Newer
Older
//*-- Author :
//////////////////////////////////////////////////////////////////////////
//
// THcScintillatorPlane
//
//////////////////////////////////////////////////////////////////////////
#include "THcScintillatorPlane.h"
#include "TClonesArray.h"
#include "THcSignalHit.h"
#include "THcGlobals.h"
#include "THcParmList.h"
#include "THcHitList.h"
#include "THcHodoscope.h"
Simon Zhamkochyan
committed
#include "TClass.h"
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <iostream>
using namespace std;
ClassImp(THcScintillatorPlane)
//______________________________________________________________________________
THcScintillatorPlane::THcScintillatorPlane( const char* name,
const char* description,
const Int_t planenum,
THaDetectorBase* parent )
: THaSubDetector(name,description,parent)
{
// Normal constructor with name and description
fPosTDCHits = new TClonesArray("THcSignalHit",16);
fNegTDCHits = new TClonesArray("THcSignalHit",16);
fPosADCHits = new TClonesArray("THcSignalHit",16);
fNegADCHits = new TClonesArray("THcSignalHit",16);
#if ROOT_VERSION_CODE < ROOT_VERSION(5,32,0)
Simon Zhamkochyan
committed
fPosTDCHitsClass = fPosTDCHits->GetClass();
fNegTDCHitsClass = fNegTDCHits->GetClass();
fPosADCHitsClass = fPosADCHits->GetClass();
fNegADCHitsClass = fNegADCHits->GetClass();
fPlaneNum = planenum;
}
//______________________________________________________________________________
THcScintillatorPlane::~THcScintillatorPlane()
{
// Destructor
delete fPosTDCHits;
delete fNegTDCHits;
delete fPosADCHits;
delete fNegADCHits;
THaAnalysisObject::EStatus THcScintillatorPlane::Init( const TDatime& date )
{
// Extra initialization for scintillator plane: set up DataDest map
cout << "THcScintillatorPlane::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;
// Get the Hodoscope hitlist
// Can't seem to cast to THcHitList. What to do if we want to use
// THcScintillatorPlane as a subdetector to other than THcHodoscope?
// fParentHitList = static_cast<THcHodoscope*>(GetParent())->GetHitList();
return fStatus = kOK;
}
//_____________________________________________________________________________
Int_t THcScintillatorPlane::ReadDatabase( const TDatime& date )
{
// See what file it looks for
char prefix[2];
char parname[100];
prefix[0]=tolower(GetParent()->GetPrefix()[0]);
prefix[1]='\0';
strcpy(parname,prefix);
strcat(parname,"scin_");
strcat(parname,GetName());
Int_t plen=strlen(parname);
strcat(parname,"_nr");
cout << " Getting value of " << parname << endl;
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.
// Think we will make special methods to pass most
// How generic do we want to make this class?
// The way we get parameter data is going to be pretty specific to
// our parameter file naming conventions. But on the other hand,
// the Hall A analyzer read database is pretty specific.
// Is there any way for this class to know which spectrometer he
// belongs too?
// Create arrays to hold results here
return kOK;
}
//_____________________________________________________________________________
Int_t THcScintillatorPlane::DefineVariables( EMode mode )
{
// Initialize global variables and lookup table for decoder
cout << "THcScintillatorPlane::DefineVariables called " << GetName() << endl;
if( mode == kDefine && fIsSetup ) return kOK;
fIsSetup = ( mode == kDefine );
// Register variables in global list
RVarDef vars[] = {
{"postdchits", "List of Positive TDC hits",
"fPosTDCHits.THcSignalHit.GetPaddleNumber()"},
{"negtdchits", "List of Negative TDC hits",
"fNegTDCHits.THcSignalHit.GetPaddleNumber()"},
{"posadchits", "List of Positive ADC hits",
"fPosADCHits.THcSignalHit.GetPaddleNumber()"},
{"negadchits", "List of Negative ADC hits",
"fNegADCHits.THcSignalHit.GetPaddleNumber()"},
{ 0 }
};
return DefineVarsFromList( vars, mode );
}
//_____________________________________________________________________________
void THcScintillatorPlane::Clear( Option_t* )
{
//cout << " Calling THcScintillatorPlane::Clear " << GetName() << endl;
// Clears the hit lists
fPosTDCHits->Clear();
fNegTDCHits->Clear();
fPosADCHits->Clear();
fNegADCHits->Clear();
//_____________________________________________________________________________
Int_t THcScintillatorPlane::Decode( const THaEvData& evdata )
{
// Doesn't actually get called. Use Fill method instead
cout << " Calling THcScintillatorPlane::Decode " << GetName() << endl;
return 0;
}
//_____________________________________________________________________________
Int_t THcScintillatorPlane::CoarseProcess( TClonesArray& tracks )
{
// HitCount();
return 0;
}
//_____________________________________________________________________________
Int_t THcScintillatorPlane::FineProcess( TClonesArray& tracks )
{
return 0;
}
//_____________________________________________________________________________
Int_t THcScintillatorPlane::ProcessHits(TClonesArray* rawhits, Int_t nexthit)
{
// Extract the data for this plane from hit list
// Assumes that the hit list is sorted by plane, so we stop when the
// plane doesn't agree and return the index for the next hit.
Int_t nPosTDCHits=0;
Int_t nNegTDCHits=0;
Int_t nPosADCHits=0;
Int_t nNegADCHits=0;
fPosTDCHits->Clear();
fNegTDCHits->Clear();
fPosADCHits->Clear();
fNegADCHits->Clear();
Int_t nrawhits = rawhits->GetLast()+1;
// cout << "THcScintillatorPlane::ProcessHits " << fPlaneNum << " " << nexthit << "/" << nrawhits << endl;
Int_t ihit = nexthit;
while(ihit < nrawhits) {
THcHodoscopeHit* hit = (THcHodoscopeHit *) rawhits->At(ihit);
if(hit->fPlane > fPlaneNum) {
break;
}
// TDC positive hit
if(hit->fTDC_pos > 0) {
Simon Zhamkochyan
committed
#if ROOT_VERSION_CODE >= ROOT_VERSION(5,32,0)
THcSignalHit *sighit = (THcSignalHit*) fPosTDCHits->ConstructedAt(nPosTDCHits++);
Simon Zhamkochyan
committed
#else
TObject* obj = (*fPosTDCHits)[nPosTDCHits++];
R__ASSERT( obj );
if(!obj->TestBit (TObject::kNotDeleted))
fPosTDCHitsClass->New(obj);
THcSignalHit *sighit = (THcSignalHit*)obj;
Simon Zhamkochyan
committed
#endif
sighit->Set(hit->fCounter, hit->fTDC_pos);
}
Simon Zhamkochyan
committed
// TDC negative hit
if(hit->fTDC_neg > 0) {
Simon Zhamkochyan
committed
#if ROOT_VERSION_CODE >= ROOT_VERSION(5,32,0)
THcSignalHit *sighit = (THcSignalHit*) fNegTDCHits->ConstructedAt(nNegTDCHits++);
Simon Zhamkochyan
committed
#else
TObject* obj = (*fNegTDCHits)[nNegTDCHits++];
R__ASSERT( obj );
if(!obj->TestBit (TObject::kNotDeleted))
Simon Zhamkochyan
committed
fNegTDCHitsClass->New(obj);
THcSignalHit *sighit = (THcSignalHit*)obj;
Simon Zhamkochyan
committed
#endif
sighit->Set(hit->fCounter, hit->fTDC_neg);
}
Simon Zhamkochyan
committed
// ADC positive hit
if(hit->fADC_pos > 0) {
// cout <<"adc pos hit!!\n";
Simon Zhamkochyan
committed
#if ROOT_VERSION_CODE >= ROOT_VERSION(5,32,0)
THcSignalHit *sighit = (THcSignalHit*) fPosADCHits->ConstructedAt(nPosADCHits++);
Simon Zhamkochyan
committed
#else
TObject* obj = (*fPosADCHits)[nPosADCHits++];
R__ASSERT( obj );
if(!obj->TestBit (TObject::kNotDeleted))
Simon Zhamkochyan
committed
fPosADCHitsClass->New(obj);
THcSignalHit *sighit = (THcSignalHit*)obj;
Simon Zhamkochyan
committed
#endif
sighit->Set(hit->fCounter, hit->fADC_pos);
}
Simon Zhamkochyan
committed
// ADC negative hit
if(hit->fADC_neg > 0) {
// cout <<"adc neg hit!!\n";
Simon Zhamkochyan
committed
#if ROOT_VERSION_CODE >= ROOT_VERSION(5,32,0)
THcSignalHit *sighit = (THcSignalHit*) fNegADCHits->ConstructedAt(nNegADCHits++);
Simon Zhamkochyan
committed
#else
TObject* obj = (*fNegADCHits)[nNegADCHits++];
R__ASSERT( obj );
if(!obj->TestBit (TObject::kNotDeleted))
Simon Zhamkochyan
committed
fNegADCHitsClass->New(obj);
THcSignalHit *sighit = (THcSignalHit*)obj;
Simon Zhamkochyan
committed
#endif
sighit->Set(hit->fCounter, hit->fADC_neg);
}
Simon Zhamkochyan
committed
ihit++;
}
return(ihit);
}
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
//_____________________________________________________________________________
Int_t THcScintillatorPlane::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 " << fPlaneNum << " " << nexthit << "/" << nrawhits << endl;
Int_t ihit = nexthit;
while(ihit < nrawhits) {
THcHodoscopeHit* hit = (THcHodoscopeHit *) rawhits->At(ihit);
if(hit->fPlane > fPlaneNum) {
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 THcScintillatorPlane::CalculatePedestals( )
{
// Use the accumulated pedestal data to calculate pedestals
// Later add check to see if pedestals have drifted ("Danger Will Robinson!")
// cout << "Plane: " << fPlaneNum << endl;
for(Int_t i=0; i<fNelem;i++) {
// Positive tubes
fPosPed[i] = ((Double_t) fPosPedSum[i]) / TMath::Max(1, fPosPedCount[i]);
fPosThresh[i] = fPosPed[i] + 15;
// Negative tubes
fNegPed[i] = ((Double_t) fNegPedSum[i]) / TMath::Max(1, fNegPedCount[i]);
fNegThresh[i] = fNegPed[i] + 15;
// cout << i+1 << " " << fPosPed[i] << " " << fNegPed[i] << endl;
}
// cout << " " << endl;
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
}
//_____________________________________________________________________________
void THcScintillatorPlane::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];
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;
}
}