#ifndef DaqRunType_HH
#define DaqRunType_HH

/**********************************************************************
 * DaqRunType - defines run types available
 *
 * Whenever you add or change the run types, you must also edit the
 * DaqConfiguration.hh and corresponding XxxConfiguration.hh file
 *
 **********************************************************************/

#include <string>
#include <fstream>
#include <iostream>

#include "UtlPack.hh"


class DaqRunType {

public:
  enum MajorType {
    daq,      // DAQ tests only; no readout
    crc,      // CRC crates using internal software triggers only
    trg,      // CRC trigger board triggers
    emc,      // ECAL crate only
    ahc,      // AHCAL crate only
    ahc1,     // AHCAL crate only continued
    dhc,      // DHCAL crate only
    tcm,      // TCMT CRC only
    bml,      // Beam line equipment only
    slow,     // Slow controls and readout only
    beam,     // Full system
    cosmics,  // Full system
    sce,      // Scintillator ECAL only
    sce1,     // Scintillator ECAL only continued
    dhe,      // DHCAL with HaRDROC only
    endOfMajorTypeEnum
  };

  enum Type {
    // daq
    daqTest=0x10*daq,
    endOfDaqTypeEnum,

    // crc
    crcTest=0x10*crc,
    crcNoise,
    crcBeParameters,
    crcFeParameters,
    crcIntDac,
    crcIntDacScan,
    crcExtDac,
    crcExtDacScan,
    crcFakeEvent,
    crcModeTest,

    // trg
    trgTest=0x10*trg,
    trgReadout,
    trgParameters,
    trgNoise,
    trgSpill,
    trgBeam,
    trgCosmics,

    // emc
    emcTest=0x10*emc,
    emcNoise,
    emcFeParameters,
    emcVfeDac,
    emcVfeDacScan,
    emcVfeHoldScan,
    emcTrgTiming,
    emcTrgTimingScan,
    emcBeam,
    emcBeamHoldScan,
    emcCosmics,
    emcCosmicsHoldScan,

    // ahc
    ahcTest=0x10*ahc,
    ahcDacScan,
    ahcCmNoise,
    ahcPmNoise,
    ahcAnalogOut,
    ahcCmAsic,
    ahcCmAsicVcalibScan,
    ahcCmAsicHoldScan,
    ahcPmAsic,
    ahcPmAsicVcalibScan,
    ahcPmAsicHoldScan,
    ahcCmLed,
    ahcCmLedVcalibScan,
    ahcCmLedHoldScan,
    ahcPmLed,
    ahcPmLedVcalibScan,
    ahcPmLedHoldScan,
    ahcScintillatorHoldScan,
    ahcBeam,
    ahcBeamHoldScan,
    ahcBeamStage,
    ahcBeamStageScan,
    ahcCosmics,
    ahcCosmicsHoldScan,
    ahcExpert,
    ahcGain,

    // dhc
    dhcTest=0x10*dhc,
    dhcNoise,
    dhcBeam,
    dhcCosmics,
    dhcQinj,
    dhcQinjScan,

    // tcm
    tcmTest=0x10*tcm,
    tcmNoise,
    tcmBeam,
    tcmBeamHoldScan,
    tcmCalLed,
    tcmPhysLed,
    tcmCalPedestal,
    tcmPhysPedestal,
    tcmCosmics,
    tcmCosmicsHoldScan,

    // bml
    bmlTest=0x10*bml,
    bmlNoise,
    bmlInternalTest,
    bmlBeam,

    // slow
    slowTest=0x10*slow,
    slowMonitor,

    // beam
    beamTest=0x10*beam,
    beamNoise,
    beamData,
    beamHoldScan,
    beamStage,
    beamStageScan,

    // cosmics
    cosmicsTest=0x10*cosmics,
    cosmicsNoise,
    cosmicsData,
    cosmicsHoldScan,

    // sce
    sceTest=0x10*sce,
    sceDacScan,
    sceCmNoise,
    scePmNoise,
    sceAnalogOut,
    sceCmAsic,
    sceCmAsicVcalibScan,
    sceCmAsicHoldScan,
    scePmAsic,
    scePmAsicVcalibScan,
    scePmAsicHoldScan,
    sceCmLed,
    sceCmLedVcalibScan,
    sceCmLedHoldScan,
    scePmLed,
    scePmLedVcalibScan,
    scePmLedHoldScan,
    sceScintillatorHoldScan,
    sceBeam,
    sceBeamHoldScan,
    sceBeamStage,
    sceBeamStageScan,
    sceCosmics,
    sceCosmicsHoldScan,
    sceExpert,
    sceGain,

    // dhe
    dheTest=0x10*dhe,
    dheNoise,
    dheBeam,
    dheCosmics,

    endOfTypeEnum
  };


  DaqRunType();
  DaqRunType(Type t, unsigned char m=0, unsigned char v=0);
  DaqRunType(std::string s, unsigned char m=0, unsigned char v=0);

  Type type() const;
  void type(Type s);

  MajorType majorType() const;

  std::string        typeName() const;
  static std::string typeName(Type t);

  std::string        typeComment() const;
  static std::string typeComment(Type t);

  std::string        majorTypeName() const;
  static std::string majorTypeName(MajorType t);

  bool        knownType() const;
  static bool knownType(Type t);

  static Type typeNumber(std::string s);

  unsigned char printLevel() const;
  void          printLevel(unsigned char m);

  unsigned char switches() const;
  void          switches(unsigned char m);

  bool bufferRun() const;
  void bufferRun(bool b);

  //bool spillRun() const; // Obsolete
  //void spillRun(bool b); // Obsolete

  bool burstRun() const;
  void burstRun(bool b);

  //bool transferRun() const;
  //void transferRun(bool b);

