#ifndef MpsReadout_HH
#define MpsReadout_HH

// TO DO; Add broadcasts, turn off all reads with cfg data enable


#include <iostream>
#include <fstream>

#include "RcdUserRW.hh"

#include "SubRecordType.hh"
#include "SubInserter.hh"
#include "SubAccessor.hh"

#include "UsbDaqDevice.hh"


class MpsReadout : public RcdUserRW {

public:
  MpsReadout(unsigned s=0, unsigned n=8) {
    for(unsigned i(0);i<n;i++) {
      UsbDaqDevice *p(new UsbDaqDevice);
      if(p->alive()) {
	
	MpsUsbDaqRunData x;
	assert(p->readMpsUsbDaqRunData(x));
	
	
	// TEMP!!! REQUIRE MASTER FOR NOW!!!
	//if(x.master()) {
	
	// ALLOW SLAVES ALSO
	if(true) {
	  
	  _vUsbDaq.push_back(p);
	  
	  MpsLocation l(s,x.usbDaqAddress(),x.sensorId());
	  l.usbDaqMaster(x.master());
	  _vLocation.push_back(l);
	  
	  // Tell configuration which sensors are connected
	  MpsConfiguration::addLocation(l);
	  
	} else {
	  std::cout << "MpsReadout::ctor()  "
		    << "USB_DAQ " << i << " was not master" << std::endl;
	  delete p;
	}
      } else {
	std::cout << "MpsReadout::ctor()  "
		  << "Could not initialise USB_DAQ " << i << std::endl;
	delete p;
      }
    }
  }

  virtual ~MpsReadout() {
    for(unsigned i(0);i<_vUsbDaq.size();i++) delete _vUsbDaq[i];
  }
  
