diff --git a/Makefile b/Makefile index 30f7d0f70bd512c0cbb3261ed6f01b3a8fe6ff4c..6fc33b4ce9637eb00322f162a4d98febd8204d88 100644 --- a/Makefile +++ b/Makefile @@ -8,8 +8,10 @@ # there must be a corresponding header file (*.h). -SRC = src/THcInterface.cxx src/THcParmList.cxx src/THcCrateMap.cxx \ - src/THcCodaDecoder.cxx +SRC = src/THcInterface.cxx src/THcParmList.cxx src/THcAnalyzer.cxx \ + src/THcHodoscopeHit.cxx src/THcRawHit.cxx \ + src/THcHitList.cxx src/THcDetectorMap.cxx src/THcHodoscope.cxx \ + src/THcHallCSpectrometer.cxx # Name of your package. # The shared library that will be built will get the name lib$(PACKAGE).so @@ -164,7 +166,7 @@ install: all cp -p $(USERLIB) $(HOME)/cue/SRC/ana clean: - rm -f *.o *~ $(USERLIB) $(USERDICT).* + rm -f src/*.o *~ $(USERLIB) $(USERDICT).* realclean: clean rm -f *.d diff --git a/podd b/podd index 9a47be4dc77822bd7af642d1b3ca962f09cf89f6..fe3e7463fe6e531dd790cf5ea103a368e4b17b7a 160000 --- a/podd +++ b/podd @@ -1 +1 @@ -Subproject commit 9a47be4dc77822bd7af642d1b3ca962f09cf89f6 +Subproject commit fe3e7463fe6e531dd790cf5ea103a368e4b17b7a diff --git a/src/HallC_LinkDef.h b/src/HallC_LinkDef.h index e6da1aaca6f3dfd7f6d1bdbbdb1b659f9fd66591..c743ba4415e2e4761787b7f6aa5e054b3b58963d 100644 --- a/src/HallC_LinkDef.h +++ b/src/HallC_LinkDef.h @@ -5,10 +5,16 @@ #pragma link off all functions; #pragma link C++ global gHcParms; +#pragma link C++ global gHcDetectorMap; #pragma link C++ class THcInterface+; #pragma link C++ class THcParmList+; -#pragma link C++ class THcCrateMap+; -#pragma link C++ class THcCodaDecoder+; +#pragma link C++ class THcAnalyzer+; +#pragma link C++ class THcRawHit+; +#pragma link C++ class THcHodoscopeHit+; +#pragma link C++ class THcHitList+; +#pragma link C++ class THcHodoscope+; +#pragma link C++ class THcDetectorMap+; +#pragma link C++ class THcHallCSpectrometer+; #endif diff --git a/src/THcAnalyzer.cxx b/src/THcAnalyzer.cxx new file mode 100644 index 0000000000000000000000000000000000000000..de063359287e3a9b2ff323dbf890aefe47cf0c32 --- /dev/null +++ b/src/THcAnalyzer.cxx @@ -0,0 +1,58 @@ +//*-- Author : Stephen Wood 13-March-2012 + +////////////////////////////////////////////////////////////////////////// +// +// THcAnalyzer +// +// THcAnalyzer is the base class for a "Hall C analyzer" class. +// An analyzer defines the basic actions to perform during analysis. +// THcAnalyzer is the default analyzer that is used if no user class is +// defined. It performs a standard analysis consisting of +// +// 1. Decoding/Calibrating +// 2. Track Reconstruction +// 3. Physics variable processing +// +// At the end of each step, testing and histogramming are done for +// the appropriate block defined in the global test/histogram lists. +// +// Hall C has their own analyzer class because some things are bound to +// be different. +// +////////////////////////////////////////////////////////////////////////// + +#include "THcAnalyzer.h" +#include "THaBenchmark.h" +#include "TList.h" + +#include <fstream> +#include <algorithm> +#include <iomanip> +#include <cstring> + +using namespace std; + + +// Pointer to single instance of this object +//THcAnalyzer* THcAnalyzer::fgAnalyzer = 0; + +//FIXME: +// do we need to "close" scalers/EPICS analysis if we reach the event limit? + +//_____________________________________________________________________________ +THcAnalyzer::THcAnalyzer() +{ + +} + +//_____________________________________________________________________________ +THcAnalyzer::~THcAnalyzer() +{ + // Destructor. + +} + +//_____________________________________________________________________________ + +ClassImp(THcAnalyzer) + diff --git a/src/THcAnalyzer.h b/src/THcAnalyzer.h new file mode 100644 index 0000000000000000000000000000000000000000..172d12560cea9e381cae9465e9209313b38c8b39 --- /dev/null +++ b/src/THcAnalyzer.h @@ -0,0 +1,29 @@ +#ifndef ROOT_THcAnalyzer +#define ROOT_THcAnalyzer + +////////////////////////////////////////////////////////////////////////// +// +// THcAnalyzer +// +////////////////////////////////////////////////////////////////////////// + +#include "THaAnalyzer.h" + +class THcAnalyzer : public THaAnalyzer { + +public: + + THcAnalyzer(); + virtual ~THcAnalyzer(); + +protected: + +private: + // THcAnalyzer( const THcAnalyzer& ); + // THcAnalyzer& operator=( const THcAnalyzer& ); + + ClassDef(THcAnalyzer,0) //Hall C Analyzer Standard Event Loop + +}; + +#endif diff --git a/src/THcCodaDecoder.cxx b/src/THcCodaDecoder.cxx deleted file mode 100644 index 2146945b9dd33b3f02cc23b098a90631bfbb4ee2..0000000000000000000000000000000000000000 --- a/src/THcCodaDecoder.cxx +++ /dev/null @@ -1,10 +0,0 @@ -// -// THcCodaDecoder -// -// author Stephen Wood (saw@jlab.org) - -#include "THcCodaDecoder.h" - -using namespace std; - -ClassImp(THcCodaDecoder) diff --git a/src/THcCodaDecoder.h b/src/THcCodaDecoder.h deleted file mode 100644 index d94d749e3f4c75ca8631942e68eced04aea9ff08..0000000000000000000000000000000000000000 --- a/src/THcCodaDecoder.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef THcCodaDecoder_ -#define THcCodaDecoder_ - -// Hall C version of decoder - -#include "THaCodaDecoder.h" - -class THcCodaDecoder : public THaCodaDecoder { - - public: - - private: - - protected: - ClassDef(THcCodaDecoder,0) // Hall C Coda Decoder - -}; -#endif - diff --git a/src/THcCrateMap.cxx b/src/THcCrateMap.cxx deleted file mode 100644 index 2546770da5da3f488f1dc536eb4c5148e6bb9002..0000000000000000000000000000000000000000 --- a/src/THcCrateMap.cxx +++ /dev/null @@ -1,46 +0,0 @@ -///////////////////////////////////////////////////////////////////// -// -// THcCrateMap -// Layout, or "map", of DAQ Crates. -// -// THaCrateMap contains info on how the DAQ crates -// are arranged in Hall A, i.e whether slots are -// fastbus or vme, what the module types are, and -// what header info to expect. Probably nobody needs -// to know about this except the author, and at present -// an object of this class is a private member of the decoder. -// -// author Robert Michaels (rom@jlab.org) -// author Stephen Wood (saw@jlab.org) -// -///////////////////////////////////////////////////////////////////// - - -#include "THcCrateMap.h" - -#include "TError.h" - -using namespace std; - -THcCrateMap::THcCrateMap( const char* db_filename ) -{ - // Need to do something different since we are going to read - // a Hall C style map file. - - // Construct uninitialized crate map. The argument is the name of - // the database file to use for initialization - - if( !db_filename || !*db_filename ) { - ::Warning( "THcCrateMap", "Undefined database file name, " - "using default \"db_cratemap.dat\"" ); - db_filename = "cratemap"; - } - // Why does this give an error? Can't I use a private - // member of the class I inherit from? - fMapfileName = db_filename; - -} - - - -ClassImp(THcCrateMap) diff --git a/src/THcCrateMap.h b/src/THcCrateMap.h deleted file mode 100644 index e286323d9f8a623fb5bee50a4eb6e7286b895c7c..0000000000000000000000000000000000000000 --- a/src/THcCrateMap.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef THcCrateMap_ -#define THcCrateMap_ - -///////////////////////////////////////////////////////////////////// -// -// THcCrateMap -// Layout, or "map", of DAQ Crates. -// -// Inheriting from THaCrateMap -// -// THcCrateMap contains info on how the DAQ crates -// are arranged in Hall A, i.e whether slots are -// fastbus or vme, what the module types are, and -// what header info to expect. Probably nobody needs -// to know about this except the author, and at present -// an object of this class is a private member of the decoder. -// -// author Robert Michaels (rom@jlab.org) -// author Stephen Wood (saw@jlab.org) -// -///////////////////////////////////////////////////////////////////// - - -#include "THaCrateMap.h" - -class THcCrateMap : public THaCrateMap { - - public: - - THcCrateMap( const char* db = "cratemap" ); // Construct uninitialized - - private: - - TString fMapfileName; - - protected: - ClassDef(THcCrateMap,0) // Crate map - - -}; -#endif diff --git a/src/THcDetectorMap.cxx b/src/THcDetectorMap.cxx new file mode 100644 index 0000000000000000000000000000000000000000..5a9214ffe6b7f2244e9fc1cce463e5de95ef81b4 --- /dev/null +++ b/src/THcDetectorMap.cxx @@ -0,0 +1,299 @@ +//*-- Author: Stephen Wood + +////////////////////////////////////////////////////////////////////////// +// +// THcDetectorMap +// +// Class to read and hold Hall C style detector map +// +// Will need method to retrieve all map entries for a given +// detector id. +// +// Not sure we will keep this class, but still need the parsing of the map file +// +////////////////////////////////////////////////////////////////////////// + +#include "THcDetectorMap.h" + +#include "TObjArray.h" +#include "TObjString.h" + +#include <iostream> +#include <fstream> +#include <cstdlib> + +using namespace std; + +ClassImp(THcDetectorMap) + +inline static bool IsComment( const string& s, string::size_type pos ) +{ + return ( pos != string::npos && pos < s.length() && + (s[pos] == '!') ); +} + +//_____________________________________________________________________________ +THcDetectorMap::THcDetectorMap() : fNchans(0) +{ +} + +//_____________________________________________________________________________ +THcDetectorMap::~THcDetectorMap() +{ +} + +bool THcDetectorMap::compare(const ChaninMod *first, const ChaninMod *second) { + // This one not used, but we get a link error if we don't include + // a compare method + return((first->channel < second->channel)? true: false); +} +struct Functor +{ + bool operator() (const THcDetectorMap::ChaninMod &first, const THcDetectorMap::ChaninMod &second) + { return((first.channel < second.channel)? true: false);} +}; +//_____________________________________________________________________________ +Int_t THcDetectorMap::FillMap(THaDetMap *detmap, const char *detectorname) +// Should probably return a status +{ + list<ModChanList>::iterator imod; + list<ChaninMod>::iterator ichan; + ChaninMod Achan; + ModChanList Amod; + + // Translate detector name into and ID + // For now just long if then else. Could get it from the comments + // at the beginning of the map file. + Int_t did; + if(strcasecmp(detectorname,"HDC")==0) { + did = 1; + } else if (strcasecmp(detectorname,"HSCIN")==0) { + did = 2; + } else if (strcasecmp(detectorname,"HCER")==0) { + did = 3; + } else if (strcasecmp(detectorname,"HCAL")==0) { + did = 4; + } else if (strcasecmp(detectorname,"HMISC")==0) { + did = 5; + } else if (strcasecmp(detectorname,"GMISC")==0) { + did = 6; + } else if (strcasecmp(detectorname,"HAERO")==0) { + did = 7; + } else { + did = 0; + } + // Start SHMS with S? What about SOS? + + mlist.clear(); + // cout << "fNchans=" << fNchans << endl; + for(Int_t ich=0;ich<fNchans;ich++) { + if(fTable[ich].did == did) { + Int_t roc=fTable[ich].roc; + Int_t slot=fTable[ich].slot; + Int_t model=fTable[ich].model; + // cout << "ROC=" << fTable[ich].roc << " SLOT=" << fTable[ich].slot + // << " CHANNEL=" << fTable[ich].channel << endl; + Achan.channel = fTable[ich].channel; + Achan.plane = fTable[ich].plane; + Achan.counter = fTable[ich].counter; + Achan.signal = fTable[ich].signal; + for(imod=mlist.begin(); imod!= mlist.end(); ++imod) { + if((*imod).roc == roc && (*imod).slot == slot) { + // cout << "Pushing chan " << Achan.channel << " to " << roc + // << " " << slot << endl; + (*imod).clist.push_back(Achan); + break; + } + } + if(imod == mlist.end()) { + Amod.roc = roc; + Amod.slot = slot; + Amod.model = model; + Amod.clist.clear(); + Amod.clist.push_back(Achan); + mlist.push_back(Amod); + // cout << "New module " << Achan.channel << " to " << roc + // << " " << slot << endl; + } + } + } + if(mlist.size() <= 0) { + return(-1); + } + Functor f; + for(imod=mlist.begin(); imod!= mlist.end(); ++imod) { + // cout << "Slot " << (*imod).slot << endl; + list<ChaninMod> *clistp = &((*imod).clist); + clistp->sort(f);//Sort by channel + } + // Copy the information to the Hall A style detector map + // grouping consecutive channels that are all the same plane + // and signal type + for(imod=mlist.begin(); imod!= mlist.end(); ++imod) { + UShort_t roc = (*imod).roc; + UShort_t slot = (*imod).slot; + UInt_t model=(*imod).model; + // cout << "Slot " << slot << endl; + list<ChaninMod> *clistp = &((*imod).clist); + Int_t first_chan = -1; + Int_t last_chan = -1; + Int_t last_plane = -1; + Int_t last_signal = -1; + Int_t first_counter = -1; + Int_t last_counter = -1; + for(ichan=clistp->begin(); ichan!=clistp->end(); ++ichan) { + Int_t this_chan = (*ichan).channel; + Int_t this_counter = (*ichan).counter; + Int_t this_signal = (*ichan).signal; + Int_t this_plane = (*ichan).plane; + if(last_chan+1!=this_chan || last_counter+1 != this_counter + || last_plane != this_plane || last_signal!=this_signal) { + if(last_chan >= 0) { + if(ichan != clistp->begin()) { + // cout << "AddModule " << slot << " " << first_chan << + // " " << last_chan << " " << first_counter << endl; + detmap->AddModule((UShort_t)roc, (UShort_t)slot, + (UShort_t)first_chan, (UShort_t)last_chan, + (UInt_t) first_counter, model, (Int_t) 0, + (Int_t) -1, (UInt_t)last_plane, (UInt_t)last_signal); + } + } + first_chan = this_chan; + first_counter = this_counter; + } + last_chan = this_chan; + last_counter = this_counter; + last_plane = this_plane; + last_signal = this_signal; + // cout << " Channel " << (*ichan).channel << " " << + // (*ichan).plane << " " << (*ichan).counter << endl; + } + detmap->AddModule((UShort_t)roc, (UShort_t)slot, + (UShort_t)first_chan, (UShort_t)last_chan, + (UInt_t) first_counter, model, (Int_t) 0, + (Int_t) -1, (UInt_t)last_plane, (UInt_t)last_signal); + } + + return(0); +} + +void THcDetectorMap::Load(const char *fname) +{ + static const char* const here = "THcDetectorMap::Load"; + static const char* const whtspc = " \t"; + + ifstream ifile; + + ifile.open(fname); + if(!ifile.is_open()) { + Error(here, "error opening detector map file %s",fname); + return; // Need a success/failure argument? + } + string line; + + Int_t roc=0; + Int_t nsubadd=0; + Int_t mask=0; + Int_t bsub=0; + Int_t detector=0; + Int_t slot=0; + Int_t model=0; + + fNchans = 0; + + string::size_type start, pos=0; + + char varname[100]; + + while(getline(ifile,line)) { + // BLank line or comment + if(line.empty() + || (start = line.find_first_not_of( whtspc )) == string::npos + || IsComment(line, start) ) + continue; + + // cout << "MAPA: " << line << endl; + + // Remove comment from line + while ((pos = line.find_first_of("!", pos+1)) != string::npos) { + if(IsComment(line, pos)) { + line.erase(pos); + break; + } + } + + // Get rid of all white space + while((pos=line.find_first_of(whtspc)) != string::npos) { + line.erase(pos,1); + } + + // cout << "MAPB: " << line << endl; + + // Decide if line is ROC/NSUBADD/MASK/BSUB/DETECTOR/SLOT = something + // or chan, plane, counter[, signal] + + + if((pos=line.find_first_of("=")) != string::npos) { // Setting parameter + strcpy(varname, (line.substr(0,pos)).c_str()); + Int_t valuestartpos = pos+1; + Int_t value = atoi(line.substr(valuestartpos).c_str()); + // Some if statements + if(strcasecmp(varname,"detector")==0) { + detector = value; + } else if (strcasecmp(varname,"roc")==0) { + roc = value; + } else if (strcasecmp(varname,"nsubadd")==0) { + nsubadd = value; + } else if (strcasecmp(varname,"mask")==0) { + mask = value; + } else if (strcasecmp(varname,"bsub")==0) { + bsub = value; + } else if (strcasecmp(varname,"slot")==0) { + slot = value; + } + if(nsubadd == 96) { + model = 1877; + } else if (nsubadd == 64) { + if(bsub == 16) { + model = 1872; + } else if(bsub == 17) { + model = 1881; + } else { + model = 0; + } + } else { + model = 0; + } + } else { // Assume channel definition + TString values(line.c_str()); + TObjArray *vararr = values.Tokenize(","); + Int_t nvals = vararr->GetLast()+1; + if(nvals<3 || nvals>4) { + if(nvals > 1) { // Silent for help, noecho, nodebug, override + cout << "Map file: Invalid value count: " << line << endl; + } + continue; + } + Int_t channel = ((TObjString*)vararr->At(0))->GetString().Atoi(); + Int_t plane = ((TObjString*)vararr->At(1))->GetString().Atoi(); + Int_t counter = ((TObjString*)vararr->At(2))->GetString().Atoi(); + Int_t signal = 0; + if(nvals==4) { + signal= ((TObjString*)vararr->At(3))->GetString().Atoi(); + } + + fTable[fNchans].roc=roc; + fTable[fNchans].slot=slot; + fTable[fNchans].channel=channel; + fTable[fNchans].did=detector; + fTable[fNchans].plane=plane; + fTable[fNchans].counter=counter; + fTable[fNchans].signal=signal; + fTable[fNchans].model=model; + + fNchans++; + } + } + +} + diff --git a/src/THcDetectorMap.h b/src/THcDetectorMap.h new file mode 100644 index 0000000000000000000000000000000000000000..d78df9035b79b3e6752ce97fc66759e4b96a8dc9 --- /dev/null +++ b/src/THcDetectorMap.h @@ -0,0 +1,61 @@ +#ifndef ROOT_THcDetectorMap +#define ROOT_THcDetectorMap + +////////////////////////////////////////////////////////////////////////// +// +// THcDetectorMap +// +////////////////////////////////////////////////////////////////////////// + +#include "TObject.h" +#include "THaDetMap.h" +#include <list> + +class THcDetectorMap : public TObject { + + public: + THcDetectorMap(); + virtual ~THcDetectorMap(); + + virtual void Load(const char *fname); + virtual Int_t FillMap(THaDetMap* detmap, const char* detectorname); + + Int_t fNchans; // Number of hardware channels + + struct Channel { // Mapping for one hardware channel + Int_t roc; + Int_t slot; + Int_t channel; + Int_t did; + Int_t plane; + Int_t counter; + Int_t signal; + Int_t model; + }; + Channel fTable[10000]; // Big ugly cache of the map file + + struct ChaninMod { + Int_t channel; + Int_t plane; + Int_t counter; + Int_t signal; + }; + struct ModChanList { + Int_t roc; + Int_t slot; + Int_t model; + std::list<ChaninMod> clist; + + }; + std::list<ModChanList> mlist; + + bool compare(const ChaninMod *first, const ChaninMod *second); + + protected: + + ClassDef(THcDetectorMap,0); +}; +#endif + + + diff --git a/src/THcGlobals.h b/src/THcGlobals.h index 39b40da8de54367c2f2ebeebb2337e34d6df90ad..c18bf53ac1c721bb8023bed65cbc4f9bd51abb54 100644 --- a/src/THcGlobals.h +++ b/src/THcGlobals.h @@ -6,8 +6,9 @@ #include "DllImport.h" #endif -// Global Analyzer variables. Defined in THaInterface implementation file. +// Global Analyzer variables. Defined in THcInterface implementation file. R__EXTERN class THcParmList* gHcParms; //List of global symbolic variables +R__EXTERN class THcDetectorMap* gHcDetectorMap; //Cached map file #endif diff --git a/src/THcHallCSpectrometer.cxx b/src/THcHallCSpectrometer.cxx new file mode 100644 index 0000000000000000000000000000000000000000..53c141cfde5b35821d78c79b122cc8f84557b82a --- /dev/null +++ b/src/THcHallCSpectrometer.cxx @@ -0,0 +1,239 @@ +//*-- Author : Stephen Wood 20-Apr-2012 + +////////////////////////////////////////////////////////////////////////// +// +// THcHallCSpectrometer +// +// A standard Hall C spectrometer. +// Contains no standard detectors, +// May add hodoscope +// +// The usual name of this object is either "H", "S", or "P" +// for HMS, SOS, or suPerHMS respectively +// +// Defines the functions FindVertices() and TrackCalc(), which are common +// to both the LeftHRS and the RightHRS. +// +// Special configurations of the HRS (e.g. more detectors, different +// detectors) can be supported in on e of three ways: +// +// 1. Use the AddDetector() method to include a new detector +// in this apparatus. The detector will be decoded properly, +// and its variables will be available for cuts and histograms. +// Its processing methods will also be called by the generic Reconstruct() +// algorithm implemented in THaSpectrometer::Reconstruct() and should +// be correctly handled if the detector class follows the standard +// interface design. +// +// 2. Write a derived class that creates the detector in the +// constructor. Write a new Reconstruct() method or extend the existing +// one if necessary. +// +// 3. Write a new class inheriting from THaSpectrometer, using this +// class as an example. This is appropriate if your HRS +// configuration has fewer or different detectors than the +// standard HRS. (It might not be sensible to provide a RemoveDetector() +// method since Reconstruct() relies on the presence of the +// standard detectors to some extent.) +// +// For timing calculations, S1 is treated as the scintillator at the +// 'reference distance', corresponding to the pathlength correction +// matrix. +// +////////////////////////////////////////////////////////////////////////// + +#include "THcHallCSpectrometer.h" +#include "THaTrackingDetector.h" +#include "THaTrack.h" +#include "THaTrackProj.h" +#include "THaTriggerTime.h" +#include "TMath.h" +#include "TList.h" + +#include "TList.h" +#include "TMath.h" + +#ifdef WITH_DEBUG +#include <iostream> +#endif + +using namespace std; + +//_____________________________________________________________________________ +THcHallCSpectrometer::THcHallCSpectrometer( const char* name, const char* description ) : + THaSpectrometer( name, description ) +{ + // Constructor. Defines the standard detectors for the HRS. + // AddDetector( new THaTriggerTime("trg","Trigger-based time offset")); + + //sc_ref = static_cast<THaScintillator*>(GetDetector("s1")); + + SetTrSorting(kFALSE); +} + +//_____________________________________________________________________________ +THcHallCSpectrometer::~THcHallCSpectrometer() +{ + // Destructor +} + +//_____________________________________________________________________________ +Bool_t THcHallCSpectrometer::SetTrSorting( Bool_t set ) +{ + if( set ) + fProperties |= kSortTracks; + else + fProperties &= ~kSortTracks; + + return set; +} + +//_____________________________________________________________________________ +Bool_t THcHallCSpectrometer::GetTrSorting() const +{ + return ((fProperties & kSortTracks) != 0); +} + +//_____________________________________________________________________________ +Int_t THcHallCSpectrometer::FindVertices( TClonesArray& tracks ) +{ + // Reconstruct target coordinates for all tracks found in the focal plane. + + TIter nextTrack( fTrackingDetectors ); + + nextTrack.Reset(); + while( THaTrackingDetector* theTrackDetector = + static_cast<THaTrackingDetector*>( nextTrack() )) { +#ifdef WITH_DEBUG + if( fDebug>1 ) cout << "Call FineTrack() for " + << theTrackDetector->GetName() << "... "; +#endif + theTrackDetector->FindVertices( tracks ); +#ifdef WITH_DEBUG + if( fDebug>1 ) cout << "done.\n"; +#endif + } + + // If enabled, sort the tracks by chi2/ndof + if( GetTrSorting() ) + fTracks->Sort(); + + // Find the "Golden Track". + if( GetNTracks() > 0 ) { + // Select first track in the array. If there is more than one track + // and track sorting is enabled, then this is the best fit track + // (smallest chi2/ndof). Otherwise, it is the track with the best + // geometrical match (smallest residuals) between the U/V clusters + // in the upper and lower VDCs (old behavior). + // + // Chi2/dof is a well-defined quantity, and the track selected in this + // way is immediately physically meaningful. The geometrical match + // criterion is mathematically less well defined and not usually used + // in track reconstruction. Hence, chi2 sortiing is preferable, albeit + // obviously slower. + + fGoldenTrack = static_cast<THaTrack*>( fTracks->At(0) ); + fTrkIfo = *fGoldenTrack; + fTrk = fGoldenTrack; + } else + fGoldenTrack = NULL; + + return 0; +} + +//_____________________________________________________________________________ +Int_t THcHallCSpectrometer::TrackCalc() +{ + // Additioal track calculations. At present, we only calculate beta here. + + return TrackTimes( fTracks ); +} + +//_____________________________________________________________________________ +Int_t THcHallCSpectrometer::TrackTimes( TClonesArray* Tracks ) { + // Do the actual track-timing (beta) calculation. + // Use multiple scintillators to average together and get "best" time at S1. + // + // To be useful, a meaningful timing resolution should be assigned + // to each Scintillator object (part of the database). + + if ( !Tracks ) return -1; + + THaTrack *track=0; + Int_t ntrack = GetNTracks(); + + // linear regression to: t = t0 + pathl/(beta*c) + // where t0 is the time of the track at the reference plane (sc_ref). + // t0 and beta are solved for. + // +#if 0 + for ( Int_t i=0; i < ntrack; i++ ) { + track = static_cast<THaTrack*>(Tracks->At(i)); + THaTrackProj* tr_ref = static_cast<THaTrackProj*> + (sc_ref->GetTrackHits()->At(i)); + + Double_t pathlref = tr_ref->GetPathLen(); + + Double_t wgt_sum=0.,wx2=0.,wx=0.,wxy=0.,wy=0.; + Int_t ncnt=0; + + // linear regression to get beta and time at ref. + TIter nextSc( fNonTrackingDetectors ); + THaNonTrackingDetector *det; + while ( ( det = static_cast<THaNonTrackingDetector*>(nextSc()) ) ) { + THaScintillator *sc = dynamic_cast<THaScintillator*>(det); + if ( !sc ) continue; + + const THaTrackProj *trh = static_cast<THaTrackProj*>(sc->GetTrackHits()->At(i)); + + Int_t pad = trh->GetChannel(); + if (pad<0) continue; + Double_t pathl = (trh->GetPathLen()-pathlref); + Double_t time = (sc->GetTimes())[pad]; + Double_t wgt = (sc->GetTuncer())[pad]; + + if (pathl>.5*kBig || time>.5*kBig) continue; + if (wgt>0) wgt = 1./(wgt*wgt); + else continue; + + wgt_sum += wgt; + wx2 += wgt*pathl*pathl; + wx += wgt*pathl; + wxy += wgt*pathl*time; + wy += wgt*time; + ncnt++; + } + + Double_t beta = kBig; + Double_t dbeta = kBig; + Double_t time = kBig; + Double_t dt = kBig; + + Double_t delta = wgt_sum*wx2-wx*wx; + + if (delta != 0.) { + time = (wx2*wy-wx*wxy)/delta; + dt = TMath::Sqrt(wx2/delta); + Double_t invbeta = (wgt_sum*wxy-wx*wy)/delta; + if (invbeta != 0.) { +#if ROOT_VERSION_CODE >= ROOT_VERSION(3,4,0) + Double_t c = TMath::C(); +#else + Double_t c = 2.99792458e8; +#endif + beta = 1./(c*invbeta); + dbeta = TMath::Sqrt(wgt_sum/delta)/(c*invbeta*invbeta); + } + } + + track->SetBeta(beta); + track->SetdBeta(dbeta); + track->SetTime(time); + track->SetdTime(dt); + } +#endif + return 0; +} + +//_____________________________________________________________________________ +ClassImp(THcHallCSpectrometer) diff --git a/src/THcHallCSpectrometer.h b/src/THcHallCSpectrometer.h new file mode 100644 index 0000000000000000000000000000000000000000..f560bbff1dba69b8887ebcee648add6c155bfd2e --- /dev/null +++ b/src/THcHallCSpectrometer.h @@ -0,0 +1,37 @@ +#ifndef ROOT_THcHallCSpectrometer +#define ROOT_THcHallCSpectrometer + +////////////////////////////////////////////////////////////////////////// +// +// THcHallCSpectrometer +// +////////////////////////////////////////////////////////////////////////// + +#include "THaSpectrometer.h" + +//class THaScintillator; + +class THcHallCSpectrometer : public THaSpectrometer { + +public: + THcHallCSpectrometer( const char* name, const char* description ); + virtual ~THcHallCSpectrometer(); + + virtual Int_t FindVertices( TClonesArray& tracks ); + virtual Int_t TrackCalc(); + virtual Int_t TrackTimes( TClonesArray* tracks ); + + Bool_t SetTrSorting( Bool_t set = kFALSE ); + Bool_t GetTrSorting() const; + +protected: + // THaScintillator *sc_ref; // calculate time track hits this plane + + // Flag for fProperties indicating that tracks are to be sorted by chi2 + static const UInt_t kSortTracks = BIT(16); + + ClassDef(THcHallCSpectrometer,0) //A Hall A High Resolution Spectrometer +}; + +#endif + diff --git a/src/THcHitList.cxx b/src/THcHitList.cxx new file mode 100644 index 0000000000000000000000000000000000000000..9a1303b7c9e7a314f3612548d487d78502367db3 --- /dev/null +++ b/src/THcHitList.cxx @@ -0,0 +1,102 @@ +//*-- Author : Stephen Wood 30-March-2012 + +////////////////////////////////////////////////////////////////////////// +// +// THcHitList +// +// Add hitlist to the Hall A detector base +// May not need to inherit from THaDetectorBase since we may end up +// replacing most of the methods +// +////////////////////////////////////////////////////////////////////////// + +#include "THcHitList.h" + +using namespace std; + +THcHitList::THcHitList() +{ + // Normal constructor. + + fRawHitList = NULL; + +} + +THcHitList::~THcHitList() { + // Destructor +} + +void THcHitList::InitHitList(THaDetMap* detmap, + const char *hitclass, Int_t maxhits) { + // Probably called by ReadDatabase + + fRawHitList = new TClonesArray(hitclass, maxhits); + fRawHitClass = fRawHitList->GetClass(); + fNMaxRawHits = maxhits; + fNRawHits = 0; + for(Int_t i=0;i<maxhits;i++) { + fRawHitList->ConstructedAt(i); + } + + fdMap = detmap; +} + +Int_t THcHitList::DecodeToHitList( const THaEvData& evdata ) { + THcRawHit* rawhit; + // cout << " Clearing TClonesArray " << endl; + fRawHitList->Clear("C"); + fNRawHits = 0; + + for ( Int_t i=0; i < fdMap->GetSize(); i++ ) { + THaDetMap::Module* d = fdMap->GetModule(i); + + // Loop over all channels that have a hit. + // cout << "Crate/Slot: " << d->crate << "/" << d->slot << endl; + for ( Int_t j=0; j < evdata.GetNumChan( d->crate, d->slot); j++) { + + Int_t chan = evdata.GetNextChan( d->crate, d->slot, j ); + if( chan < d->lo || chan > d->hi ) continue; // Not one of my channels + + // Need to convert crate, slot, chan into plane, counter, signal + // Search hitlist for this plane,counter,signal + Int_t plane = d->plane; + Int_t signal = d->signal; + Int_t counter = d->reverse ? d->first + d->hi - chan : d->first + chan - d->lo; + //cout << d->crate << " " << d->slot << " " << chan << " " << plane << " " + // << counter << " " << signal << endl; + // Search hit list for plane and counter + // We could do sorting + Int_t thishit = 0; + while(thishit < fNRawHits) { + rawhit = (THcRawHit*) (*fRawHitList)[thishit]; + if (plane == rawhit->fPlane + && counter == rawhit->fCounter) { + // cout << "Found as " << thishit << "/" << fNRawHits << endl; + break; + } + thishit++; + } + + if(thishit == fNRawHits) { + rawhit = (THcRawHit*) (*fRawHitList)[thishit]; + fNRawHits++; + rawhit->fPlane = plane; + rawhit->fCounter = counter; + } + + // Get the data from this channel + // Allow for multiple hits + Int_t nMHits = evdata.GetNumHits(d->crate, d->slot, chan); + for (Int_t mhit = 0; mhit < nMHits; mhit++) { + Int_t data = evdata.GetData( d->crate, d->slot, chan, mhit); + // cout << "Signal " << signal << "=" << data << endl; + rawhit->SetData(signal,data); + } + } + } + fRawHitList->Sort(fNRawHits); + + return fNRawHits; // Does anything care what is returned +} + +ClassImp(THcHitList) diff --git a/src/THcHitList.h b/src/THcHitList.h new file mode 100644 index 0000000000000000000000000000000000000000..be90264a614912a2c85122ea76367863040ce356 --- /dev/null +++ b/src/THcHitList.h @@ -0,0 +1,48 @@ +#ifndef ROOT_THcHitList +#define ROOT_THcHitList + +#include "THcRawHit.h" +#include "THaDetMap.h" +#include "THaEvData.h" +#include "TClonesArray.h" +#include "TObject.h" + + +using namespace std; + +////////////////////////////////////////////////////////////////////////// +// +// THcHitList +// +////////////////////////////////////////////////////////////////////////// + +//class THaDetMap; + +class THcHitList { + + public: + + virtual ~THcHitList(); + + THcHitList(); + + virtual Int_t DecodeToHitList( const THaEvData& ); + 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. + // + Int_t fNRawHits; + Int_t fNMaxRawHits; + TClonesArray* fRawHitList; // List of raw hits + TClass* fRawHitClass; // Class of raw hit object to use + + THaDetMap* fdMap; + + protected: + + ClassDef(THcHitList,0) +}; +#endif diff --git a/src/THcHodoscope.cxx b/src/THcHodoscope.cxx new file mode 100644 index 0000000000000000000000000000000000000000..ede928973ca182ae81a02979ab4a6037f0b33bd5 --- /dev/null +++ b/src/THcHodoscope.cxx @@ -0,0 +1,353 @@ +/////////////////////////////////////////////////////////////////////////////// +// // +// THcHodoscope // +// // +// Class for a generic hodoscope consisting of multiple // +// planes with multiple paddles with phototubes on both ends. // +// This differs from Hall A scintillator class in that it is the whole // +// hodoscope array, not just one plane. // +// // +/////////////////////////////////////////////////////////////////////////////// + +#include "THcHodoscope.h" +#include "THaEvData.h" +#include "THaDetMap.h" +#include "THcDetectorMap.h" +#include "THcGlobals.h" +#include "THcParmList.h" +#include "VarDef.h" +#include "VarType.h" +#include "THaTrack.h" +#include "TClonesArray.h" +#include "TMath.h" + +#include "THaTrackProj.h" + +#include <cstring> +#include <cstdio> +#include <cstdlib> +#include <iostream> + +using namespace std; + +//_____________________________________________________________________________ +THcHodoscope::THcHodoscope( const char* name, const char* description, + THaApparatus* apparatus ) : + THaNonTrackingDetector(name,description,apparatus) +{ + // Constructor + + fTrackProj = new TClonesArray( "THaTrackProj", 5 ); +} + +//_____________________________________________________________________________ +THcHodoscope::THcHodoscope( ) : + THaNonTrackingDetector() +{ + // Constructor +} + +//_____________________________________________________________________________ +THaAnalysisObject::EStatus THcHodoscope::Init( const TDatime& date ) +{ + static const char* const here = "Init()"; + + if( THaNonTrackingDetector::Init( date ) ) + return fStatus; + + // Replace with what we need for Hall C + // const DataDest tmp[NDEST] = { + // { &fRTNhit, &fRANhit, fRT, fRT_c, fRA, fRA_p, fRA_c, fROff, fRPed, fRGain }, + // { &fLTNhit, &fLANhit, fLT, fLT_c, fLA, fLA_p, fLA_c, fLOff, fLPed, fLGain } + // }; + // 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 ) { + Error( Here(here), "Error filling detectormap for %s.", + "detectorname"); + return kInitError; + } + + return fStatus = kOK; +} + +//_____________________________________________________________________________ +Int_t THcHodoscope::ReadDatabase( const TDatime& date ) +{ + // Read this detector's parameters from the database file 'fi'. + // This function is called by THaDetectorBase::Init() once at the + // beginning of the analysis. + // 'date' contains the date/time of the run being analyzed. + + // static const char* const here = "ReadDatabase()"; + + // Read data from database + // Pull values from the THcParmList instead of reading a database + // file like Hall A does. + + // DBRequest list[] = { + // { "TDC_offsetsL", fLOff, kDouble, fNelem }, + // { "TDC_offsetsR", fROff, kDouble, fNelem }, + // { "ADC_pedsL", fLPed, kDouble, fNelem }, + // { "ADC_pedsR", fRPed, kDouble, fNelem }, + // { "ADC_coefL", fLGain, kDouble, fNelem }, + // { "ADC_coefR", fRGain, kDouble, fNelem }, + // { "TDC_res", &fTdc2T }, + // { "TransSpd", &fCn }, + // { "AdcMIP", &fAdcMIP }, + // { "NTWalk", &fNTWalkPar, kInt }, + // { "Timewalk", fTWalkPar, kDouble, 2*fNelem }, + // { "ReTimeOff", fTrigOff, kDouble, fNelem }, + // { "AvgRes", &fResolution }, + // { "Atten", &fAttenuation }, + // { 0 } + // }; + + // We will probably want to add some kind of method to gHcParms to allow + // bulk retrieval of parameters of interest. + + // Will need to determine which spectrometer in order to construct + // the parameter names (e.g. hscin_1x_nr vs. sscin_1x_nr) + + fNPlanes = 4; // Hardwire for now + + fNPaddle = new Int_t [4]; + + 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[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]; + Double_t* p; + Int_t iplane; + + iplane = 0; + p = (Double_t *)gHcParms->Find("hscin_1x_center")->GetValuePointer(); + fCenter[iplane] = new Double_t [fNPaddle[iplane]]; + // Print out some parameters just to demonstrate that it works + cout << iplane; + for(Int_t i=0;i<fNPaddle[iplane];i++) { + fCenter[iplane][i] = p[i]; + cout << " " << fCenter[iplane][i]; + } + cout << endl; + + iplane = 1; + p = (Double_t *)gHcParms->Find("hscin_1y_center")->GetValuePointer(); + fCenter[iplane] = new Double_t [fNPaddle[iplane]]; + cout << iplane; + for(Int_t i=0;i<fNPaddle[iplane];i++) { + fCenter[iplane][i] = p[i]; + cout << " " << fCenter[iplane][i]; + } + cout << endl; + + iplane = 2; + p = (Double_t *)gHcParms->Find("hscin_2x_center")->GetValuePointer(); + fCenter[iplane] = new Double_t [fNPaddle[iplane]]; + cout << iplane; + for(Int_t i=0;i<fNPaddle[iplane];i++) { + fCenter[iplane][i] = p[i]; + cout << " " << fCenter[iplane][i]; + } + cout << endl; + + iplane = 3; + p = (Double_t *)gHcParms->Find("hscin_2y_center")->GetValuePointer(); + fCenter[iplane] = new Double_t [fNPaddle[iplane]]; + cout << iplane; + for(Int_t i=0;i<fNPaddle[iplane];i++) { + fCenter[iplane][i] = p[i]; + cout << " " << fCenter[iplane][i]; + } + cout << endl; + + fIsInit = true; + + return kOK; +} + +//_____________________________________________________________________________ +Int_t THcHodoscope::DefineVariables( EMode mode ) +{ + // Initialize global variables and lookup table for decoder + + if( mode == kDefine && fIsSetup ) return kOK; + fIsSetup = ( mode == kDefine ); + + // Register variables in global list + + // RVarDef vars[] = { + // { "nlthit", "Number of Left paddles TDC times", "fLTNhit" }, + // { "nrthit", "Number of Right paddles TDC times", "fRTNhit" }, + // { "nlahit", "Number of Left paddles ADCs amps", "fLANhit" }, + // { "nrahit", "Number of Right paddles ADCs amps", "fRANhit" }, + // { "lt", "TDC values left side", "fLT" }, + // { "lt_c", "Corrected times left side", "fLT_c" }, + // { "rt", "TDC values right side", "fRT" }, + // { "rt_c", "Corrected times right side", "fRT_c" }, + // { "la", "ADC values left side", "fLA" }, + // { "la_p", "Corrected ADC values left side", "fLA_p" }, + // { "la_c", "Corrected ADC values left side", "fLA_c" }, + // { "ra", "ADC values right side", "fRA" }, + // { "ra_p", "Corrected ADC values right side", "fRA_p" }, + // { "ra_c", "Corrected ADC values right side", "fRA_c" }, + // { "nthit", "Number of paddles with l&r TDCs", "fNhit" }, + // { "t_pads", "Paddles with l&r coincidence TDCs", "fHitPad" }, + // { "y_t", "y-position from timing (m)", "fYt" }, + // { "y_adc", "y-position from amplitudes (m)", "fYa" }, + // { "time", "Time of hit at plane (s)", "fTime" }, + // { "dtime", "Est. uncertainty of time (s)", "fdTime" }, + // { "dedx", "dEdX-like deposited in paddle", "fAmpl" }, + // { "troff", "Trigger offset for paddles", "fTrigOff"}, + // { "trn", "Number of tracks for hits", "GetNTracks()" }, + // { "trx", "x-position of track in det plane", "fTrackProj.THaTrackProj.fX" }, + // { "try", "y-position of track in det plane", "fTrackProj.THaTrackProj.fY" }, + // { "trpath", "TRCS pathlen of track to det plane","fTrackProj.THaTrackProj.fPathl" }, + // { "trdx", "track deviation in x-position (m)", "fTrackProj.THaTrackProj.fdX" }, + // { "trpad", "paddle-hit associated with track", "fTrackProj.THaTrackProj.fChannel" }, + // { 0 } + // }; + // return DefineVarsFromList( vars, mode ); + return kOK; +} + +//_____________________________________________________________________________ +THcHodoscope::~THcHodoscope() +{ + // Destructor. Remove variables from global list. + + if( fIsSetup ) + RemoveVariables(); + if( fIsInit ) + DeleteArrays(); + if (fTrackProj) { + fTrackProj->Clear(); + delete fTrackProj; fTrackProj = 0; + } +} + +//_____________________________________________________________________________ +void THcHodoscope::DeleteArrays() +{ + // Delete member arrays. Used by destructor. + + delete [] fNPaddle; fNPaddle = NULL; + delete [] fSpacing; fSpacing = NULL; + delete [] fCenter; fCenter = NULL; // This 2D. What is correct way to delete? + + // delete [] fRA_c; fRA_c = NULL; + // delete [] fRA_p; fRA_p = NULL; + // delete [] fRA; fRA = NULL; + // delete [] fLA_c; fLA_c = NULL; + // delete [] fLA_p; fLA_p = NULL; + // delete [] fLA; fLA = NULL; + // delete [] fRT_c; fRT_c = NULL; + // delete [] fRT; fRT = NULL; + // delete [] fLT_c; fLT_c = NULL; + // delete [] fLT; fLT = NULL; + + // delete [] fRGain; fRGain = NULL; + // delete [] fLGain; fLGain = NULL; + // delete [] fRPed; fRPed = NULL; + // delete [] fLPed; fLPed = NULL; + // delete [] fROff; fROff = NULL; + // delete [] fLOff; fLOff = NULL; + // delete [] fTWalkPar; fTWalkPar = NULL; + // delete [] fTrigOff; fTrigOff = NULL; + + // delete [] fHitPad; fHitPad = NULL; + // delete [] fTime; fTime = NULL; + // delete [] fdTime; fdTime = NULL; + // delete [] fYt; fYt = NULL; + // delete [] fYa; fYa = NULL; +} + +//_____________________________________________________________________________ +inline +void THcHodoscope::ClearEvent() +{ + // Reset per-event data. + + fTrackProj->Clear(); +} + +//_____________________________________________________________________________ +Int_t THcHodoscope::Decode( const THaEvData& evdata ) +{ + + // Get the Hall C style hitlist (fRawHitList) for this event + Int_t nhits = THcHitList::DecodeToHitList(evdata); + + // fRawHitList is TClones array of THcHodoscopeHit objects + for(Int_t ihit = 0; ihit < fNRawHits ; ihit++) { + THcHodoscopeHit* hit = (THcHodoscopeHit *) fRawHitList->At(ihit); + cout << ihit << " : " << hit->fPlane << ":" << hit->fCounter << " : " + << hit->fADC_pos << " " << hit->fADC_neg << " " << hit->fTDC_pos + << " " << hit->fTDC_neg << endl; + } + cout << endl; + + return nhits; +} + +//_____________________________________________________________________________ +Int_t THcHodoscope::ApplyCorrections( void ) +{ + return(0); +} + +//_____________________________________________________________________________ +Double_t THcHodoscope::TimeWalkCorrection(const Int_t& paddle, + const ESide side) +{ + return(0.0); +} + +//_____________________________________________________________________________ +Int_t THcHodoscope::CoarseProcess( TClonesArray& /* tracks */ ) +{ + // Calculation of coordinates of particle track cross point with scint + // plane in the detector coordinate system. For this, parameters of track + // reconstructed in THaVDC::CoarseTrack() are used. + // + // Apply corrections and reconstruct the complete hits. + // + // static const Double_t sqrt2 = TMath::Sqrt(2.); + + ApplyCorrections(); + + return 0; +} + +//_____________________________________________________________________________ +Int_t THcHodoscope::FineProcess( TClonesArray& tracks ) +{ + // Reconstruct coordinates of particle track cross point with scintillator + // plane, and copy the data into the following local data structure: + // + // Units of measurements are meters. + + // Calculation of coordinates of particle track cross point with scint + // plane in the detector coordinate system. For this, parameters of track + // reconstructed in THaVDC::FineTrack() are used. + + return 0; +} + +ClassImp(THcHodoscope) +//////////////////////////////////////////////////////////////////////////////// diff --git a/src/THcHodoscope.h b/src/THcHodoscope.h new file mode 100644 index 0000000000000000000000000000000000000000..31760f5a7797e9ff59e7cf35aec04ebb5b199216 --- /dev/null +++ b/src/THcHodoscope.h @@ -0,0 +1,88 @@ +#ifndef ROOT_THcHodoscope +#define ROOT_THcHodoscope + +/////////////////////////////////////////////////////////////////////////////// +// // +// THcHodoscope // +// // +/////////////////////////////////////////////////////////////////////////////// + +#include "TClonesArray.h" +#include "THaNonTrackingDetector.h" +#include "THcHitList.h" +#include "THcHodoscopeHit.h" + +class THaScCalib; + +class THcHodoscope : public THaNonTrackingDetector, public THcHitList { + +public: + THcHodoscope( const char* name, const char* description = "", + THaApparatus* a = NULL ); + virtual ~THcHodoscope(); + + 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 ); + + virtual Int_t ApplyCorrections( void ); + + // Int_t GetNHits() const { return fNhit; } + + Int_t GetNTracks() const { return fTrackProj->GetLast()+1; } + const TClonesArray* GetTrackHits() const { return fTrackProj; } + + friend class THaScCalib; + + THcHodoscope(); // for ROOT I/O +protected: + + // Calibration + + // Per-event data + + + // Potential Hall C parameters. Mostly here for demonstration + Int_t fNPlanes; + Int_t* fNPaddle; // Number of paddles per plane + Double_t* fSpacing; // Paddle spacing in cm + Double_t** fCenter; // Center position of each paddle + + + + TClonesArray* fTrackProj; // projection of track onto scintillator plane + // and estimated match to TOF paddle + // Useful derived quantities + // double tan_angle, sin_angle, cos_angle; + + // static const char NDEST = 2; + // struct DataDest { + // Int_t* nthit; + // Int_t* nahit; + // Double_t* tdc; + // Double_t* tdc_c; + // Double_t* adc; + // Double_t* adc_p; + // Double_t* adc_c; + // Double_t* offset; + // Double_t* ped; + // Double_t* gain; + // } fDataDest[NDEST]; // Lookup table for decoder + + void ClearEvent(); + void DeleteArrays(); + virtual Int_t ReadDatabase( const TDatime& date ); + virtual Int_t DefineVariables( EMode mode = kDefine ); + + enum ESide { kLeft = 0, kRight = 1 }; + + virtual Double_t TimeWalkCorrection(const Int_t& paddle, + const ESide side); + + ClassDef(THcHodoscope,0) // Generic hodoscope class +}; + +//////////////////////////////////////////////////////////////////////////////// + +#endif diff --git a/src/THcHodoscopeHit.cxx b/src/THcHodoscopeHit.cxx new file mode 100644 index 0000000000000000000000000000000000000000..1a34c8bc8081f7925fe3ae026400cd1069a4fbd1 --- /dev/null +++ b/src/THcHodoscopeHit.cxx @@ -0,0 +1,80 @@ +/////////////////////////////////////////////////////////////////////////////// +// // +// THcHodoscopeHit // +// // +// Class representing a single raw hit for a hodoscope paddle // +// // +// Contains plane, counter and pos/neg adc and tdc values // +// // +/////////////////////////////////////////////////////////////////////////////// + +#include "THcHodoscopeHit.h" + +using namespace std; + + +void THcHodoscopeHit::SetData(Int_t signal, Int_t data) { + if(signal==0) { + fADC_pos = data; + } else if (signal==1) { + fADC_neg = data; + } else if(signal==2) { + fTDC_pos = data; + } else if (signal==3) { + fTDC_neg = data; + } +} + +Int_t THcHodoscopeHit::GetData(Int_t signal) { + if(signal==0) { + return(fADC_pos); + } else if (signal==1) { + return(fADC_neg); + } else if(signal==2) { + return(fTDC_pos); + } else if (signal==3) { + return(fTDC_neg); + } + return(-1); // Actually should throw exception +} + +Int_t THcHodoscopeHit::Compare(const TObject* obj) const +{ + // Compare to sort by plane and counter + + const THcHodoscopeHit* hit = dynamic_cast<const THcHodoscopeHit*>(obj); + + if(!hit) return -1; + Int_t p1 = fPlane; + Int_t p2 = hit->fPlane; + if(p1 < p2) return -1; + else if(p1 > p2) return 1; + else { + Int_t c1 = fCounter; + Int_t c2 = hit->fCounter; + if(c1 < c2) return -1; + else if (c1 == c2) return 0; + else return 1; + } +} +//_____________________________________________________________________________ +THcHodoscopeHit& THcHodoscopeHit::operator=( const THcHodoscopeHit& rhs ) +{ + // Assignment operator. + + THcRawHit::operator=(rhs); + if ( this != &rhs ) { + fPlane = rhs.fPlane; + fCounter = rhs.fCounter; + fADC_pos = rhs.fADC_pos; + fADC_neg = rhs.fADC_neg; + fTDC_pos = rhs.fTDC_pos; + fTDC_neg = rhs.fTDC_neg; + } + return *this; +} + + +////////////////////////////////////////////////////////////////////////// +ClassImp(THcHodoscopeHit) + diff --git a/src/THcHodoscopeHit.h b/src/THcHodoscopeHit.h new file mode 100644 index 0000000000000000000000000000000000000000..f8ce97b90c29cf7dc7ebda5018dd8b1029261fc0 --- /dev/null +++ b/src/THcHodoscopeHit.h @@ -0,0 +1,38 @@ +#ifndef ROOT_THcHodoscopeHit +#define ROOT_THcHodoscopeHit + +#include "THcRawHit.h" + +class THcHodoscopeHit : public THcRawHit { + + public: + + THcHodoscopeHit(Int_t plane=0, Int_t counter=0) : THcRawHit(plane, counter), + fADC_pos(-1), fADC_neg(-1), + fTDC_pos(-1), fTDC_neg(-1) { + } + THcHodoscopeHit& operator=( const THcHodoscopeHit& ); + virtual ~THcHodoscopeHit() {} + + virtual void Clear( Option_t* opt="" ) + { fADC_pos = -1; fADC_neg = -1; fTDC_pos = -1; fTDC_neg = -1; } + + void SetData(Int_t signal, Int_t data); + Int_t GetData(Int_t signal); + + virtual Bool_t IsSortable () const {return kTRUE; } + virtual Int_t Compare(const TObject* obj) const; + + Int_t fADC_pos; + Int_t fADC_neg; + Int_t fTDC_pos; + Int_t fTDC_neg; + + protected: + + private: + + ClassDef(THcHodoscopeHit, 0); // Hodoscope hit class +}; + +#endif diff --git a/src/THcInterface.cxx b/src/THcInterface.cxx index 023c2ab0e40a5efcd293c0bea3f2729955221fac..887c578e365631a327e1fcc1ad3b40faf65f01f9 100644 --- a/src/THcInterface.cxx +++ b/src/THcInterface.cxx @@ -20,6 +20,7 @@ #include "TInterpreter.h" #include "THaVarList.h" #include "THcParmList.h" +#include "THcDetectorMap.h" #include "THaCutList.h" #include "THaCodaDecoder.h" #include "THaGlobals.h" @@ -48,6 +49,7 @@ THaDB* gHaDB = NULL; // Database system to use THaTextvars* gHaTextvars = NULL; // Text variable definitions THcParmList* gHcParms = NULL; // List of symbolic analyzer variables +THcDetectorMap* gHcDetectorMap = NULL; // Global (Hall C style) detector map THcInterface* THcInterface::fgAint = NULL; // Pointer to this interface @@ -161,6 +163,7 @@ THcInterface::~THcInterface() delete gHaCuts; gHaCuts=0; delete gHcParms; gHcParms=0; + delete gHcDetectorMap; gHcDetectorMap=0; fgAint = NULL; } diff --git a/src/THcRawHit.cxx b/src/THcRawHit.cxx new file mode 100644 index 0000000000000000000000000000000000000000..daa513848a9fc78045f850b2423b62ed5a639bc5 --- /dev/null +++ b/src/THcRawHit.cxx @@ -0,0 +1,18 @@ +/////////////////////////////////////////////////////////////////////////////// +// // +// THcRawHit // +// // +// Abstract class for a single raw hit // +// // +// Contains plane, counter and at least one data value // +// // +/////////////////////////////////////////////////////////////////////////////// + +#include "THcRawHit.h" + +//THcRawHit::~THcRawHit() +//{} + +ClassImp(THcRawHit) + +//_____________________________________________________________________________ diff --git a/src/THcRawHit.h b/src/THcRawHit.h new file mode 100644 index 0000000000000000000000000000000000000000..921939e5732d52cb5fea3fbef481133cb037d342 --- /dev/null +++ b/src/THcRawHit.h @@ -0,0 +1,43 @@ +#ifndef ROOT_THcRawHit +#define ROOT_THcRawHit + +/////////////////////////////////////////////////////////////////////////////// +// // +// THcRawHit // +// // +/////////////////////////////////////////////////////////////////////////////// +#include "TObject.h" + +class THcRawHit : public TObject { + +public: + THcRawHit(Int_t plane=0, Int_t counter=0) : + fPlane(plane), fCounter(counter) {}; + THcRawHit( const THcRawHit& rhs ) : TObject(rhs) {} + THcRawHit& operator=( const THcRawHit& rhs ) + { TObject::operator=(rhs); return *this; }; + + virtual ~THcRawHit() {} + + // This line causes problem + // virtual void Clear( Option_t* opt="" )=0; + + // virtual Bool_t operator==( const THcRawHit& ) = 0; + // virtual Bool_t operator!=( const THcRawHit& ) = 0; + + virtual void SetData(Int_t signal, Int_t data) {}; + virtual Int_t GetData(Int_t signal) {return 0;}; + + // Derived objects must be sortable and supply Compare method + virtual Bool_t IsSortable () const {return kFALSE; } + virtual Int_t Compare(const TObject* obj) const {return 0;} + + Int_t fPlane; + Int_t fCounter; + + private: + + ClassDef(THcRawHit,0) // Track ID abstract base class +}; + +#endif