  bool endlessRun() const;
  void endlessRun(bool b);

  bool histogramRun() const;
  void histogramRun(bool b);

  bool ascWriteRun() const;
  void ascWriteRun(bool b);

  bool writeRun() const;
  void writeRun(bool b);

  unsigned char version() const;
  void          version(unsigned char v);

  unsigned char        defaultVersion() const;
  static unsigned char defaultVersion(Type t);

  UtlPack data() const;
  void    data(UtlPack n);

  bool beamType() const;
  bool cosmicsType() const;

  static void dumpTypes(const std::string &f);

  std::ostream& print(std::ostream &o, std::string s="") const;


private:
  static const std::string _majorTypeName[endOfMajorTypeEnum];
  static const std::string _typeName[endOfTypeEnum];
  static const std::string _typeComment[endOfTypeEnum];
  static const unsigned char _defaultVersion[endOfTypeEnum];

  // Byte 0 = version number
  // Byte 1 = bit switches (bits 8-10, 13-15)
  // Byte 2 = print level
  // Byte 3 = type (major type = bits 28-31)
  UtlPack _data;
};


#ifdef CALICE_DAQ_ICC


DaqRunType::DaqRunType() : _data(0) {
}

DaqRunType::DaqRunType(Type t, unsigned char m, unsigned char v) :
  _data(0) {
  type(t);
  switches(m);
  version(v);
}

DaqRunType::DaqRunType(std::string s, unsigned char m, unsigned char v) :
  _data(0) {
  type(typeNumber(s));
  switches(m);
  version(v);
}

DaqRunType::Type DaqRunType::type() const {
  return (Type)_data.byte(3);
}

void DaqRunType::type(Type n) {
  _data.byte(3,(unsigned char)n);
  _data.byte(0,defaultVersion(n));
}

DaqRunType::MajorType DaqRunType::majorType() const {
  MajorType m((MajorType)_data.halfByte(7));
  if(m==ahc1) m=ahc; // Catch second range of AHCAL
  if(m==sce1) m=sce; // Catch second range of SCECAL
  return m;
}

std::string DaqRunType::typeName() const {
  return typeName(type());
}
 
std::string DaqRunType::typeName(Type t) {
  if(t<endOfTypeEnum) return _typeName[t];
  return "unknown";
}

std::string DaqRunType::typeComment() const {
  return typeComment(type());
}
 
std::string DaqRunType::typeComment(Type t) {
  if(t<endOfTypeEnum) return _typeComment[t];
  return "unknown";
}

std::string DaqRunType::majorTypeName() const {
  return majorTypeName(majorType());
}
 
std::string DaqRunType::majorTypeName(MajorType t) {
  if(t<endOfMajorTypeEnum) return _majorTypeName[t];
  return "unknown";
}

bool DaqRunType::knownType() const {
  return knownType(type());
}

bool DaqRunType::knownType(Type t) {
  return typeName(t)!="unknown";
}

DaqRunType::Type DaqRunType::typeNumber(std::string s) {
  for(unsigned t(0);t<endOfTypeEnum;t++) {
    if(s==typeName((Type)t)) return (Type)t;
  }
  return (Type)255;
}

unsigned char DaqRunType::printLevel() const {
  return _data.byte(2);
}

void DaqRunType::printLevel(unsigned char m) {
  _data.byte(2,m);
}

unsigned char DaqRunType::switches() const {
  return _data.byte(1);
}

void DaqRunType::switches(unsigned char m) {
  _data.byte(1,m);
}

bool DaqRunType::bufferRun() const {
  return _data.bit(8);
}

void DaqRunType::bufferRun(bool b) {
  return _data.bit(8,b);
}

bool DaqRunType::burstRun() const {
  return _data.bit(9);
}

void DaqRunType::burstRun(bool b) {
  return _data.bit(9,b);
}
/*
bool DaqRunType::transferRun() const {
  return _data.bit(10);
}

void DaqRunType::transferRun(bool b) {
  return _data.bit(10,b);
}
*/
bool DaqRunType::endlessRun() const {
  return _data.bit(12);
}

void DaqRunType::endlessRun(bool b) {
  return _data.bit(12,b);
}

bool DaqRunType::histogramRun() const {
  return _data.bit(13);
}

void DaqRunType::histogramRun(bool b) {
  return _data.bit(13,b);
}

bool DaqRunType::ascWriteRun() const {
  return _data.bit(14);
}

void DaqRunType::ascWriteRun(bool b) {
  return _data.bit(14,b);
}

bool DaqRunType::writeRun() const {
  return _data.bit(15);
}

void DaqRunType::writeRun(bool b) {
  return _data.bit(15,b);
}

unsigned char DaqRunType::version() const {
  return _data.byte(0);
}

void DaqRunType::version(unsigned char v) {
  _data.byte(0,v);
}

unsigned char DaqRunType::defaultVersion() const {
  return defaultVersion(type());
}
 
unsigned char DaqRunType::defaultVersion(Type t) {
  if(t<endOfTypeEnum) return _defaultVersion[t];
  return 0;
}

UtlPack DaqRunType::data() const {
  return _data;
}
 
void DaqRunType::data(UtlPack d) {
  _data=d;
}