  virtual bool record(RcdRecord &r) {
    if(doPrint(r.recordType())) {
      std::cout << "MpsReadout::record()" << std::endl;
      r.RcdHeader::print(std::cout," ") << std::endl;
    }
    
    SubInserter inserter(r);
    
    // Check record type
    switch (r.recordType()) {
      
      // Run start
    case RcdHeader::runStart: {
      
      // Reset whole system and then readback run data
      for(unsigned j(0);j<_vUsbDaq.size();j++) assert(_vUsbDaq[j]->runReset());
      
      readRunData(r);
      
      // Setup configuration check
      for(unsigned i(0);i<3;i++) {
	_vConfigured[i].clear();
	for(unsigned j(0);j<_vUsbDaq.size();j++) {
	  _vConfigured[i].push_back(false);
	}
      }
      
      break;
    }
 
      // Configuration start is used to set up system
    case RcdHeader::configurationStart: {
      SubAccessor accessor(r);
      
      std::vector<const MpsReadoutConfigurationData*>
        c(accessor.access<MpsReadoutConfigurationData>());
      
      if(doPrint(r.recordType(),1)) {
	std::cout << " MpsReadout::record()  configurationStart"
		  << ", number of MpsReadoutConfigurationData objects found = "
		  << c.size() << std::endl << std::endl;
      }
      
      if(doPrint(r.recordType(),2)) {
	for(unsigned i(0);i<c.size();i++) {	  
	  std::cout << " MpsReadout::record()  configurationStart"
		    << ", MpsReadoutConfigurationData object "
		    << i << std::endl;
	  c[i]->print(std::cout,"  ") << std::endl;
	}
      }
      
      assert(c.size()==1);
      if(c.size()==1) _readoutConfigurationData=*(c[0]);
      
      
      // Do USB_DAQ configuration
      std::vector<const MpsLocationData<MpsUsbDaqConfigurationData>*>
        u(accessor.access< MpsLocationData<MpsUsbDaqConfigurationData> >());
      
      if(doPrint(r.recordType(),1)) {
	std::cout << " MpsReadout::record()  configurationStart"
		  << ", number of MpsUsbDaqConfigurationData objects found = "
		  << u.size() << std::endl << std::endl;
      }
      
      // Keep a record of which is to be loaded to each board
      std::vector<const MpsLocationData<MpsUsbDaqConfigurationData>*> uUsbDaq(_vUsbDaq.size());
      for(unsigned j(0);j<_vUsbDaq.size();j++) uUsbDaq[j]=0;
      
      // Check for broadcasts first
      for(unsigned i(0);i<u.size();i++) {
	if(u[i]->write()) {
	  for(unsigned j(0);j<_vUsbDaq.size();j++) {
	    if(_readoutConfigurationData.usbDaqEnable(j)) {
	      if(u[i]->usbDaqMasterBroadcast() &&  _vLocation[j].usbDaqMaster()) uUsbDaq[j]=u[i];
	      if(u[i]->usbDaqSlaveBroadcast()  && !_vLocation[j].usbDaqMaster()) uUsbDaq[j]=u[i];
	    }
	  }
	}
      }
      
      // Now do individual boards
      for(unsigned i(0);i<u.size();i++) {
	if(u[i]->write()) {
	  if(!u[i]->usbDaqMasterBroadcast() && !u[i]->usbDaqSlaveBroadcast()) {
	    for(unsigned j(0);j<_vUsbDaq.size();j++) {
	      if(_readoutConfigurationData.usbDaqEnable(j)) {
		if(u[i]->usbDaqAddress()==_vLocation[j].usbDaqAddress()) uUsbDaq[j]=u[i];
	      }
	    }
	  }
	}
      }
      
      // Now do actual load
      unsigned n(0);
      for(unsigned j(0);j<_vUsbDaq.size();j++) {
	if(uUsbDaq[j]!=0) {
	  if(doPrint(r.recordType(),2)) {
	    std::cout << " MpsReadout::record()  configurationStart"
		      << ", writing MpsUsbDaqConfigurationData object"
		      << " to USB_DAQ " << j << std::endl;
	    uUsbDaq[j]->print(std::cout,"  ") << std::endl;
	  }
	  
	  assert(_vUsbDaq[j]->writeMpsUsbDaqConfigurationData(*(uUsbDaq[j]->data())));
	  _vConfigured[0][j]=true;
	  n++;
	}
      }
      
      if(doPrint(r.recordType(),1)) {
	std::cout << " MpsReadout::record()  configurationStart"
		  << ", number of MpsUsbDaqConfigurationData objects written = "
		  << n << std::endl << std::endl;
      }
      
      
      // Now do sensor PCBs
      std::vector<const MpsLocationData<MpsPcb1ConfigurationData>*>
        w(accessor.access< MpsLocationData<MpsPcb1ConfigurationData> >());
      
      if(doPrint(r.recordType(),1)) {
	std::cout << " MpsReadout::record()  configurationStart"
		  << ", number of MpsPcb1ConfigurationData objects found = "
		  << w.size() << std::endl << std::endl;
      }
      
      // Keep a record of which is to be loaded to each board
      std::vector<const MpsLocationData<MpsPcb1ConfigurationData>*> wUsbDaq(_vUsbDaq.size());
      for(unsigned j(0);j<_vUsbDaq.size();j++) wUsbDaq[j]=0;
      
      // Check for broadcasts first
      for(unsigned i(0);i<w.size();i++) {
	if(w[i]->write()) {
	  if(w[i]->sensorBroadcast()) {
	    for(unsigned j(0);j<_vUsbDaq.size();j++) {
	      if(_readoutConfigurationData.pcbEnable(j)) {
		wUsbDaq[j]=w[i];
	      }
	    }
	  }
	}
      }
      
      // Find individual cases
      for(unsigned i(0);i<w.size();i++) {
	if(w[i]->write()) {
	  if(!w[i]->sensorBroadcast()) {
	    for(unsigned j(0);j<_vUsbDaq.size();j++) {
	      if(_readoutConfigurationData.pcbEnable(j)) {
		if(w[i]->sensorId()==_vLocation[j].sensorId()) wUsbDaq[j]=w[i];
	      }
	    }
	  }
	}
      }
      
      // Now do actual load
      n=0;
      for(unsigned j(0);j<_vUsbDaq.size();j++) {
	if(wUsbDaq[j]!=0) {
	  if(doPrint(r.recordType(),2)) {
	    std::cout << " MpsReadout::record()  configurationStart"
		      << ", writing MpsPcb1ConfigurationData object"
		      << " to USB_DAQ " << j << std::endl;
	    wUsbDaq[j]->print(std::cout,"  ") << std::endl;
	  }
	  
	  assert(_vUsbDaq[j]->writeMpsPcb1ConfigurationData(*(wUsbDaq[j]->data())));
	  _vConfigured[1][j]=true;
	  n++;
	}
      }
      
      if(doPrint(r.recordType(),1)) {
	std::cout << " MpsReadout::record()  configurationStart"
		  << ", number of MpsPcb1ConfigurationData objects written = "
		  << n << std::endl << std::endl;
      }
      
      
      // Finally do the sensor itself; handle V1.0 and V1.1
      std::vector<const MpsLocationData<MpsSensorV10ConfigurationData>*>
        v(accessor.access< MpsLocationData<MpsSensorV10ConfigurationData> >());
      
      if(doPrint(r.recordType(),1)) {
	std::cout << " MpsReadout::record()  configurationStart"
		  << ", number of MpsSensorV10ConfigurationData objects found = "
		  << v.size() << std::endl << std::endl;
      }
      
      // Keep a record of which is to be loaded to each board
      std::vector<const MpsLocationData<MpsSensorV10ConfigurationData>*> vUsbDaqV10(_vUsbDaq.size());
      for(unsigned j(0);j<_vUsbDaq.size();j++) vUsbDaqV10[j]=0;
      
      // Check for broadcasts first
      for(unsigned i(0);i<v.size();i++) {
	if(v[i]->write()) {
	  if(v[i]->sensorBroadcast()) {
	    for(unsigned j(0);j<_vUsbDaq.size();j++) {
	      if(_readoutConfigurationData.sensorEnable(j) && !_vLocation[j].sensorV11()) {
		vUsbDaqV10[j]=v[i];
	      }
	    }
	  }
	}
      }

      // Find individual cases
      for(unsigned i(0);i<v.size();i++) {
	if(v[i]->write()) {
	  if(!v[i]->sensorBroadcast()) {
	    assert(!v[i]->sensorV11());
	    for(unsigned j(0);j<_vUsbDaq.size();j++) {
	      if(_readoutConfigurationData.sensorEnable(j)) {
		if(v[i]->sensorId()==_vLocation[j].sensorId()) vUsbDaqV10[j]=v[i];
	      }
	    }
	  }
	}
      }
      
      // Now do actual load
      n=0;
      for(unsigned j(0);j<_vUsbDaq.size();j++) {
	if(vUsbDaqV10[j]!=0) {
	  
	  MpsLocationData<MpsSensorV10ConfigurationData>
	    *m(inserter.insert< MpsLocationData<MpsSensorV10ConfigurationData> >());
	  m->location(_vLocation[j]);
	  
	  assert(_vUsbDaq[j]->readMpsSensorV10ConfigurationData(*(m->data())));
	  
	  if(doPrint(r.recordType(),2)) {
	    std::cout << " MpsReadout::record()  configurationStart"
		      << "  Read MpsSensorV10ConfigurationData object"
		      << " from USB_DAQ " << j << std::endl;
	    m->print(std::cout," ") << std::endl;
	  }
	  
	  if(doPrint(r.recordType(),2)) {
	    std::cout << " MpsReadout::record()  configurationStart"
		      << ", writing MpsSensorV10ConfigurationData object"
		      << " to USB_DAQ " << j << std::endl;
	    vUsbDaqV10[j]->print(std::cout,"  ") << std::endl;
	  }
	  
	  assert(_vUsbDaq[j]->writeMpsSensorV10ConfigurationData(*(vUsbDaqV10[j]->data())));
	  _vConfigured[2][j]=true;
	  n++;
	}
      }
      
      if(doPrint(r.recordType(),1)) {
	std::cout << " MpsReadout::record()  configurationStart"
		  << ", number of MpsSensorV10ConfigurationData objects read and written = "
		  << n << std::endl << std::endl;
      }

      
      std::vector<const MpsLocationData<MpsSensorV11ConfigurationData>*>
        x(accessor.access< MpsLocationData<MpsSensorV11ConfigurationData> >());
      
      if(doPrint(r.recordType(),1)) {
	std::cout << " MpsReadout::record()  configurationStart"
		  << ", number of MpsSensorV11ConfigurationData objects found = "
		  << x.size() << std::endl << std::endl;
      }
      
      // Keep a record of which is to be loaded to each board
      std::vector<const MpsLocationData<MpsSensorV11ConfigurationData>*> vUsbDaqV11(_vUsbDaq.size());
      for(unsigned j(0);j<_vUsbDaq.size();j++) vUsbDaqV11[j]=0;
      
      // Check for broadcasts first
      for(unsigned i(0);i<x.size();i++) {
	if(x[i]->write()) {
	  if(x[i]->sensorBroadcast()) {
	    for(unsigned j(0);j<_vUsbDaq.size();j++) {
	      if(_readoutConfigurationData.sensorEnable(j) && _vLocation[j].sensorV11()) {
		vUsbDaqV11[j]=x[i];
	      }
	    }
	  }
	}
      }

      // Find individual cases
      for(unsigned i(0);i<x.size();i++) {
	if(x[i]->write()) {
	  if(!x[i]->sensorBroadcast()) {
	    assert(x[i]->sensorV11());
	    for(unsigned j(0);j<_vUsbDaq.size();j++) {
	      if(_readoutConfigurationData.sensorEnable(j)) {
		if(x[i]->sensorId()==_vLocation[j].sensorId()) vUsbDaqV11[j]=x[i];
	      }
	    }
	  }
	}
      }
      
      // Now do actual load
      n=0;
      for(unsigned j(0);j<_vUsbDaq.size();j++) {
	if(vUsbDaqV11[j]!=0) {
	  
	  MpsLocationData<MpsSensorV11ConfigurationData>
	    *m(inserter.insert< MpsLocationData<MpsSensorV11ConfigurationData> >());
	  m->location(_vLocation[j]);
	  
	  assert(_vUsbDaq[j]->readMpsSensorV11ConfigurationData(*(m->data())));
	  
	  if(doPrint(r.recordType(),2)) {
	    std::cout << " MpsReadout::record()  configurationStart"
		      << "  Read MpsSensorV11ConfigurationData object"
		      << " from USB_DAQ " << j << std::endl;
	    m->print(std::cout," ") << std::endl;
	  }
	  
	  if(doPrint(r.recordType(),2)) {
	    std::cout << " MpsReadout::record()  configurationStart"
		      << ", writing MpsSensorV11ConfigurationData object"
		      << " to USB_DAQ " << j << std::endl;
	    vUsbDaqV11[j]->print(std::cout,"  ") << std::endl;
	  }
	  
	  assert(_vUsbDaq[j]->writeMpsSensorV11ConfigurationData(*(vUsbDaqV11[j]->data())));
	  _vConfigured[2][j]=true;
	  n++;
	}
      }
      
      if(doPrint(r.recordType(),1)) {
	std::cout << " MpsReadout::record()  configurationStart"
		  << ", number of MpsSensorV11ConfigurationData objects read and written = "
		  << n << std::endl << std::endl;
      }
      
      
      // Check all components have been configured
      /*
	for(unsigned j(0);j<_vUsbDaq.size();j++) {
	if(_readoutConfigurationData.usbDaqEnable(j)) {
	//assert(_vConfigured[0][j] && _vConfigured[1][j] && _vConfigured[2][j]); ???? TEMP!!!
	}
	}
      */
      
      // Now read back the (non-destructive read) configuration data
      readConfigurationData(r);
      
      break;
    }
      
    case RcdHeader::bunchTrain: {
      
      // Fire the USB_DAQ master(s)
      for(unsigned i(0);i<_vUsbDaq.size();i++) {
	if(_readoutConfigurationData.usbDaqEnable(i)) {
	  if(_vLocation[i].usbDaqMaster()) {
	    assert(_vUsbDaq[i]->takeBunchTrain());
	    if(doPrint(r.recordType(),2)) {
	      std::cout << " MpsReadout::record()  bunchTrain"
			<< ", taking bunch train"
			<< " from USB_DAQ " << i << std::endl;
	    }
	  }
	}
      }
      
      // Read out USB_DAQ data
      unsigned n(0);
      for(unsigned i(0);i<_vUsbDaq.size();i++) {
	if(_readoutConfigurationData.usbDaqIoEnable(i)) {
	  //if(_vConfigured[0][i]) {
	  
	  MpsLocationData<MpsUsbDaqBunchTrainData>
	    *m(inserter.insert< MpsLocationData<MpsUsbDaqBunchTrainData> >());
	  m->location(_vLocation[i]);
	  
	  assert(_vUsbDaq[i]->readMpsUsbDaqBunchTrainData(*(m->data())));
	  inserter.extend(4*m->data()->numberOfTags());
	  
	  if(doPrint(r.recordType(),2)) {
	    std::cout << " MpsReadout::record()  bunchTrain"
		      << ", read MpsUsbDaqBunchTrainData object"
		      << " from USB_DAQ " << i << std::endl;
	    m->print(std::cout,"  ") << std::endl;
	  }
	  n++;
	}
      }
      
      if(doPrint(r.recordType(),1)) {
	std::cout << " MpsReadout::record()  bunchTrain"
		  << ", number of MpsUsbDaqBunchTrainData objects read = "
		  << n << std::endl << std::endl;
      }
      
      // Start transfer of sensor data if more than one sensor
      
      n=0;
      for(unsigned i(0);i<_vUsbDaq.size();i++) {
	if(_readoutConfigurationData.sensorEnable(i)) {
	  //if(_vConfigured[1][i] && _vConfigured[2][i]) {
	  if(n>0) assert(_vUsbDaq[i]->transferMpsSensor1BunchTrainData());
	  n++;
	}
      }
      
      // Read out sensor data
      
      n=0;
      for(unsigned i(0);i<_vUsbDaq.size();i++) {
	if(_readoutConfigurationData.sensorEnable(i)) {
	  //if(_vConfigured[1][i] && _vConfigured[2][i]) {
	  
	  MpsLocationData<MpsSensor1BunchTrainData>
	    *m(inserter.insert< MpsLocationData<MpsSensor1BunchTrainData> >());
	  m->location(_vLocation[i]);
	  
	  assert(_vUsbDaq[i]->readMpsSensor1BunchTrainData(*(m->data())));
	  inserter.extend(4*m->data()->totalNumberOfHits());
	  
	  if(doPrint(r.recordType(),2)) {
	    std::cout << " MpsReadout::record()  bunchTrain"
		      << ", read MpsSensor1BunchTrainData object"
		      << " from USB_DAQ " << i << std::endl;
	    m->print(std::cout,"  ") << std::endl;
	  }
	  n++;
	}
      }
      
      if(doPrint(r.recordType(),1)) {
	std::cout << " MpsReadout::record()  bunchTrain"
		  << ", number of MpsSensor1BunchTrainData objects read = "
		  << n << std::endl << std::endl;
      }
      
      break;
    }

    case RcdHeader::configurationEnd: {
      readConfigurationData(r);
      
      // Read back (destructive) sensor configuration data
      /*
	unsigned n(0);
	for(unsigned i(0);i<_vUsbDaq.size();i++) {
	//if(_readoutConfigurationData.usbDaqEnable(i)) {
	if(_vConfigured[2][i]) {
	
	MpsLocationData<MpsSensor1ConfigurationData>
	*m(inserter.insert< MpsLocationData<MpsSensor1ConfigurationData> >());
	m->location(_vLocation[i]);
	
	assert(_vUsbDaq[i]->readMpsSensor1ConfigurationData(*(m->data())));
	
	if(doPrint(r.recordType(),2)) {
	std::cout << " MpsReadout::record()  configurationEnd"
	<< "  Read MpsSensor1ConfigurationData object"
	<< " from USB_DAQ " << i << std::endl;
	m->print(std::cout," ") << std::endl;
	}
	
	n++;
	}
	}
	
	if(doPrint(r.recordType(),1)) {
	std::cout << " MpsReadout::record()  configurationEnd"
	<< "  Number of MpsSensor1ConfigurationData objects read = "
	<< n << std::endl << std::endl;
	}
      */
      
      break;
    }
 
      // Run end
    case RcdHeader::runEnd: {
      readRunData(r);
      
      // Read back (destructive) sensor configuration data
      
      unsigned nV10(0),nV11(0);
      for(unsigned i(0);i<_vUsbDaq.size();i++) {
	if(_readoutConfigurationData.sensorEnable(i)) {
	  //if(_vConfigured[2][i]) {
	  
	  if(!_vLocation[i].sensorV11()) {
	    MpsLocationData<MpsSensorV10ConfigurationData>
	      *m(inserter.insert< MpsLocationData<MpsSensorV10ConfigurationData> >());
	    m->location(_vLocation[i]);
	    
	    assert(_vUsbDaq[i]->readMpsSensorV10ConfigurationData(*(m->data())));
	    
	    if(doPrint(r.recordType(),2)) {
	      std::cout << " MpsReadout::record()  runEnd"
			<< "  Read MpsSensorV10ConfigurationData object"
			<< " from USB_DAQ " << i << std::endl;
	      m->print(std::cout," ") << std::endl;
	    }
	    nV10++;

	  } else {
	    MpsLocationData<MpsSensorV11ConfigurationData>
	      *m(inserter.insert< MpsLocationData<MpsSensorV11ConfigurationData> >());
	    m->location(_vLocation[i]);
	    
	    assert(_vUsbDaq[i]->readMpsSensorV11ConfigurationData(*(m->data())));
	    
	    if(doPrint(r.recordType(),2)) {
	      std::cout << " MpsReadout::record()  runEnd"
			<< "  Read MpsSensorV11ConfigurationData object"
			<< " from USB_DAQ " << i << std::endl;
	      m->print(std::cout," ") << std::endl;
	    }
	    nV11++;
	  }
	}
      }
      
      if(doPrint(r.recordType(),1)) {
	std::cout << " MpsReadout::record()  configurationEnd"
		  << "  Number of MpsSensorV10ConfigurationData objects read = "
		  << nV10 << std::endl << std::endl;
	std::cout << " MpsReadout::record()  configurationEnd"
		  << "  Number of MpsSensorV11ConfigurationData objects read = "
		  << nV11 << std::endl << std::endl;
      }
      
      break;
    }
 
      // Slow readout
    case RcdHeader::slowReadout: {
      
      // Read out sensor PCB data as only temperatures
      unsigned n(0);
      for(unsigned i(0);i<_vUsbDaq.size();i++) {

	// Never allow this to be disabled; just check for sensor id
	//if(_readoutConfigurationData.pcbEnable(i)) {
	if(_vLocation[i].sensorId()!=31) {

	  MpsLocationData<MpsPcb1SlowReadoutData>
	    *m(inserter.insert< MpsLocationData<MpsPcb1SlowReadoutData> >());
	  m->location(_vLocation[i]);
	  
	  assert(_vUsbDaq[i]->readMpsPcb1SlowReadoutData(*(m->data())));
	  
	  if(doPrint(r.recordType(),2)) {
	    std::cout << " MpsReadout::record()  slowReadout"
		      << ", read MpsPcb1SlowReadoutData object"
		      << " from USB_DAQ " << i << std::endl;
	    m->print(std::cout,"  ") << std::endl;
	  }
	  n++;
	}
      }

      if(doPrint(r.recordType(),1)) {
	std::cout << " MpsReadout::record()  slowReadout"
		  << ", number of MpsPcb1SlowReadoutData objects read = "
		  << n << std::endl << std::endl;
      }

      break;
    }

    default: {
      break;
    }
    };
    
    return true;
  }

private:
  bool readRunData(RcdRecord &r) {
    SubInserter inserter(r);

    unsigned n(0);
    for(unsigned i(0);i<_vUsbDaq.size();i++) {
      MpsLocationData<MpsUsbDaqRunData>
	*m(inserter.insert< MpsLocationData<MpsUsbDaqRunData> >());
      m->location(_vLocation[i]);

      assert(_vUsbDaq[i]->readMpsUsbDaqRunData(*(m->data())));

      if(doPrint(r.recordType(),2)) {
	std::cout << " MpsReadout::readRunData()"
		  << "  Read MpsUsbDaqRunData object"
		  << " from USB_DAQ " << i << std::endl;
	m->print(std::cout," ") << std::endl;
      }

      n++;
    }

    if(doPrint(r.recordType(),1)) {
      std::cout << " MpsReadout::readRunData()"
		<< "  Number of MpsUsbDaqRunData objects read = "
		<< n << std::endl << std::endl;
    }
    
    return true;
  }

