Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DTranslationTable.cc
Go to the documentation of this file.
1 // $Id$
2 //
3 // File: DTranslationTable.cc
4 // Created: Thu Jun 27 16:07:11 EDT 2013
5 // Creator: davidl (on Darwin harriet.jlab.org 11.4.2 i386)
6 //
7 
8 #include "DTranslationTable.h"
9 
10 #include <expat.h>
11 #include <sstream>
12 
13 #include <DAQ/DModuleType.h>
14 #include <DAQ/JEventSource_EVIO.h>
17 
18 using namespace jana;
19 using namespace std;
20 
21 
22 // Use one translation table for all threads
23 pthread_mutex_t& DTranslationTable::Get_TT_Mutex(void) const
24 {
25  static pthread_mutex_t tt_mutex = PTHREAD_MUTEX_INITIALIZER;
26  return tt_mutex;
27 }
28 
30 {
31  static bool tt_initialized = false;
32  return tt_initialized;
33 }
34 
35 map<DTranslationTable::csc_t, DTranslationTable::DChannelInfo>& DTranslationTable::Get_TT(void) const
36 {
37  static map<DTranslationTable::csc_t, DTranslationTable::DChannelInfo> TT;
38  return TT;
39 }
40 
41 map<uint32_t, uint32_t>& DTranslationTable::Get_ROCID_Map(void) const
42 {
43  static map<uint32_t, uint32_t> rocid_map; // (see ReadOptionalROCidTranslation() for details)
44  return rocid_map;
45 }
46 
47 map<uint32_t, uint32_t>& DTranslationTable::Get_ROCID_Inv_Map(void) const
48 {
49  static map<uint32_t, uint32_t> rocid_inv_map; // (see ReadOptionalROCidTranslation() for details)
50  return rocid_inv_map;
51 }
52 
53 map<DTranslationTable::Detector_t, set<uint32_t> >& DTranslationTable::Get_ROCID_By_System(void)
54 {
55  static map<DTranslationTable::Detector_t, set<uint32_t> > rocid_by_system;
56  return rocid_by_system;
57 }
58 
59 //...................................
60 // Less than operator for csc_t data types. This is used by
61 // the map<csc_t, XX> to order the entires by key
63  if (a.rocid < b.rocid) return true;
64  if (a.rocid > b.rocid) return false;
65  if (a.slot < b.slot) return true;
66  if (a.slot > b.slot) return false;
67  if (a.channel < b.channel) return true;
68  return false;
69 }
70 
71 //...................................
72 // sort functions
73 bool SortBCALDigiHit(const DBCALDigiHit *a, const DBCALDigiHit *b) {
74  if (a->module == b->module) {
75  if (a->layer == b->layer) {
76  if (a->sector == b->sector) {
77  if (a->end == b->end) {
78  return a->pulse_time < b->pulse_time;
79  }else{ return a->end < b->end; }
80  }else{ return a->sector < b->sector; }
81  }else{ return a->layer< b->layer; }
82  }else { return a->module < b->module; }
83 }
84 
85 //---------------------------------
86 // DTranslationTable (Constructor)
87 //---------------------------------
89 {
90  // Default is to just read translation table from CCDB. If this fails,
91  // then an attempt will be made to read from a file on the local disk.
92  // The filename can be specified to be anything, but if the user specifies
93  // this, then we assume that they want to use it and skip using the CCDB.
94  // They may also specify that they want to skip checking the CCDB via
95  // the "TT:NO_CCDB" parameter. This would only be useful if they want to
96  // force the use of a local file named "tt.xml".
97  NO_CCDB = false;
98  XML_FILENAME = "tt.xml";
99  VERBOSE = 0;
100  SYSTEMS_TO_PARSE = "";
101  CALL_STACK = false;
102  gPARMS->SetDefaultParameter("TT:NO_CCDB", NO_CCDB,
103  "Don't try getting translation table from CCDB and just look"
104  " for file. Only useful if you want to force reading tt.xml."
105  " This is automatically set if you specify a different"
106  " filename via the TT:XML_FILENAME parameter.");
107  JParameter *p = gPARMS->SetDefaultParameter("TT:XML_FILENAME", XML_FILENAME,
108  "Fallback filename of translation table XML file."
109  " If set to non-default, CCDB will not be checked.");
110  if (p->GetDefault() != p->GetValue())
111  NO_CCDB = true;
112  gPARMS->SetDefaultParameter("TT:VERBOSE", VERBOSE,
113  "Verbosity level for Applying Translation Table."
114  " 0=no messages, 10=all messages.");
115 
116  ROCID_MAP_FILENAME = "rocid.map";
117  gPARMS->SetDefaultParameter("TT:ROCID_MAP_FILENAME", ROCID_MAP_FILENAME,
118  "Optional rocid to rocid conversion map for use with files"
119  " generated with the non-standard rocid's");
120 
121  gPARMS->SetDefaultParameter("TT:SYSTEMS_TO_PARSE", SYSTEMS_TO_PARSE,"This is deprecated. Please use EVIO:SYSTEMS_TO_PARSE instead.");
122 
123  gPARMS->SetDefaultParameter("TT:CALL_STACK", CALL_STACK,
124  "Set this to one to try and force correct recording of the"
125  "JANA call stack. You will want this if using the janadot"
126  "plugin, but otherwise, it will just give a slight performance"
127  "hit.");
128  if(SYSTEMS_TO_PARSE != ""){
129  jerr << "You have set the TT:SYSTEMS_TO_PARSE config. parameter." << endl;
130  jerr << "This is now deprecated. Please use EVIO:SYSTEMS_TO_PARSE" << endl;
131  jerr << "instead. Quitting now to make sure you see this message." << endl;
132  exit(-1);
133  }
134 
135  // Here we create a bunch of config. parameters to allow us to overwrite
136  // the nsamples_integral and nsamples_pedestal fields of each type of
137  // fADC digihit class. This is done using some special macros in
138  // DTranslationTable.h
139  InitNsamplesOverride();
140 
141  // Initialize dedicated JStreamLog used for debugging messages
142  ttout.SetTag("--- TT ---: ");
143  ttout.SetTimestampFlag();
144  ttout.SetThreadstampFlag();
145 
146  // Look for and read in an optional rocid <-> rocid translation table
147  ReadOptionalROCidTranslation();
148 
149  // Read in Translation table. This will create DChannelInfo objects
150  // and store them in the "TT" map, indexed by csc_t objects
151  ReadTranslationTable(loop->GetJCalibration());
152 
153  // Set up pointers to the factories for this JEventLoop.
154  // (n.b. each JEventLoop will have it's own DTranslationTable object)
155  InitFactoryPointers(loop);
156 }
157 
158 //---------------------------------
159 // ~DTranslationTable (Destructor)
160 //---------------------------------
162 {
163 
164 }
165 
166 //---------------------------------
167 // ReadOptionalROCidTranslation
168 //---------------------------------
170 {
171  // Some data may be taken with the ROC ID value set
172  // incorrectly in CODA. For CODA 3.0 data, there is
173  // actually no way to set it so it can be different
174  // for every CODA configuration. A simple work-around
175  // for this is to use a map file to list the translation
176  // from the crate numbers used in the evio file to those
177  // stored in the TT. Check here if a local file exists
178  // with the name specified by the TT:ROCID_MAP_FILENAME
179  // config parameter (default is "rocid.map"). If so,
180  // read it in. The format is just 2 values per line.
181  // The first is the rocid in the evio file, and the
182  // second, what the rocid is in the TT. Note that the
183  // value of the crate copied into the data objects
184  // will be what is in the EVIO file.
185  ifstream ifs(ROCID_MAP_FILENAME.c_str());
186  if (!ifs.is_open()) return;
187 
188  std::cout << "Opened ROC id translation map: " << ROCID_MAP_FILENAME << std::endl;
189  while (ifs.good()) {
190  char line[256];
191  ifs.getline(line, 256);
192  if (ifs.gcount() < 1) break;
193  if (line[0] == '#') continue;
194 
195  stringstream ss(line);
196  uint32_t from=10000, to=10000;
197  ss >> from >> to; // from=evio to=TT
198  if ( to == 10000 ) {
199  if ( from != 10000) {
200  std::cout << "unable to convert line:" << std::endl;
201  std::cout << " " << line;
202  }
203  }else{
204  Get_ROCID_Map()[from] = to;
205  Get_ROCID_Inv_Map()[to] = from;
206  }
207  }
208  ifs.close();
209 
210  if (Get_ROCID_Map().size() == Get_ROCID_Inv_Map().size()) {
211  std::cout << " Read " << Get_ROCID_Map().size() << " entries" << std::endl;
212  map<uint32_t,uint32_t>::iterator iter;
213  for (iter=Get_ROCID_Map().begin(); iter != Get_ROCID_Map().end(); iter++) {
214  std::cout << " rocid " << iter->first << " -> rocid "
215  << iter->second << std::endl;
216  }
217  }else{
218  std::cout << "Entries not unique! This can happen if there are"
219  << std::endl;
220  std::cout << "more than one entry with the same value (either"
221  << std::endl;
222  std::cout << "two keys or two vals the same.)"
223  << std::endl;
224  std::cout << "Please fix the file \"" << ROCID_MAP_FILENAME << "\"."
225  << std::endl;
226  exit(-1);
227  }
228 }
229 
230 //---------------------------------
231 // SetSystemsToParse
232 //---------------------------------
233 void DTranslationTable::SetSystemsToParse(string systems, JEventSource *eventsource)
234 {
235  /// This takes a string of comma separated system names and
236  /// identifies a list of Detector_t values from this (using
237  /// strings returned by DetectorName() ). It then tries to
238  /// copy the value into the DAQ plugin so they can be used
239  /// to restrict which banks to parse.
240 
241  if(systems == "") return; // nothing to do for empty strings
242  jout << "Setting systems to parse to: " << systems << endl;
243 
244  // Make sure this is a JEventSource_EVIO object pointer
245  JEventSource_EVIO *eviosource = dynamic_cast<JEventSource_EVIO* >(eventsource);
246  JEventSource_EVIOpp *evioppsource = dynamic_cast<JEventSource_EVIOpp*>(eventsource);
247  if( (!eviosource) && !(evioppsource) ) {
248  jerr << "eventsource not a JEventSource_EVIO or JEventSource_EVIOpp object! Cannot restrict parsing list!" << endl;
249  return;
250  }
251 
252  // Make map of system type id by name
253  map<string, Detector_t> name_to_id;
254  for(uint32_t dettype=UNKNOWN_DETECTOR; dettype<NUM_DETECTOR_TYPES; dettype++){
255  name_to_id[DetectorName((Detector_t)dettype)] = (Detector_t)dettype;
256  }
257 
258  // There is a chicken-egg problem of reading the ROCID assignments
259  // from the CCDB which requires a run number. The run number is
260  // not actually available though until parsing of the first event.
261  // If the current map of ROCID_By_System is empty, we hold our nose
262  // and fill it with the known map. Note that this map will be
263  // overwritten later when the XML from the CCDB is parsed. This
264  // potentially could lead to inconsistencies. The primary use for
265  // this is mostly expcted for parsing only certain systems which
266  // is a specialized operation.
267  auto &rocid_map = Get_ROCID_By_System();
268  if(rocid_map.empty()){
269  rocid_map[name_to_id[ "UNKNOWN"]] = {14, 78};
270  rocid_map[name_to_id[ "BCAL"]] = {31, 32, 33, 34, 35 ,36, 37, 38, 39, 40, 41, 42};
271  rocid_map[name_to_id[ "CDC"]] = {25, 26, 27, 28};
272  rocid_map[name_to_id[ "FCAL"]] = {11, 12, 13, 14 ,15, 16, 17, 18, 19, 20, 21, 22};
273  rocid_map[name_to_id["FDC_CATHODES"]] = {52, 53, 55, 56, 57, 58, 59, 60, 61, 62};
274  rocid_map[name_to_id[ "FDC_WIRES"]] = {51, 54, 63, 64};
275  rocid_map[name_to_id[ "PS"]] = {83, 84};
276  rocid_map[name_to_id[ "PSC"]] = {84, 95};
277  rocid_map[name_to_id[ "RF"]] = {51, 73, 75, 78, 94, 95};
278  rocid_map[name_to_id[ "SC"]] = {94, 95};
279  rocid_map[name_to_id[ "TAGH"]] = {73, 75};
280  rocid_map[name_to_id[ "TAGM"]] = {71, 75};
281  rocid_map[name_to_id[ "TOF"]] = {77, 78};
282  rocid_map[name_to_id[ "TPOL"]] = {84};
283  rocid_map[name_to_id[ "TAC"]] = {14, 78};
284  rocid_map[name_to_id[ "CCAL"]] = {90};
285  rocid_map[name_to_id[ "CCAL_REF"]] = {90};
286  rocid_map[name_to_id[ "DIRC"]] = {92};
287 
288  }
289 
290  // Parse string of system names
291  std::istringstream ss(systems);
292  std::string token;
293  while(std::getline(ss, token, ',')) {
294 
295  // Get initial list of rocids based on token
296  set<uint32_t> rocids = rocid_map[name_to_id[token]];
297 
298  // Let "FDC" be an alias for both cathode strips and wires
299  if(token == "FDC"){
300  set<uint32_t> rocids1 = rocid_map[name_to_id["FDC_CATHODES"]];
301  set<uint32_t> rocids2 = rocid_map[name_to_id["FDC_WIRES"]];
302  rocids.insert(rocids1.begin(), rocids1.end());
303  rocids.insert(rocids2.begin(), rocids2.end());
304  }
305 
306  // More likely than not, someone specifying "PS" will also want "PSC"
307  if(token == "PS"){
308  set<uint32_t> rocids1 = rocid_map[name_to_id["PSC"]];
309  rocids.insert(rocids1.begin(), rocids1.end());
310  }
311 
312  set<uint32_t>::iterator it;
313  for(it=rocids.begin(); it!=rocids.end(); it++){
314 
315  // Add this rocid to the DAQ parsing list
316  uint32_t rocid = *it;
317  if(eviosource ) eviosource->AddROCIDtoParseList(rocid);
318  if(evioppsource) evioppsource->AddROCIDtoParseList(rocid);
319  jout << " Added rocid " << rocid << " for system " << token << " to parse list" << endl;
320  }
321  }
322 
323 }
324 
325 //---------------------------------
326 // ApplyTranslationTable
327 //---------------------------------
328 void DTranslationTable::ApplyTranslationTable(JEventLoop *loop) const
329 {
330  /// This will get all of the low level objects and
331  /// generate detector hit objects from them, placing
332  /// them in the appropriate DANA factories.
333 
334  if (VERBOSE > 2) ttout << "Entering ApplyTranslationTable:" << std::endl;
335 
336  // Clear our internal vectors of pointers from previous event
337  ClearVectors();
338 
339  // If the JANA call stack is being recorded, then temporarily disable it
340  // so calls we make to loop->Get() here are ignored. The reason we do this
341  // is because this routine is called while already in a loop->Get() call
342  // so JANA will treat all other loop->Get() calls we make as being dependencies
343  // of the loop->Get() call that we are already in. (Confusing eh?)
344  bool record_call_stack = loop->GetCallStackRecordingStatus();
345  if (record_call_stack) loop->DisableCallStackRecording();
346 
347  // Df250PulseIntegral (will apply Df250PulseTime via associated objects)
348  vector<const Df250PulseIntegral*> pulseintegrals250;
349  loop->Get(pulseintegrals250);
350  if (VERBOSE > 2) ttout << " Number Df250PulseIntegral objects: " << pulseintegrals250.size() << std::endl;
351  for (uint32_t i=0; i<pulseintegrals250.size(); i++) {
352  const Df250PulseIntegral *pi = pulseintegrals250[i];
353 
354  // Apply optional rocid translation
355  uint32_t rocid = pi->rocid;
356  map<uint32_t, uint32_t>::iterator rocid_iter = Get_ROCID_Map().find(rocid);
357  if (rocid_iter != Get_ROCID_Map().end()) rocid = rocid_iter->second;
358 
359  if (VERBOSE > 4)
360  ttout << " Looking for rocid:" << rocid << " slot:" << pi->slot
361  << " chan:" << pi->channel << std::endl;
362 
363  // Create crate,slot,channel index and find entry in Translation table.
364  // If none is found, then just quietly skip this hit.
365  csc_t csc = {rocid, pi->slot, pi->channel};
366  map<csc_t, DChannelInfo>::const_iterator iter = Get_TT().find(csc);
367  if (iter == Get_TT().end()) {
368  if (VERBOSE > 6)
369  ttout << " - Didn't find it" << std::endl;
370  continue;
371  }
372  const DChannelInfo &chaninfo = iter->second;
373  if (VERBOSE > 6)
374  ttout << " - Found entry for: " << DetectorName(chaninfo.det_sys)
375  << std::endl;
376 
377  // Check for a pulse time (this should have been added in JEventSource_EVIO.cc)
378  const Df250PulseTime *pt = NULL;
379  const Df250PulsePedestal *pp = NULL;
380  pi->GetSingle(pt);
381  pi->GetSingle(pp);
382 
383  // Avoid f250 Error with extra PulseIntegral word
384  if( pt == NULL || pp == NULL) continue;
385 
386  // Create the appropriate hit type based on detector type
387  switch (chaninfo.det_sys) {
388  case BCAL: MakeBCALDigiHit(chaninfo.bcal, pi, pt, pp); break;
389  case FCAL: MakeFCALDigiHit(chaninfo.fcal, pi, pt, pp); break;
390  case CCAL: MakeCCALDigiHit(chaninfo.ccal, pi, pt, pp); break;
391  case CCAL_REF: MakeCCALRefDigiHit(chaninfo.ccal_ref, pi, pt, pp); break;
392  case SC: MakeSCDigiHit( chaninfo.sc, pi, pt, pp); break;
393  case TOF: MakeTOFDigiHit( chaninfo.tof, pi, pt, pp); break;
394  case TAGM: MakeTAGMDigiHit(chaninfo.tagm, pi, pt, pp); break;
395  case TAGH: MakeTAGHDigiHit(chaninfo.tagh, pi, pt, pp); break;
396  case PS: MakePSDigiHit(chaninfo.ps, pi, pt, pp); break;
397  case PSC: MakePSCDigiHit(chaninfo.psc, pi, pt, pp); break;
398  case RF: MakeRFDigiTime(chaninfo.rf, pt); break;
399  case TPOLSECTOR: MakeTPOLSectorDigiHit(chaninfo.tpolsector, pi, pt, pp); break;
400  case TAC: MakeTACDigiHit(chaninfo.tac, pi, pt, pp); break;
401 
402  default:
403  if (VERBOSE > 4) ttout << " - Don't know how to make DigiHit objects for this detector type!" << std::endl;
404  break;
405  }
406  }
407 
408  // Df250PulseData
409  vector<const Df250PulseData*> pulsedatas250;
410  loop->Get(pulsedatas250);
411  if (VERBOSE > 2) ttout << " Number Df250PulseData objects: " << pulsedatas250.size() << std::endl;
412  for(auto pd : pulsedatas250){
413 
414  // Apply optional rocid translation
415  uint32_t rocid = pd->rocid;
416  map<uint32_t, uint32_t>::iterator rocid_iter = Get_ROCID_Map().find(rocid);
417  if (rocid_iter != Get_ROCID_Map().end()) rocid = rocid_iter->second;
418 
419  if (VERBOSE > 4) ttout << " Looking for rocid:" << rocid << " slot:" << pd->slot << " chan:" << pd->channel << std::endl;
420 
421  // Create crate,slot,channel index and find entry in Translation table.
422  // If none is found, then just quietly skip this hit.
423  csc_t csc = {rocid, pd->slot, pd->channel};
424  map<csc_t, DChannelInfo>::const_iterator iter = Get_TT().find(csc);
425  if (iter == Get_TT().end()) {
426  if (VERBOSE > 6) ttout << " - Didn't find it" << std::endl;
427  continue;
428  }
429  const DChannelInfo &chaninfo = iter->second;
430  if (VERBOSE > 6) ttout << " - Found entry for: " << DetectorName(chaninfo.det_sys) << std::endl;
431 
432  // Create the appropriate hit type based on detector type
433  switch (chaninfo.det_sys) {
434  case BCAL: MakeBCALDigiHit( chaninfo.bcal, pd); break;
435  case FCAL: MakeFCALDigiHit( chaninfo.fcal, pd); break;
436  case CCAL: MakeCCALDigiHit( chaninfo.ccal, pd); break;
437  case CCAL_REF: MakeCCALRefDigiHit( chaninfo.ccal_ref, pd); break;
438  case SC: MakeSCDigiHit( chaninfo.sc, pd); break;
439  case TOF: MakeTOFDigiHit( chaninfo.tof, pd); break;
440  case TAGM: MakeTAGMDigiHit( chaninfo.tagm, pd); break;
441  case TAGH: MakeTAGHDigiHit( chaninfo.tagh, pd); break;
442  case PS: MakePSDigiHit( chaninfo.ps, pd); break;
443  case PSC: MakePSCDigiHit( chaninfo.psc, pd); break;
444  case RF: MakeRFDigiTime( chaninfo.rf, pd); break;
445  case TPOLSECTOR: MakeTPOLSectorDigiHit(chaninfo.tpolsector, pd); break;
446  case TAC: MakeTACDigiHit(chaninfo.tac, pd); break;
447  default:
448  if (VERBOSE > 4) ttout << " - Don't know how to make DigiHit objects for this detector type!" << std::endl;
449  break;
450  }
451  }
452 
453  // Df125PulseIntegral (will apply Df125PulseTime via associated objects)
454  vector<const Df125PulseIntegral*> pulseintegrals125;
455  loop->Get(pulseintegrals125);
456  if (VERBOSE > 2) ttout << " Number Df125PulseIntegral objects: " << pulseintegrals125.size() << std::endl;
457  for (uint32_t i=0; i<pulseintegrals125.size(); i++) {
458  const Df125PulseIntegral *pi = pulseintegrals125[i];
459 
460  // Apply optional rocid translation
461  uint32_t rocid = pi->rocid;
462  map<uint32_t, uint32_t>::iterator rocid_iter = Get_ROCID_Map().find(rocid);
463  if (rocid_iter != Get_ROCID_Map().end()) rocid = rocid_iter->second;
464 
465  if (VERBOSE > 4)
466  ttout << " Looking for rocid:" << rocid << " slot:" << pi->slot
467  << " chan:" << pi->channel << std::endl;
468 
469  // Create crate,slot,channel index and find entry in Translation table.
470  // If none is found, then just quietly skip this hit.
471  csc_t csc = {rocid, pi->slot, pi->channel};
472  map<csc_t, DChannelInfo>::const_iterator iter = Get_TT().find(csc);
473  if (iter == Get_TT().end()) {
474  if (VERBOSE > 6)
475  ttout << " - Didn't find it" << std::endl;
476  continue;
477  }
478  const DChannelInfo &chaninfo = iter->second;
479  if (VERBOSE > 6)
480  ttout << " - Found entry for: " << DetectorName(chaninfo.det_sys)
481  << std::endl;
482 
483  // Check for a pulse time (this should have been added in JEventSource_EVIO.cc
484  const Df125PulseTime *pt = NULL;
485  const Df125PulsePedestal *pp = NULL;
486  pi->GetSingle(pt);
487  pi->GetSingle(pp);
488 
489  // Create the appropriate hit type based on detector type
490  switch (chaninfo.det_sys) {
491  case CDC: MakeCDCDigiHit(chaninfo.cdc, pi, pt, pp); break;
492  case FDC_CATHODES: MakeFDCCathodeDigiHit(chaninfo.fdc_cathodes, pi, pt, pp); break;
493  default:
494  if (VERBOSE > 4) ttout << " - Don't know how to make DigiHit objects for this detector type!" << std::endl;
495  break;
496  }
497  }
498 
499  // Df125CDCPulse
500  vector<const Df125CDCPulse*> cdcpulses;
501  loop->Get(cdcpulses);
502  if (VERBOSE > 2) ttout << " Number Df125CDCPulse objects: " << cdcpulses.size() << std::endl;
503  for (uint32_t i=0; i<cdcpulses.size(); i++) {
504  const Df125CDCPulse *p = cdcpulses[i];
505 
506  // Apply optional rocid translation
507  uint32_t rocid = p->rocid;
508  map<uint32_t, uint32_t>::iterator rocid_iter = Get_ROCID_Map().find(rocid);
509  if (rocid_iter != Get_ROCID_Map().end()) rocid = rocid_iter->second;
510 
511  if (VERBOSE > 4)
512  ttout << " Looking for rocid:" << rocid << " slot:" << p->slot
513  << " chan:" << p->channel << std::endl;
514 
515  // Create crate,slot,channel index and find entry in Translation table.
516  // If none is found, then just quietly skip this hit.
517  csc_t csc = {rocid, p->slot, p->channel};
518  map<csc_t, DChannelInfo>::const_iterator iter = Get_TT().find(csc);
519  if (iter == Get_TT().end()) {
520  if (VERBOSE > 6)
521  ttout << " - Didn't find it" << std::endl;
522  continue;
523  }
524  const DChannelInfo &chaninfo = iter->second;
525  if (VERBOSE > 6)
526  ttout << " - Found entry for: " << DetectorName(chaninfo.det_sys)
527  << std::endl;
528 
529  // Create the appropriate hit type based on detector type
530  switch (chaninfo.det_sys) {
531  case CDC: MakeCDCDigiHit(chaninfo.cdc, p); break;
532  default:
533  if (VERBOSE > 4) ttout << " - Don't know how to make DigiHit objects for this detector type!" << std::endl;
534  break;
535  }
536  }
537 
538  // Df125FDCPulse
539  vector<const Df125FDCPulse*> fdcpulses;
540  loop->Get(fdcpulses);
541  if (VERBOSE > 2) ttout << " Number Df125FDCPulse objects: " << fdcpulses.size() << std::endl;
542  for (uint32_t i=0; i<fdcpulses.size(); i++) {
543  const Df125FDCPulse *p = fdcpulses[i];
544 
545  // Apply optional rocid translation
546  uint32_t rocid = p->rocid;
547  map<uint32_t, uint32_t>::iterator rocid_iter = Get_ROCID_Map().find(rocid);
548  if (rocid_iter != Get_ROCID_Map().end()) rocid = rocid_iter->second;
549 
550  if (VERBOSE > 4)
551  ttout << " Looking for rocid:" << rocid << " slot:" << p->slot
552  << " chan:" << p->channel << std::endl;
553 
554  // Create crate,slot,channel index and find entry in Translation table.
555  // If none is found, then just quietly skip this hit.
556  csc_t csc = {rocid, p->slot, p->channel};
557  map<csc_t, DChannelInfo>::const_iterator iter = Get_TT().find(csc);
558  if (iter == Get_TT().end()) {
559  if (VERBOSE > 6)
560  ttout << " - Didn't find it" << std::endl;
561  continue;
562  }
563  const DChannelInfo &chaninfo = iter->second;
564  if (VERBOSE > 6)
565  ttout << " - Found entry for: " << DetectorName(chaninfo.det_sys)
566  << std::endl;
567 
568  // Create the appropriate hit type based on detector type
569  switch (chaninfo.det_sys) {
570  case FDC_CATHODES: MakeFDCCathodeDigiHit(chaninfo.fdc_cathodes, p); break;
571  case CDC : MakeCDCDigiHit(chaninfo.cdc, p); break;
572  default:
573  if (VERBOSE > 4) ttout << " - Don't know how to make DigiHit objects for this detector type!" << std::endl;
574  break;
575  }
576  }
577 
578  // DF1TDCHit
579  vector<const DF1TDCHit*> f1tdchits;
580  loop->Get(f1tdchits);
581  if (VERBOSE > 2) ttout << " Number DF1TDCHit objects: " << f1tdchits.size() << std::endl;
582  for (uint32_t i=0; i<f1tdchits.size(); i++) {
583  const DF1TDCHit *hit = f1tdchits[i];
584 
585  // Apply optional rocid translation
586  uint32_t rocid = hit->rocid;
587  map<uint32_t, uint32_t>::iterator rocid_iter = Get_ROCID_Map().find(rocid);
588  if (rocid_iter != Get_ROCID_Map().end()) rocid = rocid_iter->second;
589 
590  if (VERBOSE > 4)
591  ttout << " Looking for rocid:" << rocid << " slot:" << hit->slot
592  << " chan:" << hit->channel << std::endl;
593 
594  // Create crate,slot,channel index and find entry in Translation table.
595  // If none is found, then just quietly skip this hit.
596  csc_t csc = {rocid, hit->slot, hit->channel};
597  map<csc_t, DChannelInfo>::const_iterator iter = Get_TT().find(csc);
598  if (iter == Get_TT().end()) {
599  if (VERBOSE > 6)
600  ttout << " - Didn't find it" << std::endl;
601  continue;
602  }
603  const DChannelInfo &chaninfo = iter->second;
604  if (VERBOSE > 6)
605  ttout << " - Found entry for: "
606  << DetectorName(chaninfo.det_sys) << std::endl;
607 
608  // Create the appropriate hit type based on detector type
609  switch (chaninfo.det_sys) {
610  case BCAL: MakeBCALTDCDigiHit(chaninfo.bcal, hit); break;
611  case FDC_WIRES: MakeFDCWireDigiHit(chaninfo.fdc_wires, hit); break;
612  case RF: MakeRFTDCDigiTime(chaninfo.rf, hit); break;
613  case SC: MakeSCTDCDigiHit(chaninfo.sc, hit); break;
614  case TAGM: MakeTAGMTDCDigiHit(chaninfo.tagm, hit); break;
615  case TAGH: MakeTAGHTDCDigiHit(chaninfo.tagh, hit); break;
616  case PSC: MakePSCTDCDigiHit(chaninfo.psc, hit); break;
617  default:
618  if (VERBOSE > 4) ttout << " - Don't know how to make DigiHit objects for this detector type!" << std::endl;
619  break;
620  }
621  }
622 
623  // DCAEN1290TDCHit
624  vector<const DCAEN1290TDCHit*> caen1290tdchits;
625  loop->Get(caen1290tdchits);
626  if (VERBOSE > 2) ttout << " Number DCAEN1290TDCHit objects: " << caen1290tdchits.size() << std::endl;
627  for (uint32_t i=0; i<caen1290tdchits.size(); i++) {
628  const DCAEN1290TDCHit *hit = caen1290tdchits[i];
629 
630  // Apply optional rocid translation
631  uint32_t rocid = hit->rocid;
632  map<uint32_t, uint32_t>::iterator rocid_iter = Get_ROCID_Map().find(rocid);
633  if (rocid_iter != Get_ROCID_Map().end()) rocid = rocid_iter->second;
634 
635  if (VERBOSE > 4)
636  ttout << " Looking for rocid:" << rocid << " slot:" << hit->slot
637  << " chan:" << hit->channel << std::endl;
638 
639  // Create crate,slot,channel index and find entry in Translation table.
640  // If none is found, then just quietly skip this hit.
641  csc_t csc = {rocid, hit->slot, hit->channel};
642  map<csc_t, DChannelInfo>::const_iterator iter = Get_TT().find(csc);
643  if (iter == Get_TT().end()) {
644  if (VERBOSE > 6)
645  ttout << " - Didn't find it" << std::endl;
646  continue;
647  }
648  const DChannelInfo &chaninfo = iter->second;
649  if (VERBOSE > 6)
650  ttout << " - Found entry for: " << DetectorName(chaninfo.det_sys)
651  << std::endl;
652 
653  // Create the appropriate hit type based on detector type
654  switch (chaninfo.det_sys) {
655  case TOF: MakeTOFTDCDigiHit(chaninfo.tof, hit); break;
656  case RF: MakeRFTDCDigiTime(chaninfo.rf, hit); break;
657  case TAC: MakeTACTDCDigiHit(chaninfo.tac, hit); break;
658  default:
659  if (VERBOSE > 4) ttout << " - Don't know how to make DigiHit objects for this detector type!" << std::endl;
660  break;
661  }
662  }
663 
664  // DDIRCTDCHit
665  vector<const DDIRCTDCHit*> dirctdchits;
666  loop->Get(dirctdchits);
667  if (VERBOSE > 2) ttout << " Number DDIRCTDCHit objects: " << dirctdchits.size() << std::endl;
668  for (uint32_t i=0; i<dirctdchits.size(); i++) {
669  const DDIRCTDCHit *hit = dirctdchits[i];
670 
671  // Apply optional rocid translation
672  uint32_t rocid = hit->rocid;
673  map<uint32_t, uint32_t>::iterator rocid_iter = Get_ROCID_Map().find(rocid);
674  if (rocid_iter != Get_ROCID_Map().end()) rocid = rocid_iter->second;
675 
676  if (VERBOSE > 4)
677  ttout << " Looking for rocid:" << rocid << " slot:" << hit->slot
678  << " chan:" << hit->channel << std::endl;
679 
680  // Create crate,slot,channel index and find entry in Translation table.
681  // If none is found, then just quietly skip this hit.
682  csc_t csc = {rocid, hit->slot, hit->channel};
683  map<csc_t, DChannelInfo>::const_iterator iter = Get_TT().find(csc);
684  if (iter == Get_TT().end()) {
685  if (VERBOSE > 6)
686  ttout << " - Didn't find it" << std::endl;
687  continue;
688  }
689  const DChannelInfo &chaninfo = iter->second;
690  if (VERBOSE > 6)
691  ttout << " - Found entry for: " << DetectorName(chaninfo.det_sys)
692  << std::endl;
693 
694  // Create the appropriate hit type based on detector type
695  switch (chaninfo.det_sys) {
696  case DIRC: MakeDIRCTDCDigiHit(chaninfo.dirc, hit); break;
697  default:
698  if (VERBOSE > 4) ttout << " - Don't know how to make DigiHit objects for this detector type!" << std::endl;
699  break;
700  }
701  }
702 
703  // Optionally overwrite nsamples_integral and/or nsamples_pedestal if
704  // user specified via config. parameters.
705  OverwriteNsamples();
706 
707  // Sort object order (this makes it easier to browse with hd_dump)
708  sort(vDBCALDigiHit.begin(), vDBCALDigiHit.end(), SortBCALDigiHit);
709 
710  // Copy pointers to all objects produced to their appropriate
711  // factories. This hands ownership of them over to the factories
712  // so JANA will delete them.
713  CopyToFactories();
714 
715 
716  if (VERBOSE > 3) PrintVectorSizes();
717 
718  // Add to JANA's call stack some entries to make janadot draw something reasonable
719  // Unfortunately, this is just us telling JANA the relationship as defined here.
720  // It is not derived from the above code which would guarantee the declared relationsips
721  // are correct. That would just be too complicated given how that code works.
722  if (record_call_stack) {
723  // re-enable call stack recording
724  loop->EnableCallStackRecording();
725 
726  if(CALL_STACK){
727  Addf250ObjectsToCallStack(loop, "DBCALDigiHit");
728  Addf250ObjectsToCallStack(loop, "DFCALDigiHit");
729  Addf250ObjectsToCallStack(loop, "DCCALDigiHit");
730  Addf250ObjectsToCallStack(loop, "DCCALRefDigiHit");
731  Addf250ObjectsToCallStack(loop, "DSCDigiHit");
732  Addf250ObjectsToCallStack(loop, "DTOFDigiHit");
733  Addf250ObjectsToCallStack(loop, "DTACDigiHit");
734  Addf125CDCObjectsToCallStack(loop, "DCDCDigiHit", cdcpulses.size()>0);
735  Addf125FDCObjectsToCallStack(loop, "DFDCCathodeDigiHit", fdcpulses.size()>0);
736  AddF1TDCObjectsToCallStack(loop, "DBCALTDCDigiHit");
737  AddF1TDCObjectsToCallStack(loop, "DFDCWireDigiHit");
738  AddF1TDCObjectsToCallStack(loop, "DRFDigiTime");
739  AddF1TDCObjectsToCallStack(loop, "DRFTDCDigiTime");
740  AddF1TDCObjectsToCallStack(loop, "DSCTDCDigiHit");
741  AddCAEN1290TDCObjectsToCallStack(loop, "DTOFTDCDigiHit");
742  AddCAEN1290TDCObjectsToCallStack(loop, "DTACTDCDigiHit");
743  }
744  }
745 }
746 
747 //---------------------------------
748 // MakeBCALDigiHit
749 //---------------------------------
751  const Df250PulseData *pd) const
752 {
753  if (VERBOSE > 4)
754  ttout << " - Making DBCALDigiHit for (mod,lay,sec,end)=("
755  << idx.module << "," << idx.layer << "," << idx.sector
756  << "," << (DBCALGeometry::End)idx.end << std::endl;
757 
758  DBCALDigiHit *h = new DBCALDigiHit();
759  CopyDf250Info(h, pd);
760 
761  h->module = idx.module;
762  h->layer = idx.layer;
763  h->sector = idx.sector;
764  h->end = (DBCALGeometry::End)idx.end;
765 
766  vDBCALDigiHit.push_back(h);
767 
768  return h;
769 }
770 
771 //---------------------------------
772 // MakeFCALDigiHit
773 //---------------------------------
775  const Df250PulseData *pd) const
776 {
777  DFCALDigiHit *h = new DFCALDigiHit();
778  CopyDf250Info(h, pd);
779 
780  h->row = idx.row;
781  h->column = idx.col;
782 
783  vDFCALDigiHit.push_back(h);
784 
785  return h;
786 }
787 
788 //---------------------------------
789 // MakeCCALDigiHit
790 //---------------------------------
792  const Df250PulseData *pd) const
793 {
794  DCCALDigiHit *h = new DCCALDigiHit();
795  CopyDf250Info(h, pd);
796 
797  // The CCAL coordinate system: (column,row) = (0,0) in the bottom right corner
798 
799  if(idx.col < 0)
800  h->column = idx.col + 6;
801  else if(idx.col > 0)
802  h->column = idx.col + 5;
803 
804  if(idx.row < 0)
805  h->row = idx.row + 6;
806  else if(idx.row > 0)
807  h->row = idx.row + 5;
808 
809  // h->row = idx.row;
810  // h->column = idx.col;
811 
812  vDCCALDigiHit.push_back(h);
813 
814  return h;
815 }
816 
817 //---------------------------------
818 // MakeCCALRefDigiHit
819 //---------------------------------
821  const Df250PulseData *pd) const
822 {
824  CopyDf250Info(h, pd);
825 
826  h->id = idx.id;
827 
828  vDCCALRefDigiHit.push_back(h);
829 
830  return h;
831 }
832 
833 
834 //---------------------------------
835 // MakeTOFDigiHit
836 //---------------------------------
838  const Df250PulseData *pd) const
839 {
840  DTOFDigiHit *h = new DTOFDigiHit();
841  CopyDf250Info(h, pd);
842 
843  h->plane = idx.plane;
844  h->bar = idx.bar;
845  h->end = idx.end;
846 
847  vDTOFDigiHit.push_back(h);
848 
849  return h;
850 }
851 
852 //---------------------------------
853 // MakeSCDigiHit
854 //---------------------------------
856  const Df250PulseData *pd) const
857 {
858  DSCDigiHit *h = new DSCDigiHit();
859  CopyDf250Info(h, pd);
860 
861  h->sector = idx.sector;
862 
863  vDSCDigiHit.push_back(h);
864 
865  return h;
866 }
867 
868 //---------------------------------
869 // MakeTAGMDigiHit
870 //---------------------------------
872  const Df250PulseData *pd) const
873 {
874  DTAGMDigiHit *h = new DTAGMDigiHit();
875  CopyDf250Info(h, pd);
876 
877  h->row = idx.row;
878  h->column = idx.col;
879 
880  vDTAGMDigiHit.push_back(h);
881 
882  return h;
883 }
884 
885 //---------------------------------
886 // MakeTAGHDigiHit
887 //---------------------------------
889  const Df250PulseData *pd) const
890 {
891  DTAGHDigiHit *h = new DTAGHDigiHit();
892  CopyDf250Info(h, pd);
893 
894  h->counter_id = idx.id;
895 
896  vDTAGHDigiHit.push_back(h);
897 
898  return h;
899 }
900 
901 //---------------------------------
902 // MakePSCDigiHit
903 //---------------------------------
905  const Df250PulseData *pd) const
906 {
907  DPSCDigiHit *h = new DPSCDigiHit();
908  CopyDf250Info(h, pd);
909 
910  h->counter_id = idx.id;
911 
912  vDPSCDigiHit.push_back(h);
913 
914  return h;
915 }
916 
917 //---------------------------------
918 // MakePSDigiHit
919 //---------------------------------
921  const Df250PulseData *pd) const
922 {
923  DPSDigiHit *h = new DPSDigiHit();
924  CopyDf250Info(h, pd);
925 
926  h->arm = (DPSGeometry::Arm)idx.side;
927  h->column = idx.id;
928 
929  vDPSDigiHit.push_back(h);
930 
931  return h;
932 }
933 
934 //---------------------------------
935 // MakeBCALDigiHit
936 //---------------------------------
938  const Df250PulseIntegral *pi,
939  const Df250PulseTime *pt,
940  const Df250PulsePedestal *pp) const
941 {
942  if (VERBOSE > 4)
943  ttout << " - Making DBCALDigiHit for (mod,lay,sec,end)=("
944  << idx.module << "," << idx.layer << "," << idx.sector
945  << "," << (DBCALGeometry::End)idx.end << std::endl;
946 
947  DBCALDigiHit *h = new DBCALDigiHit();
948  CopyDf250Info(h, pi, pt, pp);
949 
950  h->pulse_peak = pp==NULL ? 0 : pp->pulse_peak; // Include pulse peak information in the digihit for BCAL
951 
952  h->module = idx.module;
953  h->layer = idx.layer;
954  h->sector = idx.sector;
955  h->end = (DBCALGeometry::End)idx.end;
956 
957  vDBCALDigiHit.push_back(h);
958 
959  return h;
960 }
961 
962 //---------------------------------
963 // MakeFCALDigiHit
964 //---------------------------------
966  const Df250PulseIntegral *pi,
967  const Df250PulseTime *pt,
968  const Df250PulsePedestal *pp) const
969 {
970  DFCALDigiHit *h = new DFCALDigiHit();
971  CopyDf250Info(h, pi, pt, pp);
972 
973  h->row = idx.row;
974  h->column = idx.col;
975 
976  vDFCALDigiHit.push_back(h);
977 
978  return h;
979 }
980 
981 //---------------------------------
982 // MakeCCALDigiHit
983 //---------------------------------
985  const Df250PulseIntegral *pi,
986  const Df250PulseTime *pt,
987  const Df250PulsePedestal *pp) const
988 {
989  DCCALDigiHit *h = new DCCALDigiHit();
990  CopyDf250Info(h, pi, pt, pp);
991 
992  if(idx.col < 0)
993  h->column = idx.col + 6;
994  else if(idx.col > 0)
995  h->column = idx.col + 5;
996 
997  if(idx.row < 0)
998  h->row = idx.row + 6;
999  else if(idx.row > 0)
1000  h->row = idx.row + 5;
1001 
1002  // h->row = idx.row;
1003  // h->column = idx.col;
1004 
1005  vDCCALDigiHit.push_back(h);
1006 
1007  return h;
1008 }
1009 
1010 //---------------------------------
1011 // MakeCCALRefDigiHit
1012 //---------------------------------
1014  const Df250PulseIntegral *pi,
1015  const Df250PulseTime *pt,
1016  const Df250PulsePedestal *pp) const
1017 {
1019  CopyDf250Info(h, pi, pt, pp);
1020 
1021  h->id = idx.id;
1022 
1023  vDCCALRefDigiHit.push_back(h);
1024 
1025  return h;
1026 }
1027 
1028 
1029 //---------------------------------
1030 // MakeTOFDigiHit
1031 //---------------------------------
1033  const Df250PulseIntegral *pi,
1034  const Df250PulseTime *pt,
1035  const Df250PulsePedestal *pp) const
1036 {
1037  DTOFDigiHit *h = new DTOFDigiHit();
1038  CopyDf250Info(h, pi, pt, pp);
1039 
1040  h->plane = idx.plane;
1041  h->bar = idx.bar;
1042  h->end = idx.end;
1043 
1044  vDTOFDigiHit.push_back(h);
1045 
1046  return h;
1047 }
1048 
1049 //---------------------------------
1050 // MakeSCDigiHit
1051 //---------------------------------
1053  const Df250PulseIntegral *pi,
1054  const Df250PulseTime *pt,
1055  const Df250PulsePedestal *pp) const
1056 {
1057  DSCDigiHit *h = new DSCDigiHit();
1058  CopyDf250Info(h, pi, pt, pp);
1059 
1060  h->sector = idx.sector;
1061 
1062  vDSCDigiHit.push_back(h);
1063 
1064  return h;
1065 }
1066 
1067 //---------------------------------
1068 // MakeTAGMDigiHit
1069 //---------------------------------
1071  const Df250PulseIntegral *pi,
1072  const Df250PulseTime *pt,
1073  const Df250PulsePedestal *pp) const
1074 {
1075  DTAGMDigiHit *h = new DTAGMDigiHit();
1076  CopyDf250Info(h, pi, pt, pp);
1077 
1078  h->row = idx.row;
1079  h->column = idx.col;
1080 
1081  vDTAGMDigiHit.push_back(h);
1082 
1083  return h;
1084 }
1085 
1086 //---------------------------------
1087 // MakeTAGHDigiHit
1088 //---------------------------------
1090  const Df250PulseIntegral *pi,
1091  const Df250PulseTime *pt,
1092  const Df250PulsePedestal *pp) const
1093 {
1094  DTAGHDigiHit *h = new DTAGHDigiHit();
1095  CopyDf250Info(h, pi, pt, pp);
1096 
1097  h->counter_id = idx.id;
1098 
1099  vDTAGHDigiHit.push_back(h);
1100 
1101  return h;
1102 }
1103 
1104 //---------------------------------
1105 // MakePSCDigiHit
1106 //---------------------------------
1108  const Df250PulseIntegral *pi,
1109  const Df250PulseTime *pt,
1110  const Df250PulsePedestal *pp) const
1111 {
1112  DPSCDigiHit *h = new DPSCDigiHit();
1113  CopyDf250Info(h, pi, pt, pp);
1114 
1115  h->counter_id = idx.id;
1116 
1117  vDPSCDigiHit.push_back(h);
1118 
1119  return h;
1120 }
1121 
1122 //---------------------------------
1123 // MakePSDigiHit
1124 //---------------------------------
1126  const Df250PulseIntegral *pi,
1127  const Df250PulseTime *pt,
1128  const Df250PulsePedestal *pp) const
1129 {
1130  DPSDigiHit *h = new DPSDigiHit();
1131  CopyDf250Info(h, pi, pt, pp);
1132 
1133  h->arm = (DPSGeometry::Arm)idx.side;
1134  h->column = idx.id;
1135 
1136  vDPSDigiHit.push_back(h);
1137 
1138  return h;
1139 }
1140 
1141 //---------------------------------
1142 // MakeCDCDigiHit
1143 //---------------------------------
1145  const Df125PulseIntegral *pi,
1146  const Df125PulseTime *pt,
1147  const Df125PulsePedestal *pp) const
1148 {
1149  DCDCDigiHit *h = new DCDCDigiHit();
1150  CopyDf125Info(h, pi, pt, pp);
1151 
1152  h->ring = idx.ring;
1153  h->straw = idx.straw;
1154  h->pulse_peak = 0;
1155 
1156  vDCDCDigiHit.push_back(h);
1157 
1158  return h;
1159 }
1160 
1161 //---------------------------------
1162 // MakeCDCDigiHit
1163 //---------------------------------
1165  const Df125CDCPulse *p) const
1166 {
1167  DCDCDigiHit *h = new DCDCDigiHit();
1168  h->ring = idx.ring;
1169  h->straw = idx.straw;
1170  h->pulse_peak = p->first_max_amp;
1171  h->pulse_integral = p->integral;
1172  h->pulse_time = p->le_time;
1173  h->pedestal = p->pedestal;
1174  h->QF = p->time_quality_bit + (p->overflow_count<<1);
1177 
1178  h->AddAssociatedObject(p);
1179 
1180  vDCDCDigiHit.push_back(h);
1181 
1182  return h;
1183 }
1184 
1185 //---------------------------------
1186 // MakeCDCDigiHit
1187 //---------------------------------
1189  const Df125FDCPulse *p) const
1190 {
1191  DCDCDigiHit *h = new DCDCDigiHit();
1192  h->ring = idx.ring;
1193  h->straw = idx.straw;
1194  h->pulse_peak = p->peak_amp;
1195  h->pulse_integral = p->integral;
1196  h->pulse_time = p->le_time;
1197  h->pedestal = p->pedestal;
1198  h->QF = p->time_quality_bit + (p->overflow_count<<1);
1201 
1202  h->AddAssociatedObject(p);
1203 
1204  vDCDCDigiHit.push_back(h);
1205 
1206  return h;
1207 }
1208 
1209 //---------------------------------
1210 // MakeFDCCathodeDigiHit
1211 //---------------------------------
1213  const FDC_CathodesIndex_t &idx,
1214  const Df125PulseIntegral *pi,
1215  const Df125PulseTime *pt,
1216  const Df125PulsePedestal *pp) const
1217 {
1219  CopyDf125Info(h, pi, pt, pp);
1220 
1221  h->package = idx.package;
1222  h->chamber = idx.chamber;
1223  h->view = idx.view;
1224  h->strip = idx.strip;
1225  h->strip_type = idx.strip_type;
1226 
1227  vDFDCCathodeDigiHit.push_back(h);
1228 
1229  return h;
1230 }
1231 
1232 
1233 //---------------------------------
1234 // MakeFDCCathodeDigiHit
1235 //---------------------------------
1237  const FDC_CathodesIndex_t &idx,
1238  const Df125FDCPulse *p) const
1239 {
1241  h->package = idx.package;
1242  h->chamber = idx.chamber;
1243  h->view = idx.view;
1244  h->strip = idx.strip;
1245  h->strip_type = idx.strip_type;
1246  h->pulse_integral = p->integral;
1247  h->pulse_time = p->le_time;
1248  h->pedestal = p->pedestal;
1249  h->QF = p->time_quality_bit + (p->overflow_count<<1);
1252 
1253  h->AddAssociatedObject(p);
1254 
1255  vDFDCCathodeDigiHit.push_back(h);
1256 
1257  return h;
1258 }
1259 
1260 //---------------------------------
1261 // MakeBCALTDCDigiHit
1262 //---------------------------------
1264  const BCALIndex_t &idx,
1265  const DF1TDCHit *hit) const
1266 {
1268  CopyDF1TDCInfo(h, hit);
1269 
1270  h->module = idx.module;
1271  h->layer = idx.layer;
1272  h->sector = idx.sector;
1273  h->end = (DBCALGeometry::End)idx.end;
1274 
1275  vDBCALTDCDigiHit.push_back(h);
1276 
1277  return h;
1278 }
1279 
1280 //---------------------------------
1281 // MakeFDCWireDigiHit
1282 //---------------------------------
1284  const FDC_WiresIndex_t &idx,
1285  const DF1TDCHit *hit) const
1286 {
1288  CopyDF1TDCInfo(h, hit);
1289 
1290  h->package = idx.package;
1291  h->chamber = idx.chamber;
1292  h->wire = idx.wire;
1293 
1294  vDFDCWireDigiHit.push_back(h);
1295 
1296  return h;
1297 }
1298 
1299 //---------------------------------
1300 // MakeRFDigiTime
1301 //---------------------------------
1303  const RFIndex_t &idx,
1304  const DF1TDCHit *hit) const
1305 {
1306  DRFTDCDigiTime *h = new DRFTDCDigiTime();
1307  CopyDF1TDCInfo(h, hit);
1308 
1309  h->dSystem = idx.dSystem;
1310  h->dIsCAENTDCFlag = false;
1311 
1312  vDRFTDCDigiTime.push_back(h);
1313 
1314  return h;
1315 }
1316 
1317 //---------------------------------
1318 // MakeRFDigiTime
1319 //---------------------------------
1321  const RFIndex_t &idx,
1322  const DCAEN1290TDCHit *hit) const
1323 {
1324  DRFTDCDigiTime *h = new DRFTDCDigiTime();
1325  CopyDCAEN1290TDCInfo(h, hit);
1326 
1327  h->dSystem = idx.dSystem;
1328  h->dIsCAENTDCFlag = true;
1329 
1330  vDRFTDCDigiTime.push_back(h);
1331 
1332  return h;
1333 }
1334 
1335 //---------------------------------
1336 // MakeRFDigiTime
1337 //---------------------------------
1339  const RFIndex_t &idx,
1340  const Df250PulseTime *hit) const
1341 {
1342  DRFDigiTime *h = new DRFDigiTime();
1343  h->time = hit->time;
1344 
1345  h->dSystem = idx.dSystem;
1346 
1347  vDRFDigiTime.push_back(h);
1348 
1349  return h;
1350 }
1351 
1352 //---------------------------------
1353 // MakeRFDigiTime
1354 //---------------------------------
1356  const RFIndex_t &idx,
1357  const Df250PulseData *hit) const
1358 {
1359  DRFDigiTime *h = new DRFDigiTime();
1360  h->time = (hit->course_time<<6) + hit->fine_time;
1361 
1362  h->dSystem = idx.dSystem;
1363 
1364  vDRFDigiTime.push_back(h);
1365 
1366  return h;
1367 }
1368 
1369 //---------------------------------
1370 // MakeSCTDCDigiHit
1371 //---------------------------------
1373  const SCIndex_t &idx,
1374  const DF1TDCHit *hit) const
1375 {
1376  DSCTDCDigiHit *h = new DSCTDCDigiHit();
1377  CopyDF1TDCInfo(h, hit);
1378 
1379  h->sector = idx.sector;
1380 
1381  vDSCTDCDigiHit.push_back(h);
1382 
1383  return h;
1384 }
1385 
1386 //---------------------------------
1387 // MakeTAGMTDCDigiHit
1388 //---------------------------------
1390  const TAGMIndex_t &idx,
1391  const DF1TDCHit *hit) const
1392 {
1394  CopyDF1TDCInfo(h, hit);
1395 
1396  h->row = idx.row;
1397  h->column = idx.col;
1398 
1399  vDTAGMTDCDigiHit.push_back(h);
1400 
1401  return h;
1402 }
1403 
1404 //---------------------------------
1405 // MakeTAGHTDCDigiHit
1406 //---------------------------------
1408  const TAGHIndex_t &idx,
1409  const DF1TDCHit *hit) const
1410 {
1412  CopyDF1TDCInfo(h, hit);
1413 
1414  h->counter_id = idx.id;
1415 
1416  vDTAGHTDCDigiHit.push_back(h);
1417 
1418  return h;
1419 }
1420 
1421 //---------------------------------
1422 // MakePSCTDCDigiHit
1423 //---------------------------------
1425  const PSCIndex_t &idx,
1426  const DF1TDCHit *hit) const
1427 {
1428  DPSCTDCDigiHit *h = new DPSCTDCDigiHit();
1429  CopyDF1TDCInfo(h, hit);
1430 
1431  h->counter_id = idx.id;
1432 
1433  vDPSCTDCDigiHit.push_back(h);
1434 
1435  return h;
1436 }
1437 
1438 //---------------------------------
1439 // MakeTOFTDCDigiHit
1440 //---------------------------------
1442  const TOFIndex_t &idx,
1443  const DCAEN1290TDCHit *hit) const
1444 {
1445  DTOFTDCDigiHit *h = new DTOFTDCDigiHit();
1446  CopyDCAEN1290TDCInfo(h, hit);
1447 
1448  h->plane = idx.plane;
1449  h->bar = idx.bar;
1450  h->end = idx.end;
1451 
1452  vDTOFTDCDigiHit.push_back(h);
1453 
1454  return h;
1455 }
1456 
1457 //---------------------------------
1458 // MakeTPOLSectorDigiHit
1459 //---------------------------------
1461  const Df250PulseIntegral *pi,
1462  const Df250PulseTime *pt,
1463  const Df250PulsePedestal *pp) const
1464 {
1466  CopyDf250Info(h, pi, pt, pp);
1467 
1468  h->sector = idx.sector;
1469 
1470  vDTPOLSectorDigiHit.push_back(h);
1471 
1472  return h;
1473 }
1474 
1475 //---------------------------------
1476 // MakeTPOLSectorDigiHit
1477 //---------------------------------
1479  const Df250PulseData *pd) const
1480 {
1482  CopyDf250Info(h, pd);
1483 
1484  h->sector = idx.sector;
1485 
1486  vDTPOLSectorDigiHit.push_back(h);
1487 
1488  return h;
1489 }
1490 
1491 
1492 
1493 //---------------------------------
1494 // MakeTACDigiHit
1495 //---------------------------------
1497  const Df250PulseIntegral *pi,
1498  const Df250PulseTime *pt,
1499  const Df250PulsePedestal *pp) const
1500 {
1501  DTACDigiHit *h = new DTACDigiHit();
1502  CopyDf250Info(h, pi, pt, pp);
1503 
1504  vDTACDigiHit.push_back(h);
1505 
1506  return h;
1507 }
1508 
1509 //---------------------------------
1510 // MakeTACDigiHit
1511 //---------------------------------
1513  const Df250PulseData *pd) const
1514 {
1515  DTACDigiHit *h = new DTACDigiHit();
1516  CopyDf250Info(h, pd);
1517 
1518  vDTACDigiHit.push_back(h);
1519 
1520  return h;
1521 }
1522 
1523 //---------------------------------
1524 // MakeTACTDCDigiHit
1525 //---------------------------------
1527  const TACIndex_t &idx,
1528  const DCAEN1290TDCHit *hit) const
1529 {
1530  DTACTDCDigiHit *h = new DTACTDCDigiHit();
1531  CopyDCAEN1290TDCInfo(h, hit);
1532 
1533  vDTACTDCDigiHit.push_back(h);
1534 
1535  return h;
1536 }
1537 
1538 //---------------------------------
1539 // MakeDIRCTDCDigiHit
1540 //---------------------------------
1542  const DIRCIndex_t &idx,
1543  const DDIRCTDCHit *hit) const
1544 {
1546  CopyDIRCTDCInfo(h, hit);
1547 
1548  h->channel = idx.pixel;
1549 
1550  vDDIRCTDCDigiHit.push_back(h);
1551 
1552  return h;
1553 }
1554 
1555 //---------------------------------
1556 // GetDetectorIndex
1557 //---------------------------------
1559  &DTranslationTable::GetDetectorIndex(const csc_t &in_daq_index) const
1560 {
1561  map<DTranslationTable::csc_t, DTranslationTable::DChannelInfo>::const_iterator detector_index_itr = Get_TT().find(in_daq_index);
1562  if (detector_index_itr == Get_TT().end()) {
1563  stringstream ss_err;
1564  ss_err << "Could not find detector channel in Translaton Table: "
1565  << "rocid = " << in_daq_index.rocid
1566  << "slot = " << in_daq_index.slot
1567  << "channel = " << in_daq_index.channel;
1568  throw JException(ss_err.str());
1569  }
1570 
1571  return detector_index_itr->second;
1572 }
1573 
1574 //---------------------------------
1575 // GetDAQIndex
1576 //---------------------------------
1579 {
1580  map<DTranslationTable::csc_t, DTranslationTable::DChannelInfo>::const_iterator tt_itr = Get_TT().begin();
1581 
1582  // search through the whole Table to find the key that corresponds to our detector channel
1583  // this is not terribly efficient - linear in the size of the table
1584  bool found = false;
1585  for (; tt_itr != Get_TT().end(); tt_itr++) {
1586  const DTranslationTable::DChannelInfo &det_channel = tt_itr->second;
1587  if ( det_channel.det_sys == in_channel.det_sys ) {
1588  switch ( in_channel.det_sys ) {
1590  if ( det_channel.bcal == in_channel.bcal )
1591  found = true;
1592  break;
1594  if ( det_channel.cdc == in_channel.cdc )
1595  found = true;
1596  break;
1598  if ( det_channel.fcal == in_channel.fcal )
1599  found = true;
1600  break;
1602  if ( det_channel.ccal == in_channel.ccal )
1603  found = true;
1604  break;
1606  if ( det_channel.ccal_ref == in_channel.ccal_ref )
1607  found = true;
1608  break;
1610  if ( det_channel.fdc_cathodes == in_channel.fdc_cathodes )
1611  found = true;
1612  break;
1614  if ( det_channel.fdc_wires == in_channel.fdc_wires )
1615  found = true;
1616  break;
1617  case DTranslationTable::PS:
1618  if ( det_channel.ps == in_channel.ps )
1619  found = true;
1620  break;
1622  if ( det_channel.psc == in_channel.psc )
1623  found = true;
1624  break;
1625  case DTranslationTable::RF:
1626  if ( det_channel.rf == in_channel.rf )
1627  found = true;
1628  break;
1629  case DTranslationTable::SC:
1630  if ( det_channel.sc == in_channel.sc )
1631  found = true;
1632  break;
1634  if ( det_channel.tagh == in_channel.tagh )
1635  found = true;
1636  break;
1638  if ( det_channel.tagm == in_channel.tagm )
1639  found = true;
1640  break;
1642  if ( det_channel.tof == in_channel.tof )
1643  found = true;
1644  break;
1646  if ( det_channel.tpolsector == in_channel.tpolsector )
1647  found = true;
1648  break;
1650  if ( det_channel.tac == in_channel.tac )
1651  found = true;
1652  break;
1654  if ( det_channel.dirc == in_channel.dirc )
1655  found = true;
1656  break;
1657 
1658  default:
1659  jerr << "DTranslationTable::GetDAQIndex(): "
1660  << "Invalid detector type = " << in_channel.det_sys
1661  << std::endl;
1662  }
1663  }
1664 
1665  if (found)
1666  break;
1667  }
1668 
1669  if (tt_itr == Get_TT().end()) {
1670  stringstream ss_err;
1671  ss_err << "Could not find DAQ channel in Translaton Table: "
1672  << Channel2Str(in_channel) << std::endl;
1673  throw JException(ss_err.str());
1674  }
1675 
1676  return tt_itr->first;
1677 }
1678 
1679 //----------------
1680 // Channel2Str
1681 //----------------
1682 string DTranslationTable::Channel2Str(const DChannelInfo &in_channel) const
1683 {
1684  stringstream ss;
1685 
1686  switch ( in_channel.det_sys ) {
1688  ss << "module = " << in_channel.bcal.module << " layer = " << in_channel.bcal.layer
1689  << " sector = " << in_channel.bcal.sector << " end = " << in_channel.bcal.end;
1690  break;
1692  ss << "ring = " << in_channel.cdc.ring << " straw = " << in_channel.cdc.straw;
1693  break;
1695  ss << "row = " << in_channel.fcal.row << " column = " << in_channel.fcal.col;
1696  break;
1698  ss << "row = " << in_channel.ccal.row << " column = " << in_channel.ccal.col;
1699  break;
1701  ss << "id = " << in_channel.ccal_ref.id << " id = " << in_channel.ccal_ref.id;
1702  break;
1704  ss << "package = " << in_channel.fdc_cathodes.package
1705  << " chamber = " << in_channel.fdc_cathodes.chamber
1706  << " view = " << in_channel.fdc_cathodes.view
1707  << " strip = " << in_channel.fdc_cathodes.strip
1708  << " strip type = " << in_channel.fdc_cathodes.strip_type;
1709  break;
1711  ss << "package = " << in_channel.fdc_wires.package
1712  << " chamber = " << in_channel.fdc_wires.chamber
1713  << " wire = " << in_channel.fdc_wires.wire;
1714  break;
1715  case DTranslationTable::PS:
1716  ss << "side = " << in_channel.ps.side << " id = " << in_channel.ps.id;
1717  break;
1719  ss << "id = " << in_channel.psc.id;
1720  break;
1721  case DTranslationTable::RF:
1722  ss << "system = " << SystemName(in_channel.rf.dSystem);
1723  break;
1724  case DTranslationTable::SC:
1725  ss << "sector = " << in_channel.sc.sector;
1726  break;
1728  ss << "id = " << in_channel.tagh.id;
1729  break;
1731  ss << "row = " << in_channel.tagm.row << " column = " << in_channel.tagm.col;
1732  break;
1734  ss << "plane = " << in_channel.tof.plane << " bar = " << in_channel.tof.bar
1735  << " end = " << in_channel.tof.end;
1736  break;
1738  ss << "sector = " << in_channel.tpolsector.sector;
1739  break;
1741  ss << " ";
1742  break;
1744  ss << "pixel = " << in_channel.dirc.pixel;
1745  break;
1746 
1747  default:
1748  ss << "Unknown detector type" << std::endl;
1749  }
1750 
1751  return ss.str();
1752 }
1753 
1754 //----------------
1755 // Addf250ObjectsToCallStack
1756 //----------------
1757 void DTranslationTable::Addf250ObjectsToCallStack(JEventLoop *loop, string caller) const
1758 {
1759  AddToCallStack(loop, caller, "Df250Config");
1760  AddToCallStack(loop, caller, "Df250PulseIntegral");
1761  AddToCallStack(loop, caller, "Df250PulsePedestal");
1762  AddToCallStack(loop, caller, "Df250PulseTime");
1763 }
1764 
1765 //----------------
1766 // Addf125CDCObjectsToCallStack
1767 //----------------
1768 void DTranslationTable::Addf125CDCObjectsToCallStack(JEventLoop *loop, string caller, bool addpulseobjs) const
1769 {
1770  AddToCallStack(loop, caller, "Df125Config");
1771  if(addpulseobjs){
1772  // new style
1773  AddToCallStack(loop, caller, "Df125CDCPulse");
1774  }else{
1775  // old style
1776  AddToCallStack(loop, caller, "Df125PulseIntegral");
1777  AddToCallStack(loop, caller, "Df125PulsePedestal");
1778  AddToCallStack(loop, caller, "Df125PulseTime");
1779  }
1780 }
1781 
1782 //----------------
1783 // Addf125FDCObjectsToCallStack
1784 //----------------
1785 void DTranslationTable::Addf125FDCObjectsToCallStack(JEventLoop *loop, string caller, bool addpulseobjs) const
1786 {
1787  AddToCallStack(loop, caller, "Df125Config");
1788  if(addpulseobjs){
1789  // new style
1790  AddToCallStack(loop, caller, "Df125FDCPulse");
1791  }else{
1792  // old style
1793  AddToCallStack(loop, caller, "Df125PulseIntegral");
1794  AddToCallStack(loop, caller, "Df125PulsePedestal");
1795  AddToCallStack(loop, caller, "Df125PulseTime");
1796  }
1797 }
1798 
1799 //----------------
1800 // AddF1TDCObjectsToCallStack
1801 //----------------
1802 void DTranslationTable::AddF1TDCObjectsToCallStack(JEventLoop *loop, string caller) const
1803 {
1804  AddToCallStack(loop, caller, "DF1TDCConfig");
1805  AddToCallStack(loop, caller, "DF1TDCHit");
1806 }
1807 
1808 //----------------
1809 // AddCAEN1290TDCObjectsToCallStack
1810 //----------------
1811 void DTranslationTable::AddCAEN1290TDCObjectsToCallStack(JEventLoop *loop, string caller) const
1812 {
1813  AddToCallStack(loop, caller, "DCAEN1290TDCConfig");
1814  AddToCallStack(loop, caller, "DCAEN1290TDCHit");
1815 }
1816 
1817 //----------------
1818 // AddToCallStack
1819 //----------------
1820 void DTranslationTable::AddToCallStack(JEventLoop *loop,
1821  string caller, string callee) const
1822 {
1823  /// This is used to give information to JANA regarding the relationship and
1824  /// origin of some of these data objects. This is really just needed so that
1825  /// the janadot program can be used to produce the correct callgraph. Because
1826  /// of how this plugin works, JANA can't record the correct call stack (at
1827  /// least not easily!) Therefore, we have to give it a little help here.
1828 
1829  JEventLoop::call_stack_t cs;
1830  cs.start_time = cs.end_time = 0.0;
1831  cs.caller_name = caller;
1832  cs.callee_name = callee;
1833  cs.data_source = JEventLoop::DATA_FROM_CACHE;
1834  loop->AddToCallStack(cs);
1835  cs.callee_name = cs.caller_name;
1836  cs.caller_name = "<ignore>";
1837  cs.data_source = JEventLoop::DATA_FROM_FACTORY;
1838  loop->AddToCallStack(cs);
1839 }
1840 
1841 //----------------------------------------------------------------------------
1842 //----------------------------------------------------------------------------
1843 // The following routines access the translation table
1844 //----------------------------------------------------------------------------
1845 //----------------------------------------------------------------------------
1846 
1848 static void StartElement(void *userData, const char *xmlname, const char **atts);
1849 static void EndElement(void *userData, const char *xmlname);
1850 
1851 
1852 //---------------------------------
1853 // ReadTranslationTable
1854 //---------------------------------
1856 {
1857  // It seems expat is not thread safe so we lock a mutex here and
1858  // read in the translation table just once
1859  pthread_mutex_lock(&Get_TT_Mutex());
1860  if (Get_TT_Initialized()) {
1861  pthread_mutex_unlock(&Get_TT_Mutex());
1862  return;
1863  }
1864 
1865  // String to hold entire XML translation table
1866  string tt_xml;
1867 
1868  // Try getting it from CCDB first
1869  if (jcalib && !NO_CCDB) {
1870  map<string,string> tt;
1871  string namepath = "Translation/DAQ2detector";
1872  jout << "Reading translation table from calib DB: " << namepath << " ..." << std::endl;
1873  jcalib->GetCalib(namepath, tt);
1874  if (tt.size() != 1) {
1875  jerr << " Error: Unexpected translation table format!" << std::endl;
1876  jerr << " tt.size()=" << tt.size() << " (expected 1)" << std::endl;
1877  }else{
1878  // Copy table into tt string
1879  map<string,string>::iterator iter = tt.begin();
1880  tt_xml = iter->second;
1881  }
1882  }
1883 
1884  // If getting from CCDB fails, try just reading in local file
1885  if (tt_xml.size() == 0) {
1886  if (!NO_CCDB) jout << "Unable to get translation table from CCDB." << std::endl;
1887  jout << "Will try reading TT from local file: " << XML_FILENAME << std::endl;
1888 
1889  // Open file
1890  ifstream ifs(XML_FILENAME.c_str());
1891  if (! ifs.is_open()) {
1892  jerr << " Error: Cannot open file! Translation table unavailable." << std::endl;
1893  pthread_mutex_unlock(&Get_TT_Mutex());
1894  return;
1895  }
1896 
1897  // read lines into stringstream object
1898  stringstream ss;
1899  while (ifs.good()) {
1900  char line[4096];
1901  ifs.getline(line, 4096);
1902  ss << line;
1903  }
1904 
1905  // Close file
1906  ifs.close();
1907 
1908  // Copy from stringstream to tt
1909  tt_xml = ss.str();
1910  }
1911 
1912  // If a ROCID by system map exists it probably means the user
1913  // specified particular systems to parse and the default map
1914  // has to be installed above in SetSystemsToParse. Make a copy
1915  // and clear the map so that it can be filled while parsing.
1916  // After, we can compare the two and warn the user if there's
1917  // a descrepancy.
1918  auto save_rocid_map = Get_ROCID_By_System();
1919  Get_ROCID_By_System().clear();
1920 
1921  // create parser and specify element handlers
1922  XML_Parser xmlParser = XML_ParserCreate(NULL);
1923  if (xmlParser == NULL) {
1924  jerr << "readTranslationTable...unable to create parser" << std::endl;
1925  exit(EXIT_FAILURE);
1926  }
1927  XML_SetElementHandler(xmlParser,StartElement,EndElement);
1928  XML_SetUserData(xmlParser, &Get_TT());
1929 
1930  // Parse XML string
1931  int status=XML_Parse(xmlParser, tt_xml.c_str(), tt_xml.size(), 1); // "1" indicates this is the final piece of XML
1932  if (status == 0) {
1933  jerr << " ?readTranslationTable...parseXMLFile parse error for " << XML_FILENAME << std::endl;
1934  jerr << XML_ErrorString(XML_GetErrorCode(xmlParser)) << std::endl;
1935  }
1936 
1937  // Check if there was a rocid map prior to parsing and
1938  // if so, compare the 2.
1939  if( !save_rocid_map.empty() ){
1940  if( save_rocid_map != Get_ROCID_By_System() ){
1941  jerr << "The rocid by system map read from the translation table in" << endl;
1942  jerr << "the CCDB differs from the default. This may happen if you" << endl;
1943  jerr << "specified EVIO:SYSTEMS_TO_PARSE and the hardcoded table is" << endl;
1944  jerr << "out of date. If this is the case, you'll need to modify" << endl;
1945  jerr << "DTranslationTable.cc or just run without specifying which" << endl;
1946  jerr << "systems to parse." << endl;
1947  for(auto it : Get_ROCID_By_System()){
1948  cerr << " " << DetectorName((Detector_t)it.first) << ": CCDB rocids=" << Get_ROCID_By_System()[it.first].size() << " hardcoded rocids=" << save_rocid_map[it.first].size() << endl;
1949  cerr << " CCDB={";
1950  for(auto a : Get_ROCID_By_System()[it.first]) cerr << a <<", ";
1951  cerr << "} hardcoded={";
1952  for(auto a : save_rocid_map[it.first]) cerr << a <<", ";
1953  cerr << "}" << endl;
1954  }
1955  for(auto it : save_rocid_map){
1956  if(Get_ROCID_By_System().find(it.first) != Get_ROCID_By_System().end()) continue;
1957  cerr << " " << DetectorName((Detector_t)it.first) << ": CCDB rocids=" << Get_ROCID_By_System()[it.first].size() << " hardcoded rocids=" << save_rocid_map[it.first].size() << endl;
1958  cerr << " CCDB={";
1959  for(auto a : Get_ROCID_By_System()[it.first]) cerr << a <<", ";
1960  cerr << "} hardcoded={";
1961  for(auto a : save_rocid_map[it.first]) cerr << a <<", ";
1962  cerr << "}" << endl;
1963  }
1964  exit(-1);
1965  }
1966  }
1967 
1968  jout << Get_TT().size() << " channels defined in translation table" << std::endl;
1969  XML_ParserFree(xmlParser);
1970 
1971  pthread_mutex_unlock(&Get_TT_Mutex());
1972  Get_TT_Initialized() = true;
1973 }
1974 
1975 //---------------------------------
1976 // DetectorStr2DetID
1977 //---------------------------------
1979 {
1980  if ( type == "fdc_cathodes" ) {
1982  } else if ( type == "fdc_wires" ) {
1984  } else if ( type == "bcal" ) {
1985  return DTranslationTable::BCAL;
1986  } else if ( type == "cdc" ) {
1987  return DTranslationTable::CDC;
1988  } else if ( type == "fcal" ) {
1989  return DTranslationTable::FCAL;
1990  } else if ( type == "ccal" ) {
1991  return DTranslationTable::CCAL;
1992  } else if ( type == "ccal_ref" ) {
1994  } else if ( type == "ps" ) {
1995  return DTranslationTable::PS;
1996  } else if ( type == "psc" ) {
1997  return DTranslationTable::PSC;
1998  } else if ( type == "rf" ) {
1999  return DTranslationTable::RF;
2000  } else if ( type == "st" ) {
2001  // The start counter is labelled by "ST" in the translation table
2002  // but we stick with the "SC" label in this plugin for consistency
2003  // with the rest of the reconstruction software
2004  return DTranslationTable::SC;
2005  } else if ( type == "tagh" ) {
2006  return DTranslationTable::TAGH;
2007  } else if ( type == "tagm" ) {
2008  return DTranslationTable::TAGM;
2009  } else if ( type == "tof" ) {
2010  return DTranslationTable::TOF;
2011  } else if ( type == "tpol" ) {
2013  } else if ( type == "tac" ) {
2014  return DTranslationTable::TAC;
2015  } else if ( type == "dirc" ) {
2016  return DTranslationTable::DIRC;
2017  } else
2018  {
2020  }
2021 }
2022 
2023 //---------------------------------
2024 // StartElement
2025 //---------------------------------
2026 void StartElement(void *userData, const char *xmlname, const char **atts)
2027 {
2028  static int crate=0, slot=0;
2029 
2030  static string type,Type;
2031  int mc2codaType= 0;
2032  int channel = 0;
2033  string Detector, locSystem;
2034  int end=0;
2035  int row=0,column=0,module=0,sector=0,layer=0;
2036  int ring=0,straw=0,plane=0,bar=0;
2037  int package=0,chamber=0,view=0,strip=0,wire=0;
2038  int id=0, strip_type=0;
2039  int side=0;
2040  int pixel=0;
2041 
2042  // This complicated line just recasts the userData pointer into
2043  // a reference to the "TT" member of the DTranslationTable object
2044  // that called us.
2045  map<DTranslationTable::csc_t, DTranslationTable::DChannelInfo> &TT = *((map<DTranslationTable::csc_t, DTranslationTable::DChannelInfo>*)userData);
2046 
2047  // store crate summary info, fill both maps
2048  if (strcasecmp(xmlname,"halld_online_translation_table") == 0) {
2049  // do nothing
2050 
2051  } else if (strcasecmp(xmlname,"crate") == 0) {
2052  for (int i=0; atts[i]; i+=2) {
2053  if (strcasecmp(atts[i],"number") == 0) {
2054  crate = atoi(atts[i+1]);
2055  break;
2056  }
2057  }
2058 
2059  } else if (strcasecmp(xmlname,"slot") == 0) {
2060  for (int i=0; atts[i]; i+=2) {
2061  if (strcasecmp(atts[i],"number") == 0) {
2062  slot = atoi(atts[i+1]);
2063  } else if (strcasecmp(atts[i],"type") == 0) {
2064  Type = string(atts[i+1]);
2065  type = string(atts[i+1]);
2066  std::transform(type.begin(), type.end(), type.begin(), (int(*)(int)) tolower);
2067  }
2068  }
2069 
2070  // The detID value set here shows up in the header of the Data Block Bank
2071  // of the output file. It should be set to one if this crate has JLab
2072  // made modules that output in the standard format (see document:
2073  // "VME Data Format Standards for JLAB Modules"). These would include
2074  // f250ADC, f125ADC, F1TDC, .... Slots containing other types of modules
2075  // (e.g. CAEN1290) should have their own unique detID. We use detID of
2076  // zero for non-digitizing modules like CPUs nd TIDs even though potentially,
2077  // one could read data from these.
2078 // mc2codaType = ModuleStr2ModID(type);
2079 
2080  } else if (strcasecmp(xmlname,"channel") == 0) {
2081 
2082  for (int i=0; atts[i]; i+=2) {
2083  string tag(atts[i+0]);
2084  string sval(atts[i+1]);
2085  int ival = atoi(atts[i+1]);
2086 
2087  if (tag == "number")
2088  channel = ival;
2089  else if (tag == "detector")
2090  Detector = sval;
2091  else if (tag == "row")
2092  row = ival;
2093  else if (tag == "column")
2094  column = ival;
2095  else if (tag == "col")
2096  column = ival;
2097  else if (tag == "module")
2098  module = ival;
2099  else if (tag == "sector")
2100  sector = ival;
2101  else if (tag == "layer")
2102  layer = ival;
2103  else if (tag == "chan");
2104 // chan = ival;
2105  else if (tag == "ring")
2106  ring = ival;
2107  else if (tag == "straw")
2108  straw = ival;
2109  else if (tag == "gPlane");
2110 // gPlane = ival;
2111  else if (tag == "element");
2112 // element = ival;
2113  else if (tag == "plane")
2114  plane = ival;
2115  else if (tag == "bar")
2116  bar = ival;
2117  else if (tag == "package")
2118  package = ival;
2119  else if (tag == "chamber")
2120  chamber = ival;
2121  else if (tag == "view") {
2122  if (sval == "U")
2123  view=1;
2124  else if (sval == "D")
2125  view=3;
2126  }
2127  else if (tag == "strip")
2128  strip = ival;
2129  else if (tag == "wire")
2130  wire = ival;
2131  else if (tag == "side") {
2132  if (sval == "A") {
2133  side = DPSGeometry::kNorth;
2134  }
2135  else if (sval == "B") {
2136  side = DPSGeometry::kSouth;
2137  }
2138  }
2139  else if (tag == "pixel") {
2140  pixel = ival;
2141  }
2142  else if (tag == "id")
2143  id = ival;
2144  else if (tag == "end") {
2145  if (sval == "U") {
2147  view=1;
2148  }
2149  else if (sval == "D") {
2151  view=3;
2152  }
2153  else if (sval == "N")
2154  end = 0; // TOF north
2155  else if (sval == "S")
2156  end = 1; // TOF south
2157  else if (sval == "UP")
2158  end = 0; // TOF up
2159  else if (sval == "DW")
2160  end = 1; // TOF down
2161  }
2162  else if (tag == "strip_type") {
2163  if (sval == "full")
2164  strip_type = 1;
2165  else if (sval == "A")
2166  strip_type = 2;
2167  else if (sval == "B")
2168  strip_type = 3;
2169  }
2170  else if (tag == "system")
2171  locSystem = sval;
2172  }
2173 
2174  // ignore certain module types
2175  if (type == "disc")
2176  return;
2177  if (type == "ctp")
2178  return;
2179  if (type == "sd")
2180  return;
2181  if (type == "a1535sn")
2182  return;
2183 
2184 
2185 // // Data integrity check
2186 // if (crate < 0 || crate >= MAXDCRATE) {
2187 // jerr << " Crate value of " << crate
2188 // << " is not in range 0 <= crate < " << MAXDCRATE << std::endl;
2189 // exit(-1);
2190 // }
2191 //
2192 // if (slot < 0 || slot >= MAXDSLOT) {
2193 // jerr << " Slot value of " << slot
2194 // << " is not in range 0 <= slot < " << MAXDSLOT << std::endl;
2195 // exit(-1);
2196 // }
2197 //
2198 // if (channel < 0 || channel >= MAXDCHANNEL) {
2199 // jerr << " Crate value of " << channel
2200 // << " is not in range 0 <= channel < " << MAXDCHANNEL << std::endl;
2201 // exit(-1);
2202 // }
2203 
2204  // fill maps
2205 
2206  DTranslationTable::csc_t csc = {(uint32_t)crate,(uint32_t)slot,(uint32_t)channel};
2207  string detector = Detector;
2208  std::transform(detector.begin(), detector.end(), detector.begin(), (int(*)(int)) tolower);
2209 
2210  //string s="unknown::";
2211 
2212  // Common indexes
2213  DTranslationTable::DChannelInfo &ci = TT[csc];
2214  ci.CSC = csc;
2215  ci.module_type = (DModuleType::type_id_t)mc2codaType;
2216  ci.det_sys = DetectorStr2DetID(detector);
2217  DTranslationTable::Get_ROCID_By_System()[ci.det_sys].insert(crate);
2218 
2219  // detector-specific indexes
2220  switch (ci.det_sys) {
2222  ci.bcal.module = module;
2223  ci.bcal.layer = layer;
2224  ci.bcal.sector = sector;
2225  ci.bcal.end = end;
2226  break;
2228  ci.cdc.ring = ring;
2229  ci.cdc.straw = straw;
2230  break;
2232  ci.fcal.row = row;
2233  ci.fcal.col = column;
2234  break;
2236  ci.ccal.row = row;
2237  ci.ccal.col = column;
2238  break;
2240  ci.ccal_ref.id = id;
2241  break;
2243  ci.fdc_cathodes.package = package;
2244  ci.fdc_cathodes.chamber = chamber;
2245  ci.fdc_cathodes.view = view;
2246  ci.fdc_cathodes.strip = strip;
2247  ci.fdc_cathodes.strip_type = strip_type;
2248  break;
2250  ci.fdc_wires.package = package;
2251  ci.fdc_wires.chamber = chamber;
2252  ci.fdc_wires.wire = wire;
2253  break;
2254  case DTranslationTable::RF:
2255  ci.rf.dSystem = NameToSystem(locSystem.c_str());
2256  break;
2257  case DTranslationTable::SC:
2258  ci.sc.sector = sector;
2259  break;
2261  ci.tagh.id = id;
2262  break;
2264  ci.tagm.col = column;
2265  ci.tagm.row = row;
2266  break;
2268  ci.tof.plane = plane;
2269  ci.tof.bar = bar;
2270  ci.tof.end = end;
2271  break;
2272  case DTranslationTable::PS:
2273  ci.ps.side = side;
2274  ci.ps.id = id;
2275  break;
2277  ci.psc.id = id;
2278  break;
2280  ci.tpolsector.sector = sector;
2281  break;
2283 // ci.tac;
2284  break;
2286  ci.dirc.pixel = pixel;
2287  break;
2289  default:
2290  break;
2291  }
2292 
2293  } else {
2294  jerr << std::endl << std::endl
2295  << "?startElement...unknown xml tag " << xmlname
2296  << std::endl << std::endl;
2297  }
2298 
2299 }
2300 
2301 
2302 //--------------------------------------------------------------------------
2303 
2304 
2305 void EndElement(void *userData, const char *xmlname) {
2306  // nothing to do yet...
2307 }
2308 
2309 
2310 //--------------------------------------------------------------------------
DFDCCathodeDigiHit * MakeFDCCathodeDigiHit(const FDC_CathodesIndex_t &idx, const Df125PulseIntegral *pi, const Df125PulseTime *pt, const Df125PulsePedestal *pp) const
DCCALRefDigiHit * MakeCCALRefDigiHit(const CCALRefIndex_t &idx, const Df250PulseData *pd) const
DSCDigiHit * MakeSCDigiHit(const SCIndex_t &idx, const Df250PulseData *pd) const
uint32_t first_max_amp
from second word
Definition: Df125CDCPulse.h:68
DPSDigiHit * MakePSDigiHit(const PSIndex_t &idx, const Df250PulseData *pd) const
int counter_id
counter id 1-274
Definition: DTAGHDigiHit.h:18
DTAGMDigiHit * MakeTAGMDigiHit(const TAGMIndex_t &idx, const Df250PulseData *pd) const
DBCALTDCDigiHit * MakeBCALTDCDigiHit(const BCALIndex_t &idx, const DF1TDCHit *hit) const
void ApplyTranslationTable(jana::JEventLoop *loop) const
int column
column number 1-102
map< uint32_t, uint32_t > & Get_ROCID_Map(void) const
DetectorSystem_t dSystem
Definition: DRFDigiTime.h:24
uint32_t fine_time
DCDCDigiHit * MakeCDCDigiHit(const CDCIndex_t &idx, const Df125PulseIntegral *pi, const Df125PulseTime *pt, const Df125PulsePedestal *pp) const
static DTranslationTable::Detector_t DetectorStr2DetID(string &type)
bool operator<(const DSourceComboUse &lhs, const DSourceComboUse &rhs)
Definition: DSourceCombo.h:95
DPSCDigiHit * MakePSCDigiHit(const PSCIndex_t &idx, const Df250PulseData *pd) const
DTACDigiHit * MakeTACDigiHit(const TACIndex_t &idx, const Df250PulseData *pd) const
Int_t layer
int sector
sector number 1-24
Definition: DSCTDCDigiHit.h:19
DDIRCTDCDigiHit * MakeDIRCTDCDigiHit(const DIRCIndex_t &idx, const DDIRCTDCHit *hit) const
DBCALDigiHit * MakeBCALDigiHit(const BCALIndex_t &idx, const Df250PulseData *pd) const
char string[256]
uint32_t peak_amp
from second word (type 9)
Definition: Df125FDCPulse.h:72
static map< DTranslationTable::Detector_t, set< uint32_t > > & Get_ROCID_By_System(void)
uint32_t pulse_integral
identified pulse integral as returned by FPGA algorithm
uint32_t pedestal
from second word
Definition: Df125CDCPulse.h:66
uint32_t integral
from second word (type 6)
Definition: Df125FDCPulse.h:71
void AddROCIDtoParseList(uint32_t rocid)
uint32_t QF
Quality Factor from FPGA algorithms.
DSCTDCDigiHit * MakeSCTDCDigiHit(const SCIndex_t &idx, const DF1TDCHit *hit) const
uint32_t overflow_count
from first word
Definition: Df125CDCPulse.h:65
DPSCTDCDigiHit * MakePSCTDCDigiHit(const PSCIndex_t &idx, const DF1TDCHit *hit) const
int bar
bar number
int counter_id
counter id 1-274
void Addf125CDCObjectsToCallStack(JEventLoop *loop, string caller, bool addpulseobjs) const
uint32_t pulse_peak
from Pulse Pedestal Data word
void AddROCIDtoParseList(uint32_t rocid)
DCCALDigiHit * MakeCCALDigiHit(const CCALIndex_t &idx, const Df250PulseData *pd) const
bool & Get_TT_Initialized(void) const
void Addf250ObjectsToCallStack(JEventLoop *loop, string caller) const
Definition: CDC.h:14
uint32_t le_time
from first word
Definition: Df125CDCPulse.h:63
uint32_t pulse_time
identified pulse time as returned by FPGA algorithm
Definition: DCDCDigiHit.h:22
string Channel2Str(const DChannelInfo &in_channel) const
uint32_t nsamples_pedestal
number of samples used in integral
Definition: Df125CDCPulse.h:71
DTAGMTDCDigiHit * MakeTAGMTDCDigiHit(const TAGMIndex_t &idx, const DF1TDCHit *hit) const
DBCALGeometry::End end
Definition: DBCALDigiHit.h:28
bool SortBCALDigiHit(const DBCALDigiHit *a, const DBCALDigiHit *b)
DRFDigiTime * MakeRFDigiTime(const RFIndex_t &idx, const Df250PulseData *pd) const
uint32_t pedestal
pedestal info used by FPGA (if any)
uint32_t le_time
from first word
Definition: Df125FDCPulse.h:67
uint32_t nsamples_integral
number of samples used in integral
Definition: DCDCDigiHit.h:25
static void EndElement(void *userData, const char *xmlname)
DTOFDigiHit * MakeTOFDigiHit(const TOFIndex_t &idx, const Df250PulseData *pd) const
const bool VERBOSE
DTOFTDCDigiHit * MakeTOFTDCDigiHit(const TOFIndex_t &idx, const DCAEN1290TDCHit *hit) const
const DChannelInfo & GetDetectorIndex(const csc_t &in_daq_index) const
#define TAGM
Definition: PSEcorr.C:20
DetectorSystem_t NameToSystem(const char *locSystemName)
Definition: GlueX.h:105
How this Event Source Works
DTAGHDigiHit * MakeTAGHDigiHit(const TAGHIndex_t &idx, const Df250PulseData *pd) const
uint32_t pulse_integral
identified pulse integral as returned by FPGA algorithm
Definition: DCDCDigiHit.h:21
void Addf125FDCObjectsToCallStack(JEventLoop *loop, string caller, bool addpulseobjs) const
DPSGeometry::Arm arm
Definition: DPSDigiHit.h:19
const csc_t & GetDAQIndex(const DChannelInfo &in_channel) const
string XML_FILENAME
Definition: hddm2root.cc:17
DRFTDCDigiTime * MakeRFTDCDigiTime(const RFIndex_t &idx, const DF1TDCHit *hit) const
DFDCWireDigiHit * MakeFDCWireDigiHit(const FDC_WiresIndex_t &idx, const DF1TDCHit *hit) const
DBCALGeometry::End end
DTAGHTDCDigiHit * MakeTAGHTDCDigiHit(const TAGHIndex_t &idx, const DF1TDCHit *hit) const
uint32_t time_quality_bit
from first word
Definition: Df125CDCPulse.h:64
uint32_t time_quality_bit
from first word
Definition: Df125FDCPulse.h:68
DTranslationTable(JEventLoop *loop)
uint32_t time
Definition: DRFDigiTime.h:25
DetectorSystem_t dSystem
const char * SystemName(DetectorSystem_t sys)
Definition: GlueX.h:38
int sector
Definition: DSCDigiHit.h:18
uint32_t pulse_time
identified pulse time as returned by FPGA algorithm
uint32_t time
from Pulse Time Data word
Definition: FCAL.h:14
uint32_t QF
Quality Factor from FPGA algorithms.
Definition: DCDCDigiHit.h:24
pthread_mutex_t & Get_TT_Mutex(void) const
map< DTranslationTable::csc_t, DTranslationTable::DChannelInfo > & Get_TT(void) const
int end
left/right 0/1 or North/South 0/1
void ReadTranslationTable(JCalibration *jcalib=NULL)
void AddF1TDCObjectsToCallStack(JEventLoop *loop, string caller) const
DTACTDCDigiHit * MakeTACTDCDigiHit(const TACIndex_t &idx, const DCAEN1290TDCHit *hit) const
#define TAGH
Definition: PSEcorr.C:21
uint32_t pedestal
from second word
Definition: Df125FDCPulse.h:70
uint32_t channel
Definition: DDAQAddress.h:34
void AddCAEN1290TDCObjectsToCallStack(JEventLoop *loop, string caller) const
int column
Definition: DPSDigiHit.h:20
uint32_t nsamples_integral
number of samples used in pedestal
Definition: Df125FDCPulse.h:77
void ReadOptionalROCidTranslation(void)
uint32_t nsamples_pedestal
number of samples used in pedestal
uint32_t nsamples_integral
number of samples used in pedestal
Definition: Df125CDCPulse.h:72
uint32_t nsamples_integral
number of samples used in integral
uint32_t rocid
Definition: DDAQAddress.h:32
uint32_t course_time
uint32_t pulse_time
identified pulse time as returned by FPGA algorithm
Definition: DBCALDigiHit.h:31
uint32_t nsamples_pedestal
number of samples used in pedestal
Definition: DCDCDigiHit.h:26
The JEventSource_EVIO class implements a JEventSource capable of reading in EVIO data from raw data f...
int counter_id
Definition: DPSCDigiHit.h:18
int plane
plane (0: vertical, 1: horizontal)
DTPOLSectorDigiHit * MakeTPOLSectorDigiHit(const TPOLSECTORIndex_t &idx, const Df250PulseData *pd) const
static void StartElement(void *userData, const char *xmlname, const char **atts)
uint32_t integral
from second word
Definition: Df125CDCPulse.h:67
static void SetSystemsToParse(string systems, JEventSource *eventsource)
uint32_t pedestal
pedestal info used by FPGA (if any)
Definition: DCDCDigiHit.h:23
int row
row number 1-5
Definition: TOF.h:14
uint32_t pulse_peak
identified pulse first peak as returned by FPGA algorithm (could be either Df125CDCPulse::first_max_a...
Definition: DCDCDigiHit.h:20
void AddToCallStack(JEventLoop *loop, string caller, string callee) const
map< uint32_t, uint32_t > & Get_ROCID_Inv_Map(void) const
uint32_t nsamples_pedestal
number of samples used in integral
Definition: Df125FDCPulse.h:76
uint32_t overflow_count
from first word
Definition: Df125FDCPulse.h:69
uint32_t slot
Definition: DDAQAddress.h:33
DFCALDigiHit * MakeFCALDigiHit(const FCALIndex_t &idx, const Df250PulseData *pd) const