#ifndef AhcConfiguration_HH
#define AhcConfiguration_HH

#include <iostream>
#include <sstream>
#include <string>
#include <fstream>
#include <vector>
#include <map>

// dual/inc/rcd
#include "RcdHeader.hh"
#include "RcdUserRW.hh"

// dual/inc/sub
#include "SubInserter.hh"
#include "SubAccessor.hh"
//#include "SubModifier.hh"

// online/inc/crc
#include "CrcConfiguration.hh"
#include "CrcReadoutConfigurationData.hh"
#include "AhcVfeSlowControlsFile.hh"

// daquser/inc/ahc
#include "AhcConfigReader.hh"

class AhcConfiguration : public CrcConfiguration {

public:
  AhcConfiguration() :   CrcConfiguration(0xac), _ahcMapping(0),  _holdEndEdge(0), _holdCmAsic(11), _holdPmAsic(70), _holdCmSipm(32), _holdPmSipm(60), _holdBeamSipm(15), _holdPin(30), _holdPmt(30), _tcmCalibWidth(1), 
#ifdef SLOW_TRIGGER
    _holdOffset1version(26),_holdOffset2version(1), _holdOffset1(-8), _holdOffset2(0),_defaultHoldOffset(-10) {
#else
    _holdOffset1version(26),_holdOffset2version(1) ,_holdOffset1(-8), _holdOffset2(0), _defaultHoldOffset(0) {
#endif

    for (unsigned fe(0);fe<8;fe++) config[fe] = 0;
    _readoutConfiguration.crateNumber(0xac);
  }


  virtual ~AhcConfiguration() {
  }
  
  virtual bool record(RcdRecord &r) {
    if(doPrint(r.recordType())) {
      std::cout << "AhcConfiguration::record()" << std::endl;
      r.RcdHeader::print(std::cout," ") << std::endl;
    }
    
    // Do underlying CRC configuration
    assert(CrcConfiguration::record(r));
    
    // Check record type
    switch (r.recordType()) {
      
      // Start up
    case RcdHeader::startUp: {
      assert(readAhcCfg(r));
      assert(ahcDacConfiguration(r));
      break;
    }

      
      // Run start 
    case RcdHeader::runStart: {

      assert(writeMapping(r));
      
      //      assert(readDacValues(r)); // read in again the AHC.cfg: does not apply the DAC but the hold & vcalib settings
      
      if(_runType.type()==DaqRunType::ahcBeamStageScan || _runType.type()==DaqRunType::beamStageScan) {	 
	assert(readStagePositions(r));
      }
      
      if(doPrint(r.recordType(),1)) _readoutConfiguration.print(std::cout," ") << std::endl;
      
      break;
      
    }
      
      
      // Configuration start 
    case RcdHeader::configurationStart: {

     
      // expert run: read in from .cfg files
      if(_runType.type()==DaqRunType::ahcExpert) {
	
	//	for(unsigned s(2);s<=21;s++) _readoutConfiguration.slotEnable(s,false);
	//	_readoutConfiguration.slotEnable(12,true);        // only enable slot 12 = HCAL

	char configFilename[128];
	for (unsigned fe(0);fe<8;fe++) 
	  {
	    if(config[fe]!=0) delete config[fe];
	    sprintf(configFilename,"AhcExpertFE%d.cfg",fe); // hardcoded one fe file readin
	    config[fe] = new AhcConfigReader(configFilename,6);
	    //	    if (config[fe]->getHoldStart()+config[fe]->getHoldWidth() > _holdEndEdge) _holdEndEdge = config[fe]->getHoldStart()+config[fe]->getHoldWidth();
	  }
      }
      //else {
      _holdEndEdge = 0x4000; // standard value from CrcFeConfiguration.hh
      //}
      //  _holdEndEdge = 0xFA00;

      if(_runType.type()==DaqRunType::ahcDacScan) assert(ahcDacConfiguration(r));
      if(_runType.type()==DaqRunType::ahcTest) assert(ahcDacConfiguration(r));
      
      // Handle the ones which need work
      if(_runType.majorType()==DaqRunType::ahc ||
	 _runType.majorType()==DaqRunType::beam ||
	 _runType.majorType()==DaqRunType::cosmics) {
	
	ahcReadoutConfiguration(r);
	//ahcBeConfiguration(r);
	//ahcBeTrgConfiguration(r);
	ahcFeConfiguration(r);
	ahcVfeConfiguration(r);
	if(((_runType.type()==DaqRunType::ahcBeamStage) || (_runType.type()==DaqRunType::ahcBeamStageScan) || (_runType.type()==DaqRunType::beamStageScan)) && (_configurationNumber%3==2)) ahcSlowConfiguration(r);
      }
      
     
      break;
    }
      
  /*
    case RcdHeader::slowConfiguration: {
      if( (_runType.type()==DaqRunType::ahcBeamStage) || (_runType.type()==DaqRunType::ahcBeamStageScan) ) {
        std::cout << "STAGE RUN" << std::endl;
        ahcSlowConfiguration(r);
      }
    
    
      break;
    }
  */
      
    // Run end
    case RcdHeader::runEnd: {
      if(_runType.type()==DaqRunType::ahcDacScan) assert(ahcDacConfiguration(r));
      if(_runType.type()==DaqRunType::ahcTest) assert(ahcDacConfiguration(r));
      break;
    }

      // Shut down
    case RcdHeader::shutDown: {
      assert(ahcDacConfiguration(r));
      break;
    }
      
    default: {
      break;
    }
    };
    
    return true;
  }
  

  virtual bool writeMapping(RcdRecord &r) {
    SubInserter inserter(r);
    inserter.insert<AhcMapping> (_ahcMapping);
    
    if(doPrint(r.recordType(),1)) {
      std::cout << "MAPPING info:" << std::endl;
      _ahcMapping->print(std::cout,"  ") << std::endl;
    }

    return true;
  }  

  virtual bool readAhcCfg(const RcdRecord &r) {


    // Clear vector for DAC data
    _vDac.clear();
    _vDac8.clear();


    // remove old mapping information and generate empty record
    if (_ahcMapping !=0) delete _ahcMapping;
    _ahcMapping = new AhcMapping();


    // Disable all slots initially
    for(unsigned i(2);i<=21;i++) _readoutConfiguration.slotEnable(i,false);
    
    // count number of PIN readout configured frontends
    nPin=0;
    // count number of PMT readout configured frontends
    nPmt=0;
    
    // Set crate number
    _readoutConfiguration.crateNumber(0xac);

    // Enable trigger slot but no FEs except FE0 (for fast trigger readout)
    if(_trgLocation.slotNumber()>0) {
      _readoutConfiguration.slotEnable(_trgLocation.slotNumber(),true);
      //_readoutConfiguration.slotFeEnable(_trgLocation.slotNumber(),0,true);
    }
    // Enable slot 12 only
    //_readoutConfiguration.slotEnable(12,true);

    // get readout configuration from AHC.cfg
    std::ifstream configFile;
    char line[512];
    

    std::string* dacFileName[21][8];
    vector<unsigned> configvalues[21][8];
   
    for (int slot =0;slot<21;slot++) {
      for (int fe =0;fe<8;fe++) _detectorType[slot][fe] = new std::string("");
      for (int fe =0;fe<8;fe++) dacFileName[slot][fe] = new std::string("");
      for (int fe =0;fe<8;fe++) configvalues[slot][fe].erase(configvalues[slot][fe].begin(),configvalues[slot][fe].end());
    }

    
    configFile.open("AHC.cfg");
    while (configFile.good()) {
      
      configFile.getline(line,sizeof(line));
      int SLOT(0);
      int FE(0);
      std::string detectorType;
      std::string readFileName;

      
      if (line[0] != '#') {
	
	std::istringstream buffer(line);
	
	buffer >> SLOT;
	buffer >> FE;
	buffer >> detectorType;
	
	*(_detectorType[SLOT][FE]) = detectorType;
	
	if (detectorType == "AHCAL" || detectorType == "AHCAL8") {

	  unsigned moduleNo, holdExt, holdCmLed, holdPmLed;
	  unsigned vcalibCm, vcalibPm;
	  unsigned stackPos, cmbId, cmbCanAdr, cmbPinId;

	  buffer >> moduleNo >> stackPos >> cmbId >> cmbCanAdr >> cmbPinId >> holdExt >> holdCmLed >> holdPmLed >> vcalibCm >> vcalibPm;
	  
	  char generatedFileName[50];
	  sprintf(generatedFileName,"DAC_module%.2d.dat",moduleNo);
	  *(dacFileName[SLOT][FE]) = *(new std::string(generatedFileName));

	  configvalues[SLOT][FE].push_back(holdPmLed);
	  configvalues[SLOT][FE].push_back(holdCmLed);
	  configvalues[SLOT][FE].push_back(holdExt);
	  configvalues[SLOT][FE].push_back(vcalibCm);
	  configvalues[SLOT][FE].push_back(vcalibPm);

	  // one stack position can not hold more than one module
	  if ((_ahcMapping->module(stackPos)) != 0) std::cout << "multiple modules in one stack position, cannnot proceed, sorry" << std::endl;
	  assert((_ahcMapping->module(stackPos)) == 0);
 
	  _ahcMapping->data(stackPos, moduleNo, SLOT, FE, cmbId, cmbCanAdr, cmbPinId);
	}
	else if (detectorType == "TCMT" ) {

	  unsigned holdExt, holdCmLed, holdPmLed;
	  unsigned vcalibCm, vcalibPm;

	  buffer >> readFileName >> holdExt >> holdCmLed >> holdPmLed >> vcalibCm >> vcalibPm;

	  *(dacFileName[SLOT][FE]) = readFileName;

	  configvalues[SLOT][FE].push_back(holdPmLed);
	  configvalues[SLOT][FE].push_back(holdCmLed);
	  configvalues[SLOT][FE].push_back(holdExt);
	  configvalues[SLOT][FE].push_back(vcalibCm);
	  configvalues[SLOT][FE].push_back(vcalibPm);
	}
	else if (detectorType == "PIN" || detectorType == "PMT" ) {
	  unsigned hold;
	  buffer >> hold;
	  configvalues[SLOT][FE].push_back(hold);
	}
       

	//std::cout << "AHC.cfg read in" << std::endl;
	
      }
    }
    
    // handle the different detectors connected to the FEs
    for(unsigned slot(5);slot<21;slot++) {
      for(unsigned f(0);f<8;f++) {
	if(*(_detectorType[slot][f])=="AHCAL") { // finely granular AHCAL module
	  if(*(dacFileName[slot][f])!="") {
	    AhcVfeStartUpDataFine data;
	    AhcVfeSlowControlsFile file;
	    if(file.read(*(dacFileName[slot][f]),data,f)) {

	      // If loading DAC, also enable slot & FE
	      _location.crateNumber(0xac);
	      _readoutConfiguration.slotEnable(slot,true);
	      _readoutConfiguration.slotFeEnable(slot,f,true);
	      _location.slotNumber(slot);

	      // Now put DAC values into vector
	      if(f==0) _location.crcComponent(CrcLocation::fe0);
	      if(f==1) _location.crcComponent(CrcLocation::fe1);
	      if(f==2) _location.crcComponent(CrcLocation::fe2);
	      if(f==3) _location.crcComponent(CrcLocation::fe3);
	      if(f==4) _location.crcComponent(CrcLocation::fe4);
	      if(f==5) _location.crcComponent(CrcLocation::fe5);
	      if(f==6) _location.crcComponent(CrcLocation::fe6);
	      if(f==7) _location.crcComponent(CrcLocation::fe7);
	      _vDac.push_back(CrcLocationData<AhcVfeStartUpDataFine>(_location,data));

	      
	      //std::cout << "location: " << unsigned(_location.crateNumber()) << " " << (unsigned)_location.slotNumber() << " " << (unsigned)_location.crcComponent() << std::endl;

	      _ahcalmap.insert(make_pair(_location,configvalues[slot][f]) );
	    }
	  }
	} // end of AHCAL fine module setting

	if(*(_detectorType[slot][f])=="AHCAL8") { // coarsely granular AHCAL module
	  if(*(dacFileName[slot][f])!="") {
	    AhcVfeStartUpDataCoarse data8;
	    AhcVfeSlowControlsFile file;
	    if(file.read(*(dacFileName[slot][f]),data8,f)) {

	      // If loading DAC, also enable slot & FE
	      _location.crateNumber(0xac);
	      _readoutConfiguration.slotEnable(slot,true);
	      _readoutConfiguration.slotFeEnable(slot,f,true);
	      _location.slotNumber(slot);

	      // Now put DAC values into vector
	      if(f==0) _location.crcComponent(CrcLocation::fe0);
	      if(f==1) _location.crcComponent(CrcLocation::fe1);
	      if(f==2) _location.crcComponent(CrcLocation::fe2);
	      if(f==3) _location.crcComponent(CrcLocation::fe3);
	      if(f==4) _location.crcComponent(CrcLocation::fe4);
	      if(f==5) _location.crcComponent(CrcLocation::fe5);
	      if(f==6) _location.crcComponent(CrcLocation::fe6);
	      if(f==7) _location.crcComponent(CrcLocation::fe7);
	      _vDac8.push_back(CrcLocationData<AhcVfeStartUpDataCoarse>(_location,data8));

	      
	      //std::cout << "location: " << unsigned(_location.crateNumber()) << " " << (unsigned)_location.slotNumber() << " " << (unsigned)_location.crcComponent() << std::endl;

	      _ahcalmap.insert(make_pair(_location,configvalues[slot][f]) );
	    }
	  }
	} // end of AHCAL coarse module setting
	

	if(*(_detectorType[slot][f])=="PIN") {
	  
	  if (nPin<maxPin) {
	    _readoutConfiguration.slotEnable(slot,true);
	    _readoutConfiguration.slotFeEnable(slot,f,true);
	    
	    _pinLocation[nPin].crateNumber(0xac);
	    _pinLocation[nPin].slotNumber(slot);
	    
	    if(f==0) _pinLocation[nPin].crcComponent(CrcLocation::fe0);
	    if(f==1) _pinLocation[nPin].crcComponent(CrcLocation::fe1);
	    if(f==2) _pinLocation[nPin].crcComponent(CrcLocation::fe2);
	    if(f==3) _pinLocation[nPin].crcComponent(CrcLocation::fe3);
	    if(f==4) _pinLocation[nPin].crcComponent(CrcLocation::fe4);
	    if(f==5) _pinLocation[nPin].crcComponent(CrcLocation::fe5);
	    if(f==6) _pinLocation[nPin].crcComponent(CrcLocation::fe6);
	    if(f==7) _pinLocation[nPin].crcComponent(CrcLocation::fe7);
	    
	    _readoutConfiguration.slotFeEnable(_pinLocation[nPin].slotNumber(),
					       _pinLocation[nPin].crcComponent(),true);
	    
	    _pinmap.insert(make_pair(_pinLocation[nPin],configvalues[slot][f]));
	    
	    // max two frontends are configured for the PIN
	    nPin++;
	    std::cout <<"There are "<< nPin <<" frontend(s) for Pin readout configured" << std::endl;
	  }
	  else {
	    std::cout << "There are more than two frontends configured in the DAC.cfg file for PIN" << std::endl;
	  }
	}
	

	if(*(_detectorType[slot][f])=="PMT") {
	  
	  if (nPmt<maxPmt) {
	    _readoutConfiguration.slotEnable(slot,true);
	    _readoutConfiguration.slotFeEnable(slot,f,true);
	    
	    _pmtLocation[nPmt].crateNumber(0xac);
	    _pmtLocation[nPmt].slotNumber(slot);
	    
	    if(f==0) _pmtLocation[nPmt].crcComponent(CrcLocation::fe0);
	    if(f==1) _pmtLocation[nPmt].crcComponent(CrcLocation::fe1);
	    if(f==2) _pmtLocation[nPmt].crcComponent(CrcLocation::fe2);
	    if(f==3) _pmtLocation[nPmt].crcComponent(CrcLocation::fe3);
	    if(f==4) _pmtLocation[nPmt].crcComponent(CrcLocation::fe4);
	    if(f==5) _pmtLocation[nPmt].crcComponent(CrcLocation::fe5);
	    if(f==6) _pmtLocation[nPmt].crcComponent(CrcLocation::fe6);
	    if(f==7) _pmtLocation[nPmt].crcComponent(CrcLocation::fe7);
	    
	    _readoutConfiguration.slotFeEnable(_pmtLocation[nPmt].slotNumber(),
					       _pmtLocation[nPmt].crcComponent(),true);
	    
	    _pmtmap.insert(make_pair(_pmtLocation[nPmt],configvalues[slot][f]));
	      
	    // max one frontend is configured for the PMT
	    nPmt++;
	    std::cout <<"There is "<< nPmt <<" frontend for Pmt readout configured" << std::endl;
	  }
	  else {
	    std::cout << "There is more than one frontend configured in the DAC.cfg file for PMT" << std::endl;
	  }
	}

	
	



	if(*(_detectorType[slot][f])=="TCMT") {
	  if(*(dacFileName[slot][f])!="") {
	    AhcVfeStartUpDataFine data;
	    AhcVfeSlowControlsFile file;
	    if(file.read(*(dacFileName[slot][f]),data,f)) {

	      // If loading DAC, also enable slot & FE
	      _location.crateNumber(0xac);
	      _readoutConfiguration.slotEnable(slot,true);
	      _readoutConfiguration.slotFeEnable(slot,f,true);
	      _location.slotNumber(slot);

	      // Now put DAC values into vector
	      if(f==0) _location.crcComponent(CrcLocation::fe0);
	      if(f==1) _location.crcComponent(CrcLocation::fe1);
	      if(f==2) _location.crcComponent(CrcLocation::fe2);
	      if(f==3) _location.crcComponent(CrcLocation::fe3);
	      if(f==4) _location.crcComponent(CrcLocation::fe4);
	      if(f==5) _location.crcComponent(CrcLocation::fe5);
	      if(f==6) _location.crcComponent(CrcLocation::fe6);
	      if(f==7) _location.crcComponent(CrcLocation::fe7);
	      _vDac.push_back(CrcLocationData<AhcVfeStartUpDataFine>(_location,data));

	      
	      //std::cout << "location: " << unsigned(_location.crateNumber()) << " " << (unsigned)_location.slotNumber() << " " << (unsigned)_location.crcComponent() << std::endl;
	      _tcmmap.insert(make_pair(_location,configvalues[slot][f]) );
	    }
	  }
	} // end of TCMT module setting

      }
    }

  // std::cout << "map sizes: "<< _ahcalmap.size() << " "<< _pinmap.size() << std::endl;

   
    if(doPrint(r.recordType(),1))
      _readoutConfiguration.print(std::cout," ") << std::endl;
    
    return true;
  }

  
  virtual bool ahcDacConfiguration(RcdRecord &r) {
    

    const unsigned char v(_runType.version());  
    
    SubInserter inserter(r);
    
    if(doPrint(r.recordType(),1)) std::cout
      << " Number of AhcVfeStartUpDataFine subrecords inserted = "
      << _vDac.size() << std::endl << std::endl;
    
    for(unsigned i(0);i<_vDac.size();i++) {
      CrcLocationData<AhcVfeStartUpDataFine> data(_vDac[i]);

      if(_runType.type()==DaqRunType::ahcDacScan) {
	if(_configurationNumber>0) {

	  for(unsigned i(0);i<12;i++) {
	    for(unsigned j(0);j<18;j++) {
	      int dac(data.data()->dac(i,j));
	      //if((_configurationNumber%2)==1) { // Increment
		dac+=(_configurationNumber+1)/2;
		if(dac>255) dac=255;
		data.data()->dac(i,j,dac);
		/*
	      } else {                          // Decrement
		dac-=(_configurationNumber+1)/2;
		if(dac<0) dac=0;
		data.data()->dac(i,j,dac);
	      }
		*/
	    }
	  }
	}
      }

      if(_runType.type()==DaqRunType::ahcTest) {
        if(_configurationNumber>0) {
	  
          for(unsigned i(0);i<12;i++) {
            for(unsigned j(0);j<18;j++) {
              int dac;
              dac+=256/(v+1);
            }
          }
        }
      }

      if(doPrint(r.recordType(),1)) data.print(std::cout,"  ") << std::endl;
      inserter.insert< CrcLocationData<AhcVfeStartUpDataFine> >(data);
    }


    if(doPrint(r.recordType(),1)) std::cout
      << " Number of AhcVfeStartUpDataCoarse subrecords inserted = "
      << _vDac8.size() << std::endl << std::endl;
    
    for(unsigned i(0);i<_vDac8.size();i++) {
      CrcLocationData<AhcVfeStartUpDataCoarse> data8(_vDac8[i]);
      
      if(_runType.type()==DaqRunType::ahcDacScan) {
	if(_configurationNumber>0) {

	  for(unsigned i(0);i<8;i++) {
	    for(unsigned j(0);j<18;j++) {
	      int dac(data8.data()->dac(i,j));
	      //if((_configurationNumber%2)==1) { // Increment
	      dac+=(_configurationNumber+1)/2;
	      if(dac>255) dac=255;
	      data8.data()->dac(i,j,dac);
	      /*
		} else {                          // Decrement
		dac-=(_configurationNumber+1)/2;
		if(dac<0) dac=0;
		data.data()->dac(i,j,dac);
		}
	      */
	    }
	  }
	}
      }

      if(_runType.type()==DaqRunType::ahcTest) {
        if(_configurationNumber>0) {
	  
          for(unsigned i(0);i<8;i++) {
            for(unsigned j(0);j<18;j++) {
              int dac;
              dac+=256/(v+1);
            }
          }
        }
      }

      if(doPrint(r.recordType(),1)) data8.print(std::cout,"  ") << std::endl;
      inserter.insert< CrcLocationData<AhcVfeStartUpDataCoarse> >(data8);
    }


    return true;
  }


  virtual bool readStagePositions(const RcdRecord &r) {

    char* _STAGEfile="StagePositions.dat";
    string _strBuffer;
    char _charBuffer[128];
    int _STAGExposition;
    int _STAGEyposition;
    unsigned _rochip;
    unsigned _rochan;

    ifstream _stageFile;
    
    // clean all vectors
    _STAGEchipArray.clear();
    _STAGEchanArray.clear();
    _STAGExArray.clear();
    _STAGEyArray.clear();


    std::cout << "trying to load STAGE positions from " << _STAGEfile <<endl;
    if (_STAGEfile == "") 
      { 
	cout << "syntax error: emtpy STAGE file string. In STAGE mode multi you must supply a valid STAGEfile value" << endl;
	exit(1);
      }

    _stageFile.open(_STAGEfile);

    if (!_stageFile.good() || !_stageFile.is_open()) 
      {
	cout << "file error: error while opening "<< _STAGEfile << " please check if file exist and is readable" << endl;	  
	exit(1);
      }

    unsigned STAGEentries(0);
    unsigned connector;
    int xmovement, ymovement;
    bool dataStart(false);
    while (_stageFile.good())
      {
	if (!dataStart)
	  {
	    _stageFile >> _strBuffer;
	      
	    if (_strBuffer=="#")
	      {
		_stageFile.getline(_charBuffer,sizeof(_charBuffer));
		std::cout << "comment: "<< _charBuffer  << endl;
	      }
	    if (_strBuffer=="--data--") dataStart = true;
	      
	  }
	else
	  {
	    _stageFile >> _rochip >> _rochan >> connector >> _STAGExposition >> _STAGEyposition >> xmovement >> ymovement;

	    if(_stageFile.eof()) break;

	    if ( (_STAGExposition > 0) && (_STAGExposition < 800) && (_STAGEyposition > 0) && (_STAGEyposition < 800) )  
	      {
		_STAGEchipArray.push_back(_rochip);
		_STAGEchanArray.push_back(_rochan);
		_STAGExArray.push_back(xmovement);
		_STAGEyArray.push_back(ymovement);
	      }
	    else 
	      {
		cout << "-- range error -- chip: " << _rochip << "  channel: " << _rochan << "  STAGE x-position: "<< _STAGExposition << "  STAGE y-position: "<< _STAGEyposition   <<endl;
		exit(1);
	      }
	    STAGEentries++;
	    std::cout << "  chip: " << _rochip << "  channel: " << _rochan << "  STAGE x-position: "<< _STAGExposition << "  STAGE y-position: "<< _STAGEyposition   <<endl;
	  }
      }
    _stageFile.close();
    cout << "found " << STAGEentries << " STAGE setting entries in file" << endl;
    if (_STAGExArray.size() != _STAGEyArray.size()) 
      {
	cout << " different number of x and y positions check position file  " << endl;
	exit(1);
      }
      
 
    


    if(doPrint(r.recordType(),1))
      _readoutConfiguration.print(std::cout," ") << std::endl;
    
    return true;
  }






  virtual bool ahcReadoutConfiguration(RcdRecord &r) {

    SubInserter inserter(r);
    CrcReadoutConfigurationData
      *b(inserter.insert<CrcReadoutConfigurationData>(true));
    *b=_readoutConfiguration;
    
    // Set some reasonable defaults
    b->vlinkBlt(true);
    b->vmePeriod(10);
    b->becPeriod(1);
    b->bePeriod(10);
    b->fePeriod(20);

    // Now do the readout periods, soft triggers and modes
    //const unsigned char v(_runType.version());
    const UtlPack u(_runType.version());

    switch(_runType.type()) {

    case DaqRunType::ahcTest: {
      break;
    }
      
    case DaqRunType::ahcCmNoise:
    case DaqRunType::ahcPmNoise: {

      // Bit 0 = BE s/w trigger, otherwise BeTrg s/w trigger
      b->beSoftTrigger(u.bit(0));

      // Bit 1 long or short acquisition periods (see DaqConfiguration)

      // Block transfer Vlink read
      // Now use for inverting spill level or not 17/07/06 (see TrgConfiguration)
      //b->vlinkBlt(u.bit(2));

      // Set periods for trigger data readout
      b->vmePeriod(u.halfByte(1));
      b->bePeriod(u.halfByte(1));
      b->fePeriod(u.halfByte(1));

      // Do counter-only readout every event
      if(u.bit(3)) {
        b->becPeriod(1);
        b->fePeriod(1);
      } else {
        b->becPeriod(0);
        //b->fePeriod(0); // Set above
      }

      break;
    }

    case DaqRunType::ahcExpert: {

      // Bit 0 = BE s/w trigger, otherwise BeTrg s/w trigger
      b->beSoftTrigger(u.bit(0));
      break;
    }

    case DaqRunType::ahcAnalogOut:
    case DaqRunType::ahcDacScan:
    case DaqRunType::ahcCmAsic:
    case DaqRunType::ahcCmAsicVcalibScan:
    case DaqRunType::ahcCmAsicHoldScan:
    case DaqRunType::ahcPmAsic:
    case DaqRunType::ahcPmAsicVcalibScan:
    case DaqRunType::ahcPmAsicHoldScan:
    case DaqRunType::ahcCmLed:
    case DaqRunType::ahcGain:
    case DaqRunType::ahcCmLedVcalibScan:
    case DaqRunType::ahcCmLedHoldScan:
    case DaqRunType::ahcPmLed:
    case DaqRunType::ahcPmLedVcalibScan:
    case DaqRunType::ahcPmLedHoldScan:
    case DaqRunType::ahcScintillatorHoldScan: {
      // Always use central trigger
      break;
    }

    case DaqRunType::ahcBeam:
      //case DaqRunType::ahcBeamHoldScan:
    case DaqRunType::ahcBeamStage:
    case DaqRunType::ahcBeamStageScan:
    case DaqRunType::ahcCosmics:
    case DaqRunType::ahcCosmicsHoldScan:

    case DaqRunType::beamTest:
    case DaqRunType::beamNoise:
    case DaqRunType::beamData:
    case DaqRunType::beamHoldScan:
    case DaqRunType::beamStageScan:

    case DaqRunType::cosmicsTest:
    case DaqRunType::cosmicsNoise:
    case DaqRunType::cosmicsData:
    case DaqRunType::cosmicsHoldScan: {
      if((_configurationNumber%3)<2) {
	// Ped and calib configuration

#ifndef FNAL_SETTINGS
	b->vmePeriod(0);
	b->becPeriod(16);
	b->bePeriod(64);
	b->fePeriod(200);
#else
	b->vmePeriod(0);
	b->becPeriod(16);
	b->bePeriod(64);
	b->fePeriod(200);
#endif

      } else {
	// Beam configurations

#ifndef FNAL_SETTINGS
	b->vmePeriod(0);
	b->becPeriod(16);
	b->bePeriod(64);
	b->fePeriod(200);
#else
	b->vmePeriod(0);
	b->becPeriod(FNAL_PERIOD);
	b->bePeriod(10*FNAL_PERIOD);
	b->fePeriod(20*FNAL_PERIOD);
#endif
      }
      break;
    }

    case DaqRunType::ahcBeamHoldScan:{
      b->vmePeriod(0);
      b->becPeriod(16);
      b->bePeriod(64);
      b->fePeriod(200);
      break;
    }

    default: {
      break;
    }
    };

    if(doPrint(r.recordType(),1)) b->print(std::cout," ") << std::endl;

    return true;
  }

  virtual bool ahcBeConfiguration(RcdRecord &r) {

    // Define vector for configuration data
    std::vector< CrcLocationData<CrcBeConfigurationData> > vBcd;

    _location.slotBroadcast(true);
    _location.crcComponent(CrcLocation::be);
    vBcd.push_back(CrcLocationData<CrcBeConfigurationData>(_location));

    const unsigned char v(_runType.version());

    switch(_runType.type()) {
    case DaqRunType::ahcTest: {
      vBcd[0].data()->j0TriggerEnable(false);
      vBcd[0].data()->j0BypassEnable(false);
       break;
    }
      
    case DaqRunType::ahcCmNoise:
    case DaqRunType::ahcPmNoise: {
      vBcd[0].data()->j0TriggerEnable((v%4)==0);
      vBcd[0].data()->j0BypassEnable(false);
      break;
    }
      
    case DaqRunType::ahcAnalogOut:
    case DaqRunType::ahcDacScan:
    case DaqRunType::ahcCmAsic:
    case DaqRunType::ahcCmAsicVcalibScan:
    case DaqRunType::ahcCmAsicHoldScan:
    case DaqRunType::ahcCmLed:
    case DaqRunType::ahcGain:
    case DaqRunType::ahcCmLedVcalibScan:
    case DaqRunType::ahcCmLedHoldScan:
    case DaqRunType::ahcPmAsic:
    case DaqRunType::ahcPmAsicVcalibScan:
    case DaqRunType::ahcPmAsicHoldScan:
    case DaqRunType::ahcPmLed:
    case DaqRunType::ahcPmLedVcalibScan:
    case DaqRunType::ahcPmLedHoldScan: {
      vBcd[0].data()->j0TriggerEnable(false);
      vBcd[0].data()->j0BypassEnable(false);
      break;
    }
      
    case DaqRunType::ahcScintillatorHoldScan: {
      vBcd[0].data()->j0TriggerEnable(true);
      vBcd[0].data()->j0BypassEnable(false);
      break;
    }
      
    case DaqRunType::ahcBeam:
      // case DaqRunType::ahcBeamHoldScan:
    case DaqRunType::ahcBeamStage:
    case DaqRunType::ahcBeamStageScan:
    case DaqRunType::ahcCosmics:
    case DaqRunType::ahcCosmicsHoldScan:

    case DaqRunType::beamTest:
    case DaqRunType::beamNoise:
    case DaqRunType::beamData:
    case DaqRunType::beamHoldScan:
    case DaqRunType::beamStageScan:

    case DaqRunType::cosmicsTest:
    case DaqRunType::cosmicsNoise:
    case DaqRunType::cosmicsData:
    case DaqRunType::cosmicsHoldScan: {
      vBcd[0].data()->j0TriggerEnable((_configurationNumber%3)==2);
      vBcd[0].data()->j0BypassEnable(false);
      
      //if((_configurationNumber%3)==2) {
      //	vBcd[0].data()->trgDataFe0Enable(true);
      //	vBcd[0].data()->feDataEnable(1);
      //	vBcd[0].data()->feTriggerEnable(1);
      // }
      break;
    }
      
    case DaqRunType::ahcBeamHoldScan: {
      vBcd[0].data()->j0TriggerEnable(1);
      vBcd[0].data()->j0BypassEnable(false);
      break;

    }
      

   case DaqRunType::ahcExpert: {     
     if(config[0]->getTrigger()==24) //hardcoded to use triggerinformation only from FE 0 file 
       {
	 vBcd[0].data()->j0TriggerEnable(false);
	 vBcd[0].data()->j0BypassEnable(false);
       } else {
	 vBcd[0].data()->j0TriggerEnable(true);
	 vBcd[0].data()->j0BypassEnable(false);
       }
     break;
    }

    default: {
      vBcd[0].data()->j0TriggerEnable(true);
      vBcd[0].data()->j0BypassEnable(false);
      break;
    }
    };

    // Load configuration into record
    SubInserter inserter(r);
    
    if(doPrint(r.recordType(),1)) std::cout
      << " Number of CrcBeConfigurationData subrecords inserted = "
      << vBcd.size() << std::endl << std::endl;
    
    for(unsigned i(0);i<vBcd.size();i++) {
      if(doPrint(r.recordType(),1)) vBcd[i].print(std::cout,"  ") << std::endl;
      inserter.insert< CrcLocationData<CrcBeConfigurationData> >(vBcd[i]);
    }
    
    return true;
  }
  
  virtual bool ahcBeTrgConfiguration(RcdRecord &r) {
    /*
      removed old code that was commented out 
      the relevant code is now in TrgConfiguration.hh
      not shure if the function itself has to be iplemented
      05.06.2007 Beni
    */
    return true;
  }
  
  virtual bool ahcFeConfiguration(RcdRecord &r) {


    if (_runType.type() == DaqRunType::ahcExpert) {
     
      SubInserter inserter(r);
      
      std::vector< CrcLocationData<CrcFeConfigurationData> > vFcd;
      
      for(unsigned f(0);f<8;f++) {

	_location.slotBroadcast(true);

	if(f==0) _location.crcComponent(CrcLocation::fe0);
	if(f==1) _location.crcComponent(CrcLocation::fe1);
	if(f==2) _location.crcComponent(CrcLocation::fe2);
	if(f==3) _location.crcComponent(CrcLocation::fe3);
	if(f==4) _location.crcComponent(CrcLocation::fe4);
	if(f==5) _location.crcComponent(CrcLocation::fe5);
	if(f==6) _location.crcComponent(CrcLocation::fe6);
	if(f==7) _location.crcComponent(CrcLocation::fe7);
	
	_location.label(1);

	unsigned t(vFcd.size());
	vFcd.push_back(CrcLocationData<CrcFeConfigurationData>(_location));
	
	vFcd[t].data()->calibEnable(config[f]->getTcalib());
	vFcd[t].data()->calibWidth(config[f]->getCalibWidth());
	//	vFcd[t].data()->calibWidth(228);  // chance from 128 to 228 for pin debug
	
	vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,config[f]->getVcalib());
	vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,config[f]->getVcalib());
	
	vFcd[t].data()->holdStart(config[f]->getHoldStart());
       	//vFcd[t].data()->holdWidth(_holdEndEdge - config[f]->getHoldStart());
	//vFcd[t].data()->sequenceDelay(123);
	vFcd[t].data()->holdEnd(_holdEndEdge); 
	
	AhcVfeControl vc(0);
	vc.ledSel(false);
	
	vc.ledSel(config[f]->getLEDSel());
	vc.swHoldIn(!config[f]->getHoldEnable());
	
	if(!config[f]->getHoldEnable()) vFcd[t].data()->vfeMplexClockPulses(config[f]->getAnalogOutChan()+1);     
	vFcd[t].data()->vfeControl(vc.data());

      }

      for(unsigned i(0);i<vFcd.size();i++) {
	if(doPrint(r.recordType(),1)) vFcd[i].print(std::cout,"  ") << std::endl;
	//std::cout << "insert frontend settings for fe " << i << std::endl; 
	inserter.insert< CrcLocationData<CrcFeConfigurationData> >(vFcd[i]);
      }

      //std::cout << "end of FE expert configuration" << std::endl;
      return true; //ignore all the rest in expert mode
    }
    



