Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
JEventProcessor_ST_Propagation_Time.cc
Go to the documentation of this file.
1 // $Id$
2 //
3 // File: JEventProcessor_ST_Propagation_Time.cc
4 // Created: Thu Jan 14 12:16:20 EST 2016
5 // Creator: mkamel (on Linux ifarm1401 2.6.32-431.el6.x86_64 x86_64)
6 //
7 
9 #include "TRIGGER/DTrigger.h"
10 using namespace jana;
11 
12 // Routine used to create our JEventProcessor
13 #include <JANA/JApplication.h>
14 #include <JANA/JFactory.h>
15 extern "C"{
16 void InitPlugin(JApplication *app){
17  InitJANAPlugin(app);
18  app->AddProcessor(new JEventProcessor_ST_Propagation_Time());
19 }
20 } // "C"
21 
22 //------------------
23 // JEventProcessor_ST_Propagation_Time (Constructor)
24 //------------------
26 {
27 
28 }
29 
30 //------------------
31 // ~JEventProcessor_ST_Propagation_Time (Destructor)
32 //------------------
34 {
35 
36 }
37 
38 //------------------
39 // init
40 //------------------
42 {
43  // This is called once at program startup. If you are creating
44  // and filling historgrams in this plugin, you should lock the
45  // ROOT mutex like this:
46  //
47  // japp->RootWriteLock();
48  // ... fill historgrams or trees ...
49  // japp->RootUnLock();
50  //
51  //****** Define Some Constants*********************************
52  int NoBins_time = 200;
53  int NoBins_z = 60;
54  double time_lower_limit = -10.0;
55  double time_upper_limit = 10.0;
56  double z_lower_limit = 0.0;
57  double z_upper_limit = 60.0;
58  Photonspeed = 29.9792458;
59 
60  // **************** define histograms *************************
61 
62  //Create root folder and cd to it, store main dir
63  TDirectory *main = gDirectory;
64  gDirectory->mkdir("ST_Propagation_Time")->cd();
65 
66  h2_PropTime_z_SS_chan = new TH2I*[NCHANNELS];
67  h2_PropTime_z_BS_chan = new TH2I*[NCHANNELS];
68  h2_PropTime_z_NS_chan = new TH2I*[NCHANNELS];
69  h2_PpropTime_z = new TH2I*[NCHANNELS];
70  h2_PropTimeCorr_z_SS_chan = new TH2I*[NCHANNELS];
71  h2_PropTimeCorr_z_BS_chan = new TH2I*[NCHANNELS];
72  h2_PropTimeCorr_z_NS_chan = new TH2I*[NCHANNELS];
73  h2_CorrectedTime_z = new TH2I*[NCHANNELS];
74  for (Int_t i = 0; i < NCHANNELS; i++)
75  {
76  h2_PropTime_z_SS_chan[i] = new TH2I(Form("h2_PropTime_z_SS_chan_%i", i+1), "Prop Time vs. Path length along the paddle; Path length along the paddle (cm); Propagation Time (ns)", NoBins_z,z_lower_limit,z_upper_limit, NoBins_time, time_lower_limit, time_upper_limit);
77  h2_PropTime_z_BS_chan[i] = new TH2I(Form("h2_PropTime_z_BS_chan_%i", i+1), "Prop Time vs. Path length along the paddle; Path length along the paddle (cm); Propagation Time (ns)", NoBins_z,z_lower_limit,z_upper_limit, NoBins_time, time_lower_limit, time_upper_limit);
78  h2_PropTime_z_NS_chan[i] = new TH2I(Form("h2_PropTime_z_NS_chan_%i", i+1), "Prop Time vs. Path length along the paddle; Path length along the paddle (cm); Propagation Time (ns)", NoBins_z,z_lower_limit,z_upper_limit, NoBins_time, time_lower_limit, time_upper_limit);
79  h2_PpropTime_z[i] = new TH2I(Form("h2_PpropTime_z_%i", i+1), "Propagation Time vs. Path length along the paddle; Path length along the paddle (cm); Propagation Time (ns)", NoBins_z,z_lower_limit,z_upper_limit, NoBins_time, time_lower_limit, time_upper_limit);
80 
81 
82  h2_PropTimeCorr_z_SS_chan[i] = new TH2I(Form("h2_PropTimeCorr_z_SS_chan_%i", i+1), "Prop Time vs. Path length along the paddle; Path length along the paddle (cm); Propagation Time (ns)", NoBins_z,z_lower_limit,z_upper_limit, NoBins_time, time_lower_limit, time_upper_limit);
83  h2_PropTimeCorr_z_BS_chan[i] = new TH2I(Form("h2_PropTimeCorr_z_BS_chan_%i", i+1), "Prop Time vs. Path length along the paddle; Path length along the paddle (cm); Propagation Time (ns)", NoBins_z,z_lower_limit,z_upper_limit, NoBins_time, time_lower_limit, time_upper_limit);
84  h2_PropTimeCorr_z_NS_chan[i] = new TH2I(Form("h2_PropTimeCorr_z_NS_chan_%i", i+1), "Prop Time vs. Path length along the paddle; Path length along the paddle (cm); Propagation Time (ns)", NoBins_z,z_lower_limit,z_upper_limit, NoBins_time, time_lower_limit, time_upper_limit);
85  h2_CorrectedTime_z[i] = new TH2I(Form("h2_CorrectedTime_z_%i", i+1), "Corrected Time vs. Path length along the paddle; Path length along the paddle (cm); Propagation Time (ns)", NoBins_z,z_lower_limit,z_upper_limit, NoBins_time, time_lower_limit, time_upper_limit);
86 
87  }
88  // cd back to main directory
89  main->cd();
90 
91  return NOERROR;
92 }
93 
94 //------------------
95 // brun
96 //------------------
97 jerror_t JEventProcessor_ST_Propagation_Time::brun(JEventLoop *eventLoop, int32_t runnumber)
98 {
99  // This is called whenever the run number changes
100  // Get the particleID object for each run
101  vector<const DParticleID *> dParticleID_algos;
102  eventLoop->Get(dParticleID_algos);
103  if(dParticleID_algos.size() < 1)
104  {
105  _DBG_<<"Unable to get a DParticleID object! NO PID will be done!"<<endl;
106  return RESOURCE_UNAVAILABLE;
107  }
108  dParticleID = dParticleID_algos[0];
109  // We want to be use some of the tools available in the RFTime factory
110  // Specifically steping the RF back to a chosen time
111  dRFTimeFactory = static_cast<DRFTime_factory*>(eventLoop->GetFactory("DRFTime"));
112  // Be sure that DRFTime_factory::init() and brun() are called
113  vector<const DRFTime*> locRFTimes;
114  eventLoop->Get(locRFTimes);
115  //RF Period
116  vector<double> locRFPeriodVector;
117  eventLoop->GetCalib("PHOTON_BEAM/RF/rf_period", locRFPeriodVector);
118  dRFBunchPeriod = locRFPeriodVector[0];
119 
120  // Obtain the target center along z;
121  map<string,double> target_params;
122  if (eventLoop->GetCalib("/TARGET/target_parms", target_params))
123  jout << "Error loading /TARGET/target_parms/ !" << endl;
124  if (target_params.find("TARGET_Z_POSITION") != target_params.end())
125  z_target_center = target_params["TARGET_Z_POSITION"];
126  else
127  jerr << "Unable to get TARGET_Z_POSITION from /TARGET/target_parms !" << endl;
128  // Obtain the Start Counter geometry
129  DApplication* dapp = dynamic_cast<DApplication*>(eventLoop->GetJApplication());
130  if(!dapp)
131  _DBG_<<"Cannot get DApplication from JEventLoop! (are you using a JApplication based program?)"<<endl;
132  DGeometry* locGeometry = dapp->GetDGeometry(eventLoop->GetJEvent().GetRunNumber());
133  sc_angle_corr = 1.;
134  if(locGeometry->GetStartCounterGeom(sc_pos, sc_norm)) {
135  double theta = sc_norm[0][sc_norm[0].size()-2].Theta();
136  sc_angle_corr = 1./cos(M_PI_2 - theta);
137  }
138 
139  // Propagation Time constant
140  if(eventLoop->GetCalib("START_COUNTER/propagation_time_corr", propagation_time_corr))
141  jout << "Error loading /START_COUNTER/propagation_time_corr !" << endl;
142  // Propagation Time fit Boundaries
143  if(eventLoop->GetCalib("START_COUNTER/PTC_Boundary", PTC_Boundary))
144  jout << "Error loading /START_COUNTER/PTC_Boundary !" << endl;
145 
146  // configure parameters
147  trackingFOMCut = 0.0027; // 3 sigma cut
148 
149  return NOERROR;
150 
151 }
152 
153 //------------------
154 // evnt
155 //------------------
156 jerror_t JEventProcessor_ST_Propagation_Time::evnt(JEventLoop *loop, uint64_t eventnumber)
157 {
158  // This is called for every event. Use of common resources like writing
159  // to a file or filling a histogram should be mutex protected. Using
160  // loop->Get(...) to get reconstructed objects (and thereby activating the
161  // reconstruction algorithm) should be done outside of any mutex lock
162  // since multiple threads may call this method at the same time.
163  // Here's an example:
164  //
165  // vector<const MyDataClass*> mydataclasses;
166  // loop->Get(mydataclasses);
167  //
168  // japp->RootWriteLock();
169  // ... fill historgrams or trees ...
170  // japp->RootUnLock();
171 
172 
173  // select events with physics events, i.e., not LED and other front panel triggers
174  const DTrigger* locTrigger = NULL;
175  loop->GetSingle(locTrigger);
176  if(locTrigger->Get_L1FrontPanelTriggerBits() != 0)
177  return NOERROR;
178 
179  // SC hits
180  vector<const DSCHit *> scHitVector;
181  loop->Get(scHitVector);
182 
183  // RF time object
184  const DRFTime* thisRFTime = NULL;
185  vector <const DRFTime*> RFTimeVector;
186  loop->Get(RFTimeVector);
187  if (RFTimeVector.size() != 0)
188  thisRFTime = RFTimeVector[0];
189 
190  // Grab charged tracks
191  vector<const DChargedTrack *> chargedTrackVector;
192  loop->Get(chargedTrackVector);
193 
194  // Grab the associated detector matches object
195  const DDetectorMatches* locDetectorMatches = NULL;
196  loop->GetSingle(locDetectorMatches);
197 
198  // Grab the associated RF bunch object
199  const DEventRFBunch *thisRFBunch = NULL;
200  loop->GetSingle(thisRFBunch);
201 
202  double locTOFRFShiftedTime = 9.9E+9;
203  // Loop over the charged tracks
204  for (uint32_t i = 0; i < chargedTrackVector.size(); i++)
205  {
206  shared_ptr<const DSCHitMatchParams> locSCHitMatchParams;
207  shared_ptr<const DTOFHitMatchParams> locTOFHitMatchParams;
208 
209  // Grab the charged track and declare time based track object
210  const DChargedTrack *thisChargedTrack = chargedTrackVector[i];
211  // Grab associated time based track object by selecting charged track with best FOM
212  const DTrackTimeBased *timeBasedTrack = thisChargedTrack->Get_BestTrackingFOM()->Get_TrackTimeBased();
213 
214  // Implement quality cuts for the time based tracks
215  if(timeBasedTrack->FOM < trackingFOMCut) continue;
216 
217  // Define vertex vector and cut on target/scattering chamber geometry
218  DVector3 vertex = timeBasedTrack->position();
219  double z_v = vertex.z();
220  double r_v = vertex.Perp();
221  bool z_vertex_cut = fabs(z_target_center - z_v) <= 15.0;
222  bool r_vertex_cut = r_v < 0.5;
223  // Apply vertex cut
224  if (!z_vertex_cut) continue;
225  if (!r_vertex_cut) continue;
226 
227  // Grab the TOF hit match params object and cut on tracks matched to the TOF
228  // Want to use TOF/RF time for t0 for SC hit time
229  bool foundTOF = dParticleID->Get_BestTOFMatchParams(timeBasedTrack, locDetectorMatches, locTOFHitMatchParams);
230  if (!foundTOF) continue;
231 
232  // If there is a matched track to the SC then skip this track (avoid bias in calibration)
233  bool foundSCandTOF = dParticleID->Get_BestSCMatchParams(timeBasedTrack, locDetectorMatches, locSCHitMatchParams);
234  if (foundSCandTOF) continue;
235 
236  // Cut on the number of particle votes to find the best RF time
237  if (thisRFBunch->dNumParticleVotes < 1) continue;
238  // Calculate the TOF estimate of the target time
239  double locTOFHitTime = locTOFHitMatchParams->dHitTime; // Corrected for timewalk and propagation time
240  double locTOFTrackFlightTime = locTOFHitMatchParams->dFlightTime;
241  double locFlightTimeCorrectedTOFTime = locTOFHitTime - locTOFTrackFlightTime;
242 
243  // Calculate the RF estimate of the target time
244  double locCenteredRFTime = thisRFTime->dTime; // RF time at center of target
245  double locCenterToVertexRFTime = (timeBasedTrack->z() - z_target_center)*(1.0/Photonspeed); // Time correction for photon from target center to vertex of track
246  double locVertexRFTime = locCenteredRFTime + locCenterToVertexRFTime; // RF time progated to vertex time
247  // Correlate the proper RF target time with the TOF "target time"
248  locTOFRFShiftedTime = dRFTimeFactory->Step_TimeToNearInputTime(locVertexRFTime, locFlightTimeCorrectedTOFTime);
249  if (locTOFRFShiftedTime != 9.9E+9)
250  break;
251  }
252  if (locTOFRFShiftedTime != 9.9E+9)
253  {
254  // Loop over the charged tracks
255  for (uint32_t i = 0; i < chargedTrackVector.size(); i++)
256  {
257  shared_ptr<DSCHitMatchParams> locSCHitMatchParams;
258  shared_ptr<const DSCHitMatchParams> locBestSCHitMatchParams;
259  //DTOFHitMatchParams locTOFHitMatchParams;
260 
261  // Grab the charged track and declare time based track object
262  const DChargedTrack *thisChargedTrack = chargedTrackVector[i];
263  // Grab associated time based track object by selecting charged track with best FOM
264  const DTrackTimeBased *timeBasedTrack = thisChargedTrack->Get_BestTrackingFOM()->Get_TrackTimeBased();
265 
266 
267  // Implement quality cuts for the time based tracks
268  if(timeBasedTrack->FOM < trackingFOMCut) continue;
269 
270  // Define vertex vector and cut on target/scattering chamber geometry
271  DVector3 vertex = timeBasedTrack->position();
272  double z_v = vertex.z();
273  double r_v = vertex.Perp();
274  bool z_vertex_cut = fabs(z_target_center - z_v) <= 15.0;
275  bool r_vertex_cut = r_v < 0.5;
276  // Apply vertex cut
277  if (!z_vertex_cut) continue;
278  if (!r_vertex_cut) continue;
279  // Grab the ST hit match params object and cut on tracks matched to the ST
280  bool foundSC = dParticleID->Get_BestSCMatchParams(timeBasedTrack, locDetectorMatches, locBestSCHitMatchParams);
281  if (!foundSC) continue;
282 
283  // Define sector array index
284  int sc_index = locBestSCHitMatchParams->dSCHit->sector - 1;
285  // Start Counter geometry in hall coordinates
286  double sc_pos_soss = sc_pos[sc_index][0].z(); // Start of straight section
287  double sc_pos_eoss = sc_pos[sc_index][1].z(); // End of straight section
288  double sc_pos_eobs = sc_pos[sc_index][11].z(); // End of bend section
289  double sc_pos_eons = sc_pos[sc_index][12].z(); // End of nose section
290 
291  vector<shared_ptr<const DSCHitMatchParams>> st_params;
292  bool sc_match = locDetectorMatches->Get_SCMatchParams(timeBasedTrack, st_params);
293  // If st_match = true, there is a match between this track and the ST
294  if (!sc_match) continue;
295  DVector3 IntersectionPoint, IntersectionMomentum;
296  vector<DTrackFitter::Extrapolation_t>extrapolations=timeBasedTrack->extrapolations.at(SYS_START);
297  bool sc_match_pid = dParticleID->Cut_MatchDistance(extrapolations, st_params[0]->dSCHit, st_params[0]->dSCHit->t, locSCHitMatchParams, true, &IntersectionPoint, &IntersectionMomentum);
298 
299  if(!sc_match_pid) continue;
300  // For each paddle calculate the hit time, flight time, intersection point (z), and t0 from TOF
301  // For each hit we want to calculate thit - tflight - t0 from TOF
302  // Then correlate with hit position along z
303 
304  double locSCHitTime = st_params[0]->dSCHit->t; //Only corrected for time walk
305  double locSCTrackFlightTime = locSCHitMatchParams->dFlightTime;
306  double locFlightTimeCorrectedSCTime = locSCHitTime - locSCTrackFlightTime;
307 
308  double locSCPropTime = locFlightTimeCorrectedSCTime - locTOFRFShiftedTime;
309  // Z intersection of charged track and SC
310  double locSCzIntersection = IntersectionPoint.z();
311  // Calculate the path along the paddle
312  double path_ss=0.,path_bs=0.,path_ns=0.;
313  double SS_Length = sc_pos_eoss - sc_pos_soss;// same for along z or along the paddle
314 
315  /////////////////////////////////////////////
316  // Fill the histograms before corrections////
317  ////////////////////////////////////////////
318  // FILL HISTOGRAMS
319  // Since we are filling histograms local to this plugin, it will not interfere with other ROOT operations: can use plugin-wide ROOT fill lock
320  japp->RootFillLock(this); //ACQUIRE ROOT FILL LOCK
321 
322  // Straight Sections
323  if (locSCzIntersection > sc_pos_soss && locSCzIntersection <= sc_pos_eoss)
324  {
325  path_ss = IntersectionPoint.z() - sc_pos_soss;
326  h2_PropTime_z_SS_chan[sc_index]->Fill(path_ss,locSCPropTime);
327  h2_PpropTime_z[sc_index]->Fill(path_ss,locSCPropTime);
328  }
329  // Bend Sections
330  if(locSCzIntersection > sc_pos_eoss && locSCzIntersection <= sc_pos_eobs)
331  {
332  path_bs = SS_Length + (locSCzIntersection - sc_pos_eoss)*sc_angle_corr;;
333  h2_PropTime_z_BS_chan[sc_index]->Fill(path_bs,locSCPropTime);
334  h2_PpropTime_z[sc_index]->Fill(path_bs,locSCPropTime);
335  }
336  // Nose Sections
337  if(locSCzIntersection > sc_pos_eobs && locSCzIntersection <= sc_pos_eons)
338  {
339  path_ns = SS_Length + (locSCzIntersection - sc_pos_eoss)*sc_angle_corr;;
340  h2_PropTime_z_NS_chan[sc_index]->Fill(path_ns,locSCPropTime);
341  h2_PpropTime_z[sc_index]->Fill(path_ns,locSCPropTime);
342  }
343  ///////////////////////////////////////////////////////////////////
344  /// Fill the propagation time corrected histograms////////////////
345  /////////////////////////////////////////////////////////////////
346  // Read the constants from CCDB
347  double incpt_ss = propagation_time_corr[sc_index][0];
348  double slope_ss = propagation_time_corr[sc_index][1];
349  double incpt_bs = propagation_time_corr[sc_index][2];
350  double slope_bs = propagation_time_corr[sc_index][3];
351  double incpt_ns = propagation_time_corr[sc_index][4];
352  double slope_ns = propagation_time_corr[sc_index][5];
353  //Read fit boundary from CCDB
354  double Bound1 = PTC_Boundary[0][0];
355  double Bound2 = PTC_Boundary[1][0];
356  // Straight Sections
357  if (sc_pos_soss < locSCzIntersection && locSCzIntersection <= sc_pos_eoss)
358  {
359  double Corr_Time_ss = locSCPropTime - (incpt_ss + (slope_ss * path_ss));
360  h2_PropTimeCorr_z_SS_chan[sc_index]->Fill(path_ss,Corr_Time_ss);
361  h2_CorrectedTime_z[sc_index]->Fill(path_ss,Corr_Time_ss);
362  }
363  // Bend Sections:
364  //In new calibration we are using SS constants up to 44 cm.
365  if( sc_pos_eoss < locSCzIntersection && locSCzIntersection <= sc_pos_eobs)
366  {
367  double Corr_Time_bs = locSCPropTime - (incpt_ss + (slope_ss * path_bs));
368  h2_PropTimeCorr_z_BS_chan[sc_index]->Fill(path_bs,Corr_Time_bs);
369  h2_CorrectedTime_z[sc_index]->Fill(path_bs,Corr_Time_bs);
370  }
371  // Nose Sections
372  if(sc_pos_eobs < locSCzIntersection && locSCzIntersection <= sc_pos_eons)
373  {
374 
375  if (path_ns <= Bound1)
376  {
377  double Corr_Time_ns = locSCPropTime - (incpt_ss + (slope_ss * path_ns));
378  h2_PropTimeCorr_z_NS_chan[sc_index]->Fill(path_ns,Corr_Time_ns);
379  h2_CorrectedTime_z[sc_index]->Fill(path_ns,Corr_Time_ns);
380  }
381 
382  else if ((Bound1 < path_ns)&&(path_ns <= Bound2))
383  {
384  double Corr_Time_ns = locSCPropTime - (incpt_bs + (slope_bs * path_ns));
385  h2_PropTimeCorr_z_NS_chan[sc_index]->Fill(path_ns,Corr_Time_ns);
386  h2_CorrectedTime_z[sc_index]->Fill(path_ns,Corr_Time_ns);
387  }
388  else
389  {
390  double Corr_Time_ns = locSCPropTime - (incpt_ns + (slope_ns * path_ns));
391  h2_PropTimeCorr_z_NS_chan[sc_index]->Fill(path_ns,Corr_Time_ns);
392  h2_CorrectedTime_z[sc_index]->Fill(path_ns,Corr_Time_ns);
393  }
394  }
395  japp->RootFillUnLock(this); //RELEASE ROOT FILL LOCK
396  } // sc charged tracks
397  }// TOF reference time
398 
399 
400  return NOERROR;
401 }
402 
403 //------------------
404 // erun
405 //------------------
407 {
408  // This is called whenever the run number changes, before it is
409  // changed to give you a chance to clean up before processing
410  // events from the next run number.
411  return NOERROR;
412 }
413 
414 //------------------
415 // fini
416 //------------------
418 {
419  // Called before program exit after event processing is finished.
420  return NOERROR;
421 }
422 
DApplication * dapp
jerror_t evnt(jana::JEventLoop *eventLoop, uint64_t eventnumber)
Called every event.
double z(void) const
bool Get_SCMatchParams(const DTrackingData *locTrack, vector< shared_ptr< const DSCHitMatchParams > > &locMatchParams) const
TVector3 DVector3
Definition: DVector3.h:14
const Int_t NCHANNELS
jerror_t fini(void)
Called after last event of last event source has been processed.
jerror_t init(void)
Called once at program start.
const DChargedTrackHypothesis * Get_BestTrackingFOM(void) const
Definition: DChargedTrack.h:86
double dTime
Definition: DRFTime.h:24
const DVector3 & position(void) const
const DTrackTimeBased * Get_TrackTimeBased(void) const
jerror_t brun(jana::JEventLoop *eventLoop, int32_t runnumber)
Called everytime a new run number is detected.
uint32_t Get_L1FrontPanelTriggerBits(void) const
jerror_t erun(void)
Called everytime run number changes, provided brun has been called.
JApplication * japp
InitPlugin_t InitPlugin
DGeometry * GetDGeometry(unsigned int run_number)
#define _DBG_
Definition: HDEVIO.h:12
map< DetectorSystem_t, vector< DTrackFitter::Extrapolation_t > > extrapolations
unsigned int dNumParticleVotes
Definition: DEventRFBunch.h:32
double Step_TimeToNearInputTime(double locTimeToStep, double locTimeToStepTo) const
DRFTime_factory * dRFTimeFactory
int main(int argc, char *argv[])
Definition: gendoc.cc:6
bool GetStartCounterGeom(vector< vector< DVector3 > > &pos, vector< vector< DVector3 > > &norm) const
Definition: DGeometry.cc:1983