Bug Summary

File:alld2/home/sdobbs/Software/jana/jana_0.8.2/Linux_CentOS7.7-x86_64-gcc4.8.5/include/JANA/JEventLoop.h
Warning:line 398, column 7
Null pointer passed to 2nd parameter expecting 'nonnull'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -main-file-name DTranslationTable.cc -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /w/halld-scifs17exp/home/sdobbs/clang/llvm-project/install/lib/clang/12.0.0 -D HAVE_CCDB -D HAVE_RCDB -D HAVE_EVIO -D HAVE_TMVA=1 -D RCDB_MYSQL=1 -D RCDB_SQLITE=1 -D SQLITE_USE_LEGACY_STRUCT=ON -I .Linux_CentOS7.7-x86_64-gcc4.8.5/libraries/TTAB -I libraries/TTAB -I . -I libraries -I libraries/include -I /w/halld-scifs17exp/home/sdobbs/clang/halld_recon/Linux_CentOS7.7-x86_64-gcc4.8.5/include -I external/xstream/include -I /usr/include/tirpc -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/root/root-6.08.06/include -I /w/halld-scifs17exp/halld2/home/sdobbs/Software/jana/jana_0.8.2/Linux_CentOS7.7-x86_64-gcc4.8.5/include -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/ccdb/ccdb_1.06.06/include -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/rcdb/rcdb_0.06.00/cpp/include -I /usr/include/mysql -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/sqlitecpp/SQLiteCpp-2.2.0^bs130/include -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/sqlite/sqlite-3.13.0^bs130/include -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/hdds/hdds-4.9.0/Linux_CentOS7.7-x86_64-gcc4.8.5/src -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/xerces-c/xerces-c-3.1.4/include -I /group/halld/Software/builds/Linux_CentOS7.7-x86_64-gcc4.8.5/evio/evio-4.4.6/Linux-x86_64/include -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5 -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/x86_64-redhat-linux -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/backward -internal-isystem /usr/local/include -internal-isystem /w/halld-scifs17exp/home/sdobbs/clang/llvm-project/install/lib/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /home/sdobbs/work/clang/halld_recon/src -ferror-limit 19 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /tmp/scan-build-2021-01-21-110224-160369-1 -x c++ libraries/TTAB/DTranslationTable.cc

libraries/TTAB/DTranslationTable.cc

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

/w/halld-scifs17exp/halld2/home/sdobbs/Software/jana/jana_0.8.2/Linux_CentOS7.7-x86_64-gcc4.8.5/include/JANA/JEventLoop.h