    //std::cout << "standard mode configuration" << std::endl;

        

    SubInserter inserter(r);
      
    std::vector< CrcLocationData<CrcFeConfigurationData> > vFcd;

    for (std::map< CrcLocation, std::vector<unsigned>, compare >::iterator iter=_ahcalmap.begin(); iter != _ahcalmap.end(); ++iter) {
        	
      if ( _readoutConfiguration.slotFeEnable((unsigned)(*iter).first.slotNumber(),(unsigned)(*iter).first.crcComponent() ) )
	  {
	
	    //std::cout <<"CrcLocationTest: " << printHex((*iter).first.slotNumber()) << " "<< (*iter).first.crcComponent() << std::endl;
	    
	    _location.slotNumber((*iter).first.slotNumber());
	    _location.crcComponent((*iter).first.crcComponent());
	    _location.label(1);

       
	    unsigned t(vFcd.size());
	    vFcd.push_back(CrcLocationData<CrcFeConfigurationData>(_location));
		
	
	    AhcVfeControl vc(0);
	    vc.ledSel(false);

	    const unsigned char v(_runType.version());
		
	    switch(_runType.type()) {

	    case DaqRunType::ahcTest: {
	      //      vFcd[t].data()->calibEnable(true);
	      break;
	    }
	      
	    case DaqRunType::ahcAnalogOut: {
	      vFcd[t].data()->calibEnable(true);
	      vc.ledSel(true);
	      vc.swHoldIn(true);
	      
	      if((v&0x80)==0) { //CM
		//vFcd[t].data()->holdStart(83);
		//vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,20000);
		vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,9500);
	      } else { // PM
		//vFcd[t].data()->holdStart(113);
		//vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,25000);
		vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,30000);
	      }
	      //vFcd[t].data()->calibWidth(vFcd[t].data()->holdStart()+128);
	      
	      vFcd[t].data()->vfeMplexClockPulses((v+1)%32);
	      break;
	    }
	      
	    case DaqRunType::ahcCmAsic: {
	      vFcd[t].data()->calibEnable(true);
	      vFcd[t].data()->holdStart(_holdCmAsic);
	      vFcd[t].data()->calibWidth(vFcd[t].data()->holdStart()+128);
	      
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,0);
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,0);
	      
