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 MyProcessor.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/programs/Analysis/hdview2 -I programs/Analysis/hdview2 -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++ programs/Analysis/hdview2/MyProcessor.cc

programs/Analysis/hdview2/MyProcessor.cc

1// Author: David Lawrence June 25, 2004
2//
3//
4// MyProcessor.cc
5//
6
7#include <iostream>
8#include <vector>
9#include <string>
10using namespace std;
11
12#include <TLorentzVector.h>
13#include <TLorentzRotation.h>
14#include <TEllipse.h>
15#include <TArc.h>
16#include <TBox.h>
17#include <TLine.h>
18#include <TText.h>
19#include <TVector3.h>
20#include <TColor.h>
21#include <TLegend.h>
22
23#include <particleType.h>
24#include "hdview2.h"
25#include "hdv_mainframe.h"
26#include "hdv_debugerframe.h"
27#include "MyProcessor.h"
28#include "TRACKING/DTrackHit.h"
29#include "TRACKING/DQuickFit.h"
30#include "TRACKING/DMagneticFieldStepper.h"
31#include "TRACKING/DTrackCandidate_factory.h"
32#include "TRACKING/DMCTrackHit.h"
33#include "TRACKING/DMCThrown.h"
34#include "TRACKING/DTrackWireBased.h"
35#include "TRACKING/DTrackTimeBased.h"
36#include "PID/DChargedTrack.h"
37#include "TRACKING/DReferenceTrajectory.h"
38#include "JANA/JGeometry.h"
39#include "TRACKING/DMCTrajectoryPoint.h"
40#include "FCAL/DFCALHit.h"
41#include "CCAL/DCCALHit.h"
42#include "CCAL/DCCALShower.h"
43#include "TOF/DTOFGeometry.h"
44#include "TOF/DTOFHit.h"
45#include "TOF/DTOFTDCDigiHit.h"
46#include "TOF/DTOFDigiHit.h"
47#include "TOF/DTOFPaddleHit.h"
48#include "TOF/DTOFPoint.h"
49#include "FDC/DFDCGeometry.h"
50#include "CDC/DCDCTrackHit.h"
51#include "FDC/DFDCPseudo.h"
52#include "FDC/DFDCIntersection.h"
53#include "HDGEOMETRY/DGeometry.h"
54#include "FCAL/DFCALGeometry.h"
55#include "FCAL/DFCALHit.h"
56#include "PID/DNeutralParticle.h"
57#include "PID/DNeutralShower.h"
58#include "BCAL/DBCALHit.h"
59#include "BCAL/DBCALIncidentParticle.h"
60#include "TOF/DTOFPoint.h"
61#include "START_COUNTER/DSCHit.h"
62#include "DVector2.h"
63#include "TRIGGER/DL1Trigger.h"
64
65extern hdv_mainframe *hdvmf;
66
67// These are declared in hdv_mainframe.cc, but as static so we need to do it here as well (yechh!)
68static float FCAL_Zmin = 622.8;
69static float FCAL_Rmin = 6.0;
70static float FCAL_Rmax = 212.0/2.0;
71static float BCAL_Rmin = 65.0;
72static float BCAL_Zlen = 390.0;
73static float BCAL_Zmin = 212.0 - BCAL_Zlen/2.0;
74
75
76static vector<vector <DFDCWire *> >fdcwires;
77
78
79bool DMCTrajectoryPoint_track_cmp(const DMCTrajectoryPoint *a,const DMCTrajectoryPoint *b){
80 // sort by track number and then by particle type, then by z-coordinate
81 // (yes, I saw the same track number have different particle types!)
82 if(a->track != b->track)return a->track < b->track;
83 if(a->part != b->part )return a->part < b->part;
84 return a->z < b->z;
85}
86
87
88MyProcessor *gMYPROC=NULL__null;
89
90//------------------------------------------------------------------
91// MyProcessor
92//------------------------------------------------------------------
93MyProcessor::MyProcessor()
94{
95 Bfield = NULL__null;
96 loop = NULL__null;
97
98 // Tell factory to keep around a few density histos
99 //gPARMS->SetParameter("TRKFIND:MAX_DEBUG_BUFFERS", 16);
100
101 RMAX_INTERIOR = 65.0;
102 RMAX_EXTERIOR = 88.0;
103 gPARMS->SetDefaultParameter("RT:RMAX_INTERIOR", RMAX_INTERIOR, "cm track drawing Rmax inside solenoid region");
104 gPARMS->SetDefaultParameter("RT:RMAX_EXTERIOR", RMAX_EXTERIOR, "cm track drawing Rmax outside solenoid region");
105
106 BCALVERBOSE = 0;
107 gPARMS->SetDefaultParameter("BCALVERBOSE", BCALVERBOSE, "Verbosity level for BCAL objects and display");
108
109 gMYPROC = this;
110}
111
112//------------------------------------------------------------------
113// ~MyProcessor
114//------------------------------------------------------------------
115MyProcessor::~MyProcessor()
116{
117
118}
119
120//------------------------------------------------------------------
121// init
122//------------------------------------------------------------------
123jerror_t MyProcessor::init(void)
124{
125 // Make sure detectors have been drawn
126 //if(!drew_detectors)DrawDetectors();
127
128
129
130 vector<JEventLoop*> loops = app->GetJEventLoops();
131 if(loops.size()>0){
132
133 vector<string> facnames;
134 loops[0]->GetFactoryNames(facnames);
135
136 hdvmf = new hdv_mainframe(gClient(TGClient::Instance())->GetRoot(), 1400, 700);
137 hdvmf->SetCandidateFactories(facnames);
138 hdvmf->SetWireBasedTrackFactories(facnames);
139 hdvmf->SetTimeBasedTrackFactories(facnames);
140 hdvmf->SetReconstructedFactories(facnames);
141 hdvmf->SetChargedTrackFactories(facnames);
142 fulllistmf = hdvmf->GetFullListFrame();
143 debugermf = hdvmf->GetDebugerFrame();
144 BCALHitCanvas = hdvmf->GetBcalDispFrame();
145
146 if (BCALHitCanvas){
147 BCALHitMatrixU = new TH2F("BCALHitMatrixU","BCAL Hits Upstream", 48*4+2, -1.5, 192.5, 10, 0., 10.);
148 BCALHitMatrixD = new TH2F("BCALHitMatrixD","BCAL Hits Downstream",48*4+2, -1.5, 192.5, 10, 0., 10.);
149 BCALParticles = new TH2F("BCALParticles","BCAL Hits Downstream",(48*4+2)*4, -1.87, 361.87, 1, 0., 1.);
150 BCALHitMatrixU->SetStats(0);
151 BCALHitMatrixD->SetStats(0);
152 BCALParticles->SetStats(0);
153 BCALHitMatrixU->GetXaxis()->SetTitle("Sector number");
154 BCALHitMatrixD->GetXaxis()->SetTitle("Sector number");
155 BCALParticles->GetXaxis()->SetTitle("Phi angle [deg]");
156 }
157 }
158
159 return NOERROR;
160}
161
162//------------------------------------------------------------------
163// brun
164//------------------------------------------------------------------
165jerror_t MyProcessor::brun(JEventLoop *eventloop, int32_t runnumber)
166{
167
168 // Read in Magnetic field map
169 DApplication* dapp = dynamic_cast<DApplication*>(eventloop->GetJApplication());
170 Bfield = dapp->GetBfield(runnumber);
171 const DGeometry *dgeom = dapp->GetDGeometry(runnumber);
172 dgeom->GetFDCWires(fdcwires);
173
174 RootGeom = dapp->GetRootGeom(runnumber);
175 geom = dapp->GetDGeometry(runnumber);
176
177 MATERIAL_MAP_MODEL="DGeometry";
178 gPARMS->SetDefaultParameter("TRKFIT:MATERIAL_MAP_MODEL", MATERIAL_MAP_MODEL);
179
180 eventloop->GetCalib("PID/photon_track_matching", photon_track_matching);
181 DELTA_R_FCAL = photon_track_matching["DELTA_R_FCAL"];
182
183 return NOERROR;
184}
185
186//------------------------------------------------------------------
187// evnt
188//------------------------------------------------------------------
189jerror_t MyProcessor::evnt(JEventLoop *eventLoop, uint64_t eventnumber)
190{
191 if(!eventLoop)return NOERROR;
192 loop = eventLoop;
193 last_jevent.FreeEvent();
194 last_jevent = loop->GetJEvent();
195
196 // get the trigger bits
197 char trigstring[10];
198 const DL1Trigger *trig = NULL__null;
199 try {
200 loop->GetSingle(trig);
201 } catch (...) {}
202 if (trig) {
203 sprintf(trigstring,"0x%04x",trig->trig_mask);
204 } else {
205 sprintf(trigstring,"no bits");
206 }
207 hdvmf->SetTrig(trigstring);
208
209 string source = "<no source>";
210 if(last_jevent.GetJEventSource())source = last_jevent.GetJEventSource()->GetSourceName();
211
212 cout<<"----------- New Event "<<eventnumber<<" (run " << last_jevent.GetRunNumber()<<") -------------"<<endl;
213 hdvmf->SetEvent(eventnumber);
214 hdvmf->SetRun(last_jevent.GetRunNumber());
215 hdvmf->SetSource(source.c_str());
216 hdvmf->DoMyRedraw();
217
218 japp->SetSequentialEventComplete();
219
220 return NOERROR;
221}
222
223//------------------------------------------------------------------
224// FillGraphics
225//------------------------------------------------------------------
226void MyProcessor::FillGraphics(void)
227{
228 /// Create "graphics" objects for this event given the current GUI settings.
229 ///
230 /// This method will create DGraphicSet objects that represent tracks, hits,
231 /// and showers for the event. It creates objects for both hits and
232 /// reconstructed entities. The "graphics" objects created here are
233 /// really just collections of 3D space points with flags indicating
234 /// whether they should be drawn as markers or lines and with what
235 /// color and size. The actual graphics objects are created for the
236 /// various views of the detector in hdv_mainframe.
237
238 graphics.clear();
239 graphics_xyA.clear(); // The objects placed in these will be deleted by hdv_mainframe
240 graphics_xyB.clear(); // The objects placed in these will be deleted by hdv_mainframe
241 graphics_xz.clear(); // The objects placed in these will be deleted by hdv_mainframe
242 graphics_yz.clear(); // The objects placed in these will be deleted by hdv_mainframe
243 graphics_tof_hits.clear(); // The objects placed in these will be deleted by hdv_mainframe
244
245 if(!loop)return;
246
247 vector<const DSCHit *>schits;
248 loop->Get(schits);
249 vector<const DTrackCandidate*> trCand;
250 loop->Get(trCand);
251 vector<const DTrackTimeBased*> trTB;
252 loop->Get(trTB);
253 vector<const DTrackWireBased*> trWB;
254 loop->Get(trWB);
255 hdv_debugerframe *p = hdvmf->GetDebugerFrame();
256 p->SetNTrCand(trCand.size());
257 p->SetNTrWireBased(trWB.size());
258 p->SetNTrTimeBased(trTB.size());
259
260 if (BCALHitCanvas) {
261 vector<const DBCALHit*> locBcalHits;
262 loop->Get(locBcalHits);
263 BCALHitMatrixU->Reset();
264 BCALHitMatrixD->Reset();
265 for (unsigned int k=0;k<locBcalHits.size();k++){
266
267 const DBCALHit* hit = locBcalHits[k];
268 float idxY = (float)hit->layer-1;
269 float idxX = (float) (hit->sector-1 + (hit->module-1)*4);
270 if (hit->end == DBCALGeometry::kUpstream){
271 if (hit->layer==1){
272 BCALHitMatrixU->Fill(idxX,idxY,hit->E);
273 } else if (hit->layer==2){
274 BCALHitMatrixU->Fill(idxX,idxY,hit->E);
275 BCALHitMatrixU->Fill(idxX,idxY+1.,hit->E);
276 } else if (hit->layer==3){
277 BCALHitMatrixU->Fill(idxX,idxY+1,hit->E);
278 BCALHitMatrixU->Fill(idxX,idxY+2.,hit->E);
279 BCALHitMatrixU->Fill(idxX,idxY+3.,hit->E);
280 } else if (hit->layer==4){
281 BCALHitMatrixU->Fill(idxX,idxY+3,hit->E);
282 BCALHitMatrixU->Fill(idxX,idxY+4.,hit->E);
283 BCALHitMatrixU->Fill(idxX,idxY+5.,hit->E);
284 BCALHitMatrixU->Fill(idxX,idxY+6.,hit->E);
285 }
286 } else {
287 if (hit->layer==1){
288 BCALHitMatrixD->Fill(idxX,idxY,hit->E);
289 } else if (hit->layer==2){
290 BCALHitMatrixD->Fill(idxX,idxY,hit->E);
291 BCALHitMatrixD->Fill(idxX,idxY+1.,hit->E);
292 } else if (hit->layer==3){
293 BCALHitMatrixD->Fill(idxX,idxY+1,hit->E);
294 BCALHitMatrixD->Fill(idxX,idxY+2.,hit->E);
295 BCALHitMatrixD->Fill(idxX,idxY+3.,hit->E);
296 } else if (hit->layer==4){
297 BCALHitMatrixD->Fill(idxX,idxY+3,hit->E);
298 BCALHitMatrixD->Fill(idxX,idxY+4.,hit->E);
299 BCALHitMatrixD->Fill(idxX,idxY+5.,hit->E);
300 BCALHitMatrixD->Fill(idxX,idxY+6.,hit->E);
301 }
302 }
303 }
304
305 // Fill BCAL points into layer histograms
306 vector<const DBCALPoint*> locBcalPoint;
307 loop->Get(locBcalPoint);
308 for (int layer=0; layer<4; layer++) {
309 BCALPointZphiLayer[layer]->Reset();
310 BCALPointPhiTLayer[layer]->Reset();
311 }
312
313 vector<double> BCALpoints_z;
314 vector<double> BCALpoints_phi;
315 vector<double>::const_iterator points_min_phi;
316 vector<double>::const_iterator points_max_phi;
317 vector<double>::const_iterator points_min_z;
318 vector<double>::const_iterator points_max_z;
319
320 for(unsigned int k=0;k<locBcalPoint.size();k++){
321 BCALpoints_z.push_back(locBcalPoint[k]->z());
322 BCALpoints_phi.push_back(locBcalPoint[k]->phi()*TMath::RadToDeg());
323 }
324
325 if(BCALpoints_phi.size() > 0){
326 points_min_phi = min_element(BCALpoints_phi.begin(),BCALpoints_phi.end());
327 points_max_phi = max_element(BCALpoints_phi.begin(),BCALpoints_phi.end());
328 }
329
330 if(BCALpoints_z.size() > 0){
331 points_min_z = min_element(BCALpoints_z.begin(),BCALpoints_z.end());
332 points_max_z = max_element(BCALpoints_z.begin(),BCALpoints_z.end());
333 }
334
335 BCALpoints_z.clear();
336 BCALpoints_phi.clear();
337
338 for (unsigned int k=0;k<locBcalPoint.size();k++){
339 const DBCALPoint* point = locBcalPoint[k];
340 float pointphi = point->phi()*TMath::RadToDeg();
341 if (pointphi>360) pointphi-=360;
342 if (pointphi<0) pointphi+=360;
343 if (BCALVERBOSE>0) printf(" %3i (m,l,s) = (%2i,%i,%i) (z,phi) = (%6.1f,%4.0f) t=%7.2f E=%6.1f MeV\n",
344 k, point->module(), point->layer(), point->sector(),point->z(),
345 pointphi,point->t(),point->E()*1000);
346 float weight = log(point->E()*1000);
347 BCALPointZphiLayer[point->layer()-1]->Fill(pointphi,point->z(),weight);
348 BCALPointZphiLayer[point->layer()-1]->GetXaxis()->SetRangeUser((*points_min_phi-2),(*points_max_phi+2));
349 BCALPointZphiLayer[point->layer()-1]->GetYaxis()->SetRangeUser((*points_min_z-5),(*points_max_z+5));
350 float time = point->t();
351 if (point->t()>100) time=99; // put overflow in last bin
352 if (point->t()<-100) time=-99;
353 BCALPointPhiTLayer[point->layer()-1]->Fill(pointphi,time,weight);
354 }
355
356 // Fill BCAL Clusters into histograms
357 vector<const DBCALCluster*> locBcalCluster;
358 loop->Get(locBcalCluster);
359
360 unsigned int oldsize = BCALClusterZphiHistos.size();
361 for (unsigned int k=0;k<oldsize;k++){
362 delete BCALClusterZphiHistos[k];
363 }
364 BCALClusterZphiHistos.clear();
365
366 delete ClusterLegend;
367 ClusterLegend = new TLegend(0.91,0.01,0.99,0.99);
368
369 for(unsigned int k = 0 ; k < locBcalCluster.size() ; k++){
370 const DBCALCluster* cluster_range = locBcalCluster[k];
371
372 vector<const DBCALPoint*> clusterpoints_range;
373 cluster_range->Get(clusterpoints_range);
374
375 for(unsigned int l=0;l<clusterpoints_range.size();l++){
376 BCALpoints_z.push_back(clusterpoints_range[l]->z());
377 BCALpoints_phi.push_back(clusterpoints_range[l]->phi()*TMath::RadToDeg());
378 }
379
380 if(BCALpoints_phi.size() > 0){
381 points_min_phi = min_element(BCALpoints_phi.begin(),BCALpoints_phi.end());
382 points_max_phi = max_element(BCALpoints_phi.begin(),BCALpoints_phi.end());
383 }
384
385 if(BCALpoints_z.size() > 0){
386 points_min_z = min_element(BCALpoints_z.begin(),BCALpoints_z.end());
387 points_max_z = max_element(BCALpoints_z.begin(),BCALpoints_z.end());
388 }
389
390 }
391
392 BCALpoints_z.clear();
393 BCALpoints_phi.clear();
394
395 for (unsigned int k=0;k<locBcalCluster.size();k++){
396 char name[255];
397 sprintf(name,"ClusterZphi%i",k);
398 BCALClusterZphiHistos.push_back(new TH2F(name,"BCAL Clusters;Phi angle [deg];Z position (cm)",48*4,0,360,48,-80,400));
399 int color=k+1;
400 if (k>3) color=k+2; // remove yellow
401 if (k>7) color=k+3; // remove white
402 FormatHistogram(BCALClusterZphiHistos[k],color);
403 BCALClusterZphiHistos[k]->SetLineWidth(2);
404 sprintf(name,"Cluster %i",k+1);
405 ClusterLegend->AddEntry(BCALClusterZphiHistos[k], name);
406
407 const DBCALCluster* cluster = locBcalCluster[k];
408 if (BCALVERBOSE>0) printf("cluster %2i, (phi,theta,rho) = (%6.2f,%6.2f,%7.2f) t=%8.3f E=%8.2f MeV\n", k+1,cluster->phi(), cluster->theta(), cluster->rho(), cluster->t(), cluster->E()*1000);
409 vector<const DBCALPoint*> clusterpoints;
410 cluster->Get(clusterpoints);
411
412 for (unsigned int l=0;l<clusterpoints.size();l++){
413 const DBCALPoint* clusterpoint = clusterpoints[l];
414 float weight = log(clusterpoint->E()*1000);
415 float pointphi = clusterpoint->phi()*TMath::RadToDeg();
416 if (pointphi>360) pointphi-=360;
417 if (pointphi<0) pointphi+=360;
418 if (BCALVERBOSE>1) printf(" (m,l,s) = (%2i,%i,%i) (z,phi) = (%6.1f,%4.0f) t=%7.2f E=%6.1f MeV\n",
419 clusterpoint->module(), clusterpoint->layer(), clusterpoint->sector(),clusterpoint->z(),
420 pointphi,clusterpoint->t(),clusterpoint->E()*1000);
421 BCALClusterZphiHistos[k]->Fill(pointphi,clusterpoint->z(),weight);
422 BCALClusterZphiHistos[k]->GetXaxis()->SetRangeUser((*points_min_phi - 2),(*points_max_phi + 2));
423 BCALClusterZphiHistos[k]->GetYaxis()->SetRangeUser((*points_min_z-10),(*points_max_z+10));
424 }
425 }
426
427 vector<const DBCALIncidentParticle*> locBcalParticles;
428 loop->Get(locBcalParticles);
429 BCALParticles->Reset();
430 BCALPLables.clear();
431 for (unsigned int k=0;k<locBcalParticles.size();k++){
432 const DBCALIncidentParticle* part = locBcalParticles[k];
433
434 float p = TMath::Sqrt(part->px*part->px + part->py*part->py + part->pz*part->pz);
435 float phi=999;
436 if (part->x!=0){
437 phi = TMath::ATan(TMath::Abs(part->y/part->x));
438 //cout<<phi<<" "<<part->y<<" / "<< part->x<<endl;
439 if (part->y>0){
440 if (part->x<0.){
441 phi = 3.1415926 - phi;
442 }
443 } else {
444 if (part->x<0){
445 phi += 3.1415926;
446 } else {
447 phi = 3.1415926*2. - phi;
448 }
449 }
450
451 phi = phi*180./3.1415926;
452 }
453 //cout<<phi<<" "<<p<<endl;
454 BCALParticles->Fill(phi,0.5,p);
455 char l[20];
456 sprintf(l,"%d",part->ptype);
457 TText *t = new TText(phi,1.01,l);
458 t->SetTextSize(0.08);
459 t->SetTextFont(72);
460 t->SetTextAlign(21);
461 BCALPLables.push_back(t);
462 }
463
464 // Get Maximum bin from cluster histograms
465 float clustermax=0;
466 if (BCALClusterZphiHistos.size()>0) {
467 float max = BCALClusterZphiHistos[0]->GetMaximum();
468 if (max>clustermax) clustermax=max;
469 }
470
471 BCALHitCanvas->Clear();
472 BCALHitCanvas->Divide(1,3,0.001,0.001);
473 float leftmargin = 0.07;
474 BCALHitCanvas->cd(1);
475 gPad(TVirtualPad::Pad())->SetGridx();
476 gPad(TVirtualPad::Pad())->SetGridy();
477 gPad(TVirtualPad::Pad())->SetLeftMargin(leftmargin);
478 // if (BCALHitMatrixU->GetMaximum() < 1) {
479 // BCALHitMatrixU->Scale(1000); // Scale histogram to MeV
480 // BCALHitMatrixU->GetZaxis()->SetTitle("Energy (MeV)");
481 // } else {
482 // BCALHitMatrixU->GetZaxis()->SetTitle("Energy (GeV)");
483 // }
484 // BCALHitMatrixU->Draw("colz");
485
486 bool firstup=1;
487
488 for (int layer=0; layer<4; layer++) {
489 if (BCALPointPhiTLayer[layer]->GetEntries()>0) {
490 BCALPointPhiTLayer[layer]->SetMaximum(clustermax);
491 if (firstup==1) {
492 BCALPointPhiTLayer[layer]->Draw("box");
493 firstup=0;
494 } else {
495 BCALPointPhiTLayer[layer]->Draw("box,same");
496 }
497 }
498 }
499 LayerLegend->Draw();
500
501 BCALHitCanvas->cd(2);
502 gPad(TVirtualPad::Pad())->SetGridx();
503 gPad(TVirtualPad::Pad())->SetGridy();
504 gPad(TVirtualPad::Pad())->SetLeftMargin(leftmargin);
505 // if (BCALHitMatrixD->GetMaximum() < 1) {
506 // BCALHitMatrixD->Scale(1000); // Scale histogram to MeV
507 // BCALHitMatrixD->GetZaxis()->SetTitle("Energy (MeV)");
508 // } else {
509 // BCALHitMatrixU->GetZaxis()->SetTitle("Energy (GeV)");
510 // }
511 // BCALHitMatrixD->Draw("colz");
512 for (int layer=0; layer<4; layer++) {
513 if (BCALPointZphiLayer[layer]->GetEntries()>0) {
514 BCALPointZphiLayer[layer]->SetMaximum(clustermax);
515 if (firstup==1) {
516 BCALPointZphiLayer[layer]->Draw("box");
517 firstup=0;
518 } else {
519 BCALPointZphiLayer[layer]->Draw("box,same");
520 }
521 }
522 }
523 LayerLegend->Draw();
524
525 BCALHitCanvas->cd(3);
526 gPad(TVirtualPad::Pad())->SetGridx();
527 gPad(TVirtualPad::Pad())->SetGridy();
528 gPad(TVirtualPad::Pad())->SetLeftMargin(leftmargin);
529 if (BCALClusterZphiHistos.size()>0) {
530 BCALClusterZphiHistos[0]->SetMaximum(clustermax);
531 BCALClusterZphiHistos[0]->Draw("box");
532 for (unsigned int k=1; k<BCALClusterZphiHistos.size(); k++) {
533 BCALClusterZphiHistos[k]->SetMaximum(clustermax);
534 BCALClusterZphiHistos[k]->Draw("box,same");
535 }
536 }
537 ClusterLegend->Draw();
538 // BCALParticles->Draw("colz");
539 // for (unsigned int n=0;n<BCALPLables.size();n++){
540 // BCALPLables[n]->Draw("same");
541 // }
542 BCALHitCanvas->Update();
543 }
544
545
546 // BCAL hits
547 if(hdvmf->GetCheckButton("bcal")){
548 vector<const DBCALHit*> bcalhits;
549 loop->Get(bcalhits);
550
551 for(unsigned int i=0; i<bcalhits.size(); i++){
552 const DBCALHit *hit = bcalhits[i];
553 TPolyLine *poly = hdvmf->GetBCALPolyLine(hit->module, hit->layer, hit->sector);
554
555 if(!poly)continue;
556
557 // The aim is to have a log scale in energy
558 double E = 1000.0*hit->E; // Energy in MeV
559 double logE = log10(E);
560 // 3 = 1 GeV, 0 = 1 MeV, use range 0 through 4
561 // 0-1 White-Yellow
562 // 1-2 Yellow-Red
563 // 2-3 Red-Cyan
564 // 3-4 Cyan-Blue
565
566 float r,g,b;
567 if (E<1){
568 r = 1.;
569 g = 1.;
570 b = 1.;
571 } else {
572 if (logE<1){
573 r = 1.;
574 g = 1.;
575 b = 1.-logE;
576 } else {
577 if (logE<2){
578 r = 1.;
579 g = 1.-(logE-1);
580 b = 0.;
581 } else {
582 if (logE<3){
583 r = 1.;
584 g = 0.;
585 b = 1.-(logE-2);
586 } else {
587 if (logE<4){
588 r = 1.-(logE-3);
589 g = 0.;
590 b = 1.;
591 } else {
592 r = 0;
593 g = 1.;
594 b = 0.;
595 //printf("High BCAL cell reconstructed energy: E=%.1f MeV\n",E);
596 }
597 }
598 }
599 }
600 }
601 if (r<0||g<0||b<0||r>1||g>1||b>1) printf("color error (r,g,b)=(%f,%f,%f)\n",r,g,b);
602
603 poly->SetFillColor(TColor::GetColor(r,g,b));
604 poly->SetLineColor(TColor::GetColor(r,g,b));
605 poly->SetLineWidth(1);
606 poly->SetFillStyle(1001);
607 }
608 }
609
610 // FCAL hits
611 if(hdvmf->GetCheckButton("fcal")){
612 vector<const DFCALHit*> fcalhits;
613 loop->Get(fcalhits);
614
615 for(unsigned int i=0; i<fcalhits.size(); i++){
616 const DFCALHit *hit = fcalhits[i];
617 TPolyLine *poly = hdvmf->GetFCALPolyLine(hit->row, hit->column);
618 if(!poly)continue;
619
620#if 0
621 double a = hit->E/0.005;
622 double f = sqrt(a>1.0 ? 1.0:a<0.0 ? 0.0:a);
623 double grey = 0.8;
624 double s = 1.0 - f;
625
626 float r = s*grey;
627 float g = s*grey;
628 float b = f*(1.0-grey) + grey;
629#endif
630
631 // The aim is to have a log scale in energy (see BCAL)
632 double E = 1000*hit->E; // Change Energy to MeV
633 if(E<0.0) continue;
634 double logE = log10(E);
635
636 float r,g,b;
637 if (logE<0){
638 r = 1.;
639 g = 1.;
640 b = 1.;
641 } else {
642 if (logE<1){
643 r = 1.;
644 g = 1.;
645 b = 1.-logE;
646 } else {
647 if (logE<2){
648 r = 1.;
649 g = 1.-(logE-1);
650 b = 0.;
651 } else {
652 if (logE<3){
653 r = 1.;
654 g = 0.;
655 b = 1.-(logE-2);
656 } else {
657 if (logE<4){
658 r = 1.-(logE-3);
659 g = 0.;
660 b = 1.;
661 } else {
662 r = 0;
663 g = 0;
664 b = 0;
665 }
666 }
667 }
668 }
669 }
670 poly->SetFillColor(TColor::GetColor(r,g,b));
671 }
672 }
673
674 // CCAL hits
675 if(hdvmf->GetCheckButton("ccal")){
676 vector<const DCCALHit*> ccalhits;
677 loop->Get(ccalhits);
678
679 for(unsigned int i=0; i<ccalhits.size(); i++){
680 const DCCALHit *hit = ccalhits[i];
681 TPolyLine *poly = hdvmf->GetCCALPolyLine(hit->row, hit->column);
682 if(!poly)continue;
683
684 // The aim is to have a log scale in energy (see BCAL)
685 double E = 1000*hit->E; // Change Energy to MeV
686 E /= 1000.0; // CCAL is currently not calibrated and appears to be at least 1E3 too large 2018-12-10 DL
687 if(E<0.0) continue;
688 double logE = log10(E);
689
690 float r,g,b;
691 if (logE<0){
692 r = 1.;
693 g = 1.;
694 b = 1.;
695 } else {
696 if (logE<1){
697 r = 1.;
698 g = 1.;
699 b = 1.-logE;
700 } else {
701 if (logE<2){
702 r = 1.;
703 g = 1.-(logE-1);
704 b = 0.;
705 } else {
706 if (logE<3){
707 r = 1.;
708 g = 0.;
709 b = 1.-(logE-2);
710 } else {
711 if (logE<4){
712 r = 1.-(logE-3);
713 g = 0.;
714 b = 1.;
715 } else {
716 r = 0;
717 g = 0;
718 b = 0;
719 }
720 }
721 }
722 }
723 }
724 poly->SetFillColor(TColor::GetColor(r,g,b));
725 }
726 }
727
728 // TOF hits
729 if(hdvmf->GetCheckButton("tof")){
730
731 double hit_north[45];
732 double hit_south[45];
733 double hit_up[45];
734 double hit_down[45];
735
736 memset(hit_north,0,sizeof(hit_north));
737 memset(hit_south,0,sizeof(hit_south));
738 memset(hit_up,0,sizeof(hit_up));
739 memset(hit_down,0,sizeof(hit_down));
740
741 vector<const DTOFHit*> tofhits;
742 loop->Get(tofhits);
743
744 for(unsigned int i=0; i<tofhits.size(); i++){
745 const DTOFHit *tof_hit = tofhits[i];
746
747 int plane = tof_hit->plane;
748 int bar = tof_hit->bar;
749 int end = tof_hit->end;
750 float t = tof_hit->t;
751
752 int translate_side;
753 TPolyLine *pmtPline;
754
755
756 // Flash the PMTs that do have fADC hits
757
758 /*
759 double dE_padd = 0.2/5.2E5 * 40000;
760 double thold = 0.2/5.2E5 * 115;
761 if (tof_hit->has_fADC && (tof_hit->dE - dE_padd > thold)){
762 */
763
764 if (tof_hit->has_fADC){
765 switch(plane)
766 {
767 case 0:
768 if(end == 1){
769 //cout << "Down : " << bar << endl;
770 translate_side = 0;
771 pmtPline = hdvmf->GetTOFPolyLine(translate_side, bar);
772 pmtPline->SetFillColor(2);
773 }
774 else if(end == 0){
775 //cout << "Up : " << bar << endl;
776 translate_side = 2;
777 pmtPline = hdvmf->GetTOFPolyLine(translate_side, bar);
778 pmtPline->SetFillColor(2);
779 }
780 else{
781 cerr << "Out of range TOF end" << endl;
782 }
783 break;
784 case 1:
785 if(end == 0){
786 //cout << "North : " << bar << endl;
787 translate_side = 3;
788 pmtPline = hdvmf->GetTOFPolyLine(translate_side, bar);
789 pmtPline->SetFillColor(2);
790 }
791 else if(end == 1){
792 //cout << "South : " << bar << endl;
793 translate_side = 1;
794 pmtPline = hdvmf->GetTOFPolyLine(translate_side, bar);
795 pmtPline->SetFillColor(2);
796 }
797 else{
798 cerr << "Out of range TOF end" << endl;
799 }
800 break;
801 default:
802 cerr << "Out of range TOF plane" << endl;
803 exit(0);
804 } // close the switch plane loop
805 } // if for the fADC
806
807 // Draw the position from the events that do have tdc hits
808 // with the current status of the TOFHit object those hits appear with no match from the fADC
809 //Float_t hit_dist;
810
811 if (tof_hit->has_TDC){
812 switch(plane)
813 {
814 case 0:
815 if(end == 1){
816 if (hit_down[bar]<=0 || (t < hit_down[bar]) ){
817 hit_down[bar] = t;
818 }
819 }
820 else if(end == 0){
821 if (hit_up[bar]<=0 || (t < hit_up[bar]) ){
822 hit_up[bar] = t;
823 }
824 }
825 else{
826 cerr << "Out of range TOF end" << endl;
827 }
828 break;
829 case 1:
830 if(end == 0){
831 if (hit_north[bar]<=0 || (t < hit_north[bar]) ){
832 hit_north[bar] = t;
833 }
834 }
835 else if(end == 1){
836 if (hit_south[bar]<=0 || (t < hit_south[bar]) ){
837 hit_south[bar] = t;
838 }
839 }
840 else{
841 cerr << "Out of range TOF end" << endl;
842 }
843 break;
844 default:
845 cerr << "Out of range TOF plane" << endl;
846 exit(0);
847 }
848
849 } // close the switch if there is a TDC Hit
850
851 } // close the for TOFHit object
852
853 // Draw the TDC Points here
854
855 Float_t hit_dist;
856 Float_t distY_Horz = -126; // Horizontal plane start counting from the Bottom to Top
857 Float_t distX_Vert = -126; // Vertical plane start counting from the South to North
858 int tdc_hits = 0;
859
860 for(Int_t i_tdc = 1; i_tdc <= 44; i_tdc++){
861 if ( i_tdc == 20 || i_tdc == 21 || i_tdc == 24 || i_tdc == 25 ){
862 distY_Horz = distY_Horz + 1.5;
863 distX_Vert = distX_Vert + 1.5;
864 }
865 else{
866 distY_Horz = distY_Horz + 3.0;
867 distX_Vert = distX_Vert + 3.0;
868 }
869 if(hit_north[i_tdc] > 0 && hit_south[i_tdc] > 0){
870 hit_dist = (15.2*(Float_t(hit_south[i_tdc] - hit_north[i_tdc])/2));
871 TArc *tdc_cir = new TArc(hit_dist,distY_Horz,2);
872 tdc_cir->SetFillColor(kGreen);
873
874 graphics_tof_hits.push_back(tdc_cir);
875 tdc_hits++;
876 }
877 if(hit_up[i_tdc] > 0 && hit_down[i_tdc] > 0){
878 hit_dist = (15.2*(Float_t(hit_down[i_tdc] - hit_up[i_tdc])/2) );
879 TArc *tdc_cir = new TArc(distX_Vert,hit_dist,2);
880 tdc_cir->SetFillColor(kBlue);
881
882 graphics_tof_hits.push_back(tdc_cir);
883 tdc_hits++;
884 }
885 if ( i_tdc == 20 || i_tdc == 21 || i_tdc == 24 || i_tdc == 25 ){
886 distY_Horz = distY_Horz + 1.5;
887 distX_Vert = distX_Vert + 1.5;
888 }
889 else{
890 distY_Horz = distY_Horz + 3.0;
891 distX_Vert = distX_Vert + 3.0;
892 }
893 }
894
895 } // close the if check button for the TOF
896
897 // Start counter hits
898 for (unsigned int i=0;i<schits.size();i++){
899 DGraphicSet gset(6,kLine,2.0);
900 double r_start=7.7493;
901 double phi0=0.2094395*(schits[i]->sector-1); // span 12 deg in phi
902 double phi1=0.2094395*(schits[i]->sector);
903 TVector3 point1(r_start*cos(phi0),r_start*sin(phi0),38.75);
904 gset.points.push_back(point1); // upstream end of sctraight section of scint
905 TVector3 point2(r_start*cos(phi1),r_start*sin(phi1),38.75);
906 gset.points.push_back(point2);
907 TVector3 point3(r_start*cos(phi1),r_start*sin(phi1),78.215);
908 gset.points.push_back(point3); // downstream end of sctraight section of scint
909 TVector3 point4(r_start*cos(phi0),r_start*sin(phi0),78.215);
910 gset.points.push_back(point4);
911 TVector3 point5(r_start*cos(phi0),r_start*sin(phi0),38.75);
912 gset.points.push_back(point5);
913
914 /*
915 // ST dimensions
916 Double_t dtr = 1.74532925e-02; // Conversion factor from degrees to radians
917 Double_t st_straight = 39.465; // Distance of the straight section along scintillator path
918 Double_t st_arc_angle = 18.5; // Angle of the bend arc
919 Double_t st_arc_radius = 12.0; // Radius of the bend arc
920 Double_t st_to_beam = 7.74926; // Distance from beam to bottom side of scintillator paddle
921 Double_t st_len_cone = 16.056; // Length of the cone section along scintillator path
922 Double_t st_thickness = 0.3; // Thickness of the scintillator paddles
923 Double_t st_beam_to_arc_radius = 4.25; // Distance from the beam line to the arc radius
924
925 // Nose Arrays
926 Double_t tp_nose_z[5];
927 Double_t tp_nose_y[5];
928 Double_t bm_nose_z[5];
929 Double_t bm_nose_y[5];
930
931 // Offsets for Hall coordinates
932 Double_t z_center = 65.0; // Target Center (0,0,65)
933 Double_t us_end_pt = -26.25; // Distance of upstream end relative to target
934 Double_t ds_end_pt = 97.4; // Distance of downstream end relative
935
936 // Top start counter paddle straight section
937 TPolyLine *top_paddle_straight;
938 Double_t tp_straight_z[5] = {us_end_pt + z_center, us_end_pt + z_center, us_end_pt + st_straight + z_center, us_end_pt + st_straight + z_center, us_end_pt + z_center};
939 Double_t tp_straight_y[5] = {st_to_beam, st_to_beam + st_thickness, st_to_beam + st_thickness, st_to_beam, st_to_beam};
940 */
941 graphics.push_back(gset);
942 }
943
944 // CDC hits
945 if(hdvmf->GetCheckButton("cdc")){
946 vector<const DCDCTrackHit*> cdctrackhits;
947 loop->Get(cdctrackhits);
948
949 for(unsigned int i=0; i<cdctrackhits.size(); i++){
950 const DCDCWire *wire = cdctrackhits[i]->wire;
951
952 int color = (cdctrackhits[i]->tdrift>-20 && cdctrackhits[i]->tdrift<800) ? kCyan:kYellow;
953 DGraphicSet gset(color, kLine, 1.0);
954 DVector3 dpoint=wire->origin-(wire->L/2.0)*wire->udir;
955 TVector3 tpoint(dpoint.X(),dpoint.Y(),dpoint.Z());
956 gset.points.push_back(tpoint);
957 dpoint=wire->origin+(wire->L/2.0)*wire->udir;
958 tpoint.SetXYZ(dpoint.X(),dpoint.Y(),dpoint.Z());
959 gset.points.push_back(tpoint);
960 graphics.push_back(gset);
961
962 // Rings for drift times.
963 // NOTE: These are not perfect since they still have TOF in them
964 if(hdvmf->GetCheckButton("cdcdrift") && fabs(wire->stereo)<0.05){
965 double x = wire->origin.X();
966 double y = wire->origin.Y();
967 double dist1 = cdctrackhits[i]->dist;
968 TEllipse *e = new TEllipse(x, y, dist1, dist1);
969 e->SetLineColor(38);
970 e->SetFillStyle(0);
971 graphics_xyA.push_back(e);
972
973 double dist2 = dist1 - 4.0*55.0E-4; // what if our TOF was 4ns?
974 e = new TEllipse(x, y, dist2, dist2);
975 e->SetLineColor(38);
976 e->SetFillStyle(0);
977 graphics_xyA.push_back(e);
978 }
979 }
980 }
981
982 // FDC wire
983 if(hdvmf->GetCheckButton("fdcwire")){
984 vector<const DFDCHit*> fdchits;
985 loop->Get(fdchits);
986
987 for(unsigned int i=0; i<fdchits.size(); i++){
988 const DFDCHit *fdchit = fdchits[i];
989 if(fdchit->type!=0)continue;
990 const DFDCWire *wire =fdcwires[fdchit->gLayer-1][fdchit->element-1];
991 if(!wire){
992 _DBG_std::cerr<<"programs/Analysis/hdview2/MyProcessor.cc"<<
":"<<992<<" "
<<"Couldn't find wire for gLayer="<<fdchit->gLayer<<" and element="<<fdchit->element<<endl;
993 continue;
994 }
995
996 // Wire
997 int color = (fdchit->t>-50 && fdchit->t<2000) ? kCyan:kYellow;
998 DGraphicSet gset(color, kLine, 1.0);
999 DVector3 dpoint=wire->origin-(wire->L/2.0)*wire->udir;
1000 TVector3 tpoint(dpoint.X(),dpoint.Y(),dpoint.Z());
1001 gset.points.push_back(tpoint);
1002 dpoint=wire->origin+(wire->L/2.0)*wire->udir;
1003 tpoint.SetXYZ(dpoint.X(),dpoint.Y(),dpoint.Z());
1004 gset.points.push_back(tpoint);
1005 graphics.push_back(gset);
1006 }
1007 }
1008
1009 // FDC intersection hits
1010 if(hdvmf->GetCheckButton("fdcintersection")){
1011 vector<const DFDCIntersection*> fdcints;
1012 loop->Get(fdcints);
1013 DGraphicSet gsetp(46, kMarker, 0.5);
1014
1015 for(unsigned int i=0; i<fdcints.size(); i++){
1016 TVector3 tpos(fdcints[i]->pos.X(),fdcints[i]->pos.Y(),
1017 fdcints[i]->pos.Z());
1018 gsetp.points.push_back(tpos);
1019 }
1020 graphics.push_back(gsetp);
1021 }
1022
1023 // FDC psuedo hits
1024 if(hdvmf->GetCheckButton("fdcpseudo")){
1025 vector<const DFDCPseudo*> fdcpseudos;
1026 loop->Get(fdcpseudos);
1027 DGraphicSet gsetp(38, kMarker, 0.5);
1028
1029 for(unsigned int i=0; i<fdcpseudos.size(); i++){
1030 const DFDCWire *wire = fdcpseudos[i]->wire;
1031
1032 // Pseudo point
1033 TVector3 pos(fdcpseudos[i]->xy.X(),
1034 fdcpseudos[i]->xy.Y(), wire->origin.Z());
1035 gsetp.points.push_back(pos);
1036 }
1037 graphics.push_back(gsetp);
1038 }
1039
1040 // DMCThrown
1041 if(hdvmf->GetCheckButton("thrown")){
1042 vector<const DMCThrown*> mcthrown;
1043 loop->Get(mcthrown);
1044 for(unsigned int i=0; i<mcthrown.size(); i++){
1045 int color=14;
1046 double size=1.5;
1047 if(mcthrown[i]->charge()==0.0) color = kGreen;
1048 if(mcthrown[i]->charge() >0.0) color = kBlue;
1049 if(mcthrown[i]->charge() <0.0) color = kRed;
1050 switch(mcthrown[i]->type){
1051 case Gamma:
1052 case Positron:
1053 case Electron:
1054 size = 1.0;
1055 break;
1056 case Pi0:
1057 case PiPlus:
1058 case PiMinus:
1059 size = 2.0;
1060 break;
1061 case Neutron:
1062 case Proton:
1063 case AntiProton:
1064 size = 3.0;
1065 break;
1066 }
1067 AddKinematicDataTrack(mcthrown[i], color, size);
1068 }
1069 }
1070
1071 // CDC Truth points
1072 if(hdvmf->GetCheckButton("cdctruth")){
1073 vector<const DMCTrackHit*> mctrackhits;
1074 loop->Get(mctrackhits);
1075 DGraphicSet gset(12, kMarker, 0.5);
1076 for(unsigned int i=0; i<mctrackhits.size(); i++){
1077 const DMCTrackHit *hit = mctrackhits[i];
1078 if(hit->system != SYS_CDC)continue;
1079
1080 TVector3 pos(hit->r*cos(hit->phi), hit->r*sin(hit->phi), hit->z);
1081 gset.points.push_back(pos);
1082 }
1083 graphics.push_back(gset);
1084 }
1085
1086 // FDC Truth points
1087 if(hdvmf->GetCheckButton("fdctruth")){
1088 vector<const DMCTrackHit*> mctrackhits;
1089 loop->Get(mctrackhits);
1090 DGraphicSet gset(12, kMarker, 0.5);
1091 for(unsigned int i=0; i<mctrackhits.size(); i++){
1092 const DMCTrackHit *hit = mctrackhits[i];
1093 if(hit->system != SYS_FDC)continue;
1094
1095 TVector3 pos(hit->r*cos(hit->phi), hit->r*sin(hit->phi), hit->z);
1096 gset.points.push_back(pos);
1097 }
1098 graphics.push_back(gset);
1099 }
1100
1101 // Track Hits for Track Candidates and Candidate trajectory in Debuger Window
1102 for(unsigned int n=0; n<trCand.size(); n++){
1103 if (n>9)
1104 break;
1105 char str1[128];
1106 sprintf(str1,"Candidate%d",n+1);
1107
1108 if(hdvmf->GetCheckButton(str1)){
1109
1110 int color = n+1;
1111 if (color > 4)
1112 color++;
1113 if (color > 6)
1114 color++;
1115
1116 AddKinematicDataTrack(trCand[n], color, 1.5);
1117
1118 vector<const DCDCTrackHit*> cdctrackhits;
1119 trCand[n]->Get(cdctrackhits,"",1);
1120 for(unsigned int i=0; i<cdctrackhits.size(); i++){
1121 const DCDCWire *wire = cdctrackhits[i]->wire;
1122 DGraphicSet gset(color, kLine, 1.0);
1123 DVector3 dpoint=wire->origin-(wire->L/2.0)*wire->udir;
1124 TVector3 tpoint(dpoint.X(),dpoint.Y(),dpoint.Z());
1125 gset.points.push_back(tpoint);
1126 dpoint=wire->origin+(wire->L/2.0)*wire->udir;
1127 tpoint.SetXYZ(dpoint.X(),dpoint.Y(),dpoint.Z());
1128 gset.points.push_back(tpoint);
1129 graphics.push_back(gset);
1130
1131 } // end loop of cdc hits of track candidate
1132 vector<const DFDCPseudo*> fdcpseudos;
1133 trCand[n]->Get(fdcpseudos,"",1);
1134 DGraphicSet gsetp(color, kMarker, 0.5);
1135
1136 for(unsigned int i=0; i<fdcpseudos.size(); i++){
1137 const DFDCWire *wire = fdcpseudos[i]->wire;
1138
1139 // Pseudo point
1140 TVector3 pos(fdcpseudos[i]->xy.X(),
1141 fdcpseudos[i]->xy.Y(), wire->origin.Z());
1142 gsetp.points.push_back(pos);
1143 }
1144 graphics.push_back(gsetp);
1145
1146 }
1147 }
1148
1149 // Wire Based Track Hits and trajectory for Debuger Window
1150 for(unsigned int n=0; n<trWB.size(); n++){
1151 if (n>=MaxWireTracks21)
1152 break;
1153 char str1[128];
1154 sprintf(str1,"WireBased%d",n+1);
1155
1156 if(hdvmf->GetCheckButton(str1)){
1157
1158 int color = trWB[n]->candidateid;
1159 if (color > 4)
1160 color++;
1161 if (color > 6)
1162 color++;
1163
1164 AddKinematicDataTrack(trWB[n], color, 1.5);
1165
1166 vector<const DCDCTrackHit*> cdctrackhits;
1167 trWB[n]->Get(cdctrackhits,"",1);
1168 for(unsigned int i=0; i<cdctrackhits.size(); i++){
1169 const DCDCWire *wire = cdctrackhits[i]->wire;
1170 DGraphicSet gset(color, kLine, 1.0);
1171 DVector3 dpoint=wire->origin-(wire->L/2.0)*wire->udir;
1172 TVector3 tpoint(dpoint.X(),dpoint.Y(),dpoint.Z());
1173 gset.points.push_back(tpoint);
1174 dpoint=wire->origin+(wire->L/2.0)*wire->udir;
1175 tpoint.SetXYZ(dpoint.X(),dpoint.Y(),dpoint.Z());
1176 gset.points.push_back(tpoint);
1177 graphics.push_back(gset);
1178
1179 } // end loop of cdc hits of track candidate
1180 vector<const DFDCPseudo*> fdcpseudos;
1181 trWB[n]->Get(fdcpseudos,"",1);
1182 DGraphicSet gsetp(color, kMarker, 0.5);
1183
1184 for(unsigned int i=0; i<fdcpseudos.size(); i++){
1185 const DFDCWire *wire = fdcpseudos[i]->wire;
1186
1187 // Pseudo point
1188 TVector3 pos(fdcpseudos[i]->xy.X(),
1189 fdcpseudos[i]->xy.Y(), wire->origin.Z());
1190 gsetp.points.push_back(pos);
1191 }
1192 graphics.push_back(gsetp);
1193
1194 }
1195 }
1196
1197 // Time Based Track Hits and trajectory for Debuger Window
1198 for(unsigned int n=0; n<trTB.size(); n++){
1199 if (n>=MaxTimeTracks21)
1200 break;
1201 char str1[128];
1202 sprintf(str1,"TimeBased%d",n+1);
1203
1204 if(hdvmf->GetCheckButton(str1)){
1205
1206 int color = trTB[n]->candidateid;
1207 if (color > 4)
1208 color++;
1209 if (color > 6)
1210 color++;
1211
1212 AddKinematicDataTrack(trTB[n], color, 1.5);
1213
1214 vector<const DCDCTrackHit*> cdctrackhits;
1215 trTB[n]->Get(cdctrackhits,"",1);
1216 for(unsigned int i=0; i<cdctrackhits.size(); i++){
1217 const DCDCWire *wire = cdctrackhits[i]->wire;
1218 DGraphicSet gset(color, kLine, 1.0);
1219 DVector3 dpoint=wire->origin-(wire->L/2.0)*wire->udir;
1220 TVector3 tpoint(dpoint.X(),dpoint.Y(),dpoint.Z());
1221 gset.points.push_back(tpoint);
1222 dpoint=wire->origin+(wire->L/2.0)*wire->udir;
1223 tpoint.SetXYZ(dpoint.X(),dpoint.Y(),dpoint.Z());
1224 gset.points.push_back(tpoint);
1225 graphics.push_back(gset);
1226
1227 } // end loop of cdc hits of track candidate
1228 vector<const DFDCPseudo*> fdcpseudos;
1229 trTB[n]->Get(fdcpseudos,"",1);
1230 DGraphicSet gsetp(color, kMarker, 0.5);
1231
1232 for(unsigned int i=0; i<fdcpseudos.size(); i++){
1233 const DFDCWire *wire = fdcpseudos[i]->wire;
1234
1235 // Pseudo point
1236 TVector3 pos(fdcpseudos[i]->xy.X(),
1237 fdcpseudos[i]->xy.Y(), wire->origin.Z());
1238 gsetp.points.push_back(pos);
1239 }
1240 graphics.push_back(gsetp);
1241
1242 }
1243 }
1244
1245 // TOF reconstructed points
1246 if (hdvmf->GetCheckButton("tof")){
1247 vector<const DTOFPoint *>tofpoints;
1248 loop->Get(tofpoints);
1249 DGraphicSet gset(kRed, kMarker, 0.5);
1250 for(unsigned int i=0; i<tofpoints.size(); i++){
1251 const DTOFPoint *hit = tofpoints[i];
1252 TVector3 pos(hit->pos.x(),hit->pos.y(),hit->pos.z());
1253 gset.points.push_back(pos);
1254 }
1255 graphics.push_back(gset);
1256 }
1257
1258 // TOF Truth points
1259 if(hdvmf->GetCheckButton("toftruth")){
1260 vector<const DMCTrackHit*> mctrackhits;
1261 loop->Get(mctrackhits);
1262 DGraphicSet gset(kBlack, kMarker, 0.5);
1263 for(unsigned int i=0; i<mctrackhits.size(); i++){
1264 const DMCTrackHit *hit = mctrackhits[i];
1265 if(hit->system != SYS_TOF)continue;
1266
1267 TVector3 pos(hit->r*cos(hit->phi), hit->r*sin(hit->phi), hit->z);
1268 gset.points.push_back(pos);
1269 }
1270 graphics.push_back(gset);
1271 }
1272
1273 // BCAL Truth points
1274 if(hdvmf->GetCheckButton("bcaltruth")){
1275 vector<const DMCTrackHit*> mctrackhits;
1276 loop->Get(mctrackhits);
1277 DGraphicSet gset(kBlack, kMarker, 1.0);
1278 for(unsigned int i=0; i<mctrackhits.size(); i++){
1279 const DMCTrackHit *hit = mctrackhits[i];
1280 if(hit->system != SYS_BCAL)continue;
1281
1282 TVector3 pos(hit->r*cos(hit->phi), hit->r*sin(hit->phi), hit->z);
1283 gset.points.push_back(pos);
1284
1285 TMarker *m = new TMarker(pos.X(), pos.Y(), 2);
1286 graphics_xyA.push_back(m);
1287 }
1288 //graphics.push_back(gset);
1289 }
1290
1291 // FCAL Truth points
1292 if(hdvmf->GetCheckButton("fcaltruth")){
1293 vector<const DFCALGeometry*> fcalgeometries;
1294 vector<const DFCALHit*> mcfcalhits;
1295 loop->Get(fcalgeometries);
1296 loop->Get(mcfcalhits, "TRUTH");
1297 if(fcalgeometries.size()>0){
1298 const DFCALGeometry *fgeom = fcalgeometries[0];
1299
1300 DGraphicSet gset(kBlack, kMarker, 0.25);
1301 for(unsigned int i=0; i<mcfcalhits.size(); i++){
1302 const DFCALHit *hit = mcfcalhits[i];
1303
1304 DVector2 pos_face = fgeom->positionOnFace(hit->row, hit->column);
1305 TVector3 pos(pos_face.X(), pos_face.Y(), FCAL_Zmin);
1306 gset.points.push_back(pos);
1307
1308 TMarker *m = new TMarker(pos.X(), pos.Y(), 2);
1309 //m->SetColor(kGreen);
1310 //m->SetLineWidth(1);
1311 graphics_xyB.push_back(m);
1312
1313 TMarker *m1 = new TMarker(pos.Z(), pos.X(), 2);
1314 graphics_xz.push_back(m1);
1315 TMarker *m2 = new TMarker(pos.Z(), pos.Y(), 2);
1316 graphics_yz.push_back(m2);
1317 }
1318 //graphics.push_back(gset);
1319 }
1320 }
1321
1322 // BCAL reconstructed photons
1323 if(hdvmf->GetCheckButton("recon_photons_bcal")){
1324 vector<const DNeutralParticle*> neutrals;
1325 loop->Get(neutrals);
1326
1327 DGraphicSet gset(kYellow+2, kMarker, 1.25);
1328 gset.marker_style=21;
1329 for(unsigned int i=0; i<neutrals.size(); i++){
1330 auto locNeutralShower = neutrals[i]->dNeutralShower;
1331 DetectorSystem_t locDetectorSystem = locNeutralShower->dDetectorSystem;
1332 if(locDetectorSystem == SYS_BCAL){
1333 TVector3 pos( locNeutralShower->dSpacetimeVertex.X(),
1334 locNeutralShower->dSpacetimeVertex.Y(),
1335 locNeutralShower->dSpacetimeVertex.Z());
1336 gset.points.push_back(pos);
1337
1338 double dist2 = 2.0 + 5.0*locNeutralShower->dEnergy;
1339 TEllipse *e = new TEllipse(pos.X(), pos.Y(), dist2, dist2);
1340 e->SetLineColor(kGreen);
1341 e->SetFillStyle(0);
1342 e->SetLineWidth(2);
1343 graphics_xyA.push_back(e);
1344 }
1345 }
1346 //graphics.push_back(gset);
1347 }
1348
1349 // FCAL reconstructed photons
1350 if(hdvmf->GetCheckButton("recon_photons_fcal")){
1351 vector<const DNeutralParticle*> neutrals;
1352 loop->Get(neutrals);
1353 DGraphicSet gset(kOrange, kMarker, 1.25);
1354 gset.marker_style=2;
1355 for(unsigned int i=0; i<neutrals.size(); i++){
1356 auto locNeutralShower = neutrals[i]->dNeutralShower;
1357 DetectorSystem_t locDetectorSystem = locNeutralShower->dDetectorSystem;
1358 if(locDetectorSystem == SYS_FCAL){
1359
1360 TVector3 pos( locNeutralShower->dSpacetimeVertex.X(),
1361 locNeutralShower->dSpacetimeVertex.Y(),
1362 locNeutralShower->dSpacetimeVertex.Z());
1363 gset.points.push_back(pos);
1364
1365 double dist2 = 2.0 + 10.0*locNeutralShower->dEnergy;
1366 TEllipse *e = new TEllipse(pos.X(), pos.Y(), dist2, dist2);
1367 e->SetLineColor(kGreen);
1368 e->SetFillStyle(0);
1369 e->SetLineWidth(2);
1370 graphics_xyB.push_back(e);
1371
1372 TEllipse *e1 = new TEllipse(pos.Z(), pos.X(), dist2, dist2);
1373 e1->SetLineColor(kGreen);
1374 e1->SetFillStyle(0);
1375 e1->SetLineWidth(2);
1376 graphics_xz.push_back(e1);
1377 TEllipse *e2 = new TEllipse(pos.Z(), pos.Y(), dist2, dist2);
1378 e2->SetLineColor(kGreen);
1379 e2->SetFillStyle(0);
1380 e2->SetLineWidth(2);
1381 graphics_yz.push_back(e2);
1382
1383 }
1384 }
1385 //graphics.push_back(gset);
1386 }
1387
1388 // Reconstructed photons matched with tracks
1389 if(hdvmf->GetCheckButton("recon_photons_track_match")){
1390 vector<const DChargedTrack*> ctracks;
1391 loop->Get(ctracks);
1392 for(unsigned int i=0; i<ctracks.size(); i++){
1393 const DChargedTrack *locCTrack = ctracks[i];
1394 vector<const DNeutralShower*> locNeutralShowers;
1395 locCTrack->GetT(locNeutralShowers);
1396
1397 if (!locNeutralShowers.size()) continue;
1398 const DNeutralShower *locNeutralShower = locNeutralShowers[0];
1399
1400
1401 // Decide if this hit BCAL of FCAL based on z of position on calorimeter
1402 bool is_bcal = (locNeutralShower->dDetectorSystem == SYS_BCAL );
1403
1404 // Draw on all frames except FCAL frame
1405 DGraphicSet gset(kRed, kMarker, 1.25);
1406 gset.marker_style = is_bcal ? 22:3;
1407 TVector3 tpos( locNeutralShower->dSpacetimeVertex.X(),
1408 locNeutralShower->dSpacetimeVertex.Y(),
1409 locNeutralShower->dSpacetimeVertex.Z());
1410 gset.points.push_back(tpos);
1411 graphics.push_back(gset);
1412
1413 // For BCAL hits, don't draw them on FCAL pane
1414 if(is_bcal)continue;
1415
1416 // Draw on FCAL pane
1417 double dist2 = 2.0 + 2.0*locNeutralShower->dEnergy;
1418 TEllipse *e = new TEllipse(tpos.X(), tpos.Y(), dist2, dist2);
1419 e->SetLineColor(gset.color);
1420 e->SetFillStyle(0);
1421 e->SetLineWidth(1);
1422 TMarker *m = new TMarker(tpos.X(), tpos.Y(), gset.marker_style);
1423 m->SetMarkerColor(gset.color);
1424 m->SetMarkerSize(1.75);
1425 graphics_xyB.push_back(e);
1426 graphics_xyB.push_back(m);
1427 }
1428 }
1429
1430 // FCAL and BCAL thrown photon projections
1431 if(hdvmf->GetCheckButton("thrown_photons_fcal") || hdvmf->GetCheckButton("thrown_photons_bcal")){
1432 vector<const DMCThrown*> throwns;
1433 loop->Get(throwns);
1434 DGraphicSet gset(kSpring, kMarker, 1.25);
1435 for(unsigned int i=0; i<throwns.size(); i++){
1436 const DMCThrown *thrown = throwns[i];
1437 if(thrown->charge()!=0.0)continue;
1438
1439 // This may seem a little funny, but it saves swimming the reference trajectory
1440 // multiple times. The GetIntersectionWithCalorimeter() method will find the
1441 // intersection point of the photon with whichever calorimeter it actually hits
1442 // or if it doesn't hit either of them. Then, we decide to draw the marker based
1443 // on whether the flag is set to draw the calorimeter it hit or not.
1444 DVector3 pos;
1445 DetectorSystem_t who;
1446 GetIntersectionWithCalorimeter(thrown, pos, who);
1447
1448 if(who!=SYS_FCAL && who!=SYS_BCAL)continue;
1449 if(who==SYS_FCAL && !hdvmf->GetCheckButton("thrown_photons_fcal"))continue;
1450 if(who==SYS_BCAL && !hdvmf->GetCheckButton("thrown_photons_bcal"))continue;
1451 TVector3 tpos(pos.X(),pos.Y(),pos.Z());
1452 gset.points.push_back(tpos);
1453
1454 // Only draw on FCAL pane if photon hits FCAL
1455 if(who==SYS_BCAL)continue;
1456
1457 double dist2 = 2.0 + 2.0*thrown->energy();
1458 TEllipse *e = new TEllipse(pos.X(), pos.Y(), dist2, dist2);
1459 e->SetLineColor(kSpring);
1460 e->SetFillStyle(0);
1461 e->SetLineWidth(4);
1462 graphics_xyB.push_back(e);
1463 }
1464 graphics.push_back(gset);
1465 }
1466
1467 // FCAL and BCAL thrown charged particle projections
1468 if(hdvmf->GetCheckButton("thrown_charged_fcal") || hdvmf->GetCheckButton("thrown_charged_bcal")){
1469 vector<const DMCThrown*> throwns;
1470 loop->Get(throwns);
1471
1472 for(unsigned int i=0; i<throwns.size(); i++){
1473 const DMCThrown *thrown = throwns[i];
1474 if(thrown->charge()==0.0)continue;
1475
1476 // This may seem a little funny, but it saves swimming the reference trajectory
1477 // multiple times. The GetIntersectionWithCalorimeter() method will find the
1478 // intersection point of the photon with whichever calorimeter it actually hits
1479 // or if it doesn't hit either of them. Then, we decide to draw the marker based
1480 // on whether the flag is set to draw the calorimeter it hit or not.
1481 DVector3 pos;
1482 DetectorSystem_t who;
1483 GetIntersectionWithCalorimeter(thrown, pos, who);
1484
1485 if(who!=SYS_FCAL && who!=SYS_BCAL)continue;
1486 if(who==SYS_FCAL && !hdvmf->GetCheckButton("thrown_charged_fcal"))continue;
1487 if(who==SYS_BCAL && !hdvmf->GetCheckButton("thrown_charged_bcal"))continue;
1488
1489 DGraphicSet gset(thrown->charge()>0.0 ? kBlue:kRed, kMarker, 1.25);
1490 TVector3 tpos(pos.X(),pos.Y(),pos.Z());
1491 gset.points.push_back(tpos);
1492 graphics.push_back(gset);
1493
1494 //double dist2 = 6.0 + 2.0*thrown->momentum().Mag();
1495 double dist2 = DELTA_R_FCAL;
1496 TEllipse *e = new TEllipse(pos.X(), pos.Y(), dist2, dist2);
1497 e->SetLineColor(thrown->charge()>0.0 ? kBlue:kRed);
1498 e->SetFillStyle(0);
1499 e->SetLineWidth(4);
1500 graphics_xyB.push_back(e);
1501 }
1502 }
1503
1504 // FCAL and BCAL reconstructed charged particle projections
1505 if(hdvmf->GetCheckButton("recon_charged_bcal") || hdvmf->GetCheckButton("recon_charged_fcal")){
1506
1507 // Here we used the full time-based track list, even though it includes multiple
1508 // hypotheses for each candidate. This is because currently, the photon/track
1509 // matching code in PID/DPhoton_factory.cc uses the DTrackTimeBased objects and
1510 // the current purpose of drawing these is to see matching of reconstructed
1511 // charged tracks with calorimeter clusters.
1512 vector<const DTrackTimeBased*> tracks;
1513 loop->Get(tracks, hdvmf->GetFactoryTag("DTrackTimeBased"));
1514
1515 for(unsigned int i=0; i<tracks.size(); i++){
1516 const DTrackTimeBased *track = tracks[i];
1517
1518 // See notes for above sections
1519 DVector3 pos;
1520 DetectorSystem_t who;
1521 GetIntersectionWithCalorimeter(track, pos, who);
1522
1523 if(who!=SYS_FCAL && who!=SYS_BCAL)continue;
1524 if(who==SYS_FCAL && !hdvmf->GetCheckButton("recon_charged_fcal"))continue;
1525 if(who==SYS_BCAL && !hdvmf->GetCheckButton("recon_charged_bcal"))continue;
1526
1527 DGraphicSet gset(track->charge()>0.0 ? kBlue:kRed, kMarker, 1.25);
1528 TVector3 tpos(pos.X(),pos.Y(),pos.Z());
1529 gset.points.push_back(tpos);
1530 graphics.push_back(gset);
1531
1532 if(who==SYS_BCAL)continue; // Don't draw tracks hitting BCAL on FCAL pane
1533
1534 //double dist2 = 6.0 + 2.0*track->momentum().Mag();
1535 double dist2 = DELTA_R_FCAL;
1536 TEllipse *e = new TEllipse(pos.X(), pos.Y(), dist2, dist2);
1537 e->SetLineColor(track->charge()>0.0 ? kBlue:kRed);
1538 e->SetFillStyle(0);
1539 e->SetLineWidth(4);
1540 graphics_xyB.push_back(e);
1541 }
1542 }
1543
1544 // CCAL reconstructed clusters
1545 if(hdvmf->GetCheckButton("recon_photons_ccal")){
1546 vector<const DCCALShower*> clusters;
1547 loop->Get(clusters);
1548 for(auto cluster : clusters){
1549
1550 double E = cluster->E/1000.0; // divide by 1000 since energy does not seem to be calibrated to GeV at the moment. 2018-12-10 DL
1551 double dist2 = 1.0 + 0.5*E;
1552 DVector3 pos(cluster->x,cluster->y,cluster->z);
1553
1554 TEllipse *e = new TEllipse(pos.X(), pos.Y(), dist2, dist2);
1555 e->SetLineColor(kGreen);
1556 e->SetFillStyle(0);
1557 e->SetLineWidth(2);
1558 graphics_xyB.push_back(e);
1559
1560 TEllipse *e1 = new TEllipse(pos.Z(), pos.X(), dist2, dist2);
1561 e1->SetLineColor(kGreen);
1562 e1->SetFillStyle(0);
1563 e1->SetLineWidth(2);
1564
1565 graphics_xz.push_back(e1);
1566 TEllipse *e2 = new TEllipse(pos.Z(), pos.Y(), dist2, dist2);
1567 e2->SetLineColor(kGreen);
1568 e2->SetFillStyle(0);
1569 e2->SetLineWidth(2);
1570 graphics_yz.push_back(e2);
1571
1572 }
1573 //graphics.push_back(gset);
1574 }
1575
1576 // DMCTrajectoryPoints
1577 if(hdvmf->GetCheckButton("trajectories")){
1578 vector<const DMCTrajectoryPoint*> mctrajectorypoints;
1579 loop->Get(mctrajectorypoints);
1580 //sort(mctrajectorypoints.begin(), mctrajectorypoints.end(), DMCTrajectoryPoint_track_cmp);
1581
1582 poly_type drawtype = hdvmf->GetCheckButton("trajectories_lines") ? kLine:kMarker;
1583 double drawsize = hdvmf->GetCheckButton("trajectories_lines") ? 1.0:0.3;
1584 DGraphicSet gset(kBlack, drawtype, drawsize);
1585 //gset.marker_style = 7;
1586 TVector3 last_point;
1587 int last_track=-1;
1588 int last_part=-1;
1589 for(unsigned int i=0; i<mctrajectorypoints.size(); i++){
1590 const DMCTrajectoryPoint *pt = mctrajectorypoints[i];
1591
1592 switch(pt->part){
1593 case Gamma:
1594 if(!hdvmf->GetCheckButton("trajectories_photon"))continue;
1595 break;
1596 case Electron:
1597 if(!hdvmf->GetCheckButton("trajectories_electron"))continue;
1598 break;
1599 case Positron:
1600 if(!hdvmf->GetCheckButton("trajectories_positron"))continue;
1601 break;
1602 case Proton:
1603 if(!hdvmf->GetCheckButton("trajectories_proton"))continue;
1604 break;
1605 case Neutron:
1606 if(!hdvmf->GetCheckButton("trajectories_neutron"))continue;
1607 break;
1608 case PiPlus:
1609 if(!hdvmf->GetCheckButton("trajectories_piplus"))continue;
1610 break;
1611 case PiMinus:
1612 if(!hdvmf->GetCheckButton("trajectories_piminus"))continue;
1613 break;
1614 default:
1615 if(!hdvmf->GetCheckButton("trajectories_other"))continue;
1616 break;
1617 }
1618
1619 TVector3 v(pt->x, pt->y, pt->z);
1620
1621 if(i>0){
1622 //if((v-last_point).Mag() > 10.0){
1623 if(pt->track!=last_track || pt->part!=last_part){
1624 if(hdvmf->GetCheckButton("trajectories_colors")){
1625 switch(last_part){
1626 case Gamma:
1627 gset.color = kOrange;
1628 break;
1629 case Electron:
1630 case PiMinus:
1631 gset.color = kRed+2;
1632 break;
1633 case Positron:
1634 case Proton:
1635 case PiPlus:
1636 gset.color = kBlue+1;
1637 break;
1638 case Neutron:
1639 gset.color = kGreen+2;
1640 break;
1641 default:
1642 gset.color = kBlack;
1643 break;
1644 }
1645 }else{
1646 gset.color = kBlack;
1647 }
1648 graphics.push_back(gset);
1649 gset.points.clear();
1650 }
1651 }
1652
1653 gset.points.push_back(v);
1654 last_point = v;
1655 last_track = pt->track;
1656 last_part = pt->part;
1657 }
1658
1659 if(hdvmf->GetCheckButton("trajectories_colors")){
1660 switch(last_part){
1661 case Gamma:
1662 gset.color = kOrange;
1663 break;
1664 case Electron:
1665 case PiMinus:
1666 gset.color = kRed+2;
1667 break;
1668 case Positron:
1669 case Proton:
1670 case PiPlus:
1671 gset.color = kBlue+1;
1672 break;
1673 case Neutron:
1674 gset.color = kGreen+2;
1675 break;
1676 default:
1677 gset.color = kBlack;
1678 break;
1679 }
1680 }else{
1681 gset.color = kBlack;
1682 }
1683 graphics.push_back(gset);
1684 }
1685
1686 // DTrackCandidate
1687 if(hdvmf->GetCheckButton("candidates")){
1688 vector<const DTrackCandidate*> trackcandidates;
1689 loop->Get(trackcandidates, hdvmf->GetFactoryTag("DTrackCandidate"));
1690 for(unsigned int i=0; i<trackcandidates.size(); i++){
1691 int color=i+1;
1692 double size=2.0;
1693 //if(trackcandidates[i]->charge() >0.0) color += 100; // lighter shade
1694 //if(trackcandidates[i]->charge() <0.0) color += 150; // darker shade
1695 AddKinematicDataTrack(trackcandidates[i], color, size);
1696 }
1697 }
1698
1699 // DTrackWireBased
1700 if(hdvmf->GetCheckButton("wiretracks")){
1701 vector<const DTrackWireBased*> wiretracks;
1702 loop->Get(wiretracks, hdvmf->GetFactoryTag("DTrackWireBased"));
1703 for(unsigned int i=0; i<wiretracks.size(); i++){
1704 AddKinematicDataTrack(wiretracks[i], (wiretracks[i]->charge()>0.0 ? kBlue:kRed)+2, 1.25);
1705 }
1706 }
1707
1708 // DTrackTimeBased
1709 if(hdvmf->GetCheckButton("timetracks")){
1710 vector<const DTrackTimeBased*> timetracks;
1711 loop->Get(timetracks, hdvmf->GetFactoryTag("DTrackTimeBased"));
1712 for(unsigned int i=0; i<timetracks.size(); i++){
1713 AddKinematicDataTrack(timetracks[i], (timetracks[i]->charge()>0.0 ? kBlue:kRed)+0, 1.00);
1714 }
1715 }
1716
1717 // DChargedTrack
1718 if(hdvmf->GetCheckButton("chargedtracks")){
1719 vector<const DChargedTrack*> chargedtracks;
1720 loop->Get(chargedtracks, hdvmf->GetFactoryTag("DChargedTrack"));
1721 for(unsigned int i=0; i<chargedtracks.size(); i++){
1722 int color=kViolet-3;
1723 double size=1.25;
1724 if (chargedtracks[i]->Get_Charge() > 0) color=kMagenta;
1725
1726 if (chargedtracks[i]->Get_BestFOM()->mass() > 0.9) size=2.5;
1727 AddKinematicDataTrack(chargedtracks[i]->Get_BestFOM(),color,size);
1728 }
1729 }
1730
1731 // DNeutralParticles
1732 if(hdvmf->GetCheckButton("neutrals")){
1733 vector<const DNeutralParticle*> photons;
1734 loop->Get(photons, hdvmf->GetFactoryTag("DNeutralParticle"));
1735
1736 for(unsigned int i=0; i<photons.size(); i++){
1737 int color = kBlack;
1738 auto locNeutralShower = photons[i]->dNeutralShower;
1739 DetectorSystem_t locDetSys = locNeutralShower->dDetectorSystem;
1740 if(locDetSys==SYS_FCAL)color = kOrange;
1741 if(locDetSys==SYS_BCAL)color = kYellow+2;
1742 //if(locDetSys==DPhoton::kCharge)color = kRed;
1743 AddKinematicDataTrack(photons[i]->Get_BestFOM(), color, 1.00);
1744 }
1745 }
1746}
1747
1748void MyProcessor::UpdateBcalDisp(void)
1749{
1750 // This routine is run only once when the canvas is created.
1751 BCALHitCanvas = hdvmf->GetBcalDispFrame();
1752 BCALHitMatrixU = new TH2F("BCALHitMatrixU","BCAL Hits Upstream Energy;Sector number;Layer;Energy (MeV)", 48*4+2, -1.5, 192.5, 10, 0., 10.);
1753 BCALHitMatrixD = new TH2F("BCALHitMatrixD","BCAL Hits Downstream Energy;Sector number;Layer;Energy (MeV)",48*4+2, -1.5, 192.5, 10, 0., 10.);
1754 BCALParticles = new TH2F("BCALParticles","BCAL Particle Hits Type;Phi angle [deg];;Particle Momentum",(48*4+2)*4, -1.87, 361.87, 1, 0., 1.);
1755 BCALHitMatrixU->SetStats(0);
1756 BCALHitMatrixD->SetStats(0);
1757 BCALParticles->SetStats(0);
1758 Float_t size = 0.06;
1759 BCALHitMatrixU->GetXaxis()->SetTitleSize(size);
1760 BCALHitMatrixU->GetXaxis()->SetTitleOffset(0.8);
1761 BCALHitMatrixU->GetXaxis()->SetLabelSize(size);
1762 BCALHitMatrixU->GetYaxis()->SetTitleSize(size);
1763 BCALHitMatrixU->GetYaxis()->SetTitleOffset(0.4);
1764 BCALHitMatrixU->GetYaxis()->SetLabelSize(size);
1765 BCALHitMatrixU->GetZaxis()->SetTitleSize(size);
1766 BCALHitMatrixU->GetZaxis()->SetTitleOffset(0.4);
1767 BCALHitMatrixU->GetZaxis()->SetLabelSize(size);
1768 BCALHitMatrixD->GetXaxis()->SetTitleSize(size);
1769 BCALHitMatrixD->GetXaxis()->SetTitleOffset(0.8);
1770 BCALHitMatrixD->GetXaxis()->SetLabelSize(size);
1771 BCALHitMatrixD->GetYaxis()->SetTitleSize(size);
1772 BCALHitMatrixD->GetYaxis()->SetTitleOffset(0.4);
1773 BCALHitMatrixD->GetYaxis()->SetLabelSize(size);
1774 BCALHitMatrixD->GetZaxis()->SetTitleSize(size);
1775 BCALHitMatrixD->GetZaxis()->SetTitleOffset(0.4);
1776 BCALHitMatrixD->GetZaxis()->SetLabelSize(size);
1777 BCALParticles->GetXaxis()->SetTitleSize(size);
1778 BCALParticles->GetXaxis()->SetTitleOffset(0.8);
1779 BCALParticles->GetXaxis()->SetLabelSize(size);
1780 BCALParticles->GetYaxis()->SetTitleSize(size);
1781 BCALParticles->GetYaxis()->SetTitleOffset(0.4);
1782 BCALParticles->GetYaxis()->SetLabelSize(size);
1783 BCALParticles->GetZaxis()->SetTitleSize(size);
1784 BCALParticles->GetZaxis()->SetTitleOffset(0.4);
1785 BCALParticles->GetZaxis()->SetLabelSize(size);
1786
1787 if (BCALHitCanvas) {
1788 vector<const DBCALHit*> locBcalHits;
1789 loop->Get(locBcalHits);
1790 BCALHitMatrixU->Reset();
1791 BCALHitMatrixD->Reset();
1792 for (unsigned int k=0;k<locBcalHits.size();k++){
1793
1794 const DBCALHit* hit = locBcalHits[k];
1795 float idxY = (float)hit->layer-1;
1796 float idxX = (float) (hit->sector-1 + (hit->module-1)*4);
1797 if (hit->end == DBCALGeometry::kUpstream){
1798 if (hit->layer==1){
1799 BCALHitMatrixU->Fill(idxX,idxY,hit->E);
1800 } else if (hit->layer==2){
1801 BCALHitMatrixU->Fill(idxX,idxY,hit->E);
1802 BCALHitMatrixU->Fill(idxX,idxY+1.,hit->E);
1803 } else if (hit->layer==3){
1804 BCALHitMatrixU->Fill(idxX,idxY+1,hit->E);
1805 BCALHitMatrixU->Fill(idxX,idxY+2.,hit->E);
1806 BCALHitMatrixU->Fill(idxX,idxY+3.,hit->E);
1807 } else if (hit->layer==4){
1808 BCALHitMatrixU->Fill(idxX,idxY+3,hit->E);
1809 BCALHitMatrixU->Fill(idxX,idxY+4.,hit->E);
1810 BCALHitMatrixU->Fill(idxX,idxY+5.,hit->E);
1811 BCALHitMatrixU->Fill(idxX,idxY+6.,hit->E);
1812 }
1813 } else {
1814 if (hit->layer==1){
1815 BCALHitMatrixD->Fill(idxX,idxY,hit->E);
1816 } else if (hit->layer==2){
1817 BCALHitMatrixD->Fill(idxX,idxY,hit->E);
1818 BCALHitMatrixD->Fill(idxX,idxY+1.,hit->E);
1819 } else if (hit->layer==3){
1820 BCALHitMatrixD->Fill(idxX,idxY+1,hit->E);
1821 BCALHitMatrixD->Fill(idxX,idxY+2.,hit->E);
1822 BCALHitMatrixD->Fill(idxX,idxY+3.,hit->E);
1823 } else if (hit->layer==4){
1824 BCALHitMatrixD->Fill(idxX,idxY+3,hit->E);
1825 BCALHitMatrixD->Fill(idxX,idxY+4.,hit->E);
1826 BCALHitMatrixD->Fill(idxX,idxY+5.,hit->E);
1827 BCALHitMatrixD->Fill(idxX,idxY+6.,hit->E);
1828 }
1829 }
1830 }
1831
1832 LayerLegend = new TLegend(0.91,0.7,0.99,0.99);
1833 for (int layer=0; layer<4; layer++) {
1834 char name[255];
1835 sprintf(name,"PhiZLayer%i",layer+1);
1836 BCALPointZphiLayer[layer] = new TH2F(name,"BCAL Points vs Z position;Phi angle [deg];Z position (cm);Energy",48*4,0,360,48,-80,400);
1837 FormatHistogram(BCALPointZphiLayer[layer],layer+1);
1838 BCALPointZphiLayer[layer]->SetLineWidth(2);
1839 sprintf(name,"PhiTLayer%i",layer+1);
1840 BCALPointPhiTLayer[layer] = new TH2F(name,"BCAL Points vs time;Phi angle [deg];time (ns);Energy",48*4,0,360,50,-100,100);
1841 FormatHistogram(BCALPointPhiTLayer[layer],layer+1);
1842 BCALPointPhiTLayer[layer]->SetLineWidth(2);
1843
1844 sprintf(name,"layer %i",layer+1);
1845 LayerLegend->AddEntry(BCALPointZphiLayer[layer],name);
1846 }
1847
1848 vector<const DBCALIncidentParticle*> locBcalParticles;
1849 loop->Get(locBcalParticles);
1850 BCALParticles->Reset();
1851 BCALPLables.clear();
1852 for (unsigned int k=0;k<locBcalParticles.size();k++){
1853
1854 const DBCALIncidentParticle* part = locBcalParticles[k];
1855
1856 float p = TMath::Sqrt(part->px*part->px + part->py*part->py + part->pz*part->pz);
1857
1858 float phi=999;
1859 if (part->x!=0){
1860 phi = TMath::ATan(TMath::Abs(part->y/part->x));
1861 //cout<<phi<<" "<<part->y<<" / "<< part->x<<endl;
1862 if (part->y>0){
1863 if (part->x<0.){
1864 phi = 3.1415926 - phi;
1865 }
1866 } else {
1867 if (part->x<0){
1868 phi += 3.1415926;
1869 } else {
1870 phi = 3.1415926*2. - phi;
1871 }
1872 }
1873
1874 phi = phi*180./3.1415926;
1875 }
1876 BCALParticles->Fill(phi,0.5,p);
1877 char l[20];
1878 sprintf(l,"%d",part->ptype);
1879 TText *t = new TText(phi,1.01,l);
1880 t->SetTextSize(0.08);
1881 t->SetTextFont(72);
1882 t->SetTextAlign(21);
1883 BCALPLables.push_back(t);
1884 }
1885
1886
1887 BCALHitCanvas->Clear();
1888 BCALHitCanvas->Divide(1,3,0.001,0.001);
1889 BCALHitCanvas->cd(1);
1890 gPad(TVirtualPad::Pad())->SetRightMargin(0.2);
1891 BCALHitMatrixU->Draw("colz");
1892 BCALHitCanvas->cd(2);
1893 gPad(TVirtualPad::Pad())->SetRightMargin(0.2);
1894 BCALHitMatrixD->Draw("colz");
1895 BCALHitCanvas->cd(3);
1896 gPad(TVirtualPad::Pad())->SetRightMargin(0.2);
1897 // BCALParticles->Draw("colz");
1898 // for (unsigned int n=0;n<BCALPLables.size();n++){
1899 // BCALPLables[n]->Draw("same");
1900 // }
1901 BCALHitCanvas->Update();
1902 }
1903
1904}
1905//------------------------------------------------------------------
1906// UpdateTrackLabels
1907//------------------------------------------------------------------
1908void MyProcessor::UpdateTrackLabels(void)
1909{
1910 // Get the label pointers
1911 string name, tag;
1912 map<string, vector<TGLabel*> > &thrownlabs = hdvmf->GetThrownLabels();
1913 map<string, vector<TGLabel*> > &reconlabs = hdvmf->GetReconstructedLabels();
1914 hdvmf->GetReconFactory(name, tag);
1915
1916 // Get Thrown particles
1917 vector<const DMCThrown*> throwns;
1918 if(loop)loop->Get(throwns);
1919
1920 // Get the track info as DKinematicData objects
1921 vector<const DKinematicData*> trks;
1922 vector<const DKinematicData*> TrksCand;
1923 vector<const DTrackWireBased*> TrksWireBased;
1924 vector<const DTrackTimeBased*> TrksTimeBased;
1925 vector<const DTrackCandidate*> cand;
1926 if(loop)loop->Get(cand);
1927 for(unsigned int i=0; i<cand.size(); i++)TrksCand.push_back(cand[i]);
1928
1929 if(loop)loop->Get(TrksWireBased);
1930 if(loop)loop->Get(TrksTimeBased);
1931
1932 if(name=="DChargedTrack"){
1933 vector<const DChargedTrack*> chargedtracks;
1934 if(loop)loop->Get(chargedtracks, tag.c_str());
1935 for(unsigned int i=0; i<chargedtracks.size(); i++){
1936 trks.push_back(chargedtracks[i]->Get_BestFOM());
1937 }
1938 }
1939 if(name=="DTrackTimeBased"){
1940 vector<const DTrackTimeBased*> timetracks;
1941 if(loop)loop->Get(timetracks, tag.c_str());
1942 for(unsigned int i=0; i<timetracks.size(); i++)trks.push_back(timetracks[i]);
1943 }
1944 if(name=="DTrackWireBased"){
1945 vector<const DTrackWireBased*> wiretracks;
1946 if(loop)loop->Get(wiretracks, tag.c_str());
1947 for(unsigned int i=0; i<wiretracks.size(); i++)trks.push_back(wiretracks[i]);
1948 }
1949 if(name=="DTrackCandidate"){
1950 vector<const DTrackCandidate*> candidates;
1951 if(loop)loop->Get(candidates, tag.c_str());
1952 for(unsigned int i=0; i<candidates.size(); i++)trks.push_back(candidates[i]);
1953 }
1954 if(name=="DNeutralParticle"){
1955 vector<const DNeutralParticle*> photons;
1956 if(loop)loop->Get(photons, tag.c_str());
1957 for(unsigned int i=0; i<photons.size(); i++) {
1958 trks.push_back(photons[i]->Get_BestFOM());
1959 }
1960 }
1961
1962 // Clear all labels (i.e. draw ---- in them)
1963 map<string, vector<TGLabel*> >::iterator iter;
1964 for(iter=reconlabs.begin(); iter!=reconlabs.end(); iter++){
1965 vector<TGLabel*> &labs = iter->second;
1966 for(unsigned int i=1; i<labs.size(); i++){
1967 labs[i]->SetText("--------");
1968 }
1969 }
1970 for(iter=thrownlabs.begin(); iter!=thrownlabs.end(); iter++){
1971 vector<TGLabel*> &labs = iter->second;
1972 for(unsigned int i=1; i<labs.size(); i++){
1973 labs[i]->SetText("--------");
1974 }
1975 }
1976
1977 // Loop over thrown particles and fill in labels
1978 int ii=0;
1979 for(unsigned int i=0; i<throwns.size(); i++){
1980 const DMCThrown *trk = throwns[i];
1981 if(trk->type==0)continue;
1982 int row = thrownlabs["trk"].size()-(ii++)-1;
1983 if(row<1)break;
1984
1985 stringstream trkno, type, p, theta, phi, z;
1986 trkno<<setprecision(4)<<i+1;
1987 thrownlabs["trk"][row]->SetText(trkno.str().c_str());
1988
1989 thrownlabs["type"][row]->SetText(ParticleType((Particle_t)trk->type));
1990
1991 p<<setprecision(4)<<trk->momentum().Mag();
1992 thrownlabs["p"][row]->SetText(p.str().c_str());
1993
1994 theta<<setprecision(4)<<trk->momentum().Theta()*TMath::RadToDeg();
1995 thrownlabs["theta"][row]->SetText(theta.str().c_str());
1996
1997 double myphi = trk->momentum().Phi();
1998 if(myphi<0.0)myphi+=2.0*M_PI3.14159265358979323846;
1999 phi<<setprecision(4)<<myphi;
2000 thrownlabs["phi"][row]->SetText(phi.str().c_str());
2001
2002 z<<setprecision(4)<<trk->position().Z();
2003 thrownlabs["z"][row]->SetText(z.str().c_str());
2004 }
2005
2006 // Loop over tracks and fill in labels
2007 for(unsigned int i=0; i<trks.size(); i++){
2008 const DKinematicData *trk = trks[i];
2009 int row = reconlabs["trk"].size()-i-1;
2010 if(row<1)break;
2011
2012 stringstream trkno, type, p, theta, phi, z, chisq_per_dof, Ndof,cand;
2013 stringstream fom;
2014 trkno<<setprecision(4)<<i+1;
2015 reconlabs["trk"][row]->SetText(trkno.str().c_str());
2016
2017 double mass = trk->mass();
2018 if(fabs(mass-0.13957)<1.0E-4)type<<"pi";
2019 else if(fabs(mass-0.93827)<1.0E-4)type<<"proton";
2020 else if(fabs(mass-0.493677)<1.0E-4)type<<"K";
2021 else if(fabs(mass-0.000511)<1.0E-4)type<<"e";
2022 else if (fabs(mass)<1.e-4 && fabs(trk->charge())<1.e-4) type << "gamma";
2023 else type<<"q=";
2024 if (fabs(trk->charge())>1.e-4){
2025 type<<(trk->charge()>0 ? "+":"-");
2026 }
2027 reconlabs["type"][row]->SetText(type.str().c_str());
2028
2029 p<<setprecision(4)<<trk->momentum().Mag();
2030 reconlabs["p"][row]->SetText(p.str().c_str());
2031
2032 theta<<setprecision(4)<<trk->momentum().Theta()*TMath::RadToDeg();
2033 reconlabs["theta"][row]->SetText(theta.str().c_str());
2034
2035 phi<<setprecision(4)<<trk->momentum().Phi()*TMath::RadToDeg();
2036 reconlabs["phi"][row]->SetText(phi.str().c_str());
2037
2038 z<<setprecision(4)<<trk->position().Z();
2039 reconlabs["z"][row]->SetText(z.str().c_str());
2040
2041 // Get chisq and Ndof for DTrackTimeBased or DTrackWireBased objects
2042 const DTrackTimeBased *timetrack=dynamic_cast<const DTrackTimeBased*>(trk);
2043 const DTrackWireBased *track=dynamic_cast<const DTrackWireBased*>(trk);
2044
2045 const DTrackCandidate *candidate=dynamic_cast<const DTrackCandidate*>(trk);
2046 const DChargedTrackHypothesis *chargedtrack=dynamic_cast<const DChargedTrackHypothesis *>(trk);
2047
2048 if(timetrack){
2049 chisq_per_dof<<setprecision(4)<<timetrack->chisq/timetrack->Ndof;
2050 Ndof<<timetrack->Ndof;
2051 fom << timetrack->FOM;
2052 }else if(track){
2053 chisq_per_dof<<setprecision(4)<<track->chisq/track->Ndof;
2054 Ndof<<track->Ndof;
2055 fom << "N/A";
2056 }else if (candidate){
2057 chisq_per_dof<<setprecision(4)<<candidate->chisq/candidate->Ndof;
2058 Ndof<<candidate->Ndof;
2059 fom << "N/A";
2060 }
2061 else if (chargedtrack){
2062 auto locTrackTimeBased = chargedtrack->Get_TrackTimeBased();
2063 chisq_per_dof<<setprecision(4)<<locTrackTimeBased->chisq/locTrackTimeBased->Ndof;
2064 Ndof<<locTrackTimeBased->Ndof;
2065 fom << locTrackTimeBased->FOM;
2066 }
2067 else{
2068 chisq_per_dof << "--------";
2069 Ndof << "--------";
2070 fom << "--------";
2071 }
2072
2073 reconlabs["chisq/Ndof"][row]->SetText(chisq_per_dof.str().c_str());
2074 reconlabs["Ndof"][row]->SetText(Ndof.str().c_str());
2075 reconlabs["FOM"][row]->SetText(fom.str().c_str());
2076
2077 if (timetrack){
2078 cand << timetrack->candidateid;
2079 }
2080 else if (track){
2081 cand << track->candidateid;
2082 }
2083 else {
2084 cand << "--------";
2085 }
2086 reconlabs["cand"][row]->SetText(cand.str().c_str());
2087 }
2088
2089 // Have the pop-up window with the full particle list update it's labels
2090 if( fulllistmf ) fulllistmf->UpdateTrackLabels(throwns, trks);
2091 if( debugermf ) {
2092 debugermf->SetTrackCandidates(TrksCand);
2093 debugermf->SetTrackWireBased(TrksWireBased);
2094 debugermf->SetTrackTimeBased(TrksTimeBased);
2095 debugermf->UpdateTrackLabels();
2096 }
2097}
2098
2099//------------------------------------------------------------------
2100// AddKinematicDataTrack
2101//------------------------------------------------------------------
2102void MyProcessor::AddKinematicDataTrack(const DKinematicData* kd, int color, double size)
2103{
2104 // Create a reference trajectory with the given kinematic data and swim
2105 // it through the detector.
2106 DReferenceTrajectory rt(Bfield);
2107 rt.Rsqmax_interior = RMAX_INTERIOR*RMAX_INTERIOR;
2108 rt.Rsqmax_exterior = RMAX_EXTERIOR*RMAX_EXTERIOR;
2109
2110 if(MATERIAL_MAP_MODEL=="DRootGeom"){
2111 rt.SetDRootGeom(RootGeom);
2112 rt.SetDGeometry(NULL__null);
2113 }else if(MATERIAL_MAP_MODEL=="DGeometry"){
2114 rt.SetDRootGeom(NULL__null);
2115 rt.SetDGeometry(geom);
2116 }else if(MATERIAL_MAP_MODEL!="NONE"){
2117 _DBG_std::cerr<<"programs/Analysis/hdview2/MyProcessor.cc"<<
":"<<2117<<" "
<<"WARNING: Invalid value for TRKFIT:MATERIAL_MAP_MODEL (=\""<<MATERIAL_MAP_MODEL<<"\")"<<endl;
2118 }
2119
2120 rt.SetMass(kd->mass());
2121 rt.Swim(kd->position(), kd->momentum(), kd->charge());
2122
2123 // Create a new graphics set and fill it with all of the trajectory points
2124 DGraphicSet gset(color, kLine, size);
2125 DReferenceTrajectory::swim_step_t *step = rt.swim_steps;
2126 for(int i=0; i<rt.Nswim_steps; i++, step++){
2127 TVector3 tpoint(step->origin.X(),step->origin.Y(),step->origin.Z());
2128 gset.points.push_back(tpoint);
2129 }
2130
2131 // Push the graphics set onto the stack
2132 graphics.push_back(gset);
2133}
2134
2135//------------------------------------------------------------------
2136// GetIntersectionWithCalorimeter
2137//------------------------------------------------------------------
2138void MyProcessor::GetIntersectionWithCalorimeter(const DKinematicData* kd, DVector3 &pos, DetectorSystem_t &who)
2139{
2140 // Create a reference trajectory with the given kinematic data and swim
2141 // it through the detector.
2142 DReferenceTrajectory rt(Bfield);
2143 rt.Rsqmax_interior = RMAX_INTERIOR*RMAX_INTERIOR;
2144 rt.Rsqmax_exterior = RMAX_EXTERIOR*RMAX_EXTERIOR;
2145
2146 if(MATERIAL_MAP_MODEL=="DRootGeom"){
2147 rt.SetDRootGeom(RootGeom);
2148 rt.SetDGeometry(NULL__null);
2149 }else if(MATERIAL_MAP_MODEL=="DGeometry"){
2150 rt.SetDRootGeom(NULL__null);
2151 rt.SetDGeometry(geom);
2152 }else if(MATERIAL_MAP_MODEL!="NONE"){
2153 _DBG_std::cerr<<"programs/Analysis/hdview2/MyProcessor.cc"<<
":"<<2153<<" "
<<"WARNING: Invalid value for TRKFIT:MATERIAL_MAP_MODEL (=\""<<MATERIAL_MAP_MODEL<<"\")"<<endl;
2154 }
2155
2156 rt.SetMass(kd->mass());
2157 rt.Swim(kd->position(), kd->momentum(), kd->charge());
2158
2159 // Find intersection with FCAL
2160 DVector3 pos_fcal;
2161 double s_fcal = 1.0E6;
2162 DVector3 origin(0.0, 0.0, FCAL_Zmin);
2163 DVector3 norm(0.0, 0.0, -1.0);
2164 //rt.GetIntersectionWithPlane(origin, norm, pos_fcal, &s_fcal); // This gives different answer than below!
2165 DVector3 p_at_intersection;
2166 rt.GetIntersectionWithPlane(origin, norm, pos_fcal, p_at_intersection, &s_fcal, NULL__null, NULL__null, SYS_FCAL);
2167 if(pos_fcal.Perp()<FCAL_Rmin || pos_fcal.Perp()>FCAL_Rmax || !isfinite(pos_fcal.Z()))s_fcal = 1.0E6;
2168
2169 // Find intersection with BCAL
2170 DVector3 pos_bcal;
2171 double s_bcal = 1.0E6;
2172 rt.GetIntersectionWithRadius(BCAL_Rmin, pos_bcal, &s_bcal);
2173 if(pos_bcal.Z()<BCAL_Zmin || pos_bcal.Z()>(BCAL_Zmin+BCAL_Zlen) || !isfinite(pos_bcal.Z()))s_bcal = 1.0E6;
2174
2175 if(s_fcal>10000.0 && s_bcal>10000.0){
2176 // neither calorimeter hit
2177 who = SYS_NULL;
2178 pos.SetXYZ(0.0,0.0,0.0);
2179 }else if(s_fcal<s_bcal){
2180 // FCAL hit
2181 who = SYS_FCAL;
2182 pos = pos_fcal;
2183 }else{
2184 // BCAL hit
2185 who = SYS_BCAL;
2186 pos = pos_bcal;
2187 }
2188}
2189
2190//------------------------------------------------------------------
2191// GetFactoryNames
2192//------------------------------------------------------------------
2193void MyProcessor::GetFactoryNames(vector<string> &facnames)
2194{
2195 vector<JEventLoop*> loops = app->GetJEventLoops();
2196 if(loops.size()>0){
2197 vector<string> facnames;
2198 loops[0]->GetFactoryNames(facnames);
2199 }
2200}
2201
2202//------------------------------------------------------------------
2203// GetFactories
2204//------------------------------------------------------------------
2205void MyProcessor::GetFactories(vector<JFactory_base*> &factories)
2206{
2207 vector<JEventLoop*> loops = app->GetJEventLoops();
2208 if(loops.size()>0){
2209 factories = loops[0]->GetFactories();
2210 }
2211}
2212
2213//------------------------------------------------------------------
2214// GetNrows
2215//------------------------------------------------------------------
2216unsigned int MyProcessor::GetNrows(const string &factory, string tag)
2217{
2218 vector<JEventLoop*> loops = app->GetJEventLoops();
2219 if(loops.size()>0){
2220 // Here is something a little tricky. The GetFactory() method of JEventLoop
2221 // gets the factory of the specified data name and tag, but without trying
2222 // to substitute a user-specified tag (a'la -PDEFTAG:XXX=YYY) as is done
2223 // on normal Get() method calls. Therefore, we have to check for the default
2224 // tags ourselves and substitute it "by hand".
2225 if(tag==""){
2226 map<string,string> default_tags = loops[0]->GetDefaultTags();
2227 map<string, string>::const_iterator iter = default_tags.find(factory);
2228 if(iter!=default_tags.end())tag = iter->second.c_str();
2229 }
2230 JFactory_base *fac = loops[0]->GetFactory(factory, tag.c_str());
2231
2232 // Since calling GetNrows will cause the program to quit if there is
2233 // not a valid event, then first check that there is one before calling it
2234 if(loops[0]->GetJEvent().GetJEventSource() == NULL__null)return 0;
2235
2236 return fac==NULL__null ? 0:(unsigned int)fac->GetNrows();
2237 }
2238
2239 return 0;
2240}
2241
2242//------------------------------------------------------------------
2243// GetDReferenceTrajectory
2244//------------------------------------------------------------------
2245void MyProcessor::GetDReferenceTrajectory(string dataname, string tag, unsigned int index, DReferenceTrajectory* &rt, vector<const DCDCTrackHit*> &cdchits)
2246{
2247_DBG__std::cerr<<"programs/Analysis/hdview2/MyProcessor.cc"<<
":"<<2247<<std::endl
;
2248 // initialize rt to NULL in case we don't find the one requested
2249 rt = NULL__null;
2250 cdchits.clear();
2251
2252 // Get pointer to the JEventLoop so we can get at the data
2253 vector<JEventLoop*> loops = app->GetJEventLoops();
2254 if(loops.size()==0)return;
2255 JEventLoop* &loop = loops[0];
2256
2257 // Variables to hold track parameters
2258 DVector3 pos, mom(0,0,0);
2259 double q=0.0;
2260 double mass = 0.13957018;
2261
2262 // Find the specified track
2263 if(dataname=="DChargedTrack"){
2264 vector<const DChargedTrack*> chargedtracks;
2265 vector<const DTrackTimeBased*> timebasedtracks;
2266 loop->Get(chargedtracks, tag.c_str());
2267 if(index>=chargedtracks.size())return;
2268 q = chargedtracks[index]->Get_Charge();
2269 pos = chargedtracks[index]->Get_BestFOM()->position();
2270 mom = chargedtracks[index]->Get_BestFOM()->momentum();
2271 chargedtracks[index]->Get_BestFOM()->GetT(timebasedtracks);
2272 if(!timebasedtracks.empty()){
2273 timebasedtracks[0]->Get(cdchits);
2274 mass = chargedtracks[index]->Get_BestFOM()->mass();
2275 }
2276 }
2277
2278 if(dataname=="DTrackTimeBased"){
2279 vector<const DTrackTimeBased*> timetracks;
2280 loop->Get(timetracks, tag.c_str());
2281 if(index>=timetracks.size())return;
2282 q = timetracks[index]->charge();
2283 pos = timetracks[index]->position();
2284 mom = timetracks[index]->momentum();
2285 timetracks[index]->Get(cdchits);
2286 mass = timetracks[index]->mass();
2287 }
2288
2289 if(dataname=="DTrackWireBased"){
2290 vector<const DTrackWireBased*> wiretracks;
2291 loop->Get(wiretracks, tag.c_str());
2292 if(index>=wiretracks.size())return;
2293 q = wiretracks[index]->charge();
2294 pos = wiretracks[index]->position();
2295 mom = wiretracks[index]->momentum();
2296 wiretracks[index]->Get(cdchits);
2297 mass = wiretracks[index]->mass();
2298 }
2299
2300 if(dataname=="DTrackCandidate"){
2301 vector<const DTrackCandidate*> tracks;
2302 loop->Get(tracks, tag.c_str());
2303 if(index>=tracks.size())return;
2304 q = tracks[index]->charge();
2305 pos = tracks[index]->position();
2306 mom = tracks[index]->momentum();
2307 tracks[index]->Get(cdchits);
2308 mass = tracks[index]->mass();
2309 }
2310
2311 if(dataname=="DMCThrown"){
2312 vector<const DMCThrown*> tracks;
2313 loop->Get(tracks, tag.c_str());
2314 if(index>=tracks.size())return;
2315 const DMCThrown *t = tracks[index];
2316 q = t->charge();
2317 pos = t->position();
2318 mom = t->momentum();
2319 tracks[index]->Get(cdchits);
2320 mass = tracks[index]->mass();
2321_DBG_std::cerr<<"programs/Analysis/hdview2/MyProcessor.cc"<<
":"<<2321<<" "
<<"mass="<<mass<<endl;
2322 }
2323
2324 // Make sure we found a charged particle we can track
2325 if(q==0.0 || mom.Mag()<0.01)return;
2326
2327 // Create a new DReference trajectory object. The caller takes
2328 // ownership of this and so they are responsible for deleting it.
2329 rt = new DReferenceTrajectory(Bfield);
2330 rt->Rsqmax_interior = RMAX_INTERIOR*RMAX_INTERIOR;
2331 rt->Rsqmax_exterior = RMAX_EXTERIOR*RMAX_EXTERIOR;
2332 rt->SetMass(mass);
2333 if(MATERIAL_MAP_MODEL=="DRootGeom"){
2334 rt->SetDRootGeom(RootGeom);
2335 rt->SetDGeometry(NULL__null);
2336 }else if(MATERIAL_MAP_MODEL=="DGeometry"){
2337 rt->SetDRootGeom(NULL__null);
2338 rt->SetDGeometry(geom);
2339 }else if(MATERIAL_MAP_MODEL!="NONE"){
2340 _DBG_std::cerr<<"programs/Analysis/hdview2/MyProcessor.cc"<<
":"<<2340<<" "
<<"WARNING: Invalid value for TRKFIT:MATERIAL_MAP_MODEL (=\""<<MATERIAL_MAP_MODEL<<"\")"<<endl;
2341 }
2342 rt->Swim(pos, mom, q);
2343}
2344
2345//------------------------------------------------------------------
2346// GetAllWireHits
2347//------------------------------------------------------------------
2348void MyProcessor::GetAllWireHits(vector<pair<const DCoordinateSystem*,double> > &allhits)
2349{
2350 /// Argument is vector of pairs that contain a pointer to the
2351 /// DCoordinateSystem representing a wire and a double that
2352 /// represents the drift distance. To get info on the specific
2353 /// wire, one needs to attempt a dynamic_cast to both a DCDCWire
2354 /// and a DFDCWire and access the parameters of whichever one succeeds.
2355
2356 // Get pointer to the JEventLoop so we can get at the data
2357 vector<JEventLoop*> loops = app->GetJEventLoops();
2358 if(loops.size()==0)return;
1
Assuming the condition is false
2
Taking false branch
2359 JEventLoop* &loop = loops[0];
2360
2361 // Get CDC wire hits
2362 vector<const DCDCTrackHit*> cdchits;
2363 loop->Get(cdchits);
3
Calling 'JEventLoop::Get'
2364 for(unsigned int i=0; i<cdchits.size(); i++){
2365 pair<const DCoordinateSystem*,double> hit;
2366 hit.first = cdchits[i]->wire;
2367 hit.second = cdchits[i]->dist;
2368 allhits.push_back(hit);
2369 }
2370
2371 // Get FDC wire hits
2372 vector<const DFDCPseudo*> fdchits;
2373 loop->Get(fdchits);
2374 for(unsigned int i=0; i<fdchits.size(); i++){
2375 pair<const DCoordinateSystem*,double> hit;
2376 hit.first = fdchits[i]->wire;
2377 hit.second = 0.0055*fdchits[i]->time;
2378 allhits.push_back(hit);
2379 }
2380}
2381
2382
2383
2384//------------------------------------------------------------------
2385// FormatHistogram
2386//------------------------------------------------------------------
2387void MyProcessor::FormatHistogram(TH2* histo, int color=1)
2388{
2389 histo->SetStats(0);
2390 histo->SetLineColor(color);
2391 histo->SetMarkerColor(color);
2392 Float_t size = 0.06;
2393 histo->SetTitleSize(size);
2394 histo->GetXaxis()->SetTitleSize(size);
2395 histo->GetXaxis()->SetTitleOffset(0.8);
2396 histo->GetXaxis()->SetLabelSize(size);
2397 histo->GetYaxis()->SetTitleSize(size);
2398 histo->GetYaxis()->SetTitleOffset(0.5);
2399 histo->GetYaxis()->SetLabelSize(size);
2400 histo->GetZaxis()->SetTitleSize(size);
2401 histo->GetZaxis()->SetTitleOffset(0.4);
2402 histo->GetZaxis()->SetLabelSize(size);
2403}

