LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
TWQProjectionView.cxx
Go to the documentation of this file.
1 //
6 #include "TCanvas.h"
7 #include "TFrame.h"
8 #include "TGFrame.h" // For TGMainFrame, TGHorizontalFrame
9 #include "TGLayout.h" // For TGLayoutHints
10 #include "TGDimension.h"
11 #include "TGNumberEntry.h"
12 #include "TGLabel.h"
13 #include "TMath.h"
14 #include "TString.h"
15 #include "TRootEmbeddedCanvas.h"
16 #include "TLine.h"
17 #include "Buttons.h"
18 #include "TGTextView.h"
19 #include "TROOT.h"
20 #include "sstream"
21 
24 #include "lareventdisplay/EventDisplay/ChangeTrackers.h" // util::DataProductChangeTracker_t
40 
49 
50 
51 namespace evd{
52 
53  static unsigned int kPlane;
54  static unsigned int kWire;
55  static double kDistance;
56  static int curr_zooming_plane;
57  static const char* zoom_opt=0;
58 
59  static int shift_lock;
60 
61 
62  //......................................................................
64  : evdb::Canvas(mf)
65  , fRedraw(nullptr)
66  , fCryoInput(nullptr), fTPCInput(nullptr), fTotalTPCLabel(nullptr)
67  , isZoomAutomatic
68  (art::ServiceHandle<evd::EvdLayoutOptions>()->fAutoZoomInterest)
69  , fLastEvent(new util::DataProductChangeTracker_t)
70  {
71 
73 
74  // first make pads for things that don't depend on the number of
75  // planes in the detector
76  // bottom left corner is (0.,0.), top right is (1., 1.)
77  fAngleInfo=NULL;
78  fXYZPosition=NULL;
79 
80  fLastThreshold = -1.;
81 
82  evdb::Canvas::fCanvas->cd();
83  fHeaderPad = new HeaderPad("fHeaderPad","Header",0.0,0.0,0.15,0.13,"");
84  fHeaderPad->Draw();
85 
86  evdb::Canvas::fCanvas->cd();
87  fMC = new MCBriefPad("fMCPad","MC Info.",0.15,0.13,1.0,0.17,"");
88  fMC->Draw();
89 
90  evdb::Canvas::fCanvas->cd();
91 // fWireQ = new TQPad("fWireQPad", "ADCvsTime",0.15,0.0,1.0,0.13,"TQ", 0, 0);
92  fWireQ = new TQPad("fWireQPad", "ADCvsTime",0.15,0.0,1.0,0.14,"TQ", 0, 0);
93  fWireQ->Pad()->SetBit(TPad::kCannotMove,true);
94  fWireQ->Draw();
95 
96 
97  // add new "meta frame" to hold the GUI Canvas and a side frame (vframe)
98  fMetaFrame = new TGCompositeFrame(mf, 60, 60, kHorizontalFrame);
99  fMetaFrame->SetBit(TPad::kCannotMove,true);
100 
101  //new frame organizing the buttons on the left of the canvas.
102  fVFrame = new TGCompositeFrame(fMetaFrame, 60, 60, kVerticalFrame);
103  // Define a layout for placing the canvas within the frame.
104  fLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX |
105  kLHintsExpandY, 5, 5, 5, 5);
106 
107  mf->RemoveFrame((TGFrame *)fEmbCanvas);
108  mf->RemoveFrame(fFrame);
109 
110  fEmbCanvas->ReparentWindow( fMetaFrame, fXsize, fYsize);
111 
112 
113  fMetaFrame->AddFrame(fVFrame,new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandY));
114  fMetaFrame->AddFrame(fEmbCanvas, fLayout);
115 
116 
117  mf->AddFrame(fMetaFrame,fLayout);
118  mf->AddFrame(fFrame);
119 
120  // plane number entry
121  fPlaneEntry = new TGNumberEntry(fFrame,
122  0,2,-1,
123  TGNumberFormat::kNESInteger,
124  TGNumberFormat::kNEAAnyNumber,
125  TGNumberFormat::kNELLimitMinMax,
126  0 , geo->Nplanes()-1 );
127 
128  kPlane = 0;
129  kWire = TMath::Nint(0.5*geo->Nwires(0));
130  kDistance=1.5;
131  fWireQ->SetPlaneWire(kPlane, kWire);
132 
133  // Initial value
134  fPlaneEntry->SetNumber( kPlane );
135 
136  // There are two "signals" to which a TGNumberEntry may respond:
137  // when the user clicks on the arrows, or when the user types in a
138  // new number in the text field.
139  fPlaneEntry->Connect("ValueSet(Long_t)", "evd::TWQProjectionView", this, "SetPlane()");
140  fPlaneEntry->GetNumberEntry()->Connect("ReturnPressed()", "evd::TWQProjectionView", this, "SetPlane()");
141  // Text label for this numeric field.
142  fPlaneLabel= new TGLabel(fFrame,"Plane");
143 
144  // wire number entry
145  unsigned int maxwire=0;
146  for (unsigned int ip=0;ip<geo->Nplanes();ip++)
147  maxwire = (geo->Nwires(ip)-1 > maxwire) ? geo->Nwires(ip)-1 : maxwire;
148 
149 
150  fWireEntry = new TGNumberEntry(fFrame,0,6,-1,
151  TGNumberFormat::kNESInteger,
152  TGNumberFormat::kNEAAnyNumber,
153  TGNumberFormat::kNELLimitMinMax,
154  0 , maxwire );
155  // Initial value
156  fWireEntry->SetNumber( kWire );
157 
158  // There are two "signals" to which a TGNumberEntry may respond:
159  // when the user clicks on the arrows, or when the user types in a
160  // new number in the text field.
161  fWireEntry->Connect("ValueSet(Long_t)", "evd::TWQProjectionView", this, "SetWire()");
162  fWireEntry->GetNumberEntry()->Connect("ReturnPressed()", "evd::TWQProjectionView", this, "SetWire()");
163 
164  // Text label for this numeric field.
165  fWireLabel= new TGLabel(fFrame,"Wire");
166 
167  // adc threshold number entry
168  fThresEntry = new TGNumberEntry(fFrame,0,6,-1,
169  TGNumberFormat::kNESInteger,
170  TGNumberFormat::kNEAAnyNumber,
171  TGNumberFormat::kNELLimitMinMax,
172  0 , geo->Nwires(0)-1 );
173  // Initial value
178 
179 
180  fThresEntry->SetNumber( rawopt->fMinSignal );
181 
182  // There are two "signals" to which a TGNumberEntry may respond:
183  // when the user clicks on the arrows, or when the user types in a
184  // new number in the text field.
185  fThresEntry->Connect("ValueSet(Long_t)", "evd::TWQProjectionView", this, "SetThreshold()");
186  fThresEntry->GetNumberEntry()->Connect("ReturnPressed()", "evd::TWQProjectionView", this, "SetThreshold()");
187 
188  // Text label for this numeric field.
189  fThresLabel= new TGLabel(fFrame,"ADC Threshold");
190 
191  // check button to toggle color vs grey
192  fGreyScale = new TGCheckButton(fFrame,"Grayscale",1);
193  fGreyScale->Connect("Clicked()", "evd::TWQProjectionView", this, "SetGreyscale()");
194  if(cst->fColorOrGray == 1) fGreyScale->SetState(kButtonDown);
195 
196  // check button to toggle MC information
197  if(evdlayoutopt->fEnableMCTruthCheckBox){
198  fMCOn = new TGCheckButton(fFrame,"MC Truth",5);
199  fMCOn->Connect("Clicked()", "evd::TWQProjectionView", this, "SetMCInfo()");
200  if(sdo->fShowMCTruthText == 1) fMCOn->SetState(kButtonDown);
201  }
202 
203  // radio buttons to toggle drawing raw vs calibrated information
204  fRawCalibDraw = new TGRadioButton(fFrame,"Both", 2);
205  fCalibDraw = new TGRadioButton(fFrame,"Reconstructed", 3);
206  fRawDraw = new TGRadioButton(fFrame,"Raw", 4);
207  fRawDraw ->Connect("Clicked()", "evd::TWQProjectionView", this, "SetRawCalib()");
208  fCalibDraw ->Connect("Clicked()", "evd::TWQProjectionView", this, "SetRawCalib()");
209  fRawCalibDraw->Connect("Clicked()", "evd::TWQProjectionView", this, "SetRawCalib()");
210  if(rawopt->fDrawRawDataOrCalibWires == 0) fRawDraw->SetState(kButtonDown);
211  else if(rawopt->fDrawRawDataOrCalibWires == 1) fCalibDraw->SetState(kButtonDown);
212  else if(rawopt->fDrawRawDataOrCalibWires == 2) fRawCalibDraw->SetState(kButtonDown);
213 
214  // Put all these widgets into the frame. The last
215  // four numbers in each TGLayoutHint are padleft, padright,
216  // padtop, padbottom.
217  if(evdlayoutopt->fEnableMCTruthCheckBox){
218  fFrame->AddFrame(fMCOn, new TGLayoutHints(kLHintsBottom | kLHintsRight, 0, 0, 5, 1 ) );
219  }
220  fFrame->AddFrame(fGreyScale, new TGLayoutHints(kLHintsBottom | kLHintsRight, 0, 0, 5, 1 ) );
221  fFrame->AddFrame(fRawCalibDraw, new TGLayoutHints(kLHintsBottom | kLHintsRight, 0, 0, 5, 1 ) );
222  fFrame->AddFrame(fCalibDraw, new TGLayoutHints(kLHintsBottom | kLHintsRight, 0, 0, 5, 1 ) );
223  fFrame->AddFrame(fRawDraw, new TGLayoutHints(kLHintsBottom | kLHintsRight, 0, 0, 5, 1 ) );
224  fFrame->AddFrame(fPlaneEntry, new TGLayoutHints(kLHintsBottom | kLHintsRight, 0, 0, 2, 1 ) );
225  fFrame->AddFrame(fPlaneLabel, new TGLayoutHints(kLHintsBottom | kLHintsRight, 0, 0, 5, 1 ) );
226  fFrame->AddFrame(fWireEntry, new TGLayoutHints(kLHintsBottom | kLHintsRight, 0, 0, 2, 1 ) );
227  fFrame->AddFrame(fWireLabel, new TGLayoutHints(kLHintsBottom | kLHintsRight, 0, 0, 5, 1 ) );
228  fFrame->AddFrame(fThresEntry, new TGLayoutHints(kLHintsBottom | kLHintsRight, 0, 0, 2, 1 ) );
229  fFrame->AddFrame(fThresLabel, new TGLayoutHints(kLHintsBottom | kLHintsRight, 0, 0, 5, 1 ) );
230 
231  // geometry to figure out the number of planes
232  unsigned int nplanes = geo->Nplanes();
233 
234  if(evdlayoutopt-> fShowSideBar)
235  SetUpSideBar();
236  else
237  evdlayoutopt->fShowEndPointSection=0; // zero it to avoid a misconfiguration in the fcl file.
238 
239  //zero the ppoints queue.
240  ppoints.clear();
241  pline.clear();
242  seedlines.clear();
243 
244 
245  // now determine the positions of all the time vs wire number
246  // and charge histograms for the planes
247  for(unsigned int i = 0; i < nplanes; ++i){
248  double twx1 = 0.;
249  double twx2 = 0.97;
250  double twx3 = 1.0;
251  double twy1 = 0.17 + (i)*(1.0-0.171)/(1.*nplanes);
252  double twy2 = 0.17 + (i+1)*(1.0-0.171)/(1.*nplanes);
253 
254 
255 
256  TString padname = "fWireProjP";
257  padname += i;
258 
259  TString padtitle = "Plane";
260  padtitle += i;
261 
262  evdb::Canvas::fCanvas->cd();
263  fPlanes.push_back(new TWireProjPad(padname, padtitle, twx1, twy1, twx2, twy2, i));
264  fPlanes[i]->Draw();
265 // fPlanes[i]->Pad()->AddExec("mousedispatch",Form("evd::TWQProjectionView::MouseDispatch(%d, (void*)%d)", i, this));
266  fPlanes[i]->Pad()->AddExec("mousedispatch",Form("evd::TWQProjectionView::MouseDispatch(%d, (void*)%lu)", i, (unsigned long) this));
267 
268  padname = "fQPadPlane";
269  padname += i;
270 
271  padtitle = "QPlane";
272  padtitle += i;
273 
274  evdb::Canvas::fCanvas->cd();
275  fPlaneQ.push_back(new TQPad(padname, padtitle, twx2, twy1, twx3, twy2, "Q", i, 0));
276  fPlaneQ[i]->Draw();
277 
278  }
279 
280  // propagate the zoom setting
282 
283  evdb::Canvas::fCanvas->Update();
284 
285  }
286 
287  //......................................................................
289  {
290  if (fHeaderPad) { delete fHeaderPad; fHeaderPad = 0; }
291  if (fMC) { delete fMC; fMC = 0; }
292  if (fWireQ) { delete fWireQ; fWireQ = 0; }
293  if (fPlaneEntry){ delete fPlaneEntry; fPlaneEntry = 0; }
294  if (fWireEntry) { delete fWireEntry; fWireEntry = 0; }
295  if (fPlaneLabel){ delete fPlaneLabel; fPlaneLabel = 0; }
296  if (fWireLabel) { delete fWireLabel; fWireLabel = 0; }
297  for(unsigned int i = 0; i < fPlanes.size(); ++i){
298  if(fPlanes[i]){ delete fPlanes[i]; fPlanes[i] = 0; }
299  if(fPlaneQ[i]){ delete fPlaneQ[i]; fPlaneQ[i] = 0; }
300  }
301  fPlanes.clear();
302  fPlaneQ.clear();
303 
304  delete fLastEvent;
305  }
306 
307  //......................................................................
309  for(TWireProjPad* planePad: fPlanes)
310  planePad->RawDataDraw()->ResetRegionOfInterest();
311  } // TWQProjectionView::ResetRegionsOfInterest()
312 
313  //......................................................................
314  void TWQProjectionView::DrawPads(const char* /*opt*/)
315  {
316 
317  OnNewEvent(); // if the current event is a new one, we need some resetting
318 
319  for(unsigned int i=0; i<fPlanes.size();++i){
320  fPlanes[i]->Draw();
321  fPlanes[i]->Pad()->Update();
322  fPlanes[i]->Pad()->GetFrame()->SetBit(TPad::kCannotMove,true);
323  }
324  for(unsigned int j=0;j<fPlaneQ.size();++j){
325  fPlaneQ[j]->Draw();
326  fPlaneQ[j]->Pad()->Update();
327  fPlaneQ[j]->Pad()->GetFrame()->SetBit(TPad::kCannotMove,true);
328  }
329  }
330 
331 
332  //......................................................................
333  void TWQProjectionView::SetAutomaticZoomMode(bool bSet /* = true */) {
334  isZoomAutomatic = bSet;
335  for (TWireProjPad* pPlane: fPlanes)
336  pPlane->SetZoomToRoI(isZoomAutomatic);
337  } // TWQProjectionView::SetAutomaticZoomMode()
338 
339 
340  //......................................................................
341  void TWQProjectionView::Draw(const char* opt)
342  {
343  mf::LogDebug("TWQProjectionView") << "Starting to draw";
344 
345  OnNewEvent(); // if the current event is a new one, we need some resetting
346 
348 
349  ClearAllSeeds();
350  fPrevZoomOpt.clear();
351 
352 
353  evdb::Canvas::fCanvas->cd();
354  zoom_opt=0;
355  fHeaderPad->Draw();
356  fMC ->Draw();
357  fWireQ ->Draw();
358 
360  if(evdlayoutopt->fPrintTotalCharge)
361  PrintCharge();
362 
363  //clear queue of selected points
364  ppoints.clear();
365  pline.clear();
366  seedlines.clear();
367  // Reset current zooming plane - since it's not currently zooming.
368  curr_zooming_plane=-1;
369 
370  unsigned int const nPlanes = fPlanes.size();
371  LOG_DEBUG("TWQProjectionView") << "Start drawing " << nPlanes << " planes";
372  // double Charge=0, ConvCharge=0;
373  for(unsigned int i=0;i<nPlanes;++i){
374  TWireProjPad* planePad = fPlanes[i];
375  planePad->Draw(opt);
376  planePad->Pad()->Update();
377  planePad->Pad()->GetFrame()->SetBit(TPad::kCannotMove,true);
378  fPlaneQ[i]->Draw();
379  std::vector<double> ZoomParams = planePad->GetCurrentZoom();
380  fZoomOpt.wmin[i] = ZoomParams[0];
381  fZoomOpt.wmax[i] = ZoomParams[1];
382  fZoomOpt.tmin[i] = ZoomParams[2];
383  fZoomOpt.tmax[i] = ZoomParams[3];
384  // Charge deposit feature - not working yet
385  //
386  // if(geo->Plane(i).SignalType()==geo::kCollection)
387  // {
388  // planePad->RecoBaseDraw()->GetChargeSum(i,Charge,ConvCharge);
389  // }
390 
391  }
392  mf::LogDebug("TWQProjectionView")
393  << "Done drawing " << nPlanes << " planes";
394 
395 
396  // Charge deposit feature - not working yet
397  // std::stringstream ss;
398  // if(ConvCharge!=0)
399  // {
400  // ss << ConvCharge << "MeV"<<std::endl;
401  // }
402  // else
403  // {
404  // ss<<" no reco info";
405  // }
406  //
407  // TGText * tt = new TGText(ss.str().c_str());
408  // tt->InsLine(1, "Approx EDep:");
409  // fAngleInfo->SetText(tt);
410  //
411  // ss.flush();
412  //
413 
414  // Reset any text boxes which are enabled
415 
416  if(fXYZPosition)
417  fXYZPosition->SetForegroundColor(kBlack);
418 
419  if(fAngleInfo)
420  fAngleInfo->SetForegroundColor(kBlack);
421 
422  evdb::Canvas::fCanvas->Update();
423  mf::LogDebug("TWQProjectionView") << "Done drawing";
424  }
425 
426  // comment out this method as for now we don't want to change every
427  // plane to have the same range in wire number because wire numbers
428  // don't necessarily overlap from plane to plane, ie the same range
429  // isn't appropriate for every plane
430  //......................................................................
431  // void TWQProjectionView::RangeChanged()
432  // {
433  // static int ilolast = -1;
434  // static int ihilast = -1;
435  //
436  // int ilo;
437  // int ihi;
438  // std::vector<int> lo;
439  // std::vector<int> hi;
440  // std::vector<bool> axischanged;
441  // for(unsigned int i = 0; i < fPlanes.size(); ++i){
442  // fPlanes[i]->GetWireRange(&ilo, &ihi);
443  // lo.push_back(ilo);
444  // hi.push_back(ihi);
445  // axischanged.push_back((ilo != ilolast) || (ihi != ihilast));
446  // }
447  //
448  // TVirtualPad* ori = gPad;
449  //
450  // // loop over the bools to see which axes need to change
451  // for(unsigned int i = 0; i < axischanged.size(); ++i){
452  // if (axischanged[i]) {
453  // fPlanes[i]->SetWireRange(ilo, ihi);
454  // fPlanes[i]->Pad()->cd();
455  // fPlanes[i]->Pad()->Modified();
456  // fPlanes[i]->Pad()->Update();
457  //
458  // ilolast = ilo;
459  // ihilast = ihi;
460  // }
461  // }
462  //
463  // evdb::Canvas::fCanvas->cd();
464  // evdb::Canvas::fCanvas->Modified();
465  // evdb::Canvas::fCanvas->Update();
466  // ori->cd();
467  // }
468  //......................................................................
469 
470  //......................................................................
472  {
474  infot->SetTestFlag(number);
475  }
476 
477 
478  //......................................................................
480  {
481 
484 
485  for(size_t iplane = 0; iplane < fPlanes.size(); ++iplane){
486  geo::PlaneID planeid(rawopt->CurrentTPC(), iplane);
487  if (geo->SignalType(planeid) != geo::kCollection) continue;
488 
489  double ch=0,convch=0;
490  if(rawopt->fDrawRawDataOrCalibWires == 0){
491  fPlanes[iplane]->RawDataDraw()->GetChargeSum(iplane,ch,convch);
492  mf::LogVerbatim("TWQProjectionView") << "Warning! Calculating for RawData! ";
493  }
494  else{
495  fPlanes[iplane]->RecoBaseDraw()->GetChargeSum(iplane,ch,convch);
496  }
497 
498  mf::LogVerbatim("TWQProjectionView") << "\ncharge collected at collection plane: "
499  << iplane << " " << ch << " " << convch;
500  } // for
501 
502 
503  }
504 
505  //-------------------------------------------------------------------
506  //......................................................................
507  void TWQProjectionView::MouseDispatch(int plane, void * wqpv)
508  {
509  //initial check for a mouse click on a TBox object
510  int event = gPad->GetEvent();
513 
514  switch (event){
515 
516  case kButton1Shift:
517  shift_lock=1;
518  if(evdlayoutopt->fMakeClusters==1){wqpp->SelectHit(plane);}
519  else {wqpp->SelectPoint(plane);}
520  break;
521  case kButton1Up:
522  if(shift_lock==1) break;
523  if(evdlayoutopt-> fChangeWire==1) wqpp->ChangeWire(plane);
524  case kButton1Down: shift_lock=0;
525  case kButton1Motion:
526  if((evdlayoutopt->fMakeClusters == 1) && !(evdlayoutopt->fMakeSeeds == 1)){ wqpp->SetClusters(plane);}
527  else if((evdlayoutopt->fMakeClusters == 0) && (evdlayoutopt->fMakeSeeds == 1)){ wqpp->SetSeeds(plane);}
528  else { wqpp->SetMouseZoomRegion(plane);}
529  break;
530  // default:
531  }
532  }
533 
534 
535  //......................................................................
537  {
538  //initial check for a mouse click on a TBox object
539  int event = gPad->GetEvent();
540  int px = gPad->GetEventX();
541  if(event!=11) return;
542  TObject *select = gPad->GetSelected();
543  if(!select) return;
544  if(!select->InheritsFrom("TBox")) return;
545 
546  //now find wire that was clicked on
547  float xx = gPad->AbsPixeltoX(px);
548  float x = gPad->PadtoX(xx);
549 
550 
551  kPlane = plane;
552  kWire = (unsigned int)TMath::Nint(x);
553 
554  this->SetPlaneWire();
555 
556  return;
557 
558  }
559 
560  //......................................................................
562  {
563  //initial check for a mouse click on a TBox object
564  int event = gPad->GetEvent();
565 
566  if(event!=7) return;
567 
569  if(evdlayoutopt->fShowEndPointSection!=1)
570  return;
571  //struct planepoint;
572  int px = gPad->GetEventX();
573  double w0 = gPad->AbsPixeltoX(px);
574  double x = gPad->PadtoX(w0);
575 
576  int py = gPad->GetEventY();
577  double t0 = gPad->AbsPixeltoY(py);
578  double y = gPad->PadtoY(t0);
579 
580  util::PxPoint ppx(plane,x,y);
581  curr_zooming_plane=-1;
582 
583  // check if not clicking on a plane that is already in the ppoints list:
584  int repeat_plane=-1;
585  for(size_t ii = 0; ii < this->ppoints.size(); ++ii)
586  if(ppx.plane==this->ppoints[ii].plane){
587  this->ppoints[ii]=ppx;
588  //clear View and draw new Marker
589  this->fPlanes[this->ppoints[ii].plane]->View()->Clear();
590  if(evdlayoutopt->fShowEndPointMarkers)
591  this->fPlanes[this->ppoints[ii].plane]->View()->AddMarker(ppx.w, ppx.t, kRed, 29, 2.0);
592  else
593  this->fPlanes[plane]->View()->AddMarker(0.0,0.0,2,1,0.1);
594  this->fPlanes[this->ppoints[ii].plane]->View()->Draw();
595  repeat_plane=this->ppoints[ii].plane;
596  break;
597  }
598 
599  //if plane does not repeat and size of list is larger than 2 pop_front
600  // and delete its marker. Otherwise just push_back.
601  if(repeat_plane==-1){
602  if( this->ppoints.size()>=2){
603  this->fPlanes[this->ppoints[0].plane]->Pad()->cd();
604  this->fPlanes[this->ppoints[0].plane]->View()->Clear();
605  this->fPlanes[this->ppoints[0].plane]->View()->Draw();
606  this->ppoints.pop_front();
607  }
608  this->ppoints.push_back(ppx);
609  this->fPlanes[plane]->Pad()->cd();
610  this->fPlanes[plane]->View()->Clear();
611  if(evdlayoutopt->fShowEndPointMarkers)
612  this->fPlanes[plane]->View()->AddMarker(ppx.w, ppx.t, kRed, 29, 2.0);
613  else
614  this->fPlanes[plane]->View()->AddMarker(0.0,0.0,2,1,0.1);
615  this->fPlanes[plane]->View()->Draw();
616  }
617 
618 
619  return;
620 
621  }
622 
623  //......................................................................
625  {
626  for (size_t x = 0; x < fPlanes.size(); ++x){
627  fPlanes[x]->Pad()->cd();
628  fPlanes[x]->View()->Clear();
629  fPlanes[x]->View()->AddMarker(0.0,0.0,2,1,0.1);
630  fPlanes[x]->Pad()->Update();
631  fPlanes[x]->View()->Draw();
632  }
633  ppoints.clear();
634  gPad->Modified();
635  gPad->Update();
636  gPad->cd();
637 
638  }
639 
640 
641  //......................................................................
643  {
644  // if list is larger than or equal to two, can project to XYZ and extrapolate to third plane (if exists)
645 
647  // for(unsigned int ix=0;ix<ppoints.size();ix++)
648  // std::cout << "ppoints, planes,x,y :" << ix << " " << ppoints[ix].plane << " " << ppoints[ix].x << " " << ppoints[ix].y << std::endl;
649 
650  if(pline.size() >= 2){
651 
652  double xyz_vertex_fit[3];
653  double second_time;
654  double pos[3];
655  const double origin[3] = {0.,0.,0.};
656  double xx0 = 0., yy0 = 0., zz0 = 0.;
657  double xx1 = 0., yy1 = 0., zz1 = 0.;
658  double length;
659 
660  double y,z;
661 
663  const detinfo::DetectorProperties* detp = lar::providerFrom<detinfo::DetectorPropertiesService>();
665  double ftimetick = detp->SamplingRate()/1000.;
666  double larv = detp->DriftVelocity(detp->Efield(), detp->Temperature());
667 
668  //find wireIDs corresponding to found wires.
669  geo::WireID wire1(rawOpt->fCryostat,rawOpt->fTPC,pline[0].plane,pline[0].w0);
670  geo::WireID wire2(rawOpt->fCryostat,rawOpt->fTPC,pline[1].plane,pline[1].w0);
671 
672  bool wires_cross=false;
673  bool time_good=false;
674 
675  if(std::abs(pline[0].t0-pline[1].t0) < 200){
676  geo::WireIDIntersection widIntersect;
677  wires_cross = geom->WireIDsIntersect(wire1,wire2,widIntersect);
678  y = widIntersect.y;
679  z = widIntersect.z;
680  time_good=true;
681  }
682  else{
683  TGText *tt=new TGText("too big");
684  tt->InsLine(1,"time distance");
685  fXYZPosition->SetText(tt);
686  fXYZPosition->Update();
687  // return; //not returning, because may need to delete marker from wplane
688  }
689 
690  if(wires_cross){
691  TGText *tt=new TGText("wires cross");
692  fXYZPosition->SetText(tt);
693  fXYZPosition->Update();
694  xyz_vertex_fit[1]=y;
695  xyz_vertex_fit[2]=z;
696  geom->Plane(pline[0].plane).LocalToWorld(origin, pos);
697  xyz_vertex_fit[0]=(pline[0].t0-detp->TriggerOffset())*larv*ftimetick+pos[0];
698  geom->Plane(pline[1].plane).LocalToWorld(origin, pos);
699  second_time=(pline[1].t0-detp->TriggerOffset())*larv*ftimetick+pos[0];
700 
701  xx0=(xyz_vertex_fit[0]+second_time)/2;
702  yy0=y;
703  zz0=z;
704 
706  }
707  else{
708  if(time_good){ //otherwise the wires_cross are false by default
709  TGText *tt=new TGText("cross");
710  tt->InsLine(1,"wires do not");
711  fXYZPosition->SetText(tt);
712  fXYZPosition->Update();
713  }
714  // return; //not returning, because may need to delete marker from wplanereturn;
715  }
716  //find wireIDs corresponding to found wires AT END OF LINE.
717  wire1.Wire = pline[0].w1;
718  wire2.Wire = pline[1].w1;
719 
720  wires_cross=false;
721  time_good=false;
722 
723  if(std::abs(pline[0].t1-pline[1].t1) < 200){
724  geo::WireIDIntersection widIntersect;
725  wires_cross = geom->WireIDsIntersect(wire1,wire2,widIntersect);
726  y = widIntersect.y;
727  z = widIntersect.z;
728  time_good=true;
729  }
730  else{
731  TGText *tt=new TGText("too big");
732  tt->InsLine(1,"time distance");
733  fXYZPosition->SetText(tt);
734  fXYZPosition->Update();
735  // return; //not returning, because may need to delete marker from wplane
736  }
737 
738  if(wires_cross){
739  TGText *tt=new TGText("wires do cross");
740  fXYZPosition->SetText(tt);
741  fXYZPosition->Update();
742  xyz_vertex_fit[1]=y;
743  xyz_vertex_fit[2]=z;
744  geom->Plane(pline[0].plane).LocalToWorld(origin, pos);
745  xyz_vertex_fit[0]=(pline[0].t1-detp->TriggerOffset())*larv*ftimetick+pos[0];
746  geom->Plane(pline[1].plane).LocalToWorld(origin, pos);
747  second_time=(pline[1].t1-detp->TriggerOffset())*larv*ftimetick+pos[0];
748 
749  xx1=(xyz_vertex_fit[0]+second_time)/2;
750  yy1=y;
751  zz1=z;
752 
753  }
754  else{
755  if(time_good){ //otherwise the wires_cross are false by default
756  TGText *tt=new TGText("cross");
757  tt->InsLine(1,"wires do not");
758  fXYZPosition->SetText(tt);
759  fXYZPosition->Update();
760  }
761  // return; //not returning, because may need to delete marker from wplanereturn;
762  }
763  //update pad?
764  gPad->Modified();
765  gPad->Update();
766  gPad->cd();
767 
768  length=pow(xx0-xx1,2)+pow(yy0-yy1,2)+pow(zz0-zz1,2);
769  length=pow(length,0.5);
770  return length;
771  } // end if( this->ppoints.size()>=2)
772 
773  else{
774  TGText *tt=new TGText("selected points");
775  tt->InsLine(1,"not enough");
776  fXYZPosition->SetText(tt);
777  fXYZPosition->Update();
778  }
779 
780 
781 
782  return -99;
783  }
784 
785  //......................................................................
787  {
788  // if list is larger than or equal to two, can project to XYZ and extrapolate to third plane (if exists)
789 
791  // for(unsigned int ix=0;ix<ppoints.size();ix++)
792  // std::cout << "ppoints, planes,x,y :" << ix << " " << ppoints[ix].plane << " " << ppoints[ix].x << " " << ppoints[ix].y << std::endl;
793 
794  if(ppoints.size()>=2 ){
795 
796  double xyz_vertex_fit[3] = {0.};
797  double second_time = 0.;
798  double pos[3] = {0.};
799  const double origin[3] = {0.,0.,0.};
800  double y = 0.;
801  double z = 0.;
802 
804  const detinfo::DetectorProperties* detp = lar::providerFrom<detinfo::DetectorPropertiesService>();
806  //double ftimetick = detp->SamplingRate()/1000.;
807  //double larv = detp->DriftVelocity(detp->Efield(), detp->Temperature());
808 
809  //find channels corresponding to found wires.
810  geo::WireID wire1(rawOpt->fCryostat,rawOpt->fTPC,ppoints[0].plane,ppoints[0].w);
811  geo::WireID wire2(rawOpt->fCryostat,rawOpt->fTPC,ppoints[1].plane,ppoints[1].w);
812 
813  bool wires_cross=false;
814  bool time_good=false;
815 
816  if(std::abs(ppoints[0].t-ppoints[1].t) < 200){
817  geo::WireIDIntersection widIntersect;
818  geom->WireIDsIntersect(wire1,wire2,widIntersect);
819  y = widIntersect.y;
820  z = widIntersect.z;
821  wires_cross=true;
822  time_good=true;
823  }
824  else{
825  TGText *tt=new TGText("too big");
826  tt->InsLine(1,"time distance");
827  fXYZPosition->SetText(tt);
828  fXYZPosition->Update();
829  // return; //not returning, because may need to delete marker from wplane
830  }
831 
832  if(wires_cross){
833  xyz_vertex_fit[1]=y;
834  xyz_vertex_fit[2]=z;
835 
836  xyz_vertex_fit[0]=detp->ConvertTicksToX(ppoints[0].t,
837  ppoints[0].plane,
838  rawOpt->fTPC,
839  rawOpt->fCryostat);
840  second_time=detp->ConvertTicksToX(ppoints[1].t,
841  ppoints[1].plane,
842  rawOpt->fTPC,
843  rawOpt->fCryostat);
844 
845  TGText *tt=new TGText(Form("z:%4.1f",z));
846  tt->InsLine(1,Form("x:%4.1f,",(xyz_vertex_fit[0]+second_time)/2));
847  tt->InsLine(1,Form("y:%4.1f,",y));
848  fXYZPosition->SetText(tt);
849  fXYZPosition->Update();
851 
852  }
853  else{
854  if(time_good){ //otherwise the wires_cross are false by default
855  TGText *tt=new TGText("cross");
856  tt->InsLine(1,"wires do not");
857  fXYZPosition->SetText(tt);
858  fXYZPosition->Update();
859  }
860  // return; //not returning, because may need to delete marker from wplanereturn;
861  }
862  // extrapolate third point only if there are enough planes
863  if(fPlanes.size() > 2){
864 
865  unsigned int wplane = 0;
866  unsigned int wirevertex = 0;
868 
869  for(size_t xx = 0; xx < fPlanes.size(); ++xx){
870  wplane = 0;
871  for(int yy = 0; yy < 2; ++yy)
872  if(ppoints[yy].plane == xx)
873  ++wplane;
874 
875  if(!wplane){
876  wplane = xx;
877  break;
878  }
879  }
880 
881 
882  geom->Plane(wplane).LocalToWorld(origin, pos);
883  pos[1]=xyz_vertex_fit[1];
884  pos[2]=xyz_vertex_fit[2];
885 
886  wirevertex = geom->NearestWire(pos, wplane, rawOpt->fTPC, rawOpt->fCryostat);
887 
888  double timestart = detp->ConvertXToTicks(xyz_vertex_fit[0],
889  wplane,
890  rawOpt->fTPC,
891  rawOpt->fCryostat);
892 
893  fPlanes[wplane]->Pad()->cd();
894  fPlanes[wplane]->View()->Clear();
895  if(wires_cross && evdlayoutopt->fShowEndPointMarkers) //only Draw if it makes sense
896  fPlanes[wplane]->View()->AddMarker(wirevertex, timestart, kMagenta, 29, 2.0);
897  else //draw dummy marker to delete old one
898  fPlanes[wplane]->View()->AddMarker(0.0,0.0,2,1,0.1);
899  fPlanes[wplane]->Pad()->Update();
900  fPlanes[wplane]->View()->Draw();
901  }// end if(fPlanes.size()>2)
902  //update pad?
903  gPad->Modified();
904  gPad->Update();
905  gPad->cd();
906  } // end if( this->ppoints.size()>=2)
907  else{
908  TGText *tt=new TGText("selected points");
909  tt->InsLine(1,"not enough");
910  fXYZPosition->SetText(tt);
911  fXYZPosition->Update();
912  }
913 
914 
915 
916 
917  return;
918  }
919 
920  //......................................................................
922 
923 
924  }
925 
926  //......................................................................
927  // SaveSelection
929  {
931 
933  if(evdlayoutoptions->fMakeSeeds){
934  double KineticEnergy = fPlanes[0]->SaveSeedList( seedlines, kDistance);
935  std::stringstream ss;
936  ss<< " " << std::setprecision(1) << std::fixed << KineticEnergy << " MeV";
937 
938  TGText * tt = new TGText(fAngleInfo->GetText());
939  tt->InsLine(1,ss.str().c_str());
940  fAngleInfo->SetText(tt);
941  fAngleInfo->Update();
942  }
943  else if(evdlayoutoptions->fMakeClusters){
944  //only calculating in 3 planes now, needs to be generalized eventually
945  // evd::TWQProjectionView tt;
946  double omx[3];
947  //double omx0,omx1;
948  double xphi;
949  double xtheta;
950  unsigned int ii;
951  if(pline.size()<2) {
952  TGText *tt=new TGText("not enough lines selected");
953  fAngleInfo->SetText(tt);
954  fAngleInfo->Update();
955  return;
956  }
957  double deltawire;
958  double deltatime;
959  for(ii = 0; ii < pline.size(); ++ii){
960  //if(pline[ii].plane==0) break;
961  deltawire=pline[ii].w1-pline[ii].w0;
962  deltatime=pline[ii].t1-pline[ii].t0;
963  omx[ii]=gser.Get2Dangle(deltawire,deltatime);
964  }
965 
966  for(size_t ii = 0; ii < pline.size(); ++ii){
967  fPlanes[pline[ii].plane]->SaveHitList(pline[ii].w0,
968  pline[ii].t0,
969  pline[ii].w1,
970  pline[ii].t1,
971  kDistance,
972  zoom_opt);
973  }
974  if(fPlanes.size()>pline.size() && pline.size() >=2 ){ // need to project to third plane
975 
976 
977  util::PxPoint p00(pline[0].plane,pline[0].w0,pline[0].t0);
978  util::PxPoint p01(pline[1].plane,pline[1].w0,pline[1].t0);
979  util::PxPoint p0N(0,0,0);
980  int error1=gser.GetProjectedPoint(&p00,&p01,p0N);
981 
982 
983  util::PxPoint p10(pline[0].plane,pline[0].w1,pline[0].t1);
984  util::PxPoint p11(pline[1].plane,pline[1].w1,pline[1].t1);
985  util::PxPoint p1N(0,0,0);
986  int error2=gser.GetProjectedPoint(&p10,&p11,p1N);
987  if(error1!=-1 && error2!=-1)
988  fPlanes[p0N.plane]->SaveHitList(p0N.w,p0N.t,p1N.w,p1N.t,kDistance, zoom_opt,false);
989 
990 
991 
992  }
993 
994  for(size_t jj = 0;jj < fPlanes.size(); ++jj){
995  fPlanes[jj]->UpdatePad();
996  }
997 
998 
999  gser.Get3DaxisN(pline[0].plane,pline[1].plane,omx[0],omx[1],xphi,xtheta);
1000 
1001 // double xtheta2;
1002 // if(xphi < 2 && xphi > -2)
1003 // xtheta2=gser.Get3DSpecialCaseTheta(pline[0].plane,
1004 // pline[1].plane,
1005 // pline[0].w1-pline[0].w0,
1006 // pline[1].w1-pline[1].w0);
1007 
1008  double length=FindLineLength();
1009  TGText *tt=new TGText(Form("Length:%4.1f",length));
1010  tt->InsLine(1,Form("Omega P%d:%4.1f,",pline[0].plane,omx[0]));
1011  tt->InsLine(2,Form("Omega P%d:%4.1f,",pline[1].plane,omx[1]));
1012  tt->InsLine(3,Form("Phi: %4.1f,",xphi));
1013 
1014  tt->InsLine(4, Form("Theta: %4.1f",xtheta));
1015  fAngleInfo->SetText(tt);
1016  fAngleInfo->Update();
1017  } // end else if
1018  }
1019 
1020  //.......................................................................
1022  {
1024 
1025  if(!evdlayoutopt->fMakeSeeds && !evdlayoutopt->fMakeClusters)
1026  ppoints.clear();
1027  else if(evdlayoutopt->fMakeSeeds)
1028  ClearAllSeeds();
1029  else if(evdlayoutopt->fMakeClusters){
1030  if(this->pline.size()==0) return;
1031  for(size_t i = 0;i < fPlanes.size(); ++i){
1032  fPlanes[i]->ClearHitList();
1033  fPlanes[i]->UpdatePad();
1034  }
1035  pline.clear();
1036 
1037  }
1038  }
1039 
1040  //.......................................................................
1042  {
1044  if(!recoopt->fUseHitSelector) return;
1045 
1046  if(this->seedlines.size()==0) return;
1047  //this->DrawPads();
1048  seedlines.clear();
1049  fPlanes[0]->HitSelectorGet()->SeedVector().clear();
1050  // only for last plane
1051  for(size_t i = 0; i < fPlanes.size(); ++i){
1052  fPlanes[i]->DrawLinesinView(seedlines,true);
1053  fPlanes[i]->UpdatePad();
1054  }
1055 
1056  return;
1057  }
1058 
1059 
1060 
1061  //.......................................................................
1062  // If we are mid seed creation, stop and clear.
1063  // Otherwise, remove the last seed.
1064  //
1066  {
1068  if(!recoopt->fUseHitSelector) return;
1069 
1070  if(this->seedlines.size()==0) return;
1071 
1072  // If the seed lines vector is an event seed number, remove
1073  // one seed from the hit selector seed collection
1074  if(seedlines.size()%3==0)
1075  fPlanes[0]->HitSelectorGet()->SeedVector().pop_back();
1076 
1077  // Figure out how many display lines need to be rejected
1078  int SeedsToRemove = seedlines.size() % fPlanes.size();
1079  if(SeedsToRemove==0) SeedsToRemove=3;
1080 
1081  mf::LogVerbatim("TWQProjectionView") <<"Removing "
1082  << SeedsToRemove
1083  << " of " << seedlines.size() <<" seed lines";
1084 
1085  // Throw them out
1086  for(int i=0; i!=SeedsToRemove; ++i)
1087  seedlines.pop_back();
1088 
1089  // Then update the drawing pads
1090  for(size_t i=0; i!=fPlanes.size(); ++i){
1091  fPlanes[i]->UpdatePad();
1092  fPlanes[i]->DrawLinesinView(seedlines,true);
1093  fPlanes[i]->UpdatePad();
1094  }
1095 
1096  }
1097 
1098  //.......................................................................
1100  {
1101  //*-*-*-*-*-*-*-*-*-*-*Create a new arrow in this pad*-*-*-*-*-*-*-*-*-*-*-*-*
1102  //*-* ==============================
1103  //
1104  TObject *select = gPad->GetSelected();
1105  if(!select) return;
1106  if(!select->InheritsFrom("TBox")) return;
1107 
1108  static Float_t w0=-1, t0=-1, w1=-1, t1=-1;
1109 
1110  static Int_t pxold, pyold;
1111  static Int_t pw0, pt0;
1112  static Int_t linedrawn;
1113  //static int curr_plane;
1114  //TLine *line;
1115 
1116  static int wstart,wend;
1117  static float tstart,tend;
1118 
1119  int event = gPad->GetEvent();
1120  int px = gPad->GetEventX();
1121  int py = gPad->GetEventY();
1122 
1123  switch (event){
1124 
1125  case kButton1Down:{
1126  gVirtualX->SetLineColor(-1);
1127  w0 = gPad->AbsPixeltoX(px);
1128  t0 = gPad->AbsPixeltoY(py);
1129  pw0 = px; pt0 = py;
1130  pxold = px; pyold = py;
1131  linedrawn = 0;
1132  float x = gPad->PadtoX(w0);
1133  tstart = gPad->PadtoY(t0);
1134 
1135  wstart = (unsigned int)TMath::Nint(x);
1136  curr_zooming_plane=plane;
1137  break;
1138  }
1139  case kButton1Motion:{
1140  int lx,hx,ly,hy;
1141  if (pw0 < pxold){
1142  lx=pw0;
1143  hx=pxold;
1144  }
1145  else{
1146  lx=pxold;
1147  hx=pw0;
1148  }
1149 
1150  if (pt0 < pyold){
1151  ly=pt0;
1152  hy=pyold;
1153  }
1154  else{
1155  ly=pyold;
1156  hy=pt0;
1157  }
1158 
1159  if (linedrawn) gVirtualX->DrawBox(lx, ly, hx, hy,TVirtualX::kHollow);
1160  pxold = px;
1161  pyold = py;
1162  linedrawn = 1;
1163 
1164  if (pw0 < pxold){
1165  lx=pw0;
1166  hx=pxold;
1167  }
1168  else{
1169  lx=pxold;
1170  hx=pw0;
1171  }
1172 
1173  if (pt0 < pyold){
1174  ly=pt0;
1175  hy=pyold;
1176  }
1177  else{
1178  ly=pyold;
1179  hy=pt0;
1180  }
1181 
1182  gVirtualX->DrawBox(lx, ly, hx, hy,TVirtualX::kHollow);
1183  break;
1184  }
1185  case kButton1Up:{
1186  if (px == pw0 && py == pt0) break;
1187  w1 = gPad->AbsPixeltoX(px);
1188  t1 = gPad->AbsPixeltoY(py);
1189  gPad->Modified(kTRUE);
1190 
1191  // line = new TLine(w0,t0,w1,t1);
1192  // line->Draw();
1193 
1194  float x = gPad->PadtoX(w1);
1195  tend = gPad->PadtoY(t1);
1196  wend = (unsigned int)TMath::Nint(x);
1197 
1198  gROOT->SetEditorMode();
1199 
1200  //make sure the box is significantly big to avoid accidental zooms on nothing.
1201  double xx1,yy1,xx2,yy2;
1202 
1203  gPad->GetRangeAxis(xx1, yy1, xx2, yy2);
1204 
1205  if(wstart != 0 && tstart != 0 &&
1206  ( std::abs(wend-wstart ) > 0.01*(xx2-xx1) ) &&
1207  ( std::abs(tend-tstart ) > 0.01*(yy2-yy1) &&
1208  curr_zooming_plane==plane ) ){
1209 
1210  SetAutomaticZoomMode(false);
1211  this->SetZoom(plane,wstart,wend,tstart,tend);
1212  wstart=-1;
1213  tstart=-1;
1214  }
1215  break;
1216  }
1217  }// end switch
1218  }
1219 
1220  //......................................................................
1222  {
1224  const detinfo::DetectorProperties* det = lar::providerFrom<detinfo::DetectorPropertiesService>();
1225 
1226  static Float_t w0=-1, t0=-1, w1=-1, t1=-1;
1227 
1228  static Int_t pxold, pyold;
1229  static Int_t pw0, pt0;
1230 
1231  static Int_t linedrawn;
1232 
1233  // These static variables keep track of seed lines which
1234  // were drawn
1235  static Int_t LastSeedt0;
1236  static Int_t LastSeedt1;
1237  static Int_t LastSeedPlane;
1238 
1239 
1240  //Temporary evil - eventually from pset
1241  double MaxSeedTimeDiff=100;
1242 
1243  int event = gPad->GetEvent();
1244  int px = gPad->GetEventX();
1245  int py = gPad->GetEventY();
1246 
1247  int SeedCounter = seedlines.size();
1248 
1249 
1250  int linefinished=0;
1251 
1252  switch (event){
1253 
1254  case kButton1Down:{
1255  //not doing anything right now
1256  w0 = gPad->AbsPixeltoX(px);
1257  t0 = gPad->AbsPixeltoY(py);
1258  if(evdlayoutopt->fMakeSeeds){
1259  if((SeedCounter%3)==1){
1260  t0=det->ConvertXToTicks(det->ConvertTicksToX(LastSeedt0,LastSeedPlane,0,0),plane,0,0);
1261  py=gPad->YtoAbsPixel(t0);
1262  }
1263  else{
1264  LastSeedt0=t0;
1265  LastSeedPlane=plane;
1266  }
1267  }
1268  pw0 = px; pt0 = py;
1269  pxold = px; pyold = py;
1270  linedrawn = 0;
1271  curr_zooming_plane=plane;
1272  break;
1273  }
1274 
1275  case kButton1Motion:{
1276  int lx,hx,ly,hy;
1277 
1278  // If we are in seed mode, and one seed line
1279  // was already placed, constrain head of next line
1280  // to be at same t0
1281 
1282  if((evdlayoutopt->fMakeSeeds)&&((SeedCounter%3)==1)){
1283  t0 = det->ConvertXToTicks(det->ConvertTicksToX(LastSeedt0, LastSeedPlane,0,0),plane,0,0);
1284  t1 = det->ConvertXToTicks(det->ConvertTicksToX(LastSeedt1, LastSeedPlane,0,0),plane,0,0);
1285  pt0=gPad->YtoAbsPixel(t0);
1286  }
1287 
1288  lx=pxold;
1289  hx=pw0;
1290 
1291  ly=pyold;
1292  hy=pt0;
1293 
1294 
1295 
1296  if (linedrawn) gVirtualX->DrawLine(lx, ly, hx, hy);
1297 
1298  pxold = px;
1299  pyold = py;
1300  linedrawn = 1;
1301 
1302  lx=pxold;
1303  hx=pw0;
1304 
1305  ly=pyold;
1306  hy=pt0;
1307 
1308  if (linedrawn) gVirtualX->DrawLine(lx, ly, hx, hy);
1309  break;
1310  }
1311 
1312  case kButton1Up:{
1313  if (px == pw0 && py == pt0) break;
1314  w1 = gPad->AbsPixeltoX(px);
1315  t1 = gPad->AbsPixeltoY(py);
1316 
1317  gPad->Modified(kTRUE);
1318 
1319  // if we are making seeds, process this mouse operation
1320  // in context of how many unconnected seeds we have
1321  if(evdlayoutopt->fMakeSeeds){
1322  LastSeedt1=t1;
1323 
1324  // we keep track of how many seed lines we placed
1325  SeedCounter++;
1326 
1327  // If this is a second seed line, it should match an
1328  // existing line. \todo: Add wire check
1329  if((SeedCounter%3)==2){
1330  if(LastSeedPlane==plane){
1331  ClearLastSeed();
1332  mf::LogVerbatim("TWQProjectionView") <<"Cannot draw seed with 2 lines in same plane!";
1333  linefinished=0;
1334  return 0;
1335  }
1336  if(((LastSeedt0-t0)>MaxSeedTimeDiff)||(LastSeedt1-t1)>MaxSeedTimeDiff){
1337  mf::LogVerbatim("TWQProjectionView")<<"This seed line does not fit the last proj. not adding it";
1338  linefinished=0;
1339  SeedCounter--;
1340  }
1341  else{
1342  // This proj is compatible to make a 3D seed. Indicate this with the linefinished status
1343  mf::LogVerbatim("TWQProjectionView")<<"This is a good seed. adding line and returing 2";
1344  pline=util::PxLine(plane,w0,t0,w1,t1);
1345  linefinished=2;
1346  }
1347 
1348 
1349  }
1350  // If a first seed line, can be drawn with no constraints.
1351  // Put down guide lines in other 2 views for t
1352 
1353  else if((SeedCounter%3)==1){
1354  pline=util::PxLine(plane,w0,t0,w1,t1);
1355  linefinished=1;
1356 
1357  }
1358  // Of it is a thid seed line, something is terribly
1359  // wrong. Shout a warning.
1360  else if((SeedCounter%3)==0){
1361  mf::LogVerbatim("TWQProjectionView") <<"You have been eaten by a Grue. And seed mode is doing something wrong.";
1362  }
1363  }
1364  else{
1365 
1366  pline=util::PxLine(plane,w0,t0,w1,t1);
1367  linefinished=1;
1368  }
1369  //curr_zooming_plane=-1;
1370  //gROOT->SetEditorMode();
1371  }
1372  } //end switch
1373 
1374  return linefinished;
1375  }
1376 
1377  //.......................................................................
1379  {
1380 
1381  TObject *select = gPad->GetSelected();
1382  if(!select) return;
1383  if(!select->InheritsFrom("TBox")) return;
1384 
1385 
1386  util::PxLine ppx;
1387 
1388  if(!DrawLine(plane,ppx))
1389  return;
1390 
1391  curr_zooming_plane=-1;
1392  gROOT->SetEditorMode();
1393 
1394  // check if not clicking on a plane that is already in the ppoints list:
1395  int repeat_plane=-1;
1396 
1397  for(size_t ii = 0; ii < this->pline.size(); ++ii){
1398  if(ppx.plane==this->pline[ii].plane){
1399  this->pline[ii]=ppx;
1400 
1401  //clear View and draw new Marker
1402  this->fPlanes[plane]->Pad()->cd();
1403  this->fPlanes[this->pline[ii].plane]->View()->Clear();
1404  this->fPlanes[this->pline[ii].plane]->View()->Draw();
1405  TLine& l = this->fPlanes[this->pline[ii].plane]->View()->AddLine(pline[ii].w0,
1406  pline[ii].t0,
1407  pline[ii].w1,
1408  pline[ii].t1);
1409  evd::Style::FromPDG(l,11);
1410  this->fPlanes[this->pline[ii].plane]->View()->Draw();
1411  repeat_plane=this->pline[ii].plane;
1412  break;
1413  }
1414  }
1415 
1416  //if plane does not repeat and size of list is larger than 2 pop_front and delete its marker. Otherwise just push_back.
1417  if(repeat_plane==-1){
1418  if( this->pline.size()>=2){
1419  this->fPlanes[this->pline[0].plane]->Pad()->cd();
1420  this->fPlanes[this->pline[0].plane]->View()->Clear();
1421  this->fPlanes[this->pline[0].plane]->View()->Draw();
1422  this->fPlanes[this->pline[0].plane]->Pad()->Clear();
1423  this->fPlanes[this->pline[0].plane]->Pad()->Draw();
1424  this->fPlanes[this->pline[0].plane]->Draw();
1425  this->fPlanes[this->pline[0].plane]->Pad()->Modified();
1426  this->fPlanes[this->pline[0].plane]->Pad()->Update();
1427  this->fPlanes[this->pline[0].plane]->Pad()->GetFrame()->SetBit(TPad::kCannotMove,true);
1428  this->fPlanes[this->pline[0].plane]->Pad()->SetBit(TPad::kCannotMove,true);
1429  this->pline.pop_front();
1430  }
1431 
1432  this->pline.push_back(ppx);
1433  this->fPlanes[plane]->Pad()->cd();
1434  this->fPlanes[plane]->View()->Clear();
1435  this->fPlanes[plane]->View()->Draw();
1436 
1437  int size=pline.size()-1;
1438  TLine& l = this->fPlanes[this->pline[size].plane]->View()->AddLine(pline[size].w0,
1439  pline[size].t0,
1440  pline[size].w1,
1441  pline[size].t1);
1442  this->fPlanes[this->pline[size].plane]->View()->Draw();
1443  evd::Style::FromPDG(l,11);
1444 
1445 
1446  }
1447 
1448  }
1449 
1450  //.......................................................................
1452  {
1454  if(!recoopt->fUseHitSelector) return;
1455 
1456  TObject *select = gPad->GetSelected();
1457  if(!select) return;
1458  if(!select->InheritsFrom("TBox")) return;
1459 
1460 
1461  util::PxLine ppx;
1462 
1463  int DrawStatus = DrawLine(plane,ppx);
1464 
1465  // std::cout<<"Draw status return value for this line " <<DrawStatus<<std::endl;
1466 
1467  if(DrawStatus==0)
1468  return;
1469 
1470  curr_zooming_plane=-1;
1471  gROOT->SetEditorMode();
1472 
1473 
1474  this->seedlines.push_back(ppx);
1475 
1476  if(DrawStatus==1){
1477  // We drew the first of seed projection - go ahead and pass it on, and draq guide lines
1478  for(size_t p = 0; p != fPlanes.size(); ++p)
1479  this->fPlanes[p]->DrawLinesinView(seedlines);
1480  }
1481  else if(DrawStatus==2){
1482  mf::LogVerbatim("TWQProjectionView") << "Adding third seed projection";
1483  // We drew the second seed projection - make the 3D seed
1484 
1485  util::PxLine l0 = seedlines.at(seedlines.size()-1);
1486  util::PxLine l1 = seedlines.at(seedlines.size()-2);
1487 
1488  const detinfo::DetectorProperties* det = lar::providerFrom<detinfo::DetectorPropertiesService>();
1489 
1490  double x0 = det->ConvertTicksToX(l0.t0, l0.plane, 0,0);
1491  double x1 = det->ConvertTicksToX(l0.t1, l0.plane, 0,0);
1492 
1493 
1494 
1495  util::PxPoint thirdp0(0,0,0), thirdp1(0,0,0);
1496 
1497  util::GeometryUtilities geomutil;
1498 
1499  double yz0[2];
1500  double yz1[2];
1501  util::PxPoint l0_pt0 = l0.pt0();
1502  util::PxPoint l0_pt1 = l0.pt1();
1503  util::PxPoint l1_pt0 = l1.pt0();
1504  util::PxPoint l1_pt1 = l1.pt1();
1505  geomutil.GetProjectedPoint(&l0_pt0, &l1_pt0, thirdp0);
1506  geomutil.GetProjectedPoint(&l0_pt1, &l1_pt1, thirdp1);
1507  geomutil.GetYZ(&l0_pt0, &l1_pt0, yz0);
1508  geomutil.GetYZ(&l0_pt1, &l1_pt1, yz1);
1509 
1510  thirdp0.t = det->ConvertXToTicks(x0, thirdp0.plane,0,0);
1511  thirdp1.t = det->ConvertXToTicks(x1, thirdp1.plane,0,0);
1512 
1513  util::PxLine thirdline(thirdp0.plane, thirdp0.w, thirdp0.t, thirdp1.w, thirdp1.t);
1514 
1515  this->seedlines.push_back(thirdline);
1516 
1517  mf::LogVerbatim("TWQProjectionView") <<"Third projection goes "
1518  << thirdline.w0<<" "
1519  <<thirdline.t0<< " to "
1520  << thirdline.w1 << " "
1521  << thirdline.t1;
1522 
1523 
1524  // Update all the views, since we are also adding
1525  // guide lines
1526  for(size_t p=0; p!=fPlanes.size(); ++p){
1527  this->fPlanes[p]->DrawLinesinView(seedlines);
1528  }
1529 
1530 
1531  // Now make an actual seed object to store
1532  // in the hit selector
1533  double seedpt[3], seeddir[3], seederr[3];
1534 
1535  for(int i=0; i!=3; ++i){
1536  seederr[i] = 0;
1537  }
1538 
1539 
1540  seedpt[0] = (x0+x1)/2.;
1541  seeddir[0] = (x1-x0)/2.;
1542 
1543  seedpt[1] = (yz0[0]+yz1[0])/2.;
1544  seeddir[1] = (yz1[0]-yz0[0])/2.;
1545  seedpt[2] = (yz0[1]+yz1[1])/2.;
1546  seeddir[2] = (yz1[1]-yz0[1])/2.;
1547 
1548  recob::Seed NewSeed(seedpt,seeddir,seederr,seederr);
1549  fPlanes[0]->HitSelectorGet()->SeedVector().push_back(NewSeed);
1550  mf::LogVerbatim("TWQProjectionView") <<"Adding seed, vector now of size "
1551  << fPlanes[0]->HitSelectorGet()->SeedVector().size();
1552 
1553 
1554  }
1555 
1556  // Update the bezier curve on the screen, and the track params
1557  // text box
1558  mf::LogVerbatim("TWQProjectionView") << "size of seed vector: "
1559  << fPlanes[0]->HitSelectorGet()->SeedVector().size();
1560 
1561  int NSeeds = fPlanes[0]->HitSelectorGet()->SeedVector().size();
1562 
1563  double Length=0;
1564  std::stringstream ss;
1565  if(NSeeds>1)
1566  Length = UpdateSeedCurve();
1567  else if(NSeeds==1)
1568  Length = fPlanes[0]->HitSelectorGet()->SeedVector().at(0).GetLength()*2.;
1569 
1570  if(Length>0){
1571  ss<<" " << Length<< " cm";
1572  TGText * tt = new TGText(ss.str().c_str());
1573  tt->InsLine(1,"3D Track : ");
1574  fAngleInfo->SetText(tt);
1575  fAngleInfo->Update();
1576  ss.clear();
1577  ss.str("");
1578 
1579  double FirstPt[3], LastPt[3], FirstDir[3], LastDir[3], Err[3];
1580  fPlanes[0]->HitSelectorGet()->SeedVector().at(0).GetPoint(FirstPt,Err);
1581  fPlanes[0]->HitSelectorGet()->SeedVector().at(0).GetDirection(FirstDir,Err);
1582  fPlanes[0]->HitSelectorGet()->SeedVector().at(NSeeds-1).GetPoint(LastPt,Err);
1583  fPlanes[0]->HitSelectorGet()->SeedVector().at(NSeeds-1).GetDirection(LastDir,Err);
1584  for(int i=0; i!=3; ++i){
1585  FirstPt[i] -= FirstDir[i];
1586  LastPt[i] += LastDir[i];
1587  }
1588  ss<<"z| " <<std::setprecision(0)<<std::fixed<< FirstPt[2] <<"," <<"\t" <<LastPt[2];
1589  tt = new TGText(ss.str().c_str());
1590  ss.clear();
1591  ss.str("");
1592 
1593  ss<<"x| " <<std::setprecision(0)<<std::fixed<< FirstPt[0] <<","<<"\t" <<LastPt[0];
1594 
1595 
1596  tt->InsLine(1,ss.str().c_str());
1597  ss.clear();
1598  ss.str("");
1599 
1600  ss<<"y| " <<std::setprecision(0)<<std::fixed<< FirstPt[1] <<","<<"\t" <<LastPt[1];
1601 
1602  tt->InsLine(1,ss.str().c_str());
1603  ss.clear();
1604  ss.str("");
1605 
1606  fXYZPosition->SetText(tt);
1607 
1609 
1610  TVector3 TPCHighBoundary = TVector3(2 * geo->DetHalfWidth(),
1611  geo->DetHalfHeight(),
1612  geo->DetLength());
1613  TVector3 TPCLowBoundary = TVector3(0,
1614  0-geo->DetHalfHeight(),
1615  0);
1616  mf::LogVerbatim("TWQProjectionView") << "Boundaries "
1617  << TPCLowBoundary[0] << " "
1618  << TPCLowBoundary[1] << " "
1619  << TPCLowBoundary[2] << "\n"
1620  << TPCHighBoundary[0] << " "
1621  << TPCHighBoundary[1] << " "
1622  << TPCHighBoundary[2];
1623  bool OverPointFound=false;
1624  for(int i=0; i!=3; ++i){
1625  if((FirstPt[i]>(TPCHighBoundary[i])) ||
1626  (FirstPt[i]<(TPCLowBoundary[i])) ||
1627  (LastPt[i]>(TPCHighBoundary[i])) ||
1628  (LastPt[i]<(TPCLowBoundary[i]))){
1629  mf::LogVerbatim("TWQProjectionView") <<"One point over TPC boundary";
1630  fXYZPosition->SetForegroundColor(0xff0000);
1631  OverPointFound=true;
1632  }
1633  if(!OverPointFound){
1634  if((FirstPt[i]>(TPCHighBoundary[i]-5))||(FirstPt[i]<(TPCLowBoundary[i]+5)) ||
1635  (LastPt[i]>(TPCHighBoundary[i]-5))||(LastPt[i]<(TPCLowBoundary[i]+5))){
1636  mf::LogVerbatim("TWQProjectionView") <<"One point 5cm from TPC boundary";
1637  fXYZPosition->SetForegroundColor(0x0000ff);
1638  OverPointFound=true;
1639  }
1640 
1641  }
1642  }
1643 
1644  fXYZPosition->Update();
1645 
1646  }
1647 
1648  return;
1649  }
1650 
1651  //......................................................................
1653  {
1655  if(!recoopt->fUseHitSelector) return;
1656 
1657  //initial check for a mouse click on a TBox object
1658  int event = gPad->GetEvent();
1659 
1661  if(event!=7) return;
1662 
1664  if(evdlayoutopt->fMakeClusters != 1)
1665  return;
1666  //struct planepoint;
1667  int px = gPad->GetEventX();
1668  double w0 = gPad->AbsPixeltoX(px);
1669  double x = gPad->PadtoX(w0);
1670 
1671  int py = gPad->GetEventY();
1672  double t0 = gPad->AbsPixeltoY(py);
1673  double y = gPad->PadtoY(t0);
1674 
1675  fPlanes[plane]->SelectOneHit(x,y,zoom_opt);
1676  fPlanes[plane]->UpdatePad();
1677  return;
1678 
1679  }
1680 
1681  //......................................................................
1682  // if flag is true then zoom. If flag is false then unzoom.
1684  {
1685  mf::LogVerbatim("TWQProjectionView") <<"ZoomInterest called";
1686 
1687  if(flag==true) zoom_opt="1";
1688  else zoom_opt="0";
1689 
1692 
1693  ZoomOptions zo;
1694  // mf::LogVerbatim("TWQProjectionView") <<"Zoom interest pushing back zoom options"<<std::endl;
1695  fPrevZoomOpt.push_back(fZoomOpt);
1696 
1697 
1698  for(size_t iplane = 0; iplane < fPlanes.size(); ++iplane){
1699  int minw,maxw,mint,maxt;
1700  if(flag){
1701  int test=0;
1702  if(rawopt->fDrawRawDataOrCalibWires == 0)
1703  test = fPlanes[iplane]->RawDataDraw()->GetRegionOfInterest(iplane,minw,maxw,mint,maxt);
1704  else
1705  fPlanes[iplane]->RecoBaseDraw()->GetRegionOfInterest(iplane,minw,maxw,mint,maxt);
1706 
1707  if(test != 0)
1708  continue;
1709  }
1710  else{
1711  minw = -0.005*(geo->Nwires(iplane)-1);
1712  maxw = 1.005*(geo->Nwires(iplane)-1);
1713  mint = -0.005*fPlanes[iplane]->RawDataDraw()->TotalClockTicks();
1714  maxt = 1.01*fPlanes[iplane]->RawDataDraw()->TotalClockTicks();
1715  }
1716 
1717  SetZoom(iplane,minw,maxw,mint,maxt,false);
1718  zo.wmin[iplane]=minw;
1719  zo.tmin[iplane]=mint;
1720  zo.wmax[iplane]=maxw;
1721  zo.tmax[iplane]=maxt;
1722  zo.OnlyPlaneChanged=-1;
1723  }
1724  fZoomOpt=zo;
1725 
1726  }
1727 
1728  //......................................................................
1730  {
1731  SetUpZoomButtons();
1736  }
1737 
1738  //......................................................................
1740  {
1742  evdlayoutopt->fAutoZoomInterest = fToggleAutoZoom->GetState();
1743  SetAutomaticZoomMode(evdlayoutopt->fAutoZoomInterest == 1);
1744  }
1745 
1746  //......................................................................
1748  for (TWireProjPad* pPlane: fPlanes)
1749  pPlane->SetZoomFromView();
1750  }
1751 
1752 
1753  //......................................................................
1755  {
1757  evdlayoutopt->fMakeClusters = fToggleClusters->GetState();
1758  }
1759 
1760 
1761  //......................................................................
1763  {
1765  evdlayoutopt->fMakeSeeds = fToggleSeeds->GetState();
1766  if(evdlayoutopt->fMakeSeeds==true && evdlayoutopt->fMakeClusters==false ){
1767  evdlayoutopt->fMakeClusters = fToggleSeeds->GetState();
1768  fToggleClusters->SetState(kButtonDown);
1769  }
1770  }
1771 
1772  //......................................................................
1774  {
1776  evdlayoutopt->fShowEndPointMarkers= fToggleShowMarkers->GetState();
1777  }
1778 
1779  //......................................................................
1781  LOG_DEBUG("TWQProjectionView") << "Explicit request for redrawing";
1782 
1783  // for now, bother only about redrawing the plane pads
1784  SetZoomFromView();
1785  DrawPads();
1786 
1787  } // TWQProjectionView::ForceRedraw()
1788 
1789  //......................................................................
1791  {
1792  // enter zoom buttons
1794 
1795  fZoomInterest=new TGTextButton(fVFrame,"&Zoom Interest",150);
1796  fZoomInterest->Connect("Clicked()", "evd::TWQProjectionView", this, "ZoomInterest()");
1797 
1798 
1799 
1800  fUnZoomInterest=new TGTextButton(fVFrame,"&UnZoom Interest",150);
1801  fUnZoomInterest->Connect("Clicked()", "evd::TWQProjectionView", this, "ZoomInterest(=false)");
1802 
1803 
1804  fZoomBack=new TGTextButton(fVFrame,"&Zoom Back",150);
1805  fZoomBack->Connect("Clicked()", "evd::TWQProjectionView", this, "ZoomBack()");
1806 
1807 
1808  fToggleAutoZoom=new TGCheckButton(fVFrame,"AutoZoom",0);;
1809  fToggleAutoZoom->Connect("Clicked()", "evd::TWQProjectionView", this, "SetZoomInterest()");
1810  if(evdlayoutopt->fAutoZoomInterest == 1) fToggleAutoZoom->SetState(kButtonDown);
1811 
1812  fVFrame->AddFrame(fZoomInterest, new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 0, 5, 1 ) );
1813  fVFrame->AddFrame(fUnZoomInterest, new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 0, 5, 1 ) );
1814 
1815  fVFrame->AddFrame(fZoomBack, new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 0, 5, 1 ) );
1816 
1817  fVFrame->AddFrame(fToggleAutoZoom, new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 0, 5, 1 ) );
1818  }
1819 
1820  //......................................................................
1822  {
1824  if(!evdlayoutopt->fShowClusterSection)
1825  return;
1826  // enter zoom buttons
1827 
1828  fToggleZoom = new TGRadioButton(fVFrame,"Use Zoom", 2);
1829  fToggleClusters = new TGRadioButton(fVFrame,"Select Clusters", 3);
1830  fToggleSeeds = new TGRadioButton(fVFrame,"Select Seeds", 4);
1831 
1832  fToggleZoom->Connect("Clicked()", "evd::TWQProjectionView", this, "RadioButtonsDispatch(=0)");
1833  fToggleClusters->Connect("Clicked()", "evd::TWQProjectionView", this, "RadioButtonsDispatch(=1)");
1834  fToggleSeeds->Connect("Clicked()", "evd::TWQProjectionView", this, "RadioButtonsDispatch(=2)");
1835 
1836 
1837 
1838  //fToggleClusters=new TGCheckButton(fVFrame,"&Make Clusters",0); ///< Toggle the make cluster setting
1839 
1840  fCalcAngle=new TGTextButton(fVFrame, "&Save Selection", 150);
1841  fCalcAngle->Connect("Clicked()", "evd::TWQProjectionView",this,"SaveSelection()");
1842 
1843  fClear=new TGTextButton(fVFrame, "&Clear Selection",0);
1844  fClear->Connect("Clicked()","evd::TWQProjectionView", this, "ClearSelection()");
1845 
1846  fClearLastSeed=new TGTextButton(fVFrame, "&Clear Last Seed",0);
1847  fClearLastSeed->Connect("Clicked()","evd::TWQProjectionView", this, "ClearLastSeed()");
1848 
1849  // fRefitSeeds=new TGTextButton(fVFrame, "&Refit Seeds",0);
1850  // fRefitSeeds->Connect("Clicked()","evd::TWQProjectionView", this, "RefitSeeds()");
1851 
1852  //fClearSeeds=new TGTextButton(fVFrame, "&Clear All Seeds",0);
1853  //fClearSeeds->Connect("Clicked()","evd::TWQProjectionView", this, "ClearAllSeeds()");
1854 
1855  if(evdlayoutopt->fMakeClusters == 1) fToggleClusters->SetState(kButtonDown);
1856  else if(evdlayoutopt->fMakeSeeds == 1) fToggleSeeds->SetState(kButtonDown);
1857  else fToggleZoom->SetState(kButtonDown);
1858 
1859 
1860 
1861  fAngleInfo=new TGTextView(fVFrame,115,75,999,TGView::kNoHSB | TGView::kNoVSB);
1862  fAngleInfo->SetEditable("false");
1863  TGText *tt=new TGText("...");
1864  fAngleInfo->SetText(tt);
1865 
1866 
1867  fDistance = new TGNumberEntry(fVFrame,0,6,-1,
1868  TGNumberFormat::kNESReal,
1869  TGNumberFormat::kNEAPositive,
1870  TGNumberFormat::kNELLimitMinMax,
1871  0 , 100);
1872  // Initial value
1873  fDistance->SetNumber( 1.5 );
1874 
1875  // There are two "signals" to which a TGNumberEntry may respond:
1876  // when the user clicks on the arrows, or when the user types in a
1877  // new number in the text field.
1878  fDistance->Connect("ValueSet(Long_t)", "evd::TWQProjectionView", this, "SetDistance()");
1879  fDistance->GetNumberEntry()->Connect("ReturnPressed()", "evd::TWQProjectionView", this, "SetDistance()");
1880 
1881  // Text label for this numeric field.
1882  fDistanceLabel= new TGLabel(fVFrame,"Distance");
1883 
1884 
1885  fVFrame->AddFrame(fToggleZoom, new TGLayoutHints(kLHintsTop|kLHintsLeft,0,0,5,1));
1886  fVFrame->AddFrame(fToggleClusters, new TGLayoutHints(kLHintsTop|kLHintsLeft,0,0,5,1));
1887  fVFrame->AddFrame(fToggleSeeds, new TGLayoutHints(kLHintsTop|kLHintsLeft,0,0,5,1));
1888 
1889  fVFrame->AddFrame(fCalcAngle,new TGLayoutHints(kLHintsTop|kLHintsLeft,0,0,5,1));
1890  fVFrame->AddFrame(fClear,new TGLayoutHints(kLHintsTop | kLHintsLeft,0,0,5,1));
1891  fVFrame->AddFrame(fClearLastSeed, new TGLayoutHints(kLHintsTop|kLHintsLeft,0,0,5,1));
1892  // fVFrame->AddFrame(fRefitSeeds, new TGLayoutHints(kLHintsTop|kLHintsLeft,0,0,5,1));
1893 
1894  fVFrame->AddFrame(fDistance, new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 0, 5, 1 ) );
1895  fVFrame->AddFrame(fDistanceLabel, new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 0, 5, 1 ) );
1896 
1897  fVFrame->AddFrame(fAngleInfo,new TGLayoutHints(kLHintsTop | kLHintsLeft,0,0,5,1));
1898 
1899  fVFrame->AddFrame(fDistance, new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 0, 5, 1 ) );
1900 
1901 
1902  //fVFrame->AddFrame(fClearSeeds, new TGLayoutHints(kLHintsTop|kLHintsLeft,0,0,5,1));
1903 
1904  }
1905 
1906  //......................................................................
1908  {
1909  // enter zoom buttons
1910  // art::ServiceHandle<evd::EvdLayoutOptions> evdlayoutopt;
1911 
1912  fRedraw = new TGTextButton(fVFrame, "&Redraw", 120);
1913  fRedraw->Connect("Clicked()", "evd::TWQProjectionView", this, "ForceRedraw()");
1914 
1915  fVFrame->AddFrame(fRedraw, new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 0, 5, 1 ) );
1916 
1917  } // SetUpDrawingButtons()
1918 
1919 
1920  //......................................................................
1921  std::string TWQProjectionView::TotalElementsString(unsigned int NElements)
1922  { return "(" + std::to_string(NElements) + " total)"; }
1923 
1925  {
1928 
1929  TGHorizontalFrame* pRow = nullptr;
1930  //
1931  // Cryostat selection line
1932  //
1933  // this is the subframe with horizontal alignment where we place our widgets:
1934  pRow = new TGHorizontalFrame(fVFrame, 216, 32, kHorizontalFrame);
1935 
1936  geo::CryostatID::CryostatID_t const CurrentCryo = rawOpt->fCryostat;
1937  unsigned int const NCryo = geom.Ncryostats();
1938  if (NCryo > 1) { // allow a selector
1939  unsigned int const NCryoDigits = std::to_string(NCryo - 1).length(); // a silly way fast to code...
1940 
1941  geo::CryostatID::CryostatID_t const CurrentCryo = rawOpt->fCryostat;
1942 
1943  // label
1944  TGLabel* pLabel = new TGLabel(pRow, "Cryo #");
1945  pLabel->SetTextJustify(kTextRight | kTextCenterY);
1946 
1947  // numerical input
1948  fCryoInput = new TGNumberEntry(
1949  pRow, (Double_t) CurrentCryo, // parent widget; starting value;
1950  NCryoDigits, -1, // number of digits for the input field; ID;
1951  TGNumberFormat::kNESInteger, TGNumberFormat::kNEAAnyNumber, // type of number; number attributes;
1952  TGNumberFormat::kNELLimitMinMax, -1, NCryo // limits
1953  );
1954 
1955  TGLabel* pTotalCryoLabel = new TGLabel(pRow, TotalElementsString(NCryo).c_str());
1956  pTotalCryoLabel->SetTextJustify(kTextLeft | kTextCenterY);
1957  // the numbers are padding on the four sides
1958  pRow->AddFrame(pLabel, new TGLayoutHints(kLHintsLeft | kLHintsTop, 2, 2, 5, 5));
1959  pRow->AddFrame(fCryoInput, new TGLayoutHints(kLHintsLeft | kLHintsTop, 2, 2, 2, 2));
1960  pRow->AddFrame(pTotalCryoLabel, new TGLayoutHints(kLHintsLeft | kLHintsTop, 2, 2, 5, 5));
1961 
1962  fCryoInput->Connect("ValueSet(Long_t)", "evd::TWQProjectionView", this, "SelectTPC()");
1963  }
1964  else { // just place a static label
1965  TGLabel* pLabel = new TGLabel(pRow, "Cryo #0 (1 total)");
1966  // the numbers are padding on the four sides
1967  pRow->AddFrame(pLabel, new TGLayoutHints(kLHintsLeft | kLHintsTop, 2, 2, 5, 5));
1968  }
1969 
1970  fVFrame->AddFrame(pRow, new TGLayoutHints(kLHintsLeft | kLHintsTop, 2, 2, 2, 2));
1971 
1972  //
1973  // TPC selection line
1974  //
1975  // this is the subframe with horizontal alignment where we place our widgets:
1976  pRow = new TGHorizontalFrame(fVFrame, 216, 32, kHorizontalFrame);
1977 
1978  unsigned int MaxTPC = geom.MaxTPCs();
1979  if (MaxTPC > 1) { // label, numeric input, then total
1980  unsigned int const NTPCDigits = std::to_string(MaxTPC - 1).length(); // a silly way fast to code...
1981 
1982  geo::TPCID::TPCID_t const CurrentTPC = rawOpt->fTPC;
1983  unsigned int const NTPCs = geom.NTPC(geo::CryostatID(CurrentCryo));
1984 
1985  // label
1986  TGLabel* pLabel = new TGLabel(pRow, "TPC #");
1987  pLabel->SetTextJustify(kTextRight | kTextCenterY);
1988 
1989  // numerical input
1990  fTPCInput = new TGNumberEntry(
1991  pRow, (Double_t) CurrentTPC, // parent widget; starting value;
1992  NTPCDigits, -1, // number of digits for the input field; ID;
1993  TGNumberFormat::kNESInteger, TGNumberFormat::kNEAAnyNumber, // type of number; number attributes;
1994  TGNumberFormat::kNELLimitMinMax, -1, MaxTPC // limits
1995  );
1996 
1997  fTotalTPCLabel = new TGLabel(pRow, TotalElementsString(NTPCs).c_str());
1998  fTotalTPCLabel->SetTextJustify(kTextRight | kTextCenterY);
1999  // the numbers are padding on the four sides
2000  pRow->AddFrame(pLabel, new TGLayoutHints(kLHintsLeft | kLHintsTop, 2, 2, 5, 5));
2001  pRow->AddFrame(fTPCInput, new TGLayoutHints(kLHintsLeft | kLHintsTop, 2, 2, 2, 2));
2002  pRow->AddFrame(fTotalTPCLabel, new TGLayoutHints(kLHintsLeft | kLHintsTop, 2, 2, 5, 5));
2003 
2004  fTPCInput->Connect("ValueSet(Long_t)", "evd::TWQProjectionView", this, "SelectTPC()");
2005  }
2006  else { // just place another static label
2007  TGLabel* pLabel = new TGLabel(pRow, "TPC #0 (1 total)");
2008  // the numbers are padding on the four sides
2009  pRow->AddFrame(pLabel, new TGLayoutHints(kLHintsLeft | kLHintsTop, 2, 2, 5, 5));
2010  }
2011 
2012  fVFrame->AddFrame(pRow, new TGLayoutHints(kLHintsLeft | kLHintsTop, 2, 2, 2, 2));
2013 
2014  } // TWQProjectionView::SetUpTPCselection()
2015 
2016  //----------------------------------------------------------------------------
2018  {
2019  /*
2020  * This function takes care of the input in the cryostat and TPC fields.
2021  * It is called whenever any of the two values (cryostat and TPC) change;
2022  * it can perform a number of tasks:
2023  * - first checks if the new input is valid
2024  * - if it's not, tries to wrap it to a valid TPC ID
2025  * - if it's not possible, goes back to the current TPC
2026  * - if the resulting TPC ID is different from the original one,
2027  * updates the content of the current TPC and cryostat in the service,
2028  * and asks for redrawing
2029  * - if the cryostat is changed, updates the TPC count
2030  * - if it changed the values of the TPC ID respect to what was in input
2031  * at the beginning, then updates the input fields
2032  *
2033  */
2036 
2037  geo::TPCID CurrentTPC(rawOpt.fCryostat, rawOpt.fTPC);
2038  geo::TPCID RequestedTPC(
2039  fCryoInput? (unsigned int) fCryoInput->GetIntNumber(): 0U,
2040  fTPCInput? (unsigned int) fTPCInput->GetIntNumber(): 0U
2041  );
2042  geo::TPCID NewTPC(RequestedTPC);
2043 
2044  // if the input ends up being invalid, try to fix it somehow;
2045  // we give a special meaning to negative values;
2046  // since they are not supported by the container we store them in
2047  // (that is, TPCID) we have to handle negative values as special case:
2048  if (fCryoInput && (fCryoInput->GetIntNumber() < 0)) {
2049  // wrap back to the last cryostat, last TPC
2050  NewTPC.Cryostat = (geo::CryostatID::CryostatID_t) (geom.Ncryostats() - 1);
2051  NewTPC.TPC = (geo::TPCID::TPCID_t) (geom.NTPC(NewTPC) - 1);
2052  }
2053  else if (fTPCInput && (fTPCInput->GetIntNumber() < 0)) {
2054  // wrap back to the previous cryostat, last TPC
2055  if (NewTPC.Cryostat-- == 0)
2056  NewTPC.Cryostat = (geo::CryostatID::CryostatID_t) (geom.Ncryostats() - 1);
2057  NewTPC.TPC = (geo::TPCID::TPCID_t) (geom.NTPC(NewTPC) - 1);
2058  }
2059  else if (!geom.HasTPC(NewTPC)) {
2060  // both elements are positive: it must be overflow
2061  unsigned int const NCryos = geom.Ncryostats();
2062  // what's wrong?
2063  if (NewTPC.Cryostat >= NCryos) { // cryostat wrap
2064  NewTPC.Cryostat = (geo::CryostatID::CryostatID_t) 0;
2065  NewTPC.TPC = (geo::TPCID::TPCID_t) 0;
2066  }
2067  else { // TPC wrap
2068  if (++NewTPC.Cryostat >= NCryos)
2069  NewTPC.Cryostat = (geo::CryostatID::CryostatID_t) 0;
2070  NewTPC.TPC = (geo::TPCID::TPCID_t) 0;
2071  }
2072 
2073  LOG_DEBUG("TWQProjectionView") << __func__ << ": invalid TPC "
2074  << RequestedTPC << ", corrected as " << NewTPC << " instead";
2075  }
2076 
2077  if (!geom.HasTPC(NewTPC)) { // weird...
2078  LOG_ERROR("TWQProjectionView") << __func__ << ": internal error: "
2079  << RequestedTPC << " turned into an invalid TPC " << NewTPC;
2080  }
2081  else if (NewTPC != CurrentTPC) { // do we need to change after all?
2082  LOG_DEBUG("TWQProjectionView") << __func__ << ": switching from "
2083  << CurrentTPC << " to " << NewTPC;
2084 
2085  // new cryostat?
2086  if (rawOpt.fCryostat != NewTPC.Cryostat) { // update the TPC count
2087  unsigned int const NTPCs = geom.NTPC(NewTPC);
2088  fTotalTPCLabel->SetText(TotalElementsString(NTPCs).c_str());
2089  // fTotalTPCLabel->Modified();
2090  }
2091  // update the current TPC in the service
2092  // (that is the thing everything else refers to)
2093  rawOpt.fCryostat = NewTPC.Cryostat;
2094  rawOpt.fTPC = NewTPC.TPC;
2095 
2096  // redraw the content
2098  DrawPads();
2099  // evdb::Canvas::fCanvas->cd();
2100  // evdb::Canvas::fCanvas->Modified();
2101  // evdb::Canvas::fCanvas->Update();
2102  }
2103 
2104  // if we have changed the requested TPC, we need to update the input fields
2105  if (NewTPC != RequestedTPC) {
2106  if (fCryoInput) fCryoInput->SetIntNumber(NewTPC.Cryostat);
2107  if (fTPCInput) fTPCInput->SetIntNumber(NewTPC.TPC);
2108  }
2109 
2110  } // TWQProjectionView::SelectTPC()
2111 
2112 
2113  //----------------------------------------------------------------------------
2115  {
2117  if(parameter==0){evdlayoutopt->fMakeClusters=0;
2118  evdlayoutopt->fMakeSeeds=0;
2119  fToggleClusters->SetState(kButtonUp);
2120  fToggleSeeds->SetState(kButtonUp);
2121  }
2122  else if(parameter==1){
2123  evdlayoutopt->fMakeClusters=1;
2124  evdlayoutopt->fMakeSeeds=0;
2125  fToggleZoom->SetState(kButtonUp);
2126  fToggleSeeds->SetState(kButtonUp);
2127  }
2128  else if(parameter==2){
2129  evdlayoutopt->fMakeClusters=0;
2130  evdlayoutopt->fMakeSeeds=1;
2131  fToggleZoom->SetState(kButtonUp);
2132  fToggleClusters->SetState(kButtonUp);
2133  }
2134 
2135  }
2136 
2137  //......................................................................
2139  {
2140  // enter zoom buttons
2142  if(!evdlayoutopt->fShowEndPointSection)
2143  return;
2144 
2145  // int fShowEndPointMarkers; ///< Draw EndPoint Markers if clicked.
2146 
2147  fFindEndpoint=new TGTextButton(fVFrame,"&Find XYZ",150);
2148  fFindEndpoint->Connect("Clicked()", "evd::TWQProjectionView", this, "FindEndPoint()");
2149 
2150  fXYZPosition=new TGTextView(fVFrame,100,55,999,TGView::kNoHSB | TGView::kNoVSB);
2151  fXYZPosition->SetEditable("false");
2152  TGText *tt=new TGText("x,y,z");
2153  fXYZPosition->SetText(tt);
2154 
2155 
2156  fClearPPoints=new TGTextButton(fVFrame,"&Clear Points",150);
2157  fClearPPoints->Connect("Clicked()", "evd::TWQProjectionView", this, "ClearEndPoints()"); // ?
2158 
2159  fToggleShowMarkers=new TGCheckButton(fVFrame,"ShowMarkers",0);
2160  fToggleShowMarkers->Connect("Clicked()", "evd::TWQProjectionView", this, "ToggleEndPointMarkers()");
2161  if(evdlayoutopt->fShowEndPointMarkers == 1) fToggleShowMarkers->SetState(kButtonDown);
2162 
2163  fVFrame->AddFrame(fFindEndpoint, new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 0, 5, 1 ) );
2164  fVFrame->AddFrame(fXYZPosition, new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 0, 5, 1 ) );
2165  fVFrame->AddFrame(fClearPPoints, new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 0, 5, 1 ) );
2166  fVFrame->AddFrame(fToggleShowMarkers, new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 0, 5, 1 ) );
2167  }
2168 
2169 
2171  // Go back one step in zoom
2172 
2174  {
2175  if(fPrevZoomOpt.size()>0){
2176  ZoomOptions ThePrevZoomOpt = fPrevZoomOpt.at(fPrevZoomOpt.size()-1);
2177  int plane = fZoomOpt.OnlyPlaneChanged;
2178  if(plane != -1){
2179  SetZoom(plane,
2180  ThePrevZoomOpt.wmin[plane],
2181  ThePrevZoomOpt.wmax[plane],
2182  ThePrevZoomOpt.tmin[plane],
2183  ThePrevZoomOpt.tmax[plane],
2184  false);
2185  }
2186  else{
2187  for( size_t iplane = 0; iplane != fPlanes.size(); ++iplane){
2188  SetZoom(iplane,
2189  ThePrevZoomOpt.wmin[iplane],
2190  ThePrevZoomOpt.wmax[iplane],
2191  ThePrevZoomOpt.tmin[iplane],
2192  ThePrevZoomOpt.tmax[iplane],
2193  false);
2194 
2195  }
2196  }
2197 
2198  fPrevZoomOpt.pop_back();
2199  }
2200  else
2201  mf::LogVerbatim("TWQProjectionView") <<"unable to unzoom further - no zoom settings left on stack"<<std::endl;
2202  }
2203 
2204  //------------------------------------
2206  int wirelow,
2207  int wirehi,
2208  int timelow,
2209  int timehi,
2210  bool StoreZoom)
2211  {
2212 
2213  if(StoreZoom){
2214  fPrevZoomOpt.push_back(fZoomOpt);
2215  fZoomOpt.OnlyPlaneChanged = plane;
2216  }
2217 
2218  fZoomOpt.wmin[plane] = wirelow;
2219  fZoomOpt.wmax[plane] = wirehi;
2220  fZoomOpt.tmin[plane] = timelow;
2221  fZoomOpt.tmax[plane] = timehi;
2222 
2223 
2224  TVirtualPad *ori = gPad;
2225  zoom_opt="1";
2226 
2227  // error checking - useful for the mouse zoom.
2228  if(wirehi<wirelow){
2229  int temp=wirelow;
2230  wirelow=wirehi;
2231  wirehi=temp;
2232  }
2233 
2234  if(timehi<timelow){
2235  int temp=timelow;
2236  timelow=timehi;
2237  timehi=temp;
2238  }
2239 
2240  //if drawing, then currently not zooming
2241  curr_zooming_plane=-1;
2242 
2243  fPlanes[plane]->SetZoomRange(wirelow, wirehi,timelow,timehi);
2244  fPlanes[plane]->Draw("1");
2245  fPlanes[plane]->UpdatePad();
2246 
2247  evdb::Canvas::fCanvas->cd();
2248  evdb::Canvas::fCanvas->Modified();
2249  evdb::Canvas::fCanvas->Update();
2250 
2251  // UpdateSeedCurve();
2252 
2253  ori->cd();
2254 
2255  return;
2256  }
2257 
2258  //-----------------------------------------------------------------
2260  {
2261  TVirtualPad *ori = gPad;
2262 
2263  fWireQ->SetPlaneWire(kPlane, kWire);
2264 
2265  fWireQ->Draw();
2266  fWireQ->Pad()->cd();
2267  fWireQ->Pad()->Modified();
2268  fWireQ->Pad()->Update();
2269  fWireQ->Pad()->SetBit(TPad::kCannotMove,true);
2270  fWireQ->Pad()->GetFrame()->SetBit(TPad::kCannotMove,true);
2271 
2272  fPlaneEntry->SetNumber(kPlane);
2273  fWireEntry->SetNumber(kWire);
2274 
2275  evdb::Canvas::fCanvas->cd();
2276  evdb::Canvas::fCanvas->Modified();
2277  evdb::Canvas::fCanvas->Update();
2278 
2279  ori->cd();
2280  }
2281 
2282 
2283 
2284  //-----------------------------------------------------------------
2286  {
2287  kPlane = (unsigned int)fPlaneEntry->GetNumberEntry()->GetNumber();
2288 
2289  this->SetPlaneWire();
2290  }
2291 
2292  //-----------------------------------------------------------------
2294  {
2296  kWire = (geo->Nwires(kPlane)-1 > (unsigned int)fWireEntry->GetNumberEntry()->GetNumber() ) ? (unsigned int)fWireEntry->GetNumberEntry()->GetNumber() : geo->Nwires(kPlane)-1;
2297 
2298  this->SetPlaneWire();
2299  }
2300 
2301  //-----------------------------------------------------------------
2303  {
2304  kDistance = (double)fDistance->GetNumberEntry()->GetNumber();
2305  }
2306 
2307  //-----------------------------------------------------------------
2309  {
2310  double threshold = fThresEntry->GetNumberEntry()->GetNumber();
2311 
2312  if (threshold != fLastThreshold)
2313  {
2315  rawopt->fMinSignal = threshold;
2316 
2317  TVirtualPad *ori = gPad;
2318  this->DrawPads(zoom_opt);
2319  evdb::Canvas::fCanvas->cd();
2320  evdb::Canvas::fCanvas->Modified();
2321  evdb::Canvas::fCanvas->Update();
2322 
2323  ori->cd();
2324  }
2325 
2326  fLastThreshold = threshold;
2327 
2328  return;
2329  }
2330 
2331  //-----------------------------------------------------------------
2333  {
2335 
2336  TGButton *b = (TGButton *)gTQSender;
2337  if(b->GetState() == kButtonDown){
2338  cst->fColorOrGray = 1;
2339  }
2340  else{
2341  cst->fColorOrGray = 0;
2342  }
2343 
2344  TVirtualPad *ori = gPad;
2345  this->DrawPads(zoom_opt);
2346  evdb::Canvas::fCanvas->cd();
2347  evdb::Canvas::fCanvas->Modified();
2348  evdb::Canvas::fCanvas->Update();
2349 
2350  ori->cd();
2351 
2352  return;
2353  }
2354 
2355  //-----------------------------------------------------------------
2357  {
2359 
2360  TGButton *b = (TGButton *)gTQSender;
2361  int id = b->WidgetId();
2362 
2363  // id values are set in lines 125 - 127
2364  if(id == 4){
2365  rawopt->fDrawRawDataOrCalibWires = 0;
2366  fRawDraw->SetState(kButtonDown);
2367  fCalibDraw->SetState(kButtonUp);
2368  fRawCalibDraw->SetState(kButtonUp);
2369  }
2370  else if(id == 3){
2371  rawopt->fDrawRawDataOrCalibWires = 1;
2372  fRawDraw->SetState(kButtonUp);
2373  fCalibDraw->SetState(kButtonDown);
2374  fRawCalibDraw->SetState(kButtonUp);
2375  }
2376  else if(id == 2){
2377  rawopt->fDrawRawDataOrCalibWires = 2;
2378  fRawDraw->SetState(kButtonUp);
2379  fCalibDraw->SetState(kButtonUp);
2380  fRawCalibDraw->SetState(kButtonDown);
2381  }
2382 
2383  TVirtualPad *ori = gPad;
2384 
2385  fWireQ->Draw();
2386  fWireQ->Pad()->cd();
2387  fWireQ->Pad()->Modified();
2388  fWireQ->Pad()->Update();
2389 
2390  this->DrawPads(zoom_opt);
2391  evdb::Canvas::fCanvas->cd();
2392  evdb::Canvas::fCanvas->Modified();
2393  evdb::Canvas::fCanvas->Update();
2394 
2395  ori->cd();
2396 
2397  return;
2398  }
2399 
2400  //-----------------------------------------------------------------
2402  {
2404 
2405  TGButton *b = (TGButton *)gTQSender;
2406  if(b->GetState() == kButtonDown){
2407  sdo->fShowMCTruthText = 1;
2408  sdo->fShowMCTruthVectors = 1;
2409  }
2410  else{
2411  sdo->fShowMCTruthText = 0;
2412  sdo->fShowMCTruthVectors = 0;
2413  }
2414 
2415  TVirtualPad *ori = gPad;
2416 
2417  fMC->Draw();
2418  evdb::Canvas::fCanvas->cd();
2419  evdb::Canvas::fCanvas->Modified();
2420  evdb::Canvas::fCanvas->Update();
2421 
2422  ori->cd();
2423  }
2424 
2425  //-----------------------------------------------------------------
2427  {
2428  double BezLength = util::kBogusD;
2429 
2431  if(!recoopt->fUseHitSelector) return BezLength;
2432 
2433  std::vector<recob::Seed> SeedVec=fPlanes[0]->HitSelectorGet()->SeedVector();
2434  for(size_t p = 0; p != fPlanes.size(); ++p){
2435  // This method draws the existing seed lines on every
2436  // plane, as well as guide lines mid seeding.
2437 
2438  fPlanes[p]->DrawLinesinView(seedlines);
2439 
2440  // The update method draws the curve onto each 2D pad
2441  // and returns the track length.
2442  // note - the length is the same in every view
2443 
2444  BezLength = fPlanes[p]->UpdateSeedCurve(SeedVec, p);
2445  }
2446  return BezLength;
2447  }
2448 
2449 
2450  //-----------------------------------------------------------------
2452 
2453  // first check if it's new...
2454  art::Event const* pEvent = evdb::EventHolder::Instance()->GetEvent();
2455  if (!pEvent) {
2456  if (!fLastEvent->isValid()) return false; // no event before, nor now
2457  fLastEvent->clear();
2458  return true;
2459  }
2460 
2461  // do we have a new event?
2462  if (!fLastEvent->update
2463  ({*pEvent, art::ServiceHandle<evd::RawDrawingOptions>()->fRawDataLabel})
2464  )
2465  return false;
2466 
2467  LOG_DEBUG("TWQProjectionView") << "New event or product: " << *fLastEvent;
2468 
2470  SetAutomaticZoomMode(drawopt->fAutoZoomInterest == 1);
2471 
2472  return true; // yes, a new event is here
2473  } // TWQProjectionView::OnNewEvent()
2474 
2475  //-----------------------------------------------------------------
2476 
2477 }// namespace
Float_t x
Definition: compare.C:6
void SetTestFlag(int value)
Definition: InfoTransfer.h:50
std::vector< ZoomOptions > fPrevZoomOpt
TGNumberEntry * fCryoInput
current cryostat
code to link reconstructed objects back to the MC truth information
TGRadioButton * fToggleClusters
Use make cluster setting.
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
HeaderPad * fHeaderPad
Show header information.
std::deque< util::PxLine > pline
list of lines in each WireProjPad used for calculating 2d and 3d angles, also making seeds (eventuall...
const art::Event * GetEvent() const
Definition: EventHolder.cxx:45
double z
z position of intersection
Definition: geo_types.h:494
Namespace for general, non-LArSoft-specific utilities.
Definition: PIDAAlg.h:17
Double_t xx
Definition: macro.C:12
int fEnableMCTruthCheckBox
1 to have the check box appear, 0 otherwise
double t1
defined to be the ending t-position (of line or seed depending)
Definition: PxUtils.h:72
unsigned int fTPC
TPC number to draw, typically set by TWQProjectionView.
PlaneGeo const & Plane(unsigned int const p, unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified wire.
geo::Length_t DetHalfWidth(geo::TPCID const &tpcid) const
Returns the half width of the active volume of the specified TPC.
TTree * t1
Definition: plottest35.C:26
void SetMouseZoomRegion(int plane)
static unsigned int kWire
virtual int TriggerOffset() const =0
int DrawLine(int plane, util::PxLine &pline)
void SetTestFlag(int number=1)
Drawing pad for short summary of an MC event.
TGTextButton * fCalcAngle
Calculate the 2D & 3D angles between lines.
Drawing pad showing a single X-Z or Y-Z projection of an event.
Display parameters for the raw data.
TGTextButton * fZoomBack
Unzoom on iteresting region.
Double_t Get2Dangle(Double_t deltawire, Double_t deltatime) const
int fDrawRawDataOrCalibWires
0 for raw
TGCompositeFrame * fFrame
Graphics frame.
Definition: Canvas.h:39
Float_t x1[n_points_granero]
Definition: compare.C:5
double fLastThreshold
Kludge to prevent double drawing when changing threshold.
Float_t y
Definition: compare.C:6
unsigned int CryostatID_t
Type for the ID number.
Definition: geo_types.h:121
Double_t z
Definition: plot.C:279
TGTextButton * fZoomInterest
Zoom on iteresting region.
The data type to uniquely identify a Plane.
Definition: geo_types.h:250
void Draw(const char *opt=0)
Drawing pad for time or charge histograms.
bool isZoomAutomatic
true if user did not ask for custom zoom
Float_t ss
Definition: plot.C:23
void ForceRedraw()
Forces a redraw of the window.
TGNumberEntry * fTPCInput
current TPC
TGCheckButton * fToggleShowMarkers
Toggle the ShowEndPointMarkersSetting.
Classes detecting configuration changes.
virtual double SamplingRate() const =0
Returns the period of the TPC readout electronics clock.
TQPad * fWireQ
Histogram of charge vs time on selected wire.
std::map< int, double > wmax
TGTextView * fXYZPosition
Display the xyz position.
static unsigned int kPlane
PxPoint pt1()
Definition: PxUtils.h:67
TCanvas * fCanvas
The ROOT drawing canvas.
Definition: Canvas.h:42
A collection of drawable 2-D objects.
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:313
static void FromPDG(TLine &line, int pdgcode)
Definition: Style.cxx:139
int fMakeClusters
Draw two lines to make clusters if clicked.
void Draw()
Definition: TQPad.cxx:111
SigType_t SignalType(geo::PlaneID const &pid) const
Returns the type of signal on the channels of specified TPC plane.
TGLayoutHints * fLayout
Layout hints for frame.
Definition: Canvas.h:40
unsigned int Ncryostats() const
Returns the number of cryostats in the detector.
TGNumberEntry * fDistance
Distance from line to find hits in cluster.
Manage all things related to colors for the event display.
std::deque< util::PxPoint > ppoints
list of points in each WireProjPad used for x,y,z finding
double w0
defined to be the vertex w-position
Definition: PxUtils.h:69
TGTextButton * fFindEndpoint
Calculate XYZ position of two points in wire planes.
Singleton to hold the current art::Event for the event display.
TGRadioButton * fRawCalibDraw
Draw raw and calibrated information.
void SetAutomaticZoomMode(bool bSet=true)
Records whether we are automatically zooming to the region of interest.
unsigned int Nwires(unsigned int p, unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wires in the specified plane.
static double kDistance
virtual double ConvertXToTicks(double X, int p, int t, int c) const =0
TGRadioButton * fToggleSeeds
Use the make seed setting.
int fMakeSeeds
Draw two lines to make clusters if clicked.
#define LOG_ERROR(category)
int fShowEndPointSection
Show section corresponding to EndPoint finding.
std::vector< double > const & GetCurrentZoom() const
Definition: TWireProjPad.h:79
The color scales used by the event display.
TWQProjectionView(TGMainFrame *mf)
double w1
defined to be the ending w-position (of line or seed depending)
Definition: PxUtils.h:71
Drawing pad for time or charge histograms.
int fShowClusterSection
Show section to make clusters.
Access the description of detector geometry.
Definition: type_traits.h:56
TGCheckButton * fToggleAutoZoom
Toggle the autozoom setting.
TGCompositeFrame * fMetaFrame
needed for the side frame
TGTextButton * fClear
Clears the selected points in an event.
TGTextButton * fClearPPoints
Clear current list of End Points.
unsigned int Nplanes(unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wire planes in the specified TPC.
geo::Length_t DetHalfHeight(geo::TPCID const &tpcid) const
Returns the half height of the active volume of the specified TPC.
TGRadioButton * fToggleZoom
Use zoom setting.
LArSoft includes.
unsigned short fXsize
Size of the canvas;.
Definition: Canvas.h:44
A drawing pad for time vs wire.
Definition: TWireProjPad.h:32
void ResetRegionsOfInterest()
Clear all the regions of interest.
int fAutoZoomInterest
Set the automatic zoom to the interest region.
TGLabel * fTotalTPCLabel
total TPCs in the current cryostat
unsigned int TPCID_t
Type for the ID number.
Definition: geo_types.h:196
unsigned int fCryostat
Cryostat number to draw, typically set by TWQProjectionView.
Class to perform operations needed to select hits and pass them to a cluster.
static EventHolder * Instance()
Definition: EventHolder.cxx:15
double t
Definition: PxUtils.h:11
virtual double Temperature() const =0
static int curr_zooming_plane
geo::WireID::WireID_t NearestWire(geo::Point_t const &point, geo::PlaneID const &planeid) const
Returns the index of wire closest to position in the specified TPC.
int fShowEndPointMarkers
Draw EndPoint Markers if clicked.
double fMinSignal
minimum ADC count to display a time bin
TGTextButton * fRedraw
Button to force redraw.
geo::Length_t DetLength(geo::TPCID const &tpcid) const
Returns the length of the active volume of the specified TPC.
TPad * Pad()
Definition: DrawingPad.h:37
geo::TPCID CurrentTPC() const
Returns the current TPC as a TPCID.
TGCompositeFrame * fVFrame
needed for the side frame
static int shift_lock
void Draw(const char *opt="")
TGNumberEntry * fThresEntry
ADC threshold to display.
std::vector< TQPad * > fPlaneQ
charge on each plane
void SelectTPC()
select TPC from GUI
std::vector< util::PxLine > seedlines
list of lines in each WireProjPad used for calculating 2d and 3d angles, also making seeds (eventuall...
The data type to uniquely identify a TPC.
Definition: geo_types.h:195
Description of geometry of one entire detector.
bool OnNewEvent()
Returns if a new event is detected; if so, it also resets accordingly.
Class to aid in the rendering of RecoBase objects.
void DrawPads(const char *opt="")
TGRadioButton * fCalibDraw
Draw calibrated information only.
Class to aid in the rendering of RawData objects.
void ZoomInterest(bool flag=true)
double w
Definition: PxUtils.h:10
unsigned short fYsize
Size of the canvas;.
Definition: Canvas.h:45
unsigned int NTPC(unsigned int cstat=0) const
Returns the total number of TPCs in the specified cryostat.
void Draw(const char *opt="")
Definition: HeaderPad.cxx:42
TGRadioButton * fRawDraw
Draw Raw information only.
TGTextButton * fUnZoomInterest
Unzoom on iteresting region.
bool WireIDsIntersect(WireID const &wid1, WireID const &wid2, geo::Point_t &intersection) const
Computes the intersection between two wires.
bool HasTPC(geo::TPCID const &tpcid) const
Returns whether we have the specified TPC.
void RadioButtonsDispatch(int parameter)
virtual double ConvertTicksToX(double ticks, int p, int t, int c) const =0
TGNumberEntry * fPlaneEntry
Plane number displayed.
Int_t GetYZ(const PxPoint *p0, const PxPoint *p1, Double_t *yz) const
std::string to_string(Flag_t< Storage > const flag)
Convert a flag into a stream (shows its index).
Definition: BitMask.h:187
Encapsulate the construction of a single detector plane.
std::map< int, double > tmin
virtual double DriftVelocity(double efield=0., double temperature=0.) const =0
double y
y position of intersection
Definition: geo_types.h:493
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
static std::string TotalElementsString(unsigned int NElements)
Returns a string visualizing the total number of elements.
void clear()
Set a new event and data product label as current.
Int_t GetProjectedPoint(const PxPoint *p0, const PxPoint *p1, PxPoint &pN) const
int fColorOrGray
0 = color, 1 = gray
static void MouseDispatch(int plane, void *wqpv)
TGCheckButton * fMCOn
Display MC truth information.
#define LOG_DEBUG(id)
HLT enums.
static const char * zoom_opt
TGTextButton * fClearLastSeed
Clears the selected points in an event.
int fPrintTotalCharge
Print out the total charge in an event.
constexpr double kBogusD
obviously bogus double value
PxPoint pt0()
Definition: PxUtils.h:66
void SetZoom(int plane, int wirelow, int wirehi, int timelo, int timehi, bool StoreZoom=true)
virtual double Efield(unsigned int planegap=0) const =0
Returns the nominal electric field in the specified volume.
MCBriefPad * fMC
Short summary of MC event.
unsigned int plane
Definition: PxUtils.h:73
A view showing the time vs wire, charge and charge vs time information for an event.
std::vector< TWireProjPad * > fPlanes
time vs wire projection for each plane
Namespace collecting geometry-related classes utilities.
bool update(DataProductChangeTracker_t const &new_prod)
Update to a new data product, return true if it has changed.
TGCheckButton * fGreyScale
Display gray or color scale.
util::DataProductChangeTracker_t * fLastEvent
keeps track of latest event
TRootEmbeddedCanvas * fEmbCanvas
Embedded canvas.
Definition: Canvas.h:41
Int_t Get3DaxisN(Int_t iplane0, Int_t iplane1, Double_t omega0, Double_t omega1, Double_t &phi, Double_t &theta) const
unsigned int MaxTPCs() const
Returns the largest number of TPCs a cryostat in the detector has.
double t0
defined to be the vertex t-position
Definition: PxUtils.h:70
void LocalToWorld(const double *plane, double *world) const
Transform point from local plane frame to world frame.
Definition: PlaneGeo.h:1124
TGNumberEntry * fWireEntry
Wire number displayed.
bool isValid() const
Returns whether there is a current event and data product.
art framework interface to geometry description
unsigned int plane
Definition: PxUtils.h:12
constexpr Point origin()
Returns a origin position with a point of the specified type.
Definition: geo_vectors.h:230
Event finding and building.
The data type to uniquely identify a cryostat.
Definition: geo_types.h:120
Signal from collection planes.
Definition: geo_types.h:93
std::map< int, double > wmin
std::map< int, double > tmax
void SetPlaneWire(unsigned int plane=0, unsigned int wire=0)
Definition: TQPad.h:24