#include "THaSpectrometer.h"
#include "THaParticleInfo.h"
#include "THaTrackingDetector.h"
#include "THaNonTrackingDetector.h"
#include "THaPidDetector.h"
#include "THaPIDinfo.h"
#include "THaTrack.h"
#include "TClass.h"
#include "TList.h"
#include "TMath.h"
#include "TList.h"
#include "VarDef.h"
#include <cmath>
#ifdef WITH_DEBUG
#include <iostream>
#endif
using namespace std;
THaSpectrometer::THaSpectrometer( const char* name, const char* desc ) :
THaApparatus( name,desc ), fGoldenTrack(NULL),
fPID(kFALSE), fThetaGeo(0.0), fPhiGeo(0.0), fPcentral(1.0), fCollDist(0.0),
fStagesDone(0), fListInit(kFALSE)
{
fTracks = new TClonesArray( "THaTrack", kInitTrackMultiplicity );
fTrackPID = new TClonesArray( "THaPIDinfo", kInitTrackMultiplicity );
fTrackingDetectors = new TList;
fNonTrackingDetectors = new TList;
fPidDetectors = new TObjArray;
fPidParticles = new TObjArray;
Clear();
DefinePidParticles();
fProperties |= kNeedsRunDB;
fTrkIfo.SetSpectrometer( this );
}
THaSpectrometer::~THaSpectrometer()
{
fPidParticles->Delete();
delete fPidParticles; fPidParticles = 0;
delete fPidDetectors; fPidDetectors = 0;
delete fNonTrackingDetectors; fNonTrackingDetectors = 0;
delete fTrackingDetectors; fTrackingDetectors = 0;
delete fTrackPID; fTrackPID = 0;
delete fTracks; fTracks = 0;
DefineVariables( kDelete );
}
Int_t THaSpectrometer::AddDetector( THaDetector* pdet )
{
if( !pdet || !pdet->IsA()->InheritsFrom("THaSpectrometerDetector")) {
Error("AddDetector", "Detector is not a THaSpectrometerDetector. "
"Detector not added.");
return -1;
}
THaSpectrometerDetector* sdet =
static_cast<THaSpectrometerDetector*>( pdet );
Int_t status = THaApparatus::AddDetector( sdet );
if( status != 0 ) return status;
if( sdet->IsTracking() )
fTrackingDetectors->Add( sdet );
else
fNonTrackingDetectors->Add( sdet );
if( sdet->IsPid() )
fPidDetectors->Add( sdet );
return 0;
}
Int_t THaSpectrometer::AddPidParticle( const char* shortname,
const char* name,
Double_t mass, Int_t charge )
{
fPidParticles->Add( new THaParticleInfo( shortname, name, mass, charge ));
return 0;
}
Int_t THaSpectrometer::CalcPID()
{
THaTrack* theTrack;
THaPIDinfo* pid;
for( int i = 0; i < fTracks->GetLast()+1; i++ ) {
if( (theTrack = static_cast<THaTrack*>( fTracks->At(i) )))
if( (pid = theTrack->GetPIDinfo() )) {
pid->CombinePID();
}
}
return 0;
}
void THaSpectrometer::Clear( Option_t* opt )
{
THaApparatus::Clear(opt);
fTracks->Clear("C");
TrkIfoClear();
VertexClear();
fGoldenTrack = NULL;
fStagesDone = 0;
}
void THaSpectrometer::DefinePidParticles()
{
fPidParticles->Delete();
AddPidParticle( "pi", "pion", 0.139, 0 );
AddPidParticle( "k", "kaon", 0.4936, 0 );
AddPidParticle( "p", "proton", 0.938, 1 );
}
Int_t THaSpectrometer::DefineVariables( EMode mode )
{
if( mode == kDefine && fIsSetup ) return kOK;
fIsSetup = ( mode == kDefine );
RVarDef vars[] = {
{ "tr.n", "Number of tracks", "GetNTracks()" },
{ "tr.x", "Track x coordinate (m)", "fTracks.THaTrack.fX" },
{ "tr.y", "Track x coordinate (m)", "fTracks.THaTrack.fY" },
{ "tr.th", "Tangent of track theta angle", "fTracks.THaTrack.fTheta" },
{ "tr.ph", "Tangent of track phi angle", "fTracks.THaTrack.fPhi" },
{ "tr.p", "Track momentum (GeV)", "fTracks.THaTrack.fP" },
{ "tr.flag", "Track status flag", "fTracks.THaTrack.fFlag" },
{ "tr.chi2", "Track's chi2 from hits", "fTracks.THaTrack.fChi2" },
{ "tr.ndof", "Track's NDoF", "fTracks.THaTrack.fNDoF" },
{ "tr.d_x", "Detector x coordinate (m)", "fTracks.THaTrack.fDX" },
{ "tr.d_y", "Detector y coordinate (m)", "fTracks.THaTrack.fDY" },
{ "tr.d_th", "Detector tangent of theta", "fTracks.THaTrack.fDTheta" },
{ "tr.d_ph", "Detector tangent of phi", "fTracks.THaTrack.fDPhi" },
{ "tr.r_x", "Rotated x coordinate (m)", "fTracks.THaTrack.fRX" },
{ "tr.r_y", "Rotated y coordinate (m)", "fTracks.THaTrack.fRY" },
{ "tr.r_th", "Rotated tangent of theta", "fTracks.THaTrack.fRTheta" },
{ "tr.r_ph", "Rotated tangent of phi", "fTracks.THaTrack.fRPhi" },
{ "tr.tg_y", "Target y coordinate", "fTracks.THaTrack.fTY"},
{ "tr.tg_th", "Tangent of target theta angle", "fTracks.THaTrack.fTTheta"},
{ "tr.tg_ph", "Tangent of target phi angle", "fTracks.THaTrack.fTPhi"},
{ "tr.tg_dp", "Target delta", "fTracks.THaTrack.fDp"},
{ "tr.px", "Lab momentum x (GeV)", "fTracks.THaTrack.GetLabPx()"},
{ "tr.py", "Lab momentum y (GeV)", "fTracks.THaTrack.GetLabPy()"},
{ "tr.pz", "Lab momentum z (GeV)", "fTracks.THaTrack.GetLabPz()"},
{ "tr.vx", "Vertex x (m)", "fTracks.THaTrack.GetVertexX()"},
{ "tr.vy", "Vertex y (m)", "fTracks.THaTrack.GetVertexY()"},
{ "tr.vz", "Vertex z (m)", "fTracks.THaTrack.GetVertexZ()"},
{ "tr.pathl", "Pathlength from tg to fp (m)","fTracks.THaTrack.GetPathLen()"},
{ "tr.time", "Time of track@Ref Plane (s)", "fTracks.THaTrack.GetTime()"},
{ "tr.dtime", "uncer of time (s)", "fTracks.THaTrack.GetdTime()"},
{ "tr.beta", "Beta of track", "fTracks.THaTrack.GetBeta()"},
{ "tr.dbeta", "uncertainty of beta", "fTracks.THaTrack.GetdBeta()"},
{ "status", "Bits of completed analysis stages", "fStagesDone" },
{ 0 }
};
return DefineVarsFromList( vars, mode );
}
const TVector3& THaSpectrometer::GetVertex() const
{
return (fGoldenTrack) ? fGoldenTrack->GetVertex() : fVertex;
}
Bool_t THaSpectrometer::HasVertex() const
{
return (fGoldenTrack) ? fGoldenTrack->HasVertex() : kFALSE;
}
void THaSpectrometer::ListInit()
{
fTrackingDetectors->Clear();
fNonTrackingDetectors->Clear();
fPidDetectors->Clear();
TIter next(fDetectors);
while( THaSpectrometerDetector* theDetector =
static_cast<THaSpectrometerDetector*>( next() )) {
if( theDetector->IsTracking() )
fTrackingDetectors->Add( theDetector );
else
fNonTrackingDetectors->Add( theDetector );
if( theDetector->IsPid() )
fPidDetectors->Add( theDetector );
}
UInt_t ndet = GetNpidDetectors();
UInt_t npart = GetNpidParticles();
TClonesArray& pid = *fTrackPID;
for( int i = 0; i < kInitTrackMultiplicity; i++ ) {
new( pid[i] ) THaPIDinfo( ndet, npart );
}
fListInit = kTRUE;
}
Int_t THaSpectrometer::CoarseTrack()
{
if( !fListInit )
ListInit();
TIter next( fTrackingDetectors );
while( THaTrackingDetector* theTrackDetector =
static_cast<THaTrackingDetector*>( next() )) {
#ifdef WITH_DEBUG
if( fDebug>1 ) cout << "Call CoarseTrack() for "
<< theTrackDetector->GetName() << "... ";
#endif
theTrackDetector->CoarseTrack( *fTracks );
#ifdef WITH_DEBUG
if( fDebug>1 ) cout << "done.\n";
#endif
}
fStagesDone |= kCoarseTrack;
return 0;
}
Int_t THaSpectrometer::CoarseReconstruct()
{
if( !IsDone(kCoarseTrack))
CoarseTrack();
TIter next( fNonTrackingDetectors );
while( THaNonTrackingDetector* theNonTrackDetector =
static_cast<THaNonTrackingDetector*>( next() )) {
#ifdef WITH_DEBUG
if( fDebug>1 ) cout << "Call CoarseProcess() for "
<< theNonTrackDetector->GetName() << "... ";
#endif
theNonTrackDetector->CoarseProcess( *fTracks );
#ifdef WITH_DEBUG
if( fDebug>1 ) cout << "done.\n";
#endif
}
fStagesDone |= kCoarseRecon;
return 0;
}
Int_t THaSpectrometer::Track()
{
if( !IsDone(kCoarseRecon))
CoarseReconstruct();
TIter next( fTrackingDetectors );
while( THaTrackingDetector* theTrackDetector =
static_cast<THaTrackingDetector*>( next() )) {
#ifdef WITH_DEBUG
if( fDebug>1 ) cout << "Call FineTrack() for "
<< theTrackDetector->GetName() << "... ";
#endif
theTrackDetector->FineTrack( *fTracks );
#ifdef WITH_DEBUG
if( fDebug>1 ) cout << "done.\n";
#endif
}
FindVertices( *fTracks );
fStagesDone |= kTracking;
return 0;
}
Int_t THaSpectrometer::Reconstruct()
{
if( !IsDone(kTracking))
Track();
TIter next( fNonTrackingDetectors );
while( THaNonTrackingDetector* theNonTrackDetector =
static_cast<THaNonTrackingDetector*>( next() )) {
#ifdef WITH_DEBUG
if( fDebug>1 ) cout << "Call FineProcess() for "
<< theNonTrackDetector->GetName() << "... ";
#endif
theNonTrackDetector->FineProcess( *fTracks );
#ifdef WITH_DEBUG
if( fDebug>1 ) cout << "done.\n";
#endif
}
TrackCalc();
if( fPID ) CalcPID();
fStagesDone |= kReconstruct;
return 0;
}
void THaSpectrometer::TrackToLab( THaTrack& track, TVector3& pvect ) const
{
TransportToLab( track.GetP(), track.GetTTheta(), track.GetTPhi(), pvect );
}
void THaSpectrometer::TransportToLab( Double_t p, Double_t th, Double_t ph,
TVector3& pvect ) const
{
TVector3 v( th, ph, 1.0 );
v *= p/TMath::Sqrt( 1.0+th*th+ph*ph );
pvect = fToLabRot * v;
}
void THaSpectrometer::LabToTransport( const TVector3& vertex,
const TVector3& pvect,
TVector3& tvertex, Double_t* ray ) const
{
tvertex = fToTraRot * ( vertex - fPointingOffset );
TVector3 pt = fToTraRot * pvect;
if( pt.Z() != 0.0 ) {
ray[1] = pt.X() / pt.Z();
ray[3] = pt.Y() / pt.Z();
ray[0] = tvertex.X() - tvertex.Z() * ray[1];
ray[2] = tvertex.Y() - tvertex.Z() * ray[3];
} else
ray[0] = ray[1] = ray[2] = ray[3] = 0.0;
ray[4] = 0.0;
ray[5] = pt.Mag() / fPcentral - 1.0;
}
Int_t THaSpectrometer::ReadRunDatabase( const TDatime& date )
{
Int_t err = THaApparatus::ReadRunDatabase( date );
if( err ) return err;
FILE* file = OpenRunDBFile( date );
if( !file ) return kFileError;
static const Double_t degrad = TMath::Pi()/180.0;
Double_t th = 0.0, ph = 0.0;
Double_t off_x = 0.0, off_y = 0.0, off_z = 0.0;
const TagDef tags[] = {
{ "theta", &th, 1 },
{ "phi", &ph },
{ "pcentral", &fPcentral, 3 },
{ "colldist", &fCollDist },
{ "off_x", &off_x },
{ "off_y", &off_y },
{ "off_z", &off_z },
{ 0 }
};
err = LoadDB( file, date, tags, fPrefix );
if( err ) {
if( err>0 )
Error( Here("ReadRunDatabase()"), "Required tag %s%s missing in the "
"run database.\nSpectrometer initialization failed.",
fPrefix, tags[err-1].name );
fclose(file);
return kInitError;
}
fThetaGeo = degrad*th; fPhiGeo = degrad*ph;
GeoToSph( fThetaGeo, fPhiGeo, fThetaSph, fPhiSph );
fSinThGeo = sin( fThetaGeo ); fCosThGeo = cos( fThetaGeo );
fSinPhGeo = sin( fPhiGeo ); fCosPhGeo = cos( fPhiGeo );
Double_t st, ct, sp, cp;
st = fSinThSph = sin( fThetaSph ); ct = fCosThSph = cos( fThetaSph );
sp = fSinPhSph = sin( fPhiSph ); cp = fCosPhSph = cos( fPhiSph );
bool bend_down = false;
Double_t norm = sqrt(ct*ct + st*st*cp*cp);
TVector3 nx( st*st*sp*cp/norm, -norm, st*ct*sp/norm );
TVector3 ny( ct/norm, 0.0, -st*cp/norm );
TVector3 nz( st*cp, st*sp, ct );
if( bend_down ) { nx *= -1.0; ny *= -1.0; }
#if ROOT_VERSION_CODE >= ROOT_VERSION(3,5,4)
fToLabRot.SetToIdentity().RotateAxes( nx, ny, nz );
#else
if( !fToLabRot.IsIdentity()) {
TRotation tmp;
fToLabRot = tmp;
}
fToLabRot.RotateAxes( nx, ny, nz );
#endif
fToTraRot = fToLabRot.Inverse();
fPointingOffset.SetXYZ( off_x, off_y, off_z );
fclose(file);
return kOK;
}
ClassImp(THaSpectrometer)
Last change: Sat Nov 7 21:26:52 2009
Last generated: 2009-11-07 21:26
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.