Hall C ROOT/C++ Analyzer (hcana)
Loading...
Searching...
No Matches
THcHodoscope.cxx
Go to the documentation of this file.
1
12#include "THcSignalHit.h"
14#include "THcShower.h"
15#include "THcCherenkov.h"
17#include "THcHitList.h"
18#include "THcRawShowerHit.h"
19#include "TClass.h"
20#include "cmath"
21#include "THaSubDetector.h"
22
23#include "THcHodoscope.h"
24#include "THaEvData.h"
25#include "THaDetMap.h"
26#include "THcDetectorMap.h"
27#include "THaGlobals.h"
28#include "THaCutList.h"
29#include "THcGlobals.h"
30#include "THcParmList.h"
31#include "VarDef.h"
32#include "VarType.h"
33#include "THaTrack.h"
34#include "TClonesArray.h"
35#include "TMath.h"
36#include "Textvars.h" // for Podd::vsplit
37
38#include "THaTrackProj.h"
39#include <vector>
40
41#include <cstring>
42#include <cstdio>
43#include <cstdlib>
44#include <iostream>
45#include <iomanip>
46#include <fstream>
47#include <cassert>
48
49using namespace std;
50using std::vector;
51
52//_____________________________________________________________________________
53THcHodoscope::THcHodoscope( const char* name, const char* description,
54 THaApparatus* apparatus ) :
55 THaNonTrackingDetector(name,description,apparatus)
56{
57 // Constructor
58
59 //fTrackProj = new TClonesArray( "THaTrackProj", 5 );
60 // Construct the planes
61 fNPlanes = 0; // No planes until we make them
62 fStartTime=-1e5;
64}
65
66//_____________________________________________________________________________
69{
70 // Constructor
71}
72
73//_____________________________________________________________________________
74void THcHodoscope::Setup(const char* name, const char* description)
75{
85 if( IsZombie()) return;
86
87 // fDebug = 1; // Keep this at one while we're working on the code
88
89 char prefix[2];
90
91 prefix[0]=tolower(GetApparatus()->GetName()[0]);
92 prefix[1]='\0';
93
94 TString temp(prefix[0]);
96 if (temp == "p" ) fSHMS=kTRUE;
97 TString histname=temp+"_timehist";
98 hTime = new TH1F(histname,"",400,0,200);
99 // cout << " fSHMS = " << fSHMS << endl;
100 string planenamelist;
101 DBRequest listextra[]={
102 {"hodo_num_planes", &fNPlanes, kInt},
103 {"hodo_plane_names",&planenamelist, kString},
104 {"hodo_tdcrefcut", &fTDC_RefTimeCut, kInt, 0, 1},
105 {"hodo_adcrefcut", &fADC_RefTimeCut, kInt, 0, 1},
106 {0}
107 };
108 //fNPlanes = 4; // Default if not defined
109 fTDC_RefTimeCut = 0; // Minimum allowed reference times
110 fADC_RefTimeCut = 0;
111 gHcParms->LoadParmValues((DBRequest*)&listextra,prefix);
112
113 cout << "Plane Name List : " << planenamelist << endl;
114
115 vector<string> plane_names = Podd::vsplit(planenamelist);
116 // Plane names
117 if(plane_names.size() != (UInt_t) fNPlanes) {
118 cout << "ERROR: Number of planes " << fNPlanes << " doesn't agree with number of plane names " << plane_names.size() << endl;
119 // Should quit. Is there an official way to quit?
120 }
121 fPlaneNames = new char* [fNPlanes];
122 for(Int_t i=0;i<fNPlanes;i++) {
123 fPlaneNames[i] = new char[plane_names[i].length()+1];
124 strcpy(fPlaneNames[i], plane_names[i].c_str());
125 }
126
127 // Probably shouldn't assume that description is defined
128 char* desc = new char[strlen(description)+100];
130 for(Int_t i=0;i < fNPlanes;i++) {
131 strcpy(desc, description);
132 strcat(desc, " Plane ");
133 strcat(desc, fPlaneNames[i]);
134 fPlanes[i] = new THcScintillatorPlane(fPlaneNames[i], desc, i+1, this); // Number planes starting from zero!!
135 cout << "Created Scintillator Plane " << fPlaneNames[i] << ", " << desc << endl;
136 }
137
138 // Save the nominal particle mass
140 fPartMass = app->GetParticleMass();
141 fBetaNominal = app->GetBetaAtPcentral();
142
143
144
145 if (fSHMS) {
146 fCherenkov = dynamic_cast<THcCherenkov*>(app->GetDetector("hgcer"));
147 } else {
148 fCherenkov = dynamic_cast<THcCherenkov*>(app->GetDetector("cer"));
149 }
150
151 delete [] desc;
152}
153
154//_____________________________________________________________________________
156{
157 // cout << "In THcHodoscope::Init()" << endl;
158 Setup(GetName(), GetTitle());
159
160 char EngineDID[] = "xSCIN";
161 EngineDID[0] = toupper(GetApparatus()->GetName()[0]);
162 if( gHcDetectorMap->FillMap(fDetMap, EngineDID) < 0 ) {
163 static const char* const here = "Init()";
164 Error( Here(here), "Error filling detectormap for %s.", EngineDID );
165 return kInitError;
166 }
167
168 // Should probably put this in ReadDatabase as we will know the
169 // maximum number of hits after setting up the detector map
170 // But it needs to happen before the sub detectors are initialized
171 // so that they can get the pointer to the hitlist.
172 cout << " Hodo tdc ref time cut = " << fTDC_RefTimeCut << " " << fADC_RefTimeCut << endl;
173
174 InitHitList(fDetMap, "THcRawHodoHit", fDetMap->GetTotNumChan()+1,
176
177 EStatus status;
178 // This triggers call of ReadDatabase and DefineVariables
179 if( (status = THaNonTrackingDetector::Init( date )) )
180 return fStatus=status;
181
182 for(Int_t ip=0;ip<fNPlanes;ip++) {
183 if((status = fPlanes[ip]->Init( date ))) {
184 return fStatus=status;
185 }
186 }
187
188 fNScinHits = new Int_t [fNPlanes];
190 fNPlaneTime = new Int_t [fNPlanes];
192
193 // Double_t fHitCnt4 = 0., fHitCnt3 = 0.;
194
195 // Int_t m = 0;
196 // fScinHit = new Double_t*[fNPlanes];
197 // for ( m = 0; m < fNPlanes; m++ ){
198 // fScinHit[m] = new Double_t[fNPaddle[0]];
199 // }
200
201 for (int ip=0; ip<fNPlanes; ++ip) {
202 fScinHitPaddle.emplace_back(fNPaddle[ip], 0);
203 }
204
205 fPresentP = 0;
206 THaVar* vpresent = gHaVars->Find(Form("%s.present",GetApparatus()->GetName()));
207 if(vpresent) {
208 fPresentP = (Bool_t *) vpresent->GetValuePointer();
209 }
210
211 return fStatus = kOK;
212}
213//_____________________________________________________________________________
215{
222 // static const char* const here = "ReadDatabase()";
223 char prefix[2];
224 char parname[100];
225
226 // Determine which spectrometer in order to construct
227 // the parameter names (e.g. hscin_1x_nr vs. sscin_1x_nr)
228
229 prefix[0]=tolower(GetApparatus()->GetName()[0]);
230 //
231 prefix[1]='\0';
232 strcpy(parname,prefix);
233 strcat(parname,"scin_");
234 //
235 //
236 // Int_t plen=strlen(parname);
237 // cout << " readdatabse hodo fnplanes = " << fNPlanes << endl;
238
239 CreateMissReportParms(Form("%sscin",prefix));
240
241 fBetaNoTrk = 0.;
242 fBetaNoTrkChiSq = 0.;
243 fNPaddle = new UInt_t [fNPlanes];
244 fFPTime = new Double_t [fNPlanes];
247
248 prefix[0]=tolower(GetApparatus()->GetName()[0]);
249 //
250 prefix[1]='\0';
251
252 for(Int_t i=0;i<fNPlanes;i++) {
253
254 DBRequest list[]={
255 {Form("scin_%s_nr",fPlaneNames[i]), &fNPaddle[i], kInt},
256 {0}
257 };
258
259
260 gHcParms->LoadParmValues((DBRequest*)&list,prefix);
261 }
262
263 // GN added
264 // reading variables from *hodo.param
267 for (Int_t i=1;i<fNPlanes;i++) {
269 fTotHodScin+=(fNPaddle[i]);
270 }
271 // need this for "padded arrays" i.e. 4x16 lists of parameters (GN)
273 if (fDebug>=1) cout <<"fMaxScinPerPlane = "<<fMaxScinPerPlane<<" fMaxHodoScin = "<<fMaxHodoScin<<endl;
274
292
293 //New Time-Walk Calibration Parameters
303
304 fNHodoscopes = 2;
310 fTdcOffset = new Int_t [fNPlanes];
316
317
318 for(Int_t ip=0;ip<fNPlanes;ip++) { // Set a large default window
319 fTdcOffset[ip] = 0 ;
320 fAdcTdcOffset[ip] = 0.0 ;
321 }
322
323 DBRequest list[]={
324 {"cosmicflag", &fCosmicFlag, kInt, 0, 1},
325 {"NumPlanesBetaCalc", &fNumPlanesBetaCalc, kInt, 0, 1},
326 {"start_time_center", &fStartTimeCenter, kDouble},
327 {"start_time_slop", &fStartTimeSlop, kDouble},
328 {"scin_tdc_to_time", &fScinTdcToTime, kDouble},
329 {"scin_tdc_min", &fScinTdcMin, kDouble},
330 {"scin_tdc_max", &fScinTdcMax, kDouble},
331 {"tof_tolerance", &fTofTolerance, kDouble, 0, 1},
332 {"pathlength_central", &fPathLengthCentral, kDouble},
333 {"hodo_pos_sigma", &fHodoPosSigma[0], kDouble, fMaxHodoScin, 1},
334 {"hodo_neg_sigma", &fHodoNegSigma[0], kDouble, fMaxHodoScin, 1},
335 {"hodo_pos_ped_limit", &fHodoPosPedLimit[0], kInt, fMaxHodoScin, 1},
336 {"hodo_neg_ped_limit", &fHodoNegPedLimit[0], kInt, fMaxHodoScin, 1},
337 {"tofusinginvadc", &fTofUsingInvAdc, kInt, 0, 1},
338 {"xloscin", &fxLoScin[0], kInt, (UInt_t) fNHodoscopes},
339 {"xhiscin", &fxHiScin[0], kInt, (UInt_t) fNHodoscopes},
340 {"yloscin", &fyLoScin[0], kInt, (UInt_t) fNHodoscopes},
341 {"yhiscin", &fyHiScin[0], kInt, (UInt_t) fNHodoscopes},
342 {"track_eff_test_num_scin_planes", &fTrackEffTestNScinPlanes, kInt},
343 {"trackeff_scint_ydiff_max", &trackeff_scint_ydiff_max, kDouble, 0, 1},
344 {"trackeff_scint_xdiff_max", &trackeff_scint_xdiff_max, kDouble, 0, 1},
345 {"cer_npe", &fNCerNPE, kDouble, 0, 1},
346 {"normalized_energy_tot", &fNormETot, kDouble, 0, 1},
347 {"hodo_slop", fHodoSlop, kDouble, (UInt_t) fNPlanes},
348 {"debugprintscinraw", &fdebugprintscinraw, kInt, 0,1},
349 {"hodo_tdc_offset", fTdcOffset, kInt, (UInt_t) fNPlanes, 1},
350 {"hodo_adc_tdc_offset", fAdcTdcOffset, kDouble, (UInt_t) fNPlanes, 1},
351 {"hodo_PosAdcTimeWindowMin", fHodoPosAdcTimeWindowMin, kDouble, (UInt_t) fMaxHodoScin, 1},
352 {"hodo_PosAdcTimeWindowMax", fHodoPosAdcTimeWindowMax, kDouble, (UInt_t) fMaxHodoScin, 1},
353 {"hodo_NegAdcTimeWindowMin", fHodoNegAdcTimeWindowMin, kDouble, (UInt_t) fMaxHodoScin, 1},
354 {"hodo_NegAdcTimeWindowMax", fHodoNegAdcTimeWindowMax, kDouble, (UInt_t) fMaxHodoScin, 1},
355 {"dumptof", &fDumpTOF, kInt, 0, 1},
356 {"TOFCalib_shtrk_lo", &fTOFCalib_shtrk_lo, kDouble, 0, 1},
357 {"TOFCalib_shtrk_hi", &fTOFCalib_shtrk_hi, kDouble, 0, 1},
358 {"TOFCalib_cer_lo", &fTOFCalib_cer_lo, kDouble, 0, 1},
359 {"TOFCalib_beta_lo", &fTOFCalib_beta_lo, kDouble, 0, 1},
360 {"TOFCalib_beta_hi", &fTOFCalib_beta_hi, kDouble, 0, 1},
361 {"dumptof_filename", &fTOFDumpFile, kString, 0, 1},
362 {"TrackBetaIncludeSinglePmtHits", &fTrackBetaIncludeSinglePmtHits, kInt, 0, 1},
363 {0}
364 };
365
366 // Defaults if not defined in parameter file
367 fTrackBetaIncludeSinglePmtHits=0; // do not use paddles with only one hit in the TRack Beta calculation set ==1 to include
370 for(UInt_t ip=0;ip<fMaxHodoScin;ip++) {
371 fHodoPosAdcTimeWindowMin[ip] = -1000.;
372 fHodoPosAdcTimeWindowMax[ip] = 1000.;
373 fHodoNegAdcTimeWindowMin[ip] = -1000.;
374 fHodoNegAdcTimeWindowMax[ip] = 1000.;
375
376 fHodoPosPedLimit[ip] = 0.0;
377 fHodoNegPedLimit[ip] = 0.0;
378 fHodoPosSigma[ip] = 0.2;
379 fHodoNegSigma[ip] = 0.2;
380 }
387 fDumpTOF = 0;
388 fTOFDumpFile="";
389 fTofUsingInvAdc = 1;
390 fTofTolerance = 3.0;
391 fNCerNPE = 2.0;
392 fNormETot = 0.7;
393 fCosmicFlag=0;
395 // Gets added to each reference time corrected raw TDC value
396 // to make sure valid range is all positive.
397
398 gHcParms->LoadParmValues((DBRequest*)&list,prefix);
399 if (fCosmicFlag==1) cout << "Setup for cosmics in TOF"<< endl;
400 // cout << " cosmic flag = " << fCosmicFlag << endl;
401 if(fDumpTOF) {
402 fDumpOut.open(fTOFDumpFile.c_str());
403 if(fDumpOut.is_open()) {
404 //fDumpOut << "Hodoscope Time of Flight calibration data" << endl;
405 } else {
406 fDumpTOF = 0;
407 cout << "WARNING: Unable to open TOF Dump file " << fTOFDumpFile << endl;
408 cout << "Data for TOF calibration not being written." << endl;
409 }
410 }
411
412 // cout << " x1 lo = " << fxLoScin[0]
413 // << " x2 lo = " << fxLoScin[1]
414 // << " x1 hi = " << fxHiScin[0]
415 // << " x2 hi = " << fxHiScin[1]
416 // << endl;
417
418 // cout << " y1 lo = " << fyLoScin[0]
419 // << " y2 lo = " << fyLoScin[1]
420 // << " y1 hi = " << fyHiScin[0]
421 // << " y2 hi = " << fyHiScin[1]
422 // << endl;
423
424 // cout << "Hdososcope planes hits for trigger = " << fTrackEffTestNScinPlanes
425 // << " normalized energy min = " << fNormETot
426 // << " number of photo electrons = " << fNCerNPE
427 // << endl;
428
429 //Set scin Velocity/Cable to default
430 for (UInt_t i=0; i<fMaxHodoScin; i++) {
431 fHodoVelLight[i] = 15.0;
432 }
433
434 if (fTofUsingInvAdc) {
435 DBRequest list2[]={
436 {"hodo_vel_light", &fHodoVelLight[0], kDouble, fMaxHodoScin, 1},
437 {"hodo_pos_invadc_offset",&fHodoPosInvAdcOffset[0],kDouble,fMaxHodoScin},
438 {"hodo_neg_invadc_offset",&fHodoNegInvAdcOffset[0],kDouble,fMaxHodoScin},
439 {"hodo_pos_invadc_linear",&fHodoPosInvAdcLinear[0],kDouble,fMaxHodoScin},
440 {"hodo_neg_invadc_linear",&fHodoNegInvAdcLinear[0],kDouble,fMaxHodoScin},
441 {"hodo_pos_invadc_adc",&fHodoPosInvAdcAdc[0],kDouble,fMaxHodoScin},
442 {"hodo_neg_invadc_adc",&fHodoNegInvAdcAdc[0],kDouble,fMaxHodoScin},
443 {0}
444 };
445
446 gHcParms->LoadParmValues((DBRequest*)&list2,prefix);
447 };
448 /* if (!fTofUsingInvAdc) {
449 DBRequest list3[]={
450 {"hodo_vel_light", &fHodoVelLight[0], kDouble, fMaxHodoScin},
451 {"hodo_pos_minph", &fHodoPosMinPh[0], kDouble, fMaxHodoScin},
452 {"hodo_neg_minph", &fHodoNegMinPh[0], kDouble, fMaxHodoScin},
453 {"hodo_pos_phc_coeff", &fHodoPosPhcCoeff[0], kDouble, fMaxHodoScin},
454 {"hodo_neg_phc_coeff", &fHodoNegPhcCoeff[0], kDouble, fMaxHodoScin},
455 {"hodo_pos_time_offset", &fHodoPosTimeOffset[0], kDouble, fMaxHodoScin},
456 {"hodo_neg_time_offset", &fHodoNegTimeOffset[0], kDouble, fMaxHodoScin},
457 {0}
458 };
459
460
461 gHcParms->LoadParmValues((DBRequest*)&list3,prefix);
462 */
463 DBRequest list4[]={
464 {"hodo_velFit", &fHodoVelFit[0], kDouble, fMaxHodoScin, 1},
465 {"hodo_cableFit", &fHodoCableFit[0], kDouble, fMaxHodoScin, 1},
466 {"hodo_LCoeff", &fHodo_LCoeff[0], kDouble, fMaxHodoScin, 1},
467 {"c1_Pos", &fHodoPos_c1[0], kDouble, fMaxHodoScin, 1},
468 {"c1_Neg", &fHodoNeg_c1[0], kDouble, fMaxHodoScin, 1},
469 {"c2_Pos", &fHodoPos_c2[0], kDouble, fMaxHodoScin, 1},
470 {"c2_Neg", &fHodoNeg_c2[0], kDouble, fMaxHodoScin, 1},
471 {"TDC_threshold", &fTdc_Thrs, kDouble, 0, 1},
472 {"hodo_PosSigma", &fHodoSigmaPos[0], kDouble, fMaxHodoScin, 1},
473 {"hodo_NegSigma", &fHodoSigmaNeg[0], kDouble, fMaxHodoScin, 1},
474 {0}
475 };
476
477 fTdc_Thrs = 1.0;
478 //Set Default Values if NOT defined in param file
479 for (UInt_t i=0; i<fMaxHodoScin; i++)
480 {
481
482 //Turn OFF Time-Walk Correction if param file NOT found
483 fHodoPos_c1[i] = 0.0;
484 fHodoPos_c2[i] = 0.0;
485 fHodoNeg_c1[i] = 0.0;
486 fHodoNeg_c2[i] = 0.0;
487 }
488 for (UInt_t i=0; i<fMaxHodoScin; i++)
489 {
490 //Set scin Velocity/Cable to default
491 fHodoCableFit[i] = 0.0;
492 fHodoVelFit[i] = 15.0;
493 //set time coeff between paddles to default
494 fHodo_LCoeff[i] = 0.0;
495
496 }
497
498 gHcParms->LoadParmValues((DBRequest*)&list4,prefix);
499
500 if (fDebug >=1) {
501 cout <<"******* Testing Hodoscope Parameter Reading ***\n";
502 cout<<"StarTimeCenter = "<<fStartTimeCenter<<endl;
503 cout<<"StartTimeSlop = "<<fStartTimeSlop<<endl;
504 cout <<"ScintTdcToTime = "<<fScinTdcToTime<<endl;
505 cout <<"TdcMin = "<<fScinTdcMin<<" TdcMax = "<<fScinTdcMax<<endl;
506 cout <<"TofTolerance = "<<fTofTolerance<<endl;
507 cout <<"*** VelLight ***\n";
508 for (Int_t i1=0;i1<fNPlanes;i1++) {
509 cout<<"Plane "<<i1<<endl;
510 for (UInt_t i2=0;i2<fMaxScinPerPlane;i2++) {
511 cout<<fHodoVelLight[GetScinIndex(i1,i2)]<<" ";
512 }
513 cout <<endl;
514 }
515 cout <<endl<<endl;
516 // check fHodoPosPhcCoeff
517 /*
518 cout <<"fHodoPosPhcCoeff = ";
519 for (int i1=0;i1<fMaxHodoScin;i1++) {
520 cout<<this->GetHodoPosPhcCoeff(i1)<<" ";
521 }
522 cout<<endl;
523 */
524 }
525 //
526 if ((fTofTolerance > 0.5) && (fTofTolerance < 10000.)) {
527 cout << "USING "<<fTofTolerance<<" NSEC WINDOW FOR FP NO_TRACK CALCULATIONS.\n";
528 }
529 else {
530 fTofTolerance= 3.0;
531 cout << "*** USING DEFAULT 3 NSEC WINDOW FOR FP NO_TRACK CALCULATIONS!! ***\n";
532 }
533 //
535 TString SHMS="p";
536 TString HMS="h";
537 TString test=prefix[0];
538 if (test==SHMS ) fRatio_xpfp_to_xfp=0.0018; // SHMS
539 if (test == HMS ) fRatio_xpfp_to_xfp=0.0011; // HMS
540 cout << " fRatio_xpfp_to_xfp= " << fRatio_xpfp_to_xfp << endl;
541 //
542 fIsInit = true;
543 return kOK;
544}
545
546//_____________________________________________________________________________
548{
552 // cout << "THcHodoscope::DefineVariables called " << GetName() << endl;
553 if( mode == kDefine && fIsSetup ) return kOK;
554 fIsSetup = ( mode == kDefine );
555
556 // Register variables in global list
557
558 RVarDef vars[] = {
559 // Move these into THcHallCSpectrometer using track fTracks
560 {"beta", "Beta including track info", "fBeta"},
561 {"betanotrack", "Beta from scintillator hits", "fBetaNoTrk"},
562 {"betachisqnotrack", "Chi square of beta from scintillator hits", "fBetaNoTrkChiSq"},
563 {"fpHitsTime", "Time at focal plane from all hits", "fFPTimeAll"},
564 {"starttime", "Hodoscope Start Time", "fStartTime"},
565 {"goodstarttime", "Hodoscope Good Start Time (logical flag)", "fGoodStartTime"},
566 {"goodscinhit", "Hit in fid area", "fGoodScinHits"},
567 {"adctdc_offset"," ","fOffsetTime"},
568 {"TimeHist_StartTime_Sigma", "", "fTimeHist_StartTime_Sigma"},
569 {"TimeHist_StartTime_Peak", "", "fTimeHist_StartTime_Peak"},
570 {"TimeHist_StartTime_NumPeaks", "", "fTimeHist_StartTime_NumPeaks"},
571 {"TimeHist_StartTime_Hits", "", "fTimeHist_StartTime_Hits"},
572 {"TimeHist_FpTime_Sigma", "", "fTimeHist_FpTime_Sigma"},
573 {"TimeHist_FpTime_Peak", "", "fTimeHist_FpTime_Peak"},
574 {"TimeHist_FpTime_NumPeaks", "", "fTimeHist_FpTime_NumPeaks"},
575 {"TimeHist_FpTime_Hits", "", "fTimeHist_FpTime_Hits"},
576 { 0 }
577 };
578 return DefineVarsFromList( vars, mode );
579 // return kOK;
580}
581
582//_____________________________________________________________________________
584{
585 // Destructor. Remove variables from global list.
586
587 delete [] fFPTime;
588 delete [] fPlaneCenter;
589 delete [] fPlaneSpacing;
590
591 if( fIsSetup )
593 if( fIsInit )
594 DeleteArrays();
595
596 for( int i = 0; i < fNPlanes; ++i ) {
597 delete fPlanes[i];
598 delete [] fPlaneNames[i];
599 }
600 delete [] fPlanes;
601 delete [] fPlaneNames;
602}
603
604//_____________________________________________________________________________
606{
607 // Delete member arrays. Used by destructor.
608 // Int_t k;
609 // for( k = 0; k < fNPlanes; k++){
610 // delete [] fScinHit[k];
611 // }
612 // delete [] fScinHit;
613
614 delete [] fxLoScin; fxLoScin = NULL;
615 delete [] fxHiScin; fxHiScin = NULL;
616 delete [] fyLoScin; fyLoScin = NULL;
617 delete [] fyHiScin; fyHiScin = NULL;
618 delete [] fHodoSlop; fHodoSlop = NULL;
619
620 delete [] fNPaddle; fNPaddle = NULL;
621 delete [] fHodoVelLight; fHodoVelLight = NULL;
622 delete [] fHodoPosSigma; fHodoPosSigma = NULL;
623 delete [] fHodoNegSigma; fHodoNegSigma = NULL;
624 delete [] fHodoPosMinPh; fHodoPosMinPh = NULL;
625 delete [] fHodoNegMinPh; fHodoNegMinPh = NULL;
626 delete [] fHodoPosPhcCoeff; fHodoPosPhcCoeff = NULL;
627 delete [] fHodoNegPhcCoeff; fHodoNegPhcCoeff = NULL;
628 delete [] fHodoPosTimeOffset; fHodoPosTimeOffset = NULL;
629 delete [] fHodoNegTimeOffset; fHodoNegTimeOffset = NULL;
630 delete [] fHodoPosPedLimit; fHodoPosPedLimit = NULL;
631 delete [] fHodoNegPedLimit; fHodoNegPedLimit = NULL;
636 delete [] fHodoPosInvAdcAdc; fHodoPosInvAdcAdc = NULL;
637 delete [] fHodoNegInvAdcAdc; fHodoNegInvAdcAdc = NULL;
638 delete [] fGoodPlaneTime; fGoodPlaneTime = NULL;
639 delete [] fNPlaneTime; fNPlaneTime = NULL;
640 delete [] fSumPlaneTime; fSumPlaneTime = NULL;
641 delete [] fNScinHits; fNScinHits = NULL;
642 delete [] fTdcOffset; fTdcOffset = NULL;
643 delete [] fAdcTdcOffset; fAdcTdcOffset = NULL;
648
649 delete [] fHodoVelFit; fHodoVelFit = NULL;
650 delete [] fHodoCableFit; fHodoCableFit = NULL;
651 delete [] fHodo_LCoeff; fHodo_LCoeff = NULL;
652 delete [] fHodoPos_c1; fHodoPos_c1 = NULL;
653 delete [] fHodoNeg_c1; fHodoNeg_c1 = NULL;
654 delete [] fHodoPos_c2; fHodoPos_c2 = NULL;
655 delete [] fHodoNeg_c2; fHodoNeg_c2 = NULL;
656 delete [] fHodoSigmaPos; fHodoSigmaPos = NULL;
657 delete [] fHodoSigmaNeg; fHodoSigmaNeg = NULL;
658}
659
660//_____________________________________________________________________________
662{
676
677 fBeta = 0.0;
678 fBetaNoTrk = 0.0;
679 fBetaNoTrkChiSq = 0.0;
680 fStartTime = -1000.;
681 fADCStartTime = -1000.;
683 fFPTimeAll= -1000.;
685 fGoodScinHits = 0;
686
687 if( *opt != 'I' ) {
688 for(Int_t ip=0;ip<fNPlanes;ip++) {
689 fPlanes[ip]->Clear();
690 fFPTime[ip]=0.;
691 fPlaneCenter[ip]=0.;
692 fPlaneSpacing[ip]=0.;
693 for(UInt_t iPaddle=0;iPaddle<fNPaddle[ip]; ++iPaddle) {
694 fScinHitPaddle[ip][iPaddle]=0;
695 }
696 }
697 }
698 fdEdX.clear();
699 fNScinHit.clear();
700 fNClust.clear();
701 fClustSize.clear();
702 fClustPos.clear();
703 fNCluster.clear();
704 fClusterSize.clear();
705 fClusterXPos.clear();
706 fClusterYPos.clear();
707 fThreeScin.clear();
708 fGoodScinHitsX.clear();
709 fGoodFlags.clear();
710}
711
712//_____________________________________________________________________________
714{
727 // Get the Hall C style hitlist (fRawHitList) for this event
728 Bool_t present = kTRUE; // Suppress reference time warnings
729 if(fPresentP) { // if this spectrometer not part of trigger
730 present = *fPresentP;
731 }
732 fNHits = DecodeToHitList(evdata, !present);
733 fEventNum = evdata.GetEvNum();
734 //
735 // GN: print event number so we can cross-check with engine
736 // if (evdata.GetEvNum()>1000)
737 // cout <<"\nhcana_event " << evdata.GetEvNum()<<endl;
738
739 fCheckEvent = evdata.GetEvNum();
740 fEventType = evdata.GetEvType();
741
742 if(gHaCuts->Result("Pedestal_event")) {
743 Int_t nexthit = 0;
744 for(Int_t ip=0;ip<fNPlanes;ip++) {
745
746 nexthit = fPlanes[ip]->AccumulatePedestals(fRawHitList, nexthit);
747 }
748 fAnalyzePedestals = 1; // Analyze pedestals first normal events
749 return(0);
750 }
752 for(Int_t ip=0;ip<fNPlanes;ip++) {
753
755 }
756 fAnalyzePedestals = 0; // Don't analyze pedestals next event
757 }
758
759 // Let each plane get its hits
760 Int_t nexthit = 0;
761 //THcHallCSpectrometer *app = dynamic_cast<THcHallCSpectrometer*>(GetApparatus());
762 // cout << " event number = " << fEventNum << " Evtyp = " << fEventType<< " spec = " << app->GetName() << endl;
763 fNfptimes=0;
764 Int_t thits = 0;
765 for(Int_t ip=0;ip<fNPlanes;ip++) {
766
768 fPlaneSpacing[ip] = fPlanes[ip]->GetSpacing();
769
770 // nexthit = fPlanes[ip]->ProcessHits(fRawHitList, nexthit);
771 // GN: select only events that have reasonable TDC values to start with
772 // as per the Engine h_strip_scin.f
773 nexthit = fPlanes[ip]->ProcessHits(fRawHitList,nexthit);
774 thits+=fPlanes[ip]->GetNScinHits();
775 }
776 //
777 //
778 fStartTime=-1000;
779 if (thits>0 ) EstimateFocalPlaneTime();
780
781 if (fdebugprintscinraw == 1) {
782 for(UInt_t ihit = 0; ihit < fNRawHits ; ihit++) {
783// THcRawHodoHit* hit = (THcRawHodoHit *) fRawHitList->At(ihit);
784// cout << ihit << " : " << hit->fPlane << ":" << hit->fCounter << " : "
785// << hit->fADC_pos << " " << hit->fADC_neg << " " << hit->fTDC_pos
786// << " " << hit->fTDC_neg << endl;
787 }
788 cout << endl;
789 }
790
791
792 return fNHits;
793}
794//_____________________________________________________________________________
796{
797 Double_t time_peak=-1000;
798 Int_t NBinsX=hTime->GetNbinsX();
799 Int_t hTimeScanRange = 10.; // Integrate over HtimeScanRange
800 vector<Double_t> hpeakCent;
801 vector<Double_t> hpeakNum;
802 vector<Double_t> hpeakRMS;
803 vector<Double_t> hpeakFlag;
804 vector<Int_t> hpeakBin;
805 Double_t MinimumNum=2.;
806 Double_t test_peakmax=0.;
807 Bool_t scanning_for_local_peak=kFALSE;
808 Double_t save_mean=0,save_rms=0,save_num=0;
809 Int_t save_bin;
810 Bool_t new_peak=kFALSE;
811 Bool_t replace_peak=kFALSE;
812 UInt_t best_peak_index=0;
813 Int_t best_peak_num=-1;
814 Double_t best_peak_diff=1000;
815 Int_t nfound=0;
816 for (Int_t nb=1;nb<NBinsX-hTimeScanRange;nb++) {
817 hTime->GetXaxis()->SetRange(nb,nb+hTimeScanRange);
818 Double_t test_int = hTime->Integral();
819 if (scanning_for_local_peak) {
820 if ( test_int <= test_peakmax) {
821 Int_t ps=hpeakCent.size();
822 replace_peak=kFALSE;
823 new_peak=kFALSE;
824 if (ps==0) new_peak=kTRUE;
825 if (ps!=0 && nb==hpeakBin[ps]+1 && save_mean!=hpeakCent[ps-1]) new_peak=kFALSE;
826 if (ps!=0 && save_num > hpeakNum[ps-1] && abs(save_mean-hpeakCent[ps-1])<5) replace_peak=kTRUE;
827 if (ps!=0 && nb!=hpeakBin[ps]+1 && save_num > MinimumNum && abs(save_mean-hpeakCent[ps-1])>=5) new_peak=kTRUE;
828 if (new_peak) {
829 hpeakCent.push_back(save_mean);
830 hpeakRMS.push_back(save_rms);
831 hpeakNum.push_back(save_num);
832 hpeakBin.push_back(save_bin);
833 hpeakFlag.push_back(1);
834 }
835 if (replace_peak) {
836 hpeakCent[ps-1]=save_mean;
837 hpeakRMS[ps-1]=save_rms;
838 hpeakNum[ps-1]=save_num;
839 hpeakBin[ps-1]=save_bin;
840 hpeakFlag[ps-1]=1;
841 }
842 scanning_for_local_peak = kFALSE;
843 test_peakmax = 0;
844 best_peak_index=-1;
845 best_peak_num=5;
846 nfound=0;
847 for (UInt_t np=0;np<hpeakNum.size();np++) {
848 hpeakFlag[np]=-1;
849 if ( hpeakNum[np] > 5 && (hpeakNum[np]>= best_peak_num || abs(hpeakNum[np] - best_peak_num)<= 4) ) {
850 if (nfound==0 || (hpeakNum[np]== best_peak_num || abs(hpeakNum[np] - best_peak_num)<= 4) ) {
851 hpeakFlag[np]=1;
852 if (nfound==0 ) best_peak_num =hpeakNum[np] ;
853 if (nfound==0 ) best_peak_index= np;
854 nfound++;
855 } else {
856 for (UInt_t nt=0;nt<np;nt++) {hpeakFlag[nt]=-1;}
857 nfound=1;
858 best_peak_num =hpeakNum[np] ;
859 best_peak_index= np;
860 }
861 }
862 }
863 if (nfound>1) {
864 best_peak_diff=1000;
865 for (UInt_t np=0;np<hpeakNum.size();np++) {
866 if (hpeakFlag[np]==1 && abs(hpeakCent[np]-fStartTimeCenter)<best_peak_diff) {
867 best_peak_diff = abs(hpeakCent[np]-fStartTimeCenter);
868 best_peak_index= np;
869 }
870 }}
871 if (nfound==0) {
872 best_peak_diff=1000;
873 for (UInt_t np=0;np<hpeakNum.size();np++) {
874 if (abs(hpeakCent[np]-fStartTimeCenter)<best_peak_diff) {
875 best_peak_diff = abs(hpeakCent[np]-fStartTimeCenter);
876 best_peak_index= np;
877 }
878 }}
879
880 } else {
881 test_peakmax = test_int;
882 save_mean=hTime->GetMean();
883 save_rms=hTime->GetRMS();
884 save_num=hTime->Integral();
885 save_bin=nb;
886 }
887 } else {
888 if ( test_int > MinimumNum) {
889 test_peakmax = test_int;
890 scanning_for_local_peak = kTRUE;
891 save_mean=hTime->GetMean();
892 save_rms=hTime->GetRMS();
893 save_num=hTime->Integral();
894 save_bin=nb;
895 }
896 }
897 }
898 //
899 if (!hpeakNum.empty() && best_peak_index<hpeakNum.size() ) {
900 time_peak= hpeakCent[best_peak_index];
901 if (FillFlag==1) {
902 fTimeHist_StartTime_NumPeaks=hpeakNum.size() ;
903 fTimeHist_StartTime_Peak= time_peak;
904 fTimeHist_StartTime_Sigma= hpeakRMS[best_peak_index] ;
905 fTimeHist_StartTime_Hits= hpeakNum[best_peak_index];
906 }
907 if (FillFlag==2) {
908 fTimeHist_FpTime_NumPeaks=hpeakNum.size() ;
909 fTimeHist_FpTime_Peak= time_peak;
910 fTimeHist_FpTime_Sigma= hpeakRMS[best_peak_index] ;
911 fTimeHist_FpTime_Hits= hpeakNum[best_peak_index];
912 }
913 }
914 //
915 return time_peak;
916}
917
918//_____________________________________________________________________________
920{
930 Int_t ihit=0;
931 Int_t nscinhits=0; // Total # hits with at least one good tdc
932 hTime->Reset();
933 //
934 //
935 for(Int_t ip=0;ip<fNPlanes;ip++) {
936 Int_t nphits=fPlanes[ip]->GetNScinHits();
937 nscinhits += nphits;
938 TClonesArray* hodoHits = fPlanes[ip]->GetHits();
939 for(Int_t i=0;i<nphits;i++) {
940 THcHodoHit *hit = (THcHodoHit*)hodoHits->At(i);
941 if(hit->GetHasCorrectedTimes()) {
942 Double_t postime=hit->GetPosTOFCorrectedTime();
943 Double_t negtime=hit->GetNegTOFCorrectedTime();
944 hTime->Fill(postime);
945 hTime->Fill(negtime);
946 }
947 }
948 }
949 //
950 Double_t TimePeak=DetermineTimePeak(1);
951 hTime->Reset();
952 //
953 Double_t AdcTdcDiffTimeSum=0;
954 Double_t NAdcTdcDiffTimeSum=0;
955 //
956 for(Int_t ip=0;ip<fNPlanes;ip++) {
957 Int_t nphits=fPlanes[ip]->GetNScinHits();
958 nscinhits += nphits;
959 TClonesArray* hodoHits = fPlanes[ip]->GetHits();
960 for(Int_t i=0;i<nphits;i++) {
961 THcHodoHit *hit = (THcHodoHit*)hodoHits->At(i);
962 if(hit->GetHasCorrectedTimes()) {
963 NAdcTdcDiffTimeSum++;
964 AdcTdcDiffTimeSum+=(hit->GetPosADCtime()-hit->GetPosTDC()*fScinTdcToTime);
965 NAdcTdcDiffTimeSum++;
966 AdcTdcDiffTimeSum+=(hit->GetNegADCtime()-hit->GetNegTDC()*fScinTdcToTime);
967 Double_t postime=hit->GetPosADCCorrtime();
968 Double_t negtime=hit->GetNegADCCorrtime();
969 hTime->Fill(postime);
970 hTime->Fill(negtime);
971 }
972 }
973 }
974 if (NAdcTdcDiffTimeSum>0) AdcTdcDiffTimeSum=AdcTdcDiffTimeSum/NAdcTdcDiffTimeSum;
975 //
976 Double_t AdcTimePeak=DetermineTimePeak(3);
977 //
978 ihit = 0;
979 Double_t fpTimeSum = 0.0;
980 Double_t adcfpTimeSum = 0.0;
981 Double_t adcNfptimes=0;
982 fNfptimes=0;
983 Int_t Ngood_hits_plane=0;
984 Int_t Ngood_adchits_plane=0;
985 Double_t Plane_fptime_sum=0.0;
986 //Double_t Plane_adcfptime_sum=0.0;
987 Bool_t goodplanetime[fNPlanes];
988 Bool_t twogoodtimes[nscinhits];
989 Int_t NumPlanesGoodHit=0;
990 Int_t NumPlanesGoodAdcHit=0;
991 if (TimePeak>0) {
992 for(Int_t ip=0;ip<fNumPlanesBetaCalc;ip++) {
993 goodplanetime[ip] = kFALSE;
994 Int_t nphits=fPlanes[ip]->GetNScinHits();
995 TClonesArray* hodoHits = fPlanes[ip]->GetHits();
996 Ngood_hits_plane=0;
997 Plane_fptime_sum=0.0;
998 for(Int_t i=0;i<nphits;i++) {
999 THcHodoHit *hit = (THcHodoHit*)hodoHits->At(i);
1000 twogoodtimes[ihit] = kFALSE;
1001 if(hit->GetHasCorrectedTimes()) {
1002 Double_t postime=hit->GetPosTOFCorrectedTime();
1003 Double_t negtime=hit->GetNegTOFCorrectedTime();
1004 Double_t adcpostime=hit->GetPosADCCorrtime();
1005 Double_t adcnegtime=hit->GetNegADCCorrtime();
1006 if ((postime>(TimePeak-fTofTolerance)) && (postime<(TimePeak+fTofTolerance)) &&
1007 (negtime>(TimePeak-fTofTolerance)) && (negtime<(TimePeak+fTofTolerance)) ) {
1008 hit->SetTwoGoodTimes(kTRUE);
1009 twogoodtimes[ihit] = kTRUE; // Both tubes fired
1010 Int_t index=hit->GetPaddleNumber()-1; //
1011 Double_t fptime;
1012 if(fCosmicFlag==1) {
1013 fptime = hit->GetScinCorrectedTime()
1014 + (fPlanes[ip]->GetZpos()+(index%2)*fPlanes[ip]->GetDzpos())
1015 / (29.979 * fBetaNominal);
1016 }else{
1017 fptime = hit->GetScinCorrectedTime()
1018 - (fPlanes[ip]->GetZpos()+(index%2)*fPlanes[ip]->GetDzpos())
1019 / (29.979 * fBetaNominal);
1020 }
1021 Ngood_hits_plane++;
1022 Plane_fptime_sum+=fptime;
1023 fpTimeSum += fptime;
1024 fNfptimes++;
1025 goodplanetime[ip] = kTRUE;
1026 } else {
1027 hit->SetTwoGoodTimes(kFALSE);
1028 }
1029 //
1030 if ((adcpostime>(AdcTimePeak-fTofTolerance)) && (adcpostime<(AdcTimePeak+fTofTolerance)) &&
1031 (adcnegtime>(AdcTimePeak-fTofTolerance)) && (adcnegtime<(AdcTimePeak+fTofTolerance)) ) {
1032 Int_t index=hit->GetPaddleNumber()-1; //
1033 Double_t fptime;
1034 if(fCosmicFlag==1) {
1035 fptime = hit->GetScinCorrectedTime()
1036 + (fPlanes[ip]->GetZpos()+(index%2)*fPlanes[ip]->GetDzpos())
1037 / (29.979 * fBetaNominal);
1038 }else{
1039 fptime = hit->GetScinCorrectedTime()
1040 - (fPlanes[ip]->GetZpos()+(index%2)*fPlanes[ip]->GetDzpos())
1041 / (29.979 * fBetaNominal);
1042 }
1043 Ngood_adchits_plane++;
1044 //Plane_adcfptime_sum+=fptime;
1045 adcfpTimeSum += fptime;
1046 adcNfptimes++;
1047 }
1048 //
1049 }
1050 ihit++;
1051 }
1052 if (Ngood_hits_plane>0) NumPlanesGoodHit++;
1053 if (Ngood_adchits_plane>0) NumPlanesGoodAdcHit++;
1054 if (Ngood_hits_plane>0) fPlanes[ip]->SetFpTime(Plane_fptime_sum/float(Ngood_hits_plane));
1055 fPlanes[ip]->SetNGoodHits(Ngood_hits_plane);
1056 }
1057 } // if TimePeak>0
1058 //
1059 if(NumPlanesGoodHit>=3) {
1060 fStartTime = fpTimeSum/fNfptimes;
1063 fOffsetTime=0;
1064 if(NumPlanesGoodAdcHit>=3) {
1065 fADCStartTime = adcfpTimeSum/adcNfptimes-fStartTime;
1066 }
1067 fOffsetTime =AdcTdcDiffTimeSum;
1068 } else {
1073 fOffsetTime=AdcTdcDiffTimeSum;
1074 }
1075 //
1076 //
1077 hTime->Reset();
1078 //
1079 if(fGoodStartTime && (goodplanetime[0]||goodplanetime[1]) &&(goodplanetime[2]||goodplanetime[3])) {
1080
1081 Double_t sumW = 0.;
1082 Double_t sumT = 0.;
1083 Double_t sumZ = 0.;
1084 Double_t sumZZ = 0.;
1085 Double_t sumTZ = 0.;
1086 Int_t ihhit = 0;
1087
1088 for(Int_t ip=0;ip<fNumPlanesBetaCalc;ip++) {
1089 Int_t nphits=fPlanes[ip]->GetNScinHits();
1090 TClonesArray* hodoHits = fPlanes[ip]->GetHits();
1091
1092 for(Int_t i=0;i<nphits;i++) {
1093 Int_t index=((THcHodoHit*)hodoHits->At(i))->GetPaddleNumber()-1;
1094
1095 if(twogoodtimes[ihhit]){
1096
1097 Double_t sigma = 0.0;
1098 if(fTofUsingInvAdc)
1099 {
1102 }
1103 else{
1106 }
1107
1108 Double_t scinWeight = 1 / TMath::Power(sigma,2);
1109 Double_t zPosition = fPlanes[ip]->GetZpos() + (index%2)*fPlanes[ip]->GetDzpos();
1110 // cout << "hit = " << ihhit + 1 << " zpos = " << zPosition << " sigma = " << sigma << endl;
1111 //cout << "fHodoSigma+ = " << fHodoSigmaPos[GetScinIndex(ip,index)] << endl;
1112 sumW += scinWeight;
1113 sumT += scinWeight * ((THcHodoHit*)hodoHits->At(i))->GetScinCorrectedTime();
1114 sumZ += scinWeight * zPosition;
1115 sumZZ += scinWeight * ( zPosition * zPosition );
1116 sumTZ += scinWeight * zPosition * ((THcHodoHit*)hodoHits->At(i))->GetScinCorrectedTime();
1117
1118 } // condition of good scin time
1119 ihhit ++;
1120 } // loop over hits of plane
1121 } // loop over planes
1122
1123 Double_t tmp = sumW * sumZZ - sumZ * sumZ ;
1124 Double_t t0 = ( sumT * sumZZ - sumZ * sumTZ ) / tmp ;
1125 Double_t tmpDenom = sumW * sumTZ - sumZ * sumT;
1126
1127 if ( TMath::Abs( tmpDenom ) > ( 1 / 10000000000.0 ) ) {
1128
1129 fBetaNoTrk = tmp / tmpDenom;
1130 fBetaNoTrkChiSq = 0.;
1131 ihhit = 0;
1132
1133 for (Int_t ip = 0; ip < fNumPlanesBetaCalc; ip++ ){ // Loop over planes
1134 Int_t nphits=fPlanes[ip]->GetNScinHits();
1135 TClonesArray* hodoHits = fPlanes[ip]->GetHits();
1136
1137 for(Int_t i=0;i<nphits;i++) {
1138 Int_t index=((THcHodoHit*)hodoHits->At(i))->GetPaddleNumber()-1;
1139
1140 if(twogoodtimes[ihhit]) {
1141
1142 Double_t zPosition = fPlanes[ip]->GetZpos() + (index%2)*fPlanes[ip]->GetDzpos();
1143 Double_t timeDif = ( ((THcHodoHit*)hodoHits->At(i))->GetScinCorrectedTime() - t0 );
1144
1145 Double_t sigma = 0.0;
1146 if(fTofUsingInvAdc){
1149 }
1150 else {
1153 }
1154
1155 fBetaNoTrkChiSq += ( ( zPosition / fBetaNoTrk - timeDif ) *
1156 ( zPosition / fBetaNoTrk - timeDif ) ) / ( sigma * sigma );
1157
1158
1159 } // condition for good scin time
1160 ihhit++;
1161 } // loop over hits of a plane
1162 } // loop over planes
1163
1164 Double_t pathNorm = 1.0;
1165
1166 fBetaNoTrk = fBetaNoTrk * pathNorm;
1167 fBetaNoTrk = fBetaNoTrk / 29.979; // velocity / c
1168
1169 } // condition for fTmpDenom
1170 else {
1171 fBetaNoTrk = 0.;
1172 fBetaNoTrkChiSq = -2.;
1173 } // else condition for fTmpDenom
1174 //
1176 if ((fNumPlanesBetaCalc==4)&&goodplanetime[0]&&goodplanetime[1]&&goodplanetime[2]&&goodplanetime[3]&&fPlanes[0]->GetNGoodHits()==1&&fPlanes[1]->GetNGoodHits()==1&&fPlanes[2]->GetNGoodHits()==1&&fPlanes[3]->GetNGoodHits()==1) fGoodEventTOFCalib=kTRUE;
1177 if ((fNumPlanesBetaCalc==3)&&goodplanetime[0]&&goodplanetime[1]&&goodplanetime[2]&&fPlanes[0]->GetNGoodHits()==1&&fPlanes[1]->GetNGoodHits()==1&&fPlanes[2]->GetNGoodHits()==1) fGoodEventTOFCalib=kTRUE;
1178 //
1179 //
1180 } else {
1181 fBetaNoTrkChiSq = -10.; // Flag if does not try to find beta
1182 }
1183}
1184
1185//_____________________________________________________________________________
1187{
1188 return(0);
1189}
1190//_____________________________________________________________________________
1192 const ESide side)
1193{
1194 return(0.0);
1195}
1196
1197
1198//_____________________________________________________________________________
1200{
1201
1202
1203 Int_t ntracks = tracks.GetLast()+1; // Number of reconstructed tracks
1204 // -------------------------------------------------
1205
1206 // fDumpOut << " ntrack = " << ntracks << endl;
1207
1208 if (ntracks > 0 ) {
1209
1210 // **MAIN LOOP: Loop over all tracks and get corrected time, tof, beta...
1211 vector<Double_t> nPmtHit(ntracks);
1212 vector<Double_t> timeAtFP(ntracks);
1213 fdEdX.reserve(ntracks);
1214 fGoodFlags.reserve(ntracks);
1215 for ( Int_t itrack = 0; itrack < ntracks; itrack++ ) { // Line 133
1216 nPmtHit[itrack]=0;
1217 timeAtFP[itrack]=0;
1218
1219 THaTrack* theTrack = dynamic_cast<THaTrack*>( tracks.At(itrack) );
1220 if (!theTrack) return -1;
1221
1222 for (Int_t ip = 0; ip < fNumPlanesBetaCalc; ip++ ){
1223 fGoodPlaneTime[ip] = kFALSE;
1224 fNScinHits[ip] = 0;
1225 fNPlaneTime[ip] = 0;
1226 fSumPlaneTime[ip] = 0.;
1227 }
1228 std::vector<Double_t> dedx_temp;
1229 std::vector<std::vector<GoodFlags> > goodflagstmp1;
1230 goodflagstmp1.reserve(fNumPlanesBetaCalc);
1231#if __cplusplus >= 201103L
1232 fdEdX.push_back(std::move(dedx_temp)); // Create array of dedx per hit
1233 fGoodFlags.push_back(std::move(goodflagstmp1));
1234#else
1235 fdEdX.push_back(dedx_temp); // Create array of dedx per hit
1236 fGoodFlags.push_back(goodflagstmp1);
1237#endif
1238 Int_t nFPTime = 0;
1239 Double_t betaChiSq = -3;
1240 Double_t beta = 0;
1241 // timeAtFP[itrack] = 0.;
1242 Double_t sumFPTime = 0.; // Line 138
1243 fNScinHit.push_back(0);
1244
1245
1246
1247 hTime->Reset();
1248 fTOFCalc.clear(); // SAW - Can we
1249 fTOFPInfo.clear(); // SAW - combine these two?
1250 Int_t ihhit = 0; // Hit # overall
1251
1252 for(Int_t ip = 0; ip < fNumPlanesBetaCalc; ip++ ) {
1253
1254 std::vector<GoodFlags> goodflagstmp2;
1255 goodflagstmp2.reserve(fNScinHits[ip]);
1256#if __cplusplus >= 201103L
1257 fGoodFlags[itrack].push_back(std::move(goodflagstmp2));
1258#else
1259 fGoodFlags[itrack].push_back(goodflagstmp2);
1260#endif
1261 fNScinHits[ip] = fPlanes[ip]->GetNScinHits();
1262 TClonesArray* hodoHits = fPlanes[ip]->GetHits();
1263
1264 Double_t zPos = fPlanes[ip]->GetZpos();
1265 Double_t dzPos = fPlanes[ip]->GetDzpos();
1266
1267 // first loop over hits with in a single plane
1268 for (Int_t iphit = 0; iphit < fNScinHits[ip]; iphit++ ){
1269 // iphit is hit # within a plane
1270 THcHodoHit *hit = (THcHodoHit*)hodoHits->At(iphit);
1271
1272 fTOFPInfo.emplace_back();
1273 // Can remove these as we will initialize in the constructor
1274 // fTOFPInfo[ihhit].time_pos = -99.0;
1275 // fTOFPInfo[ihhit].time_neg = -99.0;
1276 // fTOFPInfo[ihhit].keep_pos = kFALSE;
1277 // fTOFPInfo[ihhit].keep_neg = kFALSE;
1278 fTOFPInfo[ihhit].scin_pos_time = 0.0;
1279 fTOFPInfo[ihhit].scin_neg_time = 0.0;
1280 fTOFPInfo[ihhit].hit = hit;
1281 fTOFPInfo[ihhit].planeIndex = ip;
1282 fTOFPInfo[ihhit].hitNumInPlane = iphit;
1283 fTOFPInfo[ihhit].onTrack = kFALSE;
1284
1285 Int_t paddle = hit->GetPaddleNumber()-1;
1286 Double_t zposition = zPos + (paddle%2)*dzPos;
1287
1288 Double_t xHitCoord = theTrack->GetX() + theTrack->GetTheta() *
1289 ( zposition ); // Line 183
1290
1291 Double_t yHitCoord = theTrack->GetY() + theTrack->GetPhi() *
1292 ( zposition ); // Line 184
1293
1294 Double_t scinTrnsCoord, scinLongCoord;
1295 if ( ( ip == 0 ) || ( ip == 2 ) ){ // !x plane. Line 185
1296 scinTrnsCoord = xHitCoord;
1297 scinLongCoord = yHitCoord;
1298 } else if ( ( ip == 1 ) || ( ip == 3 ) ){ // !y plane. Line 188
1299 scinTrnsCoord = yHitCoord;
1300 scinLongCoord = xHitCoord;
1301 } else { return -1; } // Line 195
1302
1303 fTOFPInfo[ihhit].scinTrnsCoord = scinTrnsCoord;
1304 fTOFPInfo[ihhit].scinLongCoord = scinLongCoord;
1305
1306 Double_t scinCenter = fPlanes[ip]->GetPosCenter(paddle) + fPlanes[ip]->GetPosOffset();
1307
1308 // Index to access the 2d arrays of paddle/scintillator properties
1309 Int_t fPIndex = GetScinIndex(ip,paddle);
1310 Double_t betatrack = theTrack->GetP()/TMath::Sqrt(theTrack->GetP()*theTrack->GetP()+fPartMass*fPartMass);
1311
1312 if ( TMath::Abs( scinCenter - scinTrnsCoord ) <
1313 ( fPlanes[ip]->GetSize() * 0.5 + fPlanes[ip]->GetHodoSlop() ) ){ // Line 293
1314
1315 fTOFPInfo[ihhit].onTrack = kTRUE;
1316 Double_t zcor = zposition/(29.979*betatrack)*
1317 TMath::Sqrt(1. + theTrack->GetTheta()*theTrack->GetTheta()
1318 + theTrack->GetPhi()*theTrack->GetPhi());
1319 fTOFPInfo[ihhit].zcor = zcor;
1320 if (fCosmicFlag) {
1321 Double_t zcor = -zposition/(29.979*1.0)*
1322 TMath::Sqrt(1. + theTrack->GetTheta()*theTrack->GetTheta()
1323 + theTrack->GetPhi()*theTrack->GetPhi());
1324 fTOFPInfo[ihhit].zcor = zcor;
1325 }
1326 Double_t tdc_pos = hit->GetPosTDC();
1327 Double_t tdc_neg = hit->GetNegTDC();
1328 //
1329 if( (tdc_pos >=fScinTdcMin && tdc_pos <= fScinTdcMax) &&
1330 (tdc_neg >=fScinTdcMin && tdc_neg <= fScinTdcMax )) {
1331 fTOFPInfo[ihhit].scin_pos_time = hit->GetPosCorrectedTime();
1332 Double_t timep = hit->GetPosCorrectedTime()-zcor;
1333 fTOFPInfo[ihhit].time_pos = timep;
1334 hTime->Fill(timep);
1335 fTOFPInfo[ihhit].scin_neg_time = hit->GetNegCorrectedTime();
1336 Double_t timen = hit->GetNegCorrectedTime()-zcor;
1337 fTOFPInfo[ihhit].time_neg = timen;
1338 hTime->Fill(timen);
1339 } else {
1340 //
1342 if(tdc_pos >=fScinTdcMin && tdc_pos <= fScinTdcMax ) {
1343 Double_t adc_pos = hit->GetPosADC();
1344 Double_t adcamp_pos = hit->GetPosADCpeak();
1345 Double_t pathp = fPlanes[ip]->GetPosLeft() - scinLongCoord;
1346 fTOFPInfo[ihhit].pathp = pathp;
1347 Double_t timep = tdc_pos*fScinTdcToTime;
1348 if(fTofUsingInvAdc) {
1349 timep -= fHodoPosInvAdcOffset[fPIndex]
1350 + pathp/fHodoPosInvAdcLinear[fPIndex]
1351 + fHodoPosInvAdcAdc[fPIndex]
1352 /TMath::Sqrt(TMath::Max(20.0*.020,adc_pos));
1353 } else {
1354 //Double_t tw_corr_pos = fHodoPos_c1[fPIndex]/pow(adcamp_pos/fTdc_Thrs,fHodoPos_c2[fPIndex]) - fHodoPos_c1[fPIndex]/pow(200./fTdc_Thrs, fHodoPos_c2[fPIndex]);
1355 Double_t tw_corr_pos=0.;
1356 pathp=scinLongCoord;
1357 if (adcamp_pos>0) tw_corr_pos = 1./pow(adcamp_pos/fTdc_Thrs,fHodoPos_c2[fPIndex]) - 1./pow(200./fTdc_Thrs, fHodoPos_c2[fPIndex]);
1358 timep += -tw_corr_pos + fHodo_LCoeff[fPIndex]+ pathp/fHodoVelFit[fPIndex];
1359 }
1360 fTOFPInfo[ihhit].scin_pos_time = timep;
1361 timep -= zcor;
1362 fTOFPInfo[ihhit].time_pos = timep;
1363
1364 hTime->Fill(timep);
1365 }
1366 if(tdc_neg >=fScinTdcMin && tdc_neg <= fScinTdcMax ) {
1367 Double_t adc_neg = hit->GetNegADC();
1368 Double_t adcamp_neg = hit->GetNegADCpeak();
1369 Double_t pathn = scinLongCoord - fPlanes[ip]->GetPosRight();
1370 fTOFPInfo[ihhit].pathn = pathn;
1371 Double_t timen = tdc_neg*fScinTdcToTime;
1372 if(fTofUsingInvAdc) {
1373 timen -= fHodoNegInvAdcOffset[fPIndex]
1374 + pathn/fHodoNegInvAdcLinear[fPIndex]
1375 + fHodoNegInvAdcAdc[fPIndex]
1376 /TMath::Sqrt(TMath::Max(20.0*.020,adc_neg));
1377 } else {
1378 pathn=scinLongCoord ;
1379 Double_t tw_corr_neg =0 ;
1380 if (adcamp_neg >0) tw_corr_neg= 1./pow(adcamp_neg/fTdc_Thrs,fHodoNeg_c2[fPIndex]) - 1./pow(200./fTdc_Thrs, fHodoNeg_c2[fPIndex]);
1381 timen += -tw_corr_neg- 2*fHodoCableFit[fPIndex] + fHodo_LCoeff[fPIndex]- pathn/fHodoVelFit[fPIndex];
1382
1383 }
1384 fTOFPInfo[ihhit].scin_neg_time = timen;
1385 timen -= zcor;
1386 fTOFPInfo[ihhit].time_neg = timen;
1387 hTime->Fill(timen);
1388 }
1389 } // new fTrackBetaIncludeSinglePmtHits
1390 } // matches else
1391 } // condition for cenetr on a paddle
1392 ihhit++;
1393 } // First loop over hits in a plane <---------
1394
1395 //-----------------------------------------------------------------------------------------------
1396 //------------- First large loop over scintillator hits ends here --------------------
1397 //-----------------------------------------------------------------------------------------------
1398 }
1399 Int_t nhits=ihhit;
1400
1401 Double_t TimePeak = DetermineTimePeak(2);
1402 if(TimePeak> 0) {
1403
1404 for(Int_t ih = 0; ih < nhits; ih++) { // loop over all scintillator hits
1405 if ( ( fTOFPInfo[ih].time_pos > (TimePeak-fTofTolerance) ) && ( fTOFPInfo[ih].time_pos < ( TimePeak + fTofTolerance ) ) ) {
1406 fTOFPInfo[ih].keep_pos=kTRUE;
1407 }
1408 if ( ( fTOFPInfo[ih].time_neg > (TimePeak-fTofTolerance) ) && ( fTOFPInfo[ih].time_neg < ( TimePeak + fTofTolerance ) ) ){
1409 fTOFPInfo[ih].keep_neg=kTRUE;
1410 }
1411 }
1412 }
1413
1414 //---------------------------------------------------------------------------------------------
1415 // ---------------------- Second loop over scint. hits in a plane -----------------------------
1416 //---------------------------------------------------------------------------------------------
1417
1418 fdEdX[itrack].reserve(nhits);
1419 fTOFCalc.reserve(nhits);
1420 for(Int_t ih=0; ih < nhits; ih++) {
1421 THcHodoHit *hit = fTOFPInfo[ih].hit;
1422 Int_t iphit = fTOFPInfo[ih].hitNumInPlane;
1423 Int_t ip = fTOFPInfo[ih].planeIndex;
1424 // fDumpOut << " looping over hits = " << ih << " plane = " << ip+1 << endl;
1425 // Flags are used by THcHodoEff
1426 fGoodFlags[itrack][ip].reserve(nhits);
1427 fGoodFlags[itrack][ip].push_back(GoodFlags());
1428 assert( iphit >= 0 && (size_t)iphit < fGoodFlags[itrack][ip].size() );
1429 fGoodFlags[itrack][ip][iphit].onTrack = kFALSE;
1430 fGoodFlags[itrack][ip][iphit].goodScinTime = kFALSE;
1431 fGoodFlags[itrack][ip][iphit].goodTdcNeg = kFALSE;
1432 fGoodFlags[itrack][ip][iphit].goodTdcPos = kFALSE;
1433
1434 fTOFCalc.emplace_back();
1435 // Do we set back to false for each track, or just once per event?
1436 assert( ih >= 0 && (size_t)ih < fTOFCalc.size() );
1437 fTOFCalc[ih].good_scin_time = kFALSE;
1438 // These need a track index too to calculate efficiencies
1439 fTOFCalc[ih].good_tdc_pos = kFALSE;
1440 fTOFCalc[ih].good_tdc_neg = kFALSE;
1441 fTOFCalc[ih].pindex = ip;
1442
1443 Int_t paddle = hit->GetPaddleNumber()-1;
1444 fTOFCalc[ih].hit_paddle = paddle;
1445 fTOFCalc[ih].good_raw_pad = paddle;
1446
1447 // Double_t scinCenter = fPlanes[ip]->GetPosCenter(paddle) + fPlanes[ip]->GetPosOffset();
1448 // Double_t scinTrnsCoord = fTOFPInfo[ih].scinTrnsCoord;
1449 // Double_t scinLongCoord = fTOFPInfo[ih].scinLongCoord;
1450
1451 Int_t fPIndex = GetScinIndex(ip,paddle);
1452
1453 if (fTOFPInfo[ih].onTrack) {
1454 fGoodFlags[itrack][ip][iphit].onTrack = kTRUE;
1455 if ( fTOFPInfo[ih].keep_pos ) { // 301
1456 fTOFCalc[ih].good_tdc_pos = kTRUE;
1457 fGoodFlags[itrack][ip][iphit].goodTdcPos = kTRUE;
1458 }
1459 if ( fTOFPInfo[ih].keep_neg ) { //
1460 fTOFCalc[ih].good_tdc_neg = kTRUE;
1461 fGoodFlags[itrack][ip][iphit].goodTdcNeg = kTRUE;
1462 }
1463 // ** Calculate ave time for scin and error.
1464 if ( fTOFCalc[ih].good_tdc_pos ){
1465 if ( fTOFCalc[ih].good_tdc_neg ){
1466 fTOFCalc[ih].scin_time = ( fTOFPInfo[ih].scin_pos_time +
1467 fTOFPInfo[ih].scin_neg_time ) / 2.;
1468 fTOFCalc[ih].scin_time_fp = ( fTOFPInfo[ih].time_pos +
1469 fTOFPInfo[ih].time_neg ) / 2.;
1470
1471 if (fTofUsingInvAdc){
1472 fTOFCalc[ih].scin_sigma = TMath::Sqrt( fHodoPosSigma[fPIndex] * fHodoPosSigma[fPIndex] +
1473 fHodoNegSigma[fPIndex] * fHodoNegSigma[fPIndex] )/2.;
1474 }
1475 else {
1476 fTOFCalc[ih].scin_sigma = TMath::Sqrt( fHodoSigmaPos[fPIndex] * fHodoSigmaPos[fPIndex] +
1477 fHodoSigmaNeg[fPIndex] * fHodoSigmaNeg[fPIndex] )/2.;
1478 }
1479
1480 fTOFCalc[ih].good_scin_time = kTRUE;
1481 fGoodFlags[itrack][ip][iphit].goodScinTime = kTRUE;
1482 } else{
1483 fTOFCalc[ih].scin_time = fTOFPInfo[ih].scin_pos_time;
1484 fTOFCalc[ih].scin_time_fp = fTOFPInfo[ih].time_pos;
1485
1486 if (fTofUsingInvAdc){
1487 fTOFCalc[ih].scin_sigma = fHodoPosSigma[fPIndex];
1488 }
1489 else{
1490 fTOFCalc[ih].scin_sigma = fHodoSigmaPos[fPIndex];
1491 }
1492
1493 fTOFCalc[ih].good_scin_time = kTRUE;
1494 fGoodFlags[itrack][ip][iphit].goodScinTime = kTRUE;
1495 }
1496 } else {
1497 if ( fTOFCalc[ih].good_tdc_neg ){
1498 fTOFCalc[ih].scin_time = fTOFPInfo[ih].scin_neg_time;
1499 fTOFCalc[ih].scin_time_fp = fTOFPInfo[ih].time_neg;
1500 if (fTofUsingInvAdc){
1501 fTOFCalc[ih].scin_sigma = fHodoNegSigma[fPIndex];
1502 }
1503 else{
1504 fTOFCalc[ih].scin_sigma = fHodoSigmaNeg[fPIndex];
1505 }
1506 fTOFCalc[ih].good_scin_time = kTRUE;
1507 fGoodFlags[itrack][ip][iphit].goodScinTime = kTRUE;
1508 }
1509 } // In h_tof.f this includes the following if condition for time at focal plane
1510 // // because it is written in FORTRAN code
1511
1512 // c Get time at focal plane
1513 if ( fTOFCalc[ih].good_scin_time ){
1514
1515 // scin_time_fp doesn't need to be an array
1516 // Is this any different than the average of time_pos and time_neg?
1517 // Double_t scin_time_fp = ( fTOFPInfo[ih].time_pos +
1518 // fTOFPInfo[ih].time_neg ) / 2.;
1519 Double_t scin_time_fp = fTOFCalc[ih].scin_time_fp;
1520
1521 sumFPTime = sumFPTime + scin_time_fp;
1522 nFPTime ++;
1523
1524 fSumPlaneTime[ip] = fSumPlaneTime[ip] + scin_time_fp;
1525 fNPlaneTime[ip] ++;
1526 fNScinHit[itrack] ++;
1527
1528 if ( ( fTOFCalc[ih].good_tdc_pos ) && ( fTOFCalc[ih].good_tdc_neg ) ){
1529 nPmtHit[itrack] = nPmtHit[itrack] + 2;
1530 } else {
1531 nPmtHit[itrack] = nPmtHit[itrack] + 1;
1532 }
1533
1534 fdEdX[itrack].push_back(0.0);
1535 assert( fNScinHit[itrack] > 0 && (size_t)fNScinHit[itrack] < fdEdX[itrack].size()+1 );
1536
1537 // --------------------------------------------------------------------------------------------
1538 if ( fTOFCalc[ih].good_tdc_pos ){
1539 if ( fTOFCalc[ih].good_tdc_neg ){
1540 fdEdX[itrack][fNScinHit[itrack]-1]=
1541 TMath::Sqrt( TMath::Max( 0., hit->GetPosADC() * hit->GetNegADC() ) );
1542 } else{
1543 fdEdX[itrack][fNScinHit[itrack]-1]=
1544 TMath::Max( 0., hit->GetPosADC() );
1545 }
1546 } else{
1547 if ( fTOFCalc[ih].good_tdc_neg ){
1548 fdEdX[itrack][fNScinHit[itrack]-1]=
1549 TMath::Max( 0., hit->GetNegADC() );
1550 } else{
1551 fdEdX[itrack][fNScinHit[itrack]-1]=0.0;
1552 }
1553 }
1554 // --------------------------------------------------------------------------------------------
1555
1556
1557 } // time at focal plane condition
1558 } // on track condition
1559
1560 // ** See if there are any good time measurements in the plane.
1561 if ( fTOFCalc[ih].good_scin_time ){
1562 fGoodPlaneTime[ip] = kTRUE;
1563 fTOFCalc[ih].dedx = fdEdX[itrack][fNScinHit[itrack]-1];
1564 } else {
1565 fTOFCalc[ih].dedx = 0.0;
1566 }
1567
1568 } // Second loop over hits of a scintillator plane ends here
1569 theTrack->SetGoodPlane3( fGoodPlaneTime[2] ? 1 : 0 );
1570 if (fNumPlanesBetaCalc==4) theTrack->SetGoodPlane4( fGoodPlaneTime[3] ? 1 : 0 );
1571 //
1572 //------------------------------------------------------------------------------
1573 //------------------------------------------------------------------------------
1574 //------------------------------------------------------------------------------
1575 //------------------------------------------------------------------------------
1576 //------------------------------------------------------------------------------
1577 //------------------------------------------------------------------------------
1578 //------------------------------------------------------------------------------
1579 //------------------------------------------------------------------------------
1580
1581 // * * Fit beta if there are enough time measurements (one upper, one lower)
1582 // From h_tof_fit
1583 if ( ( ( fGoodPlaneTime[0] ) || ( fGoodPlaneTime[1] ) ) &&
1584 ( ( fGoodPlaneTime[2] ) || ( fGoodPlaneTime[3] ) ) ){
1585
1586 Double_t sumW = 0.;
1587 Double_t sumT = 0.;
1588 Double_t sumZ = 0.;
1589 Double_t sumZZ = 0.;
1590 Double_t sumTZ = 0.;
1591
1592 for(Int_t ih=0; ih < nhits; ih++) {
1593 Int_t ip = fTOFPInfo[ih].planeIndex;
1594
1595 if ( fTOFCalc[ih].good_scin_time ) {
1596
1597 Double_t scinWeight = 1 / ( fTOFCalc[ih].scin_sigma * fTOFCalc[ih].scin_sigma );
1598 Double_t zPosition = ( fPlanes[ip]->GetZpos()
1599 +( fTOFCalc[ih].hit_paddle % 2 ) *
1600 fPlanes[ip]->GetDzpos() );
1601
1602 sumW += scinWeight;
1603 sumT += scinWeight * fTOFCalc[ih].scin_time;
1604 sumZ += scinWeight * zPosition;
1605 sumZZ += scinWeight * ( zPosition * zPosition );
1606 sumTZ += scinWeight * zPosition * fTOFCalc[ih].scin_time;
1607
1608 } // condition of good scin time
1609 } // loop over hits
1610
1611 Double_t tmp = sumW * sumZZ - sumZ * sumZ ;
1612 Double_t t0 = ( sumT * sumZZ - sumZ * sumTZ ) / tmp ;
1613 Double_t tmpDenom = sumW * sumTZ - sumZ * sumT;
1614
1615 if ( TMath::Abs( tmpDenom ) > ( 1 / 10000000000.0 ) ) {
1616
1617 beta = tmp / tmpDenom;
1618 betaChiSq = 0.;
1619
1620 for(Int_t ih=0; ih < nhits; ih++) {
1621 Int_t ip = fTOFPInfo[ih].planeIndex;
1622
1623 if ( fTOFCalc[ih].good_scin_time ){
1624
1625 Double_t zPosition = ( fPlanes[ip]->GetZpos() + ( fTOFCalc[ih].hit_paddle % 2 ) *
1626 fPlanes[ip]->GetDzpos() );
1627 Double_t timeDif = ( fTOFCalc[ih].scin_time - t0 );
1628 betaChiSq += ( ( zPosition / beta - timeDif ) *
1629 ( zPosition / beta - timeDif ) ) /
1630 ( fTOFCalc[ih].scin_sigma * fTOFCalc[ih].scin_sigma );
1631
1632 } // condition for good scin time
1633 } // loop over hits
1634
1635 Double_t pathNorm = TMath::Sqrt( 1. + theTrack->GetTheta() * theTrack->GetTheta() +
1636 theTrack->GetPhi() * theTrack->GetPhi() );
1637 // Take angle into account
1638 beta = beta / pathNorm;
1639 beta = beta / 29.979; // velocity / c
1640
1641 } // condition for fTmpDenom
1642 else {
1643 beta = 0.;
1644 betaChiSq = -2.;
1645 } // else condition for fTmpDenom
1646 } else {
1647 beta = 0.;
1648 betaChiSq = -1;
1649 }
1650
1651 if ( nFPTime != 0 ){
1652 timeAtFP[itrack] = ( sumFPTime / nFPTime );
1653 }
1654 //
1655 // ---------------------------------------------------------------------------
1656
1657 Double_t FPTimeSum=0.0;
1658 Int_t nFPTimeSum=0;
1659 Int_t nGoodPlanesHit=0;
1660 for (Int_t ip = 0; ip < fNumPlanesBetaCalc; ip++ ){
1661 if ( fNPlaneTime[ip] != 0 ){
1662 nGoodPlanesHit++;
1663 fFPTime[ip] = ( fSumPlaneTime[ip] / fNPlaneTime[ip] );
1664 FPTimeSum += fSumPlaneTime[ip];
1665 nFPTimeSum += fNPlaneTime[ip];
1666 } else {
1667 fFPTime[ip] = 1000. * ( ip + 1 );
1668 }
1669 }
1670 Double_t fptime=-2000;
1671 fptime=fStartTime;
1672 if (nGoodPlanesHit>=3) fptime = FPTimeSum/nFPTimeSum;
1673 fFPTimeAll = fptime;
1674 Double_t dedx=0.0;
1675 for( auto& ih: fTOFCalc ) {
1676 if( ih.good_scin_time ) {
1677 dedx = ih.dedx;
1678 break;
1679 }
1680 }
1681 theTrack->SetDedx(dedx);
1682 theTrack->SetFPTime(fptime);
1683 theTrack->SetBeta(beta);
1684 theTrack->SetBetaChi2( betaChiSq );
1685 theTrack->SetNPMT(nPmtHit[itrack]);
1686
1687
1688 } // Main loop over tracks ends here.
1689
1690 } // If condition for at least one track
1691
1692
1693 //OriginalTrackEffTest();
1694 TrackEffTest();
1695 //
1696 CalcCluster();
1697
1698 return 0;
1699
1700}
1701//
1703{
1704 // THcHallCSpectrometer *app = dynamic_cast<THcHallCSpectrometer*>(GetApparatus());
1705 // cout << app->GetName() << endl;
1706 const Int_t MaxNCluster=5;
1707 std::vector<Int_t > iw(MaxNCluster,0);
1708 std::vector<Double_t > dw(MaxNCluster,0);
1709 for(Int_t ip = 0; ip < fNumPlanesBetaCalc; ip++ ) {
1710 fNCluster.push_back(0);
1711 fClusterSize.push_back(iw);
1712 fClusterXPos.push_back(dw);
1713 fClusterYPos.push_back(dw);
1714 }
1715 for (Int_t ip = 0; ip < fNumPlanesBetaCalc; ip++ ){
1716 Double_t pl_xypos=0;
1717 Double_t pl_calcpos=0;
1718 Double_t pl_zpos=0;
1719 Int_t num_good_pad=0;
1720 Double_t pl_x=0,pl_y=0;
1721 TClonesArray* hodoHits = fPlanes[ip]->GetHits();
1722 Int_t prev_padnum=-100;
1723 for (Int_t iphit = 0; iphit < fPlanes[ip]->GetNScinHits(); iphit++ ){
1724 THcHodoHit *hit = (THcHodoHit*)hodoHits->At(iphit);
1725 if ( hit->GetTwoGoodTimes() ) {
1726 Int_t padind = hit->GetPaddleNumber()-1;
1727 Int_t padnum = padind+1;
1728 if (ip==0 || ip==2) pl_x = fPlanes[ip]->GetPosCenter(padind)+ fPlanes[ip]->GetPosOffset();
1729 if (ip==0 || ip==2) pl_y = ((THcHodoHit*)hodoHits->At(iphit))->GetCalcPosition();
1730 if (ip==1 || ip==3) pl_y = fPlanes[ip]->GetPosCenter(padind)+ fPlanes[ip]->GetPosOffset();
1731 if (ip==1 || ip==3) pl_x = ((THcHodoHit*)hodoHits->At(iphit))->GetCalcPosition();
1732 pl_xypos+=fPlanes[ip]->GetPosCenter(padind)+ fPlanes[ip]->GetPosOffset();
1733 pl_calcpos=((THcHodoHit*)hodoHits->At(iphit))->GetCalcPosition();
1734 pl_zpos+=fPlanes[ip]->GetZpos()+ (padind%2)*fPlanes[ip]->GetDzpos();
1735 num_good_pad++;
1736 if ( fNCluster[ip]>0 && abs(padnum-prev_padnum)==1 && fClusterSize[ip][fNCluster[ip]-1]==1) {
1737 fClusterSize[ip][fNCluster[ip]-1]=fClusterSize[ip][fNCluster[ip]-1]+1;
1738 fClusterXPos[ip][fNCluster[ip]-1]+=pl_x;
1739 fClusterYPos[ip][fNCluster[ip]-1]+=pl_y;
1740 // cout << "Add to cluster pl = " << ip+1 << " hit = " << iphit << " pad = " << padnum << " clus = " << fNCluster[ip] << " cl size = " << fClusterSize[ip][fNCluster[ip]-1] << " Xpos " << pl_x << " Ypos = " << pl_y << " postime = " << hit->GetPosTOFCorrectedTime() << " negtime = " << hit->GetNegTOFCorrectedTime() << endl;
1741 } else {
1742 if (fNCluster[ip]<MaxNCluster) fNCluster[ip]++;
1743 fClusterSize[ip][fNCluster[ip]-1]=1;
1744 fClusterXPos[ip][fNCluster[ip]-1]=pl_x;
1745 fClusterYPos[ip][fNCluster[ip]-1]=pl_y;
1746 // cout << " New clus pl = " << ip+1 << " hit = " << iphit << " pad = " << padnum << " clus = " << fNCluster[ip] << " cl size = " << fClusterSize[ip][fNCluster[ip]-1] << " Xpos = " << pl_x << " Ypos = " << pl_y << " postime = " << hit->GetPosTOFCorrectedTime() << " negtime = " << hit->GetNegTOFCorrectedTime() << endl;
1747 }
1748 prev_padnum=padnum;
1749 }
1750 }
1751 //
1752 for (Int_t ic = 0; ic < fNCluster[ip]; ic++ ){
1753 fClusterXPos[ip][ic]/=fClusterSize[ip][ic];
1754 fClusterYPos[ip][ic]/=fClusterSize[ip][ic];
1755 // cout << " Cluster = " << ic+1 << " Xpos = " << fClusterXPos[ip][ic] << " Ypos = " << fClusterYPos[ip][ic] << endl;
1756 }
1757 //
1758 if (num_good_pad !=0 ) {
1759 pl_xypos=pl_xypos/num_good_pad;
1760 pl_calcpos=pl_calcpos/num_good_pad;
1761 pl_zpos=pl_zpos/num_good_pad;
1762 } else {
1763 pl_xypos = kBig;
1764 pl_calcpos = kBig;
1765 pl_zpos = kBig;
1766 }
1767 // fPlanes[ip]->SetTranversePos(pl_xypos);
1768 //fPlanes[ip]->SetLongPos(pl_calcpos);
1769 }
1770 //
1771 // analyze clusters
1772 Int_t best_cluster[4]={-1,-1,-1,-1};
1773 Double_t diffx_test;
1774 Double_t diffx;
1775 Double_t diffy_test;
1776 Double_t diffy;
1777 Int_t pl1,pl2;
1778 for (Int_t nch = 0; nch < 2; nch++ ){
1779 if (nch==0) pl1=0;
1780 if (nch==1) pl1=2;
1781 pl2=pl1+1;
1782 diffx_test=1000;
1783 diffy_test=1000;
1784 if ( fNCluster[pl1]>=1 && fNCluster[pl2]>=1 ) {
1785 for (Int_t ic1 = 0; ic1 < fNCluster[pl1]; ic1++ ){
1786 for (Int_t ic2 = 0; ic2 < fNCluster[pl2]; ic2++ ){
1787 diffx= abs(fClusterXPos[pl1][ic1]-fClusterXPos[pl2][ic2]);
1788 diffy= abs(fClusterYPos[pl1][ic1]-fClusterYPos[pl2][ic2]);
1789 if ( (ic1==0 && ic2==0) || (diffx <=diffx_test && diffy <=diffy_test)) {
1790 diffx_test=diffx;
1791 diffy_test=diffy;
1792 best_cluster[pl1]=ic1;
1793 best_cluster[pl2]=ic2;
1794 }
1795 }}
1796 } else {
1797 if (fNCluster[pl1]==1) best_cluster[pl1]=0;
1798 if (fNCluster[pl2]==1) best_cluster[pl2]=0;
1799 }
1800 }
1801 //
1802 Int_t pl_test1[4]={0,1,2,3};
1803 Int_t pl_test2[4]={2,3,0,1};
1804 for (Int_t npl = 0; npl < 4; npl++ ){
1805 pl1=pl_test1[npl];
1806 pl2=pl_test2[npl];
1807 if (fNCluster[pl1]>0 && best_cluster[pl1]==-1 && fNCluster[pl2]>0 && best_cluster[pl2]>-1) {
1808 diffx_test=1000;
1809 diffy_test=1000;
1810 for (Int_t ic1 = 0; ic1 < fNCluster[pl1]; ic1++ ){
1811 diffx= abs(fClusterXPos[pl1][ic1]-fClusterXPos[pl2][best_cluster[pl2]]);
1812 diffy= abs(fClusterYPos[pl1][ic1]-fClusterYPos[pl2][best_cluster[pl2]]);
1813 if ( (diffx <=diffx_test && diffy <=diffy_test)) {
1814 diffx_test=diffx;
1815 diffy_test=diffy;
1816 best_cluster[pl1]=ic1;
1817 }
1818 }
1819 }
1820 }
1821 //
1822 //
1823
1824 //
1825 for (Int_t npl = 0; npl < 4; npl++ ){
1826 /*
1827 if (best_cluster[npl]==-1) {
1828 cout << " PLane = " << npl+1 << " no best cluster " << endl;
1829 } else {
1830 cout << " plane = " << npl+1 << " xpos = " << fClusterXPos[npl][best_cluster[npl]] << " ypos = " << fClusterYPos[npl][best_cluster[npl]] << endl;
1831 }
1832 */
1833 if (best_cluster[npl]!=-1) fPlanes[npl]->SetScinYPos( fClusterYPos[npl][best_cluster[npl]] );
1834 if (best_cluster[npl]!=-1) fPlanes[npl]->SetScinXPos( fClusterXPos[npl][best_cluster[npl]] );
1835 }
1836 //
1837}
1838//
1840{
1841 Double_t PadLow[4];
1842 Double_t PadHigh[4];
1843 // assume X planes are 0,2 and Y planes are 1,3
1844 PadLow[0]=fxLoScin[0];
1845 PadLow[2]=fxLoScin[1];
1846 PadLow[1]=fyLoScin[0];
1847 PadLow[3]=fyLoScin[1];
1848 PadHigh[0]=fxHiScin[0];
1849 PadHigh[2]=fxHiScin[1];
1850 PadHigh[1]=fyHiScin[0];
1851 PadHigh[3]=fyHiScin[1];
1852 //
1853 Bool_t efftest_debug = kFALSE;
1854 if (efftest_debug) cout << " spec = " << GetApparatus()->GetName()[0] << endl;
1855 Double_t PadPosLo[4];
1856 Double_t PadPosHi[4];
1857 for (Int_t ip = 0; ip < fNumPlanesBetaCalc; ip++ ){
1858 Double_t lowtemp=fPlanes[ip]->GetPosCenter(PadLow[ip]-1)+ fPlanes[ip]->GetPosOffset();
1859 Double_t hitemp=fPlanes[ip]->GetPosCenter(PadHigh[ip]-1)+ fPlanes[ip]->GetPosOffset();
1860 if (lowtemp < hitemp) {
1861 PadPosLo[ip]=lowtemp;
1862 PadPosHi[ip]=hitemp;
1863 } else {
1864 PadPosLo[ip]=hitemp;
1865 PadPosHi[ip]=lowtemp;
1866 }
1867 }
1868 //
1869 const Int_t MaxNClus=5;
1870 std::vector<Int_t > iw(MaxNClus,0);
1871 std::vector<Double_t > dw(MaxNClus,0);
1872 for(Int_t ip = 0; ip < fNumPlanesBetaCalc; ip++ ) {
1873 fNClust.push_back(0);
1874 fClustSize.push_back(iw);
1875 fClustPos.push_back(dw);
1876 }
1877 for (Int_t ip = 0; ip < fNumPlanesBetaCalc; ip++ ){
1878 TClonesArray* hodoHits = fPlanes[ip]->GetHits();
1879 Int_t prev_padnum=-100;
1880 for (Int_t iphit = 0; iphit < fPlanes[ip]->GetNScinHits(); iphit++ ){
1881 THcHodoHit *hit = (THcHodoHit*)hodoHits->At(iphit);
1882 Int_t padnum = hit->GetPaddleNumber();
1883 if ( hit->GetTwoGoodTimes() ) {
1884 if ( padnum==prev_padnum+1 ) {
1885 fClustSize[ip][fNClust[ip]-1]=fClustSize[ip][fNClust[ip]-1]+1;
1886 fClustPos[ip][fNClust[ip]-1]+=fPlanes[ip]->GetPosCenter(padnum-1)+ fPlanes[ip]->GetPosOffset();
1887 if (efftest_debug) cout << "Add to cluster pl = " << ip+1 << " hit = " << iphit << " pad = " << padnum << " clus = " << fNClust[ip] << " cl size = " << fClustSize[ip][fNClust[ip]-1] << " pos " << fPlanes[ip]->GetPosCenter(padnum-1)+ fPlanes[ip]->GetPosOffset() << endl;
1888 } else {
1889 if (fNClust[ip]<MaxNClus) fNClust[ip]++;
1890 fClustSize[ip][fNClust[ip]-1]=1;
1891 fClustPos[ip][fNClust[ip]-1]=fPlanes[ip]->GetPosCenter(padnum-1)+ fPlanes[ip]->GetPosOffset();
1892 if (efftest_debug) cout << " New clus pl = " << ip+1 << " hit = " << iphit << " pad = " << padnum << " clus = " << fNClust[ip] << " cl size = " << fClustSize[ip][fNClust[ip]-1] << " pos " << fPlanes[ip]->GetPosCenter(padnum-1)+ fPlanes[ip]->GetPosOffset() << endl;
1893 }
1894 prev_padnum=padnum;
1895 }
1896 if (!(hit->GetTwoGoodTimes()) && efftest_debug) cout << "no two good times plane = " << ip+1 << " hit = " << iphit << endl;
1897 }
1898 }
1899 //
1900 Bool_t inside_bound[4][MaxNClus];
1901 for(Int_t ip = 0; ip < fNumPlanesBetaCalc; ip++ ) {
1903 for(Int_t ic = 0; ic <fNClust[ip] ; ic++ ) {
1904 fClustPos[ip][ic]=fClustPos[ip][ic]/fClustSize[ip][ic];
1905 fPlanes[ip]->SetCluster(ic,fClustPos[ip][ic]);
1906 fPlanes[ip]->SetClusterSize(ic,fClustSize[ip][ic]);
1907 inside_bound[ip][ic] = fClustPos[ip][ic]>=PadPosLo[ip] && fClustPos[ip][ic]<=PadPosHi[ip];
1908 if (efftest_debug) cout << "plane = " << ip+1 << " Cluster = " << ic+1 << " size = " << fClustSize[ip][ic]<< " pos = " << fClustPos[ip][ic] << " inside = " << inside_bound[ip][ic] << " lo = " << PadPosLo[ip]<< " hi = " << PadPosHi[ip]<< endl;
1909 }
1910 }
1911 //
1912 Int_t MaxClusterSize=3;
1913 Int_t good_for_track_test[4][MaxNClus];
1914 Int_t sum_good_track_test[4]={0,0,0,0};
1915 Int_t num_good_plane_hit=0;
1916 for(Int_t ip = 0; ip < fNumPlanesBetaCalc; ip++ ) {
1917 for(Int_t ic = 0; ic <fNClust[ip] ; ic++ ) {
1918 if (inside_bound[ip][ic] && fClustSize[ip][ic]<=MaxClusterSize) {
1919 fPlanes[ip]->SetClusterFlag(ic,1.);
1920 good_for_track_test[ip][ic]=1;
1921 sum_good_track_test[ip]++;
1922 if (sum_good_track_test[ip]==1) num_good_plane_hit++;
1923 } else {
1924 good_for_track_test[ip][ic]=0;
1925 }
1926 if (efftest_debug) cout << " ip " << ip+1 << " clus = " << ic << " good for track = " << good_for_track_test[ip][ic] << endl;
1927 }
1928 if (efftest_debug) cout << " ip = " << ip+1 << " sum_good_track_test = " << sum_good_track_test[ip] << endl;
1929 }
1930 if (efftest_debug) cout << " number of planes hits = " << num_good_plane_hit << endl;
1931 //
1932 Bool_t xdiffTest=kFALSE;
1933 Bool_t ydiffTest=kFALSE;
1934 fGoodScinHits = 0;
1935 if (efftest_debug) cout << " fTrackEffTestNScinPlanes = " << fTrackEffTestNScinPlanes << endl;
1936 if ( (fTrackEffTestNScinPlanes == 4 || fTrackEffTestNScinPlanes == 3) && num_good_plane_hit==4) {
1937
1938 // check for matching clusters in the X planes assumed to be planes 0 and 2
1939 for(Int_t ic0 = 0; ic0 <fNClust[0] ; ic0++ ) {
1940 for(Int_t ic2 = 0; ic2 <fNClust[2] ; ic2++ ) {
1941 if (good_for_track_test[0][ic0] && good_for_track_test[2][ic2]) {
1942 Double_t x1_proj = fClustPos[0][ic0]*(1+fRatio_xpfp_to_xfp*(fPlanes[2]->GetZpos()-fPlanes[0]->GetZpos())); // project X1 to X2 Z position
1943 xdiffTest= TMath::Abs(x1_proj-fClustPos[2][ic2])<trackeff_scint_xdiff_max;
1944 if (xdiffTest) fPlanes[0]->SetClusterUsedFlag(ic0,1.);
1945 if (xdiffTest) fPlanes[2]->SetClusterUsedFlag(ic2,1.);
1946 }
1947 }
1948 }
1949 // check for matching clusters in the Y planes assumed to be planes 1 and 3
1950 for(Int_t ic1 = 0; ic1 <fNClust[1] ; ic1++ ) {
1951 for(Int_t ic3 = 0; ic3 <fNClust[3] ; ic3++ ) {
1952 if (good_for_track_test[1][ic1] && good_for_track_test[3][ic3]) {
1953 ydiffTest= TMath::Abs(fClustPos[1][ic1]-fClustPos[3][ic3])<trackeff_scint_ydiff_max;
1954 if (ydiffTest) fPlanes[1]->SetClusterUsedFlag(ic1,1.);
1955 if (ydiffTest) fPlanes[3]->SetClusterUsedFlag(ic3,1.);
1956 }
1957 }
1958 }
1959 if (xdiffTest && ydiffTest) fGoodScinHits = 1;
1960 if (efftest_debug) cout << " 4 good planes xdiff = " << xdiffTest << " ydiff = " << ydiffTest << endl;
1961 }
1962 //
1963 if (fTrackEffTestNScinPlanes == 3 && num_good_plane_hit==3) {
1964 xdiffTest=kFALSE;
1965 ydiffTest=kFALSE;
1966 // Check if two X planes hit
1967 if (sum_good_track_test[0]>0&&sum_good_track_test[2]>0) {
1968 for(Int_t ic0 = 0; ic0 <fNClust[0] ; ic0++ ) {
1969 for(Int_t ic2 = 0; ic2 <fNClust[2] ; ic2++ ) {
1970 if (good_for_track_test[0][ic0] && good_for_track_test[2][ic2]) {
1971 xdiffTest= TMath::Abs(fClustPos[0][ic0]-fClustPos[2][ic2])<trackeff_scint_xdiff_max;
1972 }
1973 }
1974 }
1975 ydiffTest = kTRUE;
1976 }
1977 // Check if two Y planes hit
1978 if ((sum_good_track_test[1]>0||sum_good_track_test[3]>0)) {
1979 for(Int_t ic1 = 0; ic1 <fNClust[1] ; ic1++ ) {
1980 for(Int_t ic3 = 0; ic3 <fNClust[3] ; ic3++ ) {
1981 if (good_for_track_test[1][ic1] && good_for_track_test[3][ic3]) {
1982 ydiffTest= TMath::Abs(fClustPos[1][ic1]-fClustPos[3][ic3])<trackeff_scint_ydiff_max;
1983 }
1984 }
1985 xdiffTest = kTRUE;
1986 }
1987 }
1988 if (xdiffTest && ydiffTest) fGoodScinHits = 1;
1989 if (efftest_debug) cout << " 3 good planes xdiff = " << xdiffTest << " ydiff = " << ydiffTest << endl;
1990 }
1991 if (efftest_debug) cout << " ************" << endl;
1992 //
1993}
1994//
1995//
1996//
1998{
2003 //************************now look at some hodoscope tests
2004 // *second, we move the scintillators. here we use scintillator cuts to see
2005 // *if a track should have been found.
2006 cout << " enter track eff" << fNumPlanesBetaCalc << endl;
2007 for(Int_t ip = 0; ip < fNumPlanesBetaCalc; ip++ ) {
2008 cout << " loop over planes " << ip+1 << endl;
2009
2010 TClonesArray* hodoHits = fPlanes[ip]->GetHits();
2011 // TClonesArray* scinPosTDC = fPlanes[ip]->GetPosTDC();
2012 // TClonesArray* scinNegTDC = fPlanes[ip]->GetNegTDC();
2013
2014 fNScinHits[ip] = fPlanes[ip]->GetNScinHits();
2015 cout << " hits = " << fNScinHits[ip] << endl;
2016 for (Int_t iphit = 0; iphit < fNScinHits[ip]; iphit++ ){
2017 Int_t paddle = ((THcHodoHit*)hodoHits->At(iphit))->GetPaddleNumber()-1;
2018
2019 fScinHitPaddle[ip][paddle] = 1;
2020 cout << " hit = " << iphit+1 << " " << paddle+1 << endl;
2021 }
2022 }
2023
2024 // *next, look for clusters of hits in a scin plane. a cluster is a group of
2025 // *adjacent scintillator hits separated by a non-firing scintillator.
2026 // *Wwe count the number of three adjacent scintillators too. (A signle track
2027 // *shouldn't fire three adjacent scintillators.
2028
2029 for(Int_t ip = 0; ip < fNumPlanesBetaCalc; ip++ ) {
2030 // Planes ip = 0 = 1X
2031 // Planes ip = 2 = 2X
2032 fNClust.push_back(0);
2033 fThreeScin.push_back(0);
2034 }
2035
2036 // *look for clusters in x planes... (16 scins) !this assume both x planes have same
2037 // *number of scintillators.
2038 cout << " looking for cluster in x planes" << endl;
2039 Int_t icount;
2040 for (Int_t ip = 0; ip < 3; ip +=2 ) {
2041 icount = 0;
2042 if ( fScinHitPaddle[ip][0] == 1 ) icount ++;
2043 cout << "plane =" << ip << "check if paddle 1 hit " << icount << endl;
2044
2045 for (Int_t ipaddle = 0; ipaddle < (Int_t) fNPaddle[ip] - 1; ipaddle++ ){
2046 // !look for number of clusters of 1 or more hits
2047 if ( ( fScinHitPaddle[ip][ipaddle] == 0 ) &&
2048 ( fScinHitPaddle[ip][ipaddle + 1] == 1 ) )
2049 icount ++;
2050 cout << " paddle = " << ipaddle+1 << " " << icount << endl;
2051
2052 } // Loop over paddles
2053 cout << "Two cluster in plane = " << ip+1 << " " << icount << endl;
2054 fNClust[ip] = icount;
2055 icount = 0;
2056
2057 for (Int_t ipaddle = 0; ipaddle < (Int_t) fNPaddle[ip] - 2; ipaddle++ ){
2058 // !look for three or more adjacent hits
2059
2060 if ( ( fScinHitPaddle[ip][ipaddle] == 1 ) &&
2061 ( fScinHitPaddle[ip][ipaddle + 1] == 1 ) &&
2062 ( fScinHitPaddle[ip][ipaddle + 2] == 1 ) )
2063 icount ++;
2064 } // Second loop over paddles
2065 cout << "Three clusters in plane = " << ip+1 << " " << icount << endl;
2066
2067 if ( icount > 0 )
2068 fThreeScin[ip] = 1;
2069
2070 } // Loop over X plane
2071
2072 // *look for clusters in y planes... (10 scins) !this assume both y planes have same
2073 // *number of scintillators.
2074 cout << " looking for cluster in y planes" << endl;
2075
2076 for (Int_t ip = 1; ip < fNumPlanesBetaCalc; ip +=2 ) {
2077 // Planes ip = 1 = 1Y
2078 // Planes ip = 3 = 2Y
2079
2080 icount = 0;
2081 if ( fScinHitPaddle[ip][0] == 1 ) icount ++;
2082 cout << "plane =" << ip << "check if paddle 1 hit " << icount << endl;
2083
2084 for (Int_t ipaddle = 0; ipaddle < (Int_t) fNPaddle[ip] - 1; ipaddle++ ){
2085 // !look for number of clusters of 1 or more hits
2086
2087 if ( ( fScinHitPaddle[ip][ipaddle] == 0 ) &&
2088 ( fScinHitPaddle[ip][ipaddle + 1] == 1 ) )
2089 icount ++;
2090 cout << " paddle = " << ipaddle+1 << " " << icount << endl;
2091
2092 } // Loop over Y paddles
2093 cout << "Two cluster in plane = " << ip+1 << " " << icount << endl;
2094
2095 fNClust[ip] = icount;
2096 icount = 0;
2097
2098 for (Int_t ipaddle = 0; ipaddle < (Int_t) fNPaddle[ip] - 2; ipaddle++ ){
2099 // !look for three or more adjacent hits
2100
2101 if ( ( fScinHitPaddle[ip][ipaddle] == 1 ) &&
2102 ( fScinHitPaddle[ip][ipaddle + 1] == 1 ) &&
2103 ( fScinHitPaddle[ip][ipaddle + 2] == 1 ) )
2104 icount ++;
2105
2106 } // Second loop over Y paddles
2107 cout << "Three clusters in plane = " << ip+1 << " " << icount << endl;
2108
2109 if ( icount > 0 )
2110 fThreeScin[ip] = 1;
2111
2112 }// Loop over Y planes
2113
2114
2115 // *next we mask out the edge scintillators, and look at triggers that happened
2116 // *at the center of the acceptance. To change which scins are in the mask
2117 // *change the values of h*loscin and h*hiscin in htracking.param
2118
2119 // fGoodScinHits = 0;
2120 for (Int_t ifidx = fxLoScin[0]; ifidx < (Int_t) fxHiScin[0]; ifidx ++ ){
2121 fGoodScinHitsX.push_back(0);
2122 }
2123
2124 fHitSweet1X=0;
2125 fHitSweet2X=0;
2126 fHitSweet1Y=0;
2127 fHitSweet2Y=0;
2128 // *first x plane. first see if there are hits inside the scin region
2129 for (Int_t ifidx = fxLoScin[0]-1; ifidx < fxHiScin[0]; ifidx ++ ){
2130 if ( fScinHitPaddle[0][ifidx] == 1 ){
2131 fHitSweet1X = 1;
2132 fSweet1XScin = ifidx + 1;
2133 }
2134 }
2135
2136 // * next make sure nothing fired outside the good region
2137 for (Int_t ifidx = 0; ifidx < fxLoScin[0]-1; ifidx ++ ){
2138 if ( fScinHitPaddle[0][ifidx] == 1 ){ fHitSweet1X = -1; }
2139 }
2140 for (Int_t ifidx = fxHiScin[0]; ifidx < (Int_t) fNPaddle[0]; ifidx ++ ){
2141 if ( fScinHitPaddle[0][ifidx] == 1 ){ fHitSweet1X = -1; }
2142 }
2143
2144 // *second x plane. first see if there are hits inside the scin region
2145 for (Int_t ifidx = fxLoScin[1]-1; ifidx < fxHiScin[1]; ifidx ++ ){
2146 if ( fScinHitPaddle[2][ifidx] == 1 ){
2147 fHitSweet2X = 1;
2148 fSweet2XScin = ifidx + 1;
2149 }
2150 }
2151 // * next make sure nothing fired outside the good region
2152 for (Int_t ifidx = 0; ifidx < fxLoScin[1]-1; ifidx ++ ){
2153 if ( fScinHitPaddle[2][ifidx] == 1 ){ fHitSweet2X = -1; }
2154 }
2155 for (Int_t ifidx = fxHiScin[1]; ifidx < (Int_t) fNPaddle[2]; ifidx ++ ){
2156 if ( fScinHitPaddle[2][ifidx] == 1 ){ fHitSweet2X = -1; }
2157 }
2158
2159 // *first y plane. first see if there are hits inside the scin region
2160 for (Int_t ifidx = fyLoScin[0]-1; ifidx < fyHiScin[0]; ifidx ++ ){
2161 if ( fScinHitPaddle[1][ifidx] == 1 ){
2162 fHitSweet1Y = 1;
2163 fSweet1YScin = ifidx + 1;
2164 }
2165 }
2166 // * next make sure nothing fired outside the good region
2167 for (Int_t ifidx = 0; ifidx < fyLoScin[0]-1; ifidx ++ ){
2168 if ( fScinHitPaddle[1][ifidx] == 1 ){ fHitSweet1Y = -1; }
2169 }
2170 for (Int_t ifidx = fyHiScin[0]; ifidx < (Int_t) fNPaddle[1]; ifidx ++ ){
2171 if ( fScinHitPaddle[1][ifidx] == 1 ){ fHitSweet1Y = -1; }
2172 }
2173
2174 // *second y plane. first see if there are hits inside the scin region
2175 for (Int_t ifidx = fyLoScin[1]-1; ifidx < fyHiScin[1]; ifidx ++ ){
2176 if ( fScinHitPaddle[3][ifidx] == 1 ){
2177 fHitSweet2Y = 1;
2178 fSweet2YScin = ifidx + 1;
2179 }
2180 }
2181
2182 // * next make sure nothing fired outside the good region
2183 for (Int_t ifidx = 0; ifidx < fyLoScin[1]-1; ifidx ++ ){
2184 if ( fScinHitPaddle[3][ifidx] == 1 ){ fHitSweet2Y = -1; }
2185 }
2186 for (Int_t ifidx = fyHiScin[1]; ifidx < (Int_t) fNPaddle[3]; ifidx ++ ){
2187 if ( fScinHitPaddle[3][ifidx] == 1 ){ fHitSweet2Y = -1; }
2188 }
2189
2191
2192 // * now define a 3/4 or 4/4 trigger of only good scintillators the value
2193 // * is specified in htracking
2195 fGoodScinHits = 1;
2196 for (Int_t ifidx = fxLoScin[0]; ifidx < fxHiScin[0]; ifidx ++ ){
2197 if ( fSweet1XScin == ifidx )
2198 fGoodScinHitsX[ifidx] = 1;
2199 }
2200 }
2201
2202 // * require front/back hodoscopes be close to each other
2203 if ( ( fGoodScinHits == 1 ) && ( fTrackEffTestNScinPlanes == 4 ) ){
2204 if ( TMath::Abs( fSweet1XScin - fSweet2XScin ) > 3 )
2205 fGoodScinHits = 0;
2206 if ( TMath::Abs( fSweet1YScin - fSweet2YScin ) > 2 )
2207 fGoodScinHits = 0;
2208 }
2209//
2210}
2211//_____________________________________________________________________________
2213{
2214 Int_t Ntracks = tracks.GetLast()+1; // Number of reconstructed tracks
2215 Double_t hitPos;
2216 Double_t hitDistance;
2217 Int_t ih=0;
2218 for (Int_t itrk=0; itrk<Ntracks; itrk++) {
2219 THaTrack* theTrack = static_cast<THaTrack*>( tracks[itrk] );
2220 if (theTrack->GetIndex()==0) {
2221 fBeta=theTrack->GetBeta();
2222 fFPTimeAll=theTrack->GetFPTime();
2223 Double_t shower_track_enorm = theTrack->GetEnergy()/theTrack->GetP();
2224 for (Int_t ip = 0; ip < fNumPlanesBetaCalc; ip++ ){
2225 Double_t pl_xypos=0;
2226 Double_t pl_zpos=0;
2227 Int_t num_good_pad=0;
2228 TClonesArray* hodoHits = fPlanes[ip]->GetHits();
2229 for (Int_t iphit = 0; iphit < fPlanes[ip]->GetNScinHits(); iphit++ ){
2230 THcHodoHit *hit = fTOFPInfo[ih].hit;
2231 if ( fTOFCalc[ih].good_tdc_pos && fTOFCalc[ih].good_tdc_neg ) {
2232 Bool_t sh_pid=(shower_track_enorm > fTOFCalib_shtrk_lo && shower_track_enorm < fTOFCalib_shtrk_hi);
2234 // cer_pid is true if there is no Cherenkov detector
2236 if(fDumpTOF && Ntracks==1 && fGoodEventTOFCalib && sh_pid && beta_pid && cer_pid) {
2237 fDumpOut << fixed << setprecision(2);
2238 fDumpOut << showpoint << " 1" << setw(3) << ip+1 << setw(3) << hit->GetPaddleNumber() << setw(10) << hit->GetPosTDC()*fScinTdcToTime << setw(10) << fTOFPInfo[ih].pathp << setw(10) << fTOFPInfo[ih].zcor << setw(10) << fTOFPInfo[ih].time_pos << setw(10) << hit->GetPosADC() << endl;
2239 fDumpOut << showpoint << " 2" << setw(3) << ip+1 << setw(3) << hit->GetPaddleNumber() << setw(10) << hit->GetNegTDC()*fScinTdcToTime << setw(10) << fTOFPInfo[ih].pathn << setw(10) << fTOFPInfo[ih].zcor << setw(10) << fTOFPInfo[ih].time_neg << setw(10) << hit->GetNegADC() << endl;
2240 }
2241 Int_t padind = ((THcHodoHit*)hodoHits->At(iphit))->GetPaddleNumber()-1;
2242 pl_xypos+=fPlanes[ip]->GetPosCenter(padind)+ fPlanes[ip]->GetPosOffset();
2243 pl_zpos+=fPlanes[ip]->GetZpos()+ (padind%2)*fPlanes[ip]->GetDzpos();
2244 num_good_pad++;
2245 }
2246 ih++;
2247 // cout << ip << " " << iphit << " " << fGoodFlags[itrk][ip][iphit].goodScinTime << " " << fGoodFlags[itrk][ip][iphit].goodTdcPos << " " << fGoodFlags[itrk][ip][iphit].goodTdcNeg << endl;
2248 }
2249 hitDistance=kBig;
2250 if (num_good_pad !=0 ) {
2251 pl_xypos=pl_xypos/num_good_pad;
2252 pl_zpos=pl_zpos/num_good_pad;
2253 hitPos = theTrack->GetY() + theTrack->GetPhi()*pl_zpos ;
2254 if (ip%2 == 0) hitPos = theTrack->GetX() + theTrack->GetTheta()*pl_zpos ;
2255 hitDistance = hitPos - pl_xypos;
2256 fPlanes[ip]->SetTrackXPosition(theTrack->GetX() + theTrack->GetTheta()*pl_zpos );
2257 fPlanes[ip]->SetTrackYPosition(theTrack->GetY() + theTrack->GetPhi()*pl_zpos );
2258 }
2259 // cout << " ip " << ip << " " << hitPos << " " << pl_xypos << " " << pl_zpos << " " << hitDistance << endl;
2260 fPlanes[ip]->SetHitDistance(hitDistance);
2261 }
2262 if(ih>0&&fDumpTOF && Ntracks==1 && fGoodEventTOFCalib && shower_track_enorm > fTOFCalib_shtrk_lo && shower_track_enorm < fTOFCalib_shtrk_hi ) {
2263 fDumpOut << "0 " << endl;
2264 }
2265 }
2266 } //over tracks
2267 //
2268 return 0;
2269}
2270//_____________________________________________________________________________
2272 // GN: Return the index of a scintillator given the plane # and the paddle #
2273 // This assumes that both planes and
2274 // paddles start counting from 0!
2275 // Result also counts from 0.
2276 return fNPlanes*nPaddle+nPlane;
2277}
2278//_____________________________________________________________________________
2280 return nSide*fMaxHodoScin+fNPlanes*nPaddle+nPlane-1;
2281}
2282//_____________________________________________________________________________
2286
2287//_____________________________________________________________________________
2289{
2290 MissReport(Form("%s.%s", GetApparatus()->GetName(), GetName()));
2291 return 0;
2292}
int Int_t
unsigned int UInt_t
const Data_t kBig
size_t size(const MatrixT &matrix)
bool Bool_t
const Bool_t kFALSE
double Double_t
const Bool_t kTRUE
const char Option_t
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t np
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char mode
R__EXTERN class THaVarList * gHaVars
R__EXTERN class THaCutList * gHaCuts
ClassImp(VDC::AnalyticTTDConv) using namespace std
R__EXTERN class THcParmList * gHcParms
Definition THcGlobals.h:11
R__EXTERN class THcDetectorMap * gHcDetectorMap
Definition THcGlobals.h:12
Int_t fDebug
char * Form(const char *fmt,...)
virtual void SetRange(Int_t first=0, Int_t last=0)
void Reset(Option_t *option="") override
virtual Double_t GetMean(Int_t axis=1) const
TAxis * GetXaxis()
virtual Int_t GetNbinsX() const
virtual Int_t Fill(const char *name, Double_t w)
Double_t GetRMS(Int_t axis=1) const
virtual Double_t Integral(Int_t binx1, Int_t binx2, Option_t *option="") const
static Int_t DefineVarsFromList(const void *list, EType type, EMode mode, const char *def_prefix, const TObject *obj, const char *prefix, const char *here, const char *comment_subst="")
virtual const char * Here(const char *) const
Int_t RemoveVariables()
virtual Int_t Result(const char *cutname="", EWarnMode mode=kWarn)
UInt_t GetTotNumChan() const
THaDetMap * fDetMap
const Double_t * GetSize() const
THaApparatus * GetApparatus() const
UInt_t GetEvType() const
UInt_t GetEvNum() const
void SetFPTime(Double_t fptime)
void SetDedx(Double_t dedx)
Double_t GetX() const
Double_t GetPhi() const
void SetGoodPlane4(Int_t gdplane4)
void SetGoodPlane3(Int_t gdplane3)
Double_t GetEnergy() const
void SetNPMT(Int_t npmt)
Double_t GetTheta() const
Double_t GetBeta() const
Double_t GetY() const
Int_t GetIndex() const
void SetBeta(Double_t beta)
Double_t GetP() const
void SetBetaChi2(Double_t betachi2)
Double_t GetFPTime() const
virtual THaVar * Find(const char *name) const
const void * GetValuePointer() const
Class for gas Cherenkov detectors.
Double_t GetCerNPE()
virtual Int_t FillMap(THaDetMap *detmap, const char *detectorname)
A standard Hall C spectrometer apparatus.
virtual Int_t DecodeToHitList(const THaEvData &evdata, Bool_t suppress=kFALSE)
Populate the hitlist from the raw event data.
TClonesArray * fRawHitList
Definition THcHitList.h:51
void CreateMissReportParms(const char *prefix) const
void InitHitList(THaDetMap *detmap, const char *hitclass, Int_t maxhits, Int_t tdcref_cut=0, Int_t adcref_cut=0)
Save the electronics module to detector mapping and initialize a hit array of hits of class hitclass.
UInt_t fNRawHits
Definition THcHitList.h:45
void MissReport(const char *name) const
Class representing a single hit for the Hodoscopes.
Definition THcHodoHit.h:16
Double_t GetNegADCtime() const
Definition THcHodoHit.h:36
Double_t GetPosADCpeak() const
Definition THcHodoHit.h:33
Double_t GetPosADCtime() const
Definition THcHodoHit.h:35
Double_t GetNegADCCorrtime() const
Definition THcHodoHit.h:38
Int_t GetNegTDC() const
Definition THcHodoHit.h:41
Double_t GetPosADC() const
Definition THcHodoHit.h:31
Double_t GetPosTOFCorrectedTime() const
Definition THcHodoHit.h:44
Double_t GetNegTOFCorrectedTime() const
Definition THcHodoHit.h:45
Double_t GetPosADCCorrtime() const
Definition THcHodoHit.h:37
Double_t GetPosCorrectedTime() const
Definition THcHodoHit.h:42
Double_t GetNegADC() const
Definition THcHodoHit.h:32
Bool_t GetTwoGoodTimes() const
Definition THcHodoHit.h:47
Double_t GetNegCorrectedTime() const
Definition THcHodoHit.h:43
Int_t GetPosTDC() const
Definition THcHodoHit.h:40
Int_t GetPaddleNumber() const
Definition THcHodoHit.h:49
Bool_t GetHasCorrectedTimes() const
Definition THcHodoHit.h:48
void SetTwoGoodTimes(Bool_t flag)
Definition THcHodoHit.h:64
Double_t GetNegADCpeak() const
Definition THcHodoHit.h:34
Double_t GetScinCorrectedTime() const
Definition THcHodoHit.h:46
Generic hodoscope consisting of multiple planes with multiple paddles with phototubes on both ends.
std::vector< std::vector< Int_t > > fClustSize
Double_t * fHodoPosInvAdcAdc
Double_t * fHodoPos_c1
Double_t * fHodoNegTimeOffset
Double_t * fHodoNeg_c1
Double_t fOffsetTime
Double_t * fPlaneCenter
std::vector< std::vector< Int_t > > fScinHitPaddle
Double_t * fHodoCableFit
Double_t fTimeHist_StartTime_Hits
Int_t * fxHiScin
Double_t fTimeHist_FpTime_NumPeaks
Int_t fdebugprintscinraw
std::vector< std::vector< Double_t > > fClusterYPos
Double_t * fHodoSigmaNeg
THcScintillatorPlane ** fPlanes
Double_t fTOFCalib_beta_lo
Double_t fTdc_Thrs
Double_t * fHodoPosPhcCoeff
void CalcCluster(void)
virtual Int_t ReadDatabase(const TDatime &date)
Double_t trackeff_scint_ydiff_max
Double_t * fHodoPosMinPh
void EstimateFocalPlaneTime(void)
Double_t * fHodoPosAdcTimeWindowMin
Int_t fNumPlanesBetaCalc
Double_t fScinTdcToTime
Double_t * fHodoNegAdcTimeWindowMin
Double_t * fFPTime
virtual Int_t End(THaRunBase *run=0)
Double_t * fHodoSlop
Double_t fFPTimeAll
Double_t fScinTdcMin
Double_t * fHodoPosTimeOffset
Double_t fTimeHist_FpTime_Peak
Int_t * fHodoNegPedLimit
string fTOFDumpFile
Double_t fBeta
std::vector< Int_t > fThreeScin
Double_t * fHodoNegInvAdcLinear
Double_t fScinTdcMax
Bool_t * fGoodPlaneTime
Double_t DetermineTimePeak(Int_t FillFlag)
Double_t * fHodoPosAdcTimeWindowMax
Double_t fBetaNoTrk
Bool_t fGoodEventTOFCalib
Int_t * fHodoPosPedLimit
virtual EStatus Init(const TDatime &run_time)
Double_t fTofTolerance
Double_t * fHodoNegPhcCoeff
std::vector< TOFPInfo > fTOFPInfo
Double_t * fHodoNegSigma
Double_t fTOFCalib_beta_hi
Int_t * fNPlaneTime
Double_t fTimeHist_StartTime_NumPeaks
UInt_t fTotHodScin
virtual Int_t Decode(const THaEvData &)
virtual ~THcHodoscope()
Int_t fTDC_RefTimeCut
Double_t * fHodoPos_c2
UInt_t * fNPaddle
char ** fPlaneNames
Double_t fNormETot
Int_t * fyLoScin
Double_t fTimeHist_FpTime_Hits
THcCherenkov * fCherenkov
std::vector< std::vector< std::vector< GoodFlags > > > fGoodFlags
Double_t fTOFCalib_shtrk_hi
Bool_t * fPresentP
Int_t fADC_RefTimeCut
std::vector< Int_t > fNCluster
Double_t fBetaNoTrkChiSq
Double_t * fHodoNegMinPh
void OriginalTrackEffTest(void)
Int_t * fyHiScin
ofstream fDumpOut
std::vector< Int_t > fNScinHit
Int_t fGoodScinHits
virtual Int_t DefineVariables(EMode mode=kDefine)
Int_t * fxLoScin
Int_t fTrackBetaIncludeSinglePmtHits
std::vector< Int_t > fGoodScinHitsX
Double_t fTimeHist_StartTime_Sigma
Int_t * fNScinHits
Double_t * fHodoNegInvAdcAdc
Double_t * fHodoPosInvAdcLinear
Double_t fStartTimeCenter
Double_t * fHodoVelLight
std::vector< Int_t > fNClust
Double_t * fHodoNegAdcTimeWindowMax
Double_t fTOFCalib_shtrk_lo
Double_t fPathLengthCentral
Int_t fTrackEffTestNScinPlanes
void Setup(const char *name, const char *description)
Int_t GetScinIndex(Int_t nPlane, Int_t nPaddle)
Double_t GetHodoSlop(Int_t ip)
Double_t fTOFCalib_cer_lo
Double_t fTimeHist_StartTime_Peak
Int_t fAnalyzePedestals
Double_t * fSumPlaneTime
Double_t fNCerNPE
UInt_t fMaxHodoScin
std::vector< std::vector< Double_t > > fdEdX
Double_t * fHodoPosInvAdcOffset
virtual Double_t TimeWalkCorrection(const Int_t &paddle, const ESide side)
UInt_t fMaxScinPerPlane
Double_t fRatio_xpfp_to_xfp
virtual Int_t CoarseProcess(TClonesArray &tracks)
std::vector< std::vector< Double_t > > fClusterXPos
Double_t * fHodoNeg_c2
Double_t fStartTimeSlop
Double_t * fHodoSigmaPos
std::vector< TOFCalc > fTOFCalc
Int_t fTofUsingInvAdc
Double_t * fHodoNegInvAdcOffset
virtual void Clear(Option_t *opt="")
Double_t * fPlaneSpacing
Double_t * fHodoPosSigma
Double_t fStartTime
virtual Int_t ApplyCorrections(void)
Double_t fTimeHist_FpTime_Sigma
Double_t fBetaNominal
Bool_t fGoodStartTime
Double_t GetPathLengthCentral()
std::vector< std::vector< Int_t > > fClusterSize
Double_t * fHodoVelFit
Double_t * fHodo_LCoeff
virtual Int_t FineProcess(TClonesArray &tracks)
Double_t * fAdcTdcOffset
Int_t * fTdcOffset
Double_t fPartMass
Double_t fADCStartTime
void TrackEffTest(void)
Double_t trackeff_scint_xdiff_max
std::vector< std::vector< Double_t > > fClustPos
Int_t LoadParmValues(const DBRequest *list, const char *prefix="")
Retrieve parameter values from the parameter cache.
A single plane of scintillators.
void SetCluster(Int_t ic, Double_t pos)
virtual void Clear(Option_t *opt="")
void SetTrackXPosition(Double_t f)
void SetScinXPos(Double_t f)
void SetScinYPos(Double_t f)
virtual Int_t ProcessHits(TClonesArray *rawhits, Int_t nexthit)
void SetNumberClusters(Int_t nclus)
virtual Int_t AccumulatePedestals(TClonesArray *rawhits, Int_t nexthit)
void SetHitDistance(Double_t f)
void SetClusterUsedFlag(Int_t ic, Double_t flag)
void SetTrackYPosition(Double_t f)
Double_t GetPosCenter(Int_t PaddleNo)
void SetClusterSize(Int_t ic, Double_t size)
void SetClusterFlag(Int_t ic, Double_t flag)
const char * GetName() const override
const char * GetTitle() const override
TObject * At(Int_t idx) const override
R__ALWAYS_INLINE Bool_t IsZombie() const
virtual void Error(const char *method, const char *msgfmt,...) const
double beta(double x, double y)
RVec< PromoteType< T > > abs(const RVec< T > &v)
RVec< PromoteTypes< T0, T1 > > pow(const RVec< T0 > &v, const T1 &y)
const Double_t sigma
Double_t Power(Double_t x, Double_t y)
Double_t Sqrt(Double_t x)
Double_t Abs(Double_t d)
Double_t Max(Double_t a, Double_t b)
STL namespace.
void tracks()