From 708c507050b575aadf25969ac2db43cc12f68366 Mon Sep 17 00:00:00 2001 From: "Stephen A. Wood" <zviwood@gmail.com> Date: Wed, 9 May 2012 14:49:27 -0400 Subject: [PATCH] Add a scintillator plane as a subdetector of THcHodoscope and add simple code to register ADC and TDC hits into global variables so that hit maps can be made. --- Makefile | 3 +- src/HallC_LinkDef.h | 2 + src/THcHitList.h | 6 +- src/THcHodoscope.cxx | 116 ++++++++++++++--- src/THcHodoscope.h | 10 +- src/THcScintillatorPlane.cxx | 234 +++++++++++++++++++++++++++++++++++ src/THcScintillatorPlane.h | 59 +++++++++ src/THcSignalHit.cxx | 11 ++ src/THcSignalHit.h | 33 +++++ 9 files changed, 453 insertions(+), 21 deletions(-) create mode 100644 src/THcScintillatorPlane.cxx create mode 100644 src/THcScintillatorPlane.h create mode 100644 src/THcSignalHit.cxx create mode 100644 src/THcSignalHit.h diff --git a/Makefile b/Makefile index 11cbf6d..583996d 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,8 @@ SRC = src/THcInterface.cxx src/THcParmList.cxx src/THcAnalyzer.cxx \ src/THcHodoscopeHit.cxx src/THcRawHit.cxx \ src/THcDCHit.cxx \ src/THcHitList.cxx src/THcDetectorMap.cxx src/THcHodoscope.cxx \ - src/THcHallCSpectrometer.cxx src/THcDriftChamber.cxx + src/THcHallCSpectrometer.cxx src/THcDriftChamber.cxx \ + src/THcScintillatorPlane.cxx src/THcSignalHit.cxx # Name of your package. # The shared library that will be built will get the name lib$(PACKAGE).so diff --git a/src/HallC_LinkDef.h b/src/HallC_LinkDef.h index 5ac786e..a8d80d8 100644 --- a/src/HallC_LinkDef.h +++ b/src/HallC_LinkDef.h @@ -18,5 +18,7 @@ #pragma link C++ class THcDriftChamber+; #pragma link C++ class THcDetectorMap+; #pragma link C++ class THcHallCSpectrometer+; +#pragma link C++ class THcScintillatorPlane+; +#pragma link C++ class THcSignalHit+; #endif diff --git a/src/THcHitList.h b/src/THcHitList.h index be90264..d96383b 100644 --- a/src/THcHitList.h +++ b/src/THcHitList.h @@ -30,10 +30,8 @@ class THcHitList { void InitHitList(THaDetMap* detmap, const char *hitclass, Int_t maxhits); - // This is a list of pointers to hit objects - // Instead should we have a list of the actual objects so that we are - // no delting and creating objects all the time. - // + TClonesArray* GetHitList() const {return fRawHitList; } + Int_t fNRawHits; Int_t fNMaxRawHits; TClonesArray* fRawHitList; // List of raw hits diff --git a/src/THcHodoscope.cxx b/src/THcHodoscope.cxx index b70ac6c..251f338 100644 --- a/src/THcHodoscope.cxx +++ b/src/THcHodoscope.cxx @@ -37,7 +37,11 @@ THcHodoscope::THcHodoscope( const char* name, const char* description, { // Constructor - fTrackProj = new TClonesArray( "THaTrackProj", 5 ); + //fTrackProj = new TClonesArray( "THaTrackProj", 5 ); + // Construct the planes + + Setup(name, description); + } //_____________________________________________________________________________ @@ -47,13 +51,83 @@ THcHodoscope::THcHodoscope( ) : // Constructor } +//_____________________________________________________________________________ +void THcHodoscope::Setup(const char* name, const char* description) +{ + + static const char* const here = "Setup()"; + static const char* const message = + "Must construct %s detector with valid name! Object construction failed."; + + // Base class constructor failed? + if( IsZombie()) return; + + fNPlanes = 4; // Eventually get # planes and plane names from a DB + fPlaneNames = new char* [fNPlanes]; + for(Int_t i=0;i<fNPlanes;i++) {fPlaneNames[i] = new char[3];} + strcpy(fPlaneNames[0],"1x"); + strcpy(fPlaneNames[1],"1y"); + strcpy(fPlaneNames[2],"2x"); + strcpy(fPlaneNames[3],"2y"); + + size_t nlen = strlen(name); + size_t slen = 0; + for(Int_t i=0;i < fNPlanes;i++) + {slen = TMath::Max(slen,strlen(fPlaneNames[i]));} + size_t len = nlen+slen+1; + + // Probably shouldn't assume that description is defined + char* desc = new char[strlen(description)+50+slen]; + fPlanes = new THcScintillatorPlane* [fNPlanes]; + for(Int_t i=0;i < fNPlanes;i++) { + strcpy(desc, description); + strcat(desc, " Plane "); + strcat(desc, fPlaneNames[i]); + + fPlanes[i] = new THcScintillatorPlane(fPlaneNames[i], desc, i+1, this); + cout << "Created Scintillator Plane " << fPlaneNames[i] << ", " << desc << endl; + } +} + +#if 0 +//_____________________________________________________________________________ +void THcHodoscope::SetApparatus( THaApparatus* app ) +{ + // Set the apparatus of this detector as well as the subdetectors + + cout << "In THcHodoscope::SetApparatus" << endl; + THaDetector::SetApparatus( app ); + for(Int_t i=0;i < fNPlanes;i++) { + fPlanes[i]->SetApparatus( app ); + } + return; +} +#endif + //_____________________________________________________________________________ THaAnalysisObject::EStatus THcHodoscope::Init( const TDatime& date ) { static const char* const here = "Init()"; - if( THaNonTrackingDetector::Init( date ) ) - return fStatus; + cout << "THcHodoscope::Init " << GetName() << endl; + + // Should probably put this in ReadDatabase as we will know the + // maximum number of hits after setting up the detector map + // But it needs to happen before the sub detectors are initialized + // so that they can get the pointer to the hitlist. + + THcHitList::InitHitList(fDetMap, "THcHodoscopeHit", 100); + + EStatus status; + // This triggers call of ReadDatabase and DefineVariables + if( (status = THaNonTrackingDetector::Init( date )) ) + return fStatus=status; + + for(Int_t ip=0;ip<fNPlanes;ip++) { + if((status = fPlanes[ip]->Init( date ))) { + return fStatus=status; + } + } // Replace with what we need for Hall C // const DataDest tmp[NDEST] = { @@ -62,11 +136,6 @@ THaAnalysisObject::EStatus THcHodoscope::Init( const TDatime& date ) // }; // memcpy( fDataDest, tmp, NDEST*sizeof(DataDest) ); - // Should probably put this in ReadDatabase as we will know the - // maximum number of hits after setting up the detector map - - THcHitList::InitHitList(fDetMap, "THcHodoscopeHit", 100); - // Will need to determine which apparatus it belongs to and use the // appropriate detector ID in the FillMap call if( gHcDetectorMap->FillMap(fDetMap, "HSCIN") < 0 ) { @@ -116,22 +185,24 @@ Int_t THcHodoscope::ReadDatabase( const TDatime& date ) // Will need to determine which spectrometer in order to construct // the parameter names (e.g. hscin_1x_nr vs. sscin_1x_nr) + cout << "THcHodoscope::ReadDatabase called " << GetName() << endl; + fNPlanes = 4; // Hardwire for now - fNPaddle = new Int_t [4]; + fNPaddle = new Int_t [fNPlanes]; fNPaddle[0] = *(Int_t *)gHcParms->Find("hscin_1x_nr")->GetValuePointer(); fNPaddle[1] = *(Int_t *)gHcParms->Find("hscin_1y_nr")->GetValuePointer(); fNPaddle[2] = *(Int_t *)gHcParms->Find("hscin_2x_nr")->GetValuePointer(); fNPaddle[3] = *(Int_t *)gHcParms->Find("hscin_2y_nr")->GetValuePointer(); - fSpacing = new Double_t [4]; + fSpacing = new Double_t [fNPlanes]; fSpacing[0] = gHcParms->Find("hscin_1x_spacing")->GetValue(0); fSpacing[1] = gHcParms->Find("hscin_1y_spacing")->GetValue(0); fSpacing[2] = gHcParms->Find("hscin_2x_spacing")->GetValue(0); fSpacing[3] = gHcParms->Find("hscin_2y_spacing")->GetValue(0); - fCenter = new Double_t* [4]; + fCenter = new Double_t* [fNPlanes]; Double_t* p; Int_t iplane; @@ -186,11 +257,19 @@ Int_t THcHodoscope::DefineVariables( EMode mode ) { // Initialize global variables and lookup table for decoder + cout << "THcHodoscope::DefineVariables called " << GetName() << endl; + if( mode == kDefine && fIsSetup ) return kOK; fIsSetup = ( mode == kDefine ); // Register variables in global list + // RVarDef vars[] = { + // hpostdc1 HMS s1x+ TDC hits + // hnegtdc1 HMS s1x+ TDC hits + //... + // hnegtdc4 HMS s2y- TDC hits + // RVarDef vars[] = { // { "nlthit", "Number of Left paddles TDC times", "fLTNhit" }, // { "nrthit", "Number of Right paddles TDC times", "fRTNhit" }, @@ -279,11 +358,12 @@ void THcHodoscope::DeleteArrays() //_____________________________________________________________________________ inline -void THcHodoscope::ClearEvent() +void THcHodoscope::Clear( Option_t* opt) { // Reset per-event data. - - fTrackProj->Clear(); + for(Int_t ip=0;ip<fNPlanes;ip++) { + fPlanes[ip]->Clear(opt); + } } //_____________________________________________________________________________ @@ -293,7 +373,14 @@ Int_t THcHodoscope::Decode( const THaEvData& evdata ) // Get the Hall C style hitlist (fRawHitList) for this event Int_t nhits = THcHitList::DecodeToHitList(evdata); + // Let each plane get its hits + Int_t nexthit = 0; + for(Int_t ip=0;ip<fNPlanes;ip++) { + nexthit = fPlanes[ip]->ProcessHits(fRawHitList, nexthit); + } + // fRawHitList is TClones array of THcHodoscopeHit objects +#if 0 for(Int_t ihit = 0; ihit < fNRawHits ; ihit++) { THcHodoscopeHit* hit = (THcHodoscopeHit *) fRawHitList->At(ihit); cout << ihit << " : " << hit->fPlane << ":" << hit->fCounter << " : " @@ -301,6 +388,7 @@ Int_t THcHodoscope::Decode( const THaEvData& evdata ) << " " << hit->fTDC_neg << endl; } cout << endl; +#endif return nhits; } diff --git a/src/THcHodoscope.h b/src/THcHodoscope.h index 31760f5..e0937b8 100644 --- a/src/THcHodoscope.h +++ b/src/THcHodoscope.h @@ -3,7 +3,7 @@ /////////////////////////////////////////////////////////////////////////////// // // -// THcHodoscope // +// THcHodoscope // // // /////////////////////////////////////////////////////////////////////////////// @@ -11,6 +11,7 @@ #include "THaNonTrackingDetector.h" #include "THcHitList.h" #include "THcHodoscopeHit.h" +#include "THcScintillatorPlane.h" class THaScCalib; @@ -21,8 +22,10 @@ public: THaApparatus* a = NULL ); virtual ~THcHodoscope(); + virtual void Clear( Option_t* opt="" ); virtual Int_t Decode( const THaEvData& ); virtual EStatus Init( const TDatime& run_time ); + virtual Int_t CoarseProcess( TClonesArray& tracks ); virtual Int_t FineProcess( TClonesArray& tracks ); @@ -45,11 +48,12 @@ protected: // Potential Hall C parameters. Mostly here for demonstration Int_t fNPlanes; + char** fPlaneNames; Int_t* fNPaddle; // Number of paddles per plane Double_t* fSpacing; // Paddle spacing in cm Double_t** fCenter; // Center position of each paddle - + THcScintillatorPlane** fPlanes; // List of plane objects TClonesArray* fTrackProj; // projection of track onto scintillator plane // and estimated match to TOF paddle @@ -80,6 +84,8 @@ protected: virtual Double_t TimeWalkCorrection(const Int_t& paddle, const ESide side); + void Setup(const char* name, const char* description); + ClassDef(THcHodoscope,0) // Generic hodoscope class }; diff --git a/src/THcScintillatorPlane.cxx b/src/THcScintillatorPlane.cxx new file mode 100644 index 0000000..7353a92 --- /dev/null +++ b/src/THcScintillatorPlane.cxx @@ -0,0 +1,234 @@ +//*-- Author : + +////////////////////////////////////////////////////////////////////////// +// +// THcScintillatorPlane +// +////////////////////////////////////////////////////////////////////////// + +#include "THcScintillatorPlane.h" +#include "TClonesArray.h" +#include "THcSignalHit.h" +#include "THcGlobals.h" +#include "THcParmList.h" +#include "THcHitList.h" +#include "THcHodoscope.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); + 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 + + 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,"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. + + + // Find the number of elements + + // 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; + } + + if(hit->fTDC_pos > 0) { + THcSignalHit *sighit = (THcSignalHit*) fPosTDCHits->ConstructedAt(nPosTDCHits++); + sighit->Set(hit->fCounter, hit->fTDC_pos); + } + + if(hit->fTDC_neg > 0) { + THcSignalHit *sighit = (THcSignalHit*) fNegTDCHits->ConstructedAt(nNegTDCHits++); + sighit->Set(hit->fCounter, hit->fTDC_neg); + } + + if(hit->fADC_pos > 0) { + THcSignalHit *sighit = (THcSignalHit*) fPosADCHits->ConstructedAt(nPosADCHits++); + sighit->Set(hit->fCounter, hit->fADC_pos); + } + + if(hit->fADC_neg > 0) { + THcSignalHit *sighit = (THcSignalHit*) fNegADCHits->ConstructedAt(nNegADCHits++); + sighit->Set(hit->fCounter, hit->fADC_neg); + } + ihit++; + } + return(ihit); +} + + + + diff --git a/src/THcScintillatorPlane.h b/src/THcScintillatorPlane.h new file mode 100644 index 0000000..ad3f6cb --- /dev/null +++ b/src/THcScintillatorPlane.h @@ -0,0 +1,59 @@ +#ifndef ROOT_THcScintillatorPlane +#define ROOT_THcScintillatorPlane + +////////////////////////////////////////////////////////////////////////////// +// +// THcScintillatorPlane +// +// A Hall C scintillator plane +// +// May want to later inherit from a THcPlane class if there are similarities +// in what a plane is shared with other detector types (shower, etc.) +// +////////////////////////////////////////////////////////////////////////////// + +#include "THaSubDetector.h" +#include "TClonesArray.h" + +class THaEvData; +class THaSignalHit; + +class THcScintillatorPlane : public THaSubDetector { + + public: + THcScintillatorPlane( const char* name, const char* description, + Int_t planenum, THaDetectorBase* parent = NULL); + virtual ~THcScintillatorPlane(); + + virtual void Clear( Option_t* opt="" ); + virtual Int_t Decode( const THaEvData& ); + virtual EStatus Init( const TDatime& run_time ); + + virtual Int_t CoarseProcess( TClonesArray& tracks ); + virtual Int_t FineProcess( TClonesArray& tracks ); + Bool_t IsTracking() { return kFALSE; } + virtual Bool_t IsPid() { return kFALSE; } + + virtual Int_t ProcessHits(TClonesArray* rawhits, Int_t nexthit); + + Double_t fSpacing; + + TClonesArray* fParentHitList; + + protected: + + TClonesArray* fPosTDCHits; + TClonesArray* fNegTDCHits; + TClonesArray* fPosADCHits; + TClonesArray* fNegADCHits; + + Int_t fPlaneNum; + + virtual Int_t ReadDatabase( const TDatime& date ); + virtual Int_t DefineVariables( EMode mode = kDefine ); + + ClassDef(THcScintillatorPlane,0) +}; +#endif + + diff --git a/src/THcSignalHit.cxx b/src/THcSignalHit.cxx new file mode 100644 index 0000000..8400419 --- /dev/null +++ b/src/THcSignalHit.cxx @@ -0,0 +1,11 @@ +/////////////////////////////////////////////////////////////////////////////// +// // +// THcSignalHit // +// // +// Class representing a single signal value and its wire/paddle number // +// // +/////////////////////////////////////////////////////////////////////////////// + +#include "THcSignalHit.h" + +ClassImp(THcSignalHit) diff --git a/src/THcSignalHit.h b/src/THcSignalHit.h new file mode 100644 index 0000000..da9d27b --- /dev/null +++ b/src/THcSignalHit.h @@ -0,0 +1,33 @@ +#ifndef ROOT_THcSignalHit +#define ROOT_THcSignalHit + +///////////////////////////////////////////////////////////////////////////// +// // +// THcSignalHit // +// // +///////////////////////////////////////////////////////////////////////////// + +#include "TObject.h" +#include <cstdio> + +class THcSignalHit : public TObject { + + public: + THcSignalHit(Int_t paddle=0, Double_t data=0.0) : + fPaddleNumber(paddle), fData(data) {} + virtual ~THcSignalHit() {} + + Int_t GetPaddleNumber() {return fPaddleNumber;} + Double_t GetData() {return fData;} + + virtual void Set(Int_t paddle, Int_t data) + { fPaddleNumber=paddle; fData=data; } + + private: + Int_t fPaddleNumber; + Double_t fData; + + ClassDef(THcSignalHit,0) +}; +///////////////////////////////////////////////////////////////// +#endif -- GitLab