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 hdv_mainframe.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/hdv_mainframe.cc

programs/Analysis/hdview2/hdv_mainframe.cc

1
2#include <iostream>
3#include <iomanip>
4#include <sstream>
5#include <cmath>
6#include <fstream>
7using namespace std;
8
9#include <unistd.h>
10#include <pthread.h>
11#include <sys/time.h>
12
13#include <TRACKING/DMCThrown.h>
14#include "hdv_mainframe.h"
15#include "hdview2.h"
16#include "MyProcessor.h"
17#include "FDC/DFDCGeometry.h"
18#include "FCAL/DFCALGeometry.h"
19#include "TOF/DTOFGeometry.h"
20#include "DVector2.h"
21#include "HDGEOMETRY/DGeometry.h"
22#include <PID/DNeutralParticle.h>
23#include <DAQ/DEPICSvalue.h>
24
25#include <TPolyMarker.h>
26#include <TLine.h>
27#include <TMarker.h>
28#include <TBox.h>
29#include <TVector3.h>
30#include <TGeoVolume.h>
31#include <TGeoManager.h>
32#include <TGLabel.h>
33#include <TGComboBox.h>
34#include <TGButton.h>
35#include <TGButtonGroup.h>
36#include <TGTextEntry.h>
37#include <TArrow.h>
38#include <TLatex.h>
39#include <TColor.h>
40#include <TMath.h>
41#include <TArc.h>
42
43extern JApplication *japp;
44//TGeoVolume *MOTHER = NULL;
45//TGeoCombiTrans *MotherRotTrans = NULL;
46
47extern int GO;
48extern bool SKIP_EPICS_EVENTS;
49
50// These values are just used to draw the detectors for visualization.
51// These should be replaced by a database lookup or something similar
52// at some point.
53static float BCAL_Rmin=65.0;
54static float BCAL_Rmax = 87.46;
55static float BCAL_MIDRAD = 77.0;
56static float BCAL_Zlen = 390.0;
57static float BCAL_Zmin = 212.0 - BCAL_Zlen/2.0;
58static float BCAL_MODS = 48;
59static float BCAL_LAYS1 = 3;
60//static float BCAL_LAYS2 = 4;
61static float BCAL_SECS1 = 4;
62static float BCAL_SECS2 = 4;
63static float BCAL_PHI_SHIFT = 0.0; // radians (will be overwritten in constructor!)
64static float FCAL_Zlen = 45.0;
65static float FCAL_Zmin = 622.8;
66static float FCAL_Rmin = 6.0;
67static float FCAL_Rmax = 212.0/2.0;
68static float CCAL_Zlen = 18.0;
69static float CCAL_Zmin = 876.106;
70static float CCAL_Rmin = 2.0;
71static float CCAL_Rmax = 24.0;
72static float CDC_Rmin = 9.0;
73static float CDC_Rmax = 59.0;
74static float CDC_Zlen = 150.0;
75static float CDC_Zmin = 17.0;
76static float TOF_Rmax = 125.0;
77static float TOF_Rmin = 6.0;
78static float TOF_Zlen = 2.54;
79static float TOF_Zmin = 618.8;
80static float FDC_Rmin = 3.5;
81static float FDC_Rmax = 48.5;
82static float TARGET_Zmid = 65.0;
83static float TARGET_Zlen = 30.0;
84
85static DFCALGeometry *fcalgeom = NULL__null;
86static DTOFGeometry *tofgeom = NULL__null;
87
88static vector<vector <DFDCWire *> >fdcwires;
89
90//-------------------
91// Constructor
92//-------------------
93hdv_mainframe::hdv_mainframe(const TGWindow *p, UInt_t w, UInt_t h):TGMainFrame(p,w,h)
94{
95 //Get pointer to DGeometry object
96 DApplication* dapp=dynamic_cast<DApplication*>(japp);
97 const DGeometry *dgeom = dapp->GetDGeometry(RUNNUMBER);
98
99 tofgeom = new DTOFGeometry(dgeom);
100 fcalgeom= new DFCALGeometry(dgeom);
101
102 dgeom->GetFDCWires(fdcwires);
103
104 // Get Target parameters from XML
105 double my_TARGET_Zmid = TARGET_Zmid;
106 double my_TARGET_Zlen = TARGET_Zlen;
107 dgeom->GetTargetZ(my_TARGET_Zmid);
108 dgeom->GetTargetLength(my_TARGET_Zlen);
109 TARGET_Zmid = my_TARGET_Zmid;
110 TARGET_Zlen = my_TARGET_Zlen;
111
112 // Get overall phi shift of BCAL
113 float my_BCAL_PHI_SHIFT;
114 dgeom->GetBCALPhiShift(my_BCAL_PHI_SHIFT);
115 BCAL_PHI_SHIFT = my_BCAL_PHI_SHIFT*TMath::DegToRad(); // convert to radians
116
117 UInt_t MainWidth = w;
118
119 // First, define all of the of the graphics objects. Below that, make all
120 // of the connections to the methods so these things will work!
121
122 // Use the "color wheel" rather than the classic palette.
123 //TColor::CreateColorWheel();
124
125 // The main GUI window is divided into three sections, top, middle, and bottom.
126 // Create those frames here.
127 TGLayoutHints *hints = new TGLayoutHints(kLHintsNormal|kLHintsExpandX|kLHintsExpandY|kLHintsLeft, 5,5,5,5);
128 TGLayoutHints *lhints = new TGLayoutHints(kLHintsNormal, 2,2,2,2);
129 TGLayoutHints *rhints = new TGLayoutHints(kLHintsCenterY|kLHintsRight, 2,2,2,2);
130 TGLayoutHints *chints = new TGLayoutHints(kLHintsCenterY|kLHintsCenterX, 2,2,2,2);
131 TGLayoutHints *bhints = new TGLayoutHints(kLHintsBottom|kLHintsCenterX, 2,2,2,2);
132 //TGLayoutHints *tofhints = new TGLayoutHints(kLHintsBottom|kLHintsCenterX, 2,2,2,2);
133 TGLayoutHints *xhints = new TGLayoutHints(kLHintsNormal|kLHintsExpandX, 2,2,2,2);
134 TGLayoutHints *yhints = new TGLayoutHints(kLHintsNormal|kLHintsExpandY, 2,2,2,2);
135 TGLayoutHints *dhints = new TGLayoutHints(kLHintsLeft|kLHintsCenterY, 0,0,0,0);
136 TGLayoutHints *ehints = new TGLayoutHints(kLHintsNormal, 2,2,0,0);
137 TGLayoutHints *thints = new TGLayoutHints(kLHintsTop|kLHintsCenterX, 2,2,0,0);
138 TGLayoutHints *lxhints = new TGLayoutHints(kLHintsLeft|kLHintsExpandX, 2,2,0,0);
139 TGHorizontalFrame *sourceframe = new TGHorizontalFrame(this,w,20);
140 TGHorizontalFrame *topframe = new TGHorizontalFrame(this, w, 200);
141 // TGHorizontalFrame *midframe = new TGHorizontalFrame(this, w, 200);
142 TGCompositeFrame *midframe = new TGCompositeFrame(this, w, 200, kHorizontalFrame);
143 TGHorizontalFrame *botframe = new TGHorizontalFrame(this, w, 200);
144 AddFrame(sourceframe, lxhints);
145 AddFrame(topframe, lhints);
146 AddFrame(midframe, lhints);
147 AddFrame(botframe, lhints);
148
149 //========== Source ===========
150 TGLabel *sourcelab = new TGLabel(sourceframe, "Source:");
151 sourceframe->AddFrame(sourcelab,ehints);
152 source = new TGLabel(sourceframe, "--");
153 sourceframe->AddFrame(source, lxhints);
154 source->SetTextJustify(1);
155
156 //========== TOP FRAME ============
157 TGGroupFrame *viewcontrols = new TGGroupFrame(topframe, "View Controls", kHorizontalFrame);
158 TGGroupFrame *eventcontrols = new TGGroupFrame(topframe, "Event Controls", kHorizontalFrame);
159 TGGroupFrame *eventinfo = new TGGroupFrame(topframe, "Info", kHorizontalFrame);
160 TGGroupFrame *inspectors = new TGGroupFrame(topframe, "Inspectors", kVerticalFrame);
161 TGHorizontalFrame *programcontrols = new TGHorizontalFrame(topframe);
162 topframe->AddFrame(viewcontrols, lhints);
163 topframe->AddFrame(eventcontrols, hints);
164 topframe->AddFrame(eventinfo, yhints);
165 topframe->AddFrame(inspectors, yhints);
166 topframe->AddFrame(programcontrols, yhints);
167
168 //-------------Pan buttons
169 TGVerticalFrame *panneg = new TGVerticalFrame(viewcontrols);
170 TGVerticalFrame *panpos = new TGVerticalFrame(viewcontrols);
171 viewcontrols->AddFrame(panneg, hints);
172 viewcontrols->AddFrame(panpos, hints);
173 TGTextButton *panxneg = new TGTextButton(panneg, "-X");
174 TGTextButton *panyneg = new TGTextButton(panneg, "-Y");
175 TGTextButton *panzneg = new TGTextButton(panneg, "-Z");
176 panneg->AddFrame(panxneg, dhints);
177 panneg->AddFrame(panyneg, dhints);
178 panneg->AddFrame(panzneg, dhints);
179
180 TGTextButton *panxpos = new TGTextButton(panpos, "X+");
181 TGTextButton *panypos = new TGTextButton(panpos, "Y+");
182 TGTextButton *panzpos = new TGTextButton(panpos, "Z+");
183 panpos->AddFrame(panxpos, dhints);
184 panpos->AddFrame(panypos, dhints);
185 panpos->AddFrame(panzpos, dhints);
186
187 panxneg->Connect("Clicked()","hdv_mainframe",this,"DoPanXneg()");
188 panyneg->Connect("Clicked()","hdv_mainframe",this,"DoPanYneg()");
189 panzneg->Connect("Clicked()","hdv_mainframe",this,"DoPanZneg()");
190 panxpos->Connect("Clicked()","hdv_mainframe",this,"DoPanXpos()");
191 panypos->Connect("Clicked()","hdv_mainframe",this,"DoPanYpos()");
192 panzpos->Connect("Clicked()","hdv_mainframe",this,"DoPanZpos()");
193 //------------- Zoom/Reset buttons
194 TGVerticalFrame *zoom = new TGVerticalFrame(viewcontrols);
195 viewcontrols->AddFrame(zoom, lhints);
196 TGGroupFrame *zoomframe = new TGGroupFrame(zoom, "ZOOM", kHorizontalFrame);
197 zoom->AddFrame(zoomframe, thints);
198 TGTextButton *zoomout = new TGTextButton(zoomframe, " - ");
199 TGTextButton *zoomin = new TGTextButton(zoomframe, " + ");
200 zoomframe->AddFrame(zoomout, thints);
201 zoomframe->AddFrame(zoomin, thints);
202 TGTextButton *reset = new TGTextButton(zoom, "Reset");
203 zoom->AddFrame(reset, chints);
204
205 //-------------- Transverse Coordinates
206 TGVButtonGroup *coordinates = new TGVButtonGroup(viewcontrols,"Transverse Coordinates");
207 viewcontrols->AddFrame(coordinates, lhints);
208 TGRadioButton *xy = new TGRadioButton(coordinates, "x/y");
209 new TGRadioButton(coordinates, "r/phi");
210
211 //-------------- Next, Previous
212 prev = new TGTextButton(eventcontrols, "<-- Prev");
213 next = new TGTextButton(eventcontrols, "Next -->");
214 TGVerticalFrame *contf = new TGVerticalFrame(eventcontrols);
215 eventcontrols->AddFrame(prev, chints);
216 eventcontrols->AddFrame(next, chints);
217 eventcontrols->AddFrame(contf, lhints);
218
219 // continuous, delay
220 checkbuttons["continuous"] = new TGCheckButton(contf, "continuous");
221 TGHorizontalFrame *delayf = new TGHorizontalFrame(contf);
222 contf->AddFrame(checkbuttons["continuous"], lhints);
223 contf->AddFrame(delayf, lhints);
224 TGLabel *delaylab = new TGLabel(delayf, "delay:");
225 delay = new TGComboBox(delayf, "0.25");
226 delay->Resize(50,20);
227 float delays[]={0, 0.25, 0.5, 1, 2, 3, 5, 10};
228 for(int i=0; i<8; i++){
229 stringstream ss;
230 ss<<delays[i];
231 delay->AddEntry(ss.str().c_str(),i);
232 }
233 delayf->AddFrame(delaylab, lhints);
234 delayf->AddFrame(delay, lhints);
235
236 //----------------- Event Info
237 TGVerticalFrame *eventlabs = new TGVerticalFrame(eventinfo);
238 TGVerticalFrame *eventvals = new TGVerticalFrame(eventinfo);
239 eventinfo->AddFrame(eventlabs, lhints);
240 eventinfo->AddFrame(eventvals, lhints);
241
242 TGLabel *runlab = new TGLabel(eventlabs, "Run:");
243 TGLabel *eventlab = new TGLabel(eventlabs, "Event:");
244 TGLabel *triglab = new TGLabel(eventlabs, "GTP bits:");
245 run = new TGLabel(eventvals, "--------------");
246 event = new TGLabel(eventvals, "--------------");
247 trig = new TGLabel(eventvals, "--------------");
248 eventlabs->AddFrame(runlab, rhints);
249 eventlabs->AddFrame(eventlab,rhints);
250 eventlabs->AddFrame(triglab,rhints);
251 eventvals->AddFrame(run, lhints);
252 eventvals->AddFrame(event, lhints);
253 eventvals->AddFrame(trig, lhints);
254
255 //----------------- Inspectors
256 TGTextButton *trackinspector = new TGTextButton(inspectors, "Track Inspector");
257 //TGTextButton *tofinspector = new TGTextButton(inspectors, "TOF Inspector");
258 //TGTextButton *bcalinspector = new TGTextButton(inspectors, "BCAL Inspector");
259 //TGTextButton *fcalinspector = new TGTextButton(inspectors, "FCAL Inspector");
260 inspectors->AddFrame(trackinspector, xhints);
261 //inspectors->AddFrame(tofinspector, xhints);
262 //inspectors->AddFrame(bcalinspector, xhints);
263 //inspectors->AddFrame(fcalinspector, xhints);
264 //tofinspector->SetEnabled(kFALSE);
265 //bcalinspector->SetEnabled(kFALSE);
266 //fcalinspector->SetEnabled(kFALSE);
267
268 //-------------- Program Controls
269 TGTextButton *quit = new TGTextButton(programcontrols, "&Quit");
270 programcontrols->AddFrame(quit, new TGLayoutHints(kLHintsTop|kLHintsRight|kLHintsExpandX, 2,2,2,2));
271
272 //========== MID FRAME ============
273 TGHorizontalFrame *detectorframe = new TGHorizontalFrame(midframe);
274 midframe->AddFrame(detectorframe, hints);
275
276 //------ Detector Frame ------
277 TGVerticalFrame *sideviews = new TGVerticalFrame(detectorframe);
278 TGVerticalFrame *endviews = new TGVerticalFrame(detectorframe);
279 TGVerticalFrame *drawopts = new TGVerticalFrame(detectorframe);
280 TGVerticalFrame *caloColorCodes = new TGVerticalFrame(detectorframe);
281 detectorframe->AddFrame(sideviews, lhints);
282 detectorframe->AddFrame(endviews, lhints);
283 detectorframe->AddFrame(caloColorCodes, lhints);
284 detectorframe->AddFrame(drawopts, lhints);
285
286 // Side views
287 int width = MainWidth/6*2;
288 TGHorizontalFrame *sideviewAframe = new TGHorizontalFrame(sideviews);
289 TGHorizontalFrame *sideviewBframe = new TGHorizontalFrame(sideviews);
290 sideviews->AddFrame(sideviewAframe, lhints);
291 sideviews->AddFrame(sideviewBframe, lhints);
292 sideviewA = new TRootEmbeddedCanvas("sideviewA Canvas", sideviewAframe, width, width/2, kSunkenFrame, GetWhitePixel());
293 sideviewB = new TRootEmbeddedCanvas("sideviewB Canvas", sideviewBframe, width, width/2, kSunkenFrame, GetWhitePixel());
294 sideviewAframe->AddFrame(sideviewA, lhints);
295 sideviewBframe->AddFrame(sideviewB, lhints);
296 sideviewA->SetScrolling(TGCanvas::kCanvasScrollBoth);
297 sideviewB->SetScrolling(TGCanvas::kCanvasScrollBoth);
298 sideviewA->SetBackgroundColor(0xafeeee);
299 sideviewB->SetBackgroundColor(0xafeeee);
300
301 // End views
302 endviewA = new TRootEmbeddedCanvas("endviewA Canvas", endviews, width/2, width/2, kSunkenFrame, GetWhitePixel());
303 endviewB = new TRootEmbeddedCanvas("endviewB Canvas", endviews, width/2, width/2, kSunkenFrame, GetWhitePixel());
304 endviews->AddFrame(endviewA, lhints);
305 endviews->AddFrame(endviewB, lhints);
306 endviewA->SetScrolling(TGCanvas::kCanvasScrollBoth);
307 endviewB->SetScrolling(TGCanvas::kCanvasScrollBoth);
308 endviewA->GetCanvas()->SetFillColor(kGray+1);
309 endviewB->GetCanvas()->SetFillColor(kGray+1);
310
311 // Draw opts
312 TGGroupFrame *trkdrawopts = new TGGroupFrame(drawopts, "Track Draw Options", kVerticalFrame);
313 TGGroupFrame *hitdrawopts = new TGGroupFrame(drawopts, "Hit Draw Options", kVerticalFrame);
314 drawopts->AddFrame(trkdrawopts, lhints);
315 drawopts->AddFrame(hitdrawopts, lhints);
316
317 // Track
318 TGHorizontalFrame *candidatesf = new TGHorizontalFrame(trkdrawopts);
319 checkbuttons["candidates"] = new TGCheckButton(candidatesf, "DTrackCandidate:");
320 candidatesfactory = new TGComboBox(candidatesf, "<default>", 0);
321 candidatesfactory->Resize(80,20);
322 candidatesf->AddFrame(checkbuttons["candidates"], lhints);
323 for(int i=0; i<100; i++)candidatesfactory->AddEntry("a",i);
324 // For some reason, this is needed for ROOT >5.14 (??!!!) real entries are filled in later
325 candidatesf->AddFrame(candidatesfactory, lhints);
326 trkdrawopts->AddFrame(candidatesf, lhints);
327
328 TGHorizontalFrame *wiretracksf = new TGHorizontalFrame(trkdrawopts);
329 checkbuttons["wiretracks"] = new TGCheckButton(wiretracksf, "DTrackWireBased:");
330 wiretracksfactory = new TGComboBox(wiretracksf, "<default>", 0);
331 wiretracksfactory->Resize(80,20);
332 wiretracksf->AddFrame(checkbuttons["wiretracks"], lhints);
333 for(int i=0; i<100; i++)wiretracksfactory->AddEntry("a",i);
334 // For some reason, this is needed for ROOT >5.14 (??!!!) real entries are filled in later
335 wiretracksf->AddFrame(wiretracksfactory, lhints);
336 trkdrawopts->AddFrame(wiretracksf, lhints);
337
338 TGHorizontalFrame *timetracksf = new TGHorizontalFrame(trkdrawopts);
339 checkbuttons["timetracks"] = new TGCheckButton(timetracksf, "DTrackTimeBased:");
340 timetracksfactory = new TGComboBox(timetracksf, "<default>", 0);
341 timetracksfactory->Resize(80,20);
342 timetracksf->AddFrame(checkbuttons["timetracks"], lhints);
343 for(int i=0; i<100; i++)timetracksfactory->AddEntry("a",i);
344 // For some reason, this is needed for ROOT >5.14 (??!!!) real entries are filled in later
345 timetracksf->AddFrame(timetracksfactory, lhints);
346 trkdrawopts->AddFrame(timetracksf, lhints);
347 TGHorizontalFrame *chargedtracksf = new TGHorizontalFrame(trkdrawopts);
348 checkbuttons["chargedtracks"] = new TGCheckButton(chargedtracksf, "DChargedTrack:");
349 chargedtracksfactory = new TGComboBox(chargedtracksf, "<default>", 0);
350 chargedtracksfactory->Resize(80,20);
351 chargedtracksf->AddFrame(checkbuttons["chargedtracks"], lhints);
352 for(int i=0; i<100; i++)chargedtracksfactory->AddEntry("a",i);
353 // For some reason, this is needed for ROOT >5.14 (??!!!) real entries are filled in later
354 chargedtracksf->AddFrame(chargedtracksfactory, lhints);
355 trkdrawopts->AddFrame(chargedtracksf, lhints);
356
357 checkbuttons["neutrals"] = new TGCheckButton(trkdrawopts,"DNeutralParticle");
358 checkbuttons["thrown"] = new TGCheckButton(trkdrawopts,"DMCThrown");
359 checkbuttons["trajectories"] = new TGCheckButton(trkdrawopts, "DMCTrajectoryPoint");
360 trkdrawopts->AddFrame(checkbuttons["neutrals"], lhints);
361 trkdrawopts->AddFrame(checkbuttons["thrown"], lhints);
362 trkdrawopts->AddFrame(checkbuttons["trajectories"], lhints);
363
364 // Hit
365 checkbuttons["cdc"] = new TGCheckButton(hitdrawopts, "CDC");
366 checkbuttons["cdcdrift"] = new TGCheckButton(hitdrawopts, "CDC Drift Time");
367 checkbuttons["cdctruth"] = new TGCheckButton(hitdrawopts, "CDCTruth");
368 checkbuttons["fdcwire"] = new TGCheckButton(hitdrawopts, "FDC Wire");
369 checkbuttons["fdcpseudo"] = new TGCheckButton(hitdrawopts, "FDC Pseudo");
370 checkbuttons["fdctruth"] = new TGCheckButton(hitdrawopts, "FDCTruth");
371 checkbuttons["tof"] = new TGCheckButton(hitdrawopts, "TOF");
372 checkbuttons["toftruth"] = new TGCheckButton(hitdrawopts, "TOFTruth");
373 checkbuttons["fcal"] = new TGCheckButton(hitdrawopts, "FCAL");
374 checkbuttons["bcal"] = new TGCheckButton(hitdrawopts, "BCAL");
375 checkbuttons["ccal"] = new TGCheckButton(hitdrawopts, "CCAL");
376
377 hitdrawopts->AddFrame(checkbuttons["cdc"], lhints);
378 hitdrawopts->AddFrame(checkbuttons["cdcdrift"], lhints);
379 hitdrawopts->AddFrame(checkbuttons["cdctruth"], lhints);
380 hitdrawopts->AddFrame(checkbuttons["fdcwire"], lhints);
381 hitdrawopts->AddFrame(checkbuttons["fdcpseudo"], lhints);
382 hitdrawopts->AddFrame(checkbuttons["fdctruth"], lhints);
383 hitdrawopts->AddFrame(checkbuttons["tof"], lhints);
384 hitdrawopts->AddFrame(checkbuttons["toftruth"], lhints);
385 hitdrawopts->AddFrame(checkbuttons["fcal"], lhints);
386 hitdrawopts->AddFrame(checkbuttons["bcal"], lhints);
387 hitdrawopts->AddFrame(checkbuttons["ccal"], lhints);
388
389 TGTextButton *moreOptions = new TGTextButton(hitdrawopts, "More options");
390 hitdrawopts->AddFrame(moreOptions, lhints);
391
392 // Color codes
393 TGGroupFrame *bcalColorCodes = new TGGroupFrame(caloColorCodes, "BCAL colors", kVerticalFrame);
394 TGGroupFrame *fcalColorCodes = new TGGroupFrame(caloColorCodes, "FCAL colors", kVerticalFrame);
395 TGTextButton *debuger = new TGTextButton(caloColorCodes,"Debugger");
396 TGTextButton *bcaldisp = new TGTextButton(caloColorCodes,"BcalDisp");
397
398 caloColorCodes->AddFrame(bcalColorCodes, thints);
399 caloColorCodes->AddFrame(debuger,lhints);
400 caloColorCodes->AddFrame(bcaldisp,lhints);
401 caloColorCodes->AddFrame(fcalColorCodes, bhints);
402 bcalColorCodes->SetWidth(30);
403 fcalColorCodes->SetWidth(30);
404
405 // color lables BCAL
406 TGLabel* BCCLables[9];
407 unsigned int BCccodes[9] = {0x0000FF,0x7700FF,0xFF00FF,0xFF0077,0xFF0000,0xFF7700,0xFFFF00,0xFFFF77,0xFFFFFF};
408 for (int i=0;i<9;i++) {
409 double e = pow(10,((8-(double)i)/2.0));
410 char str1[128];
411 if (e >= 1000) {
412 sprintf(str1,"%7.2f GeV",e/1000.);
413 } else {
414 sprintf(str1,"%7.1f MeV",e);
415 }
416 BCCLables[i] = new TGLabel(bcalColorCodes, (const char*)str1);
417 //BCCLables[i]->SetTextColor(1);
418 BCCLables[i]->SetBackgroundColor(BCccodes[i]);
419 bcalColorCodes->AddFrame(BCCLables[i],lhints);
420 }
421 // color lables FCAL
422 TGLabel* FCCLables[9];
423 unsigned int FCccodes[9] = {0x0000FF,0x7700FF,0xFF00FF,0xFF0077,0xFF0000,0xFF7700,0xFFFF00,0xFFFF77,0xFFFFFF};
424 for (int i=0;i<9;i++) {
425 double e = pow(10,((8-(double)i)/2.0));
426 char str1[128];
427 if (e >= 1000) {
428 sprintf(str1,"%7.2f GeV",e/1000.);
429 } else {
430 sprintf(str1,"%7.1f MeV",e);
431 }
432 FCCLables[i] = new TGLabel(fcalColorCodes, (const char*)str1);
433 FCCLables[i]->SetBackgroundColor(FCccodes[i]);
434 fcalColorCodes->AddFrame(FCCLables[i],lhints);
435 }
436
437 //========== BOT FRAME ============
438 TGGroupFrame *trackinfo = new TGGroupFrame(botframe, "Track Info", kHorizontalFrame);
439 botframe->AddFrame(trackinfo, xhints);
440
441 //------ Track Info ------
442 throwninfo = new TGGroupFrame(trackinfo, "Thrown", kHorizontalFrame);
443 reconinfo = new TGGroupFrame(trackinfo, "Reconstructed", kHorizontalFrame);
444 trackinfo->AddFrame(throwninfo, lhints);
445 trackinfo->AddFrame(reconinfo, lhints);
446
447 // Column names
448 vector<string> colnames;
449 colnames.push_back("trk");
450 colnames.push_back("type");
451 colnames.push_back("p");
452 colnames.push_back("theta");
453 colnames.push_back("phi");
454 colnames.push_back("z");
455 colnames.push_back("chisq/Ndof");
456 colnames.push_back("Ndof");
457 colnames.push_back("FOM");
458 colnames.push_back("cand");
459
460 // Create a vertical frame for each column and insert the label as the first item
461 for(unsigned int i=0; i<colnames.size(); i++){
462 // create frames
463 TGVerticalFrame *tf = new TGVerticalFrame(throwninfo);
464 TGVerticalFrame *rf = new TGVerticalFrame(reconinfo);
465 throwninfo->AddFrame(tf, bhints);
466 reconinfo->AddFrame(rf, bhints);
467
468 // create column labels
469 string lab = colnames[i]+":";
470 TGLabel *tl = new TGLabel(tf, lab.c_str());
471 TGLabel *rl = new TGLabel(rf, lab.c_str());
472 if(i<6)tf->AddFrame(tl, chints);
473 rf->AddFrame(rl, chints);
474 vector<TGLabel*> tv;
475 vector<TGLabel*> rv;
476 tv.push_back(tl);
477 rv.push_back(rl);
478
479 // Add 8 labels to each column
480 // These have to be added in reverse order so we can pack them from
481 // the bottom. Otherwise, it doesn't draw correctly.
482 for(int j=0; j<14; j++){
483 stringstream ss;
484 ss<<(5-j);
485 if(i<6)tl = new TGLabel(tf, i==0 ? ss.str().c_str():"--------");
486 rl = new TGLabel(rf, i==0 ? ss.str().c_str():"--------");
487 if(i<6)tf->AddFrame(tl, bhints);
488 rf->AddFrame(rl, bhints);
489 tv.push_back(tl);
490 rv.push_back(rl);
491 }
492
493 // Record the label object pointers for later use
494 thrownlabs[colnames[i]] = tv;
495 reconlabs[colnames[i]] = rv;
496 }
497
498 // Reconstruction factory and full list button
499 TGVerticalFrame *vf = new TGVerticalFrame(reconinfo);
500 reconinfo->AddFrame(vf, yhints);
501 reconfactory = new TGComboBox(vf, "DTrackCandidate:", 0);
502 reconfactory->Resize(160,20);
503 for(int i=0; i<100; i++)reconfactory->AddEntry("a",i); // For some reason, this is needed for ROOT >5.14 (??!!!) real entries are filled in later
504 vf->AddFrame(reconfactory, thints);
505
506 TGTextButton *listall = new TGTextButton(vf, "Full List");
507 vf->AddFrame(listall, new TGLayoutHints(kLHintsBottom|kLHintsExpandX, 2,2,2,2));
508
509 // Pointers to optional daughter windows (these must be done before ReadPreferences in
510 // order for the options they implement to be filled into checkbuttons)
511 trkmf = NULL__null;
512 bcaldispmf = NULL__null;
513 optionsmf = new hdv_optionsframe(this, NULL__null, 100, 100);
514 debugermf = new hdv_debugerframe(this, NULL__null, 800, 800);
515 fulllistmf = new hdv_fulllistframe(this, NULL__null, 100, 100);
516 endviewAmf = new hdv_endviewAframe(this, NULL__null, 600, 600);
517 endviewBmf = new hdv_endviewBframe(this, NULL__null, 600, 600);
518
519 //&&&&&&&&&&&&&&&& Defaults
520 ReadPreferences();
521 xy->SetState(kButtonDown,kTRUE);
522 coordinatetype = COORD_XY;
523 r0 = 50.0;
524 phi0 = M_PI3.14159265358979323846;
525 x0 = 0.0;
526 y0 = 0.0;
527 z0 = 350.0;
528 zoom_factor = 1.0;
529
530 //&&&&&&&&&&&&&&&& Connections
531 zoomin->Connect("Clicked()","hdv_mainframe", this, "DoZoomIn()");
532 zoomout->Connect("Clicked()","hdv_mainframe", this, "DoZoomOut()");
533 reset->Connect("Clicked()","hdv_mainframe", this, "DoReset()");
534
535 coordinates->Connect("Clicked(Int_t)","hdv_mainframe", this, "DoSetCoordinates(Int_t)");
536 coordinates->Connect("Clicked(Int_t)","hdv_mainframe", this, "DoMyRedraw()");
537
538 quit->Connect("Clicked()","hdv_mainframe", this, "DoQuit()");
539 this->Connect("CloseWindow()", "hdv_mainframe", this, "DoQuit()");
540 this->DontCallClose();
541 next->Connect("Clicked()","hdv_mainframe", this, "DoNext()");
542 prev->Connect("Clicked()","hdv_mainframe", this, "DoPrev()");
543 checkbuttons["continuous"]->Connect("Clicked()","hdv_mainframe", this, "DoCont()");
544 delay->Connect("Selected(Int_t)","hdv_mainframe", this, "DoSetDelay(Int_t)");
545
546 trackinspector->Connect("Clicked()","hdv_mainframe", this, "DoOpenTrackInspector()");
547 moreOptions->Connect("Clicked()","hdv_mainframe", this, "DoOpenOptionsWindow()");
548 listall->Connect("Clicked()","hdv_mainframe", this, "DoOpenFullListWindow()");
549 debuger->Connect("Clicked()","hdv_mainframe", this, "DoOpenDebugerWindow()");
550 bcaldisp->Connect("Clicked()","hdv_mainframe", this, "DoBcalDispFrame()");
551 //tofinspector->Connect("Clicked()","hdv_mainframe", this, "DoOpenTOFInspector()");
552 //fcalinspector->Connect("Clicked()","hdv_mainframe", this, "DoOpenFCALInspector()");
553 //bcalinspector->Connect("Clicked()","hdv_mainframe", this, "DoOpenBCALInspector()");
554
555 checkbuttons["candidates"]->Connect("Clicked()","hdv_mainframe", this, "DoMyRedraw()");
556 checkbuttons["wiretracks"]->Connect("Clicked()","hdv_mainframe", this, "DoMyRedraw()");
557 checkbuttons["timetracks"]->Connect("Clicked()","hdv_mainframe", this, "DoMyRedraw()");
558 checkbuttons["chargedtracks"]->Connect("Clicked()","hdv_mainframe", this, "DoMyRedraw()");
559 checkbuttons["neutrals"]->Connect("Clicked()","hdv_mainframe", this, "DoMyRedraw()");
560 checkbuttons["thrown"]->Connect("Clicked()","hdv_mainframe", this, "DoMyRedraw()");
561
562 checkbuttons["cdc"]->Connect("Clicked()","hdv_mainframe", this, "DoMyRedraw()");
563 checkbuttons["cdcdrift"]->Connect("Clicked()","hdv_mainframe", this, "DoMyRedraw()");
564 checkbuttons["cdctruth"]->Connect("Clicked()","hdv_mainframe", this, "DoMyRedraw()");
565 checkbuttons["fdcwire"]->Connect("Clicked()","hdv_mainframe", this, "DoMyRedraw()");
566 checkbuttons["fdcpseudo"]->Connect("Clicked()","hdv_mainframe", this, "DoMyRedraw()");
567 checkbuttons["fdctruth"]->Connect("Clicked()","hdv_mainframe", this, "DoMyRedraw()");
568 checkbuttons["tof"]->Connect("Clicked()","hdv_mainframe", this, "DoMyRedraw()");
569 checkbuttons["toftruth"]->Connect("Clicked()","hdv_mainframe", this, "DoMyRedraw()");
570 checkbuttons["bcal"]->Connect("Clicked()","hdv_mainframe", this, "DoMyRedraw()");
571 checkbuttons["bcaltruth"]->Connect("Clicked()","hdv_mainframe", this, "DoMyRedraw()");
572 checkbuttons["fcal"]->Connect("Clicked()","hdv_mainframe", this, "DoMyRedraw()");
573 checkbuttons["fcaltruth"]->Connect("Clicked()","hdv_mainframe", this, "DoMyRedraw()");
574 checkbuttons["ccal"]->Connect("Clicked()","hdv_mainframe", this, "DoMyRedraw()");
575 checkbuttons["trajectories"]->Connect("Clicked()","hdv_mainframe", this, "DoMyRedraw()");
576
577 for (Int_t n=1;n<debugermf->GetNTrCand();n++){
578 char str1[128];
579 sprintf(str1,"Candidate%d",n);
580 checkbuttons[str1]->Connect("Clicked()","hdv_mainframe", this, "DoMyRedraw()");
581 }
582
583 for (Int_t n=1;n<debugermf->GetNTrWB();n++){
584 char str1[128];
585 sprintf(str1,"WireBased%d",n);
586 checkbuttons[str1]->Connect("Clicked()","hdv_mainframe", this, "DoMyRedraw()");
587 }
588
589 for (Int_t n=1;n<debugermf->GetNTrTB();n++){
590 char str1[128];
591 sprintf(str1,"TimeBased%d",n);
592 checkbuttons[str1]->Connect("Clicked()","hdv_mainframe", this, "DoMyRedraw()");
593 }
594
595 candidatesfactory->Connect("Selected(Int_t)","hdv_mainframe", this, "DoMyRedraw()");
596 wiretracksfactory->Connect("Selected(Int_t)","hdv_mainframe", this, "DoMyRedraw()");
597 timetracksfactory->Connect("Selected(Int_t)","hdv_mainframe", this, "DoMyRedraw()");
598 chargedtracksfactory->Connect("Selected(Int_t)","hdv_mainframe", this, "DoMyRedraw()");
599 reconfactory->Connect("Selected(Int_t)","hdv_mainframe", this, "DoUpdateTrackLabels()");
600
601 endviewA->GetCanvas()->Connect("Selected(TVirtualPad*, TObject*, Int_t)", "hdv_mainframe", this, "DoEndViewAEvent(TVirtualPad*, TObject*, Int_t)");
602 endviewB->GetCanvas()->Connect("Selected(TVirtualPad*, TObject*, Int_t)", "hdv_mainframe", this, "DoEndViewBEvent(TVirtualPad*, TObject*, Int_t)");
603
604 // Set up timer to call the DoTimer() method repeatedly
605 // so events can be automatically advanced.
606 timer = new TTimer();
607 timer->Connect("Timeout()", "hdv_mainframe", this, "DoTimer()");
608 sleep_time = 250;
609 timer->Start(sleep_time, kFALSE);
610
611 // Finish up and map the window
612 SetWindowName("Hall-D Event Viewer");
613 SetIconName("HDView");
614 MapSubwindows();
615 Resize(GetDefaultSize());
616 MapWindow();
617
618 // Call Resize method of some group frames to get them to shrink down to smallest size
619 viewcontrols->Resize();
620 eventinfo->Resize();
621 eventcontrols->Resize();
622 inspectors->Resize();
623}
624
625//-------------------
626// ReadPreferences
627//-------------------
628void hdv_mainframe::ReadPreferences(void)
629{
630 // Preferences file is "${HOME}/.hdview2"
631 const char *home = getenv("HOME");
632 if(!home)return;
633
634 // Try and open file
635 string fname = string(home) + "/.hdview2";
636 ifstream ifs(fname.c_str());
637 if(!ifs.is_open())return;
638 cout<<"Reading preferences from \""<<fname<<"\" ..."<<endl;
639
640 // Loop over lines
641 char line[1024];
642 while(!ifs.eof()){
643 ifs.getline(line, 1024);
644 if(strlen(line)==0)continue;
645 if(line[0] == '#')continue;
646 string str(line);
647
648 // Break line into tokens
649 vector<string> tokens;
650 string buf; // Have a buffer string
651 stringstream ss(str); // Insert the string into a stream
652 while (ss >> buf)tokens.push_back(buf);
653 if(tokens.size()<1)continue;
654
655 // Check first token to decide what to do
656 if(tokens[0] == "checkbutton"){
657 if(tokens.size()!=4)continue; // should be of form "checkbutton name = value" with white space on either side of the "="
658 map<string, TGCheckButton*>::iterator it = checkbuttons.find(tokens[1]);
659 if(it != checkbuttons.end()){
660 if(tokens[3] == "on")(it->second)->SetState(kButtonDown);
661 }
662 }
663
664 if(tokens[0] == "DTrackCandidate"){
665 if(tokens.size()!=3)continue; // should be of form "DTrackCandidate = tag" with white space on either side of the "="
666 default_candidate = tokens[2];
667 }
668
669 if(tokens[0] == "DTrackWireBased"){
670 if(tokens.size()!=3)continue; // should be of form "DTrackWireBased = tag" with white space on either side of the "="
671 default_track = tokens[2];
672 }
673
674 if(tokens[0] == "DTrackTimeBased"){
675 if(tokens.size()!=3)continue; // should be of form "DTrackTimeBased = tag" with white space on either side of the "="
676 default_track = tokens[2];
677 }
678
679 if(tokens[0] == "Reconstructed"){
680 if(tokens.size()!=3)continue; // should be of form "Reconstructed = Factory:tag" with white space on either side of the "="
681 default_reconstructed = tokens[2];
682 }
683
684 }
685
686 // close file
687 ifs.close();
688}
689
690//-------------------
691// SavePreferences
692//-------------------
693void hdv_mainframe::SavePreferences(void)
694{
695 // Preferences file is "${HOME}/.hdview2"
696 const char *home = getenv("HOME");
697 if(!home)return;
698
699 // Try deleting old file and creating new file
700 string fname = string(home) + "/.hdview2";
701 unlink(fname.c_str());
702 ofstream ofs(fname.c_str());
703 if(!ofs.is_open()){
704 cout<<"Unable to create preferences file \""<<fname<<"\"!"<<endl;
705 return;
706 }
707
708 // Write header
709 time_t t = time(NULL__null);
710 ofs<<"##### hdview2 preferences file ###"<<endl;
711 ofs<<"##### Auto-generated on "<<ctime(&t)<<endl;
712 ofs<<endl;
713
714 // Write all checkbuttons that are "on"
715 map<string, TGCheckButton*>::iterator iter;
716 for(iter=checkbuttons.begin(); iter!=checkbuttons.end(); iter++){
717 TGCheckButton *but = iter->second;
718 if(but->GetState() == kButtonDown){
719 ofs<<"checkbutton "<<(iter->first)<<" = on"<<endl;
720 }
721 }
722 ofs<<endl;
723
724 ofs<<"DTrackCandidate = "<<(candidatesfactory->GetTextEntry()->GetText())<<endl;
725 ofs<<"DTrackWireBased = "<<(wiretracksfactory->GetTextEntry()->GetText())<<endl;
726 ofs<<"DTrackTimeBased = "<<(timetracksfactory->GetTextEntry()->GetText())<<endl;
727 ofs<<"Reconstructed = "<<(reconfactory->GetTextEntry()->GetText())<<endl;
728
729 ofs<<endl;
730 ofs.close();
731 cout<<"Preferences written to \""<<fname<<"\""<<endl;
732}
733
734//-------------------
735// SetRange
736//-------------------
737void hdv_mainframe::SetRange(void)
738{
739 // The following is for the bug
740 //endviewA->GetCanvas()->Range(-1, -1, 1, 1);
741
742 // Set the ranges of all canvases based on
743 // the current units (x/y or r/phi) and the zoom,pan
744 // settings
745
746 if(coordinatetype==COORD_XY){
747 // define range in each direction in cm
748 double x_width = 350.0/zoom_factor;
749 double y_width = x_width;
750 double z_width = 2.70*x_width;
751 double xlo = x0 - x_width/2.0;
752 double xhi = x0 + x_width/2.0;
753 double ylo = y0 - y_width/2.0;
754 double yhi = y0 + y_width/2.0;
755 double zlo = z0 - z_width*0.40;
756 double zhi = z0 + z_width*0.60;
757
758 sideviewA->GetCanvas()->cd();
759 sideviewA->GetCanvas()->Range(zlo, xlo, zhi, xhi);
760 sideviewB->GetCanvas()->cd();
761 sideviewB->GetCanvas()->Range(zlo, ylo, zhi, yhi);
762
763 // Zoom in a little on the end views
764 double end_to_side_ratio=1.8;
765 xlo/=end_to_side_ratio;
766 xhi/=end_to_side_ratio;
767 ylo/=end_to_side_ratio;
768 yhi/=end_to_side_ratio;
769
770 endviewA->GetCanvas()->cd();
771 endviewA->GetCanvas()->Range(xlo, ylo, xhi, yhi);
772 endviewB->GetCanvas()->cd();
773 endviewB->GetCanvas()->Range(xlo*1.3, ylo*1.3, xhi*1.3, yhi*1.3);
774 //endviewB->GetCanvas()->Range(-158, -158, 158, 158);
775 endviewAmf->SetRange(xlo, ylo, xhi, yhi);
776 endviewBmf->SetRange(xlo*1.3, ylo*1.3, xhi*1.3, yhi*1.3);
777 //endviewBmf->SetRange(-158, -158, 158, 158);
778
779 }else{
780 // define range in each direction in cm, radians
781 double r_width = 400.0/zoom_factor;
782 //double phi_width = 2.0*M_PI/zoom_factor;
783 double z_width = 2.0*r_width/zoom_factor;
784 double rlo = r0 - r_width/2.0;
785 double rhi = r0 + r_width/2.0;
786 double zlo = z0 - z_width/2.0;
787 double zhi = z0 + z_width/2.0;
788 double philo = -0.2;
789 double phihi = 2.0*M_PI3.14159265358979323846+0.2;
790
791 sideviewA->GetCanvas()->cd();
792 sideviewA->GetCanvas()->Range(zlo, rlo, zhi, rhi);
793 sideviewB->GetCanvas()->cd();
794 sideviewB->GetCanvas()->Range(zlo, philo, zhi, phihi);
795
796 // Zoom in a little on the end views in A
797 endviewA->GetCanvas()->cd();
798 endviewA->GetCanvas()->Range(philo, rlo/2.5, phihi, rhi/2.5);
799 endviewB->GetCanvas()->cd();
800 endviewB->GetCanvas()->Range(philo, rlo/10.0, phihi, rhi/1.9);
801 endviewAmf->SetRange(philo, rlo/2.5, phihi, rhi/2.5);
802 endviewBmf->SetRange(philo, rlo/10.0, phihi, rhi/1.9);
803 }
804}
805
806//-------------------
807// DoQuit
808//-------------------
809void hdv_mainframe::DoQuit(void)
810{
811 SavePreferences();
812
813 japp->Quit();
814 japp->Fini();
815 delete japp;
816 japp = NULL__null;
817
818 // This is supposed to return from the Run() method in "main()"
819 // since we call SetReturnFromRun(true), but it doesn't seem to work.
820 gApplication->Terminate(0);
821}
822
823//-------------------
824// DoNext
825//-------------------
826void hdv_mainframe::DoNext(void)
827{
828 if(eventloop){
3
Assuming 'eventloop' is non-null
4
Taking true branch
829 if(SKIP_EPICS_EVENTS){
5
Assuming 'SKIP_EPICS_EVENTS' is true
6
Taking true branch
830 while(true){
7
Loop condition is true. Entering loop body
831 eventloop->OneEvent();
832 vector<const DEPICSvalue*> epicsvalues;
833 eventloop->Get(epicsvalues);
8
Calling 'JEventLoop::Get'
834 if(epicsvalues.empty()) break;
835 cout << "Skipping EPICS event " << eventloop->GetJEvent().GetEventNumber() << endl;
836 }
837 }else{
838 eventloop->OneEvent();
839 }
840 }
841}
842
843//-------------------
844// DoPrev
845//-------------------
846void hdv_mainframe::DoPrev(void)
847{
848 //eventloop->GotoEvent(current_eventnumber-1);
849 //eventloop->OneEvent();
850}
851
852//-------------------
853// DoStop
854//-------------------
855void hdv_mainframe::DoStop(void)
856{
857 GO = 0;
858}
859
860//-------------------
861// DoCont
862//-------------------
863void hdv_mainframe::DoCont(void)
864{
865 GO = 1;
866}
867
868//-------------------
869// DoTimer
870//-------------------
871void hdv_mainframe::DoTimer(void)
872{
873 /// This gets called periodically (value is set in constructor)
874 /// It is used to automatically call DoNext() periodically
875 /// so long as the global GO is set to 1.
876 if(GetCheckButton("continuous")){
1
Taking true branch
877 DoNext();
2
Calling 'hdv_mainframe::DoNext'
878 if(sleep_time != (long)timer->GetTime())timer->SetTime(sleep_time);
879 }else{
880 if(sleep_time == 0)timer->SetTime(10);
881 }
882}
883
884//-------------------
885// DoOpenTrackInspector
886//-------------------
887void hdv_mainframe::DoOpenTrackInspector(void)
888{
889 if(trkmf==NULL__null){
890 trkmf = new trk_mainframe(this, NULL__null, 100, 100);
891 if(trkmf){
892 next->Connect("Clicked()","trk_mainframe", trkmf, "DoNewEvent()");
893 prev->Connect("Clicked()","trk_mainframe", trkmf, "DoNewEvent()");
894 }
895 }else{
896 trkmf->RaiseWindow();
897 trkmf->RequestFocus();
898 }
899}
900
901//-------------------
902// DoOpenOptionsWindow
903//-------------------
904void hdv_mainframe::DoOpenOptionsWindow(void)
905{
906 if(optionsmf==NULL__null){
907 optionsmf = new hdv_optionsframe(this, NULL__null, 100, 100);
908 }else{
909 optionsmf->MapWindow();
910 optionsmf->RaiseWindow();
911 optionsmf->RequestFocus();
912 }
913}
914//-------------------
915// DoOpenDebugerWindow
916//-------------------
917void hdv_mainframe::DoOpenDebugerWindow(void)
918{
919 if(debugermf==NULL__null){
920 debugermf = new hdv_debugerframe(this, NULL__null, 100, 100);
921 }else{
922 debugermf->MapWindow();
923 debugermf->RaiseWindow();
924 debugermf->RequestFocus();
925 DoUpdateTrackLabels();
926 }
927}
928//-------------------
929// DoOpenDebugerWindow
930//-------------------
931void hdv_mainframe::DoBcalDispFrame(void)
932{
933 if(bcaldispmf==NULL__null){
934 bcaldispmf = new TCanvas("BCALHitCanvas", "BCAL Hit Distribution", 900, 900);
935 }
936
937 DoUpdateBcalDisp();
938}
939//-------------------
940// DoOpenDebugerWindow
941//-------------------
942void hdv_mainframe::DoUpdateBcalDisp(void)
943{
944 gMYPROC->UpdateBcalDisp();
945
946}
947///-------------------
948// DoOpenFullListWindow
949//-------------------
950void hdv_mainframe::DoOpenFullListWindow(void)
951{
952 if(fulllistmf==NULL__null){
953 fulllistmf = new hdv_fulllistframe(this, NULL__null, 100, 100);
954 }else{
955 fulllistmf->MapWindow();
956 fulllistmf->RaiseWindow();
957 fulllistmf->RequestFocus();
958 DoUpdateTrackLabels();
959 }
960}
961
962//-------------------
963// DoOpenTOFInspector
964//-------------------
965void hdv_mainframe::DoOpenTOFInspector(void)
966{
967
968}
969
970//-------------------
971// DoOpenFCALInspector
972//-------------------
973void hdv_mainframe::DoOpenFCALInspector(void)
974{
975
976}
977
978//-------------------
979// DoOpenBCALInspector
980//-------------------
981void hdv_mainframe::DoOpenBCALInspector(void)
982{
983
984}
985
986//-------------------
987// DoClearTrackInspectorPointer
988//-------------------
989void hdv_mainframe::DoClearTrackInspectorPointer(void)
990{
991 trkmf = NULL__null;
992}
993
994//-------------------
995// DoClearOptionsWindowPointer
996//-------------------
997void hdv_mainframe::DoClearOptionsWindowPointer(void)
998{
999 optionsmf = NULL__null;
1000}
1001
1002//-------------------
1003// DoClearTOFInspectorPointer
1004//-------------------
1005void hdv_mainframe::DoClearTOFInspectorPointer(void)
1006{
1007
1008}
1009
1010//-------------------
1011// DoClearFCALInspectorPointer
1012//-------------------
1013void hdv_mainframe::DoClearFCALInspectorPointer(void)
1014{
1015
1016}
1017
1018//-------------------
1019// DoClearBCALInspectorPointer
1020//-------------------
1021void hdv_mainframe::DoClearBCALInspectorPointer(void)
1022{
1023
1024}
1025
1026//-------------------
1027// DoEndViewAEvent
1028//-------------------
1029void hdv_mainframe::DoEndViewAEvent(TVirtualPad* pad, TObject* obj, Int_t event)
1030{
1031 // event is the mouse button pushed (1=left, 2=center, 3=right)
1032 // It seems we can't detect double clicks here.
1033 if(endviewAmf==NULL__null){
1034 endviewAmf = new hdv_endviewAframe(this, NULL__null, 100, 100);
1035 }else{
1036 endviewAmf->MapWindow();
1037 endviewAmf->RaiseWindow();
1038 endviewAmf->RequestFocus();
1039 DoMyRedraw();
1040 }
1041}
1042
1043
1044//-------------------
1045// DoEndViewBEvent
1046//-------------------
1047void hdv_mainframe::DoEndViewBEvent(TVirtualPad* pad, TObject* obj, Int_t event)
1048{
1049 // event is the mouse button pushed (1=left, 2=center, 3=right)
1050 // It seems we can't detect double clicks here.
1051 if(endviewBmf==NULL__null){
1052 endviewBmf = new hdv_endviewBframe(this, NULL__null, 100, 100);
1053 }else{
1054 endviewBmf->MapWindow();
1055 endviewBmf->RaiseWindow();
1056 endviewBmf->RequestFocus();
1057 DoMyRedraw();
1058 }
1059}
1060
1061//-------------------
1062// DoPanXpos
1063//-------------------
1064void hdv_mainframe::DoPanXpos(void)
1065{
1066 x0 += 50/zoom_factor;
1067 SetRange();
1068 DoMyRedraw();
1069}
1070
1071//-------------------
1072// DoPanXneg
1073//-------------------
1074void hdv_mainframe::DoPanXneg(void)
1075{
1076 x0 -= 50/zoom_factor;
1077 SetRange();
1078 DoMyRedraw();
1079}
1080
1081//-------------------
1082// DoPanYpos
1083//-------------------
1084void hdv_mainframe::DoPanYpos(void)
1085{
1086 y0 += 50/zoom_factor;
1087 SetRange();
1088 DoMyRedraw();
1089}
1090
1091//-------------------
1092// DoPanYneg
1093//-------------------
1094void hdv_mainframe::DoPanYneg(void)
1095{
1096 y0 -= 50/zoom_factor;
1097 SetRange();
1098 DoMyRedraw();
1099}
1100
1101//-------------------
1102// DoPanZpos
1103//-------------------
1104void hdv_mainframe::DoPanZpos(void)
1105{
1106 z0 += 50/zoom_factor;
1107 SetRange();
1108 DoMyRedraw();
1109}
1110
1111//-------------------
1112// DoPanZneg
1113//-------------------
1114void hdv_mainframe::DoPanZneg(void)
1115{
1116 z0 -= 50/zoom_factor;
1117 SetRange();
1118 DoMyRedraw();
1119}
1120
1121//-------------------
1122// DoZoomIn
1123//-------------------
1124void hdv_mainframe::DoZoomIn(void)
1125{
1126 zoom_factor*=1.25;
1127 SetRange();
1128 DoMyRedraw();
1129 //if(gMYPROC)gMYPROC->evnt(eventloop, current_eventnumber);
1130}
1131
1132//-------------------
1133// DoZoomOut
1134//-------------------
1135void hdv_mainframe::DoZoomOut(void)
1136{
1137 zoom_factor/=1.25;
1138 SetRange();
1139 DoMyRedraw();
1140 //if(gMYPROC)gMYPROC->evnt(eventloop, current_eventnumber);
1141}
1142
1143//-------------------
1144// DoReset
1145//-------------------
1146void hdv_mainframe::DoReset(void)
1147{
1148 x0 = 0.0;
1149 y0 = 0.0;
1150 z0 = 350.0;
1151 zoom_factor = 1.0;
1152 DoMyRedraw();
1153}
1154
1155
1156//-------------------
1157// DoMyRedraw
1158//-------------------
1159void hdv_mainframe::DoMyRedraw(void)
1160{
1161 // Make sure canvases have proper ranges
1162 SetRange();
1163
1164 // Delete any existing graphics objects
1165 for(unsigned int i=0; i<graphics_sideA.size(); i++)delete graphics_sideA[i];
1166 for(unsigned int i=0; i<graphics_sideB.size(); i++)delete graphics_sideB[i];
1167 for(unsigned int i=0; i<graphics_endA.size(); i++)delete graphics_endA[i];
1168 for(unsigned int i=0; i<graphics_endB.size(); i++)delete graphics_endB[i];
1169 graphics_sideA.clear();
1170 graphics_sideB.clear();
1171 graphics_endA.clear();
1172 graphics_endB.clear();
1173
1174
1175 // Draw detectors depending on coordinate system we're using
1176 if(coordinatetype == COORD_XY){
1177 DrawDetectorsXY(); // Draw Detectors
1178 }else{
1179 DrawDetectorsRPhi(); // Draw Detectors
1180 }
1181
1182 // Collect all hits for display
1183 gMYPROC->FillGraphics();
1184
1185 // put collected hits into appropriate views
1186 AddGraphicsSideA(gMYPROC->graphics_xz);
1187 AddGraphicsSideB(gMYPROC->graphics_yz);
1188 AddGraphicsEndB(gMYPROC->graphics_tof_hits);
1189
1190 // Draw detector hits and tracks for the correct coordinates in all views
1191 vector<MyProcessor::DGraphicSet>::iterator iter = gMYPROC->graphics.begin();
1192 for(; iter!=gMYPROC->graphics.end(); iter++){
1193
1194 if(iter->type==MyProcessor::kMarker){
1195 // Markers
1196 TPolyMarker *sA = new TPolyMarker();
1197 TPolyMarker *sB = new TPolyMarker();
1198 TPolyMarker *eA = new TPolyMarker();
1199 sA->SetMarkerColor(iter->color);
1200 sB->SetMarkerColor(iter->color);
1201 eA->SetMarkerColor(iter->color);
1202 sA->SetMarkerSize(iter->size);
1203 sB->SetMarkerSize(iter->size);
1204 eA->SetMarkerSize(iter->size);
1205 sA->SetMarkerStyle(iter->marker_style);
1206 sB->SetMarkerStyle(iter->marker_style);
1207 eA->SetMarkerStyle(iter->marker_style);
1208 FillPoly(sA, sB, eA, iter->points); // in hdv_mainframe.h
1209 }else{
1210 // Lines
1211 TPolyLine *sA = new TPolyLine();
1212 TPolyLine *sB = new TPolyLine();
1213 TPolyLine *eA = new TPolyLine();
1214 sA->SetLineColor(iter->color);
1215 sB->SetLineColor(iter->color);
1216 eA->SetLineColor(iter->color);
1217 sA->SetLineWidth((Width_t)iter->size);
1218 sB->SetLineWidth((Width_t)iter->size);
1219 eA->SetLineWidth((Width_t)iter->size);
1220 sA->SetFillStyle(0);
1221 sB->SetFillStyle(0);
1222 eA->SetFillStyle(0);
1223 FillPoly(sA, sB, eA, iter->points); // in hdv_mainframe.h
1224
1225 // Axial CDC wires will end up as having zero length in the end view
1226 // so we draw an additional marker in the end view for those cases.
1227 if(eA->GetN()==2){
1228 double *x = eA->GetX();
1229 double *y = eA->GetY();
1230 if(fabs(x[0]-x[1])<0.1 && fabs(y[0]==y[1])<0.1){
1231 TMarker *m = new TMarker(x[0], y[0], 8);
1232 m->SetMarkerColor(iter->color);
1233 m->SetMarkerSize(0.5);
1234 graphics_endA.push_back(m);
1235 }
1236 }
1237 }
1238 }
1239
1240 // Add in additional view-specific objects
1241 if(coordinatetype == COORD_XY){
1242 for(unsigned int i=0; i<gMYPROC->graphics_xyA.size(); i++){
1243 graphics_endA.push_back(gMYPROC->graphics_xyA[i]);
1244 }
1245 for(unsigned int i=0; i<gMYPROC->graphics_xyB.size(); i++){
1246 graphics_endB.push_back(gMYPROC->graphics_xyB[i]);
1247 }
1248 }
1249
1250 // Draw everything
1251 endviewA->GetCanvas()->cd(0);
1252 for(unsigned int i=0; i<graphics_endA.size(); i++){
1253 TPolyLine *l = dynamic_cast<TPolyLine*>(graphics_endA[i]);
1254 if(l && l->GetFillStyle()!=0){
1255 graphics_endA[i]->Draw("f");
1256 }else{
1257 graphics_endA[i]->Draw("");
1258 }
1259 }
1260 endviewA->GetCanvas()->Update();
1261 endviewAmf->DrawObjects(graphics_endA); // duplicate drawing of objects in big window
1262
1263 endviewB->GetCanvas()->cd(0);
1264 for(unsigned int i=0; i<graphics_endB.size(); i++)graphics_endB[i]->Draw("f");
1265 for(unsigned int i=0; i<graphics_endB.size(); i++)graphics_endB[i]->Draw();
1266 endviewB->GetCanvas()->Update();
1267 endviewBmf->DrawObjects(graphics_endB); // duplicate drawing of objects in big window
1268
1269 sideviewA->GetCanvas()->cd(0);
1270 for(unsigned int i=0; i<graphics_sideA.size(); i++)graphics_sideA[i]->Draw();
1271 sideviewA->GetCanvas()->Update();
1272 sideviewB->GetCanvas()->cd(0);
1273 for(unsigned int i=0; i<graphics_sideB.size(); i++)graphics_sideB[i]->Draw();
1274 sideviewB->GetCanvas()->Update();
1275
1276 // Update track labels
1277 DoUpdateTrackLabels();
1278}
1279
1280//-------------------
1281// DoSetDelay
1282//-------------------
1283void hdv_mainframe::DoSetDelay(Int_t id)
1284{
1285 stringstream ss;
1286 ss<<delay->GetSelectedEntry()->GetTitle();
1287 double seconds;
1288 ss>>seconds;
1289 sleep_time = (int)(1000.0*seconds);
1290 timer->SetTime(sleep_time);
1291}
1292
1293//-------------------
1294// DoSetCoordinates
1295//-------------------
1296void hdv_mainframe::DoSetCoordinates(Int_t id)
1297{
1298 coordinatetype = (coordsys_t)id;
1299}
1300
1301//-------------------
1302// DoUpdateTrackLabels
1303//-------------------
1304void hdv_mainframe::DoUpdateTrackLabels(void)
1305{
1306 gMYPROC->UpdateTrackLabels();
1307
1308 throwninfo->Resize();
1309 reconinfo->Resize();
1310}
1311
1312//-------------------
1313// DrawDetectorsXY
1314//-------------------
1315void hdv_mainframe::DrawDetectorsXY(void)
1316{
1317 //============== Side A
1318 {
1319 sideviewA->GetCanvas()->cd(0);
1320 sideviewA->GetCanvas()->Clear();
1321
1322
1323
1324 // ------ Target ------
1325 TBox *target = new TBox(TARGET_Zmid-TARGET_Zlen/2.0, -0.5, TARGET_Zmid+TARGET_Zlen/2.0, +0.5);
1326 target->SetFillColor(13);
1327 graphics_sideA.push_back(target);
1328
1329
1330 // ----- BCAL ------
1331 TBox *bcal1 = new TBox(BCAL_Zmin, BCAL_Rmin, BCAL_Zmin+BCAL_Zlen, BCAL_Rmax);
1332 TBox *bcal2 = new TBox(BCAL_Zmin, -BCAL_Rmin, BCAL_Zmin+BCAL_Zlen, -BCAL_Rmax);
1333 bcal1->SetFillColor(28);
1334 bcal2->SetFillColor(28);
1335 graphics_sideA.push_back(bcal1);
1336 graphics_sideA.push_back(bcal2);
1337
1338 // ----- CDC ------
1339 TBox *cdc1 = new TBox(CDC_Zmin, CDC_Rmin, CDC_Zmin + CDC_Zlen, CDC_Rmax);
1340 TBox *cdc2 = new TBox(CDC_Zmin, -CDC_Rmin, CDC_Zmin + CDC_Zlen, -CDC_Rmax);
1341 cdc1->SetFillColor(17);
1342 cdc2->SetFillColor(17);
1343 graphics_sideA.push_back(cdc1);
1344 graphics_sideA.push_back(cdc2);
1345
1346 // ----- FDC ------
1347 for(int i=0; i<4; i++){
1348 // Get FDC package positions from FDC library
1349 float zu = fdcwires[i*6][0]->origin.z();
1350 float zd = fdcwires[i*6+5][0]->origin.z();
1351 TBox *fdc1 = new TBox(zu, FDC_Rmin, zd, FDC_Rmax);
1352 TBox *fdc2 = new TBox(zu, -FDC_Rmin, zd, -FDC_Rmax);
1353 fdc1->SetFillColor(21);
1354 fdc2->SetFillColor(21);
1355 graphics_sideA.push_back(fdc1);
1356 graphics_sideA.push_back(fdc2);
1357 }
1358
1359 // ----- TOF ------
1360 TBox *tof1 = new TBox(TOF_Zmin, TOF_Rmin, TOF_Zmin+TOF_Zlen, TOF_Rmax);
1361 TBox *tof2 = new TBox(TOF_Zmin, -TOF_Rmin, TOF_Zmin+TOF_Zlen, -TOF_Rmax);
1362 tof1->SetFillColor(11);
1363 tof2->SetFillColor(11);
1364 graphics_sideA.push_back(tof1);
1365 graphics_sideA.push_back(tof2);
1366
1367 // ----- FCAL ------
1368 TBox *fcal1 = new TBox(FCAL_Zmin, FCAL_Rmin, FCAL_Zmin+FCAL_Zlen, FCAL_Rmax);
1369 TBox *fcal2 = new TBox(FCAL_Zmin, -FCAL_Rmin, FCAL_Zmin+FCAL_Zlen, -FCAL_Rmax);
1370 fcal1->SetFillColor(40);
1371 fcal2->SetFillColor(40);
1372 graphics_sideA.push_back(fcal1);
1373 graphics_sideA.push_back(fcal2);
1374
1375 // ----- CCAL ------
1376 TBox *ccal1 = new TBox(CCAL_Zmin, CCAL_Rmin, CCAL_Zmin+CCAL_Zlen, CCAL_Rmax);
1377 TBox *ccal2 = new TBox(CCAL_Zmin, -CCAL_Rmin, CCAL_Zmin+CCAL_Zlen, -CCAL_Rmax);
1378 ccal1->SetFillColor(42);
1379 ccal2->SetFillColor(42);
1380 graphics_sideA.push_back(ccal1);
1381 graphics_sideA.push_back(ccal2);
1382
1383 // ------ scale ------
1384 DrawScale(sideviewA->GetCanvas(), graphics_sideA);
1385 }
1386
1387 //============== Side B
1388 {
1389 sideviewB->GetCanvas()->cd(0);
1390 sideviewB->GetCanvas()->Clear();
1391
1392 // Side B is exactly the same as side A so just copy it
1393 for(unsigned int i=0; i<graphics_sideA.size(); i++){
1394 graphics_sideB.push_back(graphics_sideA[i]->Clone());
1395 }
1396 }
1397
1398 //============== End A
1399 {
1400 endviewB->GetCanvas()->cd(0);
1401 endviewB->GetCanvas()->Clear();
1402
1403 // ----- BCAL ------
1404 TEllipse *bcal1 = new TEllipse(0.0, 0.0, BCAL_Rmax, BCAL_Rmax);
1405 TEllipse *bcal2 = new TEllipse(0.0, 0.0, BCAL_Rmin, BCAL_Rmin);
1406 bcal1->SetFillColor(0);
1407 bcal2->SetFillColor(0);
1408 graphics_endA.push_back(bcal1);
1409 graphics_endA.push_back(bcal2);
1410
1411 double dlayer1 = 0.5*(BCAL_MIDRAD-BCAL_Rmin)/(double)BCAL_LAYS1;
1412 //double dlayer2 = (BCAL_Rmax-BCAL_MIDRAD)/(double)BCAL_LAYS2;
1413 double dmodule = (double)TMath::TwoPi()/(double)BCAL_MODS;
1414 double dsector1 = dmodule/(double)BCAL_SECS1;
1415 double dsector2 = dmodule/(double)BCAL_SECS2;
1416
1417 // Create polygon for each readout segment for use in coloring hits
1418 if(GetCheckButton("bcal")){
1419 for(int imod=0; imod<BCAL_MODS; imod++){
1420 double mod_phi = (double)imod*dmodule -2.0*dsector1 + BCAL_PHI_SHIFT;
1421 double r_min=BCAL_Rmin;
1422 for(int ilay=0; ilay<BCAL_LAYS1; ilay++){
1423 r_min+=dlayer1*ilay;
1424 double r_max = r_min+(ilay+1)*dlayer1;
1425 for(int isec=0; isec<BCAL_SECS1; isec++){
1426 double phimin = mod_phi + (double)isec*dsector1;
1427 double phimax = phimin + dsector1;
1428
1429 double x[4], y[4];
1430 x[0] = r_min*cos(phimin);
1431 y[0] = r_min*sin(phimin);
1432 x[1] = r_max*cos(phimin);
1433 y[1] = r_max*sin(phimin);
1434 x[2] = r_max*cos(phimax);
1435 y[2] = r_max*sin(phimax);
1436 x[3] = r_min*cos(phimax);
1437 y[3] = r_min*sin(phimax);
1438
1439 TPolyLine *poly = new TPolyLine(4, x, y);
1440 poly->SetLineColor(12);
1441 poly->SetLineWidth(0);
1442 poly->SetFillColor(0);
1443 poly->SetFillStyle(0);
1444 int chan = (imod+1)*1000 + (ilay+1)*100 + (isec+1)*10;
1445 graphics_endA.push_back(poly);
1446 bcalblocks[chan] = poly; // record so we can set the color later
1447 }
1448
1449 for(int isec=0; isec<BCAL_SECS2; isec++){
1450 double phimin = mod_phi + (double)isec*dsector2;
1451 double phimax = phimin + dsector2;
1452
1453 double x[5], y[5];
1454 x[0] = BCAL_MIDRAD*cos(phimin);
1455 y[0] = BCAL_MIDRAD*sin(phimin);
1456 x[1] = BCAL_Rmax*cos(phimin);
1457 y[1] = BCAL_Rmax*sin(phimin);
1458 x[2] = BCAL_Rmax*cos(phimax);
1459 y[2] = BCAL_Rmax*sin(phimax);
1460 x[3] = BCAL_MIDRAD*cos(phimax);
1461 y[3] = BCAL_MIDRAD*sin(phimax);
1462 x[4] = x[0];
1463 y[4] = y[0];
1464 TPolyLine *poly = new TPolyLine(5, x, y);
1465 poly->SetLineColor(12);
1466 poly->SetLineWidth(1);
1467 poly->SetFillColor(0);
1468 poly->SetFillStyle(0);
1469 int chan = (int)((imod+1)*1000 + (ilay+1+BCAL_LAYS1)*100 + (isec+1)*10);
1470 graphics_endA.push_back(poly);
1471 bcalblocks[chan] = poly; // record so we can set the color later
1472 }
1473 }
1474 }
1475 }
1476 // Draw lines to identify boundaries of readout segments
1477 for(int imod=0; imod<BCAL_MODS; imod++){
1478 // Vertical(sector) boundaries
1479 double mod_phi = (double)imod*dmodule -2.0*dsector1 + BCAL_PHI_SHIFT;
1480 for(int isec=0; isec<BCAL_SECS1; isec++){
1481 double rmin = BCAL_Rmin;
1482 double rmax = BCAL_MIDRAD;
1483 double phi = mod_phi + (double)isec*dsector1;
1484
1485 TLine *l = new TLine(rmin*cos(phi), rmin*sin(phi), rmax*cos(phi), rmax*sin(phi));
1486 l->SetLineColor(isec==0 ? kBlack:12);
1487 l->SetLineWidth((Width_t)(isec==0 ? 2.5:1.0));
1488 graphics_endA.push_back(l);
1489 }
1490 for(int isec=0; isec<BCAL_SECS2; isec++){
1491 double rmin = BCAL_MIDRAD;
1492 double rmax = BCAL_Rmax;
1493 double phi = mod_phi + (double)isec*dsector2;
1494
1495 TLine *l = new TLine(rmin*cos(phi), rmin*sin(phi), rmax*cos(phi), rmax*sin(phi));
1496 l->SetLineColor(isec==0 ? kBlack:12);
1497 l->SetLineWidth((Width_t)(isec==0 ? 2.5:1.0));
1498 graphics_endA.push_back(l);
1499 }
1500
1501 // Horizontal(layer) boundaries
1502 double r=BCAL_Rmin;
1503 for(int ilay=0; ilay<BCAL_LAYS1; ilay++){
1504 r+=dlayer1*ilay;
1505 TLine *l = new TLine(r*cos(mod_phi), r*sin(mod_phi), r*cos(mod_phi+dmodule), r*sin(mod_phi+dmodule));
1506 l->SetLineColor(ilay==0 ? kBlack:12);
1507 l->SetLineWidth((Width_t)(ilay==0 ? 1.0:1.0));
1508 graphics_endA.push_back(l);
1509 }
1510
1511 TLine *l = new TLine(BCAL_MIDRAD*cos(mod_phi), BCAL_MIDRAD*sin(mod_phi), BCAL_MIDRAD*cos(mod_phi+dmodule), BCAL_MIDRAD*sin(mod_phi+dmodule));
1512 l->SetLineColor(12);
1513 l->SetLineWidth((Width_t)(1.0));
1514 graphics_endA.push_back(l);
1515 }
1516
1517 // ----- CDC ------
1518 TEllipse *cdc1 = new TEllipse(0.0, 0.0, CDC_Rmax, CDC_Rmax);
1519 TEllipse *cdc2 = new TEllipse(0.0, 0.0, CDC_Rmin, CDC_Rmin);
1520 cdc1->SetFillColor(17);
1521 cdc1->SetLineColor(17);
1522 cdc2->SetFillColor(10);
1523 graphics_endA.push_back(cdc1);
1524 graphics_endA.push_back(cdc2);
1525
1526 // ----- FDC ------
1527 TEllipse *fdc1 = new TEllipse(0.0, 0.0, FDC_Rmax, FDC_Rmax);
1528 TEllipse *fdc2 = new TEllipse(0.0, 0.0, FDC_Rmin, FDC_Rmin);
1529 fdc1->SetFillColor(21);
1530 fdc1->SetLineColor(21);
1531 fdc2->SetFillColor(10);
1532 fdc2->SetLineColor(10);
1533 graphics_endA.push_back(fdc1);
1534 graphics_endA.push_back(fdc2);
1535
1536
1537 /*
1538 // ------ Start counter ------
1539 double r_start=7.7;
1540 for (unsigned int i=0;i<30;i++){
1541 double phi_0=0.209*i;
1542 double phi_1=0.209*(i+1);
1543 TLine *l = new TLine(r_start*cos(phi_0), r_start*sin(phi_0),
1544 r_start*cos(phi_1), r_start*sin(phi_1));
1545 l->SetLineColor(10);
1546 l->SetLineWidth(2.);
1547 graphics_endA.push_back(l);
1548 }
1549 */
1550
1551 // ----- Start Counter -----
1552 // All units are in cm. These dimensions represent the geometry exactly.
1553 Double_t inner_radius = 7.7493; // Inner radius of the Start Counter
1554 Double_t outer_radius = 8.0493; // Outer radius of the Start Counter
1555 Double_t bottom_width = 1.6289; // Width of the bottom edge of scintillator
1556 Double_t top_width = 1.692; // Width of the top edge of scintillator
1557 Double_t dtr = 1.745329252e-02; // Conversion factor from degrees to radians
1558
1559 // 5 x and 5 y coordinates for each of the 30 paddles
1560 Double_t x_coords[31][5];
1561 Double_t y_coords[31][5];
1562
1563 // Initialize the x-coordinates of channel 0 (phi = [0, 12 deg] in hall coordinates)
1564 x_coords[0][0] = -outer_radius;
1565 x_coords[0][1] = -(outer_radius - top_width*sin(6.0*dtr));
1566 x_coords[0][2] = -(inner_radius - bottom_width*sin(6.0*dtr));
1567 x_coords[0][3] = -inner_radius;
1568 x_coords[0][4] = -outer_radius;
1569 // Initialize the x-coordinates of channel 0 (phi = [0, 12 deg] in hall coordinates)
1570 y_coords[0][0] = 0.0;
1571 y_coords[0][1] = top_width*cos(6.0*dtr);
1572 y_coords[0][2] = bottom_width*cos(6.0*dtr);
1573 y_coords[0][3] = 0.0;
1574 y_coords[0][4] = 0.0;
1575
1576 // Create an array of TPolyLine objects
1577 TPolyLine *ch_pline[30];
1578
1579 // Define array of points which define the individual scintillators
1580 for (int i = 1; i < 31; i++)
1581 {
1582 // Contruct the x-coordinates of the 30 scintillator paddles
1583 x_coords[i][0] = x_coords[i-1][1];
1584 x_coords[i][1] = x_coords[i-1][1] + top_width*sin((6.0 + 12.0*i)*dtr);
1585 x_coords[i][2] = x_coords[i-1][2] + bottom_width*sin((6.0 + 12.0*i)*dtr);
1586 x_coords[i][3] = x_coords[i-1][2];
1587 x_coords[i][4] = x_coords[i-1][1];
1588 // Construct the y-coordinates of the 30 scintillator paddles
1589 y_coords[i][0] = y_coords[i-1][1];
1590 y_coords[i][1] = y_coords[i-1][1] + top_width*cos((6.0 + 12.0*i)*dtr);
1591 y_coords[i][2] = y_coords[i-1][2] + bottom_width*cos((6.0 + 12.0*i)*dtr);
1592 y_coords[i][3] = y_coords[i-1][2];
1593 y_coords[i][4] = y_coords[i-1][1];
1594
1595 // Construct the TPolyLine objects that defines the paddles
1596 Double_t x[5] = {x_coords[i-1][0], x_coords[i-1][1], x_coords[i-1][2], x_coords[i-1][3], x_coords[i-1][4]};
1597 Double_t y[5] = {y_coords[i-1][0], y_coords[i-1][1], y_coords[i-1][2], y_coords[i-1][3], y_coords[i-1][4]};
1598 ch_pline[i-1] = new TPolyLine(5, x, y);
1599 ch_pline[i-1]->SetFillColor(18);
1600 ch_pline[i-1]->SetLineColor(1);
1601 ch_pline[i-1]->SetLineWidth(2);
1602 graphics_endA.push_back(ch_pline[i-1]);
1603 }
1604
1605 // ----- TARGET ------
1606 TEllipse *target = new TEllipse(0.0, 0.0, 0.5, 0.5);
1607 target->SetFillColor(13);
1608 graphics_endA.push_back(target);
1609
1610 // ------ scale ------
1611 DrawScale(endviewA->GetCanvas(), graphics_endA);
1612 }
1613
1614 //============== End B
1615 {
1616 endviewB->GetCanvas()->cd(0);
1617 endviewB->GetCanvas()->Clear();
1618
1619 // ----- FCAL ------
1620 // Get list of blocks. Loop over all getting x,y coordinates of corners for all active ones.
1621
1622 // Set up 4 2-D vectors that point from the center of a block to its
1623 // corners. This makes it easier to represent each corner as a vector
1624 // in lab coordinate which we can extract r, phi from.
1625 double blocksize = fcalgeom->blockSize();
1626 DVector2 shift[8];
1627 shift[0].Set(-blocksize/2, -blocksize/2); // these are ordered such that they
1628 shift[1].Set(-blocksize/2, +blocksize/2); // go in a clockwise manner. This
1629 shift[2].Set(+blocksize/2, +blocksize/2); // ensures the r/phi cooridinates also
1630 shift[3].Set(+blocksize/2, -blocksize/2); // define a single enclosed space
1631 double insertSize=fcalgeom->insertSize();
1632 if (insertSize>0){
1633 blocksize=fcalgeom->insertBlockSize();
1634 shift[4].Set(-blocksize/2, -blocksize/2); // these are ordered such that they
1635 shift[5].Set(-blocksize/2, +blocksize/2); // go in a clockwise manner. This
1636 shift[6].Set(+blocksize/2, +blocksize/2); // ensures the r/phi cooridinates also
1637 shift[7].Set(+blocksize/2, -blocksize/2); // define a single enclosed space
1638 }
1639
1640 fcalblocks.clear();
1641 if(GetCheckButton("fcal")){
1642 for(unsigned int chan=0; chan<fcalgeom->numChannels(); chan++){
1643 if (fcalgeom->isBlockActive(chan)==false) continue;
1644 DVector2 fcalBlockPos=fcalgeom->positionOnFace(chan);
1645
1646 double x[5], y[5];
1647 for(int i=0; i<4; i++){
1648 DVector2 pos = fcalBlockPos;
1649 if (insertSize>0
1650 && fabs(pos.X())<insertSize
1651 && fabs(pos.Y())<insertSize){
1652 pos+=shift[i+4];
1653 }
1654 else{
1655 pos+=shift[i];
1656 }
1657 x[i] = pos.X();
1658 y[i] = pos.Y();
1659 }
1660 x[4] = x[0];
1661 y[4] = y[0];
1662
1663 TPolyLine *poly = new TPolyLine(5, x, y);
1664 poly->SetFillColor(0);
1665 poly->SetLineColor(kBlack);
1666 graphics_endB.push_back(poly);
1667
1668 fcalblocks[chan] = poly; // record so we can set the color later
1669 }
1670 }
1671
1672 // ----- CCAL ------
1673 // Get list of blocks. Loop over all getting x,y coordinates of corners for all active ones.
1674
1675 // Set up 4 2-D vectors that point from the center of a block to its
1676 // corners. This makes it easier to represent each corner as a vector
1677 // in lab coordinate which we can extract r, phi from.
1678 blocksize = 2.0;
1679 shift[0].Set(-blocksize/2, -blocksize/2); // these are ordered such that they
1680 shift[1].Set(-blocksize/2, +blocksize/2); // go in a clockwise manner. This
1681 shift[2].Set(+blocksize/2, +blocksize/2); // ensures the r/phi coordinates also
1682 shift[3].Set(+blocksize/2, -blocksize/2); // define a single enclosed space
1683 ccalblocks.clear();
1684
1685 if(GetCheckButton("ccal")){
1686 for(int irow=0; irow<12; irow++){
1687 for(int icol=0; icol<12; icol++){
1688 if( (irow==5 || irow==6) && (icol==5 || icol==6) ) continue;
1689
1690 double center_x = (-6.0 + (icol+0.5))*2.0;
1691 double center_y = (-6.0 + (irow+0.5))*2.0;
1692 DVector2 mypos(center_x,center_y);
1693
1694 double x[5], y[5];
1695 for(int i=0; i<4; i++){
1696 DVector2 pos = shift[i] + mypos;
1697 x[i] = pos.X();
1698 y[i] = pos.Y();
1699 }
1700 x[4] = x[0];
1701 y[4] = y[0];
1702
1703 TPolyLine *poly = new TPolyLine(5, x, y);
1704 poly->SetFillColor(0);
1705 poly->SetLineColor(kBlack);
1706 graphics_endB.push_back(poly);
1707
1708 int channel = icol + 12*(irow);
1709 ccalblocks[channel] = poly; // record so we can set the color later
1710 }
1711 }
1712
1713 // If also drawing FCAL, draw an extra outline of the FCAL beam hole
1714 if(GetCheckButton("fcal")){
1715 double x[5] = {-6.0, -6.0, 6.0, 6.0, -6.0};
1716 double y[5] = {-6.0, 6.0, 6.0,-6.0, -6.0};
1717 TPolyLine *poly = new TPolyLine(5, x, y);
1718 poly->SetFillColor(0);
1719 poly->SetLineColor(kBlack);
1720 poly->SetLineWidth(3);
1721 poly->SetLineStyle(2);
1722 graphics_endB.push_back(poly);
1723 }
1724 }
1725
1726 // ------- TOF ---------//
1727 tofblocks.clear();
1728 if(GetCheckButton("tof")){
1729
1730 TPolyLine *pmtPline[4][44] = {{ NULL__null }, { NULL__null }};
1731
1732 // 38 PMTs for the standard modules in each side
1733 Double_t pmtX[4][44][5];
1734 Double_t pmtY[4][44][5];
1735
1736 Double_t x[5];
1737 Double_t y[5];
1738
1739 // origin: 0:DOWN; 1:NORTH; 2:UP; 3:SOUTH
1740 Double_t position_x[4] = {-126,-126,-126,126};
1741 Double_t position_y[4] = {-126,-126,126,-126};
1742
1743 // PMTs from regular and half lenght modules with 6 cm x 14 cm
1744 Double_t step_x[4][5] = {{0,0,6,6,0},{0,-14,-14,0,0},{0,0,6,6,0},{0,14,14,0,0}};
1745 Double_t step_y[4][5] = {{0,-14,-14,0,0},{0,0,6,6,0},{0,14,14,0,0},{0,0,6,6,0}};
1746 Double_t step_xl[4][5] = {{0,0,3,3,0},{0,-20,-20,0,0},{0,0,3,3,0},{0,20,20,0,0}};
1747 Double_t step_yl[4][5] = {{0,-20,-20,0,0},{0,0,3,3,0},{0,20,20,0,0},{0,0,3,3,0}};
1748 Double_t step_X[4] = {6,0,6,0};
1749 Double_t step_Y[4] = {0,6,0,6};
1750 Double_t step_XL[4] = {3,0,3,0};
1751 Double_t step_YL[4] = {0,3,0,3};
1752
1753
1754 for (int sd=0; sd<4; sd++)
1755 {
1756 for (int i=0; i<44; i++)
1757 {
1758 for (int l=0; l<5; l++)
1759 {
1760 switch(l)
1761 {
1762 case 0:
1763 if (i == 19 || i == 20 || i == 23 || i == 24){
1764 pmtX[sd][i][l]=position_x[sd] + step_xl[sd][l];
1765 pmtY[sd][i][l]=position_y[sd] + step_yl[sd][l];
1766 }
1767 else{
1768 pmtX[sd][i][l]=position_x[sd] + step_x[sd][l];
1769 pmtY[sd][i][l]=position_y[sd] + step_y[sd][l];
1770 }
1771 break;
1772 case 1:
1773 if (i == 19 || i == 20 || i == 23 || i == 24){
1774 pmtX[sd][i][l]=position_x[sd] + step_xl[sd][l];
1775 pmtY[sd][i][l]=position_y[sd] + step_yl[sd][l];
1776 }
1777 else{
1778 pmtX[sd][i][l]=position_x[sd] + step_x[sd][l];
1779 pmtY[sd][i][l]=position_y[sd] + step_y[sd][l];
1780 }
1781 break;
1782 case 2:
1783 if (i == 19 || i == 20 || i == 23 || i == 24){
1784 pmtX[sd][i][l]=position_x[sd] + step_xl[sd][l];
1785 pmtY[sd][i][l]=position_y[sd] + step_yl[sd][l];
1786 }
1787 else{
1788 pmtX[sd][i][l]=position_x[sd] + step_x[sd][l];
1789 pmtY[sd][i][l]=position_y[sd] + step_y[sd][l];
1790 }
1791 break;
1792 case 3:
1793 if (i == 19 || i == 20 || i == 23 || i == 24){
1794 pmtX[sd][i][l]=position_x[sd] + step_xl[sd][l];
1795 pmtY[sd][i][l]=position_y[sd] + step_yl[sd][l];
1796 }
1797 else{
1798 pmtX[sd][i][l]=position_x[sd] + step_x[sd][l];
1799 pmtY[sd][i][l]=position_y[sd] + step_y[sd][l];
1800 }
1801 break;
1802 case 4:
1803 if (i == 19 || i == 20 || i == 23 || i == 24){
1804 pmtX[sd][i][l]=position_x[sd] + step_xl[sd][l];
1805 pmtY[sd][i][l]=position_y[sd] + step_yl[sd][l];
1806 }
1807 else{
1808 pmtX[sd][i][l]=position_x[sd] + step_x[sd][l];
1809 pmtY[sd][i][l]=position_y[sd] + step_y[sd][l];
1810 }
1811 break;
1812 }
1813 }
1814 if ( i == 19 || i == 20 || i == 23 || i == 24){
1815 position_x[sd] = position_x[sd] + step_XL[sd];
1816 position_y[sd] = position_y[sd] + step_YL[sd];
1817 }
1818 else{
1819 position_x[sd] = position_x[sd] + step_X[sd];
1820 position_y[sd] = position_y[sd] + step_Y[sd];
1821 }
1822 }
1823 }
1824
1825 for (int sd=0; sd<4; sd++) // for the 4 sides
1826 {
1827 for (int j=0; j<44; j++) // PMT for the standard modules
1828 {
1829 for (int q=0; q<5; q++)
1830 {
1831 x[q] = pmtX[sd][j][q];
1832 y[q] = pmtY[sd][j][q];
1833 }
1834 pmtPline[sd][j] = new TPolyLine(5,x,y);
1835 }
1836 }
1837
1838 int tof_count = 0;
1839 for (int sd=0; sd<4; sd++) // for the 4 sides
1840 {
1841 for (int j=0; j<44; j++)
1842 {
1843 pmtPline[sd][j]->SetFillColor(1);
1844 pmtPline[sd][j]->SetLineColor(41);
1845 pmtPline[sd][j]->SetLineWidth(2);
1846 tof_count++;
1847 graphics_endB.push_back(pmtPline[sd][j]);
1848 tofblocks[sd][tof_count] = pmtPline[sd][j];
1849 }
1850 tof_count = 0;
1851 }
1852
1853 } // close the if tof-check button
1854
1855 // ------ scale ------
1856 DrawScale(endviewB->GetCanvas(), graphics_endB);
1857 }
1858
1859 //=============== Draw axes arrows
1860 // (this is done here since the sideB graphics are copied from sideA)
1861 DrawAxes(sideviewA->GetCanvas(), graphics_sideA, "Z", "X");
1862 DrawAxes(sideviewB->GetCanvas(), graphics_sideB, "Z", "Y");
1863 DrawAxes(endviewA->GetCanvas(), graphics_endA, "X", "Y");
1864 DrawAxes(endviewB->GetCanvas(), graphics_endB, "X", "Y");
1865
1866
1867 //=============== Draw view labels
1868 DrawLabel(sideviewA->GetCanvas(), graphics_sideA, "top view (looking down from above detector)");
1869 DrawLabel(sideviewA->GetCanvas(), graphics_sideB, "side view from beam right (south)");
1870 DrawLabel(endviewA->GetCanvas(), graphics_endA, "BCAL view from downstream looking upstream");
1871 DrawLabel(endviewB->GetCanvas(), graphics_endB, "FCAL view from downstream looking upstream");
1872}
1873
1874//-------------------
1875// DrawDetectorsRPhi
1876//-------------------
1877void hdv_mainframe::DrawDetectorsRPhi(void)
1878{
1879 //============== Side A R vs. z
1880 {
1881 sideviewA->GetCanvas()->cd(0);
1882 sideviewA->GetCanvas()->Clear();
1883
1884 // ------ Target ------
1885 TBox *target = new TBox(TARGET_Zmid-TARGET_Zlen/2.0, 0.0, TARGET_Zmid+TARGET_Zlen/2.0, 0.5);
1886 target->SetFillColor(13);
1887 graphics_sideA.push_back(target);
1888
1889 // ----- BCAL ------
1890 TBox *bcal1 = new TBox(BCAL_Zmin, BCAL_Rmin, BCAL_Zmin+BCAL_Zlen, BCAL_Rmax);
1891 bcal1->SetFillColor(28);
1892 graphics_sideA.push_back(bcal1);
1893
1894 // ----- CDC ------
1895 TBox *cdc1 = new TBox(CDC_Zmin, CDC_Rmin, CDC_Zmin + CDC_Zlen, CDC_Rmax);
1896 cdc1->SetFillColor(17);
1897 graphics_sideA.push_back(cdc1);
1898
1899 // ----- FDC ------
1900 for(int i=0; i<4; i++){
1901 // Get FDC package positions from FDC library
1902 float zu = fdcwires[i*6][0]->origin.z();
1903 float zd = fdcwires[i*6+5][0]->origin.z();
1904 TBox *fdc1 = new TBox(zu, FDC_Rmin, zd, FDC_Rmax);
1905 fdc1->SetFillColor(21);
1906 graphics_sideA.push_back(fdc1);
1907 }
1908
1909 // ----- TOF ------
1910 TBox *tof1 = new TBox(TOF_Zmin, TOF_Rmin, TOF_Zmin+TOF_Zlen, TOF_Rmax);
1911 tof1->SetFillColor(11);
1912 graphics_sideA.push_back(tof1);
1913
1914 // ----- FCAL ------
1915 TBox *fcal1 = new TBox(FCAL_Zmin, FCAL_Rmin, FCAL_Zmin+FCAL_Zlen, FCAL_Rmax);
1916 fcal1->SetFillColor(40);
1917 graphics_sideA.push_back(fcal1);
1918
1919 // ------ scale ------
1920 DrawScale(endviewA->GetCanvas(), graphics_endA);
1921 }
1922
1923 //============== Side B Phi vs. z
1924 {
1925 sideviewB->GetCanvas()->cd(0);
1926 sideviewB->GetCanvas()->Clear();
1927
1928 // ------ Target ------
1929 TBox *target = new TBox(TARGET_Zmid-TARGET_Zlen/2.0, 0.0, TARGET_Zmid+TARGET_Zlen/2.0, 2.0*M_PI3.14159265358979323846);
1930 target->SetFillColor(13);
1931 graphics_sideB.push_back(target);
1932
1933 // ----- BCAL ------
1934 TBox *bcal1 = new TBox(BCAL_Zmin, 0.0, BCAL_Zmin+BCAL_Zlen, 2.0*M_PI3.14159265358979323846);
1935 bcal1->SetFillColor(28);
1936 graphics_sideB.push_back(bcal1);
1937
1938 // ----- CDC ------
1939 TBox *cdc1 = new TBox(CDC_Zmin, 0.0, CDC_Zmin + CDC_Zlen, 2.0*M_PI3.14159265358979323846);
1940 cdc1->SetFillColor(17);
1941 graphics_sideB.push_back(cdc1);
1942
1943 // ----- FDC ------
1944 for(int i=0; i<4; i++){
1945 // Get FDC package positions from FDC library
1946 float zu = fdcwires[i*6][0]->origin.z();
1947 float zd = fdcwires[i*6+5][0]->origin.z();
1948
1949 TBox *fdc1 = new TBox(zu, 0.0, zd, 2.0*M_PI3.14159265358979323846);
1950 fdc1->SetFillColor(21);
1951 graphics_sideB.push_back(fdc1);
1952 }
1953
1954 // ----- TOF ------
1955 TBox *tof1 = new TBox(TOF_Zmin, 0.0, TOF_Zmin+TOF_Zlen, 2.0*M_PI3.14159265358979323846);
1956 tof1->SetFillColor(11);
1957 graphics_sideB.push_back(tof1);
1958
1959 // ----- FCAL ------
1960 TBox *fcal1 = new TBox(FCAL_Zmin, 0.0, FCAL_Zmin+FCAL_Zlen, 2.0*M_PI3.14159265358979323846);
1961 fcal1->SetFillColor(40);
1962 graphics_sideB.push_back(fcal1);
1963
1964 // ------ scale ------
1965 DrawScale(endviewA->GetCanvas(), graphics_endA);
1966 }
1967
1968 //============== End A R vs. phi
1969 {
1970 endviewA->GetCanvas()->cd(0);
1971 endviewA->GetCanvas()->Clear();
1972
1973 // ----- BCAL ------
1974 TBox *bcal1 = new TBox(0.0, BCAL_Rmin, 2.0*M_PI3.14159265358979323846, BCAL_Rmax);
1975 bcal1->SetFillColor(28);
1976 graphics_endA.push_back(bcal1);
1977
1978 // ----- CDC ------
1979 TBox *cdc1 = new TBox(0.0, CDC_Rmin, 2.0*M_PI3.14159265358979323846, CDC_Rmax);
1980 cdc1->SetFillColor(17);
1981 graphics_endA.push_back(cdc1);
1982
1983 // ----- FDC ------
1984 TBox *fdc1 = new TBox(0.0, FDC_Rmin, 2.0*M_PI3.14159265358979323846, FDC_Rmax);
1985 fdc1->SetFillColor(21);
1986 graphics_endA.push_back(fdc1);
1987
1988 // ----- TARGET ------
1989 TBox *target = new TBox(0.0, 0.0, 2.0*M_PI3.14159265358979323846, 0.5);
1990 target->SetFillColor(13);
1991 graphics_endA.push_back(target);
1992
1993 }
1994
1995 //============== End B R vs. phi
1996 {
1997 endviewB->GetCanvas()->cd(0);
1998 endviewB->GetCanvas()->Clear();
1999
2000 // ----- FCAL ------
2001 // Get list of blocks. Loop over all getting x,y coordinates of corners for all active ones.
2002
2003 // Set up 4 2-D vectors that point from the center of a block to its
2004 // corners. This makes it easier to represent each corner as a vector
2005 // in lab corrdinate whch we can extract r, phi from.
2006 double blocksize = fcalgeom->blockSize();
2007 DVector2 shift[8];
2008 shift[0].Set(-blocksize/2, -blocksize/2); // these are ordered such that they
2009 shift[1].Set(-blocksize/2, +blocksize/2); // go in a clockwise manner. This
2010 shift[2].Set(+blocksize/2, +blocksize/2); // ensures the r/phi cooridinates also
2011 shift[3].Set(+blocksize/2, -blocksize/2); // define a single enclosed space
2012
2013 double insertSize=fcalgeom->insertSize();
2014 if (insertSize>0){
2015 blocksize=fcalgeom->insertBlockSize();
2016 shift[4].Set(-blocksize/2, -blocksize/2); // these are ordered such that they
2017 shift[5].Set(-blocksize/2, +blocksize/2); // go in a clockwise manner. This
2018 shift[6].Set(+blocksize/2, +blocksize/2); // ensures the r/phi cooridinates also
2019 shift[7].Set(+blocksize/2, -blocksize/2); // define a single enclosed space
2020 }
2021 fcalblocks.clear();
2022 for(unsigned int chan=0; chan<fcalgeom->numChannels(); chan++){
2023 if (fcalgeom->isBlockActive(chan)==false) continue;
2024 DVector2 fcalBlockPos=fcalgeom->positionOnFace(chan);
2025
2026 double r[4], phi[4];
2027 for(int i=0; i<4; i++){
2028 DVector2 pos = fcalBlockPos;
2029 if (insertSize>0
2030 && fabs(pos.X())<insertSize
2031 && fabs(pos.Y())<insertSize){
2032 pos+=shift[i+4];
2033 }
2034 else{
2035 pos+=shift[i];
2036 }
2037 r[i] = pos.Mod();
2038 phi[i] = pos.Phi_0_2pi(pos.Phi());
2039 }
2040
2041 TPolyLine *poly = new TPolyLine(4, phi, r);
2042 poly->SetFillColor(18);
2043 poly->SetLineColor(kBlack);
2044 graphics_endB.push_back(poly);
2045
2046 fcalblocks[chan] = poly; // record so we can set the color later
2047 }
2048 }
2049
2050 //=============== Draw axes arrows
2051 DrawAxes(sideviewA->GetCanvas(), graphics_sideA, "Z", "R");
2052 DrawAxes(sideviewB->GetCanvas(), graphics_sideB, "Z", "#phi");
2053 DrawAxes(endviewA->GetCanvas(), graphics_endA, "#phi", "R");
2054 DrawAxes(endviewB->GetCanvas(), graphics_endB, "#phi", "R");
2055}
2056
2057//-------------------
2058// DrawAxes
2059//-------------------
2060void hdv_mainframe::DrawAxes(TCanvas *c, vector<TObject*> &graphics, const char *xlab, const char *ylab)
2061{
2062 /// Create arrows indicating x and y axes with labels on the specified canvas
2063 /// and add them to the specified container of graphics objects to be draw later.
2064 double x1 = c->GetX1();
2065 double x2 = c->GetX2();
2066 double y1 = c->GetY1();
2067 double y2 = c->GetY2();
2068 double deltax = x2-x1;
2069 deltax *= c->GetYsizeReal()/c->GetXsizeReal();
2070 double deltay = y2-y1;
2071 double xlo = x1+0.04*deltax;
2072 double xhi = xlo + 0.075*deltax;
2073 double ylo = y1+0.04*deltay;
2074 double yhi = ylo + 0.075*deltay;
2075 TArrow *yarrow = new TArrow(xlo, ylo, xlo, yhi, 0.02, ">");
2076 yarrow->SetLineWidth((Width_t)1.5);
2077 graphics.push_back(yarrow);
2078
2079 TLatex *ylabel = new TLatex(xlo, yhi+0.005*deltay, ylab);
2080 ylabel->SetTextAlign(21);
2081 graphics.push_back(ylabel);
2082
2083 TArrow *xarrow = new TArrow(xlo, ylo, xhi, ylo, 0.02, ">");
2084 xarrow->SetLineWidth((Width_t)1.5);
2085 graphics.push_back(xarrow);
2086
2087 TLatex *xlabel = new TLatex(xhi+0.005*deltax, ylo, xlab);
2088 xlabel->SetTextAlign(12);
2089 graphics.push_back(xlabel);
2090}
2091
2092//-------------------
2093// DrawScale
2094//-------------------
2095void hdv_mainframe::DrawScale(TCanvas *c, vector<TObject*> &graphics)
2096{
2097 /// Create a scale label on the specified canvas and add it
2098 /// to the specified container of graphics objects to be draw later.
2099 double x1 = c->GetX1();
2100 double x2 = c->GetX2();
2101 double y1 = c->GetY1();
2102 double y2 = c->GetY2();
2103 double deltax = x2-x1;
2104 double deltay = y2-y1;
2105 double p = floor(log(0.1*deltax)/log(10.0));
2106 double m = floor(0.1*deltax/pow(10.0, p) + 0.5);
2107 double xlo = x1+0.72*deltax;
2108 double xhi = xlo + m*pow(10.0, p);
2109 double y = y1+0.04*deltay;
2110 TArrow *arrow = new TArrow(xlo, y, xhi, y, 0.02, "|-|");
2111 arrow->SetLineWidth((Width_t)1.0);
2112 graphics.push_back(arrow);
2113
2114 const char *units="<out of range>";
2115 switch((int)p){
2116 case -5:
2117 units = "#mum";
2118 break;
2119 case -4:
2120 units = "#mum";
2121 break;
2122 case -3:
2123 m*=10.0;
2124 units = "#mum";
2125 break;
2126 case -2:
2127 m*=100.0;
2128 units="#mum";
2129 break;
2130 case -1:
2131 units="mm";
2132 break;
2133 case 0:
2134 units = "cm";
2135 break;
2136 case 1:
2137 m*=10.0;
2138 units = "cm";
2139 break;
2140 case 2:
2141 units = "m";
2142 break;
2143 case 3:
2144 m*=10.0;
2145 units = "m";
2146 break;
2147 case 4:
2148 m*=100.0;
2149 units = "m";
2150 break;
2151 case 5:
2152 units = "km";
2153 break;
2154 case 6:
2155 m*=10.0;
2156 units = "km";
2157 break;
2158 }
2159 char str[256];
2160 sprintf(str,"%d %s", (int)m, units);
2161 TLatex *label = new TLatex(xhi+0.01*deltax, y, str);
2162 label->SetTextAlign(12);
2163 graphics.push_back(label);
2164}
2165
2166//-------------------
2167// DrawLabel
2168//-------------------
2169void hdv_mainframe::DrawLabel(TCanvas *c, vector<TObject*> &graphics, const char *txt)
2170{
2171 /// Create label on top of the specified canvas
2172 /// and add it to the specified container of graphics
2173 /// objects to be drawn later.
2174 double x1 = c->GetX1();
2175 double x2 = c->GetX2();
2176 double y1 = c->GetY1();
2177 double y2 = c->GetY2();
2178 double deltax = x2-x1;
2179 double deltay = y2-y1;
2180 deltax *= c->GetYsizeReal()/c->GetXsizeReal();
2181 double x = x1 + 0.005*deltax;
2182 double y = y2 - 0.003*deltay;
2183
2184 TLatex *label = new TLatex(x, y, txt);
2185 label->SetTextAlign(13);
2186 label->SetTextSize(0.045);
2187 graphics.push_back(label);
2188}
2189
2190
2191//-------------------
2192// SetEvent
2193//-------------------
2194void hdv_mainframe::SetEvent(ULong64_t id)
2195{
2196 if(!event)return;
2197
2198 stringstream ss;
2199 ss << id;
2200 event->SetTitle(ss.str().c_str());
2201 event->Draw();
2202}
2203
2204//-------------------
2205// SetRun
2206//-------------------
2207void hdv_mainframe::SetRun(Int_t id)
2208{
2209 if(!event)return;
2210
2211 stringstream ss;
2212 ss << id;
2213 run->SetTitle(ss.str().c_str());
2214 run->Draw();
2215}
2216
2217//-------------------
2218// SetTrig
2219//-------------------
2220void hdv_mainframe::SetTrig(char *trigstring)
2221{
2222 if(!event)return;
2223
2224 trig->SetTitle(trigstring);
2225 trig->Draw();
2226}
2227
2228
2229//-------------------
2230// SetSource
2231//-------------------
2232void hdv_mainframe::SetSource(string source)
2233{
2234 this->source->SetTitle(source.c_str());
2235 this->source->Draw();
2236}
2237
2238//-------------------
2239// SetCandidateFactories
2240//-------------------
2241void hdv_mainframe::SetCandidateFactories(vector<string> &facnames)
2242{
2243 /// Filter out the factories that provide "DTrackCandidate" objects
2244 /// and add their tags to the tracksfactory combobox.
2245 // Erase all current entries in the combobox and add back in
2246 // "<default>".
2247 candidatesfactory->RemoveAll();
2248 candidatesfactory->AddEntry("<default>", 0);
2249 candidatesfactory->GetTextEntry()->SetText("<default>");
2250 candidatesfactory->Select(0, kFALSE);
2251
2252 for(unsigned int i=0; i< facnames.size(); i++){
2253 string name = "DTrackCandidate:";
2254 string::size_type pos = facnames[i].find(name);
2255 if(pos==string::npos)continue;
2256 string tag = facnames[i];
2257 tag.erase(0, name.size());
2258 candidatesfactory->AddEntry(tag.c_str(), i);
2259 if(tag==default_candidate){
2260 candidatesfactory->Select(i, kTRUE);
2261 candidatesfactory->GetTextEntry()->SetText(tag.c_str());
2262 }
2263 }
2264}
2265
2266//-------------------
2267// SetWireBasedTrackFactories
2268//-------------------
2269void hdv_mainframe::SetWireBasedTrackFactories(vector<string> &facnames)
2270{
2271 /// Filter out the factories that provide "DTrackWireBased" objects
2272 /// and add their tags to the tracksfactory combobox.
2273
2274 // Erase all current entries in the combobox and add back in
2275 // "<default>".
2276 wiretracksfactory->RemoveAll();
2277 wiretracksfactory->AddEntry("<default>", 0);
2278 wiretracksfactory->GetTextEntry()->SetText("<default>");
2279 wiretracksfactory->Select(0, kFALSE);
2280
2281 for(unsigned int i=0; i< facnames.size(); i++){
2282 string name = "DTrackWireBased:";
2283 string::size_type pos = facnames[i].find(name);
2284 if(pos==string::npos)continue;
2285 string tag = facnames[i];
2286 tag.erase(0, name.size());
2287 wiretracksfactory->AddEntry(tag.c_str(), i+1);
2288 if(tag==default_track){
2289 wiretracksfactory->Select(i, kTRUE);
2290 wiretracksfactory->GetTextEntry()->SetText(tag.c_str());
2291 }
2292 }
2293}
2294
2295//-------------------
2296// SetTimeBasedTrackFactories
2297//-------------------
2298void hdv_mainframe::SetTimeBasedTrackFactories(vector<string> &facnames)
2299{
2300 /// Filter out the factories that provide "DTrackTimeBased" objects
2301 /// and add their tags to the timetracksfactory combobox.
2302
2303 // Erase all current entries in the combobox and add back in
2304 // "<default>".
2305 timetracksfactory->RemoveAll();
2306 timetracksfactory->AddEntry("<default>", 0);
2307 timetracksfactory->GetTextEntry()->SetText("<default>");
2308 timetracksfactory->Select(0, kFALSE);
2309
2310 for(unsigned int i=0; i< facnames.size(); i++){
2311 string name = "DTrackTimeBased:";
2312 string::size_type pos = facnames[i].find(name);
2313 if(pos==string::npos)continue;
2314 string tag = facnames[i];
2315 tag.erase(0, name.size());
2316 timetracksfactory->AddEntry(tag.c_str(), i+1);
2317 if(tag==default_track){
2318 timetracksfactory->Select(i, kTRUE);
2319 timetracksfactory->GetTextEntry()->SetText(tag.c_str());
2320 }
2321 }
2322}
2323
2324//-------------------
2325// SetChargedTrackFactories
2326//-------------------
2327void hdv_mainframe::SetChargedTrackFactories(vector<string> &facnames)
2328{
2329 /// Filter out the factories that provide "DChargedTrack" objects
2330 /// and add their tags to the chargedtracksfactory combobox.
2331
2332 // Erase all current entries in the combobox and add back in
2333 // "<default>".
2334 chargedtracksfactory->RemoveAll();
2335 chargedtracksfactory->AddEntry("<default>", 0);
2336 chargedtracksfactory->GetTextEntry()->SetText("<default>");
2337 chargedtracksfactory->Select(0, kFALSE);
2338
2339 for(unsigned int i=0; i< facnames.size(); i++){
2340 string name = "DChargedTrack:";
2341 string::size_type pos = facnames[i].find(name);
2342 if(pos==string::npos)continue;
2343 string tag = facnames[i];
2344 tag.erase(0, name.size());
2345 chargedtracksfactory->AddEntry(tag.c_str(), i+1);
2346 if(tag==default_track){
2347 chargedtracksfactory->Select(i, kTRUE);
2348 chargedtracksfactory->GetTextEntry()->SetText(tag.c_str());
2349 }
2350 }
2351}
2352
2353
2354
2355//-------------------
2356// SetReconstructedFactories
2357//-------------------
2358void hdv_mainframe::SetReconstructedFactories(vector<string> &facnames)
2359{
2360 /// Filter out the factories that provide "DTrack" objects
2361 /// and add them to the reconfactory combobox.
2362
2363 // Erase all current entries in the combobox and add back in
2364 // "<default>".
2365 int id =0;
2366 reconfactory->RemoveAll();
2367 reconfactory->AddEntry("DTrackTimeBased:", id++);
2368 reconfactory->Select(0, kFALSE);
2369 reconfactory->GetTextEntry()->SetText("DTrackTimeBased:");
2370
2371 // Add DTrackTimeBased factories
2372 for(unsigned int i=0; i< facnames.size(); i++){
2373 string name = "DTrackTimeBased:";
2374 string::size_type pos = facnames[i].find(name);
2375 if(pos==string::npos)continue;
2376 string tag = facnames[i].substr(name.size(), facnames[i].size()-name.size());
2377 reconfactory->AddEntry(facnames[i].c_str(), id++);
2378 if(facnames[i]==default_reconstructed){
2379 reconfactory->Select(id-1, kTRUE);
2380 reconfactory->GetTextEntry()->SetText(facnames[i].c_str());
2381 }
2382 }
2383
2384 // Add DTrackWireBased factories
2385 reconfactory->AddEntry("DTrackWireBased:", id++);
2386 for(unsigned int i=0; i< facnames.size(); i++){
2387 string name = "DTrackWireBased:";
2388 string::size_type pos = facnames[i].find(name);
2389 if(pos==string::npos)continue;
2390 string tag = facnames[i].substr(name.size(), facnames[i].size()-name.size());
2391 reconfactory->AddEntry(facnames[i].c_str(), id++);
2392 if(facnames[i]==default_reconstructed){
2393 reconfactory->Select(id-1, kTRUE);
2394 reconfactory->GetTextEntry()->SetText(facnames[i].c_str());
2395 }
2396 }
2397
2398 // Add DTrackCandidate factories
2399 reconfactory->AddEntry("DTrackCandidate:", id++);
2400 for(unsigned int i=0; i< facnames.size(); i++){
2401 string name = "DTrackCandidate:";
2402 string::size_type pos = facnames[i].find(name);
2403 if(pos==string::npos)continue;
2404 string tag = facnames[i].substr(name.size(), facnames[i].size()-name.size());
2405 reconfactory->AddEntry(facnames[i].c_str(), id++);
2406 if(facnames[i]==default_reconstructed){
2407 reconfactory->Select(id-1, kTRUE);
2408 reconfactory->GetTextEntry()->SetText(facnames[i].c_str());
2409 }
2410 }
2411
2412
2413 // Add DNeutralTrack factories
2414 reconfactory->AddEntry("DNeutralParticle:", id++);
2415 for(unsigned int i=0; i< facnames.size(); i++){
2416 string name = "DNeutralParticle:";
2417 string::size_type pos = facnames[i].find(name);
2418 if(pos==string::npos)continue;
2419 string tag = facnames[i].substr(name.size(), facnames[i].size()-name.size());
2420 reconfactory->AddEntry(facnames[i].c_str(), id++);
2421 if(facnames[i]==default_reconstructed){
2422 reconfactory->Select(id-1, kTRUE);
2423 reconfactory->GetTextEntry()->SetText(facnames[i].c_str());
2424 }
2425 }
2426
2427 // Add DChargedTrack factories
2428 reconfactory->AddEntry("DChargedTrack:", id++);
2429 for(unsigned int i=0; i< facnames.size(); i++){
2430 string name = "DChargedTrack:";
2431 string::size_type pos = facnames[i].find(name);
2432 if(pos==string::npos)continue;
2433 string tag = facnames[i].substr(name.size(), facnames[i].size()-name.size());
2434 reconfactory->AddEntry(facnames[i].c_str(), id++);
2435 if(facnames[i]==default_reconstructed){
2436 reconfactory->Select(id-1, kTRUE);
2437 reconfactory->GetTextEntry()->SetText(facnames[i].c_str());
2438 }
2439 }
2440
2441
2442}
2443
2444//-------------------
2445// GetCheckButton
2446//-------------------
2447bool hdv_mainframe::GetCheckButton(string who)
2448{
2449 map<string, TGCheckButton*>::iterator iter = checkbuttons.find(who);
2450 if(iter==checkbuttons.end())return false;
2451 return iter->second->GetState()==kButtonDown;
2452}
2453//-------------------
2454// AddCheckButtons
2455//-------------------
2456void hdv_mainframe::AddCheckButtons(map<string, TGCheckButton*> &checkbuttons)
2457{
2458 this->checkbuttons.insert(checkbuttons.begin(), checkbuttons.end());
2459}
2460
2461//-------------------
2462// GetFactoryTag
2463//-------------------
2464const char* hdv_mainframe::GetFactoryTag(string who)
2465{
2466 const char *tag = "";
2467
2468 if(who=="DTrackWireBased"){
2469 tag = wiretracksfactory->GetTextEntry()->GetTitle();
2470 //tag = wiretracksfactory->GetSelectedEntry()->GetTitle();
2471 }
2472 if(who=="DTrackCandidate"){
2473 tag = candidatesfactory->GetTextEntry()->GetTitle();
2474 //tag = candidatesfactory->GetSelectedEntry()->GetTitle();
2475 }
2476 if(who=="DTrackTimeBased"){
2477 tag = timetracksfactory->GetTextEntry()->GetTitle();
2478 //tag = timetracksfactory->GetSelectedEntry()->GetTitle();
2479 }
2480 if (who=="DChargedTrack"){
2481 tag=chargedtracksfactory->GetTextEntry()->GetTitle();
2482 }
2483 if(string(tag) == "<default>")tag = "";
2484
2485 return tag;
2486}
2487
2488//-------------------
2489// GetReconFactory
2490//-------------------
2491void hdv_mainframe::GetReconFactory(string &name, string &tag)
2492{
2493 if(!reconfactory) return;
2494 if(!reconfactory->GetSelectedEntry()) return;
2495 if(!reconfactory->GetSelectedEntry()->GetTitle()) return;
2496 string nametag(reconfactory->GetSelectedEntry()->GetTitle());
2497 string::size_type pos = nametag.find(":");
2498 name = nametag.substr(0, pos);
2499 tag = nametag.substr(pos+1, nametag.size()-(pos+1));
2500}
2501
2502//-------------------
2503// GetFCALPolyLine
2504//-------------------
2505TPolyLine* hdv_mainframe::GetFCALPolyLine(int channel)
2506{
2507 map<int, TPolyLine*>::iterator iter = fcalblocks.find(channel);
2508 if(iter==fcalblocks.end())return NULL__null;
2509 return iter->second;
2510}
2511
2512//-------------------
2513// GetFCALPolyLine
2514//-------------------
2515TPolyLine* hdv_mainframe::GetFCALPolyLine(int row, int column)
2516{
2517 if(!fcalgeom)return NULL__null;
2518 return GetFCALPolyLine(fcalgeom->channel(row, column));
2519}
2520
2521//-------------------
2522// GetCCALPolyLine
2523//-------------------
2524TPolyLine* hdv_mainframe::GetCCALPolyLine(int row, int col)
2525{
2526 int channel = col + 12*(row);
2527 map<int, TPolyLine*>::iterator iter = ccalblocks.find(channel);
2528 if(iter==ccalblocks.end())return NULL__null;
2529 return iter->second;
2530}
2531
2532//-------------------
2533// GetTOFPolyLine
2534//-------------------
2535
2536TPolyLine* hdv_mainframe::GetTOFPolyLine(int translate_side, int tof_ch)
2537{
2538 map <int, map<int, TPolyLine*> >::iterator iter;
2539 iter = tofblocks.find(translate_side);
2540 map <int, TPolyLine*>::iterator iter2 = iter->second.find(tof_ch);
2541 if(iter2==iter->second.end())return NULL__null;
2542 return iter2->second;
2543}
2544
2545//-------------------
2546// GetBCALPolyLine
2547//-------------------
2548TPolyLine* hdv_mainframe::GetBCALPolyLine(int module, int layer, int sector)
2549{
2550 int chan = module*1000 + layer*100 + sector*10;
2551 map<int, TPolyLine*>::iterator iter = bcalblocks.find(chan);
2552 if(iter==bcalblocks.end()){
2553 _DBG_std::cerr<<"programs/Analysis/hdview2/hdv_mainframe.cc"
<<":"<<2553<<" "
<<"ERROR: No BCAL readout segment display poly for module="<<module<<" layer="<<layer<<" sector="<<sector<<endl;
2554 return NULL__null;
2555 }
2556 return iter->second;
2557}
2558
2559//-------------------
2560// AddGraphicsSideA
2561//-------------------
2562void hdv_mainframe::AddGraphicsSideA(vector<TObject*> &v)
2563{
2564 for(unsigned int i=0; i<v.size(); i++)graphics_sideA.push_back(v[i]);
2565}
2566
2567//-------------------
2568// AddGraphicsSideB
2569//-------------------
2570void hdv_mainframe::AddGraphicsSideB(vector<TObject*> &v)
2571{
2572 for(unsigned int i=0; i<v.size(); i++)graphics_sideB.push_back(v[i]);
2573}
2574
2575//-------------------
2576// AddGraphicsEndA
2577//-------------------
2578void hdv_mainframe::AddGraphicsEndA(vector<TObject*> &v)
2579{
2580 for(unsigned int i=0; i<v.size(); i++)graphics_endA.push_back(v[i]);
2581}
2582
2583//-------------------
2584// AddGraphicsEndB
2585//-------------------
2586void hdv_mainframe::AddGraphicsEndB(vector<TObject*> &v)
2587{
2588 for(unsigned int i=0; i<v.size(); i++)graphics_endB.push_back(v[i]);
2589}

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