bool DaqRunType::beamType() const {
  Type t(type());
  return
    t==DaqRunType::trgBeam ||
    
    t==DaqRunType::emcBeam ||
    t==DaqRunType::emcBeamHoldScan ||
    
    t==DaqRunType::ahcBeam ||
    t==DaqRunType::ahcBeamHoldScan ||
    t==DaqRunType::ahcBeamStage ||
    t==DaqRunType::ahcBeamStageScan ||
    
    t==DaqRunType::dhcBeam ||
    
    t==DaqRunType::tcmBeam ||
    t==DaqRunType::tcmBeamHoldScan ||
    
    t==DaqRunType::bmlBeam ||
    
    t==DaqRunType::beamTest ||
    t==DaqRunType::beamNoise ||
    t==DaqRunType::beamData ||
    t==DaqRunType::beamHoldScan ||
    t==DaqRunType::beamStage ||
    t==DaqRunType::beamStageScan ||

    t==DaqRunType::sceBeam ||
    t==DaqRunType::sceBeamHoldScan ||
    t==DaqRunType::sceBeamStage ||
    t==DaqRunType::sceBeamStageScan ||

    t==DaqRunType::dheBeam;
}

bool DaqRunType::cosmicsType() const {
  Type t(type());
  return
    t==DaqRunType::trgCosmics ||
    
    t==DaqRunType::emcCosmics ||
    t==DaqRunType::emcCosmicsHoldScan ||
    
    t==DaqRunType::ahcCosmics ||
    t==DaqRunType::ahcCosmicsHoldScan ||
    
    t==DaqRunType::dhcCosmics ||
    
    t==DaqRunType::tcmCosmics ||
    t==DaqRunType::tcmCosmicsHoldScan ||
    
    t==DaqRunType::cosmicsTest ||
    t==DaqRunType::cosmicsNoise ||
    t==DaqRunType::cosmicsData ||
    t==DaqRunType::cosmicsHoldScan ||
    
    t==DaqRunType::sceCosmics ||
    t==DaqRunType::sceCosmicsHoldScan ||

    t==DaqRunType::dheCosmics;
}

void DaqRunType::dumpTypes(const std::string &f) {
  std::ofstream fout(f.c_str());
  if(fout) {
 
    for(unsigned t(0);t<endOfTypeEnum;t++) {
      if(knownType((Type)t)) {
        fout << std::setw( 3) << t
             << std::setw( 8) << _majorTypeName[t>>4]
             << std::setw(24) << _typeName[t]
             << std::setw( 6) << (unsigned)_defaultVersion[t] << std::endl;
      }
    }
 
    fout.close();
  }
}

std::ostream& DaqRunType::print(std::ostream &o, std::string s) const {
  o << s << "DaqRunType::print()" << std::endl;

  o << s << " Data = " << printHex(_data) << std::endl;

  o << s << "  Type    = " << std::setw(3) << type()
    << " = " << typeName();
  if(beamType()) o << " = beam type";
  if(cosmicsType()) o << " = cosmics type";
  o << ", Major type = " << std::setw(3) << majorType()
    << " = " << majorTypeName() << std::endl;

  o << s << "  Version = " << std::setw(5) << (unsigned)version()
    << " (default = " << std::setw(5) << (unsigned)defaultVersion() << ")";
  o << ", Print level = " << std::setw(3) << (unsigned)printLevel() << std::endl;

  o << s << "  Switches  = " << printHex(switches()) << std::endl;

  if(majorType()!=slow) {
    //o << s << "   Data run" << std::endl;
    if(bufferRun()) {
      o << s << "   Buffering data run" << std::endl;
      if(burstRun())    o << s << "   Multi-trigger burst run" << std::endl;
      else              o << s << "   Single trigger run" << std::endl;
      //if(transferRun()) o << s << "   Multi-event transfer run" << std::endl;
      //else              o << s << "   Single-event transfer run" << std::endl;
    } else {
      o << s << "   Single event data run" << std::endl;
    }
  } else {
    o << s << "   Slow monitoring run" << std::endl;
  }

  if(writeRun()) {
    //o << s << "   Write run" << std::endl;
    if(ascWriteRun()) o << s << "   Ascii write run" << std::endl;
    else              o << s << "   Binary write run" << std::endl;
  } else {
    o << s << "   Dummy write run" << std::endl;
  }

  if(endlessRun()) o << s << "   Endless run enabled" << std::endl;
  else             o << s << "   Endless run disabled" << std::endl;

  if(histogramRun()) o << s << "   Histogram filling enabled" << std::endl;
  else               o << s << "   Histogram filling disabled" << std::endl;

  return o;
}

const std::string DaqRunType::_majorTypeName[]={
  "daq",
  "crc",
  "trg",
  "emc",
  "ahc",
  "ahc",
  "dhc",
  "tcm",
  "bml",
  "slow",
  "beam",
  "cosmics",
  "sce",
  "sce",
  "dhe"
};

