Bug Summary

File:libraries/TTAB/DTranslationTable.cc
Location:line 1610, column 7
Description:Value stored to 'mc2codaType' is never read

Annotated Source Code

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>
15#include <PAIR_SPECTROMETER/DPSGeometry.h>
16
17using namespace jana;
18using namespace std;
19
20// Use one translation table for all threads
21pthread_mutex_t& DTranslationTable::Get_TT_Mutex(void) const
22{
23 static pthread_mutex_t tt_mutex = PTHREAD_MUTEX_INITIALIZER{ { 0, 0, 0, 0, 0, 0, { 0, 0 } } };
24 return tt_mutex;
25}
26
27bool& DTranslationTable::Get_TT_Initialized(void) const
28{
29 static bool tt_initialized = false;
30 return tt_initialized;
31}
32
33map<DTranslationTable::csc_t, DTranslationTable::DChannelInfo>& DTranslationTable::Get_TT(void) const
34{
35 static map<DTranslationTable::csc_t, DTranslationTable::DChannelInfo> TT;
36 return TT;
37}
38
39map<uint32_t, uint32_t>& DTranslationTable::Get_ROCID_Map(void) const
40{
41 static map<uint32_t, uint32_t> rocid_map; // (see ReadOptionalROCidTranslation() for details)
42 return rocid_map;
43}
44
45map<uint32_t, uint32_t>& DTranslationTable::Get_ROCID_Inv_Map(void) const
46{
47 static map<uint32_t, uint32_t> rocid_inv_map; // (see ReadOptionalROCidTranslation() for details)
48 return rocid_inv_map;
49}
50
51map<DTranslationTable::Detector_t, set<uint32_t> >& DTranslationTable::Get_ROCID_By_System(void)
52{
53 static map<DTranslationTable::Detector_t, set<uint32_t> > rocid_by_system;
54 return rocid_by_system;
55}
56
57//...................................
58// Less than operator for csc_t data types. This is used by
59// the map<csc_t, XX> to order the entires by key
60bool operator<(const DTranslationTable::csc_t &a, const DTranslationTable::csc_t &b) {
61 if (a.rocid < b.rocid) return true;
62 if (a.rocid > b.rocid) return false;
63 if (a.slot < b.slot) return true;
64 if (a.slot > b.slot) return false;
65 if (a.channel < b.channel) return true;
66 return false;
67}
68
69//...................................
70// sort functions
71bool SortBCALDigiHit(const DBCALDigiHit *a, const DBCALDigiHit *b) {
72 if (a->module == b->module) {
73 if (a->layer == b->layer) {
74 if (a->sector == b->sector) {
75 if (a->end == b->end) {
76 return a->pulse_time < b->pulse_time;
77 }else{ return a->end < b->end; }
78 }else{ return a->sector < b->sector; }
79 }else{ return a->layer< b->layer; }
80 }else { return a->module < b->module; }
81}
82
83//---------------------------------
84// DTranslationTable (Constructor)
85//---------------------------------
86DTranslationTable::DTranslationTable(JEventLoop *loop)
87{
88 // Default is to just read translation table from CCDB. If this fails,
89 // then an attempt will be made to read from a file on the local disk.
90 // The filename can be specified to be anything, but if the user specifies
91 // this, then we assume that they want to use it and skip using the CCDB.
92 // They may also specify that they want to skip checking the CCDB via
93 // the "TT:NO_CCDB" parameter. This would only be useful if they want to
94 // force the use of a local file named "tt.xml".
95 NO_CCDB = false;
96 XML_FILENAME = "tt.xml";
97 VERBOSE = 0;
98 SYSTEMS_TO_PARSE = "";
99 gPARMS->SetDefaultParameter("TT:NO_CCDB", NO_CCDB,
100 "Don't try getting translation table from CCDB and just look"
101 " for file. Only useful if you want to force reading tt.xml."
102 " This is automatically set if you specify a different"
103 " filename via the TT:XML_FILENAME parameter.");
104 JParameter *p = gPARMS->SetDefaultParameter("TT:XML_FILENAME", XML_FILENAME,
105 "Fallback filename of translation table XML file."
106 " If set to non-default, CCDB will not be checked.");
107 if (p->GetDefault() != p->GetValue())
108 NO_CCDB = true;
109 gPARMS->SetDefaultParameter("TT:VERBOSE", VERBOSE,
110 "Verbosity level for Applying Translation Table."
111 " 0=no messages, 10=all messages.");
112
113 ROCID_MAP_FILENAME = "rocid.map";
114 gPARMS->SetDefaultParameter("TT:ROCID_MAP_FILENAME", ROCID_MAP_FILENAME,
115 "Optional rocid to rocid conversion map for use with files"
116 " generated with the non-standard rocid's");
117
118 gPARMS->SetDefaultParameter("TT:SYSTEMS_TO_PARSE", SYSTEMS_TO_PARSE,
119 "Comma separated list of systems to parse EVIO data for. "
120 "Default is empty string which means to parse all. System "
121 "names should be what is returned by DTranslationTable::DetectorName() .");
122
123 // Initialize dedicated JStreamLog used for debugging messages
124 ttout.SetTag("--- TT ---: ");
125 ttout.SetTimestampFlag();
126 ttout.SetThreadstampFlag();
127
128 // Look for and read in an optional rocid <-> rocid translation table
129 ReadOptionalROCidTranslation();
130
131 // Read in Translation table. This will create DChannelInfo objects
132 // and store them in the "TT" map, indexed by csc_t objects
133 ReadTranslationTable(loop->GetJCalibration());
134
135 // These are used to help the event source report which
136 // types of data it is capable of providing. For practical
137 // purposes, these types are "provided" by the source
138 // because they are generated and placed into their
139 // respective JANA factories during a call to GetObjects().
140 // The source is responsible for reporting the types it is
141 // directly responsible for (e.g. Df250PulseIntegral)
142 supplied_data_types.insert("DBCALDigiHit");
143 supplied_data_types.insert("DBCALTDCDigiHit");
144 supplied_data_types.insert("DCDCDigiHit");
145 supplied_data_types.insert("DFCALDigiHit");
146 supplied_data_types.insert("DFDCCathodeDigiHit");
147 supplied_data_types.insert("DFDCWireDigiHit");
148 supplied_data_types.insert("DRFDigiTime");
149 supplied_data_types.insert("DSCDigiHit");
150 supplied_data_types.insert("DSCTDCDigiHit");
151 supplied_data_types.insert("DTOFDigiHit");
152 supplied_data_types.insert("DTOFTDCDigiHit");
153 supplied_data_types.insert("DTAGMDigiHit");
154 supplied_data_types.insert("DTAGMTDCDigiHit");
155 supplied_data_types.insert("DTAGHDigiHit");
156 supplied_data_types.insert("DTAGHTDCDigiHit");
157 supplied_data_types.insert("DPSDigiHit");
158 supplied_data_types.insert("DPSCDigiHit");
159 supplied_data_types.insert("DPSCTDCDigiHit");
160 supplied_data_types.insert("DTPOLSectorDigiHit");
161}
162
163//---------------------------------
164// ~DTranslationTable (Destructor)
165//---------------------------------
166DTranslationTable::~DTranslationTable()
167{
168
169}
170
171//---------------------------------
172// IsSuppliedType
173//---------------------------------
174bool DTranslationTable::IsSuppliedType(string dataClassName) const
175{
176 return (supplied_data_types.find(dataClassName) != supplied_data_types.end());
177}
178
179//---------------------------------
180// ReadOptionalROCidTranslation
181//---------------------------------
182void DTranslationTable::ReadOptionalROCidTranslation(void)
183{
184 // Some data may be taken with the ROC ID value set
185 // incorrectly in CODA. For CODA 3.0 data, there is
186 // actually no way to set it so it can be different
187 // for every CODA configuration. A simple work-around
188 // for this is to use a map file to list the translation
189 // from the crate numbers used in the evio file to those
190 // stored in the TT. Check here if a local file exists
191 // with the name specified by the TT:ROCID_MAP_FILENAME
192 // config parameter (default is "rocid.map"). If so,
193 // read it in. The format is just 2 values per line.
194 // The first is the rocid in the evio file, and the
195 // second, what the rocid is in the TT. Note that the
196 // value of the crate copied into the data objects
197 // will be what is in the EVIO file.
198 ifstream ifs(ROCID_MAP_FILENAME.c_str());
199 if (!ifs.is_open()) return;
200
201 std::cout << "Opened ROC id translation map: " << ROCID_MAP_FILENAME << std::endl;
202 while (ifs.good()) {
203 char line[256];
204 ifs.getline(line, 256);
205 if (ifs.gcount() < 1) break;
206 if (line[0] == '#') continue;
207
208 stringstream ss(line);
209 uint32_t from=10000, to=10000;
210 ss >> from >> to; // from=evio to=TT
211 if ( to == 10000 ) {
212 if ( from != 10000) {
213 std::cout << "unable to convert line:" << std::endl;
214 std::cout << " " << line;
215 }
216 }else{
217 Get_ROCID_Map()[from] = to;
218 Get_ROCID_Inv_Map()[to] = from;
219 }
220 }
221 ifs.close();
222
223 if (Get_ROCID_Map().size() == Get_ROCID_Inv_Map().size()) {
224 std::cout << " Read " << Get_ROCID_Map().size() << " entries" << std::endl;
225 map<uint32_t,uint32_t>::iterator iter;
226 for (iter=Get_ROCID_Map().begin(); iter != Get_ROCID_Map().end(); iter++) {
227 std::cout << " rocid " << iter->first << " -> rocid "
228 << iter->second << std::endl;
229 }
230 }else{
231 std::cout << "Entries not unique! This can happen if there are"
232 << std::endl;
233 std::cout << "more than one entry with the same value (either"
234 << std::endl;
235 std::cout << "two keys or two vals the same.)"
236 << std::endl;
237 std::cout << "Please fix the file \"" << ROCID_MAP_FILENAME << "\"."
238 << std::endl;
239 exit(-1);
240 }
241}
242
243//---------------------------------
244// SetSystemsToParse
245//---------------------------------
246void DTranslationTable::SetSystemsToParse(string systems, JEventSource *eventsource)
247{
248 /// This takes a string of comma separated system names and
249 /// identifies a list of Detector_t values from this (using
250 /// strings returned by DetectorName() ). It then tries to
251 /// copy the value into the DAQ plugin so they can be used
252 /// to restrict which banks to parse.
253
254 if(systems == "") return; // nothing to do for empty strings
255
256 // Make sure this is a JEventSource_EVIO object pointer
257 JEventSource_EVIO *eviosource = dynamic_cast<JEventSource_EVIO*>(eventsource);
258 if(!eviosource) {
259 jerr << "eventsource not a JEventSource_EVIO object! Cannot restrict parsing list!" << endl;
260 return;
261 }
262
263#ifndef HAVE_EVIO1
264
265 // If we don't have EVIO, then the JEventSource_EVIO objects is crippled
266 // to the point where it can't be used. If this is the case, don't try
267 // doing anything else.
268
269#else // HAVE_EVIO
270
271 // Make map of system type id by name
272 map<string, Detector_t> name_to_id;
273 for(uint32_t dettype=UNKNOWN_DETECTOR; dettype<NUM_DETECTOR_TYPES; dettype++){
274 name_to_id[DetectorName((Detector_t)dettype)] = (Detector_t)dettype;
275 }
276
277 // Parse string of system names
278 std::istringstream ss(systems);
279 std::string token;
280 while(std::getline(ss, token, ',')) {
281
282 // Get initial list of rocids based on token
283 set<uint32_t> rocids = Get_ROCID_By_System()[name_to_id[token]];
284
285 // Let "FDC" be an alias for both cathode strips and wires
286 if(token == "FDC"){
287 set<uint32_t> rocids1 = Get_ROCID_By_System()[name_to_id["FDC_CATHODES"]];
288 set<uint32_t> rocids2 = Get_ROCID_By_System()[name_to_id["FDC_WIRES"]];
289 rocids.insert(rocids1.begin(), rocids1.end());
290 rocids.insert(rocids2.begin(), rocids2.end());
291 }
292
293 // More likely than not, someone specifying "PS" will also want "PSC"
294 if(token == "PS"){
295 set<uint32_t> rocids1 = Get_ROCID_By_System()[name_to_id["PSC"]];
296 rocids.insert(rocids1.begin(), rocids1.end());
297 }
298
299 set<uint32_t>::iterator it;
300 for(it=rocids.begin(); it!=rocids.end(); it++){
301
302 // Add this rocid to the DAQ parsing list
303 uint32_t rocid = *it;
304 eviosource->AddROCIDtoParseList(rocid);
305 if(VERBOSE>0) ttout << "Added rocid " << rocid << " for system " << token << " to parse list" << endl;
306 }
307 }
308
309#endif //HAVE_EVIO
310}
311
312//---------------------------------
313// ApplyTranslationTable
314//---------------------------------
315void DTranslationTable::ApplyTranslationTable(JEventLoop *loop) const
316{
317 /// This will get all of the low level objects and
318 /// generate detector hit objects from them, placing
319 /// them in the appropriate DANA factories.
320
321 if (VERBOSE > 0)
322 ttout << "Entering ApplyTranslationTable:" << std::endl;
323
324 // If the JANA call stack is being recorded, then temporarily disable it
325 // so calls we make to loop->Get() here are ignored. The reason we do this
326 // is because this routine is called while already in a loop->Get() call
327 // so JANA will treat all other loop->Get() calls we make as being dependencies
328 // of the loop->Get() call that we are already in. (Confusing eh?)
329 bool record_call_stack = loop->GetCallStackRecordingStatus();
330 if (record_call_stack) loop->DisableCallStackRecording();
331
332 // Containers to hold all of the detector-specific "Digi"
333 // objects. Once filled, these will be copied to the
334 // respective factories at the end of this method.
335 vector<DBCALDigiHit*> vbcal;
336 vector<DBCALTDCDigiHit*> vbcaltdc;
337 vector<DCDCDigiHit*> vcdc;
338 vector<DFCALDigiHit*> vfcal;
339 vector<DFDCCathodeDigiHit*> vfdccathode;
340 vector<DFDCWireDigiHit*> vfdcwire;
341 vector<DRFDigiTime*> vrf;
342 vector<DRFTDCDigiTime*> vrftdc;
343 vector<DSCDigiHit*> vsc;
344 vector<DSCTDCDigiHit*> vsctdc;
345 vector<DTOFDigiHit*> vtof;
346 vector<DTOFTDCDigiHit*> vtoftdc;
347 vector<DTAGMDigiHit*> vtagm;
348 vector<DTAGMTDCDigiHit*> vtagmtdc;
349 vector<DTAGHDigiHit*> vtagh;
350 vector<DTAGHTDCDigiHit*> vtaghtdc;
351 vector<DPSDigiHit*> vps;
352 vector<DPSCDigiHit*> vpsc;
353 vector<DPSCTDCDigiHit*> vpsctdc;
354 vector<DTPOLSectorDigiHit*> vtpolsector;
355
356 // Df250PulseIntegral (will apply Df250PulseTime via associated objects)
357 vector<const Df250PulseIntegral*> pulseintegrals250;
358 loop->Get(pulseintegrals250);
359 if (VERBOSE > 2)
360 ttout << " Number Df250PulseIntegral objects: "
361 << pulseintegrals250.size() << std::endl;
362 for (uint32_t i=0; i<pulseintegrals250.size(); i++) {
363 const Df250PulseIntegral *pi = pulseintegrals250[i];
364
365 // Apply optional rocid translation
366 uint32_t rocid = pi->rocid;
367 map<uint32_t, uint32_t>::iterator rocid_iter = Get_ROCID_Map().find(rocid);
368 if (rocid_iter != Get_ROCID_Map().end()) rocid = rocid_iter->second;
369
370 if (VERBOSE > 4)
371 ttout << " Looking for rocid:" << rocid << " slot:" << pi->slot
372 << " chan:" << pi->channel << std::endl;
373
374 // Create crate,slot,channel index and find entry in Translation table.
375 // If none is found, then just quietly skip this hit.
376 csc_t csc = {rocid, pi->slot, pi->channel};
377 map<csc_t, DChannelInfo>::const_iterator iter = Get_TT().find(csc);
378 if (iter == Get_TT().end()) {
379 if (VERBOSE > 6)
380 ttout << " - Didn't find it" << std::endl;
381 continue;
382 }
383 const DChannelInfo &chaninfo = iter->second;
384 if (VERBOSE > 6)
385 ttout << " - Found entry for: " << DetectorName(chaninfo.det_sys)
386 << std::endl;
387
388 // Check for a pulse time (this should have been added in JEventSource_EVIO.cc)
389 const Df250PulseTime *pt = NULL__null;
390 const Df250PulsePedestal *pp = NULL__null;
391 pi->GetSingle(pt);
392 pi->GetSingle(pp);
393
394 // Create the appropriate hit type based on detector type
395 switch (chaninfo.det_sys) {
396 case BCAL:
397 vbcal.push_back( MakeBCALDigiHit(chaninfo.bcal, pi, pt, pp) );
398 break;
399 case FCAL:
400 vfcal.push_back( MakeFCALDigiHit(chaninfo.fcal, pi, pt, pp) );
401 break;
402 case SC:
403 vsc.push_back ( MakeSCDigiHit( chaninfo.sc, pi, pt, pp) );
404 break;
405 case TOF:
406 vtof.push_back ( MakeTOFDigiHit( chaninfo.tof, pi, pt, pp) );
407 break;
408 case TAGM:
409 vtagm.push_back( MakeTAGMDigiHit(chaninfo.tagm, pi, pt, pp) );
410 break;
411 case TAGH:
412 vtagh.push_back( MakeTAGHDigiHit(chaninfo.tagh, pi, pt, pp) );
413 break;
414 case PS:
415 vps.push_back ( MakePSDigiHit(chaninfo.ps, pi, pt, pp) );
416 break;
417 case PSC:
418 vpsc.push_back ( MakePSCDigiHit(chaninfo.psc, pi, pt, pp) );
419 break;
420 case RF:
421 vrf.push_back( MakeRFDigiTime(chaninfo.rf, pt) );
422 break;
423 case TPOLSECTOR:
424 vtpolsector.push_back( MakeTPOLSectorDigiHit(chaninfo.tpolsector, pi, pt, pp) );
425 break;
426 default:
427 if (VERBOSE > 4)
428 ttout << " - Don't know how to make DigiHit objects"
429 << " for this detector type!" << std::endl;
430 break;
431 }
432 }
433
434 // Df125PulseIntegral (will apply Df125PulseTime via associated objects)
435 vector<const Df125PulseIntegral*> pulseintegrals125;
436 loop->Get(pulseintegrals125);
437 if (VERBOSE > 2)
438 ttout << " Number Df125PulseIntegral objects: "
439 << pulseintegrals125.size() << std::endl;
440 for (uint32_t i=0; i<pulseintegrals125.size(); i++) {
441 const Df125PulseIntegral *pi = pulseintegrals125[i];
442
443 // Apply optional rocid translation
444 uint32_t rocid = pi->rocid;
445 map<uint32_t, uint32_t>::iterator rocid_iter = Get_ROCID_Map().find(rocid);
446 if (rocid_iter != Get_ROCID_Map().end()) rocid = rocid_iter->second;
447
448 if (VERBOSE > 4)
449 ttout << " Looking for rocid:" << rocid << " slot:" << pi->slot
450 << " chan:" << pi->channel << std::endl;
451
452 // Create crate,slot,channel index and find entry in Translation table.
453 // If none is found, then just quietly skip this hit.
454 csc_t csc = {rocid, pi->slot, pi->channel};
455 map<csc_t, DChannelInfo>::const_iterator iter = Get_TT().find(csc);
456 if (iter == Get_TT().end()) {
457 if (VERBOSE > 6)
458 ttout << " - Didn't find it" << std::endl;
459 continue;
460 }
461 const DChannelInfo &chaninfo = iter->second;
462 if (VERBOSE > 6)
463 ttout << " - Found entry for: " << DetectorName(chaninfo.det_sys)
464 << std::endl;
465
466 // Check for a pulse time (this should have been added in JEventSource_EVIO.cc
467 const Df125PulseTime *pt = NULL__null;
468 const Df125PulsePedestal *pp = NULL__null;
469 pi->GetSingle(pt);
470 pi->GetSingle(pp);
471
472 // Create the appropriate hit type based on detector type
473 switch (chaninfo.det_sys) {
474 case CDC:
475 vcdc.push_back( MakeCDCDigiHit(chaninfo.cdc, pi, pt, pp) );
476 break;
477 case FDC_CATHODES:
478 vfdccathode.push_back( MakeFDCCathodeDigiHit(chaninfo.fdc_cathodes, pi, pt, pp) );
479 break;
480 default:
481 if (VERBOSE > 4)
482 ttout << " - Don't know how to make DigiHit"
483 << " objects for this detector type!" << std::endl;
484 break;
485 }
486 }
487
488 // Df125CDCPulse
489 vector<const Df125CDCPulse*> cdcpulses;
490 loop->Get(cdcpulses);
491 if (VERBOSE > 2)
492 ttout << " Number Df125CDCPulse objects: "
493 << cdcpulses.size() << std::endl;
494 for (uint32_t i=0; i<cdcpulses.size(); i++) {
495 const Df125CDCPulse *p = cdcpulses[i];
496
497 // Apply optional rocid translation
498 uint32_t rocid = p->rocid;
499 map<uint32_t, uint32_t>::iterator rocid_iter = Get_ROCID_Map().find(rocid);
500 if (rocid_iter != Get_ROCID_Map().end()) rocid = rocid_iter->second;
501
502 if (VERBOSE > 4)
503 ttout << " Looking for rocid:" << rocid << " slot:" << p->slot
504 << " chan:" << p->channel << std::endl;
505
506 // Create crate,slot,channel index and find entry in Translation table.
507 // If none is found, then just quietly skip this hit.
508 csc_t csc = {rocid, p->slot, p->channel};
509 map<csc_t, DChannelInfo>::const_iterator iter = Get_TT().find(csc);
510 if (iter == Get_TT().end()) {
511 if (VERBOSE > 6)
512 ttout << " - Didn't find it" << std::endl;
513 continue;
514 }
515 const DChannelInfo &chaninfo = iter->second;
516 if (VERBOSE > 6)
517 ttout << " - Found entry for: " << DetectorName(chaninfo.det_sys)
518 << std::endl;
519
520 // Create the appropriate hit type based on detector type
521 switch (chaninfo.det_sys) {
522 case CDC:
523 vcdc.push_back( MakeCDCDigiHit(chaninfo.cdc, p) );
524 break;
525 default:
526 if (VERBOSE > 4)
527 ttout << " - Don't know how to make DigiHit"
528 << " objects for this detector type!" << std::endl;
529 break;
530 }
531 }
532
533 // Df125FDCPulse
534 vector<const Df125FDCPulse*> fdcpulses;
535 loop->Get(fdcpulses);
536 if (VERBOSE > 2)
537 ttout << " Number Df125FDCPulse objects: "
538 << fdcpulses.size() << std::endl;
539 for (uint32_t i=0; i<fdcpulses.size(); i++) {
540 const Df125FDCPulse *p = fdcpulses[i];
541
542 // Apply optional rocid translation
543 uint32_t rocid = p->rocid;
544 map<uint32_t, uint32_t>::iterator rocid_iter = Get_ROCID_Map().find(rocid);
545 if (rocid_iter != Get_ROCID_Map().end()) rocid = rocid_iter->second;
546
547 if (VERBOSE > 4)
548 ttout << " Looking for rocid:" << rocid << " slot:" << p->slot
549 << " chan:" << p->channel << std::endl;
550
551 // Create crate,slot,channel index and find entry in Translation table.
552 // If none is found, then just quietly skip this hit.
553 csc_t csc = {rocid, p->slot, p->channel};
554 map<csc_t, DChannelInfo>::const_iterator iter = Get_TT().find(csc);
555 if (iter == Get_TT().end()) {
556 if (VERBOSE > 6)
557 ttout << " - Didn't find it" << std::endl;
558 continue;
559 }
560 const DChannelInfo &chaninfo = iter->second;
561 if (VERBOSE > 6)
562 ttout << " - Found entry for: " << DetectorName(chaninfo.det_sys)
563 << std::endl;
564
565 // Create the appropriate hit type based on detector type
566 switch (chaninfo.det_sys) {
567 case FDC_CATHODES:
568 vfdccathode.push_back( MakeFDCCathodeDigiHit(chaninfo.fdc_cathodes, p) );
569 break;
570 default:
571 if (VERBOSE > 4)
572 ttout << " - Don't know how to make DigiHit"
573 << " 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)
582 ttout << " Number DF1TDCHit objects: " << f1tdchits.size() << std::endl;
583 for (uint32_t i=0; i<f1tdchits.size(); i++) {
584 const DF1TDCHit *hit = f1tdchits[i];
585
586 // Apply optional rocid translation
587 uint32_t rocid = hit->rocid;
588 map<uint32_t, uint32_t>::iterator rocid_iter = Get_ROCID_Map().find(rocid);
589 if (rocid_iter != Get_ROCID_Map().end()) rocid = rocid_iter->second;
590
591 if (VERBOSE > 4)
592 ttout << " Looking for rocid:" << rocid << " slot:" << hit->slot
593 << " chan:" << hit->channel << std::endl;
594
595 // Create crate,slot,channel index and find entry in Translation table.
596 // If none is found, then just quietly skip this hit.
597 csc_t csc = {rocid, hit->slot, hit->channel};
598 map<csc_t, DChannelInfo>::const_iterator iter = Get_TT().find(csc);
599 if (iter == Get_TT().end()) {
600 if (VERBOSE > 6)
601 ttout << " - Didn't find it" << std::endl;
602 continue;
603 }
604 const DChannelInfo &chaninfo = iter->second;
605 if (VERBOSE > 6)
606 ttout << " - Found entry for: "
607 << DetectorName(chaninfo.det_sys) << std::endl;
608
609 // Create the appropriate hit type based on detector type
610 switch (chaninfo.det_sys) {
611 case BCAL:
612 vbcaltdc.push_back( MakeBCALTDCDigiHit(chaninfo.bcal, hit) );
613 break;
614 case FDC_WIRES:
615 vfdcwire.push_back( MakeFDCWireDigiHit(chaninfo.fdc_wires, hit) );
616 break;
617 case RF:
618 vrftdc.push_back( MakeRFTDCDigiTime(chaninfo.rf, hit) );
619 break;
620 case SC:
621 vsctdc.push_back( MakeSCTDCDigiHit(chaninfo.sc, hit) );
622 break;
623 case TAGM:
624 vtagmtdc.push_back( MakeTAGMTDCDigiHit(chaninfo.tagm, hit) );
625 break;
626 case TAGH:
627 vtaghtdc.push_back( MakeTAGHTDCDigiHit(chaninfo.tagh, hit) );
628 break;
629 case PSC:
630 vpsctdc.push_back( MakePSCTDCDigiHit(chaninfo.psc, hit) );
631 break;
632 default:
633 if (VERBOSE > 4)
634 ttout << " - Don't know how to make DigiHit objects"
635 << " for this detector type!" << std::endl;
636 break;
637 }
638 }
639
640 // DCAEN1290TDCHit
641 vector<const DCAEN1290TDCHit*> caen1290tdchits;
642 loop->Get(caen1290tdchits);
643 if (VERBOSE > 2)
644 ttout << " Number DCAEN1290TDCHit objects: "
645 << caen1290tdchits.size() << std::endl;
646 for (uint32_t i=0; i<caen1290tdchits.size(); i++) {
647 const DCAEN1290TDCHit *hit = caen1290tdchits[i];
648
649 // Apply optional rocid translation
650 uint32_t rocid = hit->rocid;
651 map<uint32_t, uint32_t>::iterator rocid_iter = Get_ROCID_Map().find(rocid);
652 if (rocid_iter != Get_ROCID_Map().end()) rocid = rocid_iter->second;
653
654 if (VERBOSE > 4)
655 ttout << " Looking for rocid:" << rocid << " slot:" << hit->slot
656 << " chan:" << hit->channel << std::endl;
657
658 // Create crate,slot,channel index and find entry in Translation table.
659 // If none is found, then just quietly skip this hit.
660 csc_t csc = {rocid, hit->slot, hit->channel};
661 map<csc_t, DChannelInfo>::const_iterator iter = Get_TT().find(csc);
662 if (iter == Get_TT().end()) {
663 if (VERBOSE > 6)
664 ttout << " - Didn't find it" << std::endl;
665 continue;
666 }
667 const DChannelInfo &chaninfo = iter->second;
668 if (VERBOSE > 6)
669 ttout << " - Found entry for: " << DetectorName(chaninfo.det_sys)
670 << std::endl;
671
672 // Create the appropriate hit type based on detector type
673 switch (chaninfo.det_sys) {
674 case TOF:
675 vtoftdc.push_back( MakeTOFTDCDigiHit(chaninfo.tof, hit) );
676 break;
677 case RF:
678 vrftdc.push_back( MakeRFTDCDigiTime(chaninfo.rf, hit) );
679 break;
680 default:
681 if (VERBOSE > 4)
682 ttout << " - Don't know how to make DigiHit objects"
683 << " for this detector type!" << std::endl;
684 break;
685 }
686 }
687
688 // Sort object order (this makes it easier to browse with hd_dump)
689 sort(vbcal.begin(), vbcal.end(), SortBCALDigiHit);
690
691 if (VERBOSE > 3) {
692 ttout << " vbcal.size() = " << vbcal.size() << std::endl;
693 ttout << " vbcaltdc.size() = " << vbcaltdc.size() << std::endl;
694 ttout << " vcdc.size() = " << vcdc.size() << std::endl;
695 ttout << " vfcal.size() = " << vfcal.size() << std::endl;
696 ttout << " vfdccathode.size() = " << vfdccathode.size() << std::endl;
697 ttout << " vfdcwire.size() = " << vfdcwire.size() << std::endl;
698 ttout << " vrf.size() = " << vrf.size() << std::endl;
699 ttout << " vrftdc.size() = " << vrftdc.size() << std::endl;
700 ttout << " vsc.size() = " << vsc.size() << std::endl;
701 ttout << " vsctdc.size() = " << vsctdc.size() << std::endl;
702 ttout << " vtof.size() = " << vtof.size() << std::endl;
703 ttout << " vtoftdc.size() = " << vtoftdc.size() << std::endl;
704 ttout << " vtagm.size() = " << vtagm.size() << std::endl;
705 ttout << " vtagmtdc.size() = " << vtagmtdc.size() << std::endl;
706 ttout << " vtagh.size() = " << vtagh.size() << std::endl;
707 ttout << " vtaghtdc.size() = " << vtaghtdc.size() << std::endl;
708 ttout << " vps.size() = " << vps.size() << std::endl;
709 ttout << " vpsc.size() = " << vpsc.size() << std::endl;
710 ttout << " vpsctdc.size() = " << vpsctdc.size() << std::endl;
711 ttout << " vtpolsector.size() = " << vtpolsector.size() << std::endl;
712 }
713
714 // Find factory for each container and copy the object pointers into it
715 // (n.b. do this even if container is empty since it sets the evnt_called flag)
716 CopyToFactory(loop, vbcal);
717 CopyToFactory(loop, vbcaltdc);
718 CopyToFactory(loop, vcdc);
719 CopyToFactory(loop, vfcal);
720 CopyToFactory(loop, vfdccathode);
721 CopyToFactory(loop, vfdcwire);
722 CopyToFactory(loop, vrf);
723 CopyToFactory(loop, vrftdc);
724 CopyToFactory(loop, vsc);
725 CopyToFactory(loop, vsctdc);
726 CopyToFactory(loop, vtof);
727 CopyToFactory(loop, vtoftdc);
728 CopyToFactory(loop, vtagm);
729 CopyToFactory(loop, vtagmtdc);
730 CopyToFactory(loop, vtagh);
731 CopyToFactory(loop, vtaghtdc);
732 CopyToFactory(loop, vps);
733 CopyToFactory(loop, vpsc);
734 CopyToFactory(loop, vpsctdc);
735 CopyToFactory(loop, vtpolsector);
736
737 // Add to JANA's call stack some entries to make janadot draw something reasonable
738 // Unfortunately, this is just us telling JANA the relationship as defined here.
739 // It is not derived from the above code which would guarantee the declared relationsips
740 // are correct. That would just be too complicated given how that code works.
741 if (record_call_stack) {
742 // re-enable call stack recording
743 loop->EnableCallStackRecording();
744
745 Addf250ObjectsToCallStack(loop, "DBCALDigiHit");
746 Addf250ObjectsToCallStack(loop, "DFCALDigiHit");
747 Addf250ObjectsToCallStack(loop, "DSCDigiHit");
748 Addf250ObjectsToCallStack(loop, "DTOFDigiHit");
749 Addf125ObjectsToCallStack(loop, "DCDCDigiHit");
750 Addf125ObjectsToCallStack(loop, "DFDCCathodeDigiHit");
751 AddF1TDCObjectsToCallStack(loop, "DBCALTDCDigiHit");
752 AddF1TDCObjectsToCallStack(loop, "DFDCWireDigiHit");
753 AddF1TDCObjectsToCallStack(loop, "DRFDigiTime");
754 AddF1TDCObjectsToCallStack(loop, "DRFTDCDigiTime");
755 AddF1TDCObjectsToCallStack(loop, "DSCTDCDigiHit");
756 AddCAEN1290TDCObjectsToCallStack(loop, "DTOFTDCDigiHit");
757 }
758}
759
760//---------------------------------
761// MakeBCALDigiHit
762//---------------------------------
763DBCALDigiHit* DTranslationTable::MakeBCALDigiHit(const BCALIndex_t &idx,
764 const Df250PulseIntegral *pi,
765 const Df250PulseTime *pt,
766 const Df250PulsePedestal *pp) const
767{
768 if (VERBOSE > 4)
769 ttout << " - Making DBCALDigiHit for (mod,lay,sec,end)=("
770 << idx.module << "," << idx.layer << "," << idx.sector
771 << "," << (DBCALGeometry::End)idx.end << std::endl;
772
773 DBCALDigiHit *h = new DBCALDigiHit();
774 CopyDf250Info(h, pi, pt, pp);
775
776 h->pulse_peak = pp==NULL__null ? 0 : pp->pulse_peak; // Include pulse peak information in the digihit for BCAL
777
778 h->module = idx.module;
779 h->layer = idx.layer;
780 h->sector = idx.sector;
781 h->end = (DBCALGeometry::End)idx.end;
782
783 return h;
784}
785
786//---------------------------------
787// MakeFCALDigiHit
788//---------------------------------
789DFCALDigiHit* DTranslationTable::MakeFCALDigiHit(const FCALIndex_t &idx,
790 const Df250PulseIntegral *pi,
791 const Df250PulseTime *pt,
792 const Df250PulsePedestal *pp) const
793{
794 DFCALDigiHit *h = new DFCALDigiHit();
795 CopyDf250Info(h, pi, pt, pp);
796
797 h->row = idx.row;
798 h->column = idx.col;
799
800 return h;
801}
802
803//---------------------------------
804// MakeTOFDigiHit
805//---------------------------------
806DTOFDigiHit* DTranslationTable::MakeTOFDigiHit(const TOFIndex_t &idx,
807 const Df250PulseIntegral *pi,
808 const Df250PulseTime *pt,
809 const Df250PulsePedestal *pp) const
810{
811 DTOFDigiHit *h = new DTOFDigiHit();
812 CopyDf250Info(h, pi, pt, pp);
813
814 h->plane = idx.plane;
815 h->bar = idx.bar;
816 h->end = idx.end;
817
818 return h;
819}
820
821//---------------------------------
822// MakeSCDigiHit
823//---------------------------------
824DSCDigiHit* DTranslationTable::MakeSCDigiHit(const SCIndex_t &idx,
825 const Df250PulseIntegral *pi,
826 const Df250PulseTime *pt,
827 const Df250PulsePedestal *pp) const
828{
829 DSCDigiHit *h = new DSCDigiHit();
830 CopyDf250Info(h, pi, pt, pp);
831
832 h->sector = idx.sector;
833
834 return h;
835}
836
837//---------------------------------
838// MakeTAGMDigiHit
839//---------------------------------
840DTAGMDigiHit* DTranslationTable::MakeTAGMDigiHit(const TAGMIndex_t &idx,
841 const Df250PulseIntegral *pi,
842 const Df250PulseTime *pt,
843 const Df250PulsePedestal *pp) const
844{
845 DTAGMDigiHit *h = new DTAGMDigiHit();
846 CopyDf250Info(h, pi, pt, pp);
847
848 h->row = idx.row;
849 h->column = idx.col;
850
851 return h;
852}
853
854//---------------------------------
855// MakeTAGHDigiHit
856//---------------------------------
857DTAGHDigiHit* DTranslationTable::MakeTAGHDigiHit(const TAGHIndex_t &idx,
858 const Df250PulseIntegral *pi,
859 const Df250PulseTime *pt,
860 const Df250PulsePedestal *pp) const
861{
862 DTAGHDigiHit *h = new DTAGHDigiHit();
863 CopyDf250Info(h, pi, pt, pp);
864
865 h->counter_id = idx.id;
866
867 return h;
868}
869
870//---------------------------------
871// MakePSCDigiHit
872//---------------------------------
873DPSCDigiHit* DTranslationTable::MakePSCDigiHit(const PSCIndex_t &idx,
874 const Df250PulseIntegral *pi,
875 const Df250PulseTime *pt,
876 const Df250PulsePedestal *pp) const
877{
878 DPSCDigiHit *h = new DPSCDigiHit();
879 CopyDf250Info(h, pi, pt, pp);
880
881 h->counter_id = idx.id;
882
883 return h;
884}
885
886//---------------------------------
887// MakePSDigiHit
888//---------------------------------
889DPSDigiHit* DTranslationTable::MakePSDigiHit(const PSIndex_t &idx,
890 const Df250PulseIntegral *pi,
891 const Df250PulseTime *pt,
892 const Df250PulsePedestal *pp) const
893{
894 DPSDigiHit *h = new DPSDigiHit();
895 CopyDf250Info(h, pi, pt, pp);
896
897 h->arm = (DPSGeometry::Arm)idx.side;
898 h->column = idx.id;
899
900 return h;
901}
902
903//---------------------------------
904// MakeCDCDigiHit
905//---------------------------------
906DCDCDigiHit* DTranslationTable::MakeCDCDigiHit(const CDCIndex_t &idx,
907 const Df125PulseIntegral *pi,
908 const Df125PulseTime *pt,
909 const Df125PulsePedestal *pp) const
910{
911 DCDCDigiHit *h = new DCDCDigiHit();
912 CopyDf125Info(h, pi, pt, pp);
913
914 h->ring = idx.ring;
915 h->straw = idx.straw;
916
917 return h;
918}
919
920//---------------------------------
921// MakeCDCDigiHit
922//---------------------------------
923DCDCDigiHit* DTranslationTable::MakeCDCDigiHit(const CDCIndex_t &idx,
924 const Df125CDCPulse *p) const
925{
926 DCDCDigiHit *h = new DCDCDigiHit();
927 h->ring = idx.ring;
928 h->straw = idx.straw;
929 h->pulse_integral = p->integral;
930 h->pulse_time = p->le_time;
931 h->pedestal = p->pedestal;
932 h->QF = p->time_quality_bit + (p->overflow_count<<1);
933 h->nsamples_integral = p->nsamples_integral;
934 h->nsamples_pedestal = p->nsamples_pedestal;
935
936 h->AddAssociatedObject(p);
937
938 return h;
939}
940
941//---------------------------------
942// MakeFDCCathodeDigiHit
943//---------------------------------
944DFDCCathodeDigiHit* DTranslationTable::MakeFDCCathodeDigiHit(
945 const FDC_CathodesIndex_t &idx,
946 const Df125PulseIntegral *pi,
947 const Df125PulseTime *pt,
948 const Df125PulsePedestal *pp) const
949{
950 DFDCCathodeDigiHit *h = new DFDCCathodeDigiHit();
951 CopyDf125Info(h, pi, pt, pp);
952
953 h->package = idx.package;
954 h->chamber = idx.chamber;
955 h->view = idx.view;
956 h->strip = idx.strip;
957 h->strip_type = idx.strip_type;
958
959 return h;
960}
961
962
963//---------------------------------
964// MakeFDCCathodeDigiHit
965//---------------------------------
966DFDCCathodeDigiHit* DTranslationTable::MakeFDCCathodeDigiHit(
967 const FDC_CathodesIndex_t &idx,
968 const Df125FDCPulse *p) const
969{
970 DFDCCathodeDigiHit *h = new DFDCCathodeDigiHit();
971 h->package = idx.package;
972 h->chamber = idx.chamber;
973 h->view = idx.view;
974 h->strip = idx.strip;
975 h->strip_type = idx.strip_type;
976 h->pulse_integral = p->integral;
977 h->pulse_time = p->le_time;
978 h->pedestal = p->pedestal;
979 h->QF = p->time_quality_bit + (p->overflow_count<<1);
980 h->nsamples_integral = p->nsamples_integral;
981 h->nsamples_pedestal = p->nsamples_pedestal;
982
983 h->AddAssociatedObject(p);
984
985 return h;
986}
987
988//---------------------------------
989// MakeBCALTDCDigiHit
990//---------------------------------
991DBCALTDCDigiHit* DTranslationTable::MakeBCALTDCDigiHit(
992 const BCALIndex_t &idx,
993 const DF1TDCHit *hit) const
994{
995 DBCALTDCDigiHit *h = new DBCALTDCDigiHit();
996 CopyDF1TDCInfo(h, hit);
997
998 h->module = idx.module;
999 h->layer = idx.layer;
1000 h->sector = idx.sector;
1001 h->end = (DBCALGeometry::End)idx.end;
1002
1003 return h;
1004}
1005
1006//---------------------------------
1007// MakeFDCWireDigiHit
1008//---------------------------------
1009DFDCWireDigiHit* DTranslationTable::MakeFDCWireDigiHit(
1010 const FDC_WiresIndex_t &idx,
1011 const DF1TDCHit *hit) const
1012{
1013 DFDCWireDigiHit *h = new DFDCWireDigiHit();
1014 CopyDF1TDCInfo(h, hit);
1015
1016 h->package = idx.package;
1017 h->chamber = idx.chamber;
1018 h->wire = idx.wire;
1019
1020 return h;
1021}
1022
1023//---------------------------------
1024// MakeRFDigiTime
1025//---------------------------------
1026DRFTDCDigiTime* DTranslationTable::MakeRFTDCDigiTime(
1027 const RFIndex_t &idx,
1028 const DF1TDCHit *hit) const
1029{
1030 DRFTDCDigiTime *h = new DRFTDCDigiTime();
1031 CopyDF1TDCInfo(h, hit);
1032
1033 h->dSystem = idx.dSystem;
1034 h->dIsCAENTDCFlag = false;
1035
1036 return h;
1037}
1038
1039//---------------------------------
1040// MakeRFDigiTime
1041//---------------------------------
1042DRFTDCDigiTime* DTranslationTable::MakeRFTDCDigiTime(
1043 const RFIndex_t &idx,
1044 const DCAEN1290TDCHit *hit) const
1045{
1046 DRFTDCDigiTime *h = new DRFTDCDigiTime();
1047 CopyDCAEN1290TDCInfo(h, hit);
1048
1049 h->dSystem = idx.dSystem;
1050 h->dIsCAENTDCFlag = true;
1051
1052 return h;
1053}
1054
1055//---------------------------------
1056// MakeRFDigiTime
1057//---------------------------------
1058DRFDigiTime* DTranslationTable::MakeRFDigiTime(
1059 const RFIndex_t &idx,
1060 const Df250PulseTime *hit) const
1061{
1062 DRFDigiTime *h = new DRFDigiTime();
1063 h->time = hit->time;
1064
1065 h->dSystem = idx.dSystem;
1066
1067 return h;
1068}
1069
1070//---------------------------------
1071// MakeSCTDCDigiHit
1072//---------------------------------
1073DSCTDCDigiHit* DTranslationTable::MakeSCTDCDigiHit(
1074 const SCIndex_t &idx,
1075 const DF1TDCHit *hit) const
1076{
1077 DSCTDCDigiHit *h = new DSCTDCDigiHit();
1078 CopyDF1TDCInfo(h, hit);
1079
1080 h->sector = idx.sector;
1081
1082 return h;
1083}
1084
1085//---------------------------------
1086// MakeTAGMTDCDigiHit
1087//---------------------------------
1088DTAGMTDCDigiHit* DTranslationTable::MakeTAGMTDCDigiHit(
1089 const TAGMIndex_t &idx,
1090 const DF1TDCHit *hit) const
1091{
1092 DTAGMTDCDigiHit *h = new DTAGMTDCDigiHit();
1093 CopyDF1TDCInfo(h, hit);
1094
1095 h->row = idx.row;
1096 h->column = idx.col;
1097
1098 return h;
1099}
1100
1101//---------------------------------
1102// MakeTAGHTDCDigiHit
1103//---------------------------------
1104DTAGHTDCDigiHit* DTranslationTable::MakeTAGHTDCDigiHit(
1105 const TAGHIndex_t &idx,
1106 const DF1TDCHit *hit) const
1107{
1108 DTAGHTDCDigiHit *h = new DTAGHTDCDigiHit();
1109 CopyDF1TDCInfo(h, hit);
1110
1111 h->counter_id = idx.id;
1112
1113 return h;
1114}
1115
1116//---------------------------------
1117// MakePSCTDCDigiHit
1118//---------------------------------
1119DPSCTDCDigiHit* DTranslationTable::MakePSCTDCDigiHit(
1120 const PSCIndex_t &idx,
1121 const DF1TDCHit *hit) const
1122{
1123 DPSCTDCDigiHit *h = new DPSCTDCDigiHit();
1124 CopyDF1TDCInfo(h, hit);
1125
1126 h->counter_id = idx.id;
1127
1128 return h;
1129}
1130
1131//---------------------------------
1132// MakeTOFTDCDigiHit
1133//---------------------------------
1134DTOFTDCDigiHit* DTranslationTable::MakeTOFTDCDigiHit(
1135 const TOFIndex_t &idx,
1136 const DCAEN1290TDCHit *hit) const
1137{
1138 DTOFTDCDigiHit *h = new DTOFTDCDigiHit();
1139 CopyDCAEN1290TDCInfo(h, hit);
1140
1141 h->plane = idx.plane;
1142 h->bar = idx.bar;
1143 h->end = idx.end;
1144
1145 return h;
1146}
1147
1148//---------------------------------
1149// MakeTPOLSectorDigiHit
1150//---------------------------------
1151DTPOLSectorDigiHit* DTranslationTable::MakeTPOLSectorDigiHit(const TPOLSECTORIndex_t &idx,
1152 const Df250PulseIntegral *pi,
1153 const Df250PulseTime *pt,
1154 const Df250PulsePedestal *pp) const
1155{
1156 DTPOLSectorDigiHit *h = new DTPOLSectorDigiHit();
1157 CopyDf250Info(h, pi, pt, pp);
1158
1159 h->sector = idx.sector;
1160 return h;
1161}
1162
1163//---------------------------------
1164// GetDetectorIndex
1165//---------------------------------
1166const DTranslationTable::DChannelInfo
1167 &DTranslationTable::GetDetectorIndex(const csc_t &in_daq_index) const
1168{
1169 map<DTranslationTable::csc_t, DTranslationTable::DChannelInfo>::const_iterator detector_index_itr = Get_TT().find(in_daq_index);
1170 if (detector_index_itr == Get_TT().end()) {
1171 stringstream ss_err;
1172 ss_err << "Could not find detector channel in Translaton Table: "
1173 << "rocid = " << in_daq_index.rocid
1174 << "slot = " << in_daq_index.slot
1175 << "channel = " << in_daq_index.channel;
1176 throw JException(ss_err.str());
1177 }
1178
1179 return detector_index_itr->second;
1180}
1181
1182//---------------------------------
1183// GetDAQIndex
1184//---------------------------------
1185const DTranslationTable::csc_t
1186 &DTranslationTable::GetDAQIndex(const DChannelInfo &in_channel) const
1187{
1188 map<DTranslationTable::csc_t, DTranslationTable::DChannelInfo>::const_iterator tt_itr = Get_TT().begin();
1189
1190 // search through the whole Table to find the key that corresponds to our detector channel
1191 // this is not terribly efficient - linear in the size of the table
1192 bool found = false;
1193 for (; tt_itr != Get_TT().end(); tt_itr++) {
1194 const DTranslationTable::DChannelInfo &det_channel = tt_itr->second;
1195 if ( det_channel.det_sys == in_channel.det_sys ) {
1196 switch ( in_channel.det_sys ) {
1197 case DTranslationTable::BCAL:
1198 if ( det_channel.bcal == in_channel.bcal )
1199 found = true;
1200 break;
1201 case DTranslationTable::CDC:
1202 if ( det_channel.cdc == in_channel.cdc )
1203 found = true;
1204 break;
1205 case DTranslationTable::FCAL:
1206 if ( det_channel.fcal == in_channel.fcal )
1207 found = true;
1208 break;
1209 case DTranslationTable::FDC_CATHODES:
1210 if ( det_channel.fdc_cathodes == in_channel.fdc_cathodes )
1211 found = true;
1212 break;
1213 case DTranslationTable::FDC_WIRES:
1214 if ( det_channel.fdc_wires == in_channel.fdc_wires )
1215 found = true;
1216 break;
1217 case DTranslationTable::PS:
1218 if ( det_channel.ps == in_channel.ps )
1219 found = true;
1220 break;
1221 case DTranslationTable::PSC:
1222 if ( det_channel.psc == in_channel.psc )
1223 found = true;
1224 break;
1225 case DTranslationTable::RF:
1226 if ( det_channel.rf == in_channel.rf )
1227 found = true;
1228 break;
1229 case DTranslationTable::SC:
1230 if ( det_channel.sc == in_channel.sc )
1231 found = true;
1232 break;
1233 case DTranslationTable::TAGH:
1234 if ( det_channel.tagh == in_channel.tagh )
1235 found = true;
1236 break;
1237 case DTranslationTable::TAGM:
1238 if ( det_channel.tagm == in_channel.tagm )
1239 found = true;
1240 break;
1241 case DTranslationTable::TOF:
1242 if ( det_channel.tof == in_channel.tof )
1243 found = true;
1244 break;
1245 case DTranslationTable::TPOLSECTOR:
1246 if ( det_channel.tpolsector == in_channel.tpolsector )
1247 found = true;
1248 break;
1249 default:
1250 jerr << "DTranslationTable::GetDAQIndex(): "
1251 << "Invalid detector type = " << in_channel.det_sys
1252 << std::endl;
1253 }
1254 }
1255
1256 if (found)
1257 break;
1258 }
1259
1260 if (tt_itr == Get_TT().end()) {
1261 stringstream ss_err;
1262 ss_err << "Could not find DAQ channel in Translaton Table: "
1263 << Channel2Str(in_channel) << std::endl;
1264 throw JException(ss_err.str());
1265 }
1266
1267 return tt_itr->first;
1268}
1269
1270//----------------
1271// Channel2Str
1272//----------------
1273string DTranslationTable::Channel2Str(const DChannelInfo &in_channel) const
1274{
1275 stringstream ss;
1276
1277 switch ( in_channel.det_sys ) {
1278 case DTranslationTable::BCAL:
1279 ss << "module = " << in_channel.bcal.module << " layer = " << in_channel.bcal.layer
1280 << " sector = " << in_channel.bcal.sector << " end = " << in_channel.bcal.end;
1281 break;
1282 case DTranslationTable::CDC:
1283 ss << "ring = " << in_channel.cdc.ring << " straw = " << in_channel.cdc.straw;
1284 break;
1285 case DTranslationTable::FCAL:
1286 ss << "row = " << in_channel.fcal.row << " column = " << in_channel.fcal.col;
1287 break;
1288 case DTranslationTable::FDC_CATHODES:
1289 ss << "package = " << in_channel.fdc_cathodes.package
1290 << " chamber = " << in_channel.fdc_cathodes.chamber
1291 << " view = " << in_channel.fdc_cathodes.view
1292 << " strip = " << in_channel.fdc_cathodes.strip
1293 << " strip type = " << in_channel.fdc_cathodes.strip_type;
1294 break;
1295 case DTranslationTable::FDC_WIRES:
1296 ss << "package = " << in_channel.fdc_wires.package
1297 << " chamber = " << in_channel.fdc_wires.chamber
1298 << " wire = " << in_channel.fdc_wires.wire;
1299 break;
1300 case DTranslationTable::PS:
1301 ss << "side = " << in_channel.ps.side << " id = " << in_channel.ps.id;
1302 break;
1303 case DTranslationTable::PSC:
1304 ss << "id = " << in_channel.psc.id;
1305 break;
1306 case DTranslationTable::RF:
1307 ss << "system = " << SystemName(in_channel.rf.dSystem);
1308 break;
1309 case DTranslationTable::SC:
1310 ss << "sector = " << in_channel.sc.sector;
1311 break;
1312 case DTranslationTable::TAGH:
1313 ss << "id = " << in_channel.tagh.id;
1314 break;
1315 case DTranslationTable::TAGM:
1316 ss << "row = " << in_channel.tagm.row << " column = " << in_channel.tagm.col;
1317 break;
1318 case DTranslationTable::TOF:
1319 ss << "plane = " << in_channel.tof.plane << " bar = " << in_channel.tof.bar
1320 << " end = " << in_channel.tof.end;
1321 break;
1322 case DTranslationTable::TPOLSECTOR:
1323 ss << "sector = " << in_channel.tpolsector.sector;
1324 break;
1325 default:
1326 ss << "Unknown detector type" << std::endl;
1327 }
1328
1329 return ss.str();
1330}
1331
1332//----------------
1333// Addf250ObjectsToCallStack
1334//----------------
1335void DTranslationTable::Addf250ObjectsToCallStack(JEventLoop *loop, string caller) const
1336{
1337 AddToCallStack(loop, caller, "Df250Config");
1338 AddToCallStack(loop, caller, "Df250PulseIntegral");
1339 AddToCallStack(loop, caller, "Df250PulsePedestal");
1340 AddToCallStack(loop, caller, "Df250PulseTime");
1341}
1342
1343//----------------
1344// Addf125ObjectsToCallStack
1345//----------------
1346void DTranslationTable::Addf125ObjectsToCallStack(JEventLoop *loop, string caller) const
1347{
1348 AddToCallStack(loop, caller, "Df125Config");
1349 AddToCallStack(loop, caller, "Df125PulseIntegral");
1350 AddToCallStack(loop, caller, "Df125PulsePedestal");
1351 AddToCallStack(loop, caller, "Df125PulseTime");
1352}
1353
1354//----------------
1355// AddF1TDCObjectsToCallStack
1356//----------------
1357void DTranslationTable::AddF1TDCObjectsToCallStack(JEventLoop *loop, string caller) const
1358{
1359 AddToCallStack(loop, caller, "DF1TDCConfig");
1360 AddToCallStack(loop, caller, "DF1TDCHit");
1361}
1362
1363//----------------
1364// AddCAEN1290TDCObjectsToCallStack
1365//----------------
1366void DTranslationTable::AddCAEN1290TDCObjectsToCallStack(JEventLoop *loop, string caller) const
1367{
1368 AddToCallStack(loop, caller, "DCAEN1290TDCConfig");
1369 AddToCallStack(loop, caller, "DCAEN1290TDCHit");
1370}
1371
1372//----------------
1373// AddToCallStack
1374//----------------
1375void DTranslationTable::AddToCallStack(JEventLoop *loop,
1376 string caller, string callee) const
1377{
1378 /// This is used to give information to JANA regarding the relationship and
1379 /// origin of some of these data objects. This is really just needed so that
1380 /// the janadot program can be used to produce the correct callgraph. Because
1381 /// of how this plugin works, JANA can't record the correct call stack (at
1382 /// least not easily!) Therefore, we have to give it a little help here.
1383
1384 JEventLoop::call_stack_t cs;
1385 cs.start_time = cs.end_time = 0.0;
1386 cs.caller_name = caller;
1387 cs.callee_name = callee;
1388 cs.data_source = JEventLoop::DATA_FROM_CACHE;
1389 loop->AddToCallStack(cs);
1390 cs.callee_name = cs.caller_name;
1391 cs.caller_name = "<ignore>";
1392 cs.data_source = JEventLoop::DATA_FROM_FACTORY;
1393 loop->AddToCallStack(cs);
1394}
1395
1396//----------------------------------------------------------------------------
1397//----------------------------------------------------------------------------
1398// The following routines access the translation table
1399//----------------------------------------------------------------------------
1400//----------------------------------------------------------------------------
1401
1402static int ModuleStr2ModID(string &type);
1403static DTranslationTable::Detector_t DetectorStr2DetID(string &type);
1404static void StartElement(void *userData, const char *xmlname, const char **atts);
1405static void EndElement(void *userData, const char *xmlname);
1406
1407
1408//---------------------------------
1409// ReadTranslationTable
1410//---------------------------------
1411void DTranslationTable::ReadTranslationTable(JCalibration *jcalib)
1412{
1413 // It seems expat is not thread safe so we lock a mutex here and
1414 // read in the translation table just once
1415 pthread_mutex_lock(&Get_TT_Mutex());
1416 if (Get_TT_Initialized()) {
1417 pthread_mutex_unlock(&Get_TT_Mutex());
1418 return;
1419 }
1420
1421 // String to hold entire XML translation table
1422 string tt_xml;
1423
1424 // Try getting it from CCDB first
1425 if (jcalib && !NO_CCDB) {
1426 map<string,string> tt;
1427 string namepath = "Translation/DAQ2detector";
1428 jout << "Reading translation table from calib DB: " << namepath << " ..." << std::endl;
1429 jcalib->GetCalib(namepath, tt);
1430 if (tt.size() != 1) {
1431 jerr << " Error: Unexpected translation table format!" << std::endl;
1432 jerr << " tt.size()=" << tt.size() << " (expected 1)" << std::endl;
1433 }else{
1434 // Copy table into tt string
1435 map<string,string>::iterator iter = tt.begin();
1436 tt_xml = iter->second;
1437 }
1438 }
1439
1440 // If getting from CCDB fails, try just reading in local file
1441 if (tt_xml.size() == 0) {
1442 if (!NO_CCDB) jout << "Unable to get translation table from CCDB." << std::endl;
1443 jout << "Will try reading TT from local file: " << XML_FILENAME << std::endl;
1444
1445 // Open file
1446 ifstream ifs(XML_FILENAME.c_str());
1447 if (! ifs.is_open()) {
1448 jerr << " Error: Cannot open file! Translation table unavailable." << std::endl;
1449 pthread_mutex_unlock(&Get_TT_Mutex());
1450 return;
1451 }
1452
1453 // read lines into stringstream object
1454 stringstream ss;
1455 while (ifs.good()) {
1456 char line[4096];
1457 ifs.getline(line, 4096);
1458 ss << line;
1459 }
1460
1461 // Close file
1462 ifs.close();
1463
1464 // Copy from stringstream to tt
1465 tt_xml = ss.str();
1466 }
1467
1468 // create parser and specify element handlers
1469 XML_Parser xmlParser = XML_ParserCreate(NULL__null);
1470 if (xmlParser == NULL__null) {
1471 jerr << "readTranslationTable...unable to create parser" << std::endl;
1472 exit(EXIT_FAILURE1);
1473 }
1474 XML_SetElementHandler(xmlParser,StartElement,EndElement);
1475 XML_SetUserData(xmlParser, &Get_TT());
1476
1477 // Parse XML string
1478 int status=XML_Parse(xmlParser, tt_xml.c_str(), tt_xml.size(), 1); // "1" indicates this is the final piece of XML
1479 if (status == 0) {
1480 jerr << " ?readTranslationTable...parseXMLFile parse error for " << XML_FILENAME << std::endl;
1481 jerr << XML_ErrorString(XML_GetErrorCode(xmlParser)) << std::endl;
1482 }
1483
1484 jout << Get_TT().size() << " channels defined in translation table" << std::endl;
1485 XML_ParserFree(xmlParser);
1486
1487 pthread_mutex_unlock(&Get_TT_Mutex());
1488 Get_TT_Initialized() = true;
1489}
1490
1491//---------------------------------
1492// ModuleStr2ModID
1493//---------------------------------
1494int ModuleStr2ModID(string &type)
1495{
1496 if (type == "vmecpu") {
1497 return(DModuleType::VMECPU);
1498 } else if (type == "tid") {
1499 return(DModuleType::TID);
1500 } else if (type == "fadc250") {
1501 return(DModuleType::FADC250);
1502 } else if (type == "fadc125") {
1503 return(DModuleType::FADC125);
1504 } else if (type == "f1tdcv2") {
1505 return(DModuleType::F1TDC32);
1506 } else if (type == "f1tdcv3") {
1507 return(DModuleType::F1TDC48);
1508 } else if (type == "jldisc") {
1509 return(DModuleType::JLAB_DISC);
1510 } else if (type == "vx1290a") {
1511 return(DModuleType::CAEN1290);
1512 } else {
1513 return(DModuleType::UNKNOWN);
1514 }
1515}
1516
1517//---------------------------------
1518// DetectorStr2DetID
1519//---------------------------------
1520DTranslationTable::Detector_t DetectorStr2DetID(string &type)
1521{
1522 if ( type == "fdc_cathodes" ) {
1523 return DTranslationTable::FDC_CATHODES;
1524 } else if ( type == "fdc_wires" ) {
1525 return DTranslationTable::FDC_WIRES;
1526 } else if ( type == "bcal" ) {
1527 return DTranslationTable::BCAL;
1528 } else if ( type == "cdc" ) {
1529 return DTranslationTable::CDC;
1530 } else if ( type == "fcal" ) {
1531 return DTranslationTable::FCAL;
1532 } else if ( type == "ps" ) {
1533 return DTranslationTable::PS;
1534 } else if ( type == "psc" ) {
1535 return DTranslationTable::PSC;
1536 } else if ( type == "rf" ) {
1537 return DTranslationTable::RF;
1538 } else if ( type == "st" ) {
1539 // The start counter is labelled by "ST" in the translation table
1540 // but we stick with the "SC" label in this plugin for consistency
1541 // with the rest of the reconstruction software
1542 return DTranslationTable::SC;
1543 } else if ( type == "tagh" ) {
1544 return DTranslationTable::TAGH;
1545 } else if ( type == "tagm" ) {
1546 return DTranslationTable::TAGM;
1547 } else if ( type == "tof" ) {
1548 return DTranslationTable::TOF;
1549 } else if ( type == "tpol" ) {
1550 return DTranslationTable::TPOLSECTOR;
1551 } else {
1552 return DTranslationTable::UNKNOWN_DETECTOR;
1553 }
1554}
1555
1556//---------------------------------
1557// StartElement
1558//---------------------------------
1559void StartElement(void *userData, const char *xmlname, const char **atts)
1560{
1561 static int crate=0, slot=0;
1562
1563 static string type,Type;
1564 int mc2codaType= 0;
1565 int channel = 0;
1566 string Detector, locSystem;
1567 int end=0;
1568 int row=0,column=0,module=0,sector=0,layer=0;
1569 int ring=0,straw=0,plane=0,bar=0;
1570 int package=0,chamber=0,view=0,strip=0,wire=0;
1571 int id=0, strip_type=0;
1572 int side=0;
1573
1574 // This complicated line just recasts the userData pointer into
1575 // a reference to the "TT" member of the DTranslationTable object
1576 // that called us.
1577 map<DTranslationTable::csc_t, DTranslationTable::DChannelInfo> &TT = *((map<DTranslationTable::csc_t, DTranslationTable::DChannelInfo>*)userData);
1578
1579 // store crate summary info, fill both maps
1580 if (strcasecmp(xmlname,"halld_online_translation_table") == 0) {
1581 // do nothing
1582
1583 } else if (strcasecmp(xmlname,"crate") == 0) {
1584 for (int i=0; atts[i]; i+=2) {
1585 if (strcasecmp(atts[i],"number") == 0) {
1586 crate = atoi(atts[i+1]);
1587 break;
1588 }
1589 }
1590
1591 } else if (strcasecmp(xmlname,"slot") == 0) {
1592 for (int i=0; atts[i]; i+=2) {
1593 if (strcasecmp(atts[i],"number") == 0) {
1594 slot = atoi(atts[i+1]);
1595 } else if (strcasecmp(atts[i],"type") == 0) {
1596 Type = string(atts[i+1]);
1597 type = string(atts[i+1]);
1598 std::transform(type.begin(), type.end(), type.begin(), (int(*)(int)) tolower);
1599 }
1600 }
1601
1602 // The detID value set here shows up in the header of the Data Block Bank
1603 // of the output file. It should be set to one if this crate has JLab
1604 // made modules that output in the standard format (see document:
1605 // "VME Data Format Standards for JLAB Modules"). These would include
1606 // f250ADC, f125ADC, F1TDC, .... Slots containing other types of modules
1607 // (e.g. CAEN1290) should have their own unique detID. We use detID of
1608 // zero for non-digitizing modules like CPUs nd TIDs even though potentially,
1609 // one could read data from these.
1610 mc2codaType = ModuleStr2ModID(type);
Value stored to 'mc2codaType' is never read
1611
1612 } else if (strcasecmp(xmlname,"channel") == 0) {
1613
1614 for (int i=0; atts[i]; i+=2) {
1615 string tag(atts[i+0]);
1616 string sval(atts[i+1]);
1617 int ival = atoi(atts[i+1]);
1618
1619 if (tag == "number")
1620 channel = ival;
1621 else if (tag == "detector")
1622 Detector = sval;
1623 else if (tag == "row")
1624 row = ival;
1625 else if (tag == "column")
1626 column = ival;
1627 else if (tag == "col")
1628 column = ival;
1629 else if (tag == "module")
1630 module = ival;
1631 else if (tag == "sector")
1632 sector = ival;
1633 else if (tag == "layer")
1634 layer = ival;
1635 else if (tag == "chan");
1636// chan = ival;
1637 else if (tag == "ring")
1638 ring = ival;
1639 else if (tag == "straw")
1640 straw = ival;
1641 else if (tag == "gPlane");
1642// gPlane = ival;
1643 else if (tag == "element");
1644// element = ival;
1645 else if (tag == "plane")
1646 plane = ival;
1647 else if (tag == "bar")
1648 bar = ival;
1649 else if (tag == "package")
1650 package = ival;
1651 else if (tag == "chamber")
1652 chamber = ival;
1653 else if (tag == "view") {
1654 if (sval == "U")
1655 view=1;
1656 else if (sval == "D")
1657 view=3;
1658 }
1659 else if (tag == "strip")
1660 strip = ival;
1661 else if (tag == "wire")
1662 wire = ival;
1663 else if (tag == "side") {
1664 if (sval == "A") {
1665 side = DPSGeometry::kNorth;
1666 }
1667 else if (sval == "B") {
1668 side = DPSGeometry::kSouth;
1669 }
1670 }
1671 else if (tag == "id")
1672 id = ival;
1673 else if (tag == "end") {
1674 if (sval == "U") {
1675 end = DBCALGeometry::kUpstream;
1676 view=1;
1677 }
1678 else if (sval == "D") {
1679 end = DBCALGeometry::kDownstream;
1680 view=3;
1681 }
1682 else if (sval == "N")
1683 end = 0; // TOF north
1684 else if (sval == "S")
1685 end = 1; // TOF south
1686 else if (sval == "UP")
1687 end = 0; // TOF up
1688 else if (sval == "DW")
1689 end = 1; // TOF down
1690 }
1691 else if (tag == "strip_type") {
1692 if (sval == "full")
1693 strip_type = 1;
1694 else if (sval == "A")
1695 strip_type = 2;
1696 else if (sval == "B")
1697 strip_type = 3;
1698 }
1699 else if (tag == "system")
1700 locSystem = sval;
1701 }
1702
1703 // ignore certain module types
1704 if (type == "disc")
1705 return;
1706 if (type == "ctp")
1707 return;
1708 if (type == "sd")
1709 return;
1710 if (type == "a1535sn")
1711 return;
1712
1713
1714// // Data integrity check
1715// if (crate < 0 || crate >= MAXDCRATE) {
1716// jerr << " Crate value of " << crate
1717// << " is not in range 0 <= crate < " << MAXDCRATE << std::endl;
1718// exit(-1);
1719// }
1720//
1721// if (slot < 0 || slot >= MAXDSLOT) {
1722// jerr << " Slot value of " << slot
1723// << " is not in range 0 <= slot < " << MAXDSLOT << std::endl;
1724// exit(-1);
1725// }
1726//
1727// if (channel < 0 || channel >= MAXDCHANNEL) {
1728// jerr << " Crate value of " << channel
1729// << " is not in range 0 <= channel < " << MAXDCHANNEL << std::endl;
1730// exit(-1);
1731// }
1732
1733 // fill maps
1734
1735 DTranslationTable::csc_t csc = {(uint32_t)crate,(uint32_t)slot,(uint32_t)channel};
1736 string detector = Detector;
1737 std::transform(detector.begin(), detector.end(), detector.begin(), (int(*)(int)) tolower);
1738
1739 //string s="unknown::";
1740
1741 // Common indexes
1742 DTranslationTable::DChannelInfo &ci = TT[csc];
1743 ci.CSC = csc;
1744 ci.module_type = (DModuleType::type_id_t)mc2codaType;
1745 ci.det_sys = DetectorStr2DetID(detector);
1746 DTranslationTable::Get_ROCID_By_System()[ci.det_sys].insert(crate);
1747
1748 // detector-specific indexes
1749 switch (ci.det_sys) {
1750 case DTranslationTable::BCAL:
1751 ci.bcal.module = module;
1752 ci.bcal.layer = layer;
1753 ci.bcal.sector = sector;
1754 ci.bcal.end = end;
1755 break;
1756 case DTranslationTable::CDC:
1757 ci.cdc.ring = ring;
1758 ci.cdc.straw = straw;
1759 break;
1760 case DTranslationTable::FCAL:
1761 ci.fcal.row = row;
1762 ci.fcal.col = column;
1763 break;
1764 case DTranslationTable::FDC_CATHODES:
1765 ci.fdc_cathodes.package = package;
1766 ci.fdc_cathodes.chamber = chamber;
1767 ci.fdc_cathodes.view = view;
1768 ci.fdc_cathodes.strip = strip;
1769 ci.fdc_cathodes.strip_type = strip_type;
1770 break;
1771 case DTranslationTable::FDC_WIRES:
1772 ci.fdc_wires.package = package;
1773 ci.fdc_wires.chamber = chamber;
1774 ci.fdc_wires.wire = wire;
1775 break;
1776 case DTranslationTable::RF:
1777 ci.rf.dSystem = NameToSystem(locSystem.c_str());
1778 break;
1779 case DTranslationTable::SC:
1780 ci.sc.sector = sector;
1781 break;
1782 case DTranslationTable::TAGH:
1783 ci.tagh.id = id;
1784 break;
1785 case DTranslationTable::TAGM:
1786 ci.tagm.col = column;
1787 ci.tagm.row = row;
1788 break;
1789 case DTranslationTable::TOF:
1790 ci.tof.plane = plane;
1791 ci.tof.bar = bar;
1792 ci.tof.end = end;
1793 break;
1794 case DTranslationTable::PS:
1795 ci.ps.side = side;
1796 ci.ps.id = id;
1797 break;
1798 case DTranslationTable::PSC:
1799 ci.psc.id = id;
1800 break;
1801 case DTranslationTable::TPOLSECTOR:
1802 ci.tpolsector.sector = sector;
1803 break;
1804 case DTranslationTable::UNKNOWN_DETECTOR:
1805 default:
1806 break;
1807 }
1808
1809 } else {
1810 jerr << std::endl << std::endl
1811 << "?startElement...unknown xml tag " << xmlname
1812 << std::endl << std::endl;
1813 }
1814
1815}
1816
1817
1818//--------------------------------------------------------------------------
1819
1820
1821void EndElement(void *userData, const char *xmlname) {
1822 // nothing to do yet...
1823}
1824
1825
1826//--------------------------------------------------------------------------