Newer
Older
//*-- Author :
//////////////////////////////////////////////////////////////////////////
//
// THcShowerPlane
//
//////////////////////////////////////////////////////////////////////////
#include "THcShowerPlane.h"
#include "TClonesArray.h"
#include "THcSignalHit.h"
#include "THcGlobals.h"
#include "THcParmList.h"
#include "THcHitList.h"
#include "THcShower.h"
#include "TClass.h"
#include "math.h"
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <fstream>
using namespace std;
ClassImp(THcShowerPlane)
//______________________________________________________________________________
THcShowerPlane::THcShowerPlane( const char* name,
const char* description,
const Int_t layernum,
THaDetectorBase* parent )
: THaSubDetector(name,description,parent)
{
// Normal constructor with name and description
fPosADCHits = new TClonesArray("THcSignalHit",13);
fNegADCHits = new TClonesArray("THcSignalHit",13);
//#if ROOT_VERSION_CODE < ROOT_VERSION(5,32,0)
// fPosADCHitsClass = fPosADCHits->GetClass();
// fNegADCHitsClass = fNegADCHits->GetClass();
//#endif
fLayerNum = layernum;
}
//______________________________________________________________________________
THcShowerPlane::~THcShowerPlane()
{
// Destructor
delete fPosADCHits;
delete fNegADCHits;
delete [] fA_Pos;
delete [] fA_Neg;
delete [] fA_Pos_p;
delete [] fA_Neg_p;
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
}
THaAnalysisObject::EStatus THcShowerPlane::Init( const TDatime& date )
{
// Extra initialization for shower layer: set up DataDest map
cout << "THcShowerPlane::Init called " << GetName() << endl;
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 THcShowerPlane::ReadDatabase( const TDatime& date )
{
// See what file it looks for
static const char* const here = "ReadDatabase()";
char prefix[2];
char parname[100];
prefix[0]=tolower(GetParent()->GetPrefix()[0]);
prefix[1]='\0';
strcpy(parname,prefix);
strcat(parname,"cal_");
strcat(parname,GetName());
Int_t plen=strlen(parname);
strcat(parname,"_nr");
cout << " Getting value of SHOWER!!!" << parname << endl;
// Retrieve parameters we need from parent class
THcShower* fParent;
fParent = (THcShower*) GetParent();
fNelem = fParent->GetNBlocks(fLayerNum);
fA_Pos = new Float_t[fNelem];
fA_Neg = new Float_t[fNelem];
fA_Pos_p = new Float_t[fNelem];
fA_Neg_p = new Float_t[fNelem];
// fNelem = *(Int_t *)gHcParms->Find(parname)->GetValuePointer();
//
// parname[plen]='\0';
// strcat(parname,"_spacing");
//
// fSpacing = gHcParms->Find(parname)->GetValue(0);
// First letter of GetParent()->GetPrefix() tells us what prefix to
// use on parameter names.
// Find the number of elements
// Create arrays to hold results here
InitializePedestals();
return kOK;
}
//_____________________________________________________________________________
Int_t THcShowerPlane::DefineVariables( EMode mode )
{
// Initialize global variables and lookup table for decoder
cout << "THcShowerPlane::DefineVariables called " << GetName() << endl;
if( mode == kDefine && fIsSetup ) return kOK;
fIsSetup = ( mode == kDefine );
// Register variables in global list
RVarDef vars[] = {
{"posadchits", "List of Positive ADC hits","fPosADCHits.THcSignalHit.GetPaddleNumber()"},
{"negadchits", "List of Negative ADC hits","fNegADCHits.THcSignalHit.GetPaddleNumber()"},
{"apos", "Raw Positive ADC Amplitudes", "fA_Pos"},
{"aneg", "Raw Negative ADC Amplitudes", "fA_Neg"},
{"apos_p", "Ped-subtracted Positive ADC Amplitudes", "fA_Pos_p"},
{"aneg_p", "Ped-subtracted Negative ADC Amplitudes", "fA_Neg_p"},
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
return DefineVarsFromList( vars, mode );
}
//_____________________________________________________________________________
void THcShowerPlane::Clear( Option_t* )
{
//cout << " Calling THcShowerPlane::Clear " << GetName() << endl;
// Clears the hit lists
fPosADCHits->Clear();
fNegADCHits->Clear();
}
//_____________________________________________________________________________
Int_t THcShowerPlane::Decode( const THaEvData& evdata )
{
// Doesn't actually get called. Use Fill method instead
cout << " Calling THcShowerPlane::Decode " << GetName() << endl;
return 0;
}
//_____________________________________________________________________________
Int_t THcShowerPlane::CoarseProcess( TClonesArray& tracks )
{
// HitCount();
return 0;
}
//_____________________________________________________________________________
Int_t THcShowerPlane::FineProcess( TClonesArray& tracks )
{
return 0;
}
Int_t THcShowerPlane::ProcessHits(TClonesArray* rawhits, Int_t nexthit)
{
// Extract the data for this layer from hit list
// Assumes that the hit list is sorted by layer, so we stop when the
// plane doesn't agree and return the index for the next hit.
Int_t nPosADCHits=0;
Int_t nNegADCHits=0;
fPosADCHits->Clear();
fNegADCHits->Clear();
for(Int_t i=0;i<fNelem;i++) {
fA_Pos[i] = 0;
fA_Neg[i] = 0;
fA_Pos_p[i] = 0;
fA_Neg_p[i] = 0;
}
Int_t nrawhits = rawhits->GetLast()+1;
Int_t ihit = nexthit;
//cout << "nrawhits = " << nrawhits << endl;
//cout << "nexthit = " << nexthit << endl;
while(ihit < nrawhits) {
THcShowerHit* hit = (THcShowerHit *) rawhits->At(ihit);
//cout << "fplane = " << hit->fPlane << " Num = " << fLayerNum << endl;
// Should probably check that counter # is in range
fA_Pos[hit->fCounter-1] = hit->fADC_pos;
fA_Neg[hit->fCounter-1] = hit->fADC_neg;
fA_Pos_p[hit->fCounter-1] = hit->fADC_pos - fPosPed[hit->fCounter -1];
fA_Neg_p[hit->fCounter-1] = hit->fADC_neg - fNegPed[hit->fCounter -1];
double thresh_pos = fPosThresh[hit->fCounter -1];
if(hit->fADC_pos > thresh_pos) {
THcSignalHit *sighit = (THcSignalHit*) fPosADCHits->ConstructedAt(nPosADCHits++);
sighit->Set(hit->fCounter, hit->fADC_pos);
}
double thresh_neg = fNegThresh[hit->fCounter -1];
if(hit->fADC_neg > thresh_neg) {
THcSignalHit *sighit = (THcSignalHit*) fNegADCHits->ConstructedAt(nNegADCHits++);
sighit->Set(hit->fCounter, hit->fADC_neg);
}
//_____________________________________________________________________________
Int_t THcShowerPlane::AccumulatePedestals(TClonesArray* rawhits, Int_t nexthit)
{
// Extract the data for this plane from hit list, accumulating into
// arrays for calculating pedestals.
Int_t nrawhits = rawhits->GetLast()+1;
// cout << "THcScintillatorPlane::AcculatePedestals " << fLayerNum << " " << nexthit << "/" << nrawhits << endl;
Int_t ihit = nexthit;
while(ihit < nrawhits) {
THcShowerHit* hit = (THcShowerHit *) rawhits->At(ihit);
//cout << "fPlane = " << hit->fPlane << " Limit = " << fPlaneNum << endl;
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
if(hit->fPlane > fLayerNum) {
break;
}
Int_t element = hit->fCounter - 1; // Should check if in range
Int_t adcpos = hit->fADC_pos;
Int_t adcneg = hit->fADC_neg;
if(adcpos <= fPosPedLimit[element]) {
fPosPedSum[element] += adcpos;
fPosPedSum2[element] += adcpos*adcpos;
fPosPedCount[element]++;
if(fPosPedCount[element] == fMinPeds/5) {
fPosPedLimit[element] = 100 + fPosPedSum[element]/fPosPedCount[element];
}
}
if(adcneg <= fNegPedLimit[element]) {
fNegPedSum[element] += adcneg;
fNegPedSum2[element] += adcneg*adcneg;
fNegPedCount[element]++;
if(fNegPedCount[element] == fMinPeds/5) {
fNegPedLimit[element] = 100 + fNegPedSum[element]/fNegPedCount[element];
}
}
ihit++;
}
fNPedestalEvents++;
return(ihit);
}
//_____________________________________________________________________________
void THcShowerPlane::CalculatePedestals( )
{
// Use the accumulated pedestal data to calculate pedestals
// Later add check to see if pedestals have drifted ("Danger Will Robinson!")
for(Int_t i=0; i<fNelem;i++) {
// Positive tubes
fPosPed[i] = ((Double_t) fPosPedSum[i]) / TMath::Max(1, fPosPedCount[i]);
fPosSig[i] = sqrt((fPosPedSum2[i] - 2.*fPosPed[i]*fPosPedSum[i])/TMath::Max(1, fPosPedCount[i]) + fPosPed[i]*fPosPed[i]);
// fPosThresh[i] = fPosPed[i] + 15;
fPosThresh[i] = fPosPed[i] + TMath::Min(50., TMath::Max(10., 3.*fPosSig[i]));
// Negative tubes
fNegPed[i] = ((Double_t) fNegPedSum[i]) / TMath::Max(1, fNegPedCount[i]);
fNegSig[i] = sqrt((fNegPedSum2[i] - 2.*fNegPed[i]*fNegPedSum[i])/TMath::Max(1, fNegPedCount[i]) + fNegPed[i]*fNegPed[i]);
// fNegThresh[i] = fNegPed[i] + 15;
fNegThresh[i] = fNegPed[i] + TMath::Min(50., TMath::Max(10., 3.*fNegSig[i]));
// cout << i+1 << " " << 3.*fPosSig[i] << " " << 3.*fNegSig[i] << endl;
}
// cout << " " << endl;
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
}
//_____________________________________________________________________________
void THcShowerPlane::InitializePedestals( )
{
fNPedestalEvents = 0;
fMinPeds = 500; // In engine, this is set in parameter file
fPosPedSum = new Int_t [fNelem];
fPosPedSum2 = new Int_t [fNelem];
fPosPedLimit = new Int_t [fNelem];
fPosPedCount = new Int_t [fNelem];
fNegPedSum = new Int_t [fNelem];
fNegPedSum2 = new Int_t [fNelem];
fNegPedLimit = new Int_t [fNelem];
fNegPedCount = new Int_t [fNelem];
fPosSig = new Double_t [fNelem];
fNegSig = new Double_t [fNelem];
fPosPed = new Double_t [fNelem];
fNegPed = new Double_t [fNelem];
fPosThresh = new Double_t [fNelem];
fNegThresh = new Double_t [fNelem];
for(Int_t i=0;i<fNelem;i++) {
fPosPedSum[i] = 0;
fPosPedSum2[i] = 0;
fPosPedLimit[i] = 1000; // In engine, this are set in parameter file
fPosPedCount[i] = 0;
fNegPedSum[i] = 0;
fNegPedSum2[i] = 0;
fNegPedLimit[i] = 1000; // In engine, this are set in parameter file
fNegPedCount[i] = 0;
}
}