1// $Id: JEventLoop.h 1763 2006-05-10 14:29:25Z davidl $
2//
3// File: JEventLoop.h
4// Created: Wed Jun 8 12:30:51 EDT 2005
5// Creator: davidl (on Darwin wire129.jlab.org 7.8.0 powerpc)
6//
7
8#ifndef _JEventLoop_
9#define _JEventLoop_
10
11#include <sys/time.h>
12
13#include <vector>
14#include <list>
15#include <string>
16#include <utility>
17#include <typeinfo>
18#include <string.h>
19#include <map>
20#include <utility>
21using std::vector;
22using std::list;
23using std::string;
24using std::type_info;
25
26#include <JANA/jerror.h>
27#include <JANA/JObject.h>
28#include <JANA/JException.h>
29#include <JANA/JEvent.h>
30#include <JANA/JThread.h>
31#include <JANA/JFactory_base.h>
32#include <JANA/JCalibration.h>
33#include <JANA/JGeometry.h>
34#include <JANA/JResourceManager.h>
35#include <JANA/JStreamLog.h>
36
37// The following is here just so we can use ROOT's THtml class to generate documentation.
38#include "cint.h"
39
40
41// Place everything in JANA namespace
42namespace jana{
43
44
45template<class T> class JFactory;
46class JApplication;
47class JEventProcessor;
48
49
50class JEventLoop{
51 public:
52
53 friend class JApplication;
54
55 enum data_source_t{
56 DATA_NOT_AVAILABLE = 1,
57 DATA_FROM_CACHE,
58 DATA_FROM_SOURCE,
59 DATA_FROM_FACTORY
60 };
61
62 typedef struct{
63 string caller_name;
64 string caller_tag;
65 string callee_name;
66 string callee_tag;
67 double start_time;
68 double end_time;
69 data_source_t data_source;
70 }call_stack_t;
71
72 typedef struct{
73 const char* factory_name;
74 string tag;
75 const char* filename;
76 int line;
77 }error_call_stack_t;
78
79 JEventLoop(JApplication *app); ///< Constructor
80 virtual ~JEventLoop(); ////< Destructor
81 virtual const char* className(void){return static_className();}
82 static const char* static_className(void){return "JEventLoop";}
83
84 JApplication* GetJApplication(void) const {return app;} ///< Get pointer to the JApplication object
85 void RefreshProcessorListFromJApplication(void); ///< Re-copy the list of JEventProcessors from JApplication
86 virtual jerror_t AddFactory(JFactory_base* factory); ///< Add a factory
87 jerror_t RemoveFactory(JFactory_base* factory); ///< Remove a factory
88 JFactory_base* GetFactory(const string data_name, const char *tag="", bool allow_deftag=true); ///< Get a specific factory pointer
89 vector<JFactory_base*> GetFactories(void) const {return factories;} ///< Get all factory pointers
90 void GetFactoryNames(vector<string> &factorynames); ///< Get names of all factories in name:tag format
91 void GetFactoryNames(map<string,string> &factorynames); ///< Get names of all factories in map with key=name, value=tag
92 map<string,string> GetDefaultTags(void) const {return default_tags;}
93 jerror_t ClearFactories(void); ///< Reset all factories in preparation for next event.
94 jerror_t PrintFactories(int sparsify=0); ///< Print a list of all factories.
95 jerror_t Print(const string data_name, const char *tag=""); ///< Print the data of the given type
96
97 JCalibration* GetJCalibration();
98 template<class T> bool GetCalib(string namepath, map<string,T> &vals);
99 template<class T> bool GetCalib(string namepath, vector<T> &vals);
100 template<class T> bool GetCalib(string namepath, T &val);
101
102 JGeometry* GetJGeometry();
103 template<class T> bool GetGeom(string namepath, map<string,T> &vals);
104 template<class T> bool GetGeom(string namepath, T &val);
105
106 JResourceManager* GetJResourceManager(void);
107 string GetResource(string namepath);
108 template<class T> bool GetResource(string namepath, T vals, int event_number=0);
109
110 void Initialize(void); ///< Do initializations just before event processing starts
111 jerror_t Loop(void); ///< Loop over events
112 jerror_t OneEvent(uint64_t event_number); ///< Process a specific single event (if source supports it)
113 jerror_t OneEvent(void); ///< Process a single event
114 inline void Pause(void){pause = 1;} ///< Pause event processing
115 inline void Resume(void){pause = 0;} ///< Resume event processing
116 inline void Quit(void){quit = 1;} ///< Clean up and exit the event loop
117 inline bool GetQuit(void) const {return quit;}
118 void QuitProgram(void);
119
120 // Support for random access of events
121 bool HasRandomAccess(void);
122 void AddToEventQueue(uint64_t event_number){ next_events_to_process.push_back(event_number); }
123 void AddToEventQueue(list<uint64_t> &event_numbers) { next_events_to_process.insert(next_events_to_process.end(), event_numbers.begin(), event_numbers.end()); }
124 list<uint64_t> GetEventQueue(void){ return next_events_to_process; }
125 void ClearEventQueue(void){ next_events_to_process.clear(); }
126
127 template<class T> JFactory<T>* GetSingle(const T* &t, const char *tag="", bool exception_if_not_one=true); ///< Get pointer to first data object from (source or factory).
128 template<class T> JFactory<T>* Get(vector<const T*> &t, const char *tag="", bool allow_deftag=true); ///< Get data object pointers from (source or factory)
129 template<class T> JFactory<T>* GetFromFactory(vector<const T*> &t, const char *tag="", data_source_t &data_source=null_data_source, bool allow_deftag=true); ///< Get data object pointers from factory
130 template<class T> jerror_t GetFromSource(vector<const T*> &t, JFactory_base *factory=NULL__null); ///< Get data object pointers from source.
131 inline JEvent& GetJEvent(void){return event;} ///< Get pointer to the current JEvent object.
132 inline void SetJEvent(JEvent *event){this->event = *event;} ///< Set the JEvent pointer.
133 inline void SetAutoFree(int auto_free){this->auto_free = auto_free;} ///< Set the Auto-Free flag on/off
134 inline pthread_t GetPThreadID(void) const {return pthread_id;} ///< Get the pthread of the thread to which this JEventLoop belongs
135 double GetInstantaneousRate(void) const {return rate_instantaneous;} ///< Get the current event processing rate
136 double GetIntegratedRate(void) const {return rate_integrated;} ///< Get the current event processing rate
137 double GetLastEventProcessingTime(void) const {return delta_time_single;}
138 unsigned int GetNevents(void) const {return Nevents;}
139
140 inline bool CheckEventBoundary(uint64_t event_numberA, uint64_t event_numberB);
141
142 inline bool GetCallStackRecordingStatus(void){ return record_call_stack; }
143 inline void DisableCallStackRecording(void){ record_call_stack = false; }
144 inline void EnableCallStackRecording(void){ record_call_stack = true; }
145 inline void CallStackStart(JEventLoop::call_stack_t &cs, const string &caller_name, const string &caller_tag, const string callee_name, const string callee_tag);
146 inline void CallStackEnd(JEventLoop::call_stack_t &cs);
147 inline vector<call_stack_t> GetCallStack(void){return call_stack;} ///< Get the current factory call stack
148 inline void AddToCallStack(call_stack_t &cs){if(record_call_stack) call_stack.push_back(cs);} ///< Add specified item to call stack record but only if record_call_stack is true
149 inline void AddToErrorCallStack(error_call_stack_t &cs){error_call_stack.push_back(cs);} ///< Add layer to the factory call stack
150 inline vector<error_call_stack_t> GetErrorCallStack(void){return error_call_stack;} ///< Get the current factory error call stack
151 void PrintErrorCallStack(void); ///< Print the current factory call stack
152
153 const JObject* FindByID(JObject::oid_t id); ///< Find a data object by its identifier.
154 template<class T> const T* FindByID(JObject::oid_t id); ///< Find a data object by its type and identifier
155 JFactory_base* FindOwner(const JObject *t); ///< Find the factory that owns a data object by pointer
156 JFactory_base* FindOwner(JObject::oid_t id); ///< Find a factory that owns a data object by identifier
157
158 // User defined references
159 template<class T> void SetRef(T *t); ///< Add a user reference to this JEventLoop (must be a pointer)
160 template<class T> T* GetRef(void); ///< Get a user-defined reference of a specific type
161 template<class T> vector<T*> GetRefsT(void); ///< Get all user-defined refrences of a specicif type
162 vector<pair<const char*, void*> > GetRefs(void){ return user_refs; } ///< Get copy of full list of user-defined references
163 template<class T> void RemoveRef(T *t); ///< Remove user reference from list
164
165 // Convenience methods wrapping JEvent methods of same name
166 uint64_t GetStatus(void){return event.GetStatus();}
167 bool GetStatusBit(uint32_t bit){return event.GetStatusBit(bit);}
168 bool SetStatusBit(uint32_t bit, bool val=true){return event.SetStatusBit(bit, val);}
169 bool ClearStatusBit(uint32_t bit){return event.ClearStatusBit(bit);}
170 void ClearStatus(void){event.ClearStatus();}
171 void SetStatusBitDescription(uint32_t bit, string description){event.SetStatusBitDescription(bit, description);}
172 string GetStatusBitDescription(uint32_t bit){return event.GetStatusBitDescription(bit);}
173 void GetStatusBitDescriptions(map<uint32_t, string> &status_bit_descriptions){return event.GetStatusBitDescriptions(status_bit_descriptions);}
174 string StatusWordToString(void);
175
176 private:
177 JEvent event;
178 vector<JFactory_base*> factories;
179 vector<JEventProcessor*> processors;
180 vector<error_call_stack_t> error_call_stack;
181 vector<call_stack_t> call_stack;
182 JApplication *app;
183 JThread *jthread;
184 bool initialized;
185 bool print_parameters_called;
186 int pause;
187 int quit;
188 int auto_free;
189 pthread_t pthread_id;
190 map<string, string> default_tags;
191 vector<pair<string,string> > auto_activated_factories;
192 bool record_call_stack;
193 string caller_name;
194 string caller_tag;
195 vector<uint64_t> event_boundaries;
196 int32_t event_boundaries_run; ///< Run number boundaries were retrieved from (possbily 0)
197 list<uint64_t> next_events_to_process;
198
199 uint64_t Nevents; ///< Total events processed (this thread)
200 uint64_t Nevents_rate; ///< Num. events accumulated for "instantaneous" rate
201 double delta_time_single; ///< Time spent processing last event
202 double delta_time_rate; ///< Integrated time accumulated "instantaneous" rate (partial number of events)
203 double delta_time; ///< Total time spent processing events (this thread)
204 double rate_instantaneous; ///< Latest instantaneous rate
205 double rate_integrated; ///< Rate integrated over all events
206
207 static data_source_t null_data_source;
208
209 vector<pair<const char*, void*> > user_refs;
210};
211
212
213// The following is here just so we can use ROOT's THtml class to generate documentation.
214#ifdef G__DICTIONARY
215typedef JEventLoop::call_stack_t call_stack_t;
216typedef JEventLoop::error_call_stack_t error_call_stack_t;
217#endif
218
219#if !defined(__CINT__) && !defined(__CLING__)
220
221//-------------
222// GetSingle
223//-------------
224template<class T>
225JFactory<T>* JEventLoop::GetSingle(const T* &t, const char *tag, bool exception_if_not_one)
226{
227 /// This is a convenience method that can be used to get a pointer to the single
228 /// object of type T from the specified factory. It simply calls the Get(vector<...>) method
229 /// and copies the first pointer into "t" (or NULL if something other than 1 object is returned).
230 ///
231 /// This is intended to address the common situation in which there is an interest
232 /// in the event if and only if there is exactly 1 object of type T. If the event
233 /// has no objects of that type or more than 1 object of that type (for the specified
234 /// factory) then an exception of type "unsigned long" is thrown with the value
235 /// being the number of objects of type T. You can supress the exception by setting
236 /// exception_if_not_one to false. In that case, you will have to check if t==NULL to
237 /// know if the call succeeded.
238 vector<const T*> v;
239 JFactory<T> *fac = Get(v, tag);
240
241 if(v.size()!=1){
242 t = NULL__null;
243 if(exception_if_not_one) throw v.size();
244 }
245
246 t = v[0];
247
248 return fac;
249}
250
251//-------------
252// Get
253//-------------
254template<class T>
255JFactory<T>* JEventLoop::Get(vector<const T*> &t, const char *tag, bool allow_deftag)
256{
257 /// Retrieve or generate the array of objects of
258 /// type T for the curent event being processed
259 /// by this thread.
260 ///
261 /// By default, preference is given to reading the
262 /// objects from the data source(e.g. file) before generating
263 /// them in the factory. A flag exists in the factory
264 /// however to change this so that the factory is
265 /// given preference.
266 ///
267 /// Note that regardless of the setting of this flag,
268 /// the data are only either read in or generated once.
269 /// Ownership of the objects will always be with the
270 /// factory so subsequent calls will always return pointers to
271 /// the same data.
272 ///
273 /// If the factory is called on to generate the data,
274 /// it is done by calling the factory's Get() method
275 /// which, in turn, calls the evnt() method.
276 ///
277 /// First, we just call the GetFromFactory() method.
278 /// It will make the initial decision as to whether
279 /// it should look in the source first or not. If
280 /// it returns NULL, then the factory couldn't be
281 /// found so we automatically try the file.
282 ///
283 /// Note that if no factory exists to hold the objects
284 /// from the file, one can be created automatically
285 /// providing the <i>JANA:AUTOFACTORYCREATE</i>
286 /// configuration parameter is set.
287
288 // Check if a tag was specified for this data type to use for the
289 // default.
290 const char *mytag = tag
5.1
'tag' is not equal to NULL
5.1
'tag' is not equal to NULL
5.1
'tag' is not equal to NULL
==NULL__null ? "":tag; // protection against NULL tags
6
'?' condition is false
291 if(strlen(mytag)==0 && allow_deftag
6.1
'allow_deftag' is true
6.1
'allow_deftag' is true
6.1
'allow_deftag' is true
){
7
Taking true branch
292 map<string, string>::const_iterator iter = default_tags.find(T::static_className());
293 if(iter!=default_tags.end())tag = iter->second.c_str();
8
Assuming the condition is true
9
Taking true branch
10
Value assigned to 'tag'
294 }
295
296
297 // If we are trying to keep track of the call stack then we
298 // need to add a new call_stack_t object to the the list
299 // and initialize it with the start time and caller/callee
300 // info.
301 call_stack_t cs;
302
303 // Optionally record starting info of call stack entry
304 if(record_call_stack) CallStackStart(cs, caller_name, caller_tag, T::static_className(), tag);
11
Assuming field 'record_call_stack' is false
12
Taking false branch
305
306 // Get the data (or at least try to)
307 JFactory<T>* factory=NULL__null;
308 try{
309 factory = GetFromFactory(t, tag, cs.data_source, allow_deftag);
13
Passing value via 2nd parameter 'tag'
14
Calling 'JEventLoop::GetFromFactory'
310 if(!factory){
311 // No factory exists for this type and tag. It's possible
312 // that the source may be able to provide the objects
313 // but it will need a place to put them. We can create a
314 // dumb JFactory just to hold the data in case the source
315 // can provide the objects. Before we do though, make sure
316 // the user condones this via the presence of the
317 // "JANA:AUTOFACTORYCREATE" config parameter.
318 string p;
319 try{
320 gPARMS->GetParameter("JANA:AUTOFACTORYCREATE", p);
321 }catch(...){}
322 if(p.size()==0){
323 jout<<std::endl;
324 _DBG__std::cerr<<"/w/halld-scifs17exp/halld2/home/sdobbs/Software/jana/jana_0.8.2/Linux_CentOS7.7-x86_64-gcc4.8.5/include/JANA/JEventLoop.h"
<<":"<<324<<std::endl
;
325 jout<<"No factory of type \""<<T::static_className()<<"\" with tag \""<<tag<<"\" exists."<<std::endl;
326 jout<<"If you are reading objects from a file, I can auto-create a factory"<<std::endl;
327 jout<<"of the appropriate type to hold the objects, but this feature is turned"<<std::endl;
328 jout<<"off by default. To turn it on, set the \"JANA:AUTOFACTORYCREATE\""<<std::endl;
329 jout<<"configuration parameter. This can usually be done by passing the"<<std::endl;
330 jout<<"following argument to the program from the command line:"<<std::endl;
331 jout<<std::endl;
332 jout<<" -PJANA:AUTOFACTORYCREATE=1"<<std::endl;
333 jout<<std::endl;
334 jout<<"Note that since the most commonly expected occurance of this situation."<<std::endl;
335 jout<<"is an error, the program will now throw an exception so that the factory."<<std::endl;
336 jout<<"call stack can be printed."<<std::endl;
337 jout<<std::endl;
338 throw exception();
339 }else{
340 AddFactory(new JFactory<T>(tag));
341 jout<<__FILE__"/w/halld-scifs17exp/halld2/home/sdobbs/Software/jana/jana_0.8.2/Linux_CentOS7.7-x86_64-gcc4.8.5/include/JANA/JEventLoop.h"<<":"<<__LINE__341<<" Auto-created "<<T::static_className()<<":"<<tag<<" factory"<<std::endl;
342
343 // Now try once more. The GetFromFactory method will call
344 // GetFromSource since it's empty.
345 factory = GetFromFactory(t, tag, cs.data_source, allow_deftag);
346 }
347 }
348 }catch(exception &e){
349 // Uh-oh, an exception was thrown. Add us to the call stack
350 // and re-throw the exception
351 error_call_stack_t ecs;
352 ecs.factory_name = T::static_className();
353 ecs.tag = tag;
354 ecs.filename = NULL__null;
355 error_call_stack.push_back(ecs);
356 throw e;
357 }
358
359 // If recording the call stack, update the end_time field and add to stack
360 if(record_call_stack) CallStackEnd(cs);
361
362 return factory;
363}
364
365//-------------
366// GetFromFactory
367//-------------
368template<class T>
369JFactory<T>* JEventLoop::GetFromFactory(vector<const T*> &t, const char *tag, data_source_t &data_source, bool allow_deftag)
370{
371 // We need to find the factory providing data type T with
372 // tag given by "tag".
373 vector<JFactory_base*>::iterator iter=factories.begin();
374 JFactory<T> *factory = NULL__null;
375 string className(T::static_className());
376
377 // Check if a tag was specified for this data type to use for the
378 // default.
379 const char *mytag = tag==NULL__null ? "":tag; // protection against NULL tags
15
Assuming 'tag' is equal to NULL
16
'?' condition is true
380 if(strlen(mytag)==0 && allow_deftag
16.1
'allow_deftag' is true
16.1
'allow_deftag' is true
16.1
'allow_deftag' is true
){
17
Taking true branch
381 map<string, string>::const_iterator iter = default_tags.find(className);
382 if(iter!=default_tags.end())tag = iter->second.c_str();
18
Assuming the condition is false
19
Taking false branch
383 }
384
385 for(; iter!=factories.end(); iter++){
20
Calling 'operator!=<jana::JFactory_base **, std::vector<jana::JFactory_base *>>'
23
Returning from 'operator!=<jana::JFactory_base **, std::vector<jana::JFactory_base *>>'
24
Loop condition is true. Entering loop body
386 // It turns out a long standing bug in g++ makes dynamic_cast return
387 // zero improperly when used on objects created on one side of
388 // a dynamically shared object (DSO) and the cast occurs on the
389 // other side. I saw bug reports ranging from 2001 to 2004. I saw
390 // saw it first-hand on LinuxEL4 using g++ 3.4.5. This is too bad
391 // since it is much more elegant (and safe) to use dynamic_cast.
392 // To avoid this problem which can occur with plugins, we check
393 // the name of the data classes are the same. (sigh)
394 //factory = dynamic_cast<JFactory<T> *>(*iter);
395 if(className == (*iter)->GetDataClassName())factory = (JFactory<T>*)(*iter);
25
Taking true branch
396 if(factory == NULL__null)continue;
26
Assuming 'factory' is not equal to NULL
27
Taking false branch
397 const char *factag = factory->Tag()==NULL__null ? "":factory->Tag();
28
Assuming the condition is true
29
'?' condition is true
398 if(!strcmp(factag, tag)){
30
Null pointer passed to 2nd parameter expecting 'nonnull'
399 break;
400 }else{
401 factory=NULL__null;
402 }
403 }
404
405 // If factory not found, just return now
406 if(!factory){
407 data_source = DATA_NOT_AVAILABLE;
408 return NULL__null;
409 }
410
411 // OK, we found the factory. If the evnt() routine has already
412 // been called, then just call the factory's Get() routine
413 // to return a copy of the existing data
414 if(factory->evnt_was_called()){
415 factory->CopyFrom(t);
416 data_source = DATA_FROM_CACHE;
417 return factory;
418 }
419
420 // Next option is to get the objects from the data source
421 if(factory->GetCheckSourceFirst()){
422 // If the object type/tag is found in the source, it
423 // will return NOERROR, even if there are zero instances
424 // of it. If it is not available in the source then it
425 // will return OBJECT_NOT_AVAILABLE.
426
427 jerror_t err = GetFromSource(t, factory);
428 if(err == NOERROR){
429 // A return value of NOERROR means the source had the objects
430 // even if there were zero of them.(If the source had no
431 // information about the objects OBJECT_NOT_AVAILABLE would
432 // have been returned.)
433 // The GetFromSource() call will eventually lead to a call to
434 // the GetObjects() method of the concrete class derived
435 // from JEventSource. That routine should copy the object
436 // pointers into the factory using the factory's CopyTo()
437 // method which also sets the evnt_called flag for the factory.
438 // Note also that the "t" vector is then filled with a call
439 // to the factory's CopyFrom() method in JEvent::GetObjects().
440 // All we need to do now is just set the factory pointers in
441 // the newly generated JObjects and return the factory pointer.
442
443 factory->SetFactoryPointers();
444 data_source = DATA_FROM_SOURCE;
445
446 return factory;
447 }
448 }
449
450 // OK. It looks like we have to have the factory make this.
451 // Get pointers to data from the factory.
452 factory->Get(t);
453 factory->SetFactoryPointers();
454 data_source = DATA_FROM_FACTORY;
455
456 return factory;
457}
458
459//-------------
460// GetFromSource
461//-------------
462template<class T>
463jerror_t JEventLoop::GetFromSource(vector<const T*> &t, JFactory_base *factory)
464{
465 /// This tries to get objects from the event source.
466 /// "factory" must be a valid pointer to a JFactory
467 /// object since that will take ownership of the objects
468 /// created by the source.
469 /// This should usually be called from JEventLoop::GetFromFactory
470 /// which is called from JEventLoop::Get. The latter will
471 /// create a dummy JFactory of the proper flavor and tag if
472 /// one does not already exist so if objects exist in the
473 /// file without a corresponding factory to create them, they
474 /// can still be used.
475 if(!factory)throw OBJECT_NOT_AVAILABLE;
476
477 return event.GetObjects(t, factory);
478}
479
480//-------------
481// CallStackStart
482//-------------
483inline void JEventLoop::CallStackStart(JEventLoop::call_stack_t &cs, const string &caller_name, const string &caller_tag, const string callee_name, const string callee_tag)
484{
485 /// This is used to fill initial info into a call_stack_t stucture
486 /// for recording the call stack. It should be matched with a call
487 /// to CallStackEnd. It is normally called from the Get() method
488 /// above, but may also be used by external actors to manipulate
489 /// the call stack (presumably for good and not evil).
490
491 struct itimerval tmr;
492 getitimer(ITIMER_PROFITIMER_PROF, &tmr);
493
494 cs.caller_name = this->caller_name;
495 cs.caller_tag = this->caller_tag;
496 this->caller_name = cs.callee_name = callee_name;
497 this->caller_tag = cs.callee_tag = callee_tag;
498 cs.start_time = tmr.it_value.tv_sec + tmr.it_value.tv_usec/1.0E6;
499}
500
501//-------------
502// CallStackEnd
503//-------------
504inline void JEventLoop::CallStackEnd(JEventLoop::call_stack_t &cs)
505{
506 /// Complete a call stack entry. This should be matched
507 /// with a previous call to CallStackStart which was
508 /// used to fill the cs structure.
509
510 struct itimerval tmr;
511 getitimer(ITIMER_PROFITIMER_PROF, &tmr);
512 cs.end_time = tmr.it_value.tv_sec + tmr.it_value.tv_usec/1.0E6;
513 caller_name = cs.caller_name;
514 caller_tag = cs.caller_tag;
515 call_stack.push_back(cs);
516}
517
518//-------------
519// CheckEventBoundary
520//-------------
521inline bool JEventLoop::CheckEventBoundary(uint64_t event_numberA, uint64_t event_numberB)
522{
523 /// Check whether the two event numbers span one or more boundaries
524 /// in the calibration/conditions database for the current run number.
525 /// Return true if they do and false if they don't. The first parameter
526 /// "event_numberA" is also checked if it lands on a boundary in which
527 /// case true is also returned. If event_numberB lands on a boundary,
528 /// but event_numberA does not, then false is returned.
529 ///
530 /// This method is not expected to be called by a user. It is, however called,
531 /// everytime a JFactory's Get() method is called.
532
533 // Make sure our copy of the boundaries is up to date
534 if(event.GetRunNumber()!=event_boundaries_run){
535 event_boundaries.clear(); // in case we can't get the JCalibration pointer
536 JCalibration *jcalib = GetJCalibration();
537 if(jcalib)jcalib->GetEventBoundaries(event_boundaries);
538 event_boundaries_run = event.GetRunNumber();
539 }
540
541 // Loop over boundaries
542 for(unsigned int i=0; i<event_boundaries.size(); i++){
543 uint64_t eb = event_boundaries[i];
544 if((eb - event_numberA)*(eb - event_numberB) < 0.0 || eb==event_numberA){ // think about it ....
545 // events span a boundary or is on a boundary. Return true
546 return true;
547 }
548 }
549
550 return false;
551}
552
553//-------------
554// FindByID
555//-------------
556template<class T>
557const T* JEventLoop::FindByID(JObject::oid_t id)
558{
559 /// This is a templated method that can be used in place
560 /// of the non-templated FindByID(oid_t) method if one knows
561 /// the class of the object with the specified id.
562 /// This method is faster than calling the non-templated
563 /// FindByID and dynamic_cast-ing the JObject since
564 /// this will only search the objects of factories that
565 /// produce the desired data type.
566 /// This method will cast the JObject pointer to one
567 /// of the specified type. To use this method,
568 /// a type is specified in the call as follows:
569 ///
570 /// const DMyType *t = loop->FindByID<DMyType>(id);
571
572 // Loop over factories looking for ones that provide
573 // specified data type.
574 for(unsigned int i=0; i<factories.size(); i++){
575 if(factories[i]->GetDataClassName() != T::static_className())continue;
576
577 // This factory provides data of type T. Search it for
578 // the object with the specified id.
579 const JObject *my_obj = factories[i]->GetByID(id);
580 if(my_obj)return dynamic_cast<const T*>(my_obj);
581 }
582
583 return NULL__null;
584}
585
586//-------------
587// GetCalib (map)
588//-------------
589template<class T>
590bool JEventLoop::GetCalib(string namepath, map<string,T> &vals)
591{
592 /// Get the JCalibration object from JApplication for the run number of
593 /// the current event and call its Get() method to get the constants.
594
595 // Note that we could do this by making "vals" a generic type T thus, combining
596 // this with the vector version below. However, doing this explicitly will make
597 // it easier for the user to understand how to call us.
598
599 vals.clear();
600
601 JCalibration *calib = GetJCalibration();
602 if(!calib){
603 _DBG_std::cerr<<"/w/halld-scifs17exp/halld2/home/sdobbs/Software/jana/jana_0.8.2/Linux_CentOS7.7-x86_64-gcc4.8.5/include/JANA/JEventLoop.h"
<<":"<<603<<" "
<<"Unable to get JCalibration object for run "<<event.GetRunNumber()<<std::endl;
604 return true;
605 }
606
607 return calib->Get(namepath, vals, event.GetEventNumber());
608}
609
610//-------------
611// GetCalib (vector)
612//-------------
613template<class T> bool JEventLoop::GetCalib(string namepath, vector<T> &vals)
614{
615 /// Get the JCalibration object from JApplication for the run number of
616 /// the current event and call its Get() method to get the constants.
617
618 vals.clear();
619
620 JCalibration *calib = GetJCalibration();
621 if(!calib){
622 _DBG_std::cerr<<"/w/halld-scifs17exp/halld2/home/sdobbs/Software/jana/jana_0.8.2/Linux_CentOS7.7-x86_64-gcc4.8.5/include/JANA/JEventLoop.h"
<<":"<<622<<" "
<<"Unable to get JCalibration object for run "<<event.GetRunNumber()<<std::endl;
623 return true;
624 }
625
626 return calib->Get(namepath, vals, event.GetEventNumber());
627}
628
629//-------------
630// GetCalib (single)
631//-------------
632template<class T> bool JEventLoop::GetCalib(string namepath, T &val)
633{
634 /// This is a convenience method for getting a single entry. It
635 /// simply calls the vector version and returns the first entry.
636 /// It returns true if the vector version returns true AND there
637 /// is at least one entry in the vector. No check is made for there
638 /// there being more than one entry in the vector.
639
640 vector<T> vals;
641 bool ret = GetCalib(namepath, vals);
642 if(vals.empty()) return true;
643 val = vals[0];
644
645 return ret;
646}
647
648//-------------
649// GetGeom (map)
650//-------------
651template<class T>
652bool JEventLoop::GetGeom(string namepath, map<string,T> &vals)
653{
654 /// Get the JGeometry object from JApplication for the run number of
655 /// the current event and call its Get() method to get the constants.
656
657 // Note that we could do this by making "vals" a generic type T thus, combining
658 // this with the vector version below. However, doing this explicitly will make
659 // it easier for the user to understand how to call us.
660
661 vals.clear();
662
663 JGeometry *geom = GetJGeometry();
664 if(!geom){
665 _DBG_std::cerr<<"/w/halld-scifs17exp/halld2/home/sdobbs/Software/jana/jana_0.8.2/Linux_CentOS7.7-x86_64-gcc4.8.5/include/JANA/JEventLoop.h"
<<":"<<665<<" "
<<"Unable to get JGeometry object for run "<<event.GetRunNumber()<<std::endl;
666 return true;
667 }
668
669 return geom->Get(namepath, vals);
670}
671
672//-------------
673// GetGeom (atomic)
674//-------------
675template<class T> bool JEventLoop::GetGeom(string namepath, T &val)
676{
677 /// Get the JCalibration object from JApplication for the run number of
678 /// the current event and call its Get() method to get the constants.
679
680 JGeometry *geom = GetJGeometry();
681 if(!geom){
682 _DBG_std::cerr<<"/w/halld-scifs17exp/halld2/home/sdobbs/Software/jana/jana_0.8.2/Linux_CentOS7.7-x86_64-gcc4.8.5/include/JANA/JEventLoop.h"
<<":"<<682<<" "
<<"Unable to get JGeometry object for run "<<event.GetRunNumber()<<std::endl;
683 return true;
684 }
685
686 return geom->Get(namepath, val);
687}
688
689//-------------
690// SetRef
691//-------------
692template<class T>
693void JEventLoop::SetRef(T *t)
694{
695 pair<const char*, void*> p(typeid(T).name(), (void*)t);
696 user_refs.push_back(p);
697}
698
699//-------------
700// GetResource
701//-------------
702template<class T> bool JEventLoop::GetResource(string namepath, T vals, int event_number)
703{
704 JResourceManager *resource_manager = GetJResourceManager();
705 if(!resource_manager){
706 string mess = string("Unable to get the JResourceManager object (namepath=\"")+namepath+"\")";
707 throw JException(mess);
708 }
709
710 return resource_manager->Get(namepath, vals, event_number);
711}
712
713//-------------
714// GetRef
715//-------------
716template<class T>
717T* JEventLoop::GetRef(void)
718{
719 /// Get a user-defined reference (a pointer)
720 for(unsigned int i=0; i<user_refs.size(); i++){
721 if(user_refs[i].first == typeid(T).name()) return (T*)user_refs[i].second;
722 }
723
724 return NULL__null;
725}
726
727//-------------
728// GetRefsT
729//-------------
730template<class T>
731vector<T*> JEventLoop::GetRefsT(void)
732{
733 vector<T*> refs;
734 for(unsigned int i=0; i<user_refs.size(); i++){
735 if(user_refs[i].first == typeid(T).name()){
736 refs.push_back((T*)user_refs[i].second);
737 }
738 }
739
740 return refs;
741}
742
743//-------------
744// RemoveRef
745//-------------
746template<class T>
747void JEventLoop::RemoveRef(T *t)
748{
749 vector<pair<const char*, void*> >::iterator iter;
750 for(iter=user_refs.begin(); iter!= user_refs.end(); iter++){
751 if(iter->second == (void*)t){
752 user_refs.erase(iter);
753 return;
754 }
755 }
756 _DBG_std::cerr<<"/w/halld-scifs17exp/halld2/home/sdobbs/Software/jana/jana_0.8.2/Linux_CentOS7.7-x86_64-gcc4.8.5/include/JANA/JEventLoop.h"
<<":"<<756<<" "
<<" Attempt to remove user reference not in event loop!" << std::endl;
757}
758
759
760#endif //__CINT__ __CLING__
761
762} // Close JANA namespace
763
764
765
766#endif // _JEventLoop_
767