	      if((v&0x40)==0) vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,64*(v%64));
	      if((v&0x80)==0) vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,64*(v%64));
	      break;
	    }

	    case DaqRunType::ahcCmAsicVcalibScan: {
	      vFcd[t].data()->calibEnable(true);
	      vFcd[t].data()->holdStart(_holdCmAsic);
	      vFcd[t].data()->calibWidth(vFcd[t].data()->holdStart()+128);
		  
	      unsigned steps(v+1);
	      if((_configurationNumber%2)==0) {
		vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,(_configurationNumber/2)*(4096/steps));
		vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,0);
	      } else {
		vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,0);
		vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,(_configurationNumber/2)*(4096/steps));
	      }
		  break;
	    }
	      
	    case DaqRunType::ahcCmAsicHoldScan: {
	      vFcd[t].data()->calibEnable(true);
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,1024);
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,1024);
		  
	      unsigned steps(v+1);
	      vFcd[t].data()->holdStart(_configurationNumber*(256/steps));
	      vFcd[t].data()->calibWidth(vFcd[t].data()->holdStart()+128);
	      break;
	    }
	      
	    case DaqRunType::ahcPmAsic: {
	      vFcd[t].data()->calibEnable(true);
	      vFcd[t].data()->holdStart(_holdPmAsic);
	      vFcd[t].data()->calibWidth(vFcd[t].data()->holdStart()+128);
		  
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,0);
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,0);
		  
	      if((v&0x40)==0) vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,128*(v%64));
	      if((v&0x80)==0) vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,128*(v%64));
	      break;
	    }
	      
	    case DaqRunType::ahcPmAsicVcalibScan: {
	      vFcd[t].data()->calibEnable(true);
	      vFcd[t].data()->holdStart(_holdPmAsic);
	      vFcd[t].data()->calibWidth(vFcd[t].data()->holdStart()+128);
		  
	      unsigned steps(v+1);
	      if((_configurationNumber%2)==0) {
		vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,(_configurationNumber/2)*(8192/steps));
		vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,0);
	      } else {
		vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,0);
		vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,(_configurationNumber/2)*(8192/steps));
	      }
	      break;
	    }
		  
	    case DaqRunType::ahcPmAsicHoldScan: {
	      vFcd[t].data()->calibEnable(true);
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,2048);
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,2048);
	      
	      unsigned steps(v+1);
	      vFcd[t].data()->holdStart(_configurationNumber*(512/steps));
	      vFcd[t].data()->calibWidth(vFcd[t].data()->holdStart()+128);
	      break;
	    }
	      
	    case DaqRunType::ahcCmLed: {
	      vFcd[t].data()->calibEnable(true);
	      //vFcd[t].data()->holdStart(_holdCmSipm); 
	      vFcd[t].data()->holdStart((*iter).second.at(1)); 

	      //std::cout << "HOLD for ahcCmLed: " << (*iter).second.at(1) << std::endl;
	      vFcd[t].data()->calibWidth(vFcd[t].data()->holdStart()+128);
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,0);
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,(*iter).second.at(3));
			  
	      //if((v&0x80)==0) vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,512*(v%128));
		  
	      vc.ledSel(true);
	      break;
	    }

	    case DaqRunType::ahcGain: {
	      if (_configurationNumber == 10) vFcd[t].data()->calibEnable(false);
	      else vFcd[t].data()->calibEnable(true);

	      vFcd[t].data()->holdStart((*iter).second.at(1)); 

	      vFcd[t].data()->calibWidth(vFcd[t].data()->holdStart()+128);

	      int vcalib[11]={-1000,-500,-375,-250,-125,0,125,250,375,500,-1001};
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,0);
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,(*iter).second.at(3)+vcalib[_configurationNumber]);
			  
	      //if((v&0x80)==0) vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,512*(v%128));
		  
	      vc.ledSel(true);
	      break;
	    }
		  
	    case DaqRunType::ahcCmLedVcalibScan: {
	      //if (_configurationNumber == 0) vFcd[t].data()->calibEnable(false);
	      //else vFcd[t].data()->calibEnable(true);
	      vFcd[t].data()->calibEnable(true);
	      
	      //vFcd[t].data()->holdStart(_holdCmSipm);
	      vFcd[t].data()->holdStart((*iter).second.at(1)); 
	      vFcd[t].data()->calibWidth(vFcd[t].data()->holdStart()+128);
	      
	      //unsigned steps(v+1);
	      //	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,0);
	      //vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,_configurationNumber*(65536/steps));
	      //vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,40000 + _configurationNumber*(65536-40000)/steps); // 65536/steps = maximal vcalib
	      //vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,((*iter).second.at(3)-1000)+( _configurationNumber * 100)); // 28.07.06 new approach for scan: fixed start point and fixed step width 
	      //vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,(45750 + ( _configurationNumber * 100)));
	      //vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,(41500 + ( _configurationNumber * 100)));	      

	      // 23.08.06 new setting for the second CERN testbeam period
	      //int vcalib[13]={-1001,-1000,-500,-250,0,250,500,1000,1250,1500,1750,2000,2500};
	      //vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,0);
	      //vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,((*iter).second.at(3)+vcalib[_configurationNumber]));

	      // 18.10.06 new setting for the second CERN testbeam period
	      int vcalib[20]={-500,-250,0,250,500,750,1000,1250,1500,2000,2250,2500,2750,3000,3250,3500,4000,5000,6000,7000};
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,0);

	      // first steps with absolute vcalib settings and then relativ changes in vcalib
	      if(_configurationNumber==0) vFcd[t].data()->dacData(CrcFeConfigurationData::boardB, 0 );
	      else vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,((*iter).second.at(3) + vcalib[_configurationNumber-1]));

	      // detailed scan 1 -- not used as default
	      //	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,0);
	      //	      if ( _configurationNumber < 41 ) vFcd[t].data()->dacData(CrcFeConfigurationData::boardB, 1000 * _configurationNumber );
	      //	      else  vFcd[t].data()->dacData(CrcFeConfigurationData::boardB, 41000 + 50 * (_configurationNumber - 41) );

	      // detailed scan 2 -- not used as default
	      //vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,0);
	      //if ( _configurationNumber <= 26 ) vFcd[t].data()->dacData(CrcFeConfigurationData::boardB, 1000 * _configurationNumber );
	      //else if ( _configurationNumber <= 231 )  vFcd[t].data()->dacData(CrcFeConfigurationData::boardB, 26000 + 100 * (_configurationNumber - 26) );
	      //else if ( _configurationNumber <= 240 )  vFcd[t].data()->dacData(CrcFeConfigurationData::boardB, 46500 + 1000 * (_configurationNumber - 231) );
	      //else  vFcd[t].data()->dacData(CrcFeConfigurationData::boardB, 55500 + 100 * (_configurationNumber - 240) );


	      // Niels wish 12.10.06
	      //	      int vcalib[10]={1000,2000,3000,4000,5000,6000,7000,8000,9000,10000};
	      //	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,0);
	      //	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardB, vcalib[_configurationNumber]);
	      	      	      


	      vc.ledSel(true);
	      break;
	    }
	      
	    case DaqRunType::ahcCmLedHoldScan: {
	      vFcd[t].data()->calibEnable(true);
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,0);
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,(*iter).second.at(3) + 500); 
	      
		  
	      vFcd[t].data()->holdStart(20+_configurationNumber);
	      vFcd[t].data()->calibWidth(vFcd[t].data()->holdStart()+128);
	      
	      vc.ledSel(true);
	      break;
	    }
	      
	    case DaqRunType::ahcPmLed: {
	      vFcd[t].data()->calibEnable(true);
	      //vFcd[t].data()->holdStart(_holdPmSipm);
	      vFcd[t].data()->holdStart((*iter).second.at(0)); 
	      //vFcd[t].data()->holdStart(28);
	      vFcd[t].data()->calibWidth(vFcd[t].data()->holdStart()+128);
	      	      
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,0);
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,(*iter).second.at(4) );
	      //vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,config[1]->getVcalib());
	      //vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,config[1]->getVcalib());

	      if (v>127) vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,512*(v%128));
		  
	      vc.ledSel(true);
	      break;
	    }
	      
	    case DaqRunType::ahcPmLedVcalibScan: {
	      //if (_configurationNumber == 0) vFcd[t].data()->calibEnable(false);
	      //else vFcd[t].data()->calibEnable(true);
	      vFcd[t].data()->calibEnable(true);

	      // vFcd[t].data()->holdStart(_holdPmSipm);
	      vFcd[t].data()->holdStart((*iter).second.at(0)); 
	      vFcd[t].data()->calibWidth(vFcd[t].data()->holdStart()+128);
		  
	      //unsigned steps(v+1);
	      //vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,0);
	      //vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,40000 + _configurationNumber*(65536-40000)/steps);//(10000/steps)+10000); // 65536/steps = maximal vcalib
	      //vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,((*iter).second.at(3)-1000)+( _configurationNumber * 100)); // 28.07.06 new approach for scan: fixed start point from CM vcalib setting in AHC.cfg!!! and fixed step width 


	      // the first 12 points we take the same vcalib like in the ahcCmLedVcalibScan + 20 steps of 500 in the range of 44500 - 54500 + 11 steps of 1000 in the range of 54500 - 65500

	      // 23.08.06 new setting for the second CERN testbeam period
	      //int vcalib[13]={-1001,-1000,-500,-250,0,250,500,1000,1250,1500,1750,2000,2500};
	      //vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,0);
	      //if(_configurationNumber<13) vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,((*iter).second.at(3)+vcalib[_configurationNumber]));
	      //else if(_configurationNumber<33) vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,((*iter).second.at(3) + 3000 + 500*(_configurationNumber - 13)));
	      //else vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,((*iter).second.at(3) + 14000 + 1000*(_configurationNumber - 33)));

	      // 18.10.06 new setting for the second CERN testbeam period
	      int vcalib[20]={-500,-250,0,250,500,750,1000,1250,1500,2000,2250,2500,2750,3000,3250,3500,4000,5000,6000,7000};
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,0);

	      // first and last steps with absolute vcalib settings, in between relativ changes
	      if(_configurationNumber==0) vFcd[t].data()->dacData(CrcFeConfigurationData::boardB, 0 );
	      else if(_configurationNumber<21) vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,((*iter).second.at(3) + vcalib[_configurationNumber-1]));
	      else vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,(56500 + 1000*(_configurationNumber - 22)));



	      
	      // detailed scan 1 -- not used as default
	      //	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,0);
	      //	      if ( _configurationNumber < 41 ) vFcd[t].data()->dacData(CrcFeConfigurationData::boardB, 1000 * _configurationNumber );
	      //	      else  vFcd[t].data()->dacData(CrcFeConfigurationData::boardB, 41000 + 50 * (_configurationNumber - 41) );
	      // detailed scan 2 -- not used as default
	      //vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,0);
	      //if ( _configurationNumber <= 26 ) vFcd[t].data()->dacData(CrcFeConfigurationData::boardB, 1000 * _configurationNumber );
	      //else if ( _configurationNumber <= 231 )  vFcd[t].data()->dacData(CrcFeConfigurationData::boardB, 26000 + 100 * (_configurationNumber - 26) );
	      //else if ( _configurationNumber <= 240 )  vFcd[t].data()->dacData(CrcFeConfigurationData::boardB, 46500 + 1000 * (_configurationNumber - 231) );
	      //else  vFcd[t].data()->dacData(CrcFeConfigurationData::boardB, 55500 + 100 * (_configurationNumber - 240) );

	      // Niels wish 12.10.06
	      //	      int vcalib[10]={1000,2000,3000,4000,5000,6000,7000,8000,9000,10000};
	      //	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,0);
	      //	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,vcalib[_configurationNumber]);
	      	      
		  
	      vc.ledSel(true);
	      break;
	    }
		  
	    case DaqRunType::ahcPmLedHoldScan: {
	      vFcd[t].data()->calibEnable(true);
		  
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,0);
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,(*iter).second.at(4));
	      
	      vFcd[t].data()->holdStart(20+2*_configurationNumber); 
	      vFcd[t].data()->calibWidth(vFcd[t].data()->holdStart()+128);
		  
	      vc.ledSel(true);
	      break;
	    }
		  
	    case DaqRunType::ahcBeam:
	    case DaqRunType::ahcBeamStage:
	    case DaqRunType::ahcBeamStageScan:
	    case DaqRunType::ahcCosmics:
	    case DaqRunType::ahcCosmicsHoldScan:
	      
	    case DaqRunType::beamTest:
	    case DaqRunType::beamNoise:
	    case DaqRunType::beamData:
	    case DaqRunType::beamStageScan:

	    case DaqRunType::cosmicsTest:
	    case DaqRunType::cosmicsNoise:
	    case DaqRunType::cosmicsData:
	    case DaqRunType::cosmicsHoldScan: {
	      if((_configurationNumber%3)!=1) {
		//vFcd[t].data()->sequenceDelay(8);
		//vFcd[t].data()->holdStart(_holdBeamSipm);
		if (v == _holdOffset1version) vFcd[t].data()->holdStart((*iter).second.at(2)+_holdOffset1); 
		else if (v == _holdOffset2version) vFcd[t].data()->holdStart((*iter).second.at(2)+_holdOffset2); 
		else vFcd[t].data()->holdStart((*iter).second.at(2)+_defaultHoldOffset); 
		vFcd[t].data()->calibWidth(vFcd[t].data()->holdStart()+128);
	      } else {
		vFcd[t].data()->calibEnable(true);
		//vFcd[t].data()->holdStart(_holdPmSipm);
		vFcd[t].data()->holdStart((*iter).second.at(0)); 
		vFcd[t].data()->calibWidth(vFcd[t].data()->holdStart()+128);
		//vFcd[t].data()->sequenceDelay(112);
		vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,0);
		vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,(*iter).second.at(4));
		vc.ledSel(true);
	      }
	      break;
	    }
	      
	    case DaqRunType::ahcBeamHoldScan: {
	      unsigned short hold[27]={0,2,4,6,8,9,10,11,12,13,14,15,16,17,18,19,20,22,24,26,28,30,40,50,100,150,200};
	      vFcd[t].data()->holdStart(hold[_configurationNumber%27]);
	      
	      break;
	    }

	    case DaqRunType::beamHoldScan: {
	      if((_configurationNumber%3)==0) // pedestal
		{ 
		  vFcd[t].data()->holdStart(0); 
	      
		} 
	      else if((_configurationNumber%3)==2) // beam
		{
		  //unsigned short hold[18]={0,1,2,3,4,5,6,8,10,12,15,20,30,40,50,100,150,200};
		  //unsigned short hold[27]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,30,40,50,100,150,200};
		  //		  unsigned short hold[32]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,30,40,50,100,150,200}; // CERN change: more points at the falling slope is needed!
		  //vFcd[t].data()->holdStart(hold[(_configurationNumber/3)%27]);
		  //		  vFcd[t].data()->holdStart(hold[(_configurationNumber/3)%32]);

		  //unsigned short hold[16]={0,4,8,12,16,20,30,50,2,6,10,14,18,22,1,3};// FNAL change for fast scan
		  unsigned short hold[16]={1,2,3,4,5,6,7,9,11,13,15,20,30,40,50,60};// FNAL change for fast scan
		  vFcd[t].data()->holdStart(hold[(_configurationNumber/3)%16]);

		  //vFcd[t].data()->sequenceDelay(hold[_configurationNumber%18]);
		  //vFcd[t].data()->sequenceDelay(hold[(_configurationNumber/3)%27]-1);
		} 
	      else // LED
		{
		  vFcd[t].data()->calibEnable(true);
		  vFcd[t].data()->holdStart((*iter).second.at(0)); 
		  //vFcd[t].data()->sequenceDelay(112);
		  vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,0);
		  vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,(*iter).second.at(4));
		  vc.ledSel(true);
		}

	      break;
	    }
	      
	    case DaqRunType::ahcScintillatorHoldScan: {
	      // only important when we have a CMB
	      //vFcd[t].data()->calibEnable(true);
	      //vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,0);
	      //vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,(*iter).second.at(4));
		  
	      //vc.ledSel(true);
	      
	      unsigned short hold[16]={1,2,3,4,5,6,7,8,9,10,15,20,30,40,50,100};
	      vFcd[t].data()->sequenceDelay(hold[_configurationNumber%16]-1);
	      break;
	    }
	      
	    default: {
	      
		  
	      break;
	    }
	    };
	    
		
	    //    vFcd[t].data()->holdWidth(_holdEndEdge - vFcd[t].data()->holdStart()); // equalize hold end
	    //vFcd[t].data()->sequenceDelay(123);     // shift the whole timing sequence
	    vFcd[t].data()->holdEnd(_holdEndEdge);  // equalize hold end
	    //vFcd[t].data()->holdWidth(_holdEndEdge);  // equalize hold width!!!
	    
	    // Write in VFE control
	    vFcd[t].data()->vfeControl(vc.data());
	    
	  }
	
    }
      

   
    // end of ahcal frontend settings


    // start of TCM frontend settings 
    
     for (std::map< CrcLocation, std::vector<unsigned>, compare >::iterator iter=_tcmmap.begin(); iter != _tcmmap.end(); ++iter) {
        	
      if ( _readoutConfiguration.slotFeEnable((unsigned)(*iter).first.slotNumber(),(unsigned)(*iter).first.crcComponent() ) )
	  {
	
	    //std::cout <<"CrcLocationTest: " << printHex((*iter).first.slotNumber()) << " "<< (*iter).first.crcComponent() << std::endl;
	    
	    _location.slotNumber((*iter).first.slotNumber());
	    _location.crcComponent((*iter).first.crcComponent());
	    _location.label(1);

	    // CLUDGE solution of the october 2006 where we are using two types of led board
	    /*  not necessary anymore, removed on 2007 07 09 by Beni
	      if((*iter).first.slotNumber()==12 && (*iter).first.crcComponent()==2) _tcmCalibWidth=10;
	      else _tcmCalibWidth=1;
	    */

       
	    unsigned t(vFcd.size());
	    vFcd.push_back(CrcLocationData<CrcFeConfigurationData>(_location));
		
	    AhcVfeControl vc(0);
	    vc.ledSel(false);

	    const unsigned char v(_runType.version());
		
	    switch(_runType.type()) {

	    case DaqRunType::ahcTest: {
	      //      vFcd[t].data()->calibEnable(true);
	      break;
	    }
	      
	    case DaqRunType::ahcAnalogOut: {
	      vFcd[t].data()->calibEnable(true);
	      vc.ledSel(true);
	      vc.swHoldIn(true);
	      
	      if((v&0x80)==0) { //CM
		//vFcd[t].data()->holdStart(83);
		vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,9500);
		vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,9500);
	      } else { // PM
		//vFcd[t].data()->holdStart(113);
		vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,30000);
		vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,30000);
	      }
	      //vFcd[t].data()->calibWidth(vFcd[t].data()->holdStart()+128);
	      
	      vFcd[t].data()->vfeMplexClockPulses((v+1)%32);
	      break;
	    }
	      
	    case DaqRunType::ahcCmAsic: {
	      vFcd[t].data()->calibEnable(true);
	      vFcd[t].data()->holdStart(_holdCmAsic);
	      vFcd[t].data()->calibWidth(vFcd[t].data()->holdStart()+128);
	      
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,0);
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,0);
	      
	      if((v&0x40)==0) vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,64*(v%64));
	      if((v&0x80)==0) vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,64*(v%64));
	      break;
	    }

	    case DaqRunType::ahcCmAsicVcalibScan: {
	      vFcd[t].data()->calibEnable(true);
	      vFcd[t].data()->holdStart(_holdCmAsic);
	      vFcd[t].data()->calibWidth(vFcd[t].data()->holdStart()+128);
		  
	      unsigned steps(v+1);
	      if((_configurationNumber%2)==0) {
		vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,(_configurationNumber/2)*(4096/steps));
		vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,0);
	      } else {
		vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,0);
		vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,(_configurationNumber/2)*(4096/steps));
	      }
		  break;
	    }
	      
	    case DaqRunType::ahcCmAsicHoldScan: {
	      vFcd[t].data()->calibEnable(true);
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,1024);
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,1024);
		  
	      unsigned steps(v+1);
	      vFcd[t].data()->holdStart(_configurationNumber*(256/steps));
	      vFcd[t].data()->calibWidth(vFcd[t].data()->holdStart()+128);
	      break;
	    }
	      
	    case DaqRunType::ahcPmAsic: {
	      vFcd[t].data()->calibEnable(true);
	      vFcd[t].data()->holdStart(_holdPmAsic);
	      vFcd[t].data()->calibWidth(vFcd[t].data()->holdStart()+128);
		  
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,0);
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,0);
		  
	      if((v&0x40)==0) vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,128*(v%64));
	      if((v&0x80)==0) vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,128*(v%64));
	      break;
	    }
	      
	    case DaqRunType::ahcPmAsicVcalibScan: {
	      vFcd[t].data()->calibEnable(true);
	      vFcd[t].data()->holdStart(_holdPmAsic);
	      vFcd[t].data()->calibWidth(vFcd[t].data()->holdStart()+128);
		  
	      unsigned steps(v+1);
	      if((_configurationNumber%2)==0) {
		vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,(_configurationNumber/2)*(8192/steps));
		vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,0);
	      } else {
		vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,0);
		vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,(_configurationNumber/2)*(8192/steps));
	      }
	      break;
	    }
		  
	    case DaqRunType::ahcPmAsicHoldScan: {
	      vFcd[t].data()->calibEnable(true);
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,2048);
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,2048);
	      
	      unsigned steps(v+1);
	      vFcd[t].data()->holdStart(_configurationNumber*(512/steps));
	      vFcd[t].data()->calibWidth(vFcd[t].data()->holdStart()+128);
	      break;
	    }
	      
	    case DaqRunType::ahcCmLed: {
	      vFcd[t].data()->calibEnable(true);
	      vFcd[t].data()->holdStart((*iter).second.at(1)); 

	      vFcd[t].data()->calibWidth(_tcmCalibWidth);
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,(*iter).second.at(3));
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,(*iter).second.at(3));
			  
	      vc.ledSel(true);
	      break;
	    }

	    case DaqRunType::ahcGain: {
	      if (_configurationNumber == 10) vFcd[t].data()->calibEnable(false);
	      else vFcd[t].data()->calibEnable(true);
	      vFcd[t].data()->holdStart((*iter).second.at(1)); 

	      vFcd[t].data()->calibWidth(_tcmCalibWidth);
	      //vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,(*iter).second.at(3));
	      //vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,(*iter).second.at(3));
	      
	      int vcalib[11]={+1000,-100,-75,-50,-25,0,25,50,75,100,+1001};
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,(*iter).second.at(3)+vcalib[_configurationNumber]);
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,(*iter).second.at(3)+vcalib[_configurationNumber]);
			  
	      vc.ledSel(true);
	      break;
	    }
		  
	    case DaqRunType::ahcCmLedVcalibScan: {
	      if (_configurationNumber == 0)
		vFcd[t].data()->calibEnable(false);
	      else
		vFcd[t].data()->calibEnable(true);
	      vFcd[t].data()->holdStart((*iter).second.at(1)); 
	      vFcd[t].data()->calibWidth(_tcmCalibWidth);
	      if (v==1)
		{
		  // change suggested by Kurt Francis 04.07.07: start from 0
		  vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,(
			_configurationNumber * 500) ); 
		  vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,(				 _configurationNumber * 500) ); 
		}
	      else if (v==2)
		{
		  vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,( ((*iter).second.at(3)+1000) - ( _configurationNumber * 50) )); 
		  vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,( ((*iter).second.at(3)+1000) - ( _configurationNumber * 50) )); 
		}
	      else if (v==3)
		{
		  vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,( ((*iter).second.at(3)+40) -  _configurationNumber  )); 
		  vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,( ((*iter).second.at(3)+40) -  _configurationNumber  )); 
		}
	      else  // changed 2008/05/16 by Kurt & Alex
		{
		  // standard setting (has to be decided)
		  int tmpVcalib = ( ((*iter).second.at(3)+1000) - (_configurationNumber * 100) );
		  if(tmpVcalib<0) tmpVcalib = 0;

		  vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,tmpVcalib); 
		  vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,tmpVcalib); 
		}
	      
	      vc.ledSel(true);
	      break;
	    }
	      
	    case DaqRunType::ahcCmLedHoldScan: {
	      vFcd[t].data()->calibEnable(true);
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,(*iter).second.at(3) );
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,(*iter).second.at(3) );
	      		  
	      vFcd[t].data()->holdStart(_configurationNumber);
	      vFcd[t].data()->calibWidth(_tcmCalibWidth);
	      
	      vc.ledSel(true);
	      break;
	    }
	      
	    case DaqRunType::ahcPmLed: {
	      vFcd[t].data()->calibEnable(true);
	      vFcd[t].data()->holdStart((*iter).second.at(0)); 
	      vFcd[t].data()->calibWidth(_tcmCalibWidth);
	      	      
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,(*iter).second.at(4) );
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,(*iter).second.at(4) );
		  
	      vc.ledSel(true);
	      break;
	    }
	      
	    case DaqRunType::ahcPmLedVcalibScan: {
	      if (_configurationNumber == 0) vFcd[t].data()->calibEnable(false);
	      else vFcd[t].data()->calibEnable(true);
	      vFcd[t].data()->calibEnable(true);
	      vFcd[t].data()->holdStart((*iter).second.at(0)); 
	      vFcd[t].data()->calibWidth(_tcmCalibWidth);
	      if (v==1)
		{
		  //		  vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,(65535 - ( _configurationNumber * 500) )); 
		  //		  vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,(65535 - ( _configurationNumber * 500) )); 

		  // change suggested by Kurt Francis 05.10.06: start from 0
		  vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,( _configurationNumber * 500) ); 
		  vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,( _configurationNumber * 500) ); 
		}
	      else if (v==2)
		{
		  vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,( ((*iter).second.at(3)+1000) - ( _configurationNumber * 50) )); 
		  vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,( ((*iter).second.at(3)+1000) - ( _configurationNumber * 50) )); 
		}
	      else if (v==3)
		{
		  vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,( ((*iter).second.at(3)+40) -  _configurationNumber  )); 
		  vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,( ((*iter).second.at(3)+40) -  _configurationNumber  )); 
		}
	      else  //changed 2008/05/16 by Kurt & Alex
		{
		  // standard setting (has to be decided)
		  int tmpVcalib = ( ((*iter).second.at(3)+1000) - (_configurationNumber * 100) );
		  if(tmpVcalib<0) tmpVcalib = 0;

		  vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,tmpVcalib); 
		  vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,tmpVcalib); 

		  // standard setting (has to be decided)
		  //vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,( ((*iter).second.at(3)+1000) - ( _configurationNumber * 50) )); 
		  //vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,( ((*iter).second.at(3)+1000) - ( _configurationNumber * 50) )); 
		}
		  
	      vc.ledSel(true);
	      break;
	    }
		  
	    case DaqRunType::ahcPmLedHoldScan: {
	      vFcd[t].data()->calibEnable(true);
		  
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,(*iter).second.at(4));
	      vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,(*iter).second.at(4));
	      
	      vFcd[t].data()->holdStart(20+2*_configurationNumber); 
	      vFcd[t].data()->calibWidth(_tcmCalibWidth);
		  
	      vc.ledSel(true);
	      break;
	    }
		  
	    case DaqRunType::ahcBeam:
	    case DaqRunType::ahcBeamStage:
	    case DaqRunType::ahcBeamStageScan:
	    case DaqRunType::ahcCosmics:
	    case DaqRunType::ahcCosmicsHoldScan:
	      
	    case DaqRunType::beamTest:
	    case DaqRunType::beamNoise:
	    case DaqRunType::beamData:
	    case DaqRunType::beamStageScan:

	    case DaqRunType::cosmicsTest:
	    case DaqRunType::cosmicsNoise:
	    case DaqRunType::cosmicsData:
	    case DaqRunType::cosmicsHoldScan: {
	      if((_configurationNumber%3)!=1) {
		if (v == _holdOffset1version) vFcd[t].data()->holdStart((*iter).second.at(2)+_holdOffset1); 
		else if (v == _holdOffset2version) vFcd[t].data()->holdStart((*iter).second.at(2)+_holdOffset2); 
		else vFcd[t].data()->holdStart((*iter).second.at(2)+_defaultHoldOffset); 
		// vFcd[t].data()->holdStart((*iter).second.at(2)); 
		vFcd[t].data()->calibWidth(vFcd[t].data()->holdStart()+128);
		//		vc.ledSel(true);
	      } else {
		vFcd[t].data()->calibEnable(true);
		vFcd[t].data()->holdStart((*iter).second.at(0));  //PM hold 
		vFcd[t].data()->calibWidth(_tcmCalibWidth);
		vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,(*iter).second.at(4));
		vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,(*iter).second.at(4));
		vc.ledSel(true);
	      }
	      break;
	    }
	      
	    case DaqRunType::ahcBeamHoldScan: {
	      unsigned short hold[27]={0,2,4,6,8,9,10,11,12,13,14,15,16,17,18,19,20,22,24,26,28,30,40,50,100,150,200};
	      vFcd[t].data()->holdStart(hold[_configurationNumber%27]);
	      
	      break;
	    }

	    case DaqRunType::beamHoldScan: {
	      if((_configurationNumber%3)==0) // pedestal
		{ 
		  vFcd[t].data()->holdStart(0); 
	      
		} 
	      else if((_configurationNumber%3)==2) // beam
		{
		  //		  unsigned short hold[32]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,30,40,50,100,150,200}; // CERN change: more points at the falling slope is needed!
		  //		  vFcd[t].data()->holdStart(hold[(_configurationNumber/3)%32]);

		  unsigned short hold[16]={1,2,3,4,5,6,7,9,11,13,15,20,30,40,50,60};// FNAL change for fast scan
		  //unsigned short hold[16]={0,4,8,12,16,20,30,50,2,6,10,14,18,22,1,3};// FNAL change for fast scan
		  vFcd[t].data()->holdStart(hold[(_configurationNumber/3)%16]);
		} 
	      else // LED
		{
		  vFcd[t].data()->calibEnable(true);
		  vFcd[t].data()->holdStart((*iter).second.at(0)); //PM hold 
		  vFcd[t].data()->calibWidth(_tcmCalibWidth);
		  vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,(*iter).second.at(4));
		  vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,(*iter).second.at(4));
		  vc.ledSel(true);
		}

	      break;
	    }
	      
	    case DaqRunType::ahcScintillatorHoldScan: {
	      // only important when we have a CMB
	      //vFcd[t].data()->calibEnable(true);
	      //vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,0);
	      //vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,(*iter).second.at(4));
		  
	      //vc.ledSel(true);
	      
	      unsigned short hold[16]={1,2,3,4,5,6,7,8,9,10,15,20,30,40,50,100};
	      vFcd[t].data()->sequenceDelay(hold[_configurationNumber%16]-1);
	      break;
	    }
	      
	    default: {
	      
		  
	      break;
	    }
	    };
	    
		
	    vFcd[t].data()->holdEnd(_holdEndEdge);  // equalize hold end
	    
	    // Write in VFE control
	    vFcd[t].data()->vfeControl(vc.data());
	    
	  }
	
     }
      
    // end of tcm frontend settings





    // do now the PIN frontends
    
    for (std::map< CrcLocation, std::vector<unsigned>, compare >::iterator iter=_pinmap.begin(); iter != _pinmap.end(); ++iter) {
        	
      if ( _readoutConfiguration.slotFeEnable((unsigned)(*iter).first.slotNumber(),(unsigned)(*iter).first.crcComponent() ) )
	{
	
	  //std::cout <<"CrcLocationTest: " << printHex((*iter).first.slotNumber()) << " "<< (*iter).first.crcComponent() << std::endl;
	    
	  _location.slotNumber((*iter).first.slotNumber());
	  _location.crcComponent((*iter).first.crcComponent());
	  _location.label(1);

       
	  unsigned t(vFcd.size());
	  vFcd.push_back(CrcLocationData<CrcFeConfigurationData>(_location));
		  
	  AhcVfeControl vc(0);
	  vc.ledSel(false);
	  
	
	  if(_runType.type()!=DaqRunType::ahcExpert )
	    {
	      // Now do the PIN diodes; hold and so on
	      for(unsigned i(0);i<nPin;i++) {
		//std::cout <<"PIN HOLD" << std::endl;
		//	  std::cout << _pinLocation[i].crateNumber() << " " << _pinLocation[i].crcComponent() << std::endl; 
		  
		// CrcLocationData<CrcFeConfigurationData>
		//*d(inserter.insert< CrcLocationData<CrcFeConfigurationData> >(true));
		vFcd[t].location(_location);
		      
		vc.ledSel(true);
		vFcd[t].data()->calibEnable(false);
		vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,0);
		vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,0);
		if (_runType.type()==DaqRunType::ahcCmLedHoldScan )
		  {
		    vFcd[t].data()->holdStart(20+_configurationNumber);
		    vFcd[t].data()->calibWidth(vFcd[t].data()->holdStart()+128);
		    }
		else if ( _runType.type()==DaqRunType::ahcPmLedHoldScan )
		  {
		    vFcd[t].data()->holdStart(20+_configurationNumber);
		    vFcd[t].data()->calibWidth(vFcd[t].data()->holdStart()+128+_configurationNumber);
		  }
		else 
		  {
		    //vFcd[t].data()->holdStart(_holdPin);
		    vFcd[t].data()->holdStart((*iter).second.at(0)); 
		    vFcd[t].data()->calibWidth(vFcd[t].data()->holdStart()+128);
		  }
		
		  //std::cout << _holdEndEdge <<" "<< vFcd[t].data()->holdStart() << std::endl;
		  //vFcd[t].data()->holdWidth(_holdEndEdge - vFcd[t].data()->holdStart());
		  //vFcd[t].data()->sequenceDelay(123);     // shift the whole timing sequence
		  vFcd[t].data()->holdEnd(_holdEndEdge);  // equalize hold end
		  //vFcd[t].data()->holdWidth(_holdEndEdge);  // equalize hold width!!!
		  vFcd[t].data()->vfeControl(vc.data());
		  vFcd[t].label(1);
		  // vFcd[t].print(std::cout," ");
		  
		}
	      }
	
	 
	    if(doPrint(r.recordType(),2)) {
	      vFcd[t].print(std::cout," ");
	      vc.print(std::cout," ") << std::endl;
	    }


	}
    }

    // end of PIN frontend settings

    // do now the PMT frontends
    
    for (std::map< CrcLocation, std::vector<unsigned>, compare >::iterator iter=_pmtmap.begin(); iter != _pmtmap.end(); ++iter) {
        	
      if ( _readoutConfiguration.slotFeEnable((unsigned)(*iter).first.slotNumber(),(unsigned)(*iter).first.crcComponent() ) )
	{
	
	  //std::cout <<"CrcLocationTest: " << printHex((*iter).first.slotNumber()) << " "<< (*iter).first.crcComponent() << std::endl;

	  const unsigned char v(_runType.version());
	    
	  _location.slotNumber((*iter).first.slotNumber());
	  _location.crcComponent((*iter).first.crcComponent());
	  _location.label(1);

       
	  unsigned t(vFcd.size());
	  vFcd.push_back(CrcLocationData<CrcFeConfigurationData>(_location));
		  
	  AhcVfeControl vc(0);
	  vc.ledSel(false);
	  
	
	  if(_runType.type()!=DaqRunType::ahcExpert )
	    {
	      // Now do the PMT diodes; hold and so on
	      for(unsigned i(0);i<nPmt;i++) {
		//std::cout <<"PMT HOLD" << std::endl;
		
		vFcd[t].location(_location);
		      
		vc.ledSel(true);
		vFcd[t].data()->calibEnable(false);
		vFcd[t].data()->dacData(CrcFeConfigurationData::boardA,0);
		vFcd[t].data()->dacData(CrcFeConfigurationData::boardB,0);
		if (_runType.type()==DaqRunType::ahcBeamHoldScan ) // || _runType.type()==DaqRunType::beamHoldScan  )
		  {
		    vFcd[t].data()->holdStart(_configurationNumber);
		    vFcd[t].data()->calibWidth(vFcd[t].data()->holdStart()+128);
		  }
		// Erika 02/07/07
		else if (_runType.type()==DaqRunType::beamHoldScan ){
		  vFcd[t].data()->holdStart((_configurationNumber/3)%32);
		  vFcd[t].data()->calibWidth(vFcd[t].data()->holdStart()+128);
		} // end
		else 
		  {
		    //vFcd[t].data()->holdStart(_holdPmt);
		    //		    vFcd[t].data()->holdStart((*iter).second.at(0)); 
		    if (v == _holdOffset1version) vFcd[t].data()->holdStart((*iter).second.at(0)+_holdOffset1); 
		    else if (v == _holdOffset2version) vFcd[t].data()->holdStart((*iter).second.at(0)+_holdOffset2); 
		    else vFcd[t].data()->holdStart((*iter).second.at(0)+_defaultHoldOffset); 
		    vFcd[t].data()->calibWidth(vFcd[t].data()->holdStart()+128);
		  }
		
		  vFcd[t].data()->holdEnd(_holdEndEdge);  // equalize hold end
		  //vFcd[t].data()->holdWidth(_holdEndEdge);  // equalize hold width!!!
		  vFcd[t].data()->vfeControl(vc.data());
		  vFcd[t].label(1);
		  // vFcd[t].print(std::cout," ");
		  
		}
	      }
	
	 
	    if(doPrint(r.recordType(),2)) {
	      vFcd[t].print(std::cout," ");
	      vc.print(std::cout," ") << std::endl;
	    }


	}
    }
    

    // now we insert all the configured CrcFeConfigurationData
    if(_runType.type()!=DaqRunType::ahcExpert )
      {
	//std::cout << "vFcd.size(): " << vFcd.size() << std::endl;
	for(unsigned i(0);i<vFcd.size();i++) {
	  if(doPrint(r.recordType(),1)) vFcd[i].print(std::cout,"  ") << std::endl;
	  //std::cout << "insert frontend settings for fe " << i << std::endl; 
	  inserter.insert< CrcLocationData<CrcFeConfigurationData> >(vFcd[i]);
	}
      }


  



    return true;
    // std::cout << "leaving ahcFeConfiguration" << std::endl;
  }



  virtual bool ahcVfeConfiguration(RcdRecord &r) {

    //std::cout << "entering ahcVFeConfiguration" << std::endl;

    const unsigned char v(_runType.version());  // get version number

    if (_runType.type() == DaqRunType::ahcExpert) {    //ahcExpert run type should be considered deprecated no distinction between slots and 12 or 8 HABs

      SubInserter inserter(r);
      
      std::vector< CrcLocationData<AhcVfeConfigurationDataFine> > vVcd;
      
      for(unsigned f(0);f<8;f++) {

	_location.slotBroadcast(true);

	if(f==0) _location.crcComponent(CrcLocation::fe0);
	if(f==1) _location.crcComponent(CrcLocation::fe1);
	if(f==2) _location.crcComponent(CrcLocation::fe2);
	if(f==3) _location.crcComponent(CrcLocation::fe3);
	if(f==4) _location.crcComponent(CrcLocation::fe4);
	if(f==5) _location.crcComponent(CrcLocation::fe5);
	if(f==6) _location.crcComponent(CrcLocation::fe6);
	if(f==7) _location.crcComponent(CrcLocation::fe7);

	_location.label(1);

	unsigned t(vVcd.size());
	vVcd.push_back(CrcLocationData<AhcVfeConfigurationDataFine>(_location));
	
	config[f]->insertSettings(vVcd[t].data());


      }

      for(unsigned i(0);i<vVcd.size();i++) {
	if(doPrint(r.recordType(),1)) vVcd[i].print(std::cout,"  ") << std::endl;
	inserter.insert< CrcLocationData<AhcVfeConfigurationDataFine> >(vVcd[i]);
      }

      //std::cout << "end of VFE expert configuration" << endl;
      return true; //ignore all the rest in expert mode
    }
    
    // data record inserter

    SubInserter inserter(r);


    // define modes

    AhcVfeShiftRegister calibMode;        // is set as default in the construtor

    AhcVfeShiftRegister physicsMode;
    physicsMode.shapingCapacitor(0,true); // longest shaping (3 is already on)
    physicsMode.shapingCapacitor(1,true);
    physicsMode.shapingCapacitor(2,true);

    physicsMode.gainCapacitor(1,true);    // 0.5pC (3 is already on)

    physicsMode.injectionResistor(true);  // injection resistor on


    AhcVfeShiftRegister* selectedMode;


    //loop through AHCAL 

    for (std::map< CrcLocation, std::vector<unsigned>, compare >::iterator iter=_ahcalmap.begin(); iter != _ahcalmap.end(); ++iter) {
      unsigned slot = (unsigned)(*iter).first.slotNumber();
      unsigned fe = (unsigned)(*iter).first.crcComponent();


      if ( _readoutConfiguration.slotFeEnable(slot,fe) ) {
	

	switch(_runType.type()) { 	// chose mode

	case DaqRunType::ahcTest: {
	  selectedMode = &calibMode;
	  break;
	}
	  
	case DaqRunType::ahcAnalogOut: {
	  if((v&0x80)==0) { 
	    selectedMode = &calibMode;
	  } 
	  else {
	    selectedMode = &physicsMode;
	  }
	  break;
	}

	case DaqRunType::ahcCmNoise:
	case DaqRunType::ahcCmAsic:
	case DaqRunType::ahcCmAsicVcalibScan:
	case DaqRunType::ahcCmAsicHoldScan:
	case DaqRunType::ahcCmLed:
	case DaqRunType::ahcGain:
	case DaqRunType::ahcCmLedVcalibScan:
	case DaqRunType::ahcCmLedHoldScan: {
	  selectedMode = &calibMode;
	  break;
	}
	  
	case DaqRunType::ahcDacScan:
	case DaqRunType::ahcPmNoise:
	case DaqRunType::ahcPmAsic:
	case DaqRunType::ahcPmAsicVcalibScan:
	case DaqRunType::ahcPmAsicHoldScan:
	case DaqRunType::ahcPmLed:
	case DaqRunType::ahcPmLedVcalibScan:
	case DaqRunType::ahcPmLedHoldScan:
	case DaqRunType::ahcBeam:
	case DaqRunType::ahcBeamHoldScan:
	case DaqRunType::ahcBeamStage:
	case DaqRunType::ahcBeamStageScan:
	case DaqRunType::ahcCosmics:
	  
	case DaqRunType::beamTest:
	case DaqRunType::beamData:
	case DaqRunType::beamHoldScan:
	case DaqRunType::beamStage:
	case DaqRunType::beamStageScan:
	  
	case DaqRunType::cosmicsTest:
	case DaqRunType::cosmicsData:
	case DaqRunType::cosmicsHoldScan: {
	  selectedMode = &physicsMode;
	  break;
	}
	  
	case DaqRunType::ahcExpert: {      
	}
	  

	default: {
	  break;
	}
	};
    
	// prepare data records
	
 
	if ((*(_detectorType[slot][fe])) == "AHCAL" ) {

	  std::cout << "AHCAL 12 HAB vfe configuration" << std::endl;
	  _location.slotNumber((*iter).first.slotNumber());
	  _location.crcComponent((*iter).first.crcComponent());
	  _location.label(1);
	  

	  CrcLocationData<AhcVfeConfigurationDataFine>
	    *d(inserter.insert< CrcLocationData<AhcVfeConfigurationDataFine> >(true));
	  
	  d->location(_location);
	  d->label(1);
	
	  for(unsigned h(0);h<12;h++) d->data()->shiftRegister(h,*selectedMode);
	  
	  if(doPrint(r.recordType(),2)) d->print(std::cout," ") << std::endl;
	}
	else if ((*(_detectorType[slot][fe])) == "AHCAL8" ) {

	  std::cout << "AHCAL 8 HAB vfe configuration" << std::endl;
	  _location.slotNumber((*iter).first.slotNumber());
	  _location.crcComponent((*iter).first.crcComponent());
	  _location.label(1);

	  CrcLocationData<AhcVfeConfigurationDataCoarse>
	    *d(inserter.insert< CrcLocationData<AhcVfeConfigurationDataCoarse> >(true));
	  
	  d->location(_location);
	  d->label(1);
	
	  for(unsigned h(0);h<12;h++) 
	    if (h <4 || h>7) d->data()->shiftRegister(h,*selectedMode);

	  if(doPrint(r.recordType(),2)) d->print(std::cout," ") << std::endl;
	}
	else { //something weird happend
	  assert(false);
	}

      }

    }
    

    if(_runType.type()!=DaqRunType::ahcExpert) {
	
      // tcm vfe configuration
      
      for (std::map< CrcLocation, std::vector<unsigned>, compare >::iterator iter=_tcmmap.begin(); iter != _tcmmap.end(); ++iter) {
	if ( _readoutConfiguration.slotFeEnable((unsigned)(*iter).first.slotNumber(),(unsigned)(*iter).first.crcComponent() ) )  {
	  
	  switch(_runType.type()) { 	// chose mode
	    
	  case DaqRunType::ahcTest: {
	    selectedMode = &calibMode;
	    break;
	  }
	    
	  case DaqRunType::ahcAnalogOut: {
	    if((v&0x80)==0) { 
	      selectedMode = &calibMode;
	    } 
	    else {
	      selectedMode = &physicsMode;
	    }
	    break;
	  }
	      
	  case DaqRunType::ahcCmNoise:
	  case DaqRunType::ahcCmAsic:
	  case DaqRunType::ahcCmAsicVcalibScan:
	  case DaqRunType::ahcCmAsicHoldScan:
	  case DaqRunType::ahcCmLed:
	  case DaqRunType::ahcGain:
	  case DaqRunType::ahcCmLedVcalibScan:
	  case DaqRunType::ahcCmLedHoldScan: {
	    selectedMode = &calibMode;
	    break;
	  }
	    
	  case DaqRunType::ahcDacScan:
	  case DaqRunType::ahcPmNoise:
	  case DaqRunType::ahcPmAsic:
	  case DaqRunType::ahcPmAsicVcalibScan:
	  case DaqRunType::ahcPmAsicHoldScan:
	  case DaqRunType::ahcPmLed:
	  case DaqRunType::ahcPmLedVcalibScan:
	  case DaqRunType::ahcPmLedHoldScan:
	  case DaqRunType::ahcBeam:
	  case DaqRunType::ahcBeamHoldScan:
	  case DaqRunType::ahcBeamStage:
	  case DaqRunType::ahcBeamStageScan:
	  case DaqRunType::ahcCosmics:
	      
	  case DaqRunType::beamTest:
	  case DaqRunType::beamData:
	  case DaqRunType::beamHoldScan:
	  case DaqRunType::beamStage:
	  case DaqRunType::beamStageScan:
	      
	  case DaqRunType::cosmicsTest:
	  case DaqRunType::cosmicsData:
	  case DaqRunType::cosmicsHoldScan: {
	    selectedMode = &physicsMode;
	    break;
	  }
	    
	  case DaqRunType::ahcExpert: {      
	  }
	    

	  default: {
	    break;
	  }
	  };
    


	  std::cout << "TCMT vfe configuration" << std::endl;
	  _location.slotNumber((*iter).first.slotNumber());
	  _location.crcComponent((*iter).first.crcComponent());
	  _location.label(1);
	  

	  CrcLocationData<AhcVfeConfigurationDataFine>
	    *d(inserter.insert< CrcLocationData<AhcVfeConfigurationDataFine> >(true));
	  
	  d->location(_location);
	  d->label(1);
	
	  for(unsigned h(0);h<12;h++) d->data()->shiftRegister(h,*selectedMode);
	  
	  if(doPrint(r.recordType(),2)) d->print(std::cout," ") << std::endl;



	  /*
	    switch(_runType.type()) {
	    
	    case DaqRunType::ahcBeam:
	    case DaqRunType::ahcBeamStage:
	    case DaqRunType::ahcBeamStageScan:
	    case DaqRunType::ahcCosmics:
	    case DaqRunType::ahcCosmicsHoldScan:
	      
	    case DaqRunType::beamTest:
	    case DaqRunType::beamNoise:
	    case DaqRunType::beamData:
	      
	    case DaqRunType::cosmicsTest:
	    case DaqRunType::cosmicsNoise:
	    case DaqRunType::cosmicsData:
	    case DaqRunType::cosmicsHoldScan: {
	      if((_configurationNumber%3)==1) {
		std::cout << "start of special tcm vfe configuration" << std::endl;
		_location.slotNumber((*iter).first.slotNumber());
		_location.crcComponent((*iter).first.crcComponent());
		_location.label(1);

	    
		d=inserter.insert< CrcLocationData<AhcVfeConfigurationDataFine> >(true);
		d->location(_location);
		d->label(1);

		for(unsigned h(0);h<12;h++) d->data()->shiftRegister(h,physicsMode);
		if(doPrint(r.recordType(),2)) d->print(std::cout," ") << std::endl;
		std::cout << "end of special tcm vfe configuration" << std::endl;
	      }
	      break;
	    }
	      
	    case DaqRunType::beamHoldScan: {
	      if((_configurationNumber%3)==1) {// led
		std::cout << "start of special tcm vfe configuration" << std::endl;
		_location.slotNumber((*iter).first.slotNumber());
		_location.crcComponent((*iter).first.crcComponent());
		_location.label(1);
		
	    
		d=inserter.insert< CrcLocationData<AhcVfeConfigurationDataFine> >(true);
		d->location(_location);
		d->label(1);

		for(unsigned h(0);h<12;h++) d->data()->shiftRegister(h,physicsMode);
		if(doPrint(r.recordType(),2)) d->print(std::cout," ") << std::endl;
		std::cout << "end of special tcm vfe configuration" << std::endl;
	      }
	      break;
	    }
	      
	      
	    default: {
	      break;
	    }
	    }
	  */

	  
	}
      }
      
      

      CrcLocationData<AhcVfeConfigurationDataFine> *d; // historic, was defined before and reused in later occurances
      
      // Now do the PIN diodes; the SR is the same for all runs
      for(unsigned i(0);i<nPin;i++) {
	
	//std::cout << "PIN configuration: " << std::endl;
	
	if(_pinLocation[i].crateNumber()==0xac) {
	  
	  d=inserter.insert< CrcLocationData<AhcVfeConfigurationDataFine> >(true);
	  d->location(_pinLocation[i]);
	  d->label(1);
	  
	  
	  AhcVfeShiftRegister pinMode;
	  pinMode.gainCapacitor(0,false); // 0.8pF 
	  pinMode.gainCapacitor(1,false); // 0.4pF
	  pinMode.gainCapacitor(2,false); // 0.2pF
	  pinMode.gainCapacitor(3,true);  // 0.1pF SR default setting = calib mode
	  pinMode.shapingCapacitor(0,false); // 2.4pF
	  pinMode.shapingCapacitor(1,true); // 1.2pF
	  pinMode.shapingCapacitor(2,true); // 0.6pF
	  pinMode.shapingCapacitor(3,true); // 0.3pF SR default setting = calib mode
	  
	  pinMode.injectionResistor(true);
	  
	  
	  for(unsigned h(0);h<12;h++) d->data()->shiftRegister(h,pinMode);
	  
	  if(doPrint(r.recordType(),2)) d->print(std::cout," ") << std::endl;
	}
      }
      
      
      // Now do the PMT; the SR is the same for all runs
      for(unsigned i(0);i<nPmt;i++) {
	
	//std::cout << "PMT configuration: " << std::endl;
	
	if(_pmtLocation[i].crateNumber()==0xac) {
	  
	  d=inserter.insert< CrcLocationData<AhcVfeConfigurationDataFine> >(true);
	  d->location(_pmtLocation[i]);
	  d->label(1);
	  
	  
	  AhcVfeShiftRegister pmtMode;
	  pmtMode.gainCapacitor(0,false); 
	  pmtMode.gainCapacitor(1,true);
	  pmtMode.gainCapacitor(2,false); 
	  pmtMode.gainCapacitor(3,true); // SR default setting = calib mode
	  pmtMode.shapingCapacitor(0,true); 
	  pmtMode.shapingCapacitor(1,true);
	  pmtMode.shapingCapacitor(2,true); 
	  pmtMode.shapingCapacitor(3,true); // SR default setting = calib mode
	  
	  pmtMode.injectionResistor(true);
	  
	  
	  for(unsigned h(0);h<12;h++) d->data()->shiftRegister(h,pmtMode);
    
	  if(doPrint(r.recordType(),2)) d->print(std::cout," ") << std::endl;
	}
      }
    }
    
    // std::cout << "leaving ahcVFeConfiguration" << std::endl;
    return true;
  }


  virtual bool ahcSlowConfiguration(RcdRecord &r) {
    
    
    switch(_runType.type()) {
      
    case DaqRunType::ahcTest: 
    case DaqRunType::ahcCmNoise:
    case DaqRunType::ahcPmNoise: 
    case DaqRunType::ahcAnalogOut:
    case DaqRunType::ahcDacScan:
    case DaqRunType::ahcCmAsic:
    case DaqRunType::ahcCmAsicVcalibScan:
    case DaqRunType::ahcCmAsicHoldScan:
    case DaqRunType::ahcPmAsic:
    case DaqRunType::ahcPmAsicVcalibScan:
    case DaqRunType::ahcPmAsicHoldScan:
    case DaqRunType::ahcCmLed:
    case DaqRunType::ahcGain:
    case DaqRunType::ahcCmLedVcalibScan:
    case DaqRunType::ahcCmLedHoldScan:
    case DaqRunType::ahcPmLed:
    case DaqRunType::ahcPmLedVcalibScan:
    case DaqRunType::ahcPmLedHoldScan: 
    case DaqRunType::ahcBeam:
    case DaqRunType::ahcBeamHoldScan:{
      break;
    }

    case DaqRunType::ahcBeamStage:{
      
      SubInserter inserter(r);
      AhcSlowConfigurationData *b(inserter.insert<AhcSlowConfigurationData>(true));

      //single position
      b->mmXPosition(10);
      b->mmYPosition(10);
      b->print(std::cout);
      
      if(doPrint(r.recordType(),1)) b->print(std::cout," ") << std::endl;
      
      break;
    }

    case DaqRunType::beamStageScan:
    case DaqRunType::ahcBeamStageScan:{

      SubInserter inserter(r);
      AhcSlowConfigurationData *b(inserter.insert<AhcSlowConfigurationData>(true));

      //use read in file information
      std::cout << "BeamStageScan chosen" << std::endl;
      
      int stagepositions = getSTAGEArraySize();
      // Set stage position
      //      if (_configurationNumber%3==2)
	{
	  std::cout << (int)((_configurationNumber/3)%stagepositions) << " " << getSTAGExArray((int)(_configurationNumber/3)%stagepositions) << std::endl;
      
	  b->mmXPosition( getSTAGExArray((int)((_configurationNumber/3)%stagepositions)) );
	  b->mmYPosition( getSTAGEyArray((int)((_configurationNumber/3)%stagepositions)) );
	  b->print(std::cout);
	}
      
       if(doPrint(r.recordType(),1)) b->print(std::cout," ") << std::endl;

      break;

    }
    case DaqRunType::ahcCosmics:
    case DaqRunType::beamTest:
    case DaqRunType::beamNoise:
    case DaqRunType::beamData:
    case DaqRunType::beamHoldScan:
    case DaqRunType::cosmicsTest:
    case DaqRunType::cosmicsNoise:
    case DaqRunType::cosmicsData:
    case DaqRunType::cosmicsHoldScan: 
    case DaqRunType::ahcCosmicsHoldScan: 
    case DaqRunType::ahcExpert: {
      break;
    }
    
    default: {
      break;
    }
    };

    
    return true;
  }