/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
3.1
'tag' is not equal to NULL
3.1
'tag' is not equal to NULL
3.1
'tag' is not equal to NULL
==NULL__null ? "":tag; // protection against NULL tags
4
'?' condition is false
291 if(strlen(mytag)==0 && allow_deftag
4.1
'allow_deftag' is true
4.1
'allow_deftag' is true
4.1
'allow_deftag' is true
){
5
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();
6
Assuming the condition is true
7
Taking true branch
8
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);
9
Assuming field 'record_call_stack' is false
10
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);
11
Passing value via 2nd parameter 'tag'
12
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
13
Assuming 'tag' is equal to NULL
14
'?' condition is true
380 if(strlen(mytag)==0 && allow_deftag
14.1
'allow_deftag' is true
14.1
'allow_deftag' is true
14.1
'allow_deftag' is true
){
15
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();
16
Assuming the condition is false
17
Taking false branch
383 }
384
385 for(; iter!=factories.end(); iter++){
18
Calling 'operator!=<jana::JFactory_base **, std::vector<jana::JFactory_base *>>'
21
Returning from 'operator!=<jana::JFactory_base **, std::vector<jana::JFactory_base *>>'
22
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);
23
Taking true branch
396 if(factory == NULL__null)continue;
24
Assuming 'factory' is not equal to NULL
25
Taking false branch
397 const char *factag = factory->Tag()==NULL__null ? "":factory->Tag();
26
Assuming the condition is true
27
'?' condition is true
398 if(!strcmp(factag, tag)){
28
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(); }
19
Assuming the condition is true
20
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