Newer
Older
//*-- Author :
//////////////////////////////////////////////////////////////////////////
//
// THcDriftChamberPlane
//
//////////////////////////////////////////////////////////////////////////
#include "THcDriftChamberPlane.h"
#include "THcDCWire.h"
#include "THcDCHit.h"
#include "THcDCLookupTTDConv.h"
#include "THcSignalHit.h"
#include "THcGlobals.h"
#include "THcParmList.h"
#include "THcHitList.h"
#include "THcDriftChamber.h"
Stephen A. Wood
committed
#include "THcHodoscope.h"
#include "TClass.h"
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <iostream>
using namespace std;
ClassImp(THcDriftChamberPlane)
//______________________________________________________________________________
THcDriftChamberPlane::THcDriftChamberPlane( const char* name,
const char* description,
const Int_t planenum,
THaDetectorBase* parent )
: THaSubDetector(name,description,parent)
{
// Normal constructor with name and description
fHits = new TClonesArray("THcDCHit",100);
fWires = new TClonesArray("THcDCWire", 100);
fPlaneNum = planenum;
}
//______________________________________________________________________________
THcDriftChamberPlane::~THcDriftChamberPlane()
{
// Destructor
delete fWires;
delete fHits;
delete fTTDConv;
}
THaAnalysisObject::EStatus THcDriftChamberPlane::Init( const TDatime& date )
{
// Extra initialization for scintillator plane: set up DataDest map
cout << "THcDriftChamberPlane::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;
return fStatus = kOK;
}
//_____________________________________________________________________________
Int_t THcDriftChamberPlane::ReadDatabase( const TDatime& date )
{
// See what file it looks for
static const char* const here = "ReadDatabase()";
char prefix[2];
char parname[100];
Int_t NumDriftMapBins;
Double_t DriftMapFirstBin;
Double_t DriftMapBinSize;
Double_t DriftMap[1000];
prefix[0]=tolower(GetParent()->GetPrefix()[0]);
prefix[1]='\0';
DBRequest list[]={
{"driftbins", &NumDriftMapBins, kInt},
{"drift1stbin", &DriftMapFirstBin, kDouble},
{"driftbinsz", &DriftMapBinSize, kDouble},
{Form("wc%sfract",GetName()),DriftMap,kDouble,1000},
{0}
};
gHcParms->LoadParmValues((DBRequest*)&list,prefix);
// Retrieve parameters we need from parent class
THcDriftChamber* fParent;
fParent = (THcDriftChamber*) GetParent();
// These are single variables here, but arrays in THcDriftChamber.
fNChamber = fParent->GetNChamber(fPlaneNum);
fNWires = fParent->GetNWires(fPlaneNum);
fWireOrder = fParent->GetWireOrder(fPlaneNum);
fPitch = fParent->GetPitch(fPlaneNum);
fCentralWire = fParent->GetCentralWire(fPlaneNum);
fTdcWinMin = fParent->GetTdcWinMin(fPlaneNum);
fTdcWinMax = fParent->GetTdcWinMax(fPlaneNum);
fPlaneTimeZero = fParent->GetPlaneTimeZero(fPlaneNum);
fCenter = fParent->GetCenter(fPlaneNum);
fNSperChan = fParent->GetNSperChan();
cout << fPlaneNum << " " << fNWires << endl;
fTTDConv = new THcDCLookupTTDConv(DriftMapFirstBin,fPitch/2,DriftMapBinSize,
NumDriftMapBins,DriftMap);
Int_t nWires = fParent->GetNWires(fPlaneNum);
// For HMS, wire numbers start with one, but arrays start with zero.
// So wire number is index+1
for (int i=0; i<nWires; i++) {
Double_t pos = fPitch*( (fWireOrder==0?(i+1):fNWires-i)
- fCentralWire) - fCenter;
THcDCWire* wire = new((*fWires)[i])
THcDCWire( i+1, pos , 0.0, fTTDConv);
//if( something < 0 ) wire->SetFlag(1);
}
Stephen A. Wood
committed
THaApparatus* app = GetApparatus();
const char* nm = "hod";
if( !app ||
!(fglHod = dynamic_cast<THcHodoscope*>(app->GetDetector(nm))) ) {
Warning(Here(here),"Hodoscope \"%s\" not found. "
"Event-by-event time offsets will NOT be used!!",nm);
}
return kOK;
}
//_____________________________________________________________________________
Int_t THcDriftChamberPlane::DefineVariables( EMode mode )
{
// Initialize global variables and lookup table for decoder
// cout << "THcDriftChamberPlane::DefineVariables called " << GetName() << endl;
if( mode == kDefine && fIsSetup ) return kOK;
fIsSetup = ( mode == kDefine );
// Register variables in global list
RVarDef vars[] = {
{"tdchits", "List of TDC hits",
"fHits.THcDCHit.GetWireNum()"},
{"rawtdc", "Raw TDC Values",
"fHits.THcDCHit.GetRawTime()"},
{"time","Drift times",
"fHits.THcDCHit.GetTime()"},
{"dist","Drift distancess",
"fHits.THcDCHit.GetDist()"},
{ 0 }
};
return DefineVarsFromList( vars, mode );
}
//_____________________________________________________________________________
void THcDriftChamberPlane::Clear( Option_t* )
{
//cout << " Calling THcDriftChamberPlane::Clear " << GetName() << endl;
// Clears the hit lists
fHits->Clear();
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
}
//_____________________________________________________________________________
Int_t THcDriftChamberPlane::Decode( const THaEvData& evdata )
{
// Doesn't actually get called. Use Fill method instead
cout << " Calling THcDriftChamberPlane::Decode " << GetName() << endl;
return 0;
}
//_____________________________________________________________________________
Int_t THcDriftChamberPlane::CoarseProcess( TClonesArray& tracks )
{
// HitCount();
return 0;
}
//_____________________________________________________________________________
Int_t THcDriftChamberPlane::FineProcess( TClonesArray& tracks )
{
return 0;
}
Int_t THcDriftChamberPlane::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.
Stephen A. Wood
committed
Double_t StartTime = 0.0;
// Would be nice to have a way to determine that the hodoscope decode was
// actually called for this event.
if( fglHod ) StartTime = fglHod->GetStartTime();
//cout << "Start time " << StartTime << endl;
Stephen A. Wood
committed
//Int_t nTDCHits=0;
fHits->Clear();
Int_t nrawhits = rawhits->GetLast()+1;
// cout << "THcDriftChamberPlane::ProcessHits " << fPlaneNum << " " << nexthit << "/" << nrawhits << endl;
Int_t ihit = nexthit;
Int_t nextHit = 0;
while(ihit < nrawhits) {
THcRawDCHit* hit = (THcRawDCHit *) rawhits->At(ihit);
if(hit->fPlane > fPlaneNum) {
break;
}
Int_t wireNum = hit->fCounter;
THcDCWire* wire = GetWire(wireNum);
Int_t wire_last = -1;
for(Int_t mhit=0; mhit<hit->fNHits; mhit++) {
/* Sort into early, late and ontime */
Int_t rawtdc = hit->fTDC[mhit];
if(rawtdc < fTdcWinMin) {
// Increment early counter (Actually late because TDC is backward)
} else if (rawtdc > fTdcWinMax) {
// Increment late count
} else {
// A good hit
if(wire_last == wireNum) {
// Increment extra hit counter
// Are we choosing the correct hit in the case of multiple hits?
// Are we choose the same hit that ENGINE chooses?
// cout << "Extra hit " << fPlaneNum << " " << wireNum << " " << rawtdc << endl;
} else {
Stephen A. Wood
committed
Double_t time = -StartTime // (comes from h_trans_scin
- rawtdc*fNSperChan + fPlaneTimeZero;
// How do we get this start time from the hodoscope to here
// (or at least have it ready by coarse process)
new( (*fHits)[nextHit++] ) THcDCHit(wire, rawtdc, time);
}
wire_last = wireNum;
}