Translation table 13-jul-2011

From GlueXWiki
Jump to: navigation, search

Background

We need a prototype translation table in order for the DAQ group to create a simulated raw data file from HDDM input. We will pay the DAQ group will do this work.


Proposed Translation Table Format

<translation_table version="0.1">


  <crate number="1" type="VXS">

     <slot number="1" type="FADC250">
        <channel number="1" detector="FCAL"        row="3" column="4" />
        <channel number="2" detector="BCAL"        module="10" sector="2" layer="3" end="0" />
        <channel number="3" detector="SC"          sector="21" />
        <channel number="4" detector="Tagger"      row="24" column="2" />
        <channel number="5" detector="TOF"         plane="1" bar="6" end="1" />
     </slot>

     <slot number="2" type="FADC125" >
        <channel number="1" detector="FDCCathode"  gplane="5" element="33" />
        <channel number="2" detector="CDC"         ring="3" straw="45" />
     </slot>
      
     <slot number="3" type="F1TDC32" >
        <channel number="1" detector="TOF"         plane="2" bar="1" end="0" />
        <channel number="2" detector="Tagger"      row="42" column="10" />
        <channel number="3" detector="BCAL"        module="6" sector="1" layer="3" end="1" />
        <channel number="4" detector="SC"          sector="38" />
     </slot>
      
     <slot number="3" type="F1TDC64" >
        <channel number="1" detector="FDCAnode"    gplane="2" element="99" />
     </slot>
      
     <slot number="17" type="TI" />
     <slot number="18" type="CPU" />
      
     <switchSlot number="1" type="CTP" />
     <switchSlot number="2" type="SD" />

  </crate>


</translation_table>


Fake Table Generation

I used a Python script to generate a full translation table. It includes both ADC and TDC data for the same detector when appropriate:

detectorOn = {
   'CDC':     1,
   'FDC':     1,
   'BCAL':    1,
   'FCAL':    1,
   'SC':      1,
   'TOF':     1,
   'TAGGER':  1
   }


# SC:  FADC250, 16 channels/slot
if (detectorOn['SC']==1):
   type = 'FADC250'
   slot = slot+1
   channel = 1
   if (slot>max_slot):
       file.write('  </crate>\n\n\n')
       crate = crate+1
       file.write('  <crate number="%i"  type="VXS">\n\n' % crate)
       slot=1
   file.write(('    <slot number="%i"'  % slot) + '  type="' + type + '">\n')

   for sector in range(1,41):
       if (channel>channelCount[type]):
           file.write('    </slot>\n\n')
           slot = slot+1
           channel = 1
           if (slot>max_slot):
               file.write('  </crate>\n\n\n')
               crate = crate+1
               file.write('  <crate number="%i"  type="VXS">\n\n' % crate)
               slot = 1
           file.write(('    <slot number="%i"'  % slot) + '  type="' + type + '">\n')
       file.write('      <channel number="%i" detector="SC" sector="%i"  />\n' % (channel,sector) )
       channel = channel+1
   file.write('    </slot>\n\n')


Fragment of Table

The full table contains 33k lines, 2.3 MB raw, 134k gzipped. Note that it currently includes more entries then actually exist:


<translation_table version="0.1">

  <crate number="1"  type="VXS">

    <slot number="1"  type="FADC125">
      <channel number="1" detector="CDC" ring="1" straw="1" />
      <channel number="2" detector="CDC" ring="1" straw="2" />
      <channel number="3" detector="CDC" ring="1" straw="3" />
      <channel number="4" detector="CDC" ring="1" straw="4" />
      <channel number="5" detector="CDC" ring="1" straw="5" />
      <channel number="6" detector="CDC" ring="1" straw="6" />
      <channel number="7" detector="CDC" ring="1" straw="7" />
      <channel number="8" detector="CDC" ring="1" straw="8" />


Programmatic Usage

The rawevent plugin uses the translation as follows:

 // DTOFRawHit - FADC250 and F1TDC32 (60 ps)
 vector<const DTOFRawHit*> dtofrawhits; 
 eventLoop->Get(dtofrawhits);
 for(i=0; i<dtofrawhits.size(); i++) {
   float dE  = dtofrawhits[i]->dE;
   float t   = dtofrawhits[i]->t;

   // translate to crate/slot/channel
   cscRef cscADC  = DTOFRawHitTranslationADC(dtofrawhits[i]);
   cscRef cscTDC  = DTOFRawHitTranslationTDC(dtofrawhits[i]);

     // do something with ADC info
     int crate   = cscADC.get<0>();    // may change to different crate/slot/channel storage mechanism for efficiency
     int slot    = cscADC.get<1>();
     int channel = cscADC.get<2>();
 }


Under the Hood

The XML translation table is read in, parsed and the data is stored in cscMap using a custom string as the map key:

   // in the XML parser startElement handler:
   string s="unknown::";
   if(detector=="fcal") {
     if(type=="fadc250") {
       s = "fcaladc::";
     } else {
       s = "unknownFCAL::";
       jerr << endl << endl << "?startElement...illegal type for FCAL: " << Type << endl << endl;
     }
     s += row + ":" + column;
     cscMap[s] = csc;

The map is used internally as follows

cscRef JEventProcessor_rawevent::DFCALHitTranslationADC(const DFCALHit* hit) const {
  string s = "fcaladc::" + lexical_cast<string>(hit->row) + ":" + lexical_cast<string>(hit->column);
  return(cscMap[s]);
}


Inverse

I programmed and tested the inverse operation:

#define MAX_CRATE   58+1
#define MAX_SLOT    16+1
#define MAX_CHANNEL 72+1
static string detectorMap[MAX_CRATE][MAX_SLOT][MAX_CHANNEL];

 
 // in XML parser 
 string customString = ...;
 detectorMap[crate][slot][channel] = customString;

 ...

 // usage
 string customString = detectorMap[crate][slot][channel];   // parsing is detector-dependent


Online Usage

A reasonable scenario is for using the translation table in the Experiment Controls system is as follows:

  • Latest table is stored in database (IRMIS?). Technicians need ability to add to/modify table when they install or move cables.
  • At begin run the table is compared to most recent table stored in CCDB (ascii? gzipped?).
  • If no change, do nothing, otherwise store new table in CCDB.
  • If techs discover mistakes in the table then:
    • table must be updated
    • new version must be stored in CCDB for affected run range



Still to Do

The rawevent plugin should work for the DAQ task as it stands. Future improvements:

  • optimize storage structures since methods are used in the innermost loops
  • eliminate non-existant channels from fake translation table
  • generate real translation table according to Fernando's detector mapping/labeling strategy