Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
JEventProcessor_CDC_TimeToDistance.cc
Go to the documentation of this file.
1 // $Id$
2 //
3 // File: JEventProcessor_CDC_TimeToDistance.cc
4 // Created: Mon Nov 9 12:37:01 EST 2015
5 // Creator: mstaib (on Linux ifarm1102 2.6.32-431.el6.x86_64 x86_64)
6 //
7 
9 using namespace jana;
10 
11 
12 // Routine used to create our JEventProcessor
13 #include <JANA/JApplication.h>
14 #include <JANA/JFactory.h>
15 #include "HistogramTools.h"
16 #include "PID/DChargedTrack.h"
18 #include "TRIGGER/DTrigger.h"
20 
21 extern "C"{
22 void InitPlugin(JApplication *app){
23  InitJANAPlugin(app);
24  app->AddProcessor(new JEventProcessor_CDC_TimeToDistance());
25 }
26 } // "C"
27 
28 
29 //------------------
30 // JEventProcessor_CDC_TimeToDistance (Constructor)
31 //------------------
33 {
34 
35 }
36 
37 //------------------
38 // ~JEventProcessor_CDC_TimeToDistance (Destructor)
39 //------------------
41 {
42 
43 }
44 
45 //------------------
46 // init
47 //------------------
49 {
50  // Save the current values of the T/D constants
51 
52  gDirectory->mkdir("CDC_TimeToDistance");
53  gDirectory->cd("CDC_TimeToDistance");
54  // We need the constants used for this iteration
55  // Use a TProfile to avoid problems adding together multiple root files...
56  HistCurrentConstants = new TProfile("CDC_TD_Constants", "CDC T/D constants", 125 ,0.5, 125.5);
57 
58  gDirectory->cd("..");
59 
60  UNBIASED_RING=0;
61  if(gPARMS){
62  gPARMS->SetDefaultParameter("KALMAN:RING_TO_SKIP",UNBIASED_RING);
63  gPARMS->SetDefaultParameter("CDCCOSMIC:EXCLUDERING", UNBIASED_RING);
64  }
65  return NOERROR;
66 }
67 
68 //------------------
69 // brun
70 //------------------
71 jerror_t JEventProcessor_CDC_TimeToDistance::brun(JEventLoop *eventLoop, int32_t runnumber)
72 {
73  // This is called whenever the run number changes
74  DApplication* dapp=dynamic_cast<DApplication*>(eventLoop->GetJApplication());
75  dMagneticField = dapp->GetBfield(runnumber);
76  JCalibration *jcalib = dapp->GetJCalibration(runnumber);
77  // This is called whenever the run number changes
78  // Get the straw sag parameters from the database
79  unsigned int numstraws[28]={42,42,54,54,66,66,80,80,93,93,106,106,123,123,
80  135,135,146,146,158,158,170,170,182,182,197,197,
81  209,209};
82  max_sag.clear();
83  sag_phi_offset.clear();
84  vector< map<string, double> > tvals;
85  unsigned int straw_count=0,ring_count=0;
86  if (jcalib->Get("CDC/sag_parameters", tvals)==false){
87  vector<double>temp,temp2;
88  for(unsigned int i=0; i<tvals.size(); i++){
89  map<string, double> &row = tvals[i];
90 
91  temp.push_back(row["offset"]);
92  temp2.push_back(row["phi"]);
93 
94  straw_count++;
95  if (straw_count==numstraws[ring_count]){
96  max_sag.push_back(temp);
97  sag_phi_offset.push_back(temp2);
98  temp.clear();
99  temp2.clear();
100  straw_count=0;
101  ring_count++;
102  }
103  }
104  }
105 
106  bool dIsNoFieldFlag = (dynamic_cast<const DMagneticFieldMapNoField*>(dapp->GetBfield(runnumber)) != NULL);
107 
108  char ccdbTable[128];
109  sprintf(ccdbTable,"CDC/cdc_drift_table%s",dIsNoFieldFlag?"::NoBField":"");
110 
111  if (jcalib->Get(ccdbTable, tvals)==false){
112  for(unsigned int i=0; i<tvals.size(); i++){
113  map<string, double> &row = tvals[i];
114  HistCurrentConstants->Fill(i+1,1000.*row["t"]);
115  }
116  }
117  else{
118  jerr << " CDC time-to-distance table not available... bailing..." << endl;
119  exit(0);
120  }
121 
122  sprintf(ccdbTable,"CDC/drift_parameters%s",dIsNoFieldFlag?"::NoBField":"");
123  if (jcalib->Get(ccdbTable, tvals)==false){
124  map<string, double> &row = tvals[0]; // long drift side
125  HistCurrentConstants->Fill(101,row["a1"]);
126  HistCurrentConstants->Fill(102,row["a2"]);
127  HistCurrentConstants->Fill(103,row["a3"]);
128  HistCurrentConstants->Fill(104,row["b1"]);
129  HistCurrentConstants->Fill(105,row["b2"]);
130  HistCurrentConstants->Fill(106,row["b3"]);
131  HistCurrentConstants->Fill(107,row["c1"]);
132  HistCurrentConstants->Fill(108,row["c2"]);
133  HistCurrentConstants->Fill(109,row["c3"]);
134  HistCurrentConstants->Fill(110,row["B1"]);
135  HistCurrentConstants->Fill(111,row["B2"]);
136 
137  row = tvals[1]; // short drift side
138  HistCurrentConstants->Fill(112,row["a1"]);
139  HistCurrentConstants->Fill(113,row["a2"]);
140  HistCurrentConstants->Fill(114,row["a3"]);
141  HistCurrentConstants->Fill(115,row["b1"]);
142  HistCurrentConstants->Fill(116,row["b2"]);
143  HistCurrentConstants->Fill(117,row["b3"]);
144  HistCurrentConstants->Fill(118,row["c1"]);
145  HistCurrentConstants->Fill(119,row["c2"]);
146  HistCurrentConstants->Fill(120,row["c3"]);
147  HistCurrentConstants->Fill(121,row["B1"]);
148  HistCurrentConstants->Fill(122,row["B2"]);
149  }
150 
151  // Save run number
152  HistCurrentConstants->Fill(125,runnumber);
153 
154  return NOERROR;
155 }
156 
157 //------------------
158 // evnt
159 //------------------
160 jerror_t JEventProcessor_CDC_TimeToDistance::evnt(JEventLoop *loop, uint64_t eventnumber)
161 {
162  int straw_offset[29] = {0,0,42,84,138,192,258,324,404,484,577,670,776,882,1005,1128,1263,1398,1544,1690,1848,2006,2176,2346,2528,2710,2907,3104,3313};
163 
164  // select events with physics events, i.e., not LED and other front panel triggers
165  const DTrigger* locTrigger = NULL;
166  loop->GetSingle(locTrigger);
167  if(locTrigger->Get_L1FrontPanelTriggerBits() != 0) return NOERROR;
168 
169  // Getting the charged tracks will allow us to use the field on data
170  vector <const DChargedTrack *> chargedTrackVector;
171  loop->Get(chargedTrackVector);
172 
173  for (unsigned int iTrack = 0; iTrack < chargedTrackVector.size(); iTrack++){
174 
175  const DChargedTrackHypothesis* bestHypothesis = chargedTrackVector[iTrack]->Get_BestTrackingFOM();
176 
177  // Require Single track events
178  //if (trackCandidateVector.size() != 1) return NOERROR;
179  //const DTrackCandidate* thisTrackCandidate = trackCandidateVector[0];
180  // Cut very loosely on the track quality
181  auto thisTimeBasedTrack = bestHypothesis->Get_TrackTimeBased();
182  if(!thisTimeBasedTrack->IsSmoothed) continue;
183  if (thisTimeBasedTrack->FOM < 1E-10) continue;
184  vector<DTrackFitter::pull_t> pulls = thisTimeBasedTrack->pulls;
185  // Loop over the pulls to get the appropriate information for our ring
186  for (unsigned int i = 0; i < pulls.size(); i++){
187  DTrackFitter::pull_t thisPull = pulls[i];
188  double residual = thisPull.resi;
189  //double error = thisPull.err;
190  double time = thisPull.tcorr;
191  double docaphi = thisPull.docaphi;
192  if (docaphi > TMath::Pi()) docaphi -= 2 * TMath::Pi();
193  double docaz = thisPull.z;
194  //if (docaz < 70.0 || docaz > 110.0) continue; // Only focus on the center of the chamber
195  //if (docaz < 140.0) continue; // Only focus on downstream end of chamber
196  double predictedDistance = thisPull.d; // This is the DOCA of the track
197  //double distance = residual + predictedDistance; // This is the distance from the T-D lookup
198  const DCDCTrackHit* thisCDCHit = thisPull.cdc_hit;
199 
200  if (thisCDCHit == NULL) continue;
201  if (predictedDistance > 1.5 || predictedDistance < 0.0) continue; // Some strange behavior in field on data?
202  int ring = thisCDCHit->wire->ring;
203  int straw = thisCDCHit->wire->straw;
204 
205  // Fill Histogram with the drift times neat t0 (+-50 ns)
206  Fill2DHistogram("CDC_TimeToDistance","","Early Drift Times",
207  time,straw_offset[ring]+straw,
208  "Per straw drift times; Drift time [ns];CCDB Index",
209  200,-50,50,3522,0.5,3522.5);
210 
211  Fill2DHistogram("CDC_TimeToDistance","","Residual Vs. Drift Time",
212  time,residual,
213  "Residual Vs. Drift Time; Drift time [ns];Residual [cm]",
214  250,0.,1250,100, -0.05,0.05);
215 
216  if(UNBIASED_RING != 0 && (ring != UNBIASED_RING) ) continue;
217 
218  // Now just make a bunch of histograms to display all of the information
219  //Time to distance relation in bins
220  // Calcuate delta
221  double dz = docaz - 92.0;
222  // We need the BField to make a cut for the field on data
223  DVector3 udir = thisCDCHit->wire->udir;
224  DVector3 thisHitLocation = thisCDCHit->wire->origin + udir * (dz / udir.CosTheta());
225  double Bz = dMagneticField->GetBz(thisHitLocation.X(), thisHitLocation.Y(), thisHitLocation.Z());
226  if ( Bz != 0.0 ) {
227  Fill1DHistogram("CDC_TimeToDistance", "", "Bz",
228  Bz,
229  "B_{z};B_{z} [T]", 100, 0.0, 2.5);
230  }
231  double delta = max_sag[ring - 1][straw - 1]*(1.-dz*dz/5625.)
232  *cos(docaphi + sag_phi_offset[ring - 1][straw - 1]);
233  // We only really need one histogram here
234  Fill2DProfile("CDC_TimeToDistance", "", "Predicted Drift Distance Vs Delta Vs t_drift",
235  time, delta, predictedDistance,
236  "Predicted Drift Distance Vs. #delta Vs. t_{drift}; t_{drift} [ns]; #delta [cm]",
237  500, 0, 1500, 200, -0.3, 0.3);
238  // To investigate some features, also do this in bins of Max sag
239  if (max_sag[ring - 1][straw - 1] < 0.05){
240  Fill2DProfile("CDC_TimeToDistance", "", "Predicted Drift Distance Vs Delta Vs t_drift < 0.05",
241  time, delta, predictedDistance,
242  "Predicted Drift Distance Vs. #delta Vs. t_{drift}; t_{drift} [ns]; #delta [cm]",
243  500, 0, 1500, 200, -0.3, 0.3);
244  }
245  else if (max_sag[ring - 1][straw - 1] < 0.10){
246  Fill2DProfile("CDC_TimeToDistance", "", "Predicted Drift Distance Vs Delta Vs t_drift < 0.10",
247  time, delta, predictedDistance,
248  "Predicted Drift Distance Vs. #delta Vs. t_{drift}; t_{drift} [ns]; #delta [cm]",
249  500, 0, 1500, 200, -0.3, 0.3);
250  }
251  else if (max_sag[ring - 1][straw - 1] < 0.15){
252  Fill2DProfile("CDC_TimeToDistance", "", "Predicted Drift Distance Vs Delta Vs t_drift < 0.15",
253  time, delta, predictedDistance,
254  "Predicted Drift Distance Vs. #delta Vs. t_{drift}; t_{drift} [ns]; #delta [cm]",
255  500, 0, 1500, 200, -0.3, 0.3);
256  }
257  else if (max_sag[ring - 1][straw - 1] < 0.20){
258  Fill2DProfile("CDC_TimeToDistance", "", "Predicted Drift Distance Vs Delta Vs t_drift < 0.20",
259  time, delta, predictedDistance,
260  "Predicted Drift Distance Vs. #delta Vs. t_{drift}; t_{drift} [ns]; #delta [cm]",
261  500, 0, 1500, 200, -0.3, 0.3);
262  }
263  else if (max_sag[ring - 1][straw - 1] < 0.25){
264  Fill2DProfile("CDC_TimeToDistance", "", "Predicted Drift Distance Vs Delta Vs t_drift < 0.25",
265  time, delta, predictedDistance,
266  "Predicted Drift Distance Vs. #delta Vs. t_{drift}; t_{drift} [ns]; #delta [cm]",
267  500, 0, 1500, 200, -0.3, 0.3);
268  }
269  }
270  }
271  return NOERROR;
272 }
273 
274 //------------------
275 // erun
276 //------------------
278 {
279  // This is called whenever the run number changes, before it is
280  // changed to give you a chance to clean up before processing
281  // events from the next run number.
282  return NOERROR;
283 }
284 
285 //------------------
286 // fini
287 //------------------
289 {
290  // Called before program exit after event processing is finished.
291  return NOERROR;
292 }
293 
DApplication * dapp
jerror_t brun(jana::JEventLoop *eventLoop, int32_t runnumber)
Called everytime a new run number is detected.
jerror_t fini(void)
Called after last event of last event source has been processed.
const DCDCWire * wire
Definition: DCDCTrackHit.h:37
TVector3 DVector3
Definition: DVector3.h:14
sprintf(text,"Post KinFit Cut")
DMagneticFieldMap * GetBfield(unsigned int run_number=1)
jerror_t evnt(jana::JEventLoop *eventLoop, uint64_t eventnumber)
Called every event.
const DTrackTimeBased * Get_TrackTimeBased(void) const
uint32_t Get_L1FrontPanelTriggerBits(void) const
InitPlugin_t InitPlugin
int straw
Definition: DCDCWire.h:81
const DCDCTrackHit * cdc_hit
Definition: DTrackFitter.h:113
jerror_t init(void)
Called once at program start.
void Fill1DHistogram(const char *plugin, const char *directoryName, const char *name, const double value, const char *title, int nBins, double xmin, double xmax, bool print=false)
void Fill2DHistogram(const char *plugin, const char *directoryName, const char *name, const double valueX, const double valueY, const char *title, int nBinsX, double xmin, double xmax, int nBinsY, double ymin, double ymax, bool print=false)
jerror_t erun(void)
Called everytime run number changes, provided brun has been called.
vector< DTrackFitter::pull_t > pulls
Holds pulls used in chisq calc. (not including off-diagonals)
int ring
Definition: DCDCWire.h:80
void Fill2DProfile(const char *plugin, const char *directoryName, const char *name, const double valueX, const double valueY, const double valueZ, const char *title, int nBinsX, double xmin, double xmax, int nBinsY, double ymin, double ymax, bool print=false)
TH2F * temp