File: | programs/Analysis/hdview2/trk_mainframe.cc |
Location: | line 393, column 16 |
Description: | Called C++ object pointer is null |
1 | // $Id$ | |||
2 | // | |||
3 | // File: trk_mainframe.cc | |||
4 | // Created: Wed Apr 9 08:11:16 EDT 2008 | |||
5 | // Creator: davidl (on Darwin Amelia.local 8.11.1 i386) | |||
6 | // | |||
7 | ||||
8 | using namespace std; | |||
9 | ||||
10 | #include "trk_mainframe.h" | |||
11 | #include "hdv_mainframe.h" | |||
12 | #include "hdview2.h" | |||
13 | #include "MyProcessor.h" | |||
14 | ||||
15 | #include <CDC/DCDCWire.h> | |||
16 | #include <CDC/DCDCTrackHit.h> | |||
17 | ||||
18 | #include <TGButtonGroup.h> | |||
19 | #include <TGTextEntry.h> | |||
20 | #include <TArrow.h> | |||
21 | #include <TLatex.h> | |||
22 | #include <TGaxis.h> | |||
23 | #include <TColor.h> | |||
24 | #include <TROOT.h> | |||
25 | #include <TF1.h> | |||
26 | ||||
27 | // We declare this as a global since putting it in the class would | |||
28 | // require defining the DReferenceTrajectory class to ROOT | |||
29 | static vector<DReferenceTrajectory*> REFTRAJ; | |||
30 | ||||
31 | // Ditto | |||
32 | static vector<pair<const DCoordinateSystem*,double> > TRACKHITS; | |||
33 | static map<const DCoordinateSystem*,double> S_VALS; | |||
34 | ||||
35 | ||||
36 | int colors[]={kBlue, kRed, kMagenta, kGreen, kCyan}; | |||
37 | int ncolors=5; | |||
38 | ||||
39 | ||||
40 | //--------------------------------- | |||
41 | // trk_mainframe (Constructor) | |||
42 | //--------------------------------- | |||
43 | trk_mainframe::trk_mainframe(hdv_mainframe *hdvmf, const TGWindow *p, UInt_t w, UInt_t h):TGMainFrame(p,w,h) | |||
44 | { | |||
45 | this->hdvmf = hdvmf; | |||
46 | ||||
47 | TGLayoutHints *lhints = new TGLayoutHints(kLHintsNormal, 2,2,2,2); | |||
48 | TGLayoutHints *bhints = new TGLayoutHints(kLHintsBottom|kLHintsCenterX, 2,2,2,2); | |||
49 | TGLayoutHints *bbhints = new TGLayoutHints(kLHintsTop, 2,2, -8,-8); | |||
50 | TGLayoutHints *thints = new TGLayoutHints(kLHintsTop|kLHintsCenterX, 2,2,2,2); | |||
51 | TGLayoutHints *ahints = new TGLayoutHints(kLHintsLeft|kLHintsTop, 2,2,2,2); | |||
52 | TGLayoutHints *xhints = new TGLayoutHints(kLHintsNormal|kLHintsExpandX, 2,2,2,2); | |||
53 | //TGLayoutHints *rhints = new TGLayoutHints(kLHintsRight, 2,2,2,2); | |||
54 | TGLayoutHints *dhints = new TGLayoutHints(kLHintsExpandY|kLHintsCenterY, 2,2,2,2); | |||
55 | TGLayoutHints *ehints = new TGLayoutHints(kLHintsCenterY, 2,2,2,2); | |||
56 | ||||
57 | TGHorizontalFrame *mainframe = new TGHorizontalFrame(this); | |||
58 | AddFrame(mainframe, ahints); | |||
59 | ||||
60 | //------- Left side | |||
61 | TGHorizontalFrame *leftframe = new TGHorizontalFrame(mainframe); | |||
62 | mainframe->AddFrame(leftframe, ahints); | |||
63 | ||||
64 | //------- Canvas + histo | |||
65 | TGVerticalFrame *canvasframe = new TGVerticalFrame(leftframe); | |||
66 | leftframe->AddFrame(canvasframe, bhints); | |||
67 | ||||
68 | int width=325; | |||
69 | canvas = new TRootEmbeddedCanvas("Track Canvas", canvasframe, width, (UInt_t)(2.0*width), kSunkenFrame, GetWhitePixel()); | |||
70 | canvasframe->AddFrame(canvas, lhints); | |||
71 | canvas->SetScrolling(TGCanvas::kCanvasScrollBoth); | |||
72 | ||||
73 | slo = -10.0; | |||
74 | //shi = 437.0; | |||
75 | shi = 100.0; | |||
76 | resilo = -1000; | |||
77 | resihi = +1000; | |||
78 | canvas->GetCanvas()->cd(); | |||
79 | canvas->GetCanvas()->Range(resilo, slo, resihi, shi); | |||
80 | ||||
81 | histocanvas = new TRootEmbeddedCanvas("Histo Canvas", canvasframe, width, (UInt_t)(width/5.0), kSunkenFrame, GetWhitePixel()); | |||
82 | canvasframe->AddFrame(histocanvas, lhints); | |||
83 | histocanvas->SetScrolling(TGCanvas::kCanvasScrollBoth); | |||
84 | ||||
85 | gPad(TVirtualPad::Pad())->SetGridy(); | |||
86 | gPad(TVirtualPad::Pad())->SetTicky(); | |||
87 | gPad(TVirtualPad::Pad())->SetTickx(); | |||
88 | gPad(TVirtualPad::Pad())->SetLeftMargin(0); | |||
89 | gPad(TVirtualPad::Pad())->SetRightMargin(0); | |||
90 | gPad(TVirtualPad::Pad())->SetTopMargin(0); | |||
91 | resi = new TH1D("resi", "", 30, -0.1, 0.1); | |||
92 | resi->SetStats(0); | |||
93 | resi->SetFillStyle(3002); | |||
94 | resi->SetFillColor(kMagenta); | |||
95 | resi->Draw(); | |||
96 | ||||
97 | resi_lab = new TLatex(resihi-0.25*(resihi-resilo), 0.5, "#sigma=?#mum"); | |||
98 | resi_lab->SetTextSize(0.02); | |||
99 | resi_lab->SetTextAlign(32); | |||
100 | resi_lab->Draw(); | |||
101 | ||||
102 | //------- Hits radio buttons | |||
103 | TGVButtonGroup *hitsbuttons = new TGVButtonGroup(leftframe, "Hit"); | |||
104 | leftframe->AddFrame(hitsbuttons, thints); | |||
105 | for(int i=34; i>=0; i--){ | |||
106 | char title[256]; | |||
107 | sprintf(title, "%2d", i); | |||
108 | TGRadioButton *but = new TGRadioButton(hitsbuttons, title); | |||
109 | hitsbuttons->AddFrame(but, bbhints); | |||
110 | } | |||
111 | ||||
112 | //------- Right side | |||
113 | TGVerticalFrame *rightframe = new TGVerticalFrame(mainframe); | |||
114 | mainframe->AddFrame(rightframe, ahints); | |||
115 | ||||
116 | //------- Controls | |||
117 | TGGroupFrame *controlsframe = new TGGroupFrame(rightframe, "Controls", kHorizontalFrame); | |||
118 | rightframe->AddFrame(controlsframe, xhints); | |||
119 | ||||
120 | //-------- Pan, Zoom, Reset | |||
121 | TGVerticalFrame *panzoomresetframe = new TGVerticalFrame(controlsframe); | |||
122 | controlsframe->AddFrame(panzoomresetframe, lhints); | |||
123 | TGHorizontalFrame *panzoomframe = new TGHorizontalFrame(panzoomresetframe); | |||
124 | panzoomresetframe->AddFrame(panzoomframe, lhints); | |||
125 | ||||
126 | //------- Pan | |||
127 | TGGroupFrame *panframe = new TGGroupFrame(panzoomframe, "Pan", kHorizontalFrame); | |||
128 | panzoomframe->AddFrame(panframe, dhints); | |||
129 | TGTextButton *panleft = new TGTextButton(panframe, "<"); | |||
130 | TGVerticalFrame *updownframe = new TGVerticalFrame(panframe); | |||
131 | TGTextButton *panup = new TGTextButton(updownframe, "^"); | |||
132 | TGTextButton *pandown = new TGTextButton(updownframe, "v"); | |||
133 | updownframe->AddFrame(panup, dhints); | |||
134 | updownframe->AddFrame(pandown, dhints); | |||
135 | TGTextButton *panright = new TGTextButton(panframe, ">"); | |||
136 | panframe->AddFrame(panleft, ehints); | |||
137 | panframe->AddFrame(updownframe, dhints); | |||
138 | panframe->AddFrame(panright, ehints); | |||
139 | ||||
140 | //------- Zoom | |||
141 | TGGroupFrame *zoomframe = new TGGroupFrame(panzoomframe, "Zoom", kVerticalFrame); | |||
142 | panzoomframe->AddFrame(zoomframe, lhints); | |||
143 | TGTextButton *zoomin = new TGTextButton(zoomframe, " + "); | |||
144 | TGTextButton *zoomout = new TGTextButton(zoomframe, " - "); | |||
145 | zoomframe->AddFrame(zoomin, lhints); | |||
146 | zoomframe->AddFrame(zoomout, lhints); | |||
147 | ||||
148 | TGTextButton *reset = new TGTextButton(panzoomresetframe, "reset"); | |||
149 | panzoomresetframe->AddFrame(reset, xhints); | |||
150 | ||||
151 | slock = new TGCheckButton(panzoomresetframe,"lock s-axis"); | |||
152 | panzoomresetframe->AddFrame(slock, xhints); | |||
153 | slock->Connect("Clicked()","trk_mainframe", this, "DoMyRedraw()"); | |||
154 | ||||
155 | //-------- Event, Info frame | |||
156 | TGVerticalFrame *eventinfoframe = new TGVerticalFrame(controlsframe); | |||
157 | controlsframe->AddFrame(eventinfoframe, thints); | |||
158 | ||||
159 | //-------- Next, Previous | |||
160 | TGGroupFrame *prevnextframe = new TGGroupFrame(eventinfoframe, "Event", kHorizontalFrame); | |||
161 | eventinfoframe->AddFrame(prevnextframe, thints); | |||
162 | TGTextButton *prev = new TGTextButton(prevnextframe, "<-- Prev"); | |||
163 | TGTextButton *next = new TGTextButton(prevnextframe, "Next -->"); | |||
164 | prevnextframe->AddFrame(prev, lhints); | |||
165 | prevnextframe->AddFrame(next, lhints); | |||
166 | ||||
167 | next->Connect("Clicked()","hdv_mainframe", hdvmf, "DoNext()"); | |||
168 | prev->Connect("Clicked()","hdv_mainframe", hdvmf, "DoPrev()"); | |||
169 | next->Connect("Clicked()","trk_mainframe", this, "DoNewEvent()"); | |||
170 | prev->Connect("Clicked()","trk_mainframe", this, "DoNewEvent()"); | |||
171 | ||||
172 | //-------- Info | |||
173 | TGGroupFrame *infoframe = new TGGroupFrame(eventinfoframe, "Info", kVerticalFrame); | |||
174 | eventinfoframe->AddFrame(infoframe, thints); | |||
175 | ||||
176 | //------- Tracks to plot | |||
177 | for(int i=0; i<4; i++){ | |||
178 | char title[256]; | |||
179 | sprintf(title,"Track %d%s", i+1, i==0 ? " (s-axis source)":""); | |||
180 | TGGroupFrame *trackframe = new TGGroupFrame(rightframe, title, kHorizontalFrame); | |||
181 | rightframe->AddFrame(trackframe, xhints); | |||
182 | ||||
183 | //------ Color | |||
184 | TGLabel *lab = new TGLabel(trackframe," "); | |||
185 | trackframe->AddFrame(lab, dhints); | |||
186 | lab->SetBackgroundColor(gROOT->GetColor(colors[i%ncolors])->GetPixel()); | |||
187 | ||||
188 | //------ Data type | |||
189 | TGVerticalFrame *datatypeframe = new TGVerticalFrame(trackframe); | |||
190 | trackframe->AddFrame(datatypeframe, thints); | |||
191 | ||||
192 | TGLabel *datatypelab = new TGLabel(datatypeframe, "Data type:"); | |||
193 | datatypeframe->AddFrame(datatypelab, lhints); | |||
194 | ||||
195 | TGComboBox *datatype = new TGComboBox(datatypeframe, "DTrackCandidate", i); | |||
196 | datatypeframe->AddFrame(datatype, lhints); | |||
197 | this->datatype.push_back(datatype); | |||
198 | datatype->Resize(120,20); | |||
199 | datatype->SetUniqueID(i); | |||
200 | FillDataTypeComboBox(datatype, i==0 ? "DTrackTimeBased":"<none>"); | |||
201 | ||||
202 | datatype->Connect("Selected(Int_t, Int_t)","trk_mainframe", this, "DoTagMenuUpdate(Int_t, Int_t)"); | |||
203 | datatype->Connect("Selected(Int_t)","trk_mainframe", this, "DoRequestFocus(Int_t)"); | |||
204 | ||||
205 | //------ Factory tag | |||
206 | TGVerticalFrame *factorytagframe = new TGVerticalFrame(trackframe); | |||
207 | trackframe->AddFrame(factorytagframe, thints); | |||
208 | ||||
209 | TGLabel *factorytaglab = new TGLabel(factorytagframe, "Factory Tag:"); | |||
210 | factorytagframe->AddFrame(factorytaglab, lhints); | |||
211 | ||||
212 | TGComboBox *factorytag = new TGComboBox(factorytagframe, "<default>", i); | |||
213 | factorytagframe->AddFrame(factorytag, lhints); | |||
214 | this->factorytag.push_back(factorytag); | |||
215 | factorytag->Resize(100,20); | |||
216 | factorytag->SetUniqueID(i); | |||
217 | FillFactoryTagComboBox(factorytag, datatype, i==0 ? "ALT1":"<default>"); | |||
218 | ||||
219 | factorytag->Connect("Selected(Int_t, Int_t)","trk_mainframe", this, "DoTrackNumberMenuUpdate(Int_t, Int_t)"); | |||
220 | factorytag->Connect("Selected(Int_t)","trk_mainframe", this, "DoRequestFocus(Int_t)"); | |||
221 | ||||
222 | //------ Track Number | |||
223 | TGVerticalFrame *tracknoframe = new TGVerticalFrame(trackframe); | |||
224 | trackframe->AddFrame(tracknoframe, thints); | |||
225 | ||||
226 | TGLabel *tracknolab = new TGLabel(tracknoframe, "Track:"); | |||
227 | tracknoframe->AddFrame(tracknolab, lhints); | |||
228 | ||||
229 | TGComboBox *trackno = new TGComboBox(tracknoframe, i==0 ? "0":"", 0); | |||
230 | tracknoframe->AddFrame(trackno, lhints); | |||
231 | this->trackno.push_back(trackno); | |||
232 | trackno->Resize(85, 20); | |||
233 | trackno->SetUniqueID(i); | |||
234 | ||||
235 | trackno->Connect("Selected(Int_t)","trk_mainframe", this, "DoRequestFocus(Int_t)"); | |||
236 | trackno->Connect("Selected(Int_t)","trk_mainframe", this, "DoMyRedraw()"); | |||
237 | } | |||
238 | ||||
239 | ||||
240 | //------- Track Info | |||
241 | TGGroupFrame *trackinfoframe = new TGGroupFrame(rightframe, "Track Info", kVerticalFrame); | |||
242 | rightframe->AddFrame(trackinfoframe, xhints); | |||
243 | ||||
244 | //------- Hit Info | |||
245 | TGGroupFrame *hitinfoframe = new TGGroupFrame(rightframe, "Hit Info", kVerticalFrame); | |||
246 | rightframe->AddFrame(hitinfoframe, xhints); | |||
247 | ||||
248 | ||||
249 | // Finish up and map the window | |||
250 | SetWindowName("Hall-D Event Viewer:Track Inspector"); | |||
251 | SetIconName("HDView:TrackInspector"); | |||
252 | MapSubwindows(); | |||
253 | Resize(GetDefaultSize()); | |||
254 | MapWindow(); | |||
255 | ||||
256 | RequestFocus(); | |||
257 | ||||
258 | DoNewEvent(); | |||
259 | } | |||
260 | ||||
261 | //--------------------------------- | |||
262 | // ~trk_mainframe (Destructor) | |||
263 | //--------------------------------- | |||
264 | trk_mainframe::~trk_mainframe() | |||
265 | { | |||
266 | hdvmf->DoClearTrackInspectorPointer(); | |||
267 | } | |||
268 | ||||
269 | //--------------------------------- | |||
270 | // DoNewEvent | |||
271 | //--------------------------------- | |||
272 | void trk_mainframe::DoNewEvent(void) | |||
273 | { | |||
274 | DoUpdateMenus(); | |||
275 | DoMyRedraw(); | |||
276 | } | |||
277 | ||||
278 | //--------------------------------- | |||
279 | // DoMyRedraw | |||
280 | //--------------------------------- | |||
281 | void trk_mainframe::DoMyRedraw(void) | |||
282 | { | |||
283 | // Delete any existing graphics objects | |||
284 | for(unsigned int i=0; i<graphics.size(); i++)delete graphics[i]; | |||
285 | graphics.clear(); | |||
286 | ||||
287 | // Draw hits on main canvas | |||
288 | DrawHits(graphics); | |||
289 | ||||
290 | // Draw axes and scales | |||
291 | double smargin = 0.10*(shi-slo); | |||
292 | shi+=smargin; | |||
293 | slo-=smargin; | |||
294 | resihi = (shi-slo)/5.0/4.0; | |||
295 | resihi = 2.0; | |||
296 | resilo = -resihi; | |||
297 | canvas->GetCanvas()->cd(); | |||
298 | canvas->GetCanvas()->Range(resilo, slo, resihi, shi); | |||
299 | DrawAxes(canvas->GetCanvas(), graphics, "wire pos(cm)", "s(cm)"); | |||
300 | ||||
301 | // Draw everything | |||
302 | canvas->GetCanvas()->cd(0); | |||
303 | for(unsigned int i=0; i<graphics.size(); i++)graphics[i]->Draw(); | |||
304 | canvas->GetCanvas()->Update(); | |||
305 | ||||
306 | // Update the histogram | |||
307 | histocanvas->GetCanvas()->cd(); | |||
308 | resi->Fit("gaus","Q"); | |||
309 | double sigma = resi->GetFunction("gaus")->GetParameter(2); | |||
310 | ||||
311 | // Update label (this doesn't work, but may be only a tweak away!) | |||
312 | char title[256]; | |||
313 | sprintf(title, "#sigma=%3.0f#mum",sigma*1.0E4); | |||
314 | _DBG_std::cerr<<"trk_mainframe.cc"<<":"<<314<< " "<<title<<endl; | |||
315 | resi_lab->SetText(resi->GetXaxis()->GetXmax(), resi->GetMaximum()*0.5, title); | |||
316 | TVirtualPad *pad = gPad(TVirtualPad::Pad()); | |||
317 | histocanvas->GetCanvas()->cd(); | |||
318 | resi_lab->Draw(); | |||
319 | pad->cd(); | |||
320 | ||||
321 | histocanvas->GetCanvas()->Update(); | |||
322 | } | |||
323 | ||||
324 | //--------------------------------- | |||
325 | // DoHitSelect | |||
326 | //--------------------------------- | |||
327 | void trk_mainframe::DoHitSelect(void) | |||
328 | { | |||
329 | _DBG__std::cerr<<"trk_mainframe.cc"<<":"<<329<< std::endl; | |||
330 | ||||
331 | } | |||
332 | ||||
333 | //--------------------------------- | |||
334 | // DoUpdateMenus | |||
335 | //--------------------------------- | |||
336 | void trk_mainframe::DoUpdateMenus(void) | |||
337 | { | |||
338 | for(unsigned int i=0; i<factorytag.size(); i++){ | |||
339 | FillTrackNumberComboBox(trackno[i], datatype[i], factorytag[i], i!=0); | |||
340 | } | |||
341 | } | |||
342 | ||||
343 | //--------------------------------- | |||
344 | // DoTagMenuUpdate | |||
345 | //--------------------------------- | |||
346 | void trk_mainframe::DoTagMenuUpdate(Int_t widgetId, Int_t id) | |||
347 | { | |||
348 | if(widgetId>=0 && widgetId<(int)datatype.size()){ | |||
349 | FillFactoryTagComboBox(factorytag[widgetId], datatype[widgetId], factorytag[widgetId]->GetTextEntry()->GetText()); | |||
350 | factorytag[widgetId]->EmitVA("Selected(Int_t, Int_t)", 2, widgetId, id); | |||
351 | } | |||
352 | } | |||
353 | ||||
354 | //--------------------------------- | |||
355 | // DoTrackNumberMenuUpdate | |||
356 | //--------------------------------- | |||
357 | void trk_mainframe::DoTrackNumberMenuUpdate(Int_t widgetId, Int_t id) | |||
358 | { | |||
359 | if(widgetId>=0 && widgetId<(int)datatype.size()){ | |||
360 | FillTrackNumberComboBox(trackno[widgetId], datatype[widgetId], factorytag[widgetId], widgetId!=0); | |||
361 | DoMyRedraw(); | |||
362 | } | |||
363 | } | |||
364 | ||||
365 | //--------------------------------- | |||
366 | // DoRequestFocus | |||
367 | //--------------------------------- | |||
368 | void trk_mainframe::DoRequestFocus(Int_t id) | |||
369 | { | |||
370 | RequestFocus(); | |||
371 | } | |||
372 | ||||
373 | //--------------------------------- | |||
374 | // FillDataTypeComboBox | |||
375 | //--------------------------------- | |||
376 | void trk_mainframe::FillDataTypeComboBox(TGComboBox* cb, const string &def) | |||
377 | { | |||
378 | /// Ideally, this would feel out the factories whose | |||
379 | /// data types are based on DKinematicData. This is | |||
380 | /// not currently possbile with JANA though so we have | |||
381 | /// to simply add DTrackTimeBased, DTrackWireBased, DTrackCandidate, and DMCThrown | |||
382 | /// explicitly. | |||
383 | ||||
384 | vector<string> facnames; | |||
385 | if(def=="<none>")facnames.push_back(def); | |||
| ||||
386 | facnames.push_back("DTrackTimeBased"); | |||
387 | facnames.push_back("DTrackWireBased"); | |||
388 | facnames.push_back("DTrackCandidate"); | |||
389 | facnames.push_back("DMCThrown"); | |||
390 | ||||
391 | cb->RemoveAll(); | |||
392 | for(unsigned int i=0; i<facnames.size(); i++){ | |||
393 | cb->AddEntry(facnames[i].c_str(), i); | |||
| ||||
394 | if(def==facnames[i]){ | |||
395 | cb->Select(i, kTRUE); | |||
396 | cb->GetTextEntry()->SetText(def.c_str()); | |||
397 | } | |||
398 | } | |||
399 | } | |||
400 | ||||
401 | //--------------------------------- | |||
402 | // FillFactoryTagComboBox | |||
403 | //--------------------------------- | |||
404 | void trk_mainframe::FillFactoryTagComboBox(TGComboBox* cb, TGComboBox* datanamecb, const string &def) | |||
405 | { | |||
406 | /// Fill the given TGComboBox with the tags of the factories that | |||
407 | /// provide data of the type currently selected in the "datanamecb" | |||
408 | /// combo box. | |||
409 | ||||
410 | // Get the data type that is currently selected | |||
411 | string dataname = datanamecb->GetTextEntry()->GetText(); | |||
412 | ||||
413 | // Get list of all factories | |||
414 | vector<JFactory_base*> factories; | |||
415 | gMYPROC->GetFactories(factories); | |||
416 | ||||
417 | // Loop over all factories, looking for ones with the desired | |||
418 | // data name. Add thier tags to the list | |||
419 | vector<string> tags; | |||
420 | tags.push_back("<default>"); | |||
421 | for(unsigned int i=0; i<factories.size(); i++){ | |||
422 | if(dataname == factories[i]->GetDataClassName()){ | |||
423 | string tag = factories[i]->Tag(); | |||
424 | if(tag!="")tags.push_back(tag); | |||
425 | } | |||
426 | } | |||
427 | ||||
428 | cb->RemoveAll(); | |||
429 | for(unsigned int i=0; i<tags.size(); i++){ | |||
430 | cb->AddEntry(tags[i].c_str(), i); | |||
431 | if(def==tags[i] || (def=="" && tags[i]=="<default>")){ | |||
432 | cb->Select(i, kTRUE); | |||
433 | cb->GetTextEntry()->SetText(tags[i].c_str()); | |||
434 | } | |||
435 | } | |||
436 | ||||
437 | // If "<none>" is chosen for the data type then clear the | |||
438 | // displayed area to make it more obvious that it doesn't matter | |||
439 | if(dataname=="<none>"){ | |||
440 | cb->GetTextEntry()->SetText(""); | |||
441 | }else{ | |||
442 | string str = cb->GetTextEntry()->GetText(); | |||
443 | if(str=="")cb->GetTextEntry()->SetText("<default>"); | |||
444 | } | |||
445 | } | |||
446 | ||||
447 | //--------------------------------- | |||
448 | // FillTrackNumberComboBox | |||
449 | //--------------------------------- | |||
450 | void trk_mainframe::FillTrackNumberComboBox(TGComboBox* cb, TGComboBox* datanamecb, TGComboBox* tagcb, bool add_best_match_option) | |||
451 | { | |||
452 | /// Fill the given TGComboBox with the track numbers for the factory | |||
453 | /// currently selected in the "datanamecb" with the tag in the "tagcb" | |||
454 | /// combo boxes. | |||
455 | ||||
456 | // Get the data type and tag that are currently selected | |||
457 | string dataname = datanamecb->GetTextEntry()->GetText(); | |||
458 | string tag = tagcb->GetTextEntry()->GetText(); | |||
459 | ||||
460 | ||||
461 | // Get the number of rows for this factory for this event | |||
462 | int Nrows = gMYPROC->GetNrows(dataname, tag=="<default>" ? "":tag); | |||
463 | ||||
464 | // Get the currently selected value for the trackno | |||
465 | // so we can recycle it if possible. | |||
466 | string deftrackno = cb->GetTextEntry()->GetText(); | |||
467 | if(deftrackno=="")deftrackno="0"; | |||
468 | ||||
469 | // Add "Best Match" option if specified | |||
470 | cb->RemoveAll(); | |||
471 | if(add_best_match_option){ | |||
472 | cb->AddEntry("Best Match", 1001); | |||
473 | cb->Select(1001, kTRUE); | |||
474 | cb->GetTextEntry()->SetText("Best Match"); | |||
475 | } | |||
476 | ||||
477 | // Add track(row) numbers | |||
478 | for(int i=0; i<Nrows; i++){ | |||
479 | char str[256]; | |||
480 | sprintf(str, "%d", i); | |||
481 | cb->AddEntry(str, i); | |||
482 | if(deftrackno==str){ | |||
483 | cb->Select(i, kTRUE); | |||
484 | cb->GetTextEntry()->SetText(str); | |||
485 | } | |||
486 | } | |||
487 | ||||
488 | // If "<none>" is chosen for the data type then clear the | |||
489 | // displayed area to make it more obvious that it doesn't matter | |||
490 | if(dataname=="<none>" || Nrows==0){ | |||
491 | cb->GetTextEntry()->SetText(""); | |||
492 | } | |||
493 | } | |||
494 | ||||
495 | //------------------- | |||
496 | // DrawAxes | |||
497 | //------------------- | |||
498 | void trk_mainframe::DrawAxes(TCanvas *c, vector<TObject*> &graphics, const char *xlab, const char *ylab) | |||
499 | { | |||
500 | /// Create arrows indicating x and y axes with labels on the specified canvas | |||
501 | /// and add them to the specified container of graphics objects to be draw later. | |||
502 | double x1 = c->GetX1(); | |||
503 | double x2 = c->GetX2(); | |||
504 | double y1 = c->GetY1(); | |||
505 | double y2 = c->GetY2(); | |||
506 | double deltax = x2-x1; | |||
507 | //deltax *= c->GetYsizeReal()/c->GetXsizeReal(); | |||
508 | double deltay = y2-y1; | |||
509 | double xlo = x1+0.025*deltax; | |||
510 | double xhi = xlo + 0.06*deltax; | |||
511 | double ylo = y1+0.015*deltay; | |||
512 | double yhi = ylo + 0.03*deltay; | |||
513 | TArrow *yarrow = new TArrow(xlo, ylo, xlo, yhi, 0.02, ">"); | |||
514 | yarrow->SetLineWidth((Width_t)1.5); | |||
515 | graphics.push_back(yarrow); | |||
516 | ||||
517 | TLatex *ylabel = new TLatex(xlo, yhi+0.005*deltay, ylab); | |||
518 | ylabel->SetTextAlign(12); | |||
519 | ylabel->SetTextAngle(90.0); | |||
520 | ylabel->SetTextSize(0.04); | |||
521 | graphics.push_back(ylabel); | |||
522 | ||||
523 | TArrow *xarrow = new TArrow(xlo, ylo, xhi, ylo, 0.02, ">"); | |||
524 | xarrow->SetLineWidth((Width_t)1.5); | |||
525 | graphics.push_back(xarrow); | |||
526 | ||||
527 | TLatex *xlabel = new TLatex(xhi+0.005*deltax, ylo, xlab); | |||
528 | xlabel->SetTextAlign(12); | |||
529 | xlabel->SetTextSize(0.04); | |||
530 | graphics.push_back(xlabel); | |||
531 | ||||
532 | // Left axis (and grid lines) | |||
533 | xlo = x1+0.08*deltax; | |||
534 | ylo = y1+0.05*deltay; | |||
535 | yhi = y1+0.95*deltay; | |||
536 | TGaxis *axis = new TGaxis(xlo , ylo, xlo, yhi, ylo, yhi, 510, "-RW"); | |||
537 | graphics.push_back(axis); | |||
538 | ||||
539 | // Right axis | |||
540 | xhi = x1+0.95*deltax; | |||
541 | axis = new TGaxis(xhi , ylo, xhi, yhi, ylo, yhi, 510, "+-U"); | |||
542 | graphics.push_back(axis); | |||
543 | ||||
544 | // Top axis | |||
545 | axis = new TGaxis(xlo , yhi, xhi, yhi, xlo, xhi, 510, "-R"); | |||
546 | graphics.push_back(axis); | |||
547 | ||||
548 | // Bottom axis | |||
549 | axis = new TGaxis(xlo , ylo, xhi, ylo, xlo, xhi, 510, "+UW"); | |||
550 | graphics.push_back(axis); | |||
551 | axis = new TGaxis(xlo+0.2*deltax, ylo, xhi, ylo, xlo+0.2*deltax, xhi, 507, "+L"); | |||
552 | graphics.push_back(axis); | |||
553 | ||||
554 | // Center line | |||
555 | TLine *l = new TLine(0.0, ylo, 0.0, yhi); | |||
556 | graphics.push_back(l); | |||
557 | } | |||
558 | ||||
559 | //------------------- | |||
560 | // DrawHits | |||
561 | //------------------- | |||
562 | void trk_mainframe::DrawHits(vector<TObject*> &graphics) | |||
563 | { | |||
564 | // Find the factory name, tag, and track number for the prime track | |||
565 | string dataname = datatype[0]->GetTextEntry()->GetText(); | |||
566 | string tag = factorytag[0]->GetTextEntry()->GetText(); | |||
567 | string track = trackno[0]->GetTextEntry()->GetText(); | |||
568 | ||||
569 | // Reset residual histogram | |||
570 | this->resi->Reset(); | |||
571 | ||||
572 | if(track==""){_DBG_std::cerr<<"trk_mainframe.cc"<<":"<<572<< " "<<"No prime tracks!"<<endl;return;} | |||
573 | if(tag=="<default>")tag=""; | |||
574 | unsigned int index = atoi(track.c_str()); | |||
575 | ||||
576 | // Clear out any existing reference trajectories | |||
577 | for(unsigned int i=0; i<REFTRAJ.size(); i++)delete REFTRAJ[i]; | |||
578 | REFTRAJ.clear(); | |||
579 | ||||
580 | // Get the reference trajectory for the prime track | |||
581 | DReferenceTrajectory *rt=NULL__null; | |||
582 | vector<const DCDCTrackHit*> cdctrackhits; | |||
583 | gMYPROC->GetDReferenceTrajectory(dataname, tag, index, rt, cdctrackhits); | |||
584 | if(rt==NULL__null){ | |||
585 | _DBG_std::cerr<<"trk_mainframe.cc"<<":"<<585<< " "<<"Reference trajectory unavailable for "<<dataname<<":"<<tag<<" #"<<index<<endl; | |||
586 | return; | |||
587 | } | |||
588 | ||||
589 | REFTRAJ.push_back(rt); | |||
590 | ||||
591 | // Get a list of ALL wire hits for this event | |||
592 | vector<pair<const DCoordinateSystem*,double> > allhits; | |||
593 | gMYPROC->GetAllWireHits(allhits); | |||
594 | ||||
595 | // Draw prime track | |||
596 | DrawHitsForOneTrack(graphics, allhits, rt, 0, cdctrackhits); | |||
597 | ||||
598 | // Draw other tracks | |||
599 | for(unsigned int i=1; i<datatype.size(); i++){ | |||
600 | dataname = datatype[i]->GetTextEntry()->GetText(); | |||
601 | tag = factorytag[i]->GetTextEntry()->GetText(); | |||
602 | track = trackno[i]->GetTextEntry()->GetText(); | |||
603 | if(track=="")continue; | |||
604 | if(tag=="<default>")tag=""; | |||
605 | unsigned int index = atoi(track.c_str()); | |||
606 | if(track=="Best Match"){ | |||
607 | // Need to implement algorithm to find the best match | |||
608 | index=0; | |||
609 | } | |||
610 | ||||
611 | // Get reference trajectory for this track | |||
612 | DReferenceTrajectory *myrt=NULL__null; | |||
613 | gMYPROC->GetDReferenceTrajectory(dataname, tag, index, myrt, cdctrackhits); | |||
614 | if(myrt){ | |||
615 | REFTRAJ.push_back(myrt); | |||
616 | DrawHitsForOneTrack(graphics, allhits, myrt, i, cdctrackhits); | |||
617 | } | |||
618 | } | |||
619 | } | |||
620 | ||||
621 | //------------------- | |||
622 | // DrawHitsForOneTrack | |||
623 | //------------------- | |||
624 | void trk_mainframe::DrawHitsForOneTrack( | |||
625 | vector<TObject*> &graphics, | |||
626 | vector<pair<const DCoordinateSystem*,double> > &allhits, | |||
627 | DReferenceTrajectory *rt, | |||
628 | int index, | |||
629 | vector<const DCDCTrackHit*> &cdctrackhits) | |||
630 | { | |||
631 | // Clear current hits list | |||
632 | if(index==0){ | |||
633 | TRACKHITS.clear(); | |||
634 | S_VALS.clear(); | |||
635 | slo = shi = 20.0; | |||
636 | } | |||
637 | ||||
638 | // Get state of s-lock checkbutton | |||
639 | bool lock_s_coordinate = slock->GetState(); | |||
640 | ||||
641 | vector<pair<const DCoordinateSystem*,double> > &hits = index==0 ? allhits:TRACKHITS; | |||
642 | ||||
643 | // Loop over all hits and create graphics objects for each | |||
644 | for(unsigned int i=0; i<hits.size(); i++){ | |||
645 | const DCoordinateSystem *wire = hits[i].first; | |||
646 | double dist = hits[i].second; | |||
647 | DVector3 pos_doca, mom_doca; | |||
648 | double s; | |||
649 | if(wire==NULL__null){_DBG_std::cerr<<"trk_mainframe.cc"<<":"<<649<< " "<<"wire==NULL!!"<<endl; continue;} | |||
650 | if(rt==NULL__null){_DBG_std::cerr<<"trk_mainframe.cc"<<":"<<650<< " "<<"rt==NULL!!"<<endl; continue;} | |||
651 | double doca = rt->DistToRT(wire, &s); | |||
652 | rt->GetLastDOCAPoint(pos_doca, mom_doca); | |||
653 | DVector3 shift = wire->udir.Cross(mom_doca); | |||
654 | ||||
655 | // The magnitude of "dist" is based on the drift time | |||
656 | // which does not yet subtract out the TOF. This can add | |||
657 | // 50-100 microns to the resolution. | |||
658 | // | |||
659 | // What is really needed here is to try different hypotheses | |||
660 | // as to the particle type. For now, we just assume its a pion | |||
661 | double mass = 0.13957; | |||
662 | double beta = 1.0/sqrt(1.0 + pow(mass/mom_doca.Mag(), 2.0))*2.998E10; | |||
663 | double tof = s/beta/1.0E-9; // in ns | |||
664 | dist -= tof*55.0E-4; | |||
665 | shift.SetMag(dist); | |||
666 | ||||
667 | // See comments in DTrack_factory_ALT1.cc::LeastSquaresB | |||
668 | double u = rt->GetLastDistAlongWire(); | |||
669 | DVector3 pos_wire = wire->origin + u*wire->udir; | |||
670 | DVector3 pos_diff = pos_doca-pos_wire; | |||
671 | double sdist = pos_diff.Mag(); | |||
672 | if(shift.Dot(pos_diff)<0.0){ | |||
673 | shift = -shift; | |||
674 | sdist = -sdist; | |||
675 | } | |||
676 | ||||
677 | // OK. Finally, we can decide on a sign for the residual. | |||
678 | // We do this by taking the dot product of the shift with | |||
679 | // the vector pointing to the center of the wire. | |||
680 | //double sign = (shift.Dot(pos_wire)<0.0) ? -1.0:+1.0; | |||
681 | double resi = fabs(doca)-fabs(dist); | |||
682 | if(!finite(resi))continue; | |||
683 | ||||
684 | // If the residual is reasonably small, consider this hit to be | |||
685 | // on this track and record it (if this is the prime track) | |||
686 | if(index==0)TRACKHITS.push_back(hits[i]); | |||
687 | ||||
688 | //_DBG_<<"resi="<<resi<<" s="<<s<<" resi*10E4="<<resi*1.0E4<<endl; | |||
689 | ||||
690 | if(index==0){ | |||
691 | TMarker *m = new TMarker(sdist, s, 20); | |||
692 | m->SetMarkerSize(1.6); | |||
693 | m->SetMarkerColor(kYellow); | |||
694 | graphics.push_back(m); | |||
695 | this->resi->Fill(resi); | |||
696 | ||||
697 | // Record limits for s. | |||
698 | // NOTE: We calculate resilo and resihi from these later | |||
699 | // in DoMyRedraw(). | |||
700 | if(s<slo)slo=s; | |||
701 | if(s>shi)shi=s; | |||
702 | } | |||
703 | ||||
704 | // Check if this is a CDC wire. | |||
705 | int marker_style = 20; | |||
706 | double ellipse_width = 0.8; | |||
707 | int ellipse_color = colors[index%ncolors]; | |||
708 | const DCDCWire *cdcwire = dynamic_cast<const DCDCWire*>(wire); | |||
709 | if(cdcwire!=NULL__null && cdcwire->stereo!=0.0){ | |||
710 | ellipse_width = 3.0; | |||
711 | ellipse_color += cdcwire->stereo>0.0 ? 4:-2; | |||
712 | marker_style = 5; | |||
713 | } | |||
714 | ||||
715 | // Check if this is wire is in the list of wires associated with this track | |||
716 | int ellipse_style = 1; | |||
717 | if(!WireInList(wire, cdctrackhits)){ | |||
718 | ellipse_style=2; | |||
719 | ellipse_width=2.0; | |||
720 | } | |||
721 | ||||
722 | // If the lock_s_coordinate flag is set and this is not the prime track | |||
723 | // then try and replace the s-value for this hit by the one from the | |||
724 | // prime track. If this is the prime track, then record the s-value. | |||
725 | if(lock_s_coordinate){ | |||
726 | if(index==0){ | |||
727 | // This is prime track. Record s-value for this wire | |||
728 | S_VALS[wire] = s; | |||
729 | }else{ | |||
730 | map<const DCoordinateSystem*,double>::iterator iter = S_VALS.find(wire); | |||
731 | if(iter!=S_VALS.end()){ | |||
732 | s = iter->second; | |||
733 | } | |||
734 | } | |||
735 | } | |||
736 | ||||
737 | // Create ellipse for distance from wire | |||
738 | TEllipse *e = new TEllipse(sdist, s, dist, dist); | |||
739 | e->SetLineWidth((Width_t)ellipse_width); | |||
740 | e->SetLineColor(ellipse_color); | |||
741 | e->SetLineStyle(ellipse_style); | |||
742 | e->SetFillColor(19); | |||
743 | graphics.push_back(e); | |||
744 | ||||
745 | // Create marker for wire | |||
746 | TMarker *m = new TMarker(sdist, s, marker_style); | |||
747 | m->SetMarkerSize(1.5); | |||
748 | m->SetMarkerColor(colors[index%ncolors]); | |||
749 | graphics.push_back(m); | |||
750 | ||||
751 | } | |||
752 | } | |||
753 | ||||
754 | //------------------- | |||
755 | // WireInList | |||
756 | //------------------- | |||
757 | bool trk_mainframe::WireInList(const DCoordinateSystem *wire, vector<const DCDCTrackHit*> &cdctrackhits) | |||
758 | { | |||
759 | for(unsigned int i=0; i<cdctrackhits.size(); i++){ | |||
760 | if(cdctrackhits[i]->wire == wire)return true; | |||
761 | } | |||
762 | ||||
763 | return false; | |||
764 | } | |||
765 | ||||
766 |