  bool readConfigurationData(RcdRecord &r) {
    SubInserter inserter(r);

    // Read back all the USB_DAQ configuration data

    unsigned n(0);
    for(unsigned i(0);i<_vUsbDaq.size();i++) {
      if(_readoutConfigurationData.usbDaqEnable(i)) {
	//if(_vConfigured[0][i]) {

	MpsLocationData<MpsUsbDaqConfigurationData>
	  *m(inserter.insert< MpsLocationData<MpsUsbDaqConfigurationData> >());
	m->location(_vLocation[i]);
	
	assert(_vUsbDaq[i]->readMpsUsbDaqConfigurationData(*(m->data())));
	
	if(doPrint(r.recordType(),2)) {
	  std::cout << " MpsReadout::readConfigurationData()"
		    << "  Read MpsUsbDaqConfigurationData object"
		    << " from USB_DAQ " << i << std::endl;
	  m->print(std::cout," ") << std::endl;
	}
	
	n++;
      }
    }

    if(doPrint(r.recordType(),1)) {
      std::cout << " MpsReadout::readConfigurationData()"
		<< "  Number of MpsUsbDaqConfigurationData objects read = "
		<< n << std::endl << std::endl;
    }

    // Repeat for all the PCB1 configuration data

    n=0;
    for(unsigned i(0);i<_vUsbDaq.size();i++) {
      if(_readoutConfigurationData.pcbEnable(i)) {
      //if(_vConfigured[1][i]) {

	MpsLocationData<MpsPcb1ConfigurationData>
	  *m(inserter.insert< MpsLocationData<MpsPcb1ConfigurationData> >());
	m->location(_vLocation[i]);
	
	assert(_vUsbDaq[i]->readMpsPcb1ConfigurationData(*(m->data())));
	
	if(doPrint(r.recordType(),2)) {
	  std::cout << " MpsReadout::readConfigurationData()"
		    << "  Read MpsPcb1ConfigurationData object"
		    << " from USB_DAQ " << i << std::endl;
	  m->print(std::cout," ") << std::endl;
	}
	
	n++;
      }
    }

    if(doPrint(r.recordType(),1)) {
      std::cout << " MpsReadout::readConfigurationData()"
		<< "  Number of MpsPcb1ConfigurationData objects read = "
		<< n << std::endl << std::endl;
    }

    return true;
  }



  std::vector<UsbDaqDevice*> _vUsbDaq;
  std::vector<MpsLocation> _vLocation;

  MpsReadoutConfigurationData _readoutConfigurationData;
  std::vector<bool> _vConfigured[3];

  // Buffer for bunch train reads
  unsigned _buffer[4][(sizeof(MpsSensor1BunchTrainData)/4)+3192];
  MpsSensor1BunchTrainData *_sensorBunchTrainData[4];
};

#endif
