Newer
Older
/** \class THcShowerArray
\ingroup DetSupport
Fly's eye array of shower blocks
*/
#include "THcShowerArray.h"
#include "TClonesArray.h"
#include "THcSignalHit.h"
#include "THcGlobals.h"
#include "THcParmList.h"
#include "THcHitList.h"
#include "THcShower.h"
#include "THcRawShowerHit.h"
#include "TClass.h"
#include "math.h"
#include "THaTrack.h"
#include "THaTrackProj.h"
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <fstream>
using namespace std;
ClassImp(THcShowerArray)
//______________________________________________________________________________
THcShowerArray::THcShowerArray( const char* name,
const char* description,
const Int_t layernum,
THaDetectorBase* parent )
: THaSubDetector(name,description,parent)
{
fADCHits = new TClonesArray("THcSignalHit",100);
fLayerNum = layernum;
fClusterList = new THcShowerClusterList; // List of hit clusters
//______________________________________________________________________________
THcShowerArray::~THcShowerArray()
{
// Destructor
delete fXPos;
delete fYPos;
delete fADCHits;
delete [] fA;
delete [] fP;
delete [] fA_p;
delete [] fE;
}
//_____________________________________________________________________________
THaAnalysisObject::EStatus THcShowerArray::Init( const TDatime& date )
{
// Extra initialization for shower layer: set up DataDest map
if( IsZombie())
return fStatus = kInitError;
// How to get information for parent
// if( GetParent() )
// fOrigin = GetParent()->GetOrigin();
EStatus status;
if( (status=THaSubDetector::Init( date )) )
return fStatus = status;
return fStatus = kOK;
}
//_____________________________________________________________________________
Int_t THcShowerArray::ReadDatabase( const TDatime& date )
{
char prefix[2];
prefix[0]=tolower(GetParent()->GetPrefix()[0]);
prefix[1]='\0';
cout << "Parent name: " << GetParent()->GetPrefix() << endl;
fNRows=fNColumns=0;
fXFront=fYFront=fZFront=0.;
fXStep=fYStep=fZSize=0.;
fUsingFADC=0;
fPedSampLow=0;
fPedSampHigh=9;
fDataSampLow=23;
fDataSampHigh=49;
{"cal_arr_nrows", &fNRows, kInt},
{"cal_arr_ncolumns", &fNColumns, kInt},
{"cal_arr_front_x", &fXFront, kDouble},
{"cal_arr_front_y", &fYFront, kDouble},
{"cal_arr_front_z", &fZFront, kDouble},
{"cal_arr_xstep", &fXStep, kDouble},
{"cal_arr_ystep", &fYStep, kDouble},
{"cal_arr_zsize", &fZSize, kDouble},
{"cal_using_fadc", &fUsingFADC, kInt, 0, 1},
{"cal_ped_sample_low", &fPedSampLow, kInt, 0, 1},
{"cal_ped_sample_high", &fPedSampHigh, kInt, 0, 1},
{"cal_data_sample_low", &fDataSampLow, kInt, 0, 1},
{"cal_data_sample_high", &fDataSampHigh, kInt, 0, 1},
{0}
};
gHcParms->LoadParmValues((DBRequest*)&list, prefix);
fNelem = fNRows*fNColumns;
fXPos = new Double_t* [fNRows];
fYPos = new Double_t* [fNRows];
for (UInt_t i=0; i<fNRows; i++) {
fXPos[i] = new Double_t [fNColumns];
fYPos[i] = new Double_t [fNColumns];
}
//Looking to the front, the numbering goes from left to right, and from top
//to bottom.
for (UInt_t j=0; j<fNColumns; j++)
for (UInt_t i=0; i<fNRows; i++) {
fXPos[i][j] = fXFront - (fNRows-1)*fXStep/2 + fXStep*i;
fYPos[i][j] = fYFront + (fNColumns-1)*fYStep/2 - fYStep*j;
}
fOrigin.SetXYZ(fXFront, fYFront, fZFront);
// Debug output.
THcShower* fParent;
fParent = (THcShower*) GetParent();
if (fParent->fdbg_init_cal) {
cout << "---------------------------------------------------------------\n";
cout << "Debug output from THcShowerArray::ReadDatabase for "
<< GetParent()->GetPrefix() << ":" << endl;
cout << " Layer #" << fLayerNum << ", number of elements " << dec << fNelem
<< endl;
cout << " Columns " << fNColumns << ", Rows " << fNRows << endl;
cout << "Front X, Y Z: " << fXFront << ", " << fYFront << ", " << fZFront
<< " cm" << endl;
cout << " Block to block X and Y distances: " << fXStep << ", " << fYStep
<< " cm" << endl;
cout << " Block size along Z: " << fZSize << " cm" << endl;
cout << "Block X coordinates:" << endl;
for (UInt_t i=0; i<fNRows; i++) {
for (UInt_t j=0; j<fNColumns; j++) {
cout << fXPos[i][j] << " ";
}
cout << endl;
}
cout << endl;
cout << "Block Y coordinates:" << endl;
for (UInt_t i=0; i<fNRows; i++) {
for (UInt_t j=0; j<fNColumns; j++) {
cout << fYPos[i][j] << " ";
}
cout << endl;
}
cout << endl;
cout << " Origin of Array:" << endl;
cout << " Xorig = " << GetOrigin().X() << endl;
cout << " Yorig = " << GetOrigin().Y() << endl;
cout << " Zorig = " << GetOrigin().Z() << endl;
cout << endl;
cout << " Using FADC " << fUsingFADC << endl;
if (fUsingFADC) {
cout << " FADC pedestal sample low = " << fPedSampLow << ", high = "
<< fPedSampHigh << endl;
cout << " FADC data sample low = " << fDataSampLow << ", high = "
<< fDataSampHigh << endl;
}
}
// Here read the 2-D arrays of pedestals, gains, etc.
// Pedestal limits per channel.
fPedLimit = new Int_t [fNelem];
Double_t cal_arr_cal_const[fNelem];
Double_t cal_arr_gain_cor[fNelem];
DBRequest list1[]={
{"cal_arr_ped_limit", fPedLimit, kInt, static_cast<UInt_t>(fNelem)},
{"cal_arr_cal_const", cal_arr_cal_const, kDouble, static_cast<UInt_t>(fNelem)},
{"cal_arr_gain_cor", cal_arr_gain_cor, kDouble, static_cast<UInt_t>(fNelem)},
// {"cal_min_peds", &fShMinPeds, kInt},
{0}
};
gHcParms->LoadParmValues((DBRequest*)&list1, prefix);
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
// Debug output.
if (fParent->fdbg_init_cal) {
cout << " fPedLimit:" << endl;
Int_t el=0;
for (UInt_t j=0; j<fNColumns; j++) {
cout << " ";
for (UInt_t i=0; i<fNRows; i++) {
cout << fPedLimit[el++] << " ";
};
cout << endl;
};
cout << " cal_arr_cal_const:" << endl;
el=0;
for (UInt_t j=0; j<fNColumns; j++) {
cout << " ";
for (UInt_t i=0; i<fNRows; i++) {
cout << cal_arr_cal_const[el++] << " ";
};
cout << endl;
};
cout << " cal_arr_gain_cor:" << endl;
el=0;
for (UInt_t j=0; j<fNColumns; j++) {
cout << " ";
for (UInt_t i=0; i<fNRows; i++) {
cout << cal_arr_gain_cor[el++] << " ";
};
cout << endl;
};
} // end of debug output
// Calibration constants (GeV / ADC channel).
fGain = new Double_t [fNelem];
for (UInt_t i=0; i<fNelem; i++) {
fGain[i] = cal_arr_cal_const[i] * cal_arr_gain_cor[i];
}
// Debug output.
if (fParent->fdbg_init_cal) {
cout << " fGain:" << endl;
Int_t el=0;
for (UInt_t j=0; j<fNColumns; j++) {
cout << " ";
for (UInt_t i=0; i<fNRows; i++) {
cout << fGain[el++] << " ";
};
cout << endl;
};
}
fMinPeds = fParent->GetMinPeds();
InitializePedestals();
// Event by event amplitude and pedestal
fA = new Double_t[fNelem];
fP = new Double_t[fNelem];
fA_p = new Double_t[fNelem];
// Energy depositions per block.
fE = new Double_t[fNelem];
#ifdef HITPIC
hitpic = new char*[fNRows];
for(Int_t row=0;row<fNRows;row++) {
hitpic[row] = new char[NPERLINE*(fNColumns+1)+2];
}
piccolumn=0;
#endif
// Debug output.
if (fParent->fdbg_init_cal) {
cout << " fMinPeds = " << fMinPeds << endl;
cout << "---------------------------------------------------------------\n";
}
return kOK;
}
//_____________________________________________________________________________
Int_t THcShowerArray::DefineVariables( EMode mode )
{
// Initialize global variables
if( mode == kDefine && fIsSetup ) return kOK;
fIsSetup = ( mode == kDefine );
// Register variables in global list
RVarDef vars[] = {
{"adchits", "List of ADC hits", "fADCHits.THcSignalHit.GetPaddleNumber()"},
{"a", "Raw ADC Amplitude", "fA"},
{"p", "Dynamic ADC Pedestal", "fP"},
{"a_p", "Sparsified, ped-subtracted ADC Amplitudes", "fA_p"},
{ "nhits", "Number of hits", "fNhits" },
{ "nclust", "Number of clusters", "fNclust" },
{"e", "Energy Depositions per block", "fE"},
{"earray", "Energy Deposition in array", "fEarray"},
{ "ntracks", "Number of shower tracks", "fNtracks" },
{ 0 }
};
return DefineVarsFromList( vars, mode );
}
//_____________________________________________________________________________
void THcShowerArray::Clear( Option_t* )
{
// Clears the hit lists
fADCHits->Clear();
for (THcShowerClusterListIt i=fClusterList->begin(); i!=fClusterList->end();
++i) {
delete *i;
*i = 0;
}
fClusterList->clear();
}
//_____________________________________________________________________________
Int_t THcShowerArray::Decode( const THaEvData& evdata )
{
// Doesn't actually get called. Use Fill method instead
return 0;
}
//_____________________________________________________________________________
Int_t THcShowerArray::CoarseProcess( TClonesArray& tracks )
{
// Fill set of unclustered shower array hits.
// Reuse hit class pertained to the HMS/SOS type calorimeters.
// Save Y coordinate of the hit in Z parameter of the class.
// Save energy deposition in the module as hit mean energy, do not use
// positive and negative side energies.
THcShowerHitSet HitSet; //set of hits
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
UInt_t k=0;
for (UInt_t i=0; i<fNRows; i++) {
for(UInt_t j=0; j < fNColumns; j++) {
if (fA_p[k] > 0) { //hit
THcShowerHit* hit =
new THcShowerHit(i, j, fXPos[i][j], fYPos[i][j], fE[k], 0., 0.);
HitSet.insert(hit);
}
k++;
}
}
fNhits = HitSet.size();
//Debug output, print out hits before clustering.
THcShower* fParent = (THcShower*) GetParent();
if (fParent->fdbg_clusters_cal) {
cout << "---------------------------------------------------------------\n";
cout << "Debug output from THcShowerArray::CoarseProcess for " << GetName()
<< endl;
cout << " List of unclustered hits. Total hits: " << fNhits << endl;
THcShowerHitIt it = HitSet.begin(); //<set> version
for (Int_t i=0; i!=fNhits; i++) {
cout << " hit " << i << ": ";
(*(it++))->show();
}
}
// Cluster hits and fill list of clusters.
fParent->ClusterHits(HitSet, fClusterList);
fNclust = (*fClusterList).size(); //number of clusters
//Debug output, print out clustered hits.
if (fParent->fdbg_clusters_cal) {
cout << " Clustered hits. Number of clusters: " << fNclust << endl;
UInt_t i = 0;
for (THcShowerClusterListIt ppcl = (*fClusterList).begin();
ppcl != (*fClusterList).end(); ppcl++) {
cout << " Cluster #" << i++
<<": E=" << clE(*ppcl)
<< " Epr=" << clEpr(*ppcl)
<< " X=" << clX(*ppcl)
<< " Z=" << clZ(*ppcl)
<< " size=" << (**ppcl).size()
<< endl;
Int_t j=0;
for (THcShowerClusterIt pph=(**ppcl).begin(); pph!=(**ppcl).end();
pph++) {
cout << " hit " << j++ << ": ";
(**pph).show();
}
}
cout << "---------------------------------------------------------------\n";
}
//-----------------------------------------------------------------------------
Int_t THcShowerArray::MatchCluster(THaTrack* Track,
Double_t& XTrFront, Double_t& YTrFront)
{
// Match an Array cluster to a given track. Return the cluster number,
// and track coordinates at the front of Array.
XTrFront = kBig;
YTrFront = kBig;
Double_t pathl = kBig;
// Track interception with face of Array. The coordinates are
// in the Array's local system.
fOrigin = GetOrigin();
THcShower* fParent = (THcShower*) GetParent();
fParent->CalcTrackIntercept(Track, pathl, XTrFront, YTrFront);
// Transform coordiantes to the spectrometer's coordinate system.
XTrFront += GetOrigin().X();
YTrFront += GetOrigin().Y();
Bool_t inFidVol = true; // In Fiducial Volume flag
// Re-evaluate Fid. Volume Flag if fid. volume test is requested
if (fParent->fvTest) {
TVector3 Origin = fOrigin; //save fOrigin
// Track coordinates at the back of the detector.
// Origin at the back of counter.
fOrigin.SetXYZ(GetOrigin().X(), GetOrigin().Y(), GetOrigin().Z() + fZSize);
Double_t XTrBack = kBig;
Double_t YTrBack = kBig;
fParent->CalcTrackIntercept(Track, pathl, XTrBack, YTrBack);
XTrBack += GetOrigin().X(); // from local coord. system
YTrBack += GetOrigin().Y(); // to the spectrometer system
inFidVol = (XTrFront <= fParent->fvXmax) && (XTrFront >= fParent->fvXmin) &&
(YTrFront <= fParent->fvYmax) && (YTrFront >= fParent->fvYmin) &&
(XTrBack <= fParent->fvXmax) && (XTrBack >= fParent->fvXmin) &&
(YTrBack <= fParent->fvYmax) && (YTrBack >= fParent->fvYmin);
fOrigin = Origin; //restore fOrigin
// Match a cluster to the track. Choose closest to the track cluster.
Int_t mclust = -1; // The match cluster #, initialize with a bogus value.
Double_t Delta = kBig; // Track to cluster distance
if (inFidVol) {
// Since hits and clusters are in reverse order (with respect to Engine),
// search backwards to be consistent with Engine.
//
// Note: cluster Z coordinate is used here as Y, for Z variable
// of the THcShowerHit class was used to save Y coordinates of hits.
for (Int_t i=fNclust-1; i>-1; i--) {
THcShowerCluster* cluster = *(fClusterList->begin()+i);
Double_t dx = TMath::Abs( clX(cluster) - XTrFront );
Double_t dy = TMath::Abs( clZ(cluster) - YTrFront ); //cluster Z for Y.
Double_t distance = TMath::Sqrt(dx*dx+dy*dy); //cluster-track dist.
//Choice of threshold on distance is not unuque. Use the simplest for now.
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
if (distance <= (0.5*(fXStep + fYStep) + fParent->fSlop)) {
fNtracks++;
if (distance < Delta) {
mclust = i;
Delta = distance;
}
}
}
}
//Debug output.
if (fParent->fdbg_tracks_cal) {
cout << "---------------------------------------------------------------\n";
cout << "Debug output from THcShowerArray::MatchCluster for " << GetName()
<< endl;
cout << " Track at DC:"
<< " X = " << Track->GetX()
<< " Y = " << Track->GetY()
<< " Theta = " << Track->GetTheta()
<< " Phi = " << Track->GetPhi()
<< endl;
cout << " Track at the front of Array:"
<< " X = " << XTrFront
<< " Y = " << YTrFront
<< " Pathl = " << pathl
<< endl;
if (fParent->fvTest)
cout << " Fiducial volume test: inFidVol = " << inFidVol << endl;
cout << " Matched cluster #" << mclust << ", Delta = " << Delta << endl;
cout << "---------------------------------------------------------------\n";
}
return mclust;
}
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
//_____________________________________________________________________________
Float_t THcShowerArray::GetShEnergy(THaTrack* Track) {
// Get total energy deposited in the Array cluster matched to the given
// spectrometer Track.
// Track coordinates at the front of Array, initialize out of acceptance.
Double_t Xtr = -100.;
Double_t Ytr = -100.;
// Associate a cluster to the track.
Int_t mclust = MatchCluster(Track, Xtr, Ytr);
// Coordinate corrected total energy deposition in the cluster.
Float_t Etrk = 0.;
if (mclust >= 0) { // if there is a matched cluster
// Get matched cluster.
THcShowerCluster* cluster = *(fClusterList->begin()+mclust);
// No coordinate correction for now.
Etrk = clE(cluster);
} //mclust>=0
//Debug output.
THcShower* fParent = (THcShower*) GetParent();
if (fParent->fdbg_tracks_cal) {
cout << "---------------------------------------------------------------\n";
cout << "Debug output from THcShowerArray::GetShEnergy for "
<< GetName() << endl;
cout << " Track at Array: X = " << Xtr << " Y = " << Ytr;
if (mclust >= 0)
cout << ", matched cluster #" << mclust << "." << endl;
else
cout << ", no matched cluster found." << endl;
cout << " Track's Array energy = " << Etrk << "." << endl;
cout << "---------------------------------------------------------------\n";
}
return Etrk;
}
//_____________________________________________________________________________
Int_t THcShowerArray::FineProcess( TClonesArray& tracks )
{
return 0;
}
//_____________________________________________________________________________
Int_t THcShowerArray::ProcessHits(TClonesArray* rawhits, Int_t nexthit)
{
// Extract the data for this layer from hit list.
THcShower* fParent;
fParent = (THcShower*) GetParent();
// Initialize variables.
Int_t nADCHits=0;
fADCHits->Clear();
for(Int_t i=0;i<fNelem;i++) {
fA[i] = 0;
fA_p[i] = 0;
fE[i] = 0;
fEarray = 0;
// Process raw hits. Get ADC hits for the plane, assign variables for each
// channel.
Int_t nrawhits = rawhits->GetLast()+1;
Int_t ihit = nexthit;
Int_t ngood = 0;
Int_t threshold = 100;
while(ihit < nrawhits) {
THcRawShowerHit* hit = (THcRawShowerHit *) rawhits->At(ihit);
if(hit->fPlane != fLayerNum) {
break;
}
// Should check that counter # is in range
if (fUsingFADC) {
fA[hit->fCounter-1] = hit->GetRawAdcHitPos().GetData(
fPedSampLow, fPedSampHigh, fDataSampLow, fDataSampHigh
);
fP[hit->fCounter-1] = hit->GetRawAdcHitPos().GetAverage(
fPedSampLow, fPedSampHigh
);
}
else {
fA[hit->fCounter-1] = hit->GetData(0);
}
if(fA[hit->fCounter-1] > threshold) {
ngood++;
}
// Sparsify hits, fill the hit list, compute the energy depostion.
if(fA[hit->fCounter-1] > fThresh[hit->fCounter -1]) {
THcSignalHit *sighit = (THcSignalHit*)fADCHits->ConstructedAt(nADCHits++);
sighit->Set(hit->fCounter, fA[hit->fCounter-1]);
fUsingFADC ?
fA_p[hit->fCounter-1] = fA[hit->fCounter-1] :
fA_p[hit->fCounter-1] = fA[hit->fCounter-1] - fPed[hit->fCounter -1];
fE[hit->fCounter-1] += fA_p[hit->fCounter-1] * fGain[hit->fCounter-1];
}
// Accumulate energies in the plane.
fEarray += fE[hit->fCounter-1];
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
#if 0
if(ngood > 0) {
cout << "+";
for(Int_t column=0;column<fNColumns;column++) {
cout << "-";
}
cout << "+" << endl;
for(Int_t row=0;row<fNRows;row++) {
cout << "|";
for(Int_t column=0;column<fNColumns;column++) {
Int_t counter = column*fNRows + row;
if(fA[counter]>threshold) {
cout << "X";
} else {
cout << " ";
}
}
cout << "|" << endl;
}
}
#endif
#ifdef HITPIC
if(ngood > 0) {
for(Int_t row=0;row<fNRows;row++) {
if(piccolumn==0) {
hitpic[row][0] = '|';
}
for(Int_t column=0;column<fNColumns;column++) {
Int_t counter = column*fNRows+row;
if(fA[counter] > threshold) {
hitpic[row][piccolumn*(fNColumns+1)+column+1] = 'X';
} else {
hitpic[row][piccolumn*(fNColumns+1)+column+1] = ' ';
}
hitpic[row][(piccolumn+1)*(fNColumns+1)] = '|';
}
}
piccolumn++;
if(piccolumn==NPERLINE) {
cout << "+";
for(Int_t pc=0;pc<NPERLINE;pc++) {
for(Int_t column=0;column<fNColumns;column++) {
cout << "-";
}
cout << "+";
}
cout << endl;
for(Int_t row=0;row<fNRows;row++) {
hitpic[row][(piccolumn+1)*(fNColumns+1)+1] = '\0';
cout << hitpic[row] << endl;
}
piccolumn = 0;
}
}
#endif
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
//Debug output.
if (fParent->fdbg_decoded_cal) {
cout << "---------------------------------------------------------------\n";
cout << "Debug output from THcShowerArray::ProcessHits for "
<< fParent->GetPrefix() << ":" << endl;
cout << " nrawhits = " << nrawhits << " nexthit = " << nexthit << endl;
cout << " Sparsified hits for shower array, plane #" << fLayerNum
<< ", " << GetName() << ":" << endl;
Int_t nspar = 0;
for (Int_t jhit = nexthit; jhit < nrawhits; jhit++) {
THcRawShowerHit* hit = (THcRawShowerHit *) rawhits->At(jhit);
if(hit->fPlane != fLayerNum) {
break;
}
if(fA[hit->fCounter-1] > fThresh[hit->fCounter -1]) {
cout << " counter = " << hit->fCounter
<< " E = " << fE[hit->fCounter-1]
<< endl;
nspar++;
}
}
if (nspar == 0) cout << " No hits\n";
cout << " Earray = " << fEarray << endl;
cout << "---------------------------------------------------------------\n";
}
return(ihit);
}
//_____________________________________________________________________________
Int_t THcShowerArray::AccumulatePedestals(TClonesArray* rawhits, Int_t nexthit)
{
// Extract data for this plane from hit list and accumulate in
// arrays for subsequent pedestal calculations.
Int_t nrawhits = rawhits->GetLast()+1;
Int_t ihit = nexthit;
while(ihit < nrawhits) {
THcRawShowerHit* hit = (THcRawShowerHit *) rawhits->At(ihit);
if(hit->fPlane != fLayerNum) {
break;
}
Int_t element = hit->fCounter - 1; // Should check if in range
// Should check that counter # is in range
Int_t adc = 0;
if (fUsingFADC) {
adc = hit->GetRawAdcHitPos().GetData(
fPedSampLow, fPedSampHigh, fDataSampLow, fDataSampHigh
);
}
else {
adc = hit->GetData(0);
}
if(adc <= fPedLimit[element]) {
fPedSum[element] += adc;
fPedSum2[element] += adc*adc;
fPedCount[element]++;
if(fPedCount[element] == fMinPeds/5) {
fPedLimit[element] = 100 + fPedSum[element]/fPedCount[element];
}
}
ihit++;
}
fNPedestalEvents++;
// Debug output.
if ( ((THcShower*) GetParent())->fdbg_raw_cal ) {
cout << "---------------------------------------------------------------\n";
cout << "Debug output from THcShowerArray::AcculatePedestals for "
<< GetParent()->GetPrefix() << ":" << endl;
cout << "Processed hit list for plane " << GetName() << ":\n";
for (Int_t ih=nexthit; ih<nrawhits; ih++) {
THcRawShowerHit* hit = (THcRawShowerHit *) rawhits->At(ih);
if(hit->fPlane != fLayerNum) {
break;
}
Int_t adc = 0;
if (fUsingFADC) {
adc = hit->GetRawAdcHitPos().GetData(
fPedSampLow, fPedSampHigh, fDataSampLow, fDataSampHigh
);
}
else {
adc = hit->GetData(0);
}
cout << " hit " << ih << ":"
<< " plane = " << hit->fPlane
<< " counter = " << hit->fCounter
<< endl;
}
cout << "---------------------------------------------------------------\n";
}
//_____________________________________________________________________________
void THcShowerArray::CalculatePedestals( )
{
// Use the accumulated pedestal data to calculate pedestals.
for(Int_t i=0; i<fNelem;i++) {
fPed[i] = ((Float_t) fPedSum[i]) / TMath::Max(1, fPedCount[i]);
fSig[i] = sqrt(((Float_t)fPedSum2[i])/TMath::Max(1, fPedCount[i])
- fPed[i]*fPed[i]);
fThresh[i] = fPed[i] + TMath::Min(50., TMath::Max(10., 3.*fSig[i]));
}
// Debug output.
if ( ((THcShower*) GetParent())->fdbg_raw_cal ) {
cout << "---------------------------------------------------------------\n";
cout << "Debug output from THcShowerArray::CalculatePedestals for "
<< GetParent()->GetPrefix() << ":" << endl;
cout << " ADC pedestals and thresholds for calorimeter plane "
<< GetName() << endl;
for(Int_t i=0; i<fNelem;i++) {
cout << " element " << i << ": "
<< " Pedestal = " << fPed[i]
<< " threshold = " << fThresh[i]
<< endl;
}
cout << "---------------------------------------------------------------\n";
}
}
//_____________________________________________________________________________
void THcShowerArray::InitializePedestals( )
{
fNPedestalEvents = 0;
fPedSum = new Int_t [fNelem];
fPedSum2 = new Int_t [fNelem];
fPedCount = new Int_t [fNelem];
fSig = new Float_t [fNelem];
fPed = new Float_t [fNelem];
fThresh = new Float_t [fNelem];
for(Int_t i=0;i<fNelem;i++) {
fPedSum[i] = 0;
fPedSum2[i] = 0;
fPedCount[i] = 0;
}
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
//------------------------------------------------------------------------------
// Fiducial volume limits.
Double_t THcShowerArray::fvXmin() {
THcShower* fParent;
fParent = (THcShower*) GetParent();
return fXPos[0][0] - fXStep/2 + fParent->fvDelta;
}
Double_t THcShowerArray::fvYmax() {
THcShower* fParent;
fParent = (THcShower*) GetParent();
return fYPos[0][0] + fYStep/2 - fParent->fvDelta;
}
Double_t THcShowerArray::fvXmax() {
THcShower* fParent;
fParent = (THcShower*) GetParent();
return fXPos[fNRows-1][fNColumns-1] + fXStep/2 - fParent->fvDelta;
}
Double_t THcShowerArray::fvYmin() {
THcShower* fParent;
fParent = (THcShower*) GetParent();
return fYPos[fNRows-1][fNColumns-1] - fYStep/2 + fParent->fvDelta;
}