/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/bits/stl_iterator.h

1// Iterators -*- C++ -*-
2
3// Copyright (C) 2001-2013 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23// <http://www.gnu.org/licenses/>.
24
25/*
26 *
27 * Copyright (c) 1994
28 * Hewlett-Packard Company
29 *
30 * Permission to use, copy, modify, distribute and sell this software
31 * and its documentation for any purpose is hereby granted without fee,
32 * provided that the above copyright notice appear in all copies and
33 * that both that copyright notice and this permission notice appear
34 * in supporting documentation. Hewlett-Packard Company makes no
35 * representations about the suitability of this software for any
36 * purpose. It is provided "as is" without express or implied warranty.
37 *
38 *
39 * Copyright (c) 1996-1998
40 * Silicon Graphics Computer Systems, Inc.
41 *
42 * Permission to use, copy, modify, distribute and sell this software
43 * and its documentation for any purpose is hereby granted without fee,
44 * provided that the above copyright notice appear in all copies and
45 * that both that copyright notice and this permission notice appear
46 * in supporting documentation. Silicon Graphics makes no
47 * representations about the suitability of this software for any
48 * purpose. It is provided "as is" without express or implied warranty.
49 */
50
51/** @file bits/stl_iterator.h
52 * This is an internal header file, included by other library headers.
53 * Do not attempt to use it directly. @headername{iterator}
54 *
55 * This file implements reverse_iterator, back_insert_iterator,
56 * front_insert_iterator, insert_iterator, __normal_iterator, and their
57 * supporting functions and overloaded operators.
58 */
59
60#ifndef _STL_ITERATOR_H1
61#define _STL_ITERATOR_H1 1
62
63#include <bits/cpp_type_traits.h>
64#include <ext/type_traits.h>
65#include <bits/move.h>
66
67namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
68{
69_GLIBCXX_BEGIN_NAMESPACE_VERSION
70
71 /**
72 * @addtogroup iterators
73 * @{
74 */
75
76 // 24.4.1 Reverse iterators
77 /**
78 * Bidirectional and random access iterators have corresponding reverse
79 * %iterator adaptors that iterate through the data structure in the
80 * opposite direction. They have the same signatures as the corresponding
81 * iterators. The fundamental relation between a reverse %iterator and its
82 * corresponding %iterator @c i is established by the identity:
83 * @code
84 * &*(reverse_iterator(i)) == &*(i - 1)
85 * @endcode
86 *
87 * <em>This mapping is dictated by the fact that while there is always a
88 * pointer past the end of an array, there might not be a valid pointer
89 * before the beginning of an array.</em> [24.4.1]/1,2
90 *
91 * Reverse iterators can be tricky and surprising at first. Their
92 * semantics make sense, however, and the trickiness is a side effect of
93 * the requirement that the iterators must be safe.
94 */
95 template<typename _Iterator>
96 class reverse_iterator
97 : public iterator<typename iterator_traits<_Iterator>::iterator_category,
98 typename iterator_traits<_Iterator>::value_type,
99 typename iterator_traits<_Iterator>::difference_type,
100 typename iterator_traits<_Iterator>::pointer,
101 typename iterator_traits<_Iterator>::reference>
102 {
103 protected:
104 _Iterator current;
105
106 typedef iterator_traits<_Iterator> __traits_type;
107
108 public:
109 typedef _Iterator iterator_type;
110 typedef typename __traits_type::difference_type difference_type;
111 typedef typename __traits_type::pointer pointer;
112 typedef typename __traits_type::reference reference;
113
114 /**
115 * The default constructor value-initializes member @p current.
116 * If it is a pointer, that means it is zero-initialized.
117 */
118 // _GLIBCXX_RESOLVE_LIB_DEFECTS
119 // 235 No specification of default ctor for reverse_iterator
120 reverse_iterator() : current() { }
121
122 /**
123 * This %iterator will move in the opposite direction that @p x does.
124 */
125 explicit
126 reverse_iterator(iterator_type __x) : current(__x) { }
127
128 /**
129 * The copy constructor is normal.
130 */
131 reverse_iterator(const reverse_iterator& __x)
132 : current(__x.current) { }
133
134 /**
135 * A %reverse_iterator across other types can be copied if the
136 * underlying %iterator can be converted to the type of @c current.
137 */
138 template<typename _Iter>
139 reverse_iterator(const reverse_iterator<_Iter>& __x)
140 : current(__x.base()) { }
141
142 /**
143 * @return @c current, the %iterator used for underlying work.
144 */
145 iterator_type
146 base() const
147 { return current; }
148
149 /**
150 * @return A reference to the value at @c --current
151 *
152 * This requires that @c --current is dereferenceable.
153 *
154 * @warning This implementation requires that for an iterator of the
155 * underlying iterator type, @c x, a reference obtained by
156 * @c *x remains valid after @c x has been modified or
157 * destroyed. This is a bug: http://gcc.gnu.org/PR51823
158 */
159 reference
160 operator*() const
161 {
162 _Iterator __tmp = current;
163 return *--__tmp;
164 }
165
166 /**
167 * @return A pointer to the value at @c --current
168 *
169 * This requires that @c --current is dereferenceable.
170 */
171 pointer
172 operator->() const
173 { return &(operator*()); }
174
175 /**
176 * @return @c *this
177 *
178 * Decrements the underlying iterator.
179 */
180 reverse_iterator&
181 operator++()
182 {
183 --current;
184 return *this;
185 }
186
187 /**
188 * @return The original value of @c *this
189 *
190 * Decrements the underlying iterator.
191 */
192 reverse_iterator
193 operator++(int)
194 {
195 reverse_iterator __tmp = *this;
196 --current;
197 return __tmp;
198 }
199
200 /**
201 * @return @c *this
202 *
203 * Increments the underlying iterator.
204 */
205 reverse_iterator&
206 operator--()
207 {
208 ++current;
209 return *this;
210 }
211
212 /**
213 * @return A reverse_iterator with the previous value of @c *this
214 *
215 * Increments the underlying iterator.
216 */
217 reverse_iterator
218 operator--(int)
219 {
220 reverse_iterator __tmp = *this;
221 ++current;
222 return __tmp;
223 }
224
225 /**
226 * @return A reverse_iterator that refers to @c current - @a __n
227 *
228 * The underlying iterator must be a Random Access Iterator.
229 */
230 reverse_iterator
231 operator+(difference_type __n) const
232 { return reverse_iterator(current - __n); }
233
234 /**
235 * @return *this
236 *
237 * Moves the underlying iterator backwards @a __n steps.
238 * The underlying iterator must be a Random Access Iterator.
239 */
240 reverse_iterator&
241 operator+=(difference_type __n)
242 {
243 current -= __n;
244 return *this;
245 }
246
247 /**
248 * @return A reverse_iterator that refers to @c current - @a __n
249 *
250 * The underlying iterator must be a Random Access Iterator.
251 */
252 reverse_iterator
253 operator-(difference_type __n) const
254 { return reverse_iterator(current + __n); }
255
256 /**
257 * @return *this
258 *
259 * Moves the underlying iterator forwards @a __n steps.
260 * The underlying iterator must be a Random Access Iterator.
261 */
262 reverse_iterator&
263 operator-=(difference_type __n)
264 {
265 current += __n;
266 return *this;
267 }
268
269 /**
270 * @return The value at @c current - @a __n - 1
271 *
272 * The underlying iterator must be a Random Access Iterator.
273 */
274 reference
275 operator[](difference_type __n) const
276 { return *(*this + __n); }
277 };
278
279 //@{
280 /**
281 * @param __x A %reverse_iterator.
282 * @param __y A %reverse_iterator.
283 * @return A simple bool.
284 *
285 * Reverse iterators forward many operations to their underlying base()
286 * iterators. Others are implemented in terms of one another.
287 *
288 */
289 template<typename _Iterator>
290 inline bool
291 operator==(const reverse_iterator<_Iterator>& __x,
292 const reverse_iterator<_Iterator>& __y)
293 { return __x.base() == __y.base(); }
294
295 template<typename _Iterator>
296 inline bool
297 operator<(const reverse_iterator<_Iterator>& __x,
298 const reverse_iterator<_Iterator>& __y)
299 { return __y.base() < __x.base(); }
300
301 template<typename _Iterator>
302 inline bool
303 operator!=(const reverse_iterator<_Iterator>& __x,
304 const reverse_iterator<_Iterator>& __y)
305 { return !(__x == __y); }
306
307 template<typename _Iterator>
308 inline bool
309 operator>(const reverse_iterator<_Iterator>& __x,
310 const reverse_iterator<_Iterator>& __y)
311 { return __y < __x; }
312
313 template<typename _Iterator>
314 inline bool
315 operator<=(const reverse_iterator<_Iterator>& __x,
316 const reverse_iterator<_Iterator>& __y)
317 { return !(__y < __x); }
318
319 template<typename _Iterator>
320 inline bool
321 operator>=(const reverse_iterator<_Iterator>& __x,
322 const reverse_iterator<_Iterator>& __y)
323 { return !(__x < __y); }
324
325 template<typename _Iterator>
326 inline typename reverse_iterator<_Iterator>::difference_type
327 operator-(const reverse_iterator<_Iterator>& __x,
328 const reverse_iterator<_Iterator>& __y)
329 { return __y.base() - __x.base(); }
330
331 template<typename _Iterator>
332 inline reverse_iterator<_Iterator>
333 operator+(typename reverse_iterator<_Iterator>::difference_type __n,
334 const reverse_iterator<_Iterator>& __x)
335 { return reverse_iterator<_Iterator>(__x.base() - __n); }
336
337 // _GLIBCXX_RESOLVE_LIB_DEFECTS
338 // DR 280. Comparison of reverse_iterator to const reverse_iterator.
339 template<typename _IteratorL, typename _IteratorR>
340 inline bool
341 operator==(const reverse_iterator<_IteratorL>& __x,
342 const reverse_iterator<_IteratorR>& __y)
343 { return __x.base() == __y.base(); }
344
345 template<typename _IteratorL, typename _IteratorR>
346 inline bool
347 operator<(const reverse_iterator<_IteratorL>& __x,
348 const reverse_iterator<_IteratorR>& __y)
349 { return __y.base() < __x.base(); }
350
351 template<typename _IteratorL, typename _IteratorR>
352 inline bool
353 operator!=(const reverse_iterator<_IteratorL>& __x,
354 const reverse_iterator<_IteratorR>& __y)
355 { return !(__x == __y); }
356
357 template<typename _IteratorL, typename _IteratorR>
358 inline bool
359 operator>(const reverse_iterator<_IteratorL>& __x,
360 const reverse_iterator<_IteratorR>& __y)
361 { return __y < __x; }
362
363 template<typename _IteratorL, typename _IteratorR>
364 inline bool
365 operator<=(const reverse_iterator<_IteratorL>& __x,
366 const reverse_iterator<_IteratorR>& __y)
367 { return !(__y < __x); }
368
369 template<typename _IteratorL, typename _IteratorR>
370 inline bool
371 operator>=(const reverse_iterator<_IteratorL>& __x,
372 const reverse_iterator<_IteratorR>& __y)
373 { return !(__x < __y); }
374
375 template<typename _IteratorL, typename _IteratorR>
376#if __cplusplus201103L >= 201103L
377 // DR 685.
378 inline auto
379 operator-(const reverse_iterator<_IteratorL>& __x,
380 const reverse_iterator<_IteratorR>& __y)
381 -> decltype(__y.base() - __x.base())
382#else
383 inline typename reverse_iterator<_IteratorL>::difference_type
384 operator-(const reverse_iterator<_IteratorL>& __x,
385 const reverse_iterator<_IteratorR>& __y)
386#endif
387 { return __y.base() - __x.base(); }
388 //@}
389
390 // 24.4.2.2.1 back_insert_iterator
391 /**
392 * @brief Turns assignment into insertion.
393 *
394 * These are output iterators, constructed from a container-of-T.
395 * Assigning a T to the iterator appends it to the container using
396 * push_back.
397 *
398 * Tip: Using the back_inserter function to create these iterators can
399 * save typing.
400 */
401 template<typename _Container>
402 class back_insert_iterator
403 : public iterator<output_iterator_tag, void, void, void, void>
404 {
405 protected:
406 _Container* container;
407
408 public:
409 /// A nested typedef for the type of whatever container you used.
410 typedef _Container container_type;
411
412 /// The only way to create this %iterator is with a container.
413 explicit
414 back_insert_iterator(_Container& __x) : container(&__x) { }
415
416 /**
417 * @param __value An instance of whatever type
418 * container_type::const_reference is; presumably a
419 * reference-to-const T for container<T>.
420 * @return This %iterator, for chained operations.
421 *
422 * This kind of %iterator doesn't really have a @a position in the
423 * container (you can think of the position as being permanently at
424 * the end, if you like). Assigning a value to the %iterator will
425 * always append the value to the end of the container.
426 */
427#if __cplusplus201103L < 201103L
428 back_insert_iterator&
429 operator=(typename _Container::const_reference __value)
430 {
431 container->push_back(__value);
432 return *this;
433 }
434#else
435 back_insert_iterator&
436 operator=(const typename _Container::value_type& __value)
437 {
438 container->push_back(__value);
439 return *this;
440 }
441
442 back_insert_iterator&
443 operator=(typename _Container::value_type&& __value)
444 {
445 container->push_back(std::move(__value));
446 return *this;
447 }
448#endif
449
450 /// Simply returns *this.
451 back_insert_iterator&
452 operator*()
453 { return *this; }
454
455 /// Simply returns *this. (This %iterator does not @a move.)
456 back_insert_iterator&
457 operator++()
458 { return *this; }
459
460 /// Simply returns *this. (This %iterator does not @a move.)
461 back_insert_iterator
462 operator++(int)
463 { return *this; }
464 };
465
466 /**
467 * @param __x A container of arbitrary type.
468 * @return An instance of back_insert_iterator working on @p __x.
469 *
470 * This wrapper function helps in creating back_insert_iterator instances.
471 * Typing the name of the %iterator requires knowing the precise full
472 * type of the container, which can be tedious and impedes generic
473 * programming. Using this function lets you take advantage of automatic
474 * template parameter deduction, making the compiler match the correct
475 * types for you.
476 */
477 template<typename _Container>
478 inline back_insert_iterator<_Container>
479 back_inserter(_Container& __x)
480 { return back_insert_iterator<_Container>(__x); }
481
482 /**
483 * @brief Turns assignment into insertion.
484 *
485 * These are output iterators, constructed from a container-of-T.
486 * Assigning a T to the iterator prepends it to the container using
487 * push_front.
488 *
489 * Tip: Using the front_inserter function to create these iterators can
490 * save typing.
491 */
492 template<typename _Container>
493 class front_insert_iterator
494 : public iterator<output_iterator_tag, void, void, void, void>
495 {
496 protected:
497 _Container* container;
498
499 public:
500 /// A nested typedef for the type of whatever container you used.
501 typedef _Container container_type;
502
503 /// The only way to create this %iterator is with a container.
504 explicit front_insert_iterator(_Container& __x) : container(&__x) { }
505
506 /**
507 * @param __value An instance of whatever type
508 * container_type::const_reference is; presumably a
509 * reference-to-const T for container<T>.
510 * @return This %iterator, for chained operations.
511 *
512 * This kind of %iterator doesn't really have a @a position in the
513 * container (you can think of the position as being permanently at
514 * the front, if you like). Assigning a value to the %iterator will
515 * always prepend the value to the front of the container.
516 */
517#if __cplusplus201103L < 201103L
518 front_insert_iterator&
519 operator=(typename _Container::const_reference __value)
520 {
521 container->push_front(__value);
522 return *this;
523 }
524#else
525 front_insert_iterator&
526 operator=(const typename _Container::value_type& __value)
527 {
528 container->push_front(__value);
529 return *this;
530 }
531
532 front_insert_iterator&
533 operator=(typename _Container::value_type&& __value)
534 {
535 container->push_front(std::move(__value));
536 return *this;
537 }
538#endif
539
540 /// Simply returns *this.
541 front_insert_iterator&
542 operator*()
543 { return *this; }
544
545 /// Simply returns *this. (This %iterator does not @a move.)
546 front_insert_iterator&
547 operator++()
548 { return *this; }
549
550 /// Simply returns *this. (This %iterator does not @a move.)
551 front_insert_iterator
552 operator++(int)
553 { return *this; }
554 };
555
556 /**
557 * @param __x A container of arbitrary type.
558 * @return An instance of front_insert_iterator working on @p x.
559 *
560 * This wrapper function helps in creating front_insert_iterator instances.
561 * Typing the name of the %iterator requires knowing the precise full
562 * type of the container, which can be tedious and impedes generic
563 * programming. Using this function lets you take advantage of automatic
564 * template parameter deduction, making the compiler match the correct
565 * types for you.
566 */
567 template<typename _Container>
568 inline front_insert_iterator<_Container>
569 front_inserter(_Container& __x)
570 { return front_insert_iterator<_Container>(__x); }
571
572 /**
573 * @brief Turns assignment into insertion.
574 *
575 * These are output iterators, constructed from a container-of-T.
576 * Assigning a T to the iterator inserts it in the container at the
577 * %iterator's position, rather than overwriting the value at that
578 * position.
579 *
580 * (Sequences will actually insert a @e copy of the value before the
581 * %iterator's position.)
582 *
583 * Tip: Using the inserter function to create these iterators can
584 * save typing.
585 */
586 template<typename _Container>
587 class insert_iterator
588 : public iterator<output_iterator_tag, void, void, void, void>
589 {
590 protected:
591 _Container* container;
592 typename _Container::iterator iter;
593
594 public:
595 /// A nested typedef for the type of whatever container you used.
596 typedef _Container container_type;
597
598 /**
599 * The only way to create this %iterator is with a container and an
600 * initial position (a normal %iterator into the container).
601 */
602 insert_iterator(_Container& __x, typename _Container::iterator __i)
603 : container(&__x), iter(__i) {}
604
605 /**
606 * @param __value An instance of whatever type
607 * container_type::const_reference is; presumably a
608 * reference-to-const T for container<T>.
609 * @return This %iterator, for chained operations.
610 *
611 * This kind of %iterator maintains its own position in the
612 * container. Assigning a value to the %iterator will insert the
613 * value into the container at the place before the %iterator.
614 *
615 * The position is maintained such that subsequent assignments will
616 * insert values immediately after one another. For example,
617 * @code
618 * // vector v contains A and Z
619 *
620 * insert_iterator i (v, ++v.begin());
621 * i = 1;
622 * i = 2;
623 * i = 3;
624 *
625 * // vector v contains A, 1, 2, 3, and Z
626 * @endcode
627 */
628#if __cplusplus201103L < 201103L
629 insert_iterator&
630 operator=(typename _Container::const_reference __value)
631 {
632 iter = container->insert(iter, __value);
633 ++iter;
634 return *this;
635 }
636#else
637 insert_iterator&
638 operator=(const typename _Container::value_type& __value)
639 {
640 iter = container->insert(iter, __value);
641 ++iter;
642 return *this;
643 }
644
645 insert_iterator&
646 operator=(typename _Container::value_type&& __value)
647 {
648 iter = container->insert(iter, std::move(__value));
649 ++iter;
650 return *this;
651 }
652#endif
653
654 /// Simply returns *this.
655 insert_iterator&
656 operator*()
657 { return *this; }
658
659 /// Simply returns *this. (This %iterator does not @a move.)
660 insert_iterator&
661 operator++()
662 { return *this; }
663
664 /// Simply returns *this. (This %iterator does not @a move.)
665 insert_iterator&
666 operator++(int)
667 { return *this; }
668 };
669
670 /**
671 * @param __x A container of arbitrary type.
672 * @return An instance of insert_iterator working on @p __x.
673 *
674 * This wrapper function helps in creating insert_iterator instances.
675 * Typing the name of the %iterator requires knowing the precise full
676 * type of the container, which can be tedious and impedes generic
677 * programming. Using this function lets you take advantage of automatic
678 * template parameter deduction, making the compiler match the correct
679 * types for you.
680 */
681 template<typename _Container, typename _Iterator>
682 inline insert_iterator<_Container>
683 inserter(_Container& __x, _Iterator __i)
684 {
685 return insert_iterator<_Container>(__x,
686 typename _Container::iterator(__i));
687 }
688
689 // @} group iterators
690
691_GLIBCXX_END_NAMESPACE_VERSION
692} // namespace
693
694namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
695{
696_GLIBCXX_BEGIN_NAMESPACE_VERSION
697
698 // This iterator adapter is @a normal in the sense that it does not
699 // change the semantics of any of the operators of its iterator
700 // parameter. Its primary purpose is to convert an iterator that is
701 // not a class, e.g. a pointer, into an iterator that is a class.
702 // The _Container parameter exists solely so that different containers
703 // using this template can instantiate different types, even if the
704 // _Iterator parameter is the same.
705 using std::iterator_traits;
706 using std::iterator;
707 template<typename _Iterator, typename _Container>
708 class __normal_iterator
709 {
710 protected:
711 _Iterator _M_current;
712
713 typedef iterator_traits<_Iterator> __traits_type;
714
715 public:
716 typedef _Iterator iterator_type;
717 typedef typename __traits_type::iterator_category iterator_category;
718 typedef typename __traits_type::value_type value_type;
719 typedef typename __traits_type::difference_type difference_type;
720 typedef typename __traits_type::reference reference;
721 typedef typename __traits_type::pointer pointer;
722
723 _GLIBCXX_CONSTEXPRconstexpr __normal_iterator() : _M_current(_Iterator()) { }
724
725 explicit
726 __normal_iterator(const _Iterator& __i) : _M_current(__i) { }
727
728 // Allow iterator to const_iterator conversion
729 template<typename _Iter>
730 __normal_iterator(const __normal_iterator<_Iter,
731 typename __enable_if<
732 (std::__are_same<_Iter, typename _Container::pointer>::__value),
733 _Container>::__type>& __i)
734 : _M_current(__i.base()) { }
735
736 // Forward iterator requirements
737 reference
738 operator*() const
739 { return *_M_current; }
740
741 pointer
742 operator->() const
743 { return _M_current; }
744
745 __normal_iterator&
746 operator++()
747 {
748 ++_M_current;
749 return *this;
750 }
751
752 __normal_iterator
753 operator++(int)
754 { return __normal_iterator(_M_current++); }
755
756 // Bidirectional iterator requirements
757 __normal_iterator&
758 operator--()
759 {
760 --_M_current;
761 return *this;
762 }
763
764 __normal_iterator
765 operator--(int)
766 { return __normal_iterator(_M_current--); }
767
768 // Random access iterator requirements
769 reference
770 operator[](const difference_type& __n) const
771 { return _M_current[__n]; }
772
773 __normal_iterator&
774 operator+=(const difference_type& __n)
775 { _M_current += __n; return *this; }
776
777 __normal_iterator
778 operator+(const difference_type& __n) const
779 { return __normal_iterator(_M_current + __n); }
780
781 __normal_iterator&
782 operator-=(const difference_type& __n)
783 { _M_current -= __n; return *this; }
784
785 __normal_iterator
786 operator-(const difference_type& __n) const
787 { return __normal_iterator(_M_current - __n); }
788
789 const _Iterator&
790 base() const
791 { return _M_current; }
792 };
793
794 // Note: In what follows, the left- and right-hand-side iterators are
795 // allowed to vary in types (conceptually in cv-qualification) so that
796 // comparison between cv-qualified and non-cv-qualified iterators be
797 // valid. However, the greedy and unfriendly operators in std::rel_ops
798 // will make overload resolution ambiguous (when in scope) if we don't
799 // provide overloads whose operands are of the same type. Can someone
800 // remind me what generic programming is about? -- Gaby
801
802 // Forward iterator requirements
803 template<typename _IteratorL, typename _IteratorR, typename _Container>
804 inline bool
805 operator==(const __normal_iterator<_IteratorL, _Container>& __lhs,
806 const __normal_iterator<_IteratorR, _Container>& __rhs)
807 { return __lhs.base() == __rhs.base(); }
808
809 template<typename _Iterator, typename _Container>
810 inline bool
811 operator==(const __normal_iterator<_Iterator, _Container>& __lhs,
812 const __normal_iterator<_Iterator, _Container>& __rhs)
813 { return __lhs.base() == __rhs.base(); }
814
815 template<typename _IteratorL, typename _IteratorR, typename _Container>
816 inline bool
817 operator!=(const __normal_iterator<_IteratorL, _Container>& __lhs,
818 const __normal_iterator<_IteratorR, _Container>& __rhs)
819 { return __lhs.base() != __rhs.base(); }
820
821 template<typename _Iterator, typename _Container>
822 inline bool
823 operator!=(const __normal_iterator<_Iterator, _Container>& __lhs,
824 const __normal_iterator<_Iterator, _Container>& __rhs)
825 { return __lhs.base() != __rhs.base(); }
21
Assuming the condition is true
22
Returning the value 1, which participates in a condition later
826
827 // Random access iterator requirements
828 template<typename _IteratorL, typename _IteratorR, typename _Container>
829 inline bool
830 operator<(const __normal_iterator<_IteratorL, _Container>& __lhs,
831 const __normal_iterator<_IteratorR, _Container>& __rhs)
832 { return __lhs.base() < __rhs.base(); }
833
834 template<typename _Iterator, typename _Container>
835 inline bool
836 operator<(const __normal_iterator<_Iterator, _Container>& __lhs,
837 const __normal_iterator<_Iterator, _Container>& __rhs)
838 { return __lhs.base() < __rhs.base(); }
839
840 template<typename _IteratorL, typename _IteratorR, typename _Container>
841 inline bool
842 operator>(const __normal_iterator<_IteratorL, _Container>& __lhs,
843 const __normal_iterator<_IteratorR, _Container>& __rhs)
844 { return __lhs.base() > __rhs.base(); }
845
846 template<typename _Iterator, typename _Container>
847 inline bool
848 operator>(const __normal_iterator<_Iterator, _Container>& __lhs,
849 const __normal_iterator<_Iterator, _Container>& __rhs)
850 { return __lhs.base() > __rhs.base(); }
851
852 template<typename _IteratorL, typename _IteratorR, typename _Container>
853 inline bool
854 operator<=(const __normal_iterator<_IteratorL, _Container>& __lhs,
855 const __normal_iterator<_IteratorR, _Container>& __rhs)
856 { return __lhs.base() <= __rhs.base(); }
857
858 template<typename _Iterator, typename _Container>
859 inline bool
860 operator<=(const __normal_iterator<_Iterator, _Container>& __lhs,
861 const __normal_iterator<_Iterator, _Container>& __rhs)
862 { return __lhs.base() <= __rhs.base(); }
863
864 template<typename _IteratorL, typename _IteratorR, typename _Container>
865 inline bool
866 operator>=(const __normal_iterator<_IteratorL, _Container>& __lhs,
867 const __normal_iterator<_IteratorR, _Container>& __rhs)
868 { return __lhs.base() >= __rhs.base(); }
869
870 template<typename _Iterator, typename _Container>
871 inline bool
872 operator>=(const __normal_iterator<_Iterator, _Container>& __lhs,
873 const __normal_iterator<_Iterator, _Container>& __rhs)
874 { return __lhs.base() >= __rhs.base(); }
875
876 // _GLIBCXX_RESOLVE_LIB_DEFECTS
877 // According to the resolution of DR179 not only the various comparison
878 // operators but also operator- must accept mixed iterator/const_iterator
879 // parameters.
880 template<typename _IteratorL, typename _IteratorR, typename _Container>
881#if __cplusplus201103L >= 201103L
882 // DR 685.
883 inline auto
884 operator-(const __normal_iterator<_IteratorL, _Container>& __lhs,
885 const __normal_iterator<_IteratorR, _Container>& __rhs)
886 -> decltype(__lhs.base() - __rhs.base())
887#else
888 inline typename __normal_iterator<_IteratorL, _Container>::difference_type
889 operator-(const __normal_iterator<_IteratorL, _Container>& __lhs,
890 const __normal_iterator<_IteratorR, _Container>& __rhs)
891#endif
892 { return __lhs.base() - __rhs.base(); }
893
894 template<typename _Iterator, typename _Container>
895 inline typename __normal_iterator<_Iterator, _Container>::difference_type
896 operator-(const __normal_iterator<_Iterator, _Container>& __lhs,
897 const __normal_iterator<_Iterator, _Container>& __rhs)
898 { return __lhs.base() - __rhs.base(); }
899
900 template<typename _Iterator, typename _Container>
901 inline __normal_iterator<_Iterator, _Container>
902 operator+(typename __normal_iterator<_Iterator, _Container>::difference_type
903 __n, const __normal_iterator<_Iterator, _Container>& __i)
904 { return __normal_iterator<_Iterator, _Container>(__i.base() + __n); }
905
906_GLIBCXX_END_NAMESPACE_VERSION
907} // namespace
908
909#if __cplusplus201103L >= 201103L
910
911namespace std _GLIBCXX_VISIBILITY(default)__attribute__ ((__visibility__ ("default")))
912{
913_GLIBCXX_BEGIN_NAMESPACE_VERSION
914
915 /**
916 * @addtogroup iterators
917 * @{
918 */
919
920 // 24.4.3 Move iterators
921 /**
922 * Class template move_iterator is an iterator adapter with the same
923 * behavior as the underlying iterator except that its dereference
924 * operator implicitly converts the value returned by the underlying
925 * iterator's dereference operator to an rvalue reference. Some
926 * generic algorithms can be called with move iterators to replace
927 * copying with moving.
928 */
929 template<typename _Iterator>
930 class move_iterator
931 {
932 protected:
933 _Iterator _M_current;
934
935 typedef iterator_traits<_Iterator> __traits_type;
936
937 public:
938 typedef _Iterator iterator_type;
939 typedef typename __traits_type::iterator_category iterator_category;
940 typedef typename __traits_type::value_type value_type;
941 typedef typename __traits_type::difference_type difference_type;
942 // NB: DR 680.
943 typedef _Iterator pointer;
944 typedef value_type&& reference;
945
946 move_iterator()
947 : _M_current() { }
948
949 explicit
950 move_iterator(iterator_type __i)
951 : _M_current(__i) { }
952
953 template<typename _Iter>
954 move_iterator(const move_iterator<_Iter>& __i)
955 : _M_current(__i.base()) { }
956
957 iterator_type
958 base() const
959 { return _M_current; }
960
961 reference
962 operator*() const
963 { return std::move(*_M_current); }
964
965 pointer
966 operator->() const
967 { return _M_current; }
968
969 move_iterator&
970 operator++()
971 {
972 ++_M_current;
973 return *this;
974 }
975
976 move_iterator
977 operator++(int)
978 {
979 move_iterator __tmp = *this;
980 ++_M_current;
981 return __tmp;
982 }
983
984 move_iterator&
985 operator--()
986 {
987 --_M_current;
988 return *this;
989 }
990
991 move_iterator
992 operator--(int)
993 {
994 move_iterator __tmp = *this;
995 --_M_current;
996 return __tmp;
997 }
998
999 move_iterator
1000 operator+(difference_type __n) const
1001 { return move_iterator(_M_current + __n); }
1002
1003 move_iterator&
1004 operator+=(difference_type __n)
1005 {
1006 _M_current += __n;
1007 return *this;
1008 }
1009
1010 move_iterator
1011 operator-(difference_type __n) const
1012 { return move_iterator(_M_current - __n); }
1013
1014 move_iterator&
1015 operator-=(difference_type __n)
1016 {
1017 _M_current -= __n;
1018 return *this;
1019 }
1020
1021 reference
1022 operator[](difference_type __n) const
1023 { return std::move(_M_current[__n]); }
1024 };
1025
1026 // Note: See __normal_iterator operators note from Gaby to understand
1027 // why there are always 2 versions for most of the move_iterator
1028 // operators.
1029 template<typename _IteratorL, typename _IteratorR>
1030 inline bool
1031 operator==(const move_iterator<_IteratorL>& __x,
1032 const move_iterator<_IteratorR>& __y)
1033 { return __x.base() == __y.base(); }
1034
1035 template<typename _Iterator>
1036 inline bool
1037 operator==(const move_iterator<_Iterator>& __x,
1038 const move_iterator<_Iterator>& __y)
1039 { return __x.base() == __y.base(); }
1040
1041 template<typename _IteratorL, typename _IteratorR>
1042 inline bool
1043 operator!=(const move_iterator<_IteratorL>& __x,
1044 const move_iterator<_IteratorR>& __y)
1045 { return !(__x == __y); }
1046
1047 template<typename _Iterator>
1048 inline bool
1049 operator!=(const move_iterator<_Iterator>& __x,
1050 const move_iterator<_Iterator>& __y)
1051 { return !(__x == __y); }
1052
1053 template<typename _IteratorL, typename _IteratorR>
1054 inline bool
1055 operator<(const move_iterator<_IteratorL>& __x,
1056 const move_iterator<_IteratorR>& __y)
1057 { return __x.base() < __y.base(); }
1058
1059 template<typename _Iterator>
1060 inline bool
1061 operator<(const move_iterator<_Iterator>& __x,
1062 const move_iterator<_Iterator>& __y)
1063 { return __x.base() < __y.base(); }
1064
1065 template<typename _IteratorL, typename _IteratorR>
1066 inline bool
1067 operator<=(const move_iterator<_IteratorL>& __x,
1068 const move_iterator<_IteratorR>& __y)
1069 { return !(__y < __x); }
1070
1071 template<typename _Iterator>
1072 inline bool
1073 operator<=(const move_iterator<_Iterator>& __x,
1074 const move_iterator<_Iterator>& __y)
1075 { return !(__y < __x); }
1076
1077 template<typename _IteratorL, typename _IteratorR>
1078 inline bool
1079 operator>(const move_iterator<_IteratorL>& __x,
1080 const move_iterator<_IteratorR>& __y)
1081 { return __y < __x; }
1082
1083 template<typename _Iterator>
1084 inline bool
1085 operator>(const move_iterator<_Iterator>& __x,
1086 const move_iterator<_Iterator>& __y)
1087 { return __y < __x; }
1088
1089 template<typename _IteratorL, typename _IteratorR>
1090 inline bool
1091 operator>=(const move_iterator<_IteratorL>& __x,
1092 const move_iterator<_IteratorR>& __y)
1093 { return !(__x < __y); }
1094
1095 template<typename _Iterator>
1096 inline bool
1097 operator>=(const move_iterator<_Iterator>& __x,
1098 const move_iterator<_Iterator>& __y)
1099 { return !(__x < __y); }
1100
1101 // DR 685.
1102 template<typename _IteratorL, typename _IteratorR>
1103 inline auto
1104 operator-(const move_iterator<_IteratorL>& __x,
1105 const move_iterator<_IteratorR>& __y)
1106 -> decltype(__x.base() - __y.base())
1107 { return __x.base() - __y.base(); }
1108
1109 template<typename _Iterator>
1110 inline auto
1111 operator-(const move_iterator<_Iterator>& __x,
1112 const move_iterator<_Iterator>& __y)
1113 -> decltype(__x.base() - __y.base())
1114 { return __x.base() - __y.base(); }
1115
1116 template<typename _Iterator>
1117 inline move_iterator<_Iterator>
1118 operator+(typename move_iterator<_Iterator>::difference_type __n,
1119 const move_iterator<_Iterator>& __x)
1120 { return __x + __n; }
1121
1122 template<typename _Iterator>
1123 inline move_iterator<_Iterator>
1124 make_move_iterator(_Iterator __i)
1125 { return move_iterator<_Iterator>(__i); }
1126
1127 template<typename _Iterator, typename _ReturnType
1128 = typename conditional<__move_if_noexcept_cond
1129 <typename iterator_traits<_Iterator>::value_type>::value,
1130 _Iterator, move_iterator<_Iterator>>::type>
1131 inline _ReturnType
1132 __make_move_if_noexcept_iterator(_Iterator __i)
1133 { return _ReturnType(__i); }
1134
1135 // @} group iterators
1136
1137_GLIBCXX_END_NAMESPACE_VERSION
1138} // namespace
1139
1140#define _GLIBCXX_MAKE_MOVE_ITERATOR(_Iter)std::make_move_iterator(_Iter) std::make_move_iterator(_Iter)
1141#define _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(_Iter)std::__make_move_if_noexcept_iterator(_Iter) \
1142 std::__make_move_if_noexcept_iterator(_Iter)
1143#else
1144#define _GLIBCXX_MAKE_MOVE_ITERATOR(_Iter)std::make_move_iterator(_Iter) (_Iter)
1145#define _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(_Iter)std::__make_move_if_noexcept_iterator(_Iter) (_Iter)
1146#endif // C++11
1147
1148#endif