Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DFCALShower_factory.cc
Go to the documentation of this file.
1 //
2 // File: DFCALShower_factory.cc
3 // Created: Tue May 17 11:57:50 EST 2005
4 // Creator: remitche (on Linux mantrid00 2.4.20-18.8smp i686)
5 
6 #include <thread>
7 #include <math.h>
8 #include <DVector3.h>
9 #include "TH2F.h"
10 #include "TROOT.h"
11 #include "TDirectory.h"
12 using namespace std;
13 
15 #include "FCAL/DFCALGeometry.h"
16 #include "FCAL/DFCALCluster.h"
17 #include "FCAL/DFCALHit.h"
19 #include <JANA/JEvent.h>
20 #include <JANA/JApplication.h>
21 using namespace jana;
22 
23 //----------------
24 // Constructor
25 //----------------
27 {
28  // should we use CCDB constants?
29  LOAD_CCDB_CONSTANTS = 1.;
30  gPARMS->SetDefaultParameter("FCAL:LOAD_NONLIN_CCDB", LOAD_CCDB_CONSTANTS);
31 
32  SHOWER_ENERGY_THRESHOLD = 50*k_MeV;
33  gPARMS->SetDefaultParameter("FCAL:SHOWER_ENERGY_THRESHOLD", SHOWER_ENERGY_THRESHOLD);
34 
35  // these need to come from database to ensure accuracy
36  // remove default value which might be close to the right solution,
37  // but not quite correct -- allow command line tuning
38 
39  cutoff_energy= 0;
40  linfit_slope = 0;
41  linfit_intercept = 0;
42  expfit_param1 = 0;
43  expfit_param2 = 0;
44  expfit_param3 = 0;
45 
46  timeConst0 = 0;
47  timeConst1 = 0;
48  timeConst2 = 0;
49  timeConst3 = 0;
50  timeConst4 = 0;
51 
52  gPARMS->SetDefaultParameter("FCAL:cutoff_enegry", cutoff_energy);
53  gPARMS->SetDefaultParameter("FCAL:linfit_slope", linfit_slope);
54  gPARMS->SetDefaultParameter("FCAL:linfit_intercept", linfit_intercept);
55  gPARMS->SetDefaultParameter("FCAL:expfit_param1", expfit_param1);
56  gPARMS->SetDefaultParameter("FCAL:expfit_param2", expfit_param2);
57  gPARMS->SetDefaultParameter("FCAL:expfit_param3", expfit_param3);
58 
59  gPARMS->SetDefaultParameter("FCAL:P0", timeConst0);
60  gPARMS->SetDefaultParameter("FCAL:P1", timeConst1);
61  gPARMS->SetDefaultParameter("FCAL:P2", timeConst2);
62  gPARMS->SetDefaultParameter("FCAL:P3", timeConst3);
63  gPARMS->SetDefaultParameter("FCAL:P4", timeConst4);
64 
65  // Parameters to make shower-depth correction taken from Radphi,
66  // slightly modifed to match photon-polar angle
67  FCAL_RADIATION_LENGTH = 3.1;
68  FCAL_CRITICAL_ENERGY = 0.035;
69  FCAL_SHOWER_OFFSET = 1.0;
70 
71  gPARMS->SetDefaultParameter("FCAL:FCAL_RADIATION_LENGTH", FCAL_RADIATION_LENGTH);
72  gPARMS->SetDefaultParameter("FCAL:FCAL_CRITICAL_ENERGY", FCAL_CRITICAL_ENERGY);
73  gPARMS->SetDefaultParameter("FCAL:FCAL_SHOWER_OFFSET", FCAL_SHOWER_OFFSET);
74 
75  VERBOSE = 0; ///< >0 once off info ; >2 event by event ; >3 everything
76  COVARIANCEFILENAME = ""; ///< Setting the filename will take precidence over the CCDB. Files must end in ij.txt, where i and j are integers corresponding to the element of the matrix
77  gPARMS->SetDefaultParameter("DFCALShower:VERBOSE", VERBOSE, "Verbosity level for DFCALShower objects and factories");
78  gPARMS->SetDefaultParameter("DFCALShower:COVARIANCEFILENAME", COVARIANCEFILENAME, "File name for covariance files");
79 
80 }
81 
82 //------------------
83 // brun
84 //------------------
85 jerror_t DFCALShower_factory::brun(JEventLoop *loop, int32_t runnumber)
86 {
87 
88  // Get calibration constants
89  map<string, double> fcal_parms;
90  loop->GetCalib("FCAL/fcal_parms", fcal_parms);
91  if (fcal_parms.find("FCAL_C_EFFECTIVE")!=fcal_parms.end()){
92  FCAL_C_EFFECTIVE = fcal_parms["FCAL_C_EFFECTIVE"];
93  if(debug_level>0)jout<<"FCAL_C_EFFECTIVE = "<<FCAL_C_EFFECTIVE<<endl;
94  } else {
95  jerr<<"Unable to get FCAL_C_EFFECTIVE from FCAL/fcal_parms in Calib database!"<<endl;
96  }
97 
98  DApplication *dapp = dynamic_cast<DApplication*>(loop->GetJApplication());
99  const DGeometry *geom = dapp->GetDGeometry(runnumber);
100 
101  if (geom) {
102  geom->GetTargetZ(m_zTarget);
103  geom->GetFCALZ(m_FCALfront);
104  }
105  else{
106 
107  cerr << "No geometry accessbile." << endl;
108  return RESOURCE_UNAVAILABLE;
109  }
110 
111  // by default, load non-linear shower corrections from the CCDB
112  // but allow these to be overridden by command line parameters
113  if(LOAD_CCDB_CONSTANTS > 0.1) {
114  map<string, double> shower_calib_piecewise;
115  loop->GetCalib("FCAL/shower_calib_piecewise", shower_calib_piecewise);
116  cutoff_energy = shower_calib_piecewise["cutoff_energy"];
117  linfit_slope = shower_calib_piecewise["linfit_slope"];
118  linfit_intercept = shower_calib_piecewise["linfit_intercept"];
119  expfit_param1 = shower_calib_piecewise["expfit_param1"];
120  expfit_param2 = shower_calib_piecewise["expfit_param2"];
121  expfit_param3 = shower_calib_piecewise["expfit_param3"];
122 
123  if(debug_level>0) {
124  jout << "cutoff_energy = " << cutoff_energy << endl;
125  jout << "linfit_slope = " << linfit_slope << endl;
126  jout << "linfit_intercept = " << linfit_intercept << endl;
127  jout << "expfit_param1 = " << expfit_param1 << endl;
128  jout << "expfit_param2 = " << expfit_param2<< endl;
129  jout << "expfit_param3 = " << expfit_param3 << endl;
130 
131  }
132  }
133 
134  // Get timing correction polynomial, J. Mirabelli 10/31/17
135  if(LOAD_CCDB_CONSTANTS > 0.1) {
136  map<string,double> timing_correction;
137  loop->GetCalib("FCAL/shower_timing_correction", timing_correction);
138  timeConst0 = timing_correction["P0"];
139  timeConst1 = timing_correction["P1"];
140  timeConst2 = timing_correction["P2"];
141  timeConst3 = timing_correction["P3"];
142  timeConst4 = timing_correction["P4"];
143 
144  if(debug_level>0) {
145 
146  jout << "timeConst0 = " << timeConst0 << endl;
147  jout << "timeConst1 = " << timeConst1 << endl;
148  jout << "timeConst2 = " << timeConst2 << endl;
149  jout << "timeConst3 = " << timeConst3 << endl;
150  jout << "timeConst4 = " << timeConst4 << endl;
151  }
152 
153  }
154 
155 
156 
157 
158  jerror_t result = LoadCovarianceLookupTables(eventLoop);
159  if (result!=NOERROR) return result;
160 
161  return NOERROR;
162 }
163 
164 
166  // delete lookup tables to prevent memory leak
167  for (int i=0; i<5; i++) {
168  for (int j=0; j<=i; j++) {
169  delete CovarianceLookupTable[i][j];
170  CovarianceLookupTable[i][j] = nullptr;
171  }
172  }
173  return NOERROR;
174 }
175 
176 
177 //------------------
178 // evnt
179 //------------------
180 jerror_t DFCALShower_factory::evnt(JEventLoop *eventLoop, uint64_t eventnumber)
181 {
182  vector<const DFCALCluster*> fcalClusters;
183  eventLoop->Get(fcalClusters);
184  if(fcalClusters.size()<1)return NOERROR;
185 
186  // Use the center of the target as an approximation for the vertex position
187  DVector3 vertex(0.0, 0.0, m_zTarget);
188 
189  vector< const DTrackWireBased* > allWBTracks;
190  eventLoop->Get( allWBTracks );
191  vector< const DTrackWireBased* > wbTracks = filterWireBasedTracks( allWBTracks );
192 
193  // Loop over list of DFCALCluster objects and calculate the "Non-linear" corrected
194  // energy and position for each. We'll use a logarithmic energy-weighting to
195  // find the final position and error.
196  for( vector< const DFCALCluster* >::const_iterator clItr = fcalClusters.begin();
197  clItr != fcalClusters.end(); ++clItr ){
198  const DFCALCluster* cluster=*clItr;
199 
200  // energy weighted time provides better resolution:
201  double cTime = cluster->getTimeEWeight();
202 
203  double errZ; // will be filled by call to GetCorrectedEnergyAndPosition()
204 
205  // Get corrected energy, position, and errZ
206  double Ecorrected;
207  DVector3 pos_corrected;
208  GetCorrectedEnergyAndPosition( cluster , Ecorrected, pos_corrected, errZ, &vertex);
209 
210  if (Ecorrected>0.){
211  //up to this point, all times have been times at which light reaches
212  //the back of the detector. Here we correct for the time that it
213  //takes the Cherenkov light to reach the back of the detector
214  //so that the t reported is roughly the time of the shower at the
215  //position pos_corrected
216  cTime -= ( m_FCALfront + DFCALGeometry::blockLength() - pos_corrected.Z() )/FCAL_C_EFFECTIVE;
217 
218  //Apply time-walk correction/global timing offset
219  cTime += ( timeConst0 + timeConst1 * Ecorrected + timeConst2 * TMath::Power( Ecorrected, 2 ) +
220  timeConst3 * TMath::Power( Ecorrected, 3 ) + timeConst4 * TMath::Power( Ecorrected, 4 ) );
221 
222  // Make the DFCALShower object
223  DFCALShower* shower = new DFCALShower;
224 
225  shower->setEnergy( Ecorrected );
226  shower->setPosition( pos_corrected );
227  shower->setTime ( cTime );
228  FillCovarianceMatrix( shower );
229 
230  if( VERBOSE > 2 ){
231  printf("FCAL shower: E=%f x=%f y=%f z=%f t=%f\n",
232  shower->getEnergy(),shower->getPosition().X(),shower->getPosition().Y(),shower->getPosition().Z(),shower->getTime());
233  printf("FCAL shower: dE=%f dx=%f dy=%f dz=%f dt=%f\n",
234  shower->EErr(),shower->xErr(),shower->yErr(),shower->zErr(),shower->tErr());
235  printf("FCAL shower: Ex=%f Ey=%f Ez=%f Et=%f xy=%f\n",
236  shower->EXcorr(),shower->EYcorr(),shower->EZcorr(),shower->ETcorr(),shower->XYcorr());
237  printf("FCAL shower: xz=%f xt=%f yz=%f yt=%f zt=%f\n",
238  shower->XZcorr(),shower->XTcorr(),shower->YZcorr(),shower->YTcorr(),shower->ZTcorr());
239  }
240 
241  // now fill information related to shower shape and nearby
242  // tracks -- useful for splitoff rejection later
243 
244  double docaTr = 1E6;
245  double timeTr = 1E6;
246  double xTr = 0;
247  double yTr = 0;
248 
249  double flightTime;
250  DVector3 projPos, projMom;
251 
252  // find the closest track to the shower -- here we loop over the best FOM
253  // wire-based track for every track candidate not just the ones associated
254  // with the topology
255  for( size_t iTrk = 0; iTrk < wbTracks.size(); ++iTrk ){
256 
257  if( !wbTracks[iTrk]->GetProjection( SYS_FCAL, projPos, &projMom, &flightTime ) ) continue;
258 
259  // need to swim fcalPos to common z for DOCA calculation -- this really
260  // shouldn't be in the loop if the z-value of projPos doesn't change
261  // with each track
262 
263  DVector3 fcalFacePos = ( shower->getPosition() - vertex );
264  fcalFacePos.SetMag( fcalFacePos.Mag() * projPos.Z() / fcalFacePos.Z() );
265 
266  double distance = ( fcalFacePos - projPos ).Mag();
267 
268  if( distance < docaTr ){
269 
270  docaTr = distance;
271  // this is the time from the center of the target to the detector -- to compare with
272  // the FCAL time, one needs to have the t0RF at the center of the target. That
273  // comparison happens at a later stage in the analysis.
274  timeTr = ( wbTracks[iTrk]->position().Z() - vertex.Z() ) / SPEED_OF_LIGHT + flightTime;
275  xTr = projPos.X();
276  yTr = projPos.Y();
277  }
278  }
279 
280  shower->setDocaTrack( docaTr );
281  shower->setTimeTrack( timeTr );
282 
283  // now compute some variables at the hit level
284 
285  vector< const DFCALHit* > fcalHits;
286  cluster->Get( fcalHits );
287  shower->setNumBlocks( fcalHits.size() );
288 
289  double e9e25, e1e9;
290  getE1925FromHits( e1e9, e9e25, fcalHits, getMaxHit( fcalHits ) );
291  shower->setE1E9( e1e9 );
292  shower->setE9E25( e9e25 );
293 
294  double sumU = 0;
295  double sumV = 0;
296  // if there is no nearest track, the defaults for xTr and yTr will result
297  // in using the beam axis as the directional axis
298  getUVFromHits( sumU, sumV, fcalHits,
299  DVector3( shower->getPosition().X(), shower->getPosition().Y(), 0 ),
300  DVector3( xTr, yTr, 0 ) );
301 
302  shower->setSumU( sumU );
303  shower->setSumV( sumV );
304 
305  shower->AddAssociatedObject( cluster );
306 
307  _data.push_back(shower);
308  }
309  }
310 
311  return NOERROR;
312 }
313 
314 //--------------------------------
315 // GetCorrectedEnergyAndPosition
316 //
317 // Non-linear and depth corrections should be fixed within DFCALShower member functions
318 //--------------------------------
319 void DFCALShower_factory::GetCorrectedEnergyAndPosition(const DFCALCluster* cluster, double &Ecorrected, DVector3 &pos_corrected, double &errZ, const DVector3 *vertex)
320 {
321  // Non-linear energy correction are done here
322  //int MAXITER = 1000;
323 
324  DVector3 posInCal = cluster->getCentroid();
325  float x0 = posInCal.Px();
326  float y0 = posInCal.Py();
327 
328  double Eclust = cluster->getEnergy();
329 
330  double Ecutoff = cutoff_energy;
331  double A = linfit_slope;
332  double B = linfit_intercept;
333  double C = expfit_param1;
334  double D = expfit_param2;
335  double E = expfit_param3;
336 
337 
338  double Egamma = 0.;
339 
340  // 06/02/2016 Shower Non-linearity Correction by Adesh.
341 
342  if ( Eclust <= Ecutoff ) {
343 
344  Egamma = Eclust/(A*Eclust + B); // Linear part
345 
346  }
347 
348  if ( Eclust > Ecutoff ) {
349 
350  Egamma = Eclust/(C - exp(-D*Eclust+ E)); // Non-linear part
351 
352  }
353 
354  // End Correction
355 
356 
357  // then depth corrections
358  if ( Egamma > 0 ) {
359  float dxV = x0-vertex->X();
360  float dyV = y0-vertex->Y();
361  float zV = vertex->Z();
362 
363  double z0 = m_FCALfront - zV;
364  double zMax = FCAL_RADIATION_LENGTH*(FCAL_SHOWER_OFFSET
365  + log(Egamma/FCAL_CRITICAL_ENERGY));
366  double zed = z0;
367  double zed1 = z0 + zMax;
368 
369  double r0 = sqrt(dxV*dxV + dyV*dyV );
370 
371  int niter;
372  for ( niter=0; niter<100; niter++) {
373  double tt = r0/zed1;
374  zed = z0 + zMax/sqrt( 1 + tt*tt );
375  if ( fabs( (zed-zed1) ) < 0.001) {
376  break;
377  }
378  zed1 = zed;
379  }
380 
381  posInCal.SetZ( zed + zV );
382  errZ = zed - zed1;
383  }
384 
385  Ecorrected = Egamma;
386  pos_corrected = posInCal;
387 }
388 
389 
390 
391 jerror_t
393  /// This function takes a FCALShower object and using the internal variables
394  /// overwrites any existing covaraince matrix using lookup tables.
395 
396  // Get edges of lookup table histograms (assume that all histograms have the same limits.)
397  TAxis *xaxis = CovarianceLookupTable[0][0]->GetXaxis();
398  TAxis *yaxis = CovarianceLookupTable[0][0]->GetYaxis();
399  float minElookup = xaxis->GetBinLowEdge(1);
400  float maxElookup = xaxis->GetBinUpEdge(xaxis->GetNbins());
401  float minthlookup = yaxis->GetBinLowEdge(1);
402  float maxthlookup = yaxis->GetBinUpEdge(yaxis->GetNbins());
403 
404  float shower_E = shower->getEnergy();
405  float shower_x = shower->getPosition().X();
406  float shower_y = shower->getPosition().Y();
407  float shower_z = shower->getPosition().Z();
408  float shower_r = sqrt(shower_x*shower_x + shower_y*shower_y);
409  float shower_theta = atan2(shower_r,shower_z);
410  float thlookup = shower_theta/3.14159265*180;
411  float Elookup = shower_E;
412 
413  // Adjust values: in order to use Interpolate() must be within histogram range
414  if (Elookup<minElookup) Elookup=minElookup;
415  if (Elookup>maxElookup) Elookup=maxElookup-0.0001; // move below edge, on edge doesn't work.
416  if (thlookup<minthlookup) thlookup=minthlookup;
417  if (thlookup>maxthlookup) thlookup=maxthlookup-0.0001;
418  if (VERBOSE>3) printf("(%f,%F) limits (%f,%f) (%f,%f)\n",Elookup,thlookup,minElookup,maxElookup,minthlookup,maxthlookup);
419 
420  DMatrixDSym ErphiztCovariance(5);
421  for (int i=0; i<5; i++) {
422  for (int j=0; j<=i; j++) {
423  float val = CovarianceLookupTable[i][j]->Interpolate(Elookup, thlookup);
424  if (i==0 && j==0) val *= shower_E; // E variance is divided by energy in CCDB
425  ErphiztCovariance(i,j) = ErphiztCovariance(j,i) = val;
426  }
427  }
428 
429  float shower_phi = atan2(shower_y,shower_x);
430  float cosPhi = cos(shower_phi);
431  float sinPhi = sin(shower_phi);
432  DMatrix rotationmatrix(5,5);
433  rotationmatrix(0,0) = 1;
434  rotationmatrix(3,3) = 1;
435  rotationmatrix(4,4) = 1;
436  rotationmatrix(1,1) = cosPhi;
437  rotationmatrix(1,2) = -sinPhi;
438  rotationmatrix(2,1) = sinPhi;
439  rotationmatrix(2,2) = cosPhi;
440 
441  if (VERBOSE>3) {printf("(E,r,phi,z,t) "); ErphiztCovariance.Print(); }
442  DMatrixDSym &D = ErphiztCovariance.Similarity(rotationmatrix);
443  for (int i=0; i<5; i++) {
444  for (int j=0; j<5; j++)
445  shower->ExyztCovariance(i, j) = D(i, j);
446  }
447  if (VERBOSE>2) {printf("(E,x,y,z,t) "); shower->ExyztCovariance.Print(); }
448 
449  return NOERROR;
450 }
451 
452 
453 jerror_t
455  std::thread::id this_id = std::this_thread::get_id();
456  stringstream idstring;
457  idstring << this_id;
458  if (VERBOSE>0) printf("DFCALShower_factory::LoadCovarianceLookupTables(): Thread %s\n",idstring.str().c_str());
459 
460  bool USECCDB=0;
461  bool DUMMYTABLES=0;
462  // if filename specified try to use filename else get info from CCDB
463  if (COVARIANCEFILENAME == "") USECCDB=1;
464 
465  map<string,string> covariance_data;
466  if (USECCDB) {
467  // load information for covariance matrix
468  if (eventLoop->GetJCalibration()->GetCalib("/FCAL/shower_covariance", covariance_data)) {
469  jerr << "Error loading /FCAL/shower_covariance !" << endl;
470  DUMMYTABLES=1;
471  }
472  if (covariance_data.size() == 15) { // there are 15 elements in the covariance matrix
473  // for example, print it all out
474  if (VERBOSE>0) {
475  for(auto element : covariance_data) {
476  cout << "\nTEST: " << element.first << " = " << element.second << endl;
477  }
478  }
479  } else {
480  jerr << "Wrong number of elements /FCAL/shower_covariance !" << endl;
481  DUMMYTABLES=1;
482  }
483  }
484 
485  for (int i=0; i<5; i++) {
486  for (int j=0; j<=i; j++) {
487 
488  japp->RootWriteLock();
489  // change directory to memory so that histograms are not saved to file
490  TDirectory *savedir = gDirectory;
491 
492  char histname[255];
493  sprintf(histname,"covariance_%i%i_thread%s",i,j,idstring.str().c_str());
494  // Read in string
495  ifstream ifs;
496  string line;
497  stringstream ss;
498  if (USECCDB) {
499  stringstream matrixname;
500  matrixname << "covmatrix_" << i << j;
501  if (VERBOSE>1) cout << "Using CCDB \"" << matrixname.str() << "\" " << covariance_data[matrixname.str()] << endl;
502  ss.str(covariance_data[matrixname.str()]);
503  } else {
504  char filename[255];
505  sprintf(filename,"%s%i%i.txt",COVARIANCEFILENAME.c_str(),i,j);
506  if (VERBOSE>0) cout << filename << std::endl;
507  ifs.open(filename);
508  if (! ifs.is_open()) {
509  jerr << " Error: Cannot open file! " << filename << std::endl;
510  DUMMYTABLES=1;
511  } else {
512  getline(ifs, line, '\n');
513  ss.str(line);
514  if (VERBOSE>1) cout << filename << " dump: " <<line<<endl;
515  }
516  }
517  if (DUMMYTABLES) {
518  // create dummy histogram since something went wrong
519  CovarianceLookupTable[i][j] = new TH2F(histname,"Covariance histogram",10,0,12,10,0,12);
520  CovarianceLookupTable[i][j]->SetDirectory(nullptr);
521  } else {
522  // Parse string
523  int nxbins, nybins;
524  ss>>nxbins;
525  ss>>nybins;
526  if (VERBOSE>1) printf("parsed dump: bins (%i,%i)\n",nxbins,nybins);
527  Float_t xbins[nxbins+1];
528  Float_t ybins[nybins+1];
529  for (int count=0; count<=nxbins; count++) {
530  ss>>xbins[count];
531  if (VERBOSE>1) printf("(%i,%f) ",count,xbins[count]);
532  }
533  if (VERBOSE>1) printf("\n");
534  for (int count=0; count<=nybins; count++) {
535  ss>>ybins[count];
536  if (VERBOSE>1) printf("(%i,%f) ",count,ybins[count]);
537  }
538  if (VERBOSE>1) printf("\n");
539  int xbin=1;
540  double cont;
541  int ybin=1;
542  // create histogram
543  CovarianceLookupTable[i][j] = new TH2F(histname,"Covariance histogram",nxbins,xbins,nybins,ybins);
544  CovarianceLookupTable[i][j]->SetDirectory(nullptr);
545  // fill histogram
546  while(ss>>cont){
547  if (VERBOSE>1) printf("(%i,%i) (%i,%i) %e ",i,j,xbin,ybin,cont);
548  CovarianceLookupTable[i][j]->SetBinContent(xbin,ybin,cont);
549  ybin++;
550  if (ybin>nybins) { xbin++; ybin=1; }
551  }
552  if (VERBOSE>1) printf("\n");
553  // Close file
554  ifs.close();
555  }
556  savedir->cd();
557  japp->RootUnLock();
558  }
559  }
560  return NOERROR;
561 }
562 
563 unsigned int
564 DFCALShower_factory::getMaxHit( const vector< const DFCALHit* >& hitVec ) const {
565 
566  unsigned int maxIndex = 0;
567 
568  double eMaxSh = 0;
569 
570  for( vector< const DFCALHit* >::const_iterator hit = hitVec.begin();
571  hit != hitVec.end(); ++hit ){
572 
573  if( (**hit).E > eMaxSh ){
574 
575  eMaxSh = (**hit).E;
576  maxIndex = hit - hitVec.begin();
577  }
578  }
579 
580  return maxIndex;
581 }
582 
583 void
584 DFCALShower_factory::getUVFromHits( double& sumUSh, double& sumVSh,
585  const vector< const DFCALHit* >& hits,
586  const DVector3& showerVec,
587  const DVector3& trackVec ) const {
588 
589  // This method forms an axis pointing from the shower to nearest track
590  // and computes the energy-weighted second moment of the shower along
591  // and perpendicular to this axis. True photons are fairly symmetric
592  // and have similar values of sumU and sumV whereas splitoffs tend
593  // to be asymmetric in these variables.
594 
595  DVector3 u = ( showerVec - trackVec ).Unit();
596  DVector3 z( 0, 0, 1 );
597  DVector3 v = u.Cross( z );
598 
599  DVector3 hitLoc( 0, 0, 0 );
600 
601  sumUSh = 0;
602  sumVSh = 0;
603 
604  double sumE = 0;
605 
606  for( vector< const DFCALHit* >::const_iterator hit = hits.begin();
607  hit != hits.end(); ++hit ){
608 
609  hitLoc.SetX( (**hit).x - showerVec.X() );
610  hitLoc.SetY( (**hit).y - showerVec.Y() );
611 
612  sumUSh += (**hit).E * pow( u.Dot( hitLoc ), 2 );
613  sumVSh += (**hit).E * pow( v.Dot( hitLoc ), 2 );
614 
615  sumE += (**hit).E;
616  }
617 
618  sumUSh /= sumE;
619  sumVSh /= sumE;
620 }
621 
622 void
623 DFCALShower_factory::getE1925FromHits( double& e1e9Sh, double& e9e25Sh,
624  const vector< const DFCALHit* >& hits,
625  unsigned int maxIndex ) const {
626 
627  double E9 = 0;
628  double E25 = 0;
629 
630  const DFCALHit* maxHit = hits[maxIndex];
631 
632  for( vector< const DFCALHit* >::const_iterator hit = hits.begin();
633  hit != hits.end(); ++hit ){
634 
635  if( fabs( (**hit).x - maxHit->x ) < 4.5 && fabs( (**hit).y - maxHit->y ) < 4.5 )
636  E9 += (**hit).E;
637 
638  if( fabs( (**hit).x - maxHit->x ) < 8.5 && fabs( (**hit).y - maxHit->y ) < 8.5 )
639  E25 += (**hit).E;
640  }
641 
642  e1e9Sh = maxHit->E/E9;
643  e9e25Sh = E9/E25;
644 }
645 
646 
647 vector< const DTrackWireBased* >
648 DFCALShower_factory::filterWireBasedTracks( vector< const DTrackWireBased* >& wbTracks ) const {
649 
650  vector< const DTrackWireBased* > finalTracks;
651  map< unsigned int, vector< const DTrackWireBased* > > sortedTracks;
652 
653  // first sort the wire based tracks into lists with a common candidate id
654  // this means that they all come from the same track in the detector
655 
656  for( unsigned int i = 0; i < wbTracks.size(); ++i ){
657 
658  unsigned int id = wbTracks[i]->candidateid;
659 
660  if( sortedTracks.find( id ) == sortedTracks.end() ){
661 
662  sortedTracks[id] = vector< const DTrackWireBased* >();
663  }
664 
665  sortedTracks[id].push_back( wbTracks[i] );
666  }
667 
668  // now loop through that list of unique tracks and for each set
669  // of wire based tracks, choose the one with the highest FOM
670  // (this is choosing among different particle hypotheses)
671 
672  for( map< unsigned int, vector< const DTrackWireBased* > >::const_iterator
673  anId = sortedTracks.begin();
674  anId != sortedTracks.end(); ++anId ){
675 
676  double maxFOM = 0;
677  unsigned int bestIndex = 0;
678 
679  for( unsigned int i = 0; i < anId->second.size(); ++i ){
680 
681  if( anId->second[i]->Ndof < 15 ) continue;
682 
683  if( anId->second[i]->FOM > maxFOM ){
684 
685  maxFOM = anId->second[i]->FOM;
686  bestIndex = i;
687  }
688  }
689 
690  finalTracks.push_back( anId->second[bestIndex] );
691  }
692 
693  return finalTracks;
694 }
void setDocaTrack(const double docaTrack)
Definition: DFCALShower.cc:40
void setTimeTrack(const double tTrack)
Definition: DFCALShower.cc:41
DVector3 getCentroid() const
Definition: DFCALCluster.h:183
double getEnergy() const
Definition: DFCALShower.h:156
DApplication * dapp
float yErr() const
Definition: DFCALShower.h:60
const double k_MeV
Definition: units.h:44
#define SPEED_OF_LIGHT
TMatrixD DMatrix
Definition: DMatrix.h:14
float YZcorr() const
Definition: DFCALShower.h:71
static double blockLength()
Definition: DFCALGeometry.h:50
void setE9E25(const double e9e25)
Definition: DFCALShower.cc:44
TVector3 DVector3
Definition: DVector3.h:14
float xErr() const
Definition: DFCALShower.h:59
float EErr() const
Definition: DFCALShower.h:58
sprintf(text,"Post KinFit Cut")
double getTime() const
Definition: DFCALShower.h:161
float XTcorr() const
Definition: DFCALShower.h:87
TString filename
float XYcorr() const
Definition: DFCALShower.h:63
jerror_t brun(JEventLoop *loop, int32_t runnumber)
double getTimeEWeight() const
Definition: DFCALCluster.h:178
jerror_t LoadCovarianceLookupTables(JEventLoop *eventLoop)
void setTime(const double time)
Definition: DFCALShower.cc:30
void getE1925FromHits(double &e1e9Sh, double &e9e25Sh, const vector< const DFCALHit * > &hits, unsigned int maxIndex) const
float YTcorr() const
Definition: DFCALShower.h:91
TMatrixDSym DMatrixDSym
Definition: DMatrixDSym.h:13
void setSumU(const double sumU)
Definition: DFCALShower.cc:42
bool GetFCALZ(double &z_fcal) const
z-location of front face of CCAL in cm
Definition: DGeometry.cc:1718
unsigned int getMaxHit(const vector< const DFCALHit * > &hitVec) const
void getUVFromHits(double &sumUSh, double &sumVSh, const vector< const DFCALHit * > &hits, const DVector3 &showerVec, const DVector3 &trackVec) const
JApplication * japp
void setPosition(const DVector3 &aPosition)
Definition: DFCALShower.cc:35
float EZcorr() const
Definition: DFCALShower.h:83
double getEnergy() const
Definition: DFCALCluster.h:155
float EYcorr() const
Definition: DFCALShower.h:79
const bool VERBOSE
TMatrixFSym ExyztCovariance
Definition: DFCALShower.h:56
DGeometry * GetDGeometry(unsigned int run_number)
Definition: GlueX.h:22
void setEnergy(const double energy)
Definition: DFCALShower.cc:25
void setE1E9(const double e1e9)
Definition: DFCALShower.cc:45
float tErr() const
Definition: DFCALShower.h:62
float y
Definition: DFCALHit.h:26
float ETcorr() const
Definition: DFCALShower.h:99
double sqrt(double)
double sin(double)
void GetCorrectedEnergyAndPosition(const DFCALCluster *cluster, double &Ecorrected, DVector3 &pos_corrected, double &errZ, const DVector3 *aVertex)
TDirectory * savedir
jerror_t evnt(JEventLoop *eventLoop, uint64_t eventnumber)
Invoked via JEventProcessor virtual method.
float ZTcorr() const
Definition: DFCALShower.h:95
float EXcorr() const
Definition: DFCALShower.h:75
float x
Definition: DFCALHit.h:25
float E
Definition: DFCALHit.h:27
jerror_t FillCovarianceMatrix(DFCALShower *shower)
printf("string=%s", string)
void setSumV(const double sumV)
Definition: DFCALShower.cc:43
DVector3 getPosition() const
Definition: DFCALShower.h:151
vector< const DTrackWireBased * > filterWireBasedTracks(vector< const DTrackWireBased * > &wbTracks) const
float zErr() const
Definition: DFCALShower.h:61
bool GetTargetZ(double &z_target) const
z-location of center of target
Definition: DGeometry.cc:1933
union @6::@8 u
float XZcorr() const
Definition: DFCALShower.h:67
void setNumBlocks(const int numBlocks)
Definition: DFCALShower.cc:46