diff --git a/src/Scandalizer.cxx b/src/Scandalizer.cxx new file mode 100644 index 0000000000000000000000000000000000000000..9d802a413a9bd6cf25a491603150ec0cb373f4df --- /dev/null +++ b/src/Scandalizer.cxx @@ -0,0 +1,312 @@ +#include "Scandalizer.h" + +using namespace std; + +namespace hcana { + +Int_t Scandalizer::ReadOneEvent() +{ + // Read one event from current run (fRun) and raw-decode it using the + // current decoder (fEvData) + + if( fDoBench ) fBench->Begin("RawDecode"); + + bool to_read_file = false; + if( !fEvData->IsMultiBlockMode() || + (fEvData->IsMultiBlockMode() && fEvData->BlockIsDone()) ) + to_read_file = true; + + // Find next event buffer in CODA file. Quit if error. + Int_t status = THaRunBase::READ_OK; + if (to_read_file) + status = fRun->ReadEvent(); + + // there may be a better place to do this, but this works + if (fWantCodaVers > 0) { + fEvData->SetCodaVersion(fWantCodaVers); + } else { + fEvData->SetCodaVersion(fRun->GetCodaVersion()); + } + + switch( status ) { + case THaRunBase::READ_OK: + // Decode the event + if (to_read_file) { + status = fEvData->LoadEvent( fRun->GetEvBuffer() ); + } else { + status = fEvData->LoadFromMultiBlock( ); // load next event in block + } + switch( status ) { + case THaEvData::HED_WARN: + //std::cout << "HED_WARN\n"; + case THaEvData::HED_OK: // fall through + status = THaRunBase::READ_OK; + Incr(kNevRead); + break; + case THaEvData::HED_ERR: + // Decoding error + status = THaRunBase::READ_ERROR; + Incr(kDecodeErr); + break; + case THaEvData::HED_FATAL: + status = THaRunBase::READ_FATAL; + break; + } + break; + + case THaRunBase::READ_EOF: // fall through + std::cout << " READ_EOF\n"; + case THaRunBase::READ_FATAL: + // Just exit on EOF - don't count it + break; + default: + Incr(kCodaErr); + break; + } + + if( fDoBench ) fBench->Stop("RawDecode"); + return status; +} + +Int_t Scandalizer::Process( THaRunBase* run ) +{ + // Process the given run. Loop over all events in the event range and + // analyze all apparatuses defined in the global apparatus list. + // Fill Event structure if it is defined. + // If Event and Filename are defined, then fill the output tree with Event + // and write the file. + + static const char* const here = "Process"; + + if( !run ) { + if( fRun ) + run = fRun; + else + return -1; + } + + //--- Initialization. Creates fFile, fOutput, and fEvent if necessary. + // Also copies run to fRun if run is different from fRun + Int_t status = Init( run ); + if( status != 0 ) { + return status; + } + + // Restart "Total" since it is stopped in Init() + fBench->Begin("Total"); + + //--- Re-open the data source. Should succeed since this was tested in Init(). + if( (status = fRun->Open()) != THaRunBase::READ_OK ) { + Error( here, "Failed to re-open the input file. " + "Make sure the file still exists."); + fBench->Stop("Total"); + return -4; + } + + // Make the current run available globally - the run parameters are + // needed by some modules + gHaRun = fRun; + + // Enable/disable helicity decoding as requested + fEvData->EnableHelicity( HelicityEnabled() ); + // Set decoder reporting level. FIXME: update when THaEvData is updated + fEvData->SetVerbose( (fVerbose>2) ); + fEvData->SetDebug( (fVerbose>3) ); + + // Informational messages + if( fVerbose>1 ) { + cout << "Decoder: helicity " + << (fEvData->HelicityEnabled() ? "enabled" : "disabled") + << endl; + cout << endl << "Starting analysis" << endl; + } + if( fVerbose>2 && fRun->GetFirstEvent()>1 ) + cout << "Skipping " << fRun->GetFirstEvent() << " events" << endl; + + //--- The main event loop. + + fNev = 0; + bool terminate = false, fatal = false; + UInt_t nlast = fRun->GetLastEvent(); + fAnalysisStarted = kTRUE; + BeginAnalysis(); + if( fFile ) { + fFile->cd(); + fRun->Write("Run_Data"); // Save run data to first ROOT file + } + void (*prev_handler)(int); + prev_handler = signal (SIGINT, handle_sig); + + while ( !terminate && (fNev < nlast)) { + //&& (status = ReadOneEvent()) != THaRunBase::READ_EOF ) + //std::cout << " evtype(last) " << fEvData->GetEvType() << "\n"; + status = ReadOneEvent(); + //std::cout << " status " << status << "\n"; + //std::cout << " evtype " << fEvData->GetEvType() << "\n"; + + // If an interupt signal is sent (ctrl-c) + // // + if(sig_caught) { + terminate = true; + break; + } + + + if( status == THaRunBase::READ_EOF ) { + //if( fEvData->GetEvType() != 20 ) { + // std::cout << " sleeping...."; + // //gSystem->Sleep(1000); + //}else { + //} + break; + } + + //--- Skip events with errors, unless fatal + if( status == THaRunBase::READ_FATAL ){ + std::cout << " READ_FATAL\n"; + break; + } + if( status != THaRunBase::READ_OK ){ + continue; + } + + UInt_t evnum = fEvData->GetEvNum(); + + // Count events according to the requested mode + // Whether or not to ignore events prior to fRun->GetFirstEvent() + // is up to the analysis routines. + switch(fCountMode) { + case kCountPhysics: + if( fEvData->IsPhysicsTrigger() ) + fNev++; + break; + case kCountAll: + fNev++; + break; + case kCountRaw: + fNev = evnum; + break; + default: + break; + } + + //--- Print marks periodically + if( (fVerbose>1) && (evnum > 0) && (evnum % fMarkInterval == 0)){ + cout << "test run: "<< fRun->GetNumber() << ", " << dec << evnum << endl; + } + if( (evnum > 0) &&(evnum % fAutoSaveInterval == 0)){ + fOutput->GetTree()->AutoSave("SaveSelf"); + } + + //--- Update run parameters with current event + if( fUpdateRun ){ + fRun->Update( fEvData ); + } + + //--- Clear all tests/cuts + if( fDoBench ) fBench->Begin("Cuts"); + gHaCuts->ClearAll(); + if( fDoBench ) fBench->Stop("Cuts"); + + //--- Perform the analysis + Int_t err = MainAnalysis(); + switch( err ) { + case kOK: + break; + case kSkip: + continue; + case kFatal: + fatal = terminate = true; + continue; + case kTerminate: + terminate = true; + break; + default: + Error( here, "Unknown return code from MainAnalysis(): %d", err ); + terminate = fatal = true; + continue; + } + + Incr(kNevAccepted); + + } // End of event loop + + signal (SIGINT, prev_handler); + EndAnalysis(); + + //--- Close the input file + fRun->Close(); + + // Save final run parameters in run object of caller, if any + *run = *fRun; + + // Write the output file and clean up. + // This writes the Tree as well as any objects (histograms etc.) + // that are defined in the current directory. + + if( fDoBench ) fBench->Begin("Output"); + // Ensure that we are in the output file's current directory + // ... someone might have pulled the rug from under our feet + + // get the CURRENT file, since splitting might have occurred + if( fOutput && fOutput->GetTree() ) + fFile = fOutput->GetTree()->GetCurrentFile(); + if( fFile ) fFile->cd(); + if( fOutput ) fOutput->End(); + if( fFile ) { + fRun->Write("Run_Data"); // Save run data to ROOT file + // fFile->Write();//already done by fOutput->End() + fFile->Purge(); // get rid of excess object "cycles" + } + if( fDoBench ) fBench->Stop("Output"); + + fBench->Stop("Total"); + + //--- Report statistics + if( fVerbose>0 ) { + cout << dec; + if( status == THaRunBase::READ_EOF ) + cout << "End of file"; + else if ( fNev == nlast ) + cout << "Event limit reached."; + else if ( fatal ) + cout << "Fatal processing error."; + else if ( terminate ) + cout << "Terminated during processing."; + cout << endl; + + if( !fatal ) { + PrintCounters(); + + if( fVerbose>1 ) + PrintScalers(); + } + } + + // Print cut summary (also to file if one given) + //if( !fatal ) + // PrintCutSummary(); + + // Print timing statistics, if benchmarking enabled + //if( fDoBench && !fatal ) { + // cout << "Timing summary:" << endl; + // fBench->Print("Init"); + // fBench->Print("RawDecode"); + // fBench->Print("Decode"); + // fBench->Print("CoarseTracking"); + // fBench->Print("CoarseReconstruct"); + // fBench->Print("Tracking"); + // fBench->Print("Reconstruct"); + // fBench->Print("Physics"); + // fBench->Print("Output"); + // fBench->Print("Cuts"); + //} + //if( (fVerbose>1 || fDoBench) && !fatal ) + // fBench->Print("Total"); + + //keep the last run available + // gHaRun = NULL; + return fNev; +} + +} diff --git a/src/Scandalizer.h b/src/Scandalizer.h new file mode 100644 index 0000000000000000000000000000000000000000..7b08e1c1390f0220b46ab670f8a159a3a36759e5 --- /dev/null +++ b/src/Scandalizer.h @@ -0,0 +1,24 @@ +#ifndef hcana_Scandalizer_h_ +#define hcana_Scandalizer_h_ + +#include "THaBenchmark.h" +#include "THcAnalyzer.h" +#include <iostream> + +namespace hcana { + + class Scandalizer : public THcAnalyzer { + public: + Scandalizer() : THcAnalyzer() {} + virtual ~Scandalizer() {} + + virtual Int_t Process(THaRunBase* run = nullptr); + virtual Int_t ReadOneEvent(); + + Int_t GoToEndOfCodaFile(); + + ClassDef(Scandalizer, 0) // Hall C Analyzer Standard Event Loop + }; + +} // namespace hcana +#endif diff --git a/src/THcAnalyzer.h b/src/THcAnalyzer.h index d5bd10bae17f11b4980e128a8d0745ae4c8f335b..80208f02d1b44ed4153f98f7c0dee446c80447e6 100644 --- a/src/THcAnalyzer.h +++ b/src/THcAnalyzer.h @@ -8,6 +8,41 @@ ////////////////////////////////////////////////////////////////////////// #include "THaAnalyzer.h" +#include "THaRunBase.h" +#include "THaEvent.h" +#include "THaOutput.h" +#include "THaEvData.h" +#include "THaGlobals.h" +#include "THaSpectrometer.h" +#include "THaNamedList.h" +#include "THaCutList.h" +#include "THaCut.h" +#include "THaPhysicsModule.h" +#include "THaPostProcess.h" +#include "THaBenchmark.h" +#include "THaEvtTypeHandler.h" +#include "THaEpicsEvtHandler.h" +#include "TList.h" +#include "TTree.h" +#include "TFile.h" +#include "TClass.h" +#include "TDatime.h" +#include "TClass.h" +#include "TError.h" +#include "TSystem.h" +#include "TROOT.h" +#include "TMath.h" +#include "TDirectory.h" +#include "THaCrateMap.h" + +#include <algorithm> +#include <csignal> +#include <cstring> +#include <exception> +#include <fstream> +#include <iomanip> +#include <iostream> +#include <stdexcept> class THcAnalyzer : public THaAnalyzer { diff --git a/src/THcHitList.cxx b/src/THcHitList.cxx index 8422139db38f86c6dc2f2e238db95cc394349346..dce91765b5d04c85f9d41ecaf4ce85ae2c27ea16 100644 --- a/src/THcHitList.cxx +++ b/src/THcHitList.cxx @@ -186,7 +186,7 @@ Int_t THcHitList::DecodeToHitList( const THaEvData& evdata, Bool_t suppresswarni if(!fMap) { // Find the TI slot for ADCs // Assumes that all FADCs are in the same crate - cout << "Got the Crate map" << endl; + //cout << "Got the Crate map" << endl; fMap = evdata.GetCrateMap(); for (Int_t i=0; i < fdMap->GetSize(); i++) { // Look for a FADC250 THaDetMap::Module* d = fdMap->GetModule(i); @@ -197,7 +197,7 @@ Int_t THcHitList::DecodeToHitList( const THaEvData& evdata, Bool_t suppresswarni if(fMap->getModel(d->crate, slot) == 4) { fTISlot = slot; fTICrate = d->crate; - cout << "TI Slot = " << fTISlot << endl; + //cout << "TI Slot = " << fTISlot << endl; break; } } diff --git a/src/TrackingEfficiency.cxx b/src/TrackingEfficiency.cxx new file mode 100644 index 0000000000000000000000000000000000000000..53b055a53a4d19b9c5326e8f34ec3aff765292b0 --- /dev/null +++ b/src/TrackingEfficiency.cxx @@ -0,0 +1,451 @@ +#include "THaEvData.h" +#include "THaCutList.h" +#include "VarDef.h" +#include "VarType.h" +#include "TClonesArray.h" + +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include <iostream> + +#include "THaApparatus.h" +#include "THcGlobals.h" +#include "THcHodoHit.h" +#include "THcParmList.h" +#include "TrackingEfficiency.h" + +namespace hcana { + + using namespace std; + + TrackingEfficiency::TrackingEfficiency(const char* name, const char* description, + const char* hodname) + : THaPhysicsModule(name, description) {} + + TrackingEfficiency::~TrackingEfficiency() { + // Destructor + RemoveVariables(); + } + //_____________________________________________________________________________ + + void TrackingEfficiency::Reset(Option_t* opt) + // Clear event-by-event data + { + Clear(opt); + } + + //_____________________________________________________________________________ + Int_t TrackingEfficiency::Begin(THaRunBase*) { + // Start of analysis + + //if (!IsOK()) + // return -1; + + //// Book any special histograms here + + //fNevt = 0; + + //// Clear all the accumulators here + //for (Int_t ip = 0; ip < fNPlanes; ip++) { + // fHitPlane[ip] = 0; + // for (Int_t ic = 0; ic < fNCounters[ip]; ic++) { + // fStatPosHit[ip][ic] = 0; + // fStatNegHit[ip][ic] = 0; + // fStatAndHit[ip][ic] = 0; + // fStatOrHit[ip][ic] = 0; + // fBothGood[ip][ic] = 0; + // fPosGood[ip][ic] = 0; + // fNegGood[ip][ic] = 0; + // for (Int_t idel = 0; idel < 20; idel++) { + // fStatTrkDel[ip][ic][idel] = 0; + // fStatAndHitDel[ip][ic][idel] = 0; + // } + // } + //} + + return 0; + } + + //_____________________________________________________________________________ + Int_t TrackingEfficiency::End(THaRunBase*) { + //// End of analysis + //for (Int_t ip = 0; ip < fNPlanes; ip++) { + // fStatAndEff[ip] = 0; + // for (Int_t ic = 0; ic < fNCounters[ip]; ic++) { + // fStatTrkSum[ip] += fStatTrk[fHod->GetScinIndex(ip, ic)]; + // fStatAndSum[ip] += fHodoAndEffi[fHod->GetScinIndex(ip, ic)]; + // } + // if (fStatTrkSum[ip] != 0) + // fStatAndEff[ip] = float(fStatAndSum[ip]) / float(fStatTrkSum[ip]); + //} + //// + //Double_t p1 = fStatAndEff[0]; + //Double_t p2 = fStatAndEff[1]; + //Double_t p3 = fStatAndEff[2]; + //Double_t p4 = fStatAndEff[3]; + //// probability that ONLY the listed planes had triggers + //Double_t p1234 = p1 * p2 * p3 * p4; + //Double_t p123 = p1 * p2 * p3 * (1. - p4); + //Double_t p124 = p1 * p2 * (1. - p3) * p4; + //Double_t p134 = p1 * (1. - p2) * p3 * p4; + //Double_t p234 = (1. - p1) * p2 * p3 * p4; + //fHodoEff_s1 = 1. - ((1. - p1) * (1. - p2)); + //fHodoEff_s2 = 1. - ((1. - p3) * (1. - p4)); + //fHodoEff_tof = fHodoEff_s1 * fHodoEff_s2; + //fHodoEff_3_of_4 = p1234 + p123 + p124 + p134 + p234; + //fHodoEff_4_of_4 = p1234; + return 0; + } + + //_____________________________________________________________________________ + THaAnalysisObject::EStatus TrackingEfficiency::Init(const TDatime& run_time) { + // Initialize TrackingEfficiency physics module + + // const char* const here = "Init"; + + // Standard initialization. Calls ReadDatabase(), ReadRunDatabase(), + // and DefineVariables() (see THaAnalysisObject::Init) + + //fHod = dynamic_cast<THcHodoscope*>(FindModule(fName.Data(), "THcHodoscope")); + + //fSpectro = static_cast<THaSpectrometer*>(fHod->GetApparatus()); + + //if (THaPhysicsModule::Init(run_time) != kOK) + // return fStatus; + + //cout << "TrackingEfficiency::Init nplanes=" << fHod->GetNPlanes() << endl; + //cout << "TrackingEfficiency::Init Apparatus = " << fHod->GetName() << " " + // << (fHod->GetApparatus())->GetName() << endl; + + return fStatus = kOK; + } + + //_____________________________________________________________________________ + Int_t TrackingEfficiency::ReadDatabase(const TDatime& date) { + //// Read database. Gets variable needed for efficiency calculation + //// Get # of planes and their z positions here. + + //fNPlanes = fHod->GetNPlanes(); + //fPlanes = new THcScintillatorPlane*[fNPlanes]; + //fPosZ = new Double_t[fNPlanes]; + //fSpacing = new Double_t[fNPlanes]; + //fCenterFirst = new Double_t[fNPlanes]; + //fNCounters = new Int_t[fNPlanes]; + //fHodoSlop = new Double_t[fNPlanes]; + //fStatTrkSum = new Int_t[fNPlanes]; + //fStatAndSum = new Int_t[fNPlanes]; + //fStatAndEff = new Double_t[fNPlanes]; + + //Int_t maxcountersperplane = 0; + //for (Int_t ip = 0; ip < fNPlanes; ip++) { + // fStatTrkSum[ip] = 0.; + // fStatAndSum[ip] = 0.; + // fStatAndEff[ip] = 0.; + // fPlanes[ip] = fHod->GetPlane(ip); + // fPosZ[ip] = fPlanes[ip]->GetZpos() + 0.5 * fPlanes[ip]->GetDzpos(); + // fSpacing[ip] = fPlanes[ip]->GetSpacing(); + // fCenterFirst[ip] = fPlanes[ip]->GetPosCenter(0) + fPlanes[ip]->GetPosOffset(); + // fNCounters[ip] = fPlanes[ip]->GetNelem(); + // maxcountersperplane = TMath::Max(maxcountersperplane, fNCounters[ip]); + //} + //Int_t totalpaddles = fNPlanes * maxcountersperplane; + //fHodoPosEffi = new Int_t[totalpaddles]; + //fHodoNegEffi = new Int_t[totalpaddles]; + //fHodoOrEffi = new Int_t[totalpaddles]; + //fHodoAndEffi = new Int_t[totalpaddles]; + //fStatTrk = new Int_t[totalpaddles]; + + //char prefix[2]; + //prefix[0] = tolower((fHod->GetApparatus())->GetName()[0]); + //prefix[1] = '\0'; + + //DBRequest list[] = {{"stat_slop", &fStatSlop, kDouble}, + // {"stat_maxchisq", &fMaxChisq, kDouble}, + // {"HodoEff_CalEnergy_Cut", &fHodoEff_CalEnergy_Cut, kDouble, 0, 1}, + // {"hodo_slop", fHodoSlop, kDouble, (UInt_t)fNPlanes}, + // {0}}; + //fHodoEff_CalEnergy_Cut = 0.050; // set default value + //gHcParms->LoadParmValues((DBRequest*)&list, prefix); + //cout << "\n\nTrackingEfficiency::ReadDatabase nplanes=" << fHod->GetNPlanes() << endl; + //// Setup statistics arrays + //// Better method to put this in? + //// These all need to be cleared in Begin + //fHitPlane = new Int_t[fNPlanes]; + //fStatTrkDel.resize(fNPlanes); + //fStatAndHitDel.resize(fNPlanes); + //fStatPosHit.resize(fNPlanes); + //fStatNegHit.resize(fNPlanes); + //fStatAndHit.resize(fNPlanes); + //fStatOrHit.resize(fNPlanes); + //fBothGood.resize(fNPlanes); + //fPosGood.resize(fNPlanes); + //fNegGood.resize(fNPlanes); + + //for (Int_t ip = 0; ip < fNPlanes; ip++) { + + // cout << "Plane = " << ip + 1 << " counters = " << fNCounters[ip] << endl; + + // fStatTrkDel[ip].resize(fNCounters[ip]); + // fStatAndHitDel[ip].resize(fNCounters[ip]); + // fStatPosHit[ip].resize(fNCounters[ip]); + // fStatNegHit[ip].resize(fNCounters[ip]); + // fStatAndHit[ip].resize(fNCounters[ip]); + // fStatOrHit[ip].resize(fNCounters[ip]); + // fBothGood[ip].resize(fNCounters[ip]); + // fPosGood[ip].resize(fNCounters[ip]); + // fNegGood[ip].resize(fNCounters[ip]); + // for (Int_t ic = 0; ic < fNCounters[ip]; ic++) { + // fStatTrkDel[ip][ic].resize(20); // Max this settable + // fStatAndHitDel[ip][ic].resize(20); // Max this settable + + // fHodoPosEffi[fHod->GetScinIndex(ip, ic)] = 0; + // fHodoNegEffi[fHod->GetScinIndex(ip, ic)] = 0; + // fHodoOrEffi[fHod->GetScinIndex(ip, ic)] = 0; + // fHodoAndEffi[fHod->GetScinIndex(ip, ic)] = 0; + // fStatTrk[fHod->GetScinIndex(ip, ic)] = 0; + // } + //} + + //// Int_t fHodPaddles = fNCounters[0]; + //// gHcParms->Define(Form("%shodo_pos_hits[%d][%d]",fPrefix,fNPlanes,fHodPaddles), + //// "Golden track's pos pmt hit",*&fStatPosHit); + + //gHcParms->Define(Form("%shodo_pos_eff[%d]", prefix, totalpaddles), "Hodo positive effi", + // *fHodoPosEffi); + //gHcParms->Define(Form("%shodo_neg_eff[%d]", prefix, totalpaddles), "Hodo negative effi", + // *fHodoNegEffi); + //gHcParms->Define(Form("%shodo_or_eff[%d]", prefix, totalpaddles), "Hodo or effi", *fHodoOrEffi); + //gHcParms->Define(Form("%shodo_and_eff[%d]", prefix, totalpaddles), "Hodo and effi", + // *fHodoAndEffi); + //gHcParms->Define(Form("%shodo_plane_AND_eff[%d]", prefix, fNPlanes), "Hodo plane AND eff", + // *fStatAndEff); + //gHcParms->Define(Form("%shodo_gold_hits[%d]", prefix, totalpaddles), "Hodo golden hits", + // *fStatTrk); + //gHcParms->Define(Form("%shodo_s1XY_eff", prefix), "Efficiency for S1XY", fHodoEff_s1); + //gHcParms->Define(Form("%shodo_s2XY_eff", prefix), "Efficiency for S2XY", fHodoEff_s2); + //gHcParms->Define(Form("%shodo_stof_eff", prefix), "Efficiency for STOF", fHodoEff_tof); + //gHcParms->Define(Form("%shodo_3_of_4_eff", prefix), "Efficiency for 3 of 4", fHodoEff_3_of_4); + //gHcParms->Define(Form("%shodo_4_of_4_eff", prefix), "Efficiency for 4 of 4", fHodoEff_4_of_4); + + return kOK; + } + + //_____________________________________________________________________________ + Int_t TrackingEfficiency::DefineVariables(EMode mode) { + + //if (mode == kDefine && fIsSetup) + // return kOK; + //fIsSetup = (mode == kDefine); + + //// fEffiTest = 0; + //// gHcParms->Define(Form("hodoeffi"),"Testing effi",fEffiTest); + + //const RVarDef vars[] = {// Move these into THcHallCSpectrometer using track fTracks + // // {"effitestvar", "efficiency test var", "fEffiTest"}, + // // {"goldhodposhit", "pos pmt hit in hodo", "fStatPosHit"}, + // {0}}; + //return DefineVarsFromList(vars, mode); + return kOK; + } + + //_____________________________________________________________________________ + Int_t TrackingEfficiency::Process(const THaEvData& evdata) { + // Accumulate statistics for efficiency + + // const char* const here = "Process"; + + if (!IsOK()) + return -1; + + //// Project the golden track to each + //// plane. Need to get track at Focal Plane, not tgt. + //// + //// Assumes that planes are X, Y, X, Y + //THaTrack* theTrack = fSpectro->GetGoldenTrack(); + //// Since fSpectro knows the index of the golden track, we can + //// get other information about the track from fSpectro. + //// Need to remove the specialized stuff from fGoldenTrack + + //if (!theTrack) + // return 0; + //Int_t trackIndex = theTrack->GetTrkNum() - 1; + + //// May make these member variables + //Double_t hitPos[fNPlanes]; + //Double_t hitDistance[fNPlanes]; + //Int_t hitCounter[fNPlanes]; + //Int_t checkHit[fNPlanes]; + //// Bool_t goodTdcBothSides[fNPlanes]; + //// Bool_t goodTdcOneSide[fNPlanes]; + + //for (Int_t ip = 0; ip < fNPlanes; ip++) { + // // Should really have plane object self identify as X or Y + // if (ip % 2 == 0) { // X Plane + // hitPos[ip] = theTrack->GetX() + theTrack->GetTheta() * fPosZ[ip]; + // hitCounter[ip] = + // TMath::Max(TMath::Min(TMath::Nint((hitPos[ip] - fCenterFirst[ip]) / fSpacing[ip] + 1), + // fNCounters[ip]), + // 1); + // hitDistance[ip] = hitPos[ip] - (fSpacing[ip] * (hitCounter[ip] - 1) + fCenterFirst[ip]); + // } else { // Y Plane + // hitPos[ip] = theTrack->GetY() + theTrack->GetPhi() * fPosZ[ip]; + // hitCounter[ip] = + // TMath::Max(TMath::Min(TMath::Nint((fCenterFirst[ip] - hitPos[ip]) / fSpacing[ip] + 1), + // fNCounters[ip]), + // 1); + // hitDistance[ip] = hitPos[ip] - (fCenterFirst[ip] - fSpacing[ip] * (hitCounter[ip] - 1)); + // } + //} + + //// Fill dpos histograms and set checkHit for each plane. + //// dpos stuff not implemented + //// Why do dpos stuff here, does any other part need the dpos historgrams + //// Look to VDCEff code to see how to create and fill histograms + + //for (Int_t ip = 0; ip < fNPlanes; ip++) { + // Int_t hitcounter = hitCounter[ip]; + // // goodTdcBothSides[ip] = kFALSE; + // // goodTdcOneSide[ip] = kFALSE; + // checkHit[ip] = 2; + // Int_t nphits = fPlanes[ip]->GetNScinHits(); + // TClonesArray* hodoHits = fPlanes[ip]->GetHits(); + // for (Int_t ihit = 0; ihit < nphits; ihit++) { + // THcHodoHit* hit = (THcHodoHit*)hodoHits->At(ihit); + // Int_t counter = hit->GetPaddleNumber(); + // if (counter == hitcounter) { + // checkHit[ip] = 0; + // } else { + // if (TMath::Abs(counter - hitcounter) == 1 && checkHit[ip] != 0) { + // checkHit[ip] = 1; + // } + // } + // } + //} + + //// Record position differences between track and center of scin + //// and increment 'should have hit' counters + //for (Int_t ip = 0; ip < fNPlanes; ip++) { + // // Int_t hitcounter = hitCounter[ip]; + // Double_t dist = hitDistance[ip]; + // if (TMath::Abs(dist) <= fStatSlop && theTrack->GetChi2() / theTrack->GetNDoF() <= fMaxChisq && + // theTrack->GetEnergy() >= fHodoEff_CalEnergy_Cut) { + // fStatTrk[fHod->GetScinIndex(ip, hitCounter[ip] - 1)]++; + // // Double_t delta = theTrack->GetDp(); + // // Int_t idel = TMath::Floor(delta+10.0); + // // Should + // // if(idel >=0 && idel < 20) { + // // fStatTrkDel[ip][hitcounter][idel]++; + // // } + // // lookat[ip] = TRUE; + // } + // fHitPlane[ip] = 0; + //} + //// Is there a hit on or adjacent to paddle that track + //// passes through? + + //// May collapse this loop into last + + //// record the hits as a "didhit" if track is near center of + //// scintillator, the chisqared of the track is good and it is the + //// first "didhit" in that plane. + + //for (Int_t ip = 0; ip < fNPlanes; ip++) { + // Int_t hitcounter = hitCounter[ip]; + // if (hitcounter >= fNCounters[ip]) + // hitcounter = fNCounters[ip] - 1; + // if (hitcounter < 0) + // hitcounter = 0; + // Double_t dist = hitDistance[ip]; + // Int_t nphits = fPlanes[ip]->GetNScinHits(); + // TClonesArray* hodoHits = fPlanes[ip]->GetHits(); + // for (Int_t ihit = 0; ihit < nphits; ihit++) { + // THcHodoHit* hit = (THcHodoHit*)hodoHits->At(ihit); + // Int_t counter = hit->GetPaddleNumber(); + // // Finds first best hit + // Bool_t onTrack, goodScinTime, goodTdcNeg, goodTdcPos; + // fHod->GetFlags(trackIndex, ip, ihit, onTrack, goodScinTime, goodTdcNeg, goodTdcPos); + // if (TMath::Abs(dist) <= fStatSlop && TMath::Abs(hitcounter - counter) <= checkHit[ip] && + // fHitPlane[ip] == 0 && theTrack->GetChi2() / theTrack->GetNDoF() <= fMaxChisq && + // theTrack->GetEnergy() >= fHodoEff_CalEnergy_Cut) { + // fHitPlane[ip]++; + + // // Need to find out hgood_tdc_pos(igoldentrack,ihit) and neg + // if (goodTdcPos) { + // if (goodTdcNeg) { // Both fired + // fStatPosHit[ip][hitcounter]++; + // fStatNegHit[ip][hitcounter]++; + // fStatAndHit[ip][hitcounter]++; + // fStatOrHit[ip][hitcounter]++; + + // fHodoPosEffi[fHod->GetScinIndex(ip, hitCounter[ip] - 1)]++; + // fHodoNegEffi[fHod->GetScinIndex(ip, hitCounter[ip] - 1)]++; + // fHodoAndEffi[fHod->GetScinIndex(ip, hitCounter[ip] - 1)]++; + // fHodoOrEffi[fHod->GetScinIndex(ip, hitCounter[ip] - 1)]++; + + // // Double_t delta = theTrack->GetDp(); + // // Int_t idel = TMath::Floor(delta+10.0); + // // if(idel >=0 && idel < 20) { + // // fStatAndHitDel[ip][hitcounter][idel]++; + // // } + // } else { + // fStatPosHit[ip][hitcounter]++; + // fStatOrHit[ip][hitcounter]++; + // fHodoPosEffi[fHod->GetScinIndex(ip, hitCounter[ip] - 1)]++; + // fHodoOrEffi[fHod->GetScinIndex(ip, hitCounter[ip] - 1)]++; + // } + // } else if (goodTdcNeg) { + // fStatNegHit[ip][hitcounter]++; + // fStatOrHit[ip][hitcounter]++; + // fHodoNegEffi[fHod->GetScinIndex(ip, hitCounter[ip] - 1)]++; + // fHodoOrEffi[fHod->GetScinIndex(ip, hitCounter[ip] - 1)]++; + // } + + // // Increment pos/neg/both fired. Track independent, so + // // no chisquared cut, but note that only scintillators on the + // // track are examined. + // if (goodTdcPos) { + // if (goodTdcNeg) { + // fBothGood[ip][hitcounter]++; + // } else { + // fPosGood[ip][hitcounter]++; + // } + // } else if (goodTdcNeg) { + // fNegGood[ip][hitcounter]++; + // } + // // Determine if one or both PMTs had a good tdc + + // // if(goodTdcPos && goodTdcNeg) { + // // goodTdcBothSides[ip] = kTRUE; + // // } + // // if(goodTdcPos || goodTdcNeg) { + // // goodTdcOneSide[ip] = kTRUE; + // // } + // } + + // /* + // For each plane, see of other 3 fired. This means that they were enough + // to form a 3/4 trigger, and so the fraction of times this plane fired is + // the plane trigger efficiency. NOTE: we only require a TDC hit, not a + // TDC hit within the SCIN 3/4 trigger window, so high rates will make + // this seem better than it is. Also, make sure we're not near the edge + // of the hodoscope (at the last plane), using the same hhodo_slop param. + // as for h_tof.f + // NOTE ALSO: to make this check simpler, we are assuming that all planes + // have identical active areas. y_scin = y_cent + y_offset, so shift track + // position by offset for comparing to edges. + // */ + + // // Need to add calculation and cuts on + // // xatback and yatback in order to set the + // // htrig_hododidflag, htrig_hodoshouldflag and otherthreehit flags + // // + + // ++fNevt; + // } + //} + return 0; + } + +} // namespace hcana + diff --git a/src/TrackingEfficiency.h b/src/TrackingEfficiency.h new file mode 100644 index 0000000000000000000000000000000000000000..5e2ea1b5866891e87ab41c6c8a119eaf9af941f3 --- /dev/null +++ b/src/TrackingEfficiency.h @@ -0,0 +1,104 @@ +#ifndef ROOT_TrackingEfficiency +#define ROOT_TrackingEfficiency + +/////////////////////////////////////////////////////////////////////////////// +// // +// TrackingEfficiency // +// // +/////////////////////////////////////////////////////////////////////////////// + +#include "THaEvData.h" +#include "THaCutList.h" +#include "VarDef.h" +#include "VarType.h" +#include "TClonesArray.h" + +#include <cstring> +#include <cstdio> +#include <cstdlib> +#include <iostream> + +#include "THaPhysicsModule.h" +#include "THcHodoscope.h" +#include "THaSpectrometer.h" +#include "THaTrack.h" + +namespace hcana { + + + /** \brief TrackingEfficiency calculation. + * + * \ingroup PhysMods + */ + class TrackingEfficiency : public THaPhysicsModule { + public: + TrackingEfficiency(const char* name, const char* description, const char* hodname); + virtual ~TrackingEfficiency(); + + virtual Int_t Begin(THaRunBase* r = 0); + virtual Int_t End(THaRunBase* r = 0); + virtual EStatus Init(const TDatime& run_time); + virtual Int_t Process(const THaEvData&); + + void Reset(Option_t* opt = ""); + + protected: + virtual Int_t ReadDatabase(const TDatime& date); + virtual Int_t DefineVariables(EMode mode = kDefine); + /* Int_t GetScinIndex(Int_t nPlane, Int_t nPaddle); */ + + // Data needed for efficiency calculation for one Hodoscope paddle + + // Double_t* fZPos; // + + // TString fName; // Name of hodoscope + // THcHodoscope* fHod; // Hodscope object + // THaSpectrometer* fSpectro; // Spectrometer object + + // Long64_t fNevt; + + //// Information about the hodoscopes that we get from the + //// THcHodoscope object + + // Int_t fEffiTest; + // Int_t fNPlanes; + // THcScintillatorPlane** fPlanes; + // Double_t* fPosZ; + // Double_t* fSpacing; + // Double_t* fCenterFirst; + // Int_t* fNCounters; + //// Int_t* fHodoPlnContHit; + // Int_t* fHodoPosEffi; + // Int_t* fHodoNegEffi; + // Int_t* fHodoOrEffi; + // Int_t* fHodoAndEffi; + // Int_t* fStatTrk; + // Int_t* fStatTrkSum; + // Int_t* fStatAndSum; + // Double_t* fStatAndEff; + // Double_t fStatSlop; + // Double_t fHodoEff_CalEnergy_Cut; + // Double_t fMaxChisq; + // Double_t* fHodoSlop; + // Double_t fHodoEff_s1, fHodoEff_s2, fHodoEff_tof, fHodoEff_3_of_4, fHodoEff_4_of_4; + + //// Arrays for accumulating statistics + // vector<vector<vector<Int_t>>> fHitShould; + // vector<vector<vector<Int_t>>> fStatAndHitDel; + // vector<vector<vector<Int_t>>> fStatTrkDel; + // vector<vector<Int_t>> fStatPosHit; + // vector<vector<Int_t>> fStatNegHit; + // vector<vector<Int_t>> fStatAndHit; + // vector<vector<Int_t>> fStatOrHit; + // vector<vector<Int_t>> fBothGood; + // vector<vector<Int_t>> fNegGood; + // vector<vector<Int_t>> fPosGood; + + // Int_t* fHitPlane; + + ClassDef(TrackingEfficiency, 0) // Hodoscope efficiency module + }; + +} // namespace hcana + +#endif diff --git a/src/include/HallC_LinkDef.h b/src/include/HallC_LinkDef.h index d3af17de665afe8abbb0f3355f7bf96a89c98c3f..e666b7e61449aa49fb75adc7f697ceeecd9b05f4 100644 --- a/src/include/HallC_LinkDef.h +++ b/src/include/HallC_LinkDef.h @@ -77,6 +77,8 @@ #pragma link C++ class Decoder::TIBlobModule+; #pragma link C++ class hcana::Shower2+; +#pragma link C++ class hcana::Scandalizer+; +#pragma link C++ class hcana::TrackingEfficiency+; // Postamble for HallC_Linkdef.h file #endif