const std::string DaqRunType::_typeName[]={
  "daqTest",
  "unknown","unknown","unknown","unknown","unknown",
  "unknown","unknown","unknown","unknown","unknown",
  "unknown","unknown","unknown","unknown","unknown",

  "crcTest",
  "crcNoise",
  "crcBeParameters",
  "crcFeParameters",
  "crcIntDac",
  "crcIntDacScan",
  "crcExtDac",
  "crcExtDacScan",
  "crcFakeEvent",
  "crcModeTest",
  "unknown",
  "unknown","unknown","unknown","unknown","unknown",

  "trgTest",
  "trgReadout",
  "trgParameters",
  "trgNoise",
  "trgSpill",
  "trgBeam",
  "trgCosmics",
  "unknown","unknown","unknown","unknown",
  "unknown","unknown","unknown","unknown","unknown",
  
  "emcTest",
  "emcNoise",
  "emcFeParameters",
  "emcVfeDac",
  "emcVfeDacScan",
  "emcVfeHoldScan",
  "emcTrgTiming",
  "emcTrgTimingScan",
  "emcBeam",
  "emcBeamHoldScan",
  "emcCosmics",
  "emcCosmicsHoldScan",
  "unknown","unknown","unknown","unknown",

  "ahcTest",
  "ahcDacScan",
  "ahcCmNoise",
  "ahcPmNoise",
  "ahcAnalogOut",
  "ahcCmAsic",
  "ahcCmAsicVcalibScan",
  "ahcCmAsicHoldScan",
  "ahcPmAsic",
  "ahcPmAsicVcalibScan",
  "ahcPmAsicHoldScan",
  "ahcCmLed",
  "ahcCmLedVcalibScan",
  "ahcCmLedHoldScan",
  "ahcPmLed",
  "ahcPmLedVcalibScan",

  "ahcPmLedHoldScan",
  "ahcScintillatorHoldScan",
  "ahcBeam",
  "ahcBeamHoldScan",
  "ahcBeamStage",
  "ahcBeamStageScan",
  "ahcCosmics",
  "ahcCosmicsHoldScan",
  "ahcExpert",
  "ahcGain",
  "unknown",
  "unknown","unknown","unknown","unknown","unknown",

  "dhcTest",
  "dhcNoise",
  "dhcBeam",
  "dhcCosmics",
  "dhcQinj",
  "dhcQinjScan",
  "unknown","unknown","unknown","unknown","unknown",
  "unknown","unknown","unknown","unknown","unknown",

  "tcmTest",
  "tcmNoise",
  "tcmBeam",
  "tcmBeamHoldScan",
  "tcmCalLed",
  "tcmPhysLed",
  "tcmCalPedestal",
  "tcmPhysPedestal",
  "tcmCosmics",
  "tcmCosmicsHoldScan",
  "unknown",
  "unknown","unknown","unknown","unknown","unknown",

  "bmlTest",
  "bmlNoise",
  "bmlInternalTest",
  "bmlBeam",
  "unknown","unknown",
  "unknown","unknown","unknown","unknown","unknown",
  "unknown","unknown","unknown","unknown","unknown",

  "slowTest",
  "slowMonitor",
  "unknown","unknown","unknown","unknown",
  "unknown","unknown","unknown","unknown","unknown",
  "unknown","unknown","unknown","unknown","unknown",

  "beamTest",
  "beamNoise",
  "beamData",
  "beamHoldScan",
  "beamStage",
  "beamStageScan",
  "unknown","unknown","unknown","unknown","unknown",
  "unknown","unknown","unknown","unknown","unknown",

  "cosmicsTest",
  "cosmicsNoise",
  "cosmicsData",
  "cosmicsHoldScan",
  "unknown","unknown",
  "unknown","unknown","unknown","unknown","unknown",
  "unknown","unknown","unknown","unknown","unknown",

  "sceTest",
  "sceDacScan",
  "sceCmNoise",
  "scePmNoise",
  "sceAnalogOut",
  "sceCmAsic",
  "sceCmAsicVcalibScan",
  "sceCmAsicHoldScan",
  "scePmAsic",
  "scePmAsicVcalibScan",
  "scePmAsicHoldScan",
  "sceCmLed",
  "sceCmLedVcalibScan",
  "sceCmLedHoldScan",
  "scePmLed",
  "scePmLedVcalibScan",

  "scePmLedHoldScan",
  "sceScintillatorHoldScan",
  "sceBeam",
  "sceBeamHoldScan",
  "sceBeamStage",
  "sceBeamStageScan",
  "sceCosmics",
  "sceCosmicsHoldScan",
  "sceExpert",
  "sceGain",
  "unknown",
  "unknown","unknown","unknown","unknown","unknown",

  "dheTest",
  "dheNoise",
  "dheBeam",
  "dheCosmics",
};

const unsigned char DaqRunType::_defaultVersion[]={
  // daq
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  // crc
  0,  5,  4,  2, 16, 63, 32, 63,  0,  0,  0,  0,  0,  0,  0,  0,
  // trg
  0, 12,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  // emc
  0,  0,  0,  4, 31, 31,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  // ahc
  0,  0,  0,  0,  1, 32, 10,255, 32, 10, 63,  0,  0,  0,  0,  0,
  0,  0, 21, 21, 21, 21,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  // dhc
  0,  0,  0,  0, 80, 18,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  // tcm
  0,  0, 13, 13,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  // bml
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  // slow
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  // beam
  0,  0, 21, 21, 21, 21,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  // cosmics
  0,  0, 13, 13,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  // sce
  0,  0,  0,  0,  1, 32, 10,255, 32, 10, 63,  0,  0,  0,  0,  0,
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  // dhe
  0,  0,  0,  0
};