protected:
  // it is not really necessary to check the max number of frontends configured for PIN & PMT
  unsigned const static maxPin=2;
  CrcLocation _pinLocation[maxPin];
  unsigned nPin;
  unsigned const static maxPmt=1;
  CrcLocation _pmtLocation[maxPmt];
  unsigned nPmt;
  std::string* _detectorType[21][8];

  AhcMapping* _ahcMapping;
  
  CrcReadoutConfigurationData _readoutConfiguration;
  std::vector< CrcLocationData<AhcVfeStartUpDataFine> > _vDac;
  std::vector< CrcLocationData<AhcVfeStartUpDataCoarse> > _vDac8;
 
  // definition of three maps to store the information read in by DAC.cfg: which slot/fe is connected to which
  // kind of detector (pin, ahcal, tc) and which hold value should be set for this frontend
  //
  
  struct compare
  {
    bool operator()( const CrcLocation &left, const CrcLocation &right ) const
    {
      if (unsigned(left.slotNumber()) != unsigned(right.slotNumber()) )
	return ( unsigned(left.slotNumber()) < unsigned(right.slotNumber()) );
      else
	return ( unsigned(left.crcComponent()) < unsigned(right.crcComponent()) );
    }
  };
  
  std::map< CrcLocation, std::vector<unsigned>, compare > _pinmap;
  std::map< CrcLocation, std::vector<unsigned>, compare > _pmtmap;
  std::map< CrcLocation, std::vector<unsigned>, compare > _ahcalmap;
  std::map< CrcLocation, std::vector<unsigned>, compare > _tcmmap;

  // AhcConfigReader reads in the AhcExpertFE?.cfg files to do ahcExpert runs
  AhcConfigReader* config[8];
  unsigned _holdEndEdge;
  unsigned _holdCmAsic;
  unsigned _holdPmAsic;
  unsigned _holdCmSipm;
  unsigned _holdPmSipm;
  unsigned _holdBeamSipm;
  unsigned _holdPin;
  unsigned _holdPmt;
  unsigned _tcmCalibWidth;
  char     _holdOffset1version;
  char     _holdOffset2version;
  int      _holdOffset1;
  int      _holdOffset2;
  int      _defaultHoldOffset;

  //stage positions are stored in the following vectors --- possible UPDATE: use maps //
  vector<int> _STAGEchipArray;
  vector<int> _STAGEchanArray;
  vector<int> _STAGExArray;
  vector<int> _STAGEyArray;

  int AhcConfiguration::getSTAGExArray(int i) { return _STAGExArray[i]; }
  int AhcConfiguration::getSTAGEyArray(int i) { return _STAGEyArray[i]; }
  unsigned AhcConfiguration::getSTAGEArraySize() { return _STAGExArray.size(); }
  unsigned AhcConfiguration::getROchip(int i) { return _STAGEchipArray[i]; }
  unsigned AhcConfiguration::getROchan(int i)  { return _STAGEchanArray[i]; }


};

#endif
