diff --git a/src/THcShower.cxx b/src/THcShower.cxx index 15172b1d71a6692245305a5028dc8fc0f7f5c225..e1dbf46bdbec3bd8569e010e7ea950008f75bea1 100644 --- a/src/THcShower.cxx +++ b/src/THcShower.cxx @@ -1169,6 +1169,13 @@ Int_t THcShower::FineProcess( TClonesArray& tracks ) } } //over tracks + if (Ntracks>0) { + for(UInt_t ip=0;ip<fNLayers;ip++) { + fPlanes[ip]-> AccumulateStat(tracks); + } + if(fHasArray) fArray->AccumulateStat(tracks); + } + //Debug output. if (fdbg_tracks_cal) { diff --git a/src/THcShowerArray.cxx b/src/THcShowerArray.cxx index e64a577bae1ecb2424de56fc8bc7399bb6816c73..007f5df9b5f154b5d07d120dbc9f7ccfcd685cb4 100644 --- a/src/THcShowerArray.cxx +++ b/src/THcShowerArray.cxx @@ -17,6 +17,8 @@ #include "math.h" #include "THaTrack.h" #include "THaTrackProj.h" +#include "THcCherenkov.h" //for efficiency calculations +#include "THcHallCSpectrometer.h" #include <cstring> #include <cstdio> @@ -129,6 +131,9 @@ Int_t THcShowerArray::ReadDatabase( const TDatime& date ) fPedSampHigh=9; fDataSampLow=23; fDataSampHigh=49; + fStatCerMin=1.; + fStatSlop=3.; + fStatMaxChi2=10.; DBRequest list[]={ {"cal_arr_nrows", &fNRows, kInt}, {"cal_arr_ncolumns", &fNColumns, kInt}, @@ -148,6 +153,9 @@ Int_t THcShowerArray::ReadDatabase( const TDatime& date ) {"cal_data_sample_low", &fDataSampLow, kInt, 0, 1}, {"cal_data_sample_high", &fDataSampHigh, kInt, 0, 1}, {"cal_debug_adc", &fDebugAdc, kInt, 0, 1}, + {"stat_cermin", &fStatCerMin, kDouble, 0, 1}, + {"stat_slop_array", &fStatSlop, kDouble, 0, 1}, + {"stat_maxchisq", &fStatMaxChi2, kDouble, 0, 1}, {0} }; @@ -342,6 +350,13 @@ Int_t THcShowerArray::ReadDatabase( const TDatime& date ) //fE = new Double_t[fNelem]; + // Numbers of tracks and hits , for efficiency calculations. + + fStatNumTrk = vector<Int_t> (fNelem, 0); + fStatNumHit = vector<Int_t> (fNelem, 0); + fTotStatNumTrk = 0; + fTotStatNumHit = 0; + #ifdef HITPIC hitpic = new char*[fNRows]; for(Int_t row=0;row<fNRows;row++) { @@ -370,6 +385,14 @@ Int_t THcShowerArray::DefineVariables( EMode mode ) if( mode == kDefine && fIsSetup ) return kOK; fIsSetup = ( mode == kDefine ); + // Register counters for efficiency calculations in gHcParms so that the + // variables can be used in end of run reports. + + gHcParms->Define(Form("%sstat_trksum_array", GetParent()->GetPrefix()), + "Number of tracks in calo. array", fTotStatNumTrk); + gHcParms->Define(Form("%sstat_hitsum_array", GetParent()->GetPrefix()), + "Number of hits in calo. array", fTotStatNumHit); + // Register variables in global list if (fDebugAdc) { RVarDef vars[] = { @@ -1163,3 +1186,99 @@ Double_t THcShowerArray::clMaxEnergyBlock(THcShowerCluster* cluster) { } return max_block; } + +//_____________________________________________________________________________ +Int_t THcShowerArray::AccumulateStat(TClonesArray& tracks ) +{ + // Accumumate statistics for efficiency calculations. + // + // Choose electron events in gas Cherenkov with good Chisq of the best track. + // Project best track to Array, + // calculate module number for the track, + // accrue number of tracks for the module, + // accrue number of hits for the module, if it is hit. + // Accrue total numbers of tracks and hits for Array. + + THaTrack* BestTrack = static_cast<THaTrack*>( tracks[0]); + if (BestTrack->GetChi2()/BestTrack->GetNDoF() > fStatMaxChi2) return 0; + + THcHallCSpectrometer *app=dynamic_cast<THcHallCSpectrometer*>(GetApparatus()); + + THaDetector* detc; + if (GetParent()->GetPrefix()[0] == 'P') + detc = app->GetDetector("hgcer"); + else + detc = app->GetDetector("cer"); + + THcCherenkov* hgcer = dynamic_cast<THcCherenkov*>(detc); + if (!hgcer) { + cout << "****** THcShowerArray::AccumulateStat: HGCer not found! ******" + << endl; + return 0; + } + + if (hgcer->GetCerNPE() < fStatCerMin) return 0; + + Double_t XTrk = kBig; + Double_t YTrk = kBig; + Double_t pathl = kBig; + + // Track interception with Array. The coordinates are in the calorimeter's + // local system. + + fOrigin = GetOrigin(); + THcShower* fParent = (THcShower*) GetParent(); + fParent->CalcTrackIntercept(BestTrack, pathl, XTrk, YTrk); + + // Transform coordiantes to the spectrometer's coordinate system. + XTrk += GetOrigin().X(); + YTrk += GetOrigin().Y(); + + for (Int_t i=0; i<fNelem; i++) { + + Int_t row = i%fNRows; + Int_t col =i/fNRows; + + if (TMath::Abs(XTrk - fXPos[row][col]) < fStatSlop && + TMath::Abs(YTrk - fYPos[row][col]) < fStatSlop) { + + fStatNumTrk.at(i)++; + fTotStatNumTrk++; + + if (fGoodAdcPulseInt.at(i) > 0.) { + fStatNumHit.at(i)++; + fTotStatNumHit++; + } + + } + + } + + if ( ((THcShower*) GetParent())->fdbg_tracks_cal ) { + cout << "---------------------------------------------------------------\n"; + cout << "THcShowerArray::AccumulateStat:" << endl; + cout << " Chi2/NDF = " <<BestTrack->GetChi2()/BestTrack->GetNDoF() <<endl; + cout << " HGCER Npe = " << hgcer->GetCerNPE() << endl; + cout << " XTrk, YTrk = " << XTrk << " " << YTrk << endl; + for (Int_t i=0; i<fNelem; i++) { + + Int_t row = i%fNRows; + Int_t col =i/fNRows; + + if (TMath::Abs(XTrk - fXPos[row][col]) < fStatSlop && + TMath::Abs(YTrk - fYPos[row][col]) < fStatSlop) { + + cout << " Module " << i << ", X=" << fXPos[i/fNRows][i%fNRows] + << ", Y=" << fYPos[i/fNRows][i%fNRows] << " matches track" << endl; + + if (fGoodAdcPulseInt.at(i) > 0.) + cout << " PulseIntegral = " << fGoodAdcPulseInt.at(i) << endl; + } + } + + cout << "---------------------------------------------------------------\n"; + // getchar(); + } + + return 1; +} diff --git a/src/THcShowerArray.h b/src/THcShowerArray.h index 8e45937cb1e1e15c7c38c007cc4a7f3ea289638c..0ac6f1a87c440fdfc10ec01d0b45638fe4d5705a 100644 --- a/src/THcShowerArray.h +++ b/src/THcShowerArray.h @@ -89,6 +89,8 @@ public: Double_t fvYmin(); Double_t clMaxEnergyBlock(THcShowerCluster* cluster); + Int_t AccumulateStat(TClonesArray& tracks); + protected: #ifdef HITPIC @@ -192,6 +194,15 @@ protected: TClonesArray* frAdcPulseInt; TClonesArray* frAdcPulseAmp; + //Quatitites for efficiency calculations. + + Double_t fStatCerMin; + Double_t fStatSlop; + Double_t fStatMaxChi2; + vector<Int_t> fStatNumTrk; + vector<Int_t> fStatNumHit; + Int_t fTotStatNumTrk; + Int_t fTotStatNumHit; virtual Int_t ReadDatabase( const TDatime& date ); virtual Int_t DefineVariables( EMode mode = kDefine ); diff --git a/src/THcShowerPlane.cxx b/src/THcShowerPlane.cxx index 4b5d7cce17a9e5fbf9e7900c98d144fe9b30774f..4df9594a93574e97c203baac002c2e3de7dc068e 100644 --- a/src/THcShowerPlane.cxx +++ b/src/THcShowerPlane.cxx @@ -17,6 +17,8 @@ One plane of shower blocks with side readout #include "math.h" #include "THaTrack.h" #include "THaTrackProj.h" +#include "THcCherenkov.h" //for efficiency calculations +#include "THcHallCSpectrometer.h" #include <cstring> #include <cstdio> @@ -158,6 +160,9 @@ Int_t THcShowerPlane::ReadDatabase( const TDatime& date ) fDataSampHigh=49; fAdcNegThreshold=0.; fAdcPosThreshold=0.; + fStatCerMin=1.; + fStatSlop=2.; + fStatMaxChi2=10.; DBRequest list[]={ {"cal_AdcNegThreshold", &fAdcNegThreshold, kDouble, 0, 1}, {"cal_AdcPosThreshold", &fAdcPosThreshold, kDouble, 0, 1}, @@ -166,6 +171,9 @@ Int_t THcShowerPlane::ReadDatabase( const TDatime& date ) {"cal_data_sample_low", &fDataSampLow, kInt, 0, 1}, {"cal_data_sample_high", &fDataSampHigh, kInt, 0, 1}, {"cal_debug_adc", &fDebugAdc, kInt, 0, 1}, + {"stat_cermin", &fStatCerMin, kDouble, 0, 1}, + {"stat_slop", &fStatSlop, kDouble, 0, 1}, + {"stat_maxchisq", &fStatMaxChi2, kDouble, 0, 1}, {0} }; @@ -243,6 +251,13 @@ Int_t THcShowerPlane::ReadDatabase( const TDatime& date ) // fEneg = new Double_t[fNelem]; // fEmean= new Double_t[fNelem]; + // Numbers of tracks and hits , for efficiency calculations. + + fStatNumTrk = vector<Int_t> (fNelem, 0); + fStatNumHit = vector<Int_t> (fNelem, 0); + fTotStatNumTrk = 0; + fTotStatNumHit = 0; + // Debug output. if (fParent->fdbg_init_cal) { @@ -304,6 +319,19 @@ Int_t THcShowerPlane::DefineVariables( EMode mode ) DefineVarsFromList( vars, mode); } //end debug statement + // Register counters for efficiency calculations in gHcParms so that the + // variables can be used in end of run reports. + + gHcParms->Define(Form("%sstat_trksum%d", GetParent()->GetPrefix(), fLayerNum), + Form("Number of tracks in calo. layer %d",fLayerNum), fTotStatNumTrk); + gHcParms->Define(Form("%sstat_hitsum%d", GetParent()->GetPrefix(), fLayerNum), + Form("Number of hits in calo. layer %d", fLayerNum), fTotStatNumHit); + + cout << "THcShowerPlane::DefineVariables: registered counters " + << Form("%sstat_trksum%d",GetParent()->GetPrefix(),fLayerNum) << " and " + << Form("%sstat_hitsum%d",GetParent()->GetPrefix(),fLayerNum) << endl; + // getchar(); + RVarDef vars[] = { {"posAdcErrorFlag", "List of positive raw ADC Error Flags", "frPosAdcErrorFlag.THcSignalHit.GetData()"}, {"negAdcErrorFlag", "List of negative raw ADC Error Flags ", "frNegAdcErrorFlag.THcSignalHit.GetData()"}, @@ -891,3 +919,92 @@ void THcShowerPlane::InitializePedestals( ) fNegPedCount[i] = 0; } } + +//_____________________________________________________________________________ +Int_t THcShowerPlane::AccumulateStat(TClonesArray& tracks ) +{ + // Accumumate statistics for efficiency calculations. + // + // Choose electron events in gas Cherenkov with good Chisq of the best track. + // Project best track to the plane, + // calculate row number for the track, + // accrue number of tracks for the row, + // accrue number of hits for the row, if row is hit. + // Accrue total numbers of tracks and hits for plane. + + THaTrack* BestTrack = static_cast<THaTrack*>( tracks[0]); + if (BestTrack->GetChi2()/BestTrack->GetNDoF() > fStatMaxChi2) return 0; + + THcHallCSpectrometer *app=dynamic_cast<THcHallCSpectrometer*>(GetApparatus()); + + THaDetector* detc; + if (GetParent()->GetPrefix()[0] == 'P') + detc = app->GetDetector("hgcer"); + else + detc = app->GetDetector("cer"); + + THcCherenkov* hgcer = dynamic_cast<THcCherenkov*>(detc); + if (!hgcer) { + cout << "****** THcShowerPlane::AccumulateStat: HGCer not found! ******" + << endl; + return 0; + } + + if (hgcer->GetCerNPE() < fStatCerMin) return 0; + + Double_t XTrk = kBig; + Double_t YTrk = kBig; + Double_t pathl = kBig; + + // Track interception with plane. The coordinates are in the calorimeter's + // local system. + + fOrigin = GetOrigin(); + THcShower* fParent = (THcShower*) GetParent(); + fParent->CalcTrackIntercept(BestTrack, pathl, XTrk, YTrk); + + // Transform coordiantes to the spectrometer's coordinate system. + XTrk += GetOrigin().X(); + YTrk += GetOrigin().Y(); + + for (Int_t i=0; i<fNelem; i++) { + + if (TMath::Abs(XTrk - fParent->GetXPos(fLayerNum-1,i)) < fStatSlop && + YTrk > fParent->GetYPos(fLayerNum-1,1) && + YTrk < fParent->GetYPos(fLayerNum-1,0) ) { + + fStatNumTrk.at(i)++; + fTotStatNumTrk++; + + if (fGoodPosAdcPulseInt.at(i) > 0. || fGoodNegAdcPulseInt.at(i) > 0.) { + fStatNumHit.at(i)++; + fTotStatNumHit++; + } + + } + + } + + if ( ((THcShower*) GetParent())->fdbg_tracks_cal ) { + cout << "---------------------------------------------------------------\n"; + cout << "THcShowerPlane::AccumulateStat:" << endl; + cout << " Chi2/NDF = " <<BestTrack->GetChi2()/BestTrack->GetNDoF() << endl; + cout << " HGCER Npe = " << hgcer->GetCerNPE() << endl; + cout << " XTrk, YTrk = " << XTrk << " " << YTrk << endl; + for (Int_t i=0; i<fNelem; i++) { + if (TMath::Abs(XTrk - fParent->GetXPos(fLayerNum-1,i)) < fStatSlop) { + + cout << " Module " << i << ", X=" << fParent->GetXPos(fLayerNum-1,i) + << " matches track" << endl; + + if (fGoodPosAdcPulseInt.at(i) > 0. || fGoodNegAdcPulseInt.at(i) > 0.) + cout << " PulseIntegrals = " << fGoodPosAdcPulseInt.at(i) << " " + << fGoodNegAdcPulseInt.at(i) << endl; + } + } + cout << "---------------------------------------------------------------\n"; + // getchar(); + } + + return 1; +} diff --git a/src/THcShowerPlane.h b/src/THcShowerPlane.h index 6a029e13ee808848d1b85d63eb58db573929c8a1..cc9f94ff62b8165e37383936b5b92a859a1df849 100644 --- a/src/THcShowerPlane.h +++ b/src/THcShowerPlane.h @@ -109,6 +109,8 @@ public: return fNegPed[i]; }; + Int_t AccumulateStat(TClonesArray& tracks); + protected: // Flash ADC parameters @@ -218,6 +220,17 @@ protected: virtual void FillADC_SampleIntegral( ); virtual void FillADC_SampIntDynPed( ); virtual void FillADC_Standard( ); + + //Quatitites for efficiency calculations. + + Double_t fStatCerMin; + Double_t fStatSlop; + Double_t fStatMaxChi2; + vector<Int_t> fStatNumTrk; + vector<Int_t> fStatNumHit; + Int_t fTotStatNumTrk; + Int_t fTotStatNumHit; + ClassDef(THcShowerPlane,0); // Calorimeter bars in a plane }; #endif