Hall C ROOT/C++ Analyzer (hcana)
THcShowerArray.cxx
Go to the documentation of this file.
1 
8 #include "THcShowerArray.h"
9 #include "THcHodoscope.h"
10 #include "TClonesArray.h"
11 #include "THcSignalHit.h"
12 #include "THcGlobals.h"
13 #include "THcParmList.h"
14 #include "THcHitList.h"
15 #include "THcShower.h"
16 #include "THcRawShowerHit.h"
17 #include "TClass.h"
18 #include "math.h"
19 #include "THaTrack.h"
20 #include "THaTrackProj.h"
21 #include "THcCherenkov.h" //for efficiency calculations
22 #include "THcHallCSpectrometer.h"
23 #include "Helper.h"
24 
25 #include <cstring>
26 #include <cstdio>
27 #include <cstdlib>
28 #include <iostream>
29 #include <cassert>
30 #include <fstream>
31 
32 using namespace std;
33 
35 
36 //______________________________________________________________________________
37 THcShowerArray::THcShowerArray( const char* name,
38  const char* description,
39  const Int_t layernum,
40  THaDetectorBase* parent )
41  : THaSubDetector(name,description,parent)
42 {
43  fADCHits = new TClonesArray("THcSignalHit",100);
44  fLayerNum = layernum;
45 
46  frAdcPedRaw = new TClonesArray("THcSignalHit", 16);
47  frAdcErrorFlag = new TClonesArray("THcSignalHit", 16);
48  frAdcPulseIntRaw = new TClonesArray("THcSignalHit", 16);
49  frAdcPulseAmpRaw = new TClonesArray("THcSignalHit", 16);
50  frAdcPulseTimeRaw = new TClonesArray("THcSignalHit", 16);
51 
52  frAdcPed = new TClonesArray("THcSignalHit", 16);
53  frAdcPulseInt = new TClonesArray("THcSignalHit", 16);
54  frAdcPulseAmp = new TClonesArray("THcSignalHit", 16);
55  frAdcPulseTime = new TClonesArray("THcSignalHit", 16);
56 
57  fClusterList = new THcShowerClusterList; // List of hit clusters
58 }
59 
60 //______________________________________________________________________________
62 {
63  // Destructor
64 
65  Clear(); // deletes allocations in fClusterList
66  for (UInt_t i=0; i<fNRows; i++) {
67  delete [] fXPos[i];
68  delete [] fYPos[i];
69  delete [] fZPos[i];
70  }
71  delete [] fXPos; fXPos = 0;
72  delete [] fYPos; fYPos = 0;
73  delete [] fZPos; fZPos = 0;
74 
75  delete [] fPedLimit;
76  delete [] fGain;
77  delete [] fPedSum;
78  delete [] fPedSum2;
79  delete [] fPedCount;
80  delete [] fSig;
81  delete [] fPed;
82  delete [] fThresh;
83 
84  delete fADCHits; fADCHits = NULL;
85 
86  delete frAdcPedRaw; frAdcPedRaw = NULL;
87  delete frAdcErrorFlag; frAdcErrorFlag = NULL;
88  delete frAdcPulseIntRaw; frAdcPulseIntRaw = NULL;
89  delete frAdcPulseAmpRaw; frAdcPulseAmpRaw = NULL;
90  delete frAdcPulseTimeRaw; frAdcPulseTimeRaw = NULL;
91 
92  delete frAdcPed; frAdcPed = NULL;
93  delete frAdcPulseInt; frAdcPulseInt = NULL;
94  delete frAdcPulseAmp; frAdcPulseAmp = NULL;
95  delete frAdcPulseTime; frAdcPulseTime = NULL;
96 
97  // delete [] fA;
98  //delete [] fP;
99  // delete [] fA_p;
100 
101  //delete [] fE;
102  delete [] fBlock_ClusterID;
103 
104  delete fClusterList; fClusterList = 0;
105 
106  delete [] fAdcTimeWindowMin; fAdcTimeWindowMin = 0;
107  delete [] fAdcTimeWindowMax; fAdcTimeWindowMax = 0;
108  delete [] fPedDefault; fPedDefault = 0;
109 }
110 
111 //_____________________________________________________________________________
112 THaAnalysisObject::EStatus THcShowerArray::Init( const TDatime& date )
113 {
114  // Extra initialization for shower layer: set up DataDest map
115 
116  if( IsZombie())
117  return fStatus = kInitError;
118 
119  // How to get information for parent
120  // if( GetParent() )
121  // fOrigin = GetParent()->GetOrigin();
122  THcHallCSpectrometer *app=dynamic_cast<THcHallCSpectrometer*>(GetApparatus());
123  if( !app ||
124  !(fglHod = dynamic_cast<THcHodoscope*>(app->GetDetector("hod"))) ) {
125  static const char* const here = "ReadDatabase()";
126  Warning(Here(here),"Hodoscope \"%s\" not found. ","hod");
127  }
128 
129  EStatus status;
130  if( (status=THaSubDetector::Init( date )) )
131  return fStatus = status;
132 
133  return fStatus = kOK;
134 
135 }
136 
137 //_____________________________________________________________________________
139 {
140 
141  char prefix[2];
142  prefix[0]=tolower(GetParent()->GetPrefix()[0]);
143  prefix[1]='\0';
144 
145  // cout << "Parent name: " << GetParent()->GetPrefix() << endl;
146  fNRows=fNColumns=0;
148  fXStep=fYStep=fZSize=0.;
149  fUsingFADC=0;
150  fPedSampLow=0;
151  fPedSampHigh=9;
152  fDataSampLow=23;
153  fDataSampHigh=49;
154  fStatCerMin=1.;
155  fStatSlop=3.;
156  fStatMaxChi2=10.;
157  DBRequest list[]={
158  {"cal_arr_nrows", &fNRows, kInt},
159  {"cal_arr_ncolumns", &fNColumns, kInt},
160  {"cal_arr_front_x", &fXFront, kDouble},
161  {"cal_arr_front_y", &fYFront, kDouble},
162  {"cal_arr_front_z", &fZFront, kDouble},
163  {"cal_arr_xstep", &fXStep, kDouble},
164  {"cal_arr_ystep", &fYStep, kDouble},
165  {"cal_arr_zsize", &fZSize, kDouble},
166  {"cal_using_fadc", &fUsingFADC, kInt, 0, 1},
167  {"cal_arr_ADCMode", &fADCMode, kInt, 0, 1},
168  {"cal_arr_adc_tdc_offset", &fAdcTdcOffset, kDouble, 0, 1},
169  {"cal_arr_AdcThreshold", &fAdcThreshold, kDouble, 0, 1},
170  {"cal_ped_sample_low", &fPedSampLow, kInt, 0, 1},
171  {"cal_ped_sample_high", &fPedSampHigh, kInt, 0, 1},
172  {"cal_data_sample_low", &fDataSampLow, kInt, 0, 1},
173  {"cal_data_sample_high", &fDataSampHigh, kInt, 0, 1},
174  {"cal_debug_adc", &fDebugAdc, kInt, 0, 1},
175  {"stat_cermin", &fStatCerMin, kDouble, 0, 1},
176  {"stat_slop_array", &fStatSlop, kDouble, 0, 1},
177  {"stat_maxchisq", &fStatMaxChi2, kDouble, 0, 1},
178  {0}
179  };
180 
181  fDebugAdc = 0; // Set ADC debug parameter to false unless set in parameter file
183  fAdcTdcOffset=0.0;
184  fAdcThreshold=0.;
185 
186  gHcParms->LoadParmValues((DBRequest*)&list, prefix);
187  fNelem = fNRows*fNColumns;
188 
189  fXPos = new Double_t* [fNRows];
190  fYPos = new Double_t* [fNRows];
191  fZPos = new Double_t* [fNRows];
192  for (UInt_t i=0; i<fNRows; i++) {
193  fXPos[i] = new Double_t [fNColumns];
194  fYPos[i] = new Double_t [fNColumns];
195  fZPos[i] = new Double_t [fNColumns];
196  }
197 
198  //Looking to the front, the numbering goes from left to right, and from top
199  //to bottom.
200 
201  for (UInt_t j=0; j<fNColumns; j++)
202  for (UInt_t i=0; i<fNRows; i++) {
203  fXPos[i][j] = fXFront - (fNRows-1)*fXStep/2 + fXStep*i;
204  fYPos[i][j] = fYFront + (fNColumns-1)*fYStep/2 - fYStep*j;
205  fZPos[i][j] = fZFront ;
206  }
207 
208  fOrigin.SetXYZ(fXFront, fYFront, fZFront);
209 
210  // Debug output.
211 
212  fParent = GetParent();
213 
214  if (static_cast<THcShower*>(fParent)->fdbg_init_cal) {
215  cout << "---------------------------------------------------------------\n";
216  cout << "Debug output from THcShowerArray::ReadDatabase for "
217  << GetParent()->GetPrefix() << ":" << endl;
218 
219  cout << " Layer #" << fLayerNum << ", number of elements " << dec << fNelem
220  << endl;
221  cout << " Columns " << fNColumns << ", Rows " << fNRows << endl;
222 
223  cout << "Front X, Y Z: " << fXFront << ", " << fYFront << ", " << fZFront
224  << " cm" << endl;
225 
226  cout << " Block to block X and Y distances: " << fXStep << ", " << fYStep
227  << " cm" << endl;
228 
229  cout << " Block size along Z: " << fZSize << " cm" << endl;
230 
231  cout << "Block X coordinates:" << endl;
232  for (UInt_t i=0; i<fNRows; i++) {
233  for (UInt_t j=0; j<fNColumns; j++) {
234  cout << fXPos[i][j] << " ";
235  }
236  cout << endl;
237  }
238  cout << endl;
239 
240  cout << "Block Y coordinates:" << endl;
241  for (UInt_t i=0; i<fNRows; i++) {
242  for (UInt_t j=0; j<fNColumns; j++) {
243  cout << fYPos[i][j] << " ";
244  }
245  cout << endl;
246  }
247  cout << endl;
248 
249  cout << "Block Z coordinates:" << endl;
250  for (UInt_t i=0; i<fNRows; i++) {
251  for (UInt_t j=0; j<fNColumns; j++) {
252  cout << fZPos[i][j] << " ";
253  }
254  cout << endl;
255  }
256  cout << endl;
257 
258  cout << " Origin of Array:" << endl;
259  cout << " Xorig = " << GetOrigin().X() << endl;
260  cout << " Yorig = " << GetOrigin().Y() << endl;
261  cout << " Zorig = " << GetOrigin().Z() << endl;
262  cout << endl;
263 
264  cout << " Using FADC " << fUsingFADC << endl;
265  if (fUsingFADC) {
266  cout << " FADC pedestal sample low = " << fPedSampLow << ", high = "
267  << fPedSampHigh << endl;
268  cout << " FADC data sample low = " << fDataSampLow << ", high = "
269  << fDataSampHigh << endl;
270  }
271 
272  }
273 
274  // Here read the 2-D arrays of pedestals, gains, etc.
275 
276  // Pedestal limits per channel.
277  fPedLimit = new Int_t [fNelem];
278 
279  Double_t cal_arr_cal_const[fNelem];
280  Double_t cal_arr_gain_cor[fNelem];
281 
282  fAdcTimeWindowMin = new Double_t [fNelem];
283  fAdcTimeWindowMax = new Double_t [fNelem];
284  fPedDefault = new Int_t [fNelem];
285 
286  DBRequest list1[]={
287  {"cal_arr_ped_limit", fPedLimit, kInt, static_cast<UInt_t>(fNelem),1},
288  {"cal_arr_cal_const", cal_arr_cal_const, kDouble, static_cast<UInt_t>(fNelem)},
289  {"cal_arr_gain_cor", cal_arr_gain_cor, kDouble, static_cast<UInt_t>(fNelem)},
290  {"cal_arr_AdcTimeWindowMin", fAdcTimeWindowMin, kDouble, static_cast<UInt_t>(fNelem),1},
291  {"cal_arr_AdcTimeWindowMax", fAdcTimeWindowMax, kDouble, static_cast<UInt_t>(fNelem),1},
292  {"cal_arr_PedDefault", fPedDefault, kInt, static_cast<UInt_t>(fNelem),1},
293  {0}
294  };
295 
296  for(Int_t ip=0;ip<fNelem;ip++) {
297  fAdcTimeWindowMin[ip] = -1000.;
298  fAdcTimeWindowMax[ip] = 1000.;
299  fPedDefault[ip] = 0;
300  }
301 
302  gHcParms->LoadParmValues((DBRequest*)&list1, prefix);
303 
304  // Debug output.
305  if (static_cast<THcShower*>(fParent)->fdbg_init_cal) {
306 
307  cout << " fPedLimit:" << endl;
308  Int_t el=0;
309  for (UInt_t j=0; j<fNColumns; j++) {
310  cout << " ";
311  for (UInt_t i=0; i<fNRows; i++) {
312  cout << fPedLimit[el++] << " ";
313  };
314  cout << endl;
315  };
316 
317  cout << " cal_arr_cal_const:" << endl;
318  el=0;
319  for (UInt_t j=0; j<fNColumns; j++) {
320  cout << " ";
321  for (UInt_t i=0; i<fNRows; i++) {
322  cout << cal_arr_cal_const[el++] << " ";
323  };
324  cout << endl;
325  };
326 
327  cout << " cal_arr_gain_cor:" << endl;
328  el=0;
329  for (UInt_t j=0; j<fNColumns; j++) {
330  cout << " ";
331  for (UInt_t i=0; i<fNRows; i++) {
332  cout << cal_arr_gain_cor[el++] << " ";
333  };
334  cout << endl;
335  };
336 
337  } // end of debug output
338 
339  // Calibration constants (GeV / ADC channel).
340  fGain = new Double_t [fNelem];
341  for (Int_t i=0; i<fNelem; i++) {
342  fGain[i] = cal_arr_cal_const[i] * cal_arr_gain_cor[i];
343  }
344 
345  // Debug output.
346  if (static_cast<THcShower*>(fParent)->fdbg_init_cal) {
347 
348  cout << " fGain:" << endl;
349  Int_t el=0;
350  for (UInt_t j=0; j<fNColumns; j++) {
351  cout << " ";
352  for (UInt_t i=0; i<fNRows; i++) {
353  cout << fGain[el++] << " ";
354  };
355  cout << endl;
356  };
357 
358  }
359 
360  fMinPeds = static_cast<THcShower*>(fParent)->GetMinPeds();
361 
363 
364  // Event by event amplitude and pedestal
365  //fA = new Double_t[fNelem];
366  //fP = new Double_t[fNelem];
367  //fA_p = new Double_t[fNelem];
368 
369  fE = vector<Double_t> (fNelem, 0.0);
370  fNumGoodAdcHits = vector<Int_t> (fNelem, 0.0);
371  fGoodAdcPulseIntRaw = vector<Double_t> (fNelem, 0.0);
372  fGoodAdcPed = vector<Double_t> (fNelem, 0.0);
373  fGoodAdcMult = vector<Double_t> (fNelem, 0.0);
374  fGoodAdcPulseInt = vector<Double_t> (fNelem, 0.0);
375  fGoodAdcPulseAmp = vector<Double_t> (fNelem, 0.0);
376  fGoodAdcPulseTime = vector<Double_t> (fNelem, 0.0);
377  fGoodAdcTdcDiffTime = vector<Double_t> (fNelem, 0.0);
378 
379 
380  fBlock_ClusterID = new Int_t[fNelem];
381 
382  // Energy depositions per block.
383 
384  //fE = new Double_t[fNelem];
385 
386  // Numbers of tracks and hits , for efficiency calculations.
387 
388  fStatNumTrk = vector<Int_t> (fNelem, 0);
389  fStatNumHit = vector<Int_t> (fNelem, 0);
390  fTotStatNumTrk = 0;
391  fTotStatNumHit = 0;
392 
393 #ifdef HITPIC
394  hitpic = new char*[fNRows];
395  for(Int_t row=0;row<fNRows;row++) {
396  hitpic[row] = new char[NPERLINE*(fNColumns+1)+2];
397  }
398  piccolumn=0;
399 #endif
400 
401  // Debug output.
402 
403  if (static_cast<THcShower*>(fParent)->fdbg_init_cal) {
404 
405  cout << " fMinPeds = " << fMinPeds << endl;
406 
407  cout << "---------------------------------------------------------------\n";
408  }
409 
410  return kOK;
411 }
412 
413 //_____________________________________________________________________________
415 {
416  // Initialize global variables
417 
418  if( mode == kDefine && fIsSetup ) return kOK;
419  fIsSetup = ( mode == kDefine );
420 
421  // Register counters for efficiency calculations in gHcParms so that the
422  // variables can be used in end of run reports.
423 
424  gHcParms->Define(Form("%sstat_trksum_array", fParent->GetPrefix()),
425  "Number of tracks in calo. array", fTotStatNumTrk);
426  gHcParms->Define(Form("%sstat_hitsum_array", fParent->GetPrefix()),
427  "Number of hits in calo. array", fTotStatNumHit);
428 
429  // Register variables in global list
430  if (fDebugAdc) {
431  RVarDef vars[] = {
432  {"adcPedRaw", "List of raw ADC pedestals", "frAdcPedRaw.THcSignalHit.GetData()"},
433  {"adcPulseIntRaw", "List of raw ADC pulse integrals.", "frAdcPulseIntRaw.THcSignalHit.GetData()"},
434  {"adcPulseAmpRaw", "List of raw ADC pulse amplitudes.", "frAdcPulseAmpRaw.THcSignalHit.GetData()"},
435  {"adcPulseTimeRaw", "List of raw ADC pulse times.", "frAdcPulseTimeRaw.THcSignalHit.GetData()"},
436 
437  {"adcPed", "List of ADC pedestals", "frAdcPed.THcSignalHit.GetData()"},
438  {"adcPulseInt", "List of ADC pulse integrals.", "frAdcPulseInt.THcSignalHit.GetData()"},
439  {"adcPulseAmp", "List of ADC pulse amplitudes.", "frAdcPulseAmp.THcSignalHit.GetData()"},
440  {"adcPulseTime", "List of ADC pulse times.", "frAdcPulseTime.THcSignalHit.GetData()"},
441  { 0 }
442  };
443  DefineVarsFromList( vars, mode);
444  } //end debug statement
445 
446  RVarDef vars[] = {
447  //{"adchits", "List of ADC hits", "fADCHits.THcSignalHit.GetPaddleNumber()"}, // appears an empty histogram in the root file
448 
449  {"adcErrorFlag", "Error Flag When FPGA Fails", "frAdcErrorFlag.THcSignalHit.GetData()"},
450 
451  {"adcCounter", "List of ADC counter numbers.", "frAdcPulseIntRaw.THcSignalHit.GetPaddleNumber()"}, //raw occupancy
452  {"numGoodAdcHits", "Number of Good ADC Hits per PMT", "fNumGoodAdcHits" }, //good occupancy
453 
454  {"totNumAdcHits", "Total Number of ADC Hits", "fTotNumAdcHits" }, // raw multiplicity
455  {"totNumGoodAdcHits", "Total Number of Good ADC Hits", "fTotNumGoodAdcHits" }, // good multiplicity
456 
457 
458  {"goodAdcPulseIntRaw", "Good Raw ADC Pulse Integrals", "fGoodAdcPulseIntRaw"}, //this is defined as pulseIntRaw, NOT ADC Amplitude in FillADC_DynamicPedestal() method
459  {"goodAdcPed", "Good ADC Pedestals", "fGoodAdcPed"},
460  {"goodAdcMult", "Good ADC Multiplicity", "fGoodAdcMult"},
461  {"goodAdcPulseInt", "Good ADC Pulse Integrals", "fGoodAdcPulseInt"}, //this is defined as pulseInt, which is the pedestal subtracted pulse integrals, and is defined if threshold is passed
462  {"goodAdcPulseAmp", "Good ADC Pulse Amplitudes", "fGoodAdcPulseAmp"},
463  {"goodAdcPulseTime", "Good ADC Pulse Times", "fGoodAdcPulseTime"}, //this is defined as pulseInt, which is the pedestal subtracted pulse integrals, and is defined if threshold is passed
464  {"goodAdcTdcDiffTime", "Good Hodo Starttime - ADC Pulse Times", "fGoodAdcTdcDiffTime"},
465 
466 
467  {"e", "Energy Depositions per block", "fE"}, //defined as fE = fA_p*fGain = pulseInt * Gain
468  {"earray", "Energy Deposition in Shower Array", "fEarray"}, //defined as a Double_t and represents a sum of the total deposited energy in the shower counter
469 
470  {"nclust", "Number of clusters", "fNclust" }, //what is the difference between nclust defined here and that in THcShower.cxx ?
471  {"block_clusterID", "Cluster ID number", "fBlock_ClusterID"}, // im NOT very clear about this. it is histogrammed at wither -1 or 0.
472  {"ntracks", "Number of shower tracks", "fNtracks" }, //number of cluster-to-track associations
473  { 0 }
474  };
475 
476  return DefineVarsFromList(vars, mode );
477 }
478 
479 //_____________________________________________________________________________
481 {
482  // Clears the hit lists
483  fADCHits->Clear();
484 
485  fTotNumAdcHits = 0;
486  fTotNumGoodAdcHits = 0;
487  fNclust = 0;
488  fClustSize = 0;
489  fNtracks = 0;
490  fMatchClX = -1000.;
491  fMatchClY = -1000.;
492  fMatchClMaxEnergyBlock = -1000.;
493 
494  for (THcShowerClusterListIt i=fClusterList->begin(); i!=fClusterList->end();
495  ++i) {
496  Podd::DeleteContainer(**i);
497  delete *i;
498  }
499  fClusterList->clear();
500 
501  frAdcPedRaw->Clear();
506 
507  frAdcPed->Clear();
508  frAdcPulseInt->Clear();
509  frAdcPulseAmp->Clear();
511 
512  for (UInt_t ielem = 0; ielem < fGoodAdcPed.size(); ielem++) {
513  fGoodAdcPulseIntRaw.at(ielem) = 0.0;
514  fGoodAdcPed.at(ielem) = 0.0;
515  fGoodAdcMult.at(ielem) = 0.0;
516  fGoodAdcPulseInt.at(ielem) = 0.0;
517  fGoodAdcPulseAmp.at(ielem) = 0.0;
518  fGoodAdcPulseTime.at(ielem) = kBig;
519  fGoodAdcTdcDiffTime.at(ielem) = kBig;
520  fNumGoodAdcHits.at(ielem) = 0.0;
521  fE.at(ielem) = 0.0;
522  }
523 
524 }
525 
526 //_____________________________________________________________________________
528 {
529  // Doesn't actually get called. Use Fill method instead
530 
531  return 0;
532 }
533 
534 //_____________________________________________________________________________
536 {
537 
538  // Fill set of unclustered shower array hits.
539  // Reuse hit class pertained to the HMS/SOS type calorimeters.
540  // Save energy deposition in the module as hit mean energy, do not use
541  // positive and negative side energies.
542 
543  THcShowerHitSet HitSet; //set of hits
544 
545  UInt_t k=0;
546  for(UInt_t j=0; j < fNColumns; j++) {
547  for (UInt_t i=0; i<fNRows; i++) {
548 
549  if (fGoodAdcPulseInt.at(k) > 0) { //hit
550 
551  THcShowerHit* hit =
552  new THcShowerHit(i, j, fXPos[i][j], fYPos[i][j], fZPos[i][j], fE[k], 0., 0.);
553 
554  HitSet.insert(hit);
555  }
556 
557  k++;
558  }
559  }
560  //Debug output, print out hits before clustering.
561 
562  if (static_cast<THcShower*>(fParent)->fdbg_clusters_cal) {
563  cout << "---------------------------------------------------------------\n";
564  cout << "Debug output from THcShowerArray::CoarseProcess for " << GetName()
565  << endl;
566 
567  cout << " List of unclustered hits. Total hits: " << fTotNumAdcHits << endl;
568  THcShowerHitIt it = HitSet.begin(); //<set> version
569  for (Int_t i=0; i!=fTotNumGoodAdcHits; i++) {
570  cout << " hit " << i << ": ";
571  (*(it++))->show();
572  }
573  }
574 
576 
577  // if ((int)HitSet.size() != fTotNumGoodAdcHits) {
578  // cout << "***" << endl;
579  // cout << "*** THcShowerArray::CoarseProcess: HitSet.size = " << HitSet.size()
580  // << " != fTotNumGoodAdcHits = " << fTotNumGoodAdcHits << endl;
581  // cout << "***" << endl;
582  // }
583 
584  // Cluster hits and fill list of clusters.
585 
586  static_cast<THcShower*>(fParent)->ClusterHits(HitSet, fClusterList);
587  assert( HitSet.empty() ); // else bug in ClusterHits()
588 
589  fNclust = (*fClusterList).size(); //number of clusters
590 
591  // Set cluster ID for each block
592  Int_t ncl=0;
593  Int_t block;
594  for (THcShowerClusterListIt ppcl = (*fClusterList).begin();
595  ppcl != (*fClusterList).end(); ++ppcl) {
596  for (THcShowerClusterIt pph=(**ppcl).begin(); pph!=(**ppcl).end();
597  ++pph) {
598  block = ((**pph).hitColumn())*fNRows + (**pph).hitRow()+1;
599  fBlock_ClusterID[block-1] = ncl;
600  }
601  ncl++;
602  }
603 
604  //Debug output, print out clustered hits.
605 
606  if (static_cast<THcShower*>(fParent)->fdbg_clusters_cal) {
607 
608  cout << " Clustered hits. Number of clusters: " << fNclust << endl;
609 
610  UInt_t i = 0;
611  for (THcShowerClusterListIt ppcl = (*fClusterList).begin();
612  ppcl != (*fClusterList).end(); ++ppcl) {
613 
614  cout << " Cluster #" << i++
615  <<": E=" << clE(*ppcl)
616  << " Epr=" << clEpr(*ppcl)
617  << " X=" << clX(*ppcl)
618  << " Y=" << clY(*ppcl)
619  << " Z=" << clZ(*ppcl)
620  << " size=" << (**ppcl).size()
621  << endl;
622 
623  Int_t j=0;
624  for (THcShowerClusterIt pph=(**ppcl).begin(); pph!=(**ppcl).end();
625  ++pph) {
626  cout << " hit " << j++ << ": ";
627  (**pph).show();
628  }
629 
630  }
631 
632  cout << "---------------------------------------------------------------\n";
633  }
634 
635  return 0;
636 }
637 
638 //-----------------------------------------------------------------------------
639 
641  Double_t& XTrFront, Double_t& YTrFront)
642 {
643  // Match an Array cluster to a given track. Return the cluster number,
644  // and track coordinates at the front of Array.
645 
646  XTrFront = kBig;
647  YTrFront = kBig;
648  Double_t pathl = kBig;
649 
650  // Track interception with face of Array. The coordinates are
651  // in the Array's local system.
652 
653  fOrigin = GetOrigin();
654 
655  static_cast<THcShower*>(fParent)->CalcTrackIntercept(Track, pathl, XTrFront, YTrFront);
656 
657  // Transform coordiantes to the spectrometer's coordinate system.
658 
659  XTrFront += GetOrigin().X();
660  YTrFront += GetOrigin().Y();
661 
662  Bool_t inFidVol = true; // In Fiducial Volume flag
663 
664  // Re-evaluate Fid. Volume Flag if fid. volume test is requested
665 
666  if (static_cast<THcShower*>(fParent)->fvTest) {
667 
668  TVector3 Origin = fOrigin; //save fOrigin
669 
670  // Track coordinates at the back of the detector.
671 
672  // Origin at the back of counter.
673  fOrigin.SetXYZ(GetOrigin().X(), GetOrigin().Y(), GetOrigin().Z() + fZSize);
674 
675  Double_t XTrBack = kBig;
676  Double_t YTrBack = kBig;
677 
678  static_cast<THcShower*>(fParent)->CalcTrackIntercept(Track, pathl, XTrBack, YTrBack);
679 
680  XTrBack += GetOrigin().X(); // from local coord. system
681  YTrBack += GetOrigin().Y(); // to the spectrometer system
682 
683  inFidVol = (XTrFront <= static_cast<THcShower*>(fParent)->fvXmax) && (XTrFront >= static_cast<THcShower*>(fParent)->fvXmin) &&
684  (YTrFront <= static_cast<THcShower*>(fParent)->fvYmax) && (YTrFront >= static_cast<THcShower*>(fParent)->fvYmin) &&
685  (XTrBack <= static_cast<THcShower*>(fParent)->fvXmax) && (XTrBack >= static_cast<THcShower*>(fParent)->fvXmin) &&
686  (YTrBack <= static_cast<THcShower*>(fParent)->fvYmax) && (YTrBack >= static_cast<THcShower*>(fParent)->fvYmin);
687 
688  fOrigin = Origin; //restore fOrigin
689  }
690 
691  // Match a cluster to the track. Choose closest to the track cluster.
692 
693  Int_t mclust = -1; // The match cluster #, initialize with a bogus value.
694  Double_t Delta = kBig; // Track to cluster distance
695 
696  if (inFidVol) {
697 
698  // Since hits and clusters are in reverse order (with respect to Engine),
699  // search backwards to be consistent with Engine.
700 
701  for (Int_t i=fNclust-1; i>-1; i--) {
702 
703  THcShowerCluster* cluster = *(fClusterList->begin()+i);
704  fClustSize = (*cluster).size();
705  Double_t dx = TMath::Abs( clX(cluster) - XTrFront );
706  Double_t dy = TMath::Abs( clY(cluster) - YTrFront );
707  Double_t distance = TMath::Sqrt(dx*dx+dy*dy); //cluster-track dist.
708  if (static_cast<THcShower*>(fParent)->fdbg_tracks_cal) {
709  cout << " match clust = " << i << " clX = " << clX(cluster)<< " clY = " << clY(cluster) << " distacne = " << distance << " test = " << (0.5*(fXStep + fYStep) + static_cast<THcShower*>(fParent)->fSlop) << endl;
710  }
711 
712  //Choice of threshold on distance is not unuque. Use the simplest for now.
713 
714  if (distance <= (0.5*(fXStep + fYStep) + static_cast<THcShower*>(fParent)->fSlop)) {
715  fNtracks++;
716  if (distance < Delta) {
717  mclust = i;
718  fMatchClX= clX(cluster);
719  fMatchClY= clY(cluster);
721  Delta = distance;
722  }
723  }
724  }
725  }
726 
727  //Debug output.
728 
729  if (static_cast<THcShower*>(fParent)->fdbg_tracks_cal) {
730  cout << "---------------------------------------------------------------\n";
731  cout << "Debug output from THcShowerArray::MatchCluster for " << GetName()
732  << endl;
733 
734  cout << " Track at DC:"
735  << " X = " << Track->GetX()
736  << " Y = " << Track->GetY()
737  << " Theta = " << Track->GetTheta()
738  << " Phi = " << Track->GetPhi()
739  << endl;
740  cout << " Track at the front of Array:"
741  << " X = " << XTrFront
742  << " Y = " << YTrFront
743  << " Pathl = " << pathl
744  << endl;
745  if (static_cast<THcShower*>(fParent)->fvTest)
746  cout << " Fiducial volume test: inFidVol = " << inFidVol << endl;
747 
748  cout << " Matched cluster #" << mclust << ", Delta = " << Delta << endl;
749  cout << "---------------------------------------------------------------\n";
750  }
751 
752  return mclust;
753 }
754 
755 //_____________________________________________________________________________
757 
758  // Get total energy deposited in the Array cluster matched to the given
759  // spectrometer Track.
760 
761  // Track coordinates at the front of Array, initialize out of acceptance.
762  Double_t Xtr = -100.;
763  Double_t Ytr = -100.;
764 
765  // Associate a cluster to the track.
766 
767  Int_t mclust = MatchCluster(Track, Xtr, Ytr);
768 
769  // Coordinate corrected total energy deposition in the cluster.
770 
771  Float_t Etrk = 0.;
772  if (mclust >= 0) { // if there is a matched cluster
773 
774  // Get matched cluster.
775  THcShowerCluster* cluster = *(fClusterList->begin()+mclust);
776 
777  // No coordinate correction for now.
778  Etrk = clE(cluster);
779 
780  } //mclust>=0
781 
782  //Debug output.
783 
784  if (static_cast<THcShower*>(fParent)->fdbg_tracks_cal) {
785  cout << "---------------------------------------------------------------\n";
786  cout << "Debug output from THcShowerArray::GetShEnergy for "
787  << GetName() << endl;
788 
789  cout << " Track at Array: X = " << Xtr << " Y = " << Ytr;
790  if (mclust >= 0)
791  cout << ", matched cluster #" << mclust << "." << endl;
792  else
793  cout << ", no matched cluster found." << endl;
794 
795  cout << " Track's Array energy = " << Etrk << "." << endl;
796  cout << "---------------------------------------------------------------\n";
797  }
798 
799  return Etrk;
800 }
801 
802 //_____________________________________________________________________________
804 {
805  return 0;
806 }
807 
808 //_____________________________________________________________________________
810 {
811  Int_t ADCMode=static_cast<THcShower*>(fParent)->GetADCMode();
812  if(ADCMode == kADCDynamicPedestal) {
814  } else if (ADCMode == kADCSampleIntegral) {
816  } else if (ADCMode == kADCSampIntDynPed) {
818  } else {
820  }
821  //
822  if (static_cast<THcShower*>(fParent)->fdbg_decoded_cal) {
823 
824  cout << "---------------------------------------------------------------\n";
825  cout << "Debug output from THcShowerArray::ProcessHits for "
826  << static_cast<THcShower*>(fParent)->GetPrefix() << ":" << endl;
827 
828  cout << " Sparsified hits for shower array, plane #" << fLayerNum
829  << ", " << GetName() << ":" << endl;
830 
831  Int_t nspar = 0;
832  Int_t k=0;
833  for(UInt_t j=0; j < fNColumns; j++) {
834  for (UInt_t i=0; i<fNRows; i++) {
835  if(fGoodAdcPulseIntRaw.at(k) > fThresh[k]) {
836  cout << " counter = " << k
837  << " E = " << fE[k]
838  << endl;
839  nspar++;
840  }
841  k++;
842  }
843  }
844 
845  if (nspar == 0) cout << " No hits\n";
846 
847  cout << " Earray = " << fEarray << endl;
848  cout << "---------------------------------------------------------------\n";
849  }
850  //
851  return 1;
852 }
853 //_____________________________________________________________________________
855 {
856  // adc_pos = hit->GetRawAdcHitPos().GetSampleInt();
857  // adc_neg = hit->GetRawAdcHitNeg().GetSampleInt();
858  // adc_pos_pedsub = hit->GetRawAdcHitPos().GetSampleIntRaw();
859  // adc_neg_pedsub = hit->GetRawAdcHitNeg().GetSampleIntRaw();
860  // Need to create
861 }
862 //_____________________________________________________________________________
864 {
866  // adc_neg_pedsub = hit->GetRawAdcHitNeg().GetSampleIntRaw() - fNegPed[hit->fCounter -1];
867  // adc_pos = hit->GetRawAdcHitPos().GetSampleIntRaw();
868  // adc_neg = hit->GetRawAdcHitNeg().GetSampleIntRaw();
869  // need to create
870 }
871 //_____________________________________________________________________________
873 {
874 }
875 //_____________________________________________________________________________
877 {
878  Double_t StartTime = 0.0;
879  if( fglHod ) StartTime = fglHod->GetStartTime();
880  Double_t OffsetTime = 0.0;
881  if( fglHod ) OffsetTime = fglHod->GetOffsetTime();
882  for (Int_t ielem=0;ielem<frAdcPulseInt->GetEntries();ielem++) {
883 
884  Int_t npad = ((THcSignalHit*) frAdcPulseInt->ConstructedAt(ielem))->GetPaddleNumber() - 1;
885  Double_t pulseIntRaw = ((THcSignalHit*) frAdcPulseIntRaw->ConstructedAt(ielem))->GetData();
886  Double_t pulsePed = ((THcSignalHit*) frAdcPed->ConstructedAt(ielem))->GetData();
887  Double_t pulseInt = ((THcSignalHit*) frAdcPulseInt->ConstructedAt(ielem))->GetData();
888  Double_t pulseAmp = ((THcSignalHit*) frAdcPulseAmp->ConstructedAt(ielem))->GetData();
889  Double_t pulseTime = ((THcSignalHit*) frAdcPulseTime->ConstructedAt(ielem))->GetData();
890  Double_t adctdcdiffTime = StartTime-pulseTime+OffsetTime;
891  Bool_t pulseTimeCut = (adctdcdiffTime > fAdcTimeWindowMin[npad]) && (adctdcdiffTime < fAdcTimeWindowMax[npad]);
892  fGoodAdcMult.at(npad) += 1;
893  if (pulseTimeCut) {
894 
895  fTotNumAdcHits++;
896  fGoodAdcPulseIntRaw.at(npad) = pulseIntRaw;
897 
898  if(fGoodAdcPulseIntRaw.at(npad) > fThresh[npad] && fGoodAdcPulseInt.at(npad)==0) {
900  fGoodAdcPulseInt.at(npad) = pulseInt;
901  fE.at(npad) = fGoodAdcPulseInt.at(npad)*fGain[npad];
902  fEarray += fE.at(npad);
903 
904  fGoodAdcPed.at(npad) = pulsePed;
905  fGoodAdcPulseAmp.at(npad) = pulseAmp;
906  fGoodAdcPulseTime.at(npad) = pulseTime;
907  fGoodAdcTdcDiffTime.at(npad) = adctdcdiffTime;
908 
909  fNumGoodAdcHits.at(npad) = npad + 1;
910  }
911  }
912  }
913  //
914 }
915 //_____________________________________________________________________________
917 {
918  // Extract the data for this layer from hit list.
919 
920  //THcShower* fParent;
921  //fParent = (THcShower*) GetParent();
922 
923  // Initialize variables.
924 
925  fADCHits->Clear();
926 
927  frAdcPedRaw->Clear();
932 
933  frAdcPed->Clear();
934  frAdcPulseInt->Clear();
935  frAdcPulseAmp->Clear();
937 
938  for(Int_t i=0;i<fNelem;i++) {
939  //fA[i] = 0;
940  //fA_p[i] = 0;
941  //fE[i] = 0;
942 
943  fBlock_ClusterID[i] = -1;
944  }
945 
946  fEarray = 0;
947 
948  // Process raw hits. Get ADC hits for the plane, assign variables for each
949  // channel.
950 
951  Int_t nrawhits = rawhits->GetLast()+1;
952 
953  Int_t ihit = nexthit;
954 
955  UInt_t nrAdcHits = 0;
956 
957  while(ihit < nrawhits) {
958  THcRawShowerHit* hit = (THcRawShowerHit *) rawhits->At(ihit);
959 
960  if(hit->fPlane != fLayerNum) {
961  break;
962  }
963 
964  Int_t padnum = hit->fCounter;
965  THcRawAdcHit& rawAdcHit = hit->GetRawAdcHitPos();
966  //
967  for (UInt_t thit=0; thit<rawAdcHit.GetNPulses(); ++thit) {
968  ((THcSignalHit*) frAdcPedRaw->ConstructedAt(nrAdcHits))->Set(padnum, rawAdcHit.GetPedRaw());
969  fThresh[padnum-1]=rawAdcHit.GetPedRaw()*rawAdcHit.GetF250_PeakPedestalRatio()+fAdcThreshold;
970  ((THcSignalHit*) frAdcPed->ConstructedAt(nrAdcHits))->Set(padnum, rawAdcHit.GetPed());
971 
972  ((THcSignalHit*) frAdcPulseIntRaw->ConstructedAt(nrAdcHits))->Set(padnum, rawAdcHit.GetPulseIntRaw(thit));
973  ((THcSignalHit*) frAdcPulseInt->ConstructedAt(nrAdcHits))->Set(padnum, rawAdcHit.GetPulseInt(thit));
974 
975  ((THcSignalHit*) frAdcPulseAmpRaw->ConstructedAt(nrAdcHits))->Set(padnum, rawAdcHit.GetPulseAmpRaw(thit));
976  ((THcSignalHit*) frAdcPulseAmp->ConstructedAt(nrAdcHits))->Set(padnum, rawAdcHit.GetPulseAmp(thit));
977 
978  ((THcSignalHit*) frAdcPulseTimeRaw->ConstructedAt(nrAdcHits))->Set(padnum, rawAdcHit.GetPulseTimeRaw(thit));
979  ((THcSignalHit*) frAdcPulseTime->ConstructedAt(nrAdcHits))->Set(padnum, rawAdcHit.GetPulseTime(thit)+fAdcTdcOffset);
980 
981  if (rawAdcHit.GetPulseAmp(thit)>0&&rawAdcHit.GetPulseIntRaw(thit)>0) {
982  ((THcSignalHit*) frAdcErrorFlag->ConstructedAt(nrAdcHits))->Set(padnum,0);
983  } else {
984  ((THcSignalHit*) frAdcErrorFlag->ConstructedAt(nrAdcHits))->Set(padnum,1);
985  }
986 
987  if (rawAdcHit.GetPulseAmpRaw(thit) <= 0) {
988  Double_t PeakPedRatio= rawAdcHit.GetF250_PeakPedestalRatio();
989  Int_t NPedSamples= rawAdcHit.GetF250_NPedestalSamples();
990  Double_t AdcToC = rawAdcHit.GetAdcTopC();
991  Double_t AdcToV = rawAdcHit.GetAdcTomV();
992  if (fPedDefault[padnum-1] !=0) {
993  Double_t tPulseInt = AdcToC*(rawAdcHit.GetPulseIntRaw(thit) - fPedDefault[padnum-1]*PeakPedRatio);
994  ((THcSignalHit*) frAdcPulseInt->ConstructedAt(nrAdcHits))->Set(padnum, tPulseInt);
995  ((THcSignalHit*) frAdcPedRaw->ConstructedAt(nrAdcHits))->Set(padnum, fPedDefault[padnum-1]);
996  ((THcSignalHit*) frAdcPed->ConstructedAt(nrAdcHits))->Set(padnum, float(fPedDefault[padnum-1])/float(NPedSamples)*AdcToV);
997 
998  }
999  ((THcSignalHit*) frAdcPulseAmp->ConstructedAt(nrAdcHits))->Set(padnum, 0.);
1000 
1001  }
1002 
1003 
1004  ++nrAdcHits;
1005  }
1006  ihit++;
1007  }
1008 
1009 #if 0
1010  if(fTotNumGoodAdcHits > 0) {
1011  cout << "+";
1012  for(Int_t column=0;column<fNColumns;column++) {
1013  cout << "-";
1014  }
1015  cout << "+" << endl;
1016  for(Int_t row=0;row<fNRows;row++) {
1017  cout << "|";
1018  for(Int_t column=0;column<fNColumns;column++) {
1019  Int_t counter = column*fNRows + row;
1020  if(fGoodAdcPulseIntRaw.at(counter) > threshold) {
1021  cout << "X";
1022  } else {
1023  cout << " ";
1024  }
1025  }
1026  cout << "|" << endl;
1027  }
1028  }
1029 #endif
1030 #ifdef HITPIC
1031  if(fTotNumGoodAdcHits > 0) {
1032  for(Int_t row=0;row<fNRows;row++) {
1033  if(piccolumn==0) {
1034  hitpic[row][0] = '|';
1035  }
1036  for(Int_t column=0;column<fNColumns;column++) {
1037  Int_t counter = column*fNRows+row;
1038  if(fGoodAdcPulseIntRaw.at(counter) > threshold) {
1039  hitpic[row][piccolumn*(fNColumns+1)+column+1] = 'X';
1040  } else {
1041  hitpic[row][piccolumn*(fNColumns+1)+column+1] = ' ';
1042  }
1043  hitpic[row][(piccolumn+1)*(fNColumns+1)] = '|';
1044  }
1045  }
1046  piccolumn++;
1047  if(piccolumn==NPERLINE) {
1048  cout << "+";
1049  for(Int_t pc=0;pc<NPERLINE;pc++) {
1050  for(Int_t column=0;column<fNColumns;column++) {
1051  cout << "-";
1052  }
1053  cout << "+";
1054  }
1055  cout << endl;
1056  for(Int_t row=0;row<fNRows;row++) {
1057  hitpic[row][(piccolumn+1)*(fNColumns+1)+1] = '\0';
1058  cout << hitpic[row] << endl;
1059  }
1060  piccolumn = 0;
1061  }
1062  }
1063 #endif
1064 
1065  //Debug output.
1066 
1067 
1068  return(ihit);
1069 }
1070 //_____________________________________________________________________________
1072 {
1073  // Extract data for this plane from hit list and accumulate in
1074  // arrays for subsequent pedestal calculations.
1075 
1076  Int_t nrawhits = rawhits->GetLast()+1;
1077 
1078  Int_t ihit = nexthit;
1079 
1080  while(ihit < nrawhits) {
1081 
1082  THcRawShowerHit* hit = (THcRawShowerHit *) rawhits->At(ihit);
1083 
1084  if(hit->fPlane != fLayerNum) {
1085  break;
1086  }
1087 
1088  Int_t element = hit->fCounter - 1; // Should check if in range
1089 
1090  // Should check that counter # is in range
1091  Int_t adc = 0;
1092  if (fUsingFADC) {
1093  adc = hit->GetRawAdcHitPos().GetData(
1095  );
1096  }
1097  else {
1098  adc = hit->GetData(0);
1099  }
1100 
1101  if(adc <= fPedLimit[element]) {
1102  fPedSum[element] += adc;
1103  fPedSum2[element] += adc*adc;
1104  fPedCount[element]++;
1105  if(fPedCount[element] == fMinPeds/5) {
1106  fPedLimit[element] = 100 + fPedSum[element]/fPedCount[element];
1107  }
1108  }
1109  ihit++;
1110  }
1111  fNPedestalEvents++;
1112 
1113  // Debug output.
1114 
1115  if ( static_cast<THcShower*>(fParent)->fdbg_raw_cal ) {
1116 
1117  cout << "---------------------------------------------------------------\n";
1118  cout << "Debug output from THcShowerArray::AcculatePedestals for "
1119  << fParent->GetPrefix() << ":" << endl;
1120 
1121  cout << "Processed hit list for plane " << GetName() << ":\n";
1122 
1123  for (Int_t ih=nexthit; ih<nrawhits; ih++) {
1124 
1125  THcRawShowerHit* hit = (THcRawShowerHit *) rawhits->At(ih);
1126 
1127  if(hit->fPlane != fLayerNum) {
1128  break;
1129  }
1130 
1131  Int_t adc = 0;
1132  if (fUsingFADC) {
1133  adc = hit->GetRawAdcHitPos().GetData(
1135  );
1136  }
1137  else {
1138  adc = hit->GetData(0);
1139  }
1140 
1141  cout << " hit " << ih << ":"
1142  << " plane = " << hit->fPlane
1143  << " counter = " << hit->fCounter
1144  << " ADC = " << adc
1145  << endl;
1146  }
1147 
1148  cout << "---------------------------------------------------------------\n";
1149 
1150  }
1151 
1152  return(ihit);
1153 }
1154 
1155 //_____________________________________________________________________________
1157 {
1158  // Use the accumulated pedestal data to calculate pedestals.
1159 
1160  for(Int_t i=0; i<fNelem;i++) {
1161 
1162  fPed[i] = ((Float_t) fPedSum[i]) / TMath::Max(1, fPedCount[i]);
1163  fSig[i] = sqrt(((Float_t)fPedSum2[i])/TMath::Max(1, fPedCount[i])
1164  - fPed[i]*fPed[i]);
1165  fThresh[i] = fPed[i] + TMath::Min(50., TMath::Max(10., 3.*fSig[i]));
1166 
1167  }
1168 
1169  // Debug output.
1170 
1171  if ( static_cast<THcShower*>(fParent)->fdbg_raw_cal ) {
1172 
1173  cout << "---------------------------------------------------------------\n";
1174  cout << "Debug output from THcShowerArray::CalculatePedestals for "
1175  << fParent->GetPrefix() << ":" << endl;
1176 
1177  cout << " ADC pedestals and thresholds for calorimeter plane "
1178  << GetName() << endl;
1179  for(Int_t i=0; i<fNelem;i++) {
1180  cout << " element " << i << ": "
1181  << " Pedestal = " << fPed[i]
1182  << " threshold = " << fThresh[i]
1183  << endl;
1184  }
1185  cout << "---------------------------------------------------------------\n";
1186 
1187  }
1188 
1189 }
1190 //_____________________________________________________________________________
1192 {
1193  fNPedestalEvents = 0;
1194 
1195  fPedSum = new Int_t [fNelem];
1196  fPedSum2 = new Int_t [fNelem];
1197  fPedCount = new Int_t [fNelem];
1198 
1199  fSig = new Float_t [fNelem];
1200  fPed = new Float_t [fNelem];
1201  fThresh = new Float_t [fNelem];
1202 
1203  for(Int_t i=0;i<fNelem;i++) {
1204  fPedSum[i] = 0;
1205  fPedSum2[i] = 0;
1206  fPedCount[i] = 0;
1207  }
1208 }
1209 
1210 //------------------------------------------------------------------------------
1211 
1212 // Fiducial volume limits.
1213 
1215  return fXPos[0][0] - fXStep/2 + static_cast<THcShower*>(fParent)->fvDelta;
1216 }
1217 
1219  return fYPos[0][0] + fYStep/2 - static_cast<THcShower*>(fParent)->fvDelta;
1220 }
1221 
1223  return fXPos[fNRows-1][fNColumns-1] + fXStep/2 - static_cast<THcShower*>(fParent)->fvDelta;
1224 }
1225 
1227  return fYPos[fNRows-1][fNColumns-1] - fYStep/2 + static_cast<THcShower*>(fParent)->fvDelta;
1228 }
1230  Double_t max_energy=-1.;
1231  Double_t max_block=-1.;
1232  for (THcShowerClusterIt it=(*cluster).begin(); it!=(*cluster).end(); ++it) {
1233  if ( (**it).hitE() > max_energy ) {
1234  max_energy = (**it).hitE();
1235  max_block = ((**it).hitColumn())*fNRows + (**it).hitRow()+1;
1236  }
1237  }
1238  return max_block;
1239 }
1240 
1241 //_____________________________________________________________________________
1243 {
1244  // Accumumate statistics for efficiency calculations.
1245  //
1246  // Choose electron events in gas Cherenkov with good Chisq of the best track.
1247  // Project best track to Array,
1248  // calculate module number for the track,
1249  // accrue number of tracks for the module,
1250  // accrue number of hits for the module, if it is hit.
1251  // Accrue total numbers of tracks and hits for Array.
1252 
1253  THaTrack* BestTrack = static_cast<THaTrack*>( tracks[0]);
1254  if (BestTrack->GetChi2()/BestTrack->GetNDoF() > fStatMaxChi2) return 0;
1255 
1256  THcHallCSpectrometer *app=dynamic_cast<THcHallCSpectrometer*>(GetApparatus());
1257 
1258  THaDetector* detc;
1259  if (fParent->GetPrefix()[0] == 'P')
1260  detc = app->GetDetector("hgcer");
1261  else
1262  detc = app->GetDetector("cer");
1263 
1264  THcCherenkov* hgcer = dynamic_cast<THcCherenkov*>(detc);
1265  if (!hgcer) {
1266  cout << "****** THcShowerArray::AccumulateStat: HGCer not found! ******"
1267  << endl;
1268  return 0;
1269  }
1270 
1271  if (hgcer->GetCerNPE() < fStatCerMin) return 0;
1272 
1273  Double_t XTrk = kBig;
1274  Double_t YTrk = kBig;
1275  Double_t pathl = kBig;
1276 
1277  // Track interception with Array. The coordinates are in the calorimeter's
1278  // local system.
1279 
1280  fOrigin = GetOrigin();
1281  static_cast<THcShower*>(fParent)->CalcTrackIntercept(BestTrack, pathl, XTrk, YTrk);
1282 
1283  // Transform coordiantes to the spectrometer's coordinate system.
1284  XTrk += GetOrigin().X();
1285  YTrk += GetOrigin().Y();
1286 
1287  for (Int_t i=0; i<fNelem; i++) {
1288 
1289  Int_t row = i%fNRows;
1290  Int_t col =i/fNRows;
1291 
1292  if (TMath::Abs(XTrk - fXPos[row][col]) < fStatSlop &&
1293  TMath::Abs(YTrk - fYPos[row][col]) < fStatSlop) {
1294 
1295  fStatNumTrk.at(i)++;
1296  fTotStatNumTrk++;
1297 
1298  if (fGoodAdcPulseInt.at(i) > 0.) {
1299  fStatNumHit.at(i)++;
1300  fTotStatNumHit++;
1301  }
1302 
1303  }
1304 
1305  }
1306 
1307  if (static_cast<THcShower*>(fParent)->fdbg_tracks_cal ) {
1308  cout << "---------------------------------------------------------------\n";
1309  cout << "THcShowerArray::AccumulateStat:" << endl;
1310  cout << " Chi2/NDF = " <<BestTrack->GetChi2()/BestTrack->GetNDoF() <<endl;
1311  cout << " HGCER Npe = " << hgcer->GetCerNPE() << endl;
1312  cout << " XTrk, YTrk = " << XTrk << " " << YTrk << endl;
1313  for (Int_t i=0; i<fNelem; i++) {
1314 
1315  Int_t row = i%fNRows;
1316  Int_t col =i/fNRows;
1317 
1318  if (TMath::Abs(XTrk - fXPos[row][col]) < fStatSlop &&
1319  TMath::Abs(YTrk - fYPos[row][col]) < fStatSlop) {
1320 
1321  cout << " Module " << i << ", X=" << fXPos[i/fNRows][i%fNRows]
1322  << ", Y=" << fYPos[i/fNRows][i%fNRows] << " matches track" << endl;
1323 
1324  if (fGoodAdcPulseInt.at(i) > 0.)
1325  cout << " PulseIntegral = " << fGoodAdcPulseInt.at(i) << endl;
1326  }
1327  }
1328 
1329  cout << "---------------------------------------------------------------\n";
1330  // getchar();
1331  }
1332 
1333  return 1;
1334 }
Double_t GetData(UInt_t iPedLow, UInt_t iPedHigh, UInt_t iIntLow, UInt_t iIntHigh) const
Gets pedestal subtracted integral of samples. In channels.
Double_t GetF250_PeakPedestalRatio()
Definition: THcRawAdcHit.h:24
std::string GetName(const std::string &scope_name)
virtual EStatus Init(const TDatime &run_time)
static const Int_t kADCSampIntDynPed
virtual void FillADC_SampleIntegral()
TClonesArray * frAdcPulseAmp
vector< Int_t > fNumGoodAdcHits
vector< Double_t > fGoodAdcPed
vector< Double_t > fE
TClonesArray * frAdcPulseTime
Fly's eye array of shower blocks.
float Float_t
Int_t GetLast() const
const char Option_t
Class for gas Cherenkov detectors.
Definition: THcCherenkov.h:16
THcShowerClusterList::iterator THcShowerClusterListIt
Definition: THcShowerHit.h:89
Int_t fTotNumGoodAdcHits
TClonesArray * frAdcErrorFlag
Double_t clMaxEnergyBlock(THcShowerCluster *cluster)
TClonesArray * fADCHits
virtual void InitializePedestals()
vector< Int_t > fStatNumHit
vector< Double_t > fGoodAdcMult
vector< THcShowerCluster * > THcShowerClusterList
Definition: THcShowerHit.h:88
Double_t GetOffsetTime() const
Definition: THcHodoscope.h:59
vector< Double_t > fGoodAdcPulseAmp
Int_t GetPulseTimeRaw(UInt_t iPulse=0) const
Gets raw pulse time. In subsamples.
Short_t Min(Short_t a, Short_t b)
int Int_t
bool Bool_t
Double_t ** fYPos
STL namespace.
TClonesArray * frAdcPed
Int_t fCounter
Definition: THcRawHit.h:55
vector< Double_t > fGoodAdcTdcDiffTime
Short_t Abs(Short_t d)
UInt_t threshold[NUMSLOTS][NADCCHAN]
THcShowerCluster::iterator THcShowerClusterIt
Definition: THcShowerHit.h:82
Float_t * fThresh
Double_t fMatchClY
Double_t fStatMaxChi2
virtual void FillADC_DynamicPedestal()
virtual Int_t FineProcess(TClonesArray &tracks)
vector< Double_t > fGoodAdcPulseIntRaw
virtual Int_t GetData(Int_t signal)
Double_t clEpr(THcShowerCluster *cluster)
Definition: THcShower.cxx:986
TObject * ConstructedAt(Int_t idx)
virtual void FillADC_SampIntDynPed()
virtual Int_t CoarseProcessHits()
Double_t fMatchClMaxEnergyBlock
void SetXYZ(Double_t x, Double_t y, Double_t z)
Int_t MatchCluster(THaTrack *, Double_t &, Double_t &)
Float_t GetShEnergy(THaTrack *)
tuple app
TClonesArray * frAdcPedRaw
virtual Int_t DefineVariables(EMode mode=kDefine)
Double_t fAdcThreshold
virtual Int_t ProcessHits(TClonesArray *rawhits, Int_t nexthit)
Double_t GetPed() const
Gets sample pedestal. In channels.
Double_t clZ(THcShowerCluster *cluster)
Definition: THcShower.cxx:972
Double_t ** fXPos
Double_t * fGain
VecExpr< UnaryOp< Sqrt< T >, SVector< T, D >, T >, T, D > sqrt(const SVector< T, D > &rhs)
virtual void Clear(Option_t *option="")
Double_t GetCerNPE()
Double_t clY(THcShowerCluster *cluster)
Definition: THcShower.cxx:953
Double_t ** fZPos
THcRawAdcHit & GetRawAdcHitPos()
Int_t GetPulseAmpRaw(UInt_t iPulse=0) const
Gets raw pulse amplitude. In channels.
virtual void FillADC_Standard()
Double_t GetPulseAmp(UInt_t iPulse=0) const
Gets pedestal subtracted pulse amplitude. In channels.
Double_t GetPulseInt(UInt_t iPulse=0) const
Gets pedestal subtracted pulse integral. In channels.
Int_t * fBlock_ClusterID
unsigned int UInt_t
char * Form(const char *fmt,...)
static const Int_t kADCSampleIntegral
Double_t GetStartTime() const
Definition: THcHodoscope.h:58
void Warning(const char *location, const char *msgfmt,...)
vector< Double_t > fGoodAdcPulseInt
TClonesArray * frAdcPulseTimeRaw
tuple list
Definition: SConscript.py:9
virtual void Clear(Option_t *opt="")
Int_t GetPulseIntRaw(UInt_t iPulse=0) const
Gets raw pulse integral. In channels.
THcShowerHitSet THcShowerCluster
Definition: THcShowerHit.h:81
Int_t AccumulateStat(TClonesArray &tracks)
ClassImp(THcShowerArray) THcShowerArray
virtual void CalculatePedestals()
Int_t LoadParmValues(const DBRequest *list, const char *prefix="")
Retrieve parameter values from the parameter cache.
double Double_t
TClonesArray * frAdcPulseAmpRaw
UInt_t GetNPulses() const
Gets number of set pulses.
vector< Double_t > fGoodAdcPulseTime
Double_t fStatSlop
TClonesArray * frAdcPulseIntRaw
virtual ~THcShowerArray()
Double_t clX(THcShowerCluster *cluster)
Definition: THcShower.cxx:962
Int_t GetEntries() const
Int_t fPlane
Definition: THcRawHit.h:54
Double_t * fAdcTimeWindowMax
vector< Int_t > fStatNumTrk
Class representing a single raw hit for a shower paddle.
Generic segmented shower detector.
Definition: THcShower.h:18
virtual Int_t AccumulatePedestals(TClonesArray *rawhits, Int_t nexthit)
virtual Int_t Decode(const THaEvData &)
THcHodoscope * fglHod
Int_t GetPedRaw() const
Gets raw signal pedestal. In channels.
Short_t Max(Short_t a, Short_t b)
set< THcShowerHit * > THcShowerHitSet
Definition: THcShowerHit.h:78
static const Int_t kADCDynamicPedestal
Double_t GetPulseTime(UInt_t iPulse=0) const
THcShowerClusterList * fClusterList
TClonesArray * frAdcPulseInt
R__EXTERN class THcParmList * gHcParms
Definition: THcGlobals.h:11
Double_t fMatchClX
Double_t Sqrt(Double_t x)
TObject * At(Int_t idx) const
Int_t GetF250_NPedestalSamples()
Definition: THcRawAdcHit.h:25
Double_t fClustSize
void GetData(std::string s, double *x, double *y, double *ey)
static const Double_t kBig
Definition: THcFormula.cxx:31
Double_t clE(THcShowerCluster *cluster)
Definition: THcShower.cxx:980
Double_t GetAdcTopC() const
virtual Int_t ReadDatabase(const TDatime &date)
Class representing a single raw ADC hit.
Definition: THcRawAdcHit.h:7
THaDetectorBase * fParent
Double_t * fAdcTimeWindowMin
virtual Int_t CoarseProcess(TClonesArray &tracks)
Double_t fAdcTdcOffset
Double_t fStatCerMin
Double_t GetAdcTomV() const
THcShowerHitSet::iterator THcShowerHitIt
Definition: THcShowerHit.h:79
A standard Hall C spectrometer apparatus.