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