/////////////////////////////////////////////////////////////////////////////// // // // THcDC // // // // 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 "THcDC.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; //_____________________________________________________________________________ THcDC::THcDC( const char* name, const char* description, THaApparatus* apparatus ) : THaTrackingDetector(name,description,apparatus) { // Constructor // fTrackProj = new TClonesArray( "THaTrackProj", 5 ); fNPlanes = 0; // No planes until we make them fXCenter = NULL; fYCenter = NULL; fMinHits = NULL; fMaxHits = NULL; fMinCombos = NULL; fSpace_Point_Criterion2 = NULL; fTdcWinMin = NULL; fTdcWinMax = NULL; fCentralTime = NULL; fNWires = NULL; fNChamber = NULL; fWireOrder = NULL; fDriftTimeSign = NULL; fZPos = NULL; fAlphaAngle = NULL; fBetaAngle = NULL; fGammaAngle = NULL; fPitch = NULL; fCentralWire = NULL; fPlaneTimeZero = NULL; fSigma = NULL; } //_____________________________________________________________________________ void THcDC::Setup(const char* name, const char* description) { static const char* const here = "Setup"; char prefix[2]; char parname[100]; THaApparatus *app = GetApparatus(); if(app) { cout << app->GetName() << endl; } else { cout << "No apparatus found" << endl; } prefix[0]=tolower(app->GetName()[0]); prefix[1]='\0'; string planenamelist; DBRequest list[]={ {"dc_num_planes",&fNPlanes, kInt}, {"dc_num_chambers",&fNChambers, kInt}, {"dc_tdc_time_per_channel",&fNSperChan, kDouble}, {"dc_wire_velocity",&fWireVelocity,kDouble}, {"dc_plane_names",&planenamelist, kString}, {0} }; gHcParms->LoadParmValues((DBRequest*)&list,prefix); cout << planenamelist << endl; cout << "Drift Chambers: " << fNPlanes << " planes in " << fNChambers << " chambers" << endl; vector<string> plane_names = vsplit(planenamelist); if(plane_names.size() != (UInt_t) fNPlanes) { cout << "ERROR: Number of planes " << fNPlanes << " doesn't agree with number of plane names " << plane_names.size() << endl; // Should quit. Is there an official way to quit? } fPlaneNames = new char* [fNPlanes]; for(Int_t i=0;i<fNPlanes;i++) { fPlaneNames[i] = new char[plane_names[i].length()]; strcpy(fPlaneNames[i], plane_names[i].c_str()); } char *desc = new char[strlen(description)+100]; fPlanes.clear(); for(Int_t i=0;i<fNPlanes;i++) { strcpy(desc, description); strcat(desc, " Plane "); strcat(desc, fPlaneNames[i]); THcDriftChamberPlane* newplane = new THcDriftChamberPlane(fPlaneNames[i], desc, i+1, this); if( !newplane or newplane->IsZombie() ) { Error( Here(here), "Error creating Drift Chamber plane %s. Call expert.", name); MakeZombie(); return; } fPlanes.push_back(newplane); newplane->SetDebug(fDebug); cout << "Created Drift Chamber Plane " << fPlaneNames[i] << ", " << desc << endl; } fChambers.clear(); for(Int_t i=0;i<fNChambers;i++) { sprintf(desc,"%s Chamber %d",description, i+1); // Should construct a better chamber name THcDriftChamber* newchamber = new THcDriftChamber(desc, desc, i+1, this); fChambers.push_back(newchamber); cout << "Created Drift Chamber " << i+1 << ", " << desc << endl; } } //_____________________________________________________________________________ THcDC::THcDC( ) : THaTrackingDetector() { // Constructor } //_____________________________________________________________________________ THaAnalysisObject::EStatus THcDC::Init( const TDatime& date ) { static const char* const here = "Init()"; Setup(GetName(), GetTitle()); // Create the subdetectors here // Should probably put this in ReadDatabase as we will know the // maximum number of hits after setting up the detector map THcHitList::InitHitList(fDetMap, "THcRawDCHit", 1000); EStatus status; // This triggers call of ReadDatabase and DefineVariables if( (status = THaTrackingDetector::Init( date )) ) return fStatus=status; // Initialize planes and add them to chambers for(Int_t ip=0;ip<fNPlanes;ip++) { if((status = fPlanes[ip]->Init( date ))) { return fStatus=status; } else { Int_t chamber=fNChamber[ip]; fChambers[chamber-1]->AddPlane(fPlanes[ip]); } } // Initialize chambers for(Int_t ic=0;ic<fNChambers;ic++) { if((status = fChambers[ic]->Init ( date ))) { return fStatus=status; } } // 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) ); // Will need to determine which apparatus it belongs to and use the // appropriate detector ID in the FillMap call char EngineDID[4]; EngineDID[0] = toupper(GetApparatus()->GetName()[0]); EngineDID[1] = 'D'; EngineDID[2] = 'C'; EngineDID[3] = '\0'; if( gHcDetectorMap->FillMap(fDetMap, EngineDID) < 0 ) { Error( Here(here), "Error filling detectormap for %s.", EngineDID); return kInitError; } return fStatus = kOK; } //_____________________________________________________________________________ Int_t THcDC::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()"; char prefix[2]; char parname[100]; // Read data from database // Pull values from the THcParmList instead of reading a database // file like Hall A does. // 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) prefix[0]=tolower(GetApparatus()->GetName()[0]); prefix[1]='\0'; delete [] fXCenter; fXCenter = new Double_t [fNChambers]; delete [] fYCenter; fYCenter = new Double_t [fNChambers]; delete [] fMinHits; fMinHits = new Int_t [fNChambers]; delete [] fMaxHits; fMaxHits = new Int_t [fNChambers]; delete [] fMinCombos; fMinCombos = new Int_t [fNChambers]; delete [] fSpace_Point_Criterion2; fSpace_Point_Criterion2 = new Double_t [fNChambers]; delete [] fTdcWinMin; fTdcWinMin = new Int_t [fNPlanes]; delete [] fTdcWinMax; fTdcWinMax = new Int_t [fNPlanes]; delete [] fCentralTime; fCentralTime = new Int_t [fNPlanes]; delete [] fNWires; fNWires = new Int_t [fNPlanes]; delete [] fNChamber; fNChamber = new Int_t [fNPlanes]; // Which chamber is this plane delete [] fWireOrder; fWireOrder = new Int_t [fNPlanes]; // Wire readout order delete [] fDriftTimeSign; fDriftTimeSign = new Int_t [fNPlanes]; delete [] fZPos; fZPos = new Double_t [fNPlanes]; delete [] fAlphaAngle; fAlphaAngle = new Double_t [fNPlanes]; delete [] fBetaAngle; fBetaAngle = new Double_t [fNPlanes]; delete [] fGammaAngle; fGammaAngle = new Double_t [fNPlanes]; delete [] fPitch; fPitch = new Double_t [fNPlanes]; delete [] fCentralWire; fCentralWire = new Double_t [fNPlanes]; delete [] fPlaneTimeZero; fPlaneTimeZero = new Double_t [fNPlanes]; delete [] fSigma; fSigma = new Double_t [fNPlanes]; DBRequest list[]={ {"dc_tdc_time_per_channel",&fNSperChan, kDouble}, {"dc_wire_velocity",&fWireVelocity,kDouble}, {"dc_xcenter", fXCenter, kDouble, fNChambers}, {"dc_ycenter", fYCenter, kDouble, fNChambers}, {"min_hit", fMinHits, kInt, fNChambers}, {"max_pr_hits", fMaxHits, kInt, fNChambers}, {"min_combos", fMinCombos, kInt, fNChambers}, {"space_point_criterion", fSpace_Point_Criterion2, kDouble, fNChambers}, {"dc_tdc_min_win", fTdcWinMin, kInt, fNPlanes}, {"dc_tdc_max_win", fTdcWinMax, kInt, fNPlanes}, {"dc_central_time", fCentralTime, kInt, fNPlanes}, {"dc_nrwire", fNWires, kInt, fNPlanes}, {"dc_chamber_planes", fNChamber, kInt, fNPlanes}, {"dc_wire_counting", fWireOrder, kInt, fNPlanes}, {"dc_drifttime_sign", fDriftTimeSign, kInt, fNPlanes}, {"dc_zpos", fZPos, kDouble, fNPlanes}, {"dc_alpha_angle", fAlphaAngle, kDouble, fNPlanes}, {"dc_beta_angle", fBetaAngle, kDouble, fNPlanes}, {"dc_gamma_angle", fGammaAngle, kDouble, fNPlanes}, {"dc_pitch", fPitch, kDouble, fNPlanes}, {"dc_central_wire", fCentralWire, kDouble, fNPlanes}, {"dc_plane_time_zero", fPlaneTimeZero, kDouble, fNPlanes}, {"dc_sigma", fSigma, kDouble, fNPlanes}, {0} }; gHcParms->LoadParmValues((DBRequest*)&list,prefix); cout << "Plane counts:"; for(Int_t i=0;i<fNPlanes;i++) { cout << " " << fNWires[i]; } cout << endl; fIsInit = true; return kOK; } //_____________________________________________________________________________ Int_t THcDC::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[] = { { "nhit", "Number of DC hits", "fNhits" }, { 0 } }; return DefineVarsFromList( vars, mode ); } //_____________________________________________________________________________ THcDC::~THcDC() { // Destructor. Remove variables from global list. if( fIsSetup ) RemoveVariables(); if( fIsInit ) DeleteArrays(); // Delete the plane objects for (vector<THcDriftChamberPlane*>::iterator ip = fPlanes.begin(); ip != fPlanes.end(); ip++) delete *ip; // Delete the chamber objects for (vector<THcDriftChamber*>::iterator ip = fChambers.begin(); ip != fChambers.end(); ip++) delete *ip; if (fTrackProj) { fTrackProj->Clear(); delete fTrackProj; fTrackProj = 0; } } //_____________________________________________________________________________ void THcDC::DeleteArrays() { // Delete member arrays. Used by destructor. delete [] fXCenter; fXCenter = NULL; delete [] fYCenter; fYCenter = NULL; delete [] fMinHits; fMinHits = NULL; delete [] fMaxHits; fMaxHits = NULL; delete [] fMinCombos; fMinCombos = NULL; delete [] fSpace_Point_Criterion2; fSpace_Point_Criterion2 = NULL; delete [] fTdcWinMin; fTdcWinMin = NULL; delete [] fTdcWinMax; fTdcWinMax = NULL; delete [] fCentralTime; fCentralTime = NULL; delete [] fNWires; fNWires = NULL; delete [] fNChamber; fNChamber = NULL; delete [] fWireOrder; fWireOrder = NULL; delete [] fDriftTimeSign; fDriftTimeSign = NULL; delete [] fZPos; fZPos = NULL; delete [] fAlphaAngle; fAlphaAngle = NULL; delete [] fBetaAngle; fBetaAngle = NULL; delete [] fGammaAngle; fGammaAngle = NULL; delete [] fPitch; fPitch = NULL; delete [] fCentralWire; fCentralWire = NULL; delete [] fPlaneTimeZero; fPlaneTimeZero = NULL; delete [] fSigma; fSigma = NULL; } //_____________________________________________________________________________ inline void THcDC::ClearEvent() { // Reset per-event data. fNhits = 0; for(Int_t i=0;i<fNChambers;i++) { fChambers[i]->Clear(); } // fTrackProj->Clear(); } //_____________________________________________________________________________ Int_t THcDC::Decode( const THaEvData& evdata ) { ClearEvent(); // Get the Hall C style hitlist (fRawHitList) for this event fNhits = 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); } // Let each chamber get its hits for(Int_t ic=0;ic<fNChambers;ic++) { fChambers[ic]->ProcessHits(); } #if 0 // fRawHitList is TClones array of THcRawDCHit objects for(Int_t ihit = 0; ihit < fNRawHits ; ihit++) { THcRawDCHit* hit = (THcRawDCHit *) fRawHitList->At(ihit); // cout << ihit << " : " << hit->fPlane << ":" << hit->fCounter << " : " // << endl; for(Int_t imhit = 0; imhit < hit->fNHits; imhit++) { // cout << " " << imhit << " " << hit->fTDC[imhit] // << endl; } } // cout << endl; #endif return fNhits; } //_____________________________________________________________________________ Int_t THcDC::ApplyCorrections( void ) { return(0); } //_____________________________________________________________________________ Int_t THcDC::CoarseTrack( 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.); for(Int_t i=0;i<fNChambers;i++) { fChambers[i]->FindSpacePoints(); fChambers[i]->CorrectHitTimes(); fChambers[i]->LeftRight(); } ApplyCorrections(); return 0; } //_____________________________________________________________________________ Int_t THcDC::FineTrack( 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(THcDC) ////////////////////////////////////////////////////////////////////////////////