const std::string DaqRunType::_typeComment[]={
  std::string("daqTest: ")+
  "Used for run type development; versions undefined",

  "unknown","unknown","unknown","unknown","unknown",
  "unknown","unknown","unknown","unknown","unknown",
  "unknown","unknown","unknown","unknown","unknown",


  std::string("crcTest: ")+
  "Used for run type development; versions undefined",

  std::string("crcNoise: ")+
  "Read out basic ADC data to find pedestals and noise\n"+
  "Version controls trigger used and data read out\n"+
  " Bits 0-1 - 0 use backplane-distributed software trigger (nyi)\n"+
  "            1 use BE software trigger\n"+
  "            2 use FE broadcast trigger\n"+
  "            3 use FE individual triggers\n"+
  " Bit    2 - Enable VME block data transfer for ADC data\n"+
  " Bits   3 - Enable readout event data for FE and event counter for BE via\n"+
  "            slow link for every event.\n"+
  " Bits 4-7 - Readout event period for VME and BE data via slow link. Readout\n"+
  "            is done only for one event in every period\n"+
  "The default is set to v=5, i.e. BE software trigger and VME block transfer\n"+
  "with no slow data readout.",

  std::string("crcBeParameters: ")+
  "Varies the BE parameters to check their effects on pedestals and noise\n"+
  "Version controls which parameter is varied and how long to run for\n"+
  " Bits 0-6 - Parameter to be varied:\n"+
  "             0 Trigger select, 0-255 in steps of 1\n"+
  "             1 Mode, 0-255 in steps of 1\n"+
  "             2 Readout control, 0-255 in steps of 1\n"+
  "             3 Run control, 0-255 in steps of 1\n"+
  "             4 FE data enable, 0-255 in steps of 1\n"+
  "             5 DAQ identifier,0-4095 in steps of 1\n"+
  "             6 QDR address, 0-3 in steps of 1\n"+
  "             7 FE trigger enable, 0-255 in steps of 1\n"+
  "             8 J0 enables, 0-3 in steps of 1, bit 0 trg, bit 1 bypass\n"+
  "             9 Test value, 0-65535 in steps of 1\n"+
  "            10 Test length, 0-65535 in steps of 1\n"+
  " Bit    7 - Enable infinite repeating loop over parameter values\n"+
  "Default is v=4, i.e. enabling various FEs for ADC data readout",

  std::string("crcFeParameters: ")+
  "Varies the BE parameters to check their effects on pedestals and noise\n"+
  "Version controls which parameter is varied and how long to run for\n"+
  " Bits 0-6 - Parameter to be varied:\n"+
  "             0 HOLD width, incremented from defaul by 0,3 in steps of 1\n"+
  "             1 HOLD width set differently on FEs\n"+
  "             2 ADC start and stop times; set equal, 0-17 in steps of 1\n"+
  "             3 ADC delay, 0-31 in steps of 1\n"+
  "             4 FrameSyncOut delay, 0-31 in steps of 1\n"+
  "             5 QDR (ReadoutSync) data delay, 0-15 in steps of 1\n"+
  "             6 VFE control line counters, 0-127 combinations\n"+
  " Bit    7 - Enable infinite repeating loop over parameter values\n"+
  "Default is v=2, i.e. ADC start and stop time variation",

  std::string("crcIntDac: ")+
  "Turns on the on-CRC DACs and loops them back internally to the ADCs\n"+
  "Version controls the DAC value and which DACs are used\n"+
  " Bits 0-5 - 1024*value gives DAC setting, range 0-64512\n"+
  " Bit    6 - Set bot/boardA DAC to zero\n"+
  " Bit    7 - Set top/boardB DAC to zero\n"+
  "Default is v=32, i.e. both DACs at half scale",

  std::string("crcIntDacScan: ")+
  "Turns on the on-CRC DACs, loops them back internally and scans the value\n"+
  "A configuration with the DACs disabled is taken at the beginning and end\n"+
  "The bot/top DACs alternate on/off with the intermediate configurations\n"+
  "Version controls the number of steps over the DAC range 0-65535\n"+
  "The number of steps for each of the bot and top DACs is v+1, with the\n"+
  "step size therefore being 65536/(v+1)\n"+
  "The default value is v=63, i.e. 64 steps for each DAC, each 1024",

  std::string("crcExtDac: ")+
  "Turns on the on-CRC DACs and sends them out on the front connector\n"+
  "Version controls the DAC value and which DACs are used\n"+
  " Bits 0-5 - 1024*value gives DAC setting, range 0-64512\n"+
  " Bit    6 - Set bot/boardA DAC to zero\n"+
  " Bit    7 - Set top/boardB DAC to zero\n"+
  "Default is v=32, i.e. both DACs at half scale",

  std::string("crcExtDacScan: ")+
  "Turns on the on-CRC DACs on the front connector and scans their values\n"+
  "The bot/top DACs alternate on/off with the intermediate configurations\n"+
  "Version controls the number of steps over the DAC range 0-65535\n"+
  "The number of steps for each of the bot and top DACs is v+1, with the\n"+
  "step size therefore being 65536/(v+1)\n"+
  "The default value is v=63, i.e. 64 steps for each DAC, each 1024",

  std::string("crcFakeEvent: ")+
  "Loads data patterns into the FE FIFO memory to play back through the ADC\n"+
  "data path. Not yet implemented.",

  std::string("crcModeTest: ")+
  "Tests the BE memory storage size. The first set of configurations have\n"+
  "a large number of small events, the second set have a small number of\n"+
  "large events and the third set have a large number of nominal size events.\n"+
  "Version controls trigger used and data read out\n"+
  " Bits 0-1 - 0 use backplane-distributed software trigger (nyi)\n"+
  "            1 use BE software trigger\n"+
  "            2 use FE broadcast trigger\n"+
  "            3 use FE individual triggers\n"+
  " Bit    2 - Enable VME block data transfer for ADC data\n"+
  " Bits   3 - Enable readout event data for FE and event counter for BE via\n"+
  "            slow link for every event.\n"+
  " Bits 4-7 - Readout event period for VME and BE data via slow link. Readout\n"+
  "            is done only for one event in every period\n"+
  "The default is set to v=5, i.e. BE software trigger and VME block transfer\n"+
  "with no slow data readout.",

  "unknown",
  "unknown","unknown","unknown","unknown","unknown",


  std::string("trgTest: ")+
  "Used for run type development; versions undefined",

  std::string("trgReadout: ")+
  "Under development; not yet implemented.",

  std::string("trgParameters: ")+
  "Under development; not yet implemented.",

  std::string("trgNoise: ")+
  "Under development; not yet implemented.",

  std::string("trgSpill: ")+
  "Under development; not yet implemented.",

  "trgBeam",
  "trgCosmics",
  "unknown","unknown","unknown","unknown",
  "unknown","unknown","unknown","unknown","unknown",


  std::string("emcTest: ")+
  "Used for run type development; versions undefined",

  std::string("emcNoise: ")+
  "Read out pedestals and noise with VFE settings for ECAL\n"+
  "Version controls gain used and numbers of events\n"+
  " Bit    0 - Enable high gain (x8) for bot\n"+
  "        1 - Enable high gain (x8) for top\n"+
  " Bits 2-6 - Unused\n"+
  " Bit    7 - Reduce acquisition (i.e. refresh) rate to 100 events\n"+
  "Default is v=0, i.e. low gain (x1) and full acquisition ",

  std::string("emcFeParameters: ")+
  "Under development; not yet implemented.",

  std::string("emcVfeDac: ")+
  "Turns on on-CRC DACs and enables one (of six) VFE PCB calibration groups\n"+
  "Version controls DACs, calibration groups and DAC value\n"+
  " Bits 0-2 - 8192*value gives DAC setting, range 0-57344\n"+
  " Bits 3-5 - Group number 0-5; 6 or 7 does not enable any group\n"+
  " Bit    6 - Set bot DAC value to zero\n"+
  " Bit    7 - Set top DAC value to zero\n"+
  "Default is v=4, i.e. DAC value at half range for group 0 on bot and top",

  std::string("emcVfeDacScan: ")+
  "Scans both on-CRC DACs for all VFE PCB calibration groups\n"+
  "Configurations with the calibration pulse disabled and with it enabled\n"+
  "but no groups enabled are done at the beginning and end. In between,\n"+
  "configurations loop over the six groups.\n"+
  "Version controls the number of steps over the DAC range 0-65535\n"+
  "The number of steps for each of combination is v+1, with the step size\n"+
  "therefore being 65536/(v+1)\n"+
  "The default value is v=31, i.e. 32 steps for each DAC, each 2048",

  std::string("emcVfeHoldScan: ")+
  "Scans HOLD for both on-CRC DACs for all VFE PCB calibration groups\n"+
  "Configurations with the calibration pulse disabled and with it enabled\n"+
  "but no groups enabled are done at the beginning and end. In between,\n"+
  "configurations loop over the six groups.\n"+
  "Version controls the number of steps over the HOLD range of 0-256.\n"+
  "The number of steps for each combination is v+1, with the step size\n"+
  "therefore being 256/(v+1)\n"+
  "The default value is v=31, i.e. 32 steps for each combination, each 8 = 50ns",

  std::string("emcTrgTiming: ")+
  "Triggers with oscillator to give adjustable trigger rates\n"+
  "Version controls trigger rate and number of channels\n"+
  " Bits 0-4 - 2^value gives oscillator period in units of 25ns\n"+
  " Bits 5-6 - Unused\n"+
  " Bit    7 - Enable 18 channel readout, otherwise 19",

  std::string("emcTrgTimingScan: ")+
  "Scans oscillator period to vary trigger rate. Configurations alternate\n"+
  "between 18 and 19 channel raedout and increment the oscillator period\n"+
  "by a factor of two after each pair. Version is unused.",
  
  "emcBeam",
  "emcBeamHoldScan",
  "emcCosmics",
  "emcCosmicsHoldScan",
  "unknown","unknown","unknown","unknown",


  std::string("ahcTest: ")+
  "Used for run type development; versions undefined",

  std::string("ahcDacScan: ")+
  "Scans HAB DACs around their nominal values\n"+
  "  Configuration 0 - nominal\n"+
  "  Configuration 1 - nominal+1\n"+
  "  Configuration 2 - nominal-1\n"+
  "  Configuration 3 - nominal+2\n"+
  "  Configuration 4 - nominal-2\n"+
  "  Configuration 5 - nominal+3, etc\n"+
  "Run end resets DACs to nominal value\n"+
  "Version number gives maximum difference from nominal, so v=0 does\n"+
  "DAC reset only, i.e. 1 configuration, v=1 does 3 configurations, etc.",

  std::string("ahcCmNoise: ")+
  "Read out pedestals and noise in calib mode\n"+
  "Version controls trigger used and data read out\n"+
  " Bits 0-1 - 0 use backplane-distributed software trigger\n"+
  "            1 use BE software trigger\n"+
  "            2 use FE broadcast trigger\n"+
  "            3 use FE individual triggers\n"+
  " Bit    2 - Enable VME block data transfer for ADC data\n"+
  " Bits 3-7 - Readout event period for VME, FE and BE trigger data via slow\n"+
  "            link. Readout is done only for one event in every period.\n"+
  "            A value of zero means never read these data.\n"+
  "A typical use would be v=5, i.e. BE software trigger, fast ADC read and\n"+
  "no slow links reads.",

  std::string("ahcPmNoise: ")+
  "Read out with no signals in physics mode\n"+
  "Version is the same as for ahcCmNoise",

  std::string("ahcAnalogOut: ")+
  "Inhibit HOLD and allow partial multiplex sequence to see analogue\n"+
  "output of single channel. Tcalib, Vcalib and LEDs are enabled.\n"+
  "Version controls channel number and mode\n"+
  " Bits 0-4 - Channel number\n"+
  " Bit  5-6 - Unused\n"+
  " Bit    7 - 0 is calib mode, 1 is physics mode",

  std::string("ahcCmAsic: ")+
  "Reads out ASIC calibration signals in calib mode\n"+
  "Version controls Vcalib value\n"+
  " Bits 0-5 - 64*value gives Vcalib DAC value; max is 4032\n"+
  " Bit    6 - Disable Vcalib to board A\n"+
  " Bit    7 - Disable Vcalib to board B",

  std::string("ahcCmAsicVcalibScan: ")+
  "Scan Vcalib to see ASIC calibration signals in calib mode\n"+
  "Configurations alternate Vcalib on boards A and B.\n"+
  "Version controls number of steps taken to cover Vcalib DAC range 0-4095.\n"+
  "The number of steps for each of board A and B is v+1, with the step\n"+
  "size therefore being 4096/(v+1)",

  std::string("ahcCmAsicHoldScan: ")+
  "Scan Hold to see ASIC calibration signals in calib mode.\n"+
  "Version controls number of steps taken to cover Hold range 0-255.\n"+
  "The number of steps is v+1, with the step size therefore being 256/(v+1)",
 
  std::string("ahcPmAsic: ")+
  "Reads out ASIC calibration signals in physics mode\n"+
  "Version controls Vcalib value\n"+
  " Bits 0-5 - 128*value gives Vcalib DAC value; max is 8064\n"+
  " Bit    6 - Disable Vcalib to board A\n"+
  " Bit    7 - Disable Vcalib to board B",

  std::string("ahcPmAsicVcalibScan: ")+
  "Scan Vcalib to see ASIC calibration signals in physics mode\n"+
  "Configurations alternate Vcalib on boards A and B.\n"+
  "Version controls number of steps taken to cover Vcalib DAC range 0-8191.\n"+
  "The number of steps for each of board A and B is v+1, with the step\n"+
  "size therefore being 8192/(v+1)",

  std::string("ahcPmAsicHoldScan: ")+
  "Scan Hold to see ASIC calibration signals in physics mode.\n"+
  "Version controls number of steps taken to cover Hold range 0-511.\n"+
  "The number of steps is v+1, with the step size therefore being 512/(v+1)",

  std::string("ahcCmLed: ")+
  "Reads out LED calibration signals in calib mode\n"+
  "Version gives Vcalib DAC value as 256*v; max is 65280",

  std::string("ahcCmLedVcalibScan: ")+
  "Scan Vcalib to see LED calibration signals in calib mode\n"+
  "Version controls number of steps taken to cover Vcalib DAC range 0-65535.\n"+
  "The number of steps is v+1, with the step size therefore being 65536/(v+1)",

  std::string("ahcCmLedHoldScan: ")+
  "Scan Hold to see LED calibration signals in calib mode.\n"+
  "Version controls number of steps of size 1 taken above a Hold of 70\n"+
  "so the Hold range is 70 to 70+v inclusive",

  std::string("ahcPmLed: ")+
  "Reads out LED calibration signals in physics mode\n"+
  "Version gives Vcalib DAC value as 256*v; max is 65280",

  std::string("ahcPmLedVcalibScan: ")+
  "Scan Vcalib to see LED calibration signals in physics mode\n"+
  "Version controls number of steps taken to cover Vcalib DAC range 0-65535.\n"+
  "The number of steps is v+1, with the step size therefore being 65536/(v+1)",

  std::string("ahcPmLedHoldScan: ")+
  "Scan Hold to see LED calibration signals in physics mode.\n"+
  "Version controls number of steps of size 2 taken above a Hold of 70\n"+
  "so the Hold range is 70 to 70+2*v inclusive",

  std::string("ahcScintillatorHoldScan: ")+
  "Scan the Hold while pulsing the LEDs in the scintillator trigger as\n"+
  "well as the detector. The version number is used to select the trigger\n"+
  " Version v <16 - Use trigger input v on backplane",

  std::string("ahcBeam: ")+
  "All beam and cosmics runs use the version number to control the trigger\n"+
  "used during the data taking configuration (every third configuration).\n"+
  " Version v <16 - Use trigger input v on backplane\n"+
  "         v=255 - Use oscillator trigger as test",

  std::string("ahcBeamHoldScan: ")+
  "All beam and cosmics runs use the version number to control the trigger\n"+
  "used during the data taking configuration (every third configuration).\n"+
  " Version v <16 - Use trigger input v on backplane\n"+
  "         v=255 - Use oscillator trigger as test",

  std::string("ahcBeamStage: ")+
  "All beam and cosmics runs use the version number to control the trigger\n"+
  "used during the data taking configuration (every third configuration).\n"+
  " Version v <16 - Use trigger input v on backplane\n"+
  "         v=255 - Use oscillator trigger as test",

  std::string("ahcBeamStageScan: ")+
  "All beam and cosmics runs use the version number to control the trigger\n"+
  "used during the data taking configuration (every third configuration).\n"+
  " Version v <16 - Use trigger input v on backplane\n"+
  "         v=255 - Use oscillator trigger as test",

  std::string("ahcCosmics: ")+
  "All beam and cosmics runs use the version number to control the trigger\n"+
  "used during the data taking configuration (every third configuration).\n"+
  " Version v <16 - Use trigger input v on backplane\n"+
  "         v=255 - Use oscillator trigger as test",

  std::string("ahcCosmicsHoldScan: ")+
  "All beam and cosmics runs use the version number to control the trigger\n"+
  "used during the data taking configuration (every third configuration).\n"+
  " Version v <16 - Use trigger input v on backplane\n"+
  "         v=255 - Use oscillator trigger as test",

  std::string("ahcExpert: ")+
  "If you dont already know, you dont want to know...",

  "ahcGain",
  "unknown",
  "unknown","unknown","unknown","unknown","unknown",


  std::string("dhcTest: ")+
  "Used for run type development; versions undefined",

  "dhcNoise",
  "dhcBeam",
  "dhcCosmics",

  std::string("dhcQinj: ")+
  "Operates the front end ASICs in charge injection mode.\n"+
  "Four configurations are run with one fourth of the channels active in each configuration.\n"+
  " Version controls the threshold value (default value=80)",

  std::string("dhcQinjScan: ")+
  "Operates the front end ASICs in charge injection mode while scanning the threshold setting.\n"+
  "For each setting, four configurations are run with one fourth of the channels active in each "+
  "configuration.\n"+
  " Version controls the number of threshold values scanned and the step size.\n"+
  " Bit  0-3 - step size, max=15\n"+
  " Bits 4-5 - number of steps*16\n",

  "unknown","unknown","unknown","unknown","unknown",
  "unknown","unknown","unknown","unknown","unknown",


  std::string("tcmTest: ")+
  "Used for run type development; versions undefined",

  std::string("tcmNoise: ")+
  "Basic ADC data readout.",

  std::string("tcmBeam: ")+
  "TCMT-only beam runs.",

  std::string("tcmBeamHoldScan: ")+
  "TCMT-only beam runs.",

  std::string("tcmCalLed: ")+
  "Calibrations; details unknown.",

  std::string("tcmPhysLed: ")+
  "Calibrations; details unknown.",

  std::string("tcmCalPedestal: ")+
  "Calibrations; details unknown.",

  std::string("tcmPhysPedestal: ")+
  "Calibrations; details unknown.",

  std::string("tcmCosmics: ")+
  "TCMT-only cosmics runs.",

  std::string("tcmCosmicsHoldScan: ")+
  "TCMT-only cosmics runs.",

  "unknown",
  "unknown","unknown","unknown","unknown","unknown",


  std::string("bmlTest: ")+
  "Used for run type development; versions undefined",

  std::string("bmlNoise: ")+
  "Basic readout of beam line components (TDC, etc) only",

  std::string("bmlInternalTest: ")+
  "Runs LC1176 TDC in internal test mode to generate hit patterns",

  "bmlBeam",
  "unknown","unknown",
  "unknown","unknown","unknown","unknown","unknown",
  "unknown","unknown","unknown","unknown","unknown",


  std::string("slowTest: ")+
  "Used for run type development; versions undefined",

  "slowMonitor",
  "unknown","unknown","unknown","unknown",
  "unknown","unknown","unknown","unknown","unknown",
  "unknown","unknown","unknown","unknown","unknown",

  std::string("beamTest: ")+
  "Used for run type development; versions undefined",

  std::string("beamNoise: ")+
  "All beam and cosmics runs use the version number to control the trigger\n"+
  "used during the data taking configuration (every third configuration)\n"+
  " Bits 0-6 - Unused\n"+
  " Bit    7 - 0 use real trigger\n"+
  "	     1 use oscillator trigger",

  std::string("beamData: ")+
  "All beam and cosmics runs use the version number to control the trigger\n"+
  "used during the data taking configuration (every third configuration)\n"+
  " Bits 0-6 - Unused\n"+
  " Bit    7 - 0 use real trigger\n"+
  "	     1 use oscillator trigger",

  std::string("beamHoldScan: ")+
  "All beam and cosmics runs use the version number to control the trigger\n"+
  "used during the data taking configuration (every third configuration)\n"+
  " Bits 0-6 - Unused\n"+
  " Bit    7 - 0 use real trigger\n"+
  "	     1 use oscillator trigger",

  std::string("beamStage: ")+
  "All beam and cosmics runs use the version number to control the trigger\n"+
  "used during the data taking configuration (every third configuration)\n"+
  " Bits 0-6 - Unused\n"+
  " Bit    7 - 0 use real trigger\n"+
  "	     1 use oscillator trigger",

  std::string("beamStageScan: ")+
  "All beam and cosmics runs use the version number to control the trigger\n"+
  "used during the data taking configuration (every third configuration)\n"+
  " Bits 0-6 - Unused\n"+
  " Bit    7 - 0 use real trigger\n"+
  "	     1 use oscillator trigger",

  "unknown","unknown","unknown","unknown","unknown",
  "unknown","unknown","unknown","unknown","unknown",


  std::string("cosmicsTest: ")+
  "Used for run type development; versions undefined",

  std::string("cosmicsNoise: ")+
  "All beam and cosmics runs use the version number to control the trigger\n"+
  "used during the data taking configuration (every third configuration)\n"+
  " v = 0-15 - Use trigger input = v\n"+
  "      254 - Use software trigger\n"+
  "      255 - Use oscillator trigger",

  std::string("cosmicsData: ")+
  "All beam and cosmics runs use the version number to control the trigger\n"+
  "used during the data taking configuration (every third configuration)\n"+
  " v = 0-15 - Use trigger input = v\n"+
  "      254 - Use software trigger\n"+
  "      255 - Use oscillator trigger",

  std::string("cosmicsHoldScan: ")+
  "All beam and cosmics runs use the version number to control the trigger\n"+
  "used during the data taking configuration (every third configuration)\n"+
  " v = 0-15 - Use trigger input = v\n"+
  "      254 - Use software trigger\n"+
  "      255 - Use oscillator trigger",

  "unknown","unknown",
  "unknown","unknown","unknown","unknown","unknown",
  "unknown","unknown","unknown","unknown","unknown",

  "sceTest",
  "sceDacScan",
  "sceCmNoise",
  "scePmNoise",
  "sceAnalogOut",
  "sceCmAsic",
  "sceCmAsicVcalibScan",
  "sceCmAsicHoldScan",
  "scePmAsic",
  "scePmAsicVcalibScan",
  "scePmAsicHoldScan",
  "sceCmLed",
  "sceCmLedVcalibScan",
  "sceCmLedHoldScan",
  "scePmLed",
  "scePmLedVcalibScan",

  "scePmLedHoldScan",
  "sceScintillatorHoldScan",
  "sceBeam",
  "sceBeamHoldScan",
  "sceBeamStage",
  "sceBeamStageScan",
  "sceCosmics",
  "sceCosmicsHoldScan",
  "sceExpert",
  "sceGain",
  "unknown",
  "unknown","unknown","unknown","unknown","unknown",

  "dheTest",
  "dheNoise",
  "dheBeam",
  "dheCosmics"
};

#endif
#endif
