//*-- Author : A.Sadovsky <sadovski@fz-rossendorf.de> (04.11.2004); Special thanks to A.Ivashkin, V.Pechenov and A.Rustamov
//*-- Last modified : 10/08/2005 by Ilse Koenig
#include <iostream>
#include "hrktrackBF.h"
#include "hades.h"
#include "hruntimedb.h"
#include "hevent.h"
#include "hdetector.h"
#include "hiterator.h"
#include "hcategory.h"
#include "hmdctrkcand.h"
#include "hmdcgetcontainers.h"
#include "hrktrackB.h"
#include "hrungekutta.h"
#include "hmetamatch.h"
#include "htofcluster.h"
#include "htofclustersim.h"
#include "hgeomvolume.h"
#include "hspectrometer.h"
#include "hmdcdetector.h"
#include "hmdcgeompar.h"
#include "htofinogeompar.h"
#include "htofgeompar.h"
#include "hshowergeometry.h"
#include "hspecgeompar.h"
#include "tofdef.h"
#include "hmdcseg.h"
#include "hmdchit.h"
#include "showerdef.h"
#include "hmdctrackgfieldpar.h"
#include "hmatrixcategory.h"
#include "showertofinodef.h"
#include "hgeantmdc.h"
#include "hkickplane2.h"
#include "hgeantkine.h"
#include "hgeomtransform.h"
#include "hmdctrackddef.h"
#include "hmdctrackgdef.h"
#include "hmdctrackgspline.h"
#include "hgeomvector.h"
#include "hsplinetrack.h"
#include "hmagnetpar.h"
#include "hshowerhittoftrack.h"
#include "hmdcsizescells.h"
using namespace std;
//_HADES_CLASS_DESCRIPTION
/////////////////////////////////////////////////////////////////////////////
//
// This class implements Runge Kutta method of momentum calculation
// into Hydra framework. Output is compartible with General Tracking Scheme
// User valuable output is HRKTrackB class in a ROOT tree
// Now it works with all 4 MDCs present
//
/////////////////////////////////////////////////////////////////////////////
ClassImp(HRKTrackBF)
HRKTrackBF::HRKTrackBF() {
// DUMMY constructor:
// Initial momentum is taken as a self guess (mode=0)
mode=0;
clear();
}
HRKTrackBF::HRKTrackBF(Text_t *name, Short_t m) : HReconstructor(name,name) {
// Mode m = {0,1,2} Take initial momentum from: 0-self guess, 1-from KickPlane, 2-from SplineTrack
mode=m;
clear();
}
void HRKTrackBF::clear() {
// sets all pointers to NULL
pMagnet =0;
field =0;
fieldFactor =0.;
fSpecGeomPar =0;
fGetCont =0;
fTofGeometry =0;
fTofinoGeometry =0;
fShowerGeometry =0;
fCatMetaMatch =0;
fMetaMatchIter =0;
fCatMdcTrkCand =0;
fCatMdcSeg =0;
fCatMdcHit =0;
fSplineTrack =0;
fKickTrack =0;
fCatKine =0;
fCatShower =0;
fCatTof =0;
fCatTofCluster =0;
fCatRKTrack =0;
pMetaMatch =0;
pMdcTrkCand =0;
pSplineTrack =0;
pKickTrack =0;
pTofHit =0;
pTofCluster =0;
pShowerHitTofTrack=0;
pRungeKutta =0;
}
HRKTrackBF::~HRKTrackBF() {
// destructor
if (pRungeKutta) {
delete pRungeKutta;
pRungeKutta=0;
}
HMdcSizesCells::deleteCont();
}
Bool_t HRKTrackBF::init(){
// sets pointers to all categories and the parameter containers
if (gHades) {
HRuntimeDb *rtdb=gHades->getRuntimeDb();
HSpectrometer *spec=gHades->getSetup();
HEvent *event=gHades->getCurrentEvent();
if (!event) return kFALSE;
field=(HMdcTrackGFieldPar*)(rtdb->getContainer("MdcTrackGFieldPar"));
fSpecGeomPar=(HSpecGeomPar*)(rtdb->getContainer("SpecGeomPar"));
pMagnet=(HMagnetPar*)( rtdb->getContainer("MagnetPar"));
fGetCont=HMdcGetContainers::getObject();
pMSizesCells = HMdcSizesCells::getObject();
// TOF-geometry-for-metaEnergy loss calculation
if (spec->getDetector("Tof")) { // has the user set up a TOF?
fTofGeometry = (HTofGeomPar *)rtdb->getContainer("TofGeomPar");
}
// TOFINO/Shower-geometry-for-metaEnergy loss calculation
if (spec->getDetector("Shower")&&spec->getDetector("Tofino")) {
fTofinoGeometry = (HTofinoGeomPar *)rtdb->getContainer("TofinoGeomPar");
fShowerGeometry = (HShowerGeometry *)rtdb->getContainer("ShowerGeometry");
}
// Categories
fCatMetaMatch=event->getCategory(catMetaMatch);
if (!fCatMetaMatch) return kFALSE;
fMetaMatchIter=(HIterator*)fCatMetaMatch->MakeIterator();
if (!fMetaMatchIter) return kFALSE;
fCatMdcTrkCand=event->getCategory(catMdcTrkCand);
if (!fCatMdcTrkCand) return kFALSE;
fCatMdcSeg=event->getCategory(catMdcSeg);
if (!fCatMdcSeg) return kFALSE;
fCatMdcHit=event->getCategory(catMdcHit);
if (!fCatMdcHit) return kFALSE;
// momentum guess if any
if (mode==1) { //- use KickTrack as initial guess for momentum
fKickTrack=event->getCategory(catKickTrack123B);
if(!fKickTrack) {
Error("init",
"KickTRack123 is used as initial momentum guess, but was not initialized before Runge-Kutta");
return kFALSE;
}
} else if (mode==2) { //- use SplineTrack as initial guess for momentum
fSplineTrack=event->getCategory(catSplineTrack);
if (!fSplineTrack) {
Error("init",
"Spline is used as initial momentum guess, but was not initialized before Runge-Kutta");
return kFALSE;
}
}
//- META detectors part
fCatTof=event->getCategory(catTofHit);
if (!fCatTof) return kFALSE;
fCatTofCluster=event->getCategory(catTofCluster);
if (!fCatTofCluster) Warning("init","No catTofCluster in input!");
if (!event->getCategory(catGeantKine)) {
fCatShower=event->getCategory(catShowerHitTof);
if (!fCatShower) return kFALSE;
} else {
fCatShower=event->getCategory(catShowerHitTofTrack);
if(!fCatShower) return kFALSE;
}
//- Here we get category HRKTrackB to use it as an output in "execute()"
fCatRKTrack=event->getCategory(catRKTrackB);
if (!fCatRKTrack) {
Int_t size[2]={6,600};
fCatRKTrack=new HMatrixCategory("HRKTrackB",2,size,0.5);
if (fCatRKTrack) event->addCategory(catRKTrackB,fCatRKTrack,"RKTrackB");
}
return kTRUE;
} // end if (gHades)
return kFALSE;
}
Bool_t HRKTrackBF::reinit(){
// creates The Runge Kutta objects and sets the field and MDC geometry parameters
// calculates norm vectors on TOF and Tofino modules
if (!pRungeKutta) {
pRungeKutta = new HRungeKutta();
}
if (pMagnet->hasChanged()) {
fieldFactor=pMagnet->getScalingFactor();
if(pMagnet->getPolarity()<0){ fieldFactor=-fieldFactor; } // changed!
pRungeKutta->setField(field->getPointer(),fieldFactor);
}
if (!pMSizesCells->initContainer()) {
Error("reinit()","HMdcSizesCells is not initialzed!");
return kFALSE;
}
if (pMSizesCells->hasChanged()) {
// Geometry transformation from module to sector coord system for MDCs
HGeomTransform gtrMod2Sec;
for(Int_t is=0; is<6; is++) {
HMdcSizesCellsSec& fSCSec = (*pMSizesCells)[is];
if(&fSCSec == 0) continue; // sector is not active
secTrans[is]=*(fSCSec.getLabTrans());
for(Int_t im=0; im<4; im++) {
HMdcSizesCellsMod& fSCMod=fSCSec[im];
if (&fSCMod) {
gtrMod2Sec = *(fSCMod.getSecTrans());
pRungeKutta->setMdcPosition(is,im,gtrMod2Sec);
}
}
}
}
//Geometry of the TOF and TOFINO/SHOWER-Hit (needed by MetaEloss calculation)
// (normale on each module in the sector coordinate system)
for(Int_t is=0; is<6; is++) {
if (fTofinoGeometry&&fTofinoGeometry->hasChanged()) {
HModGeomPar *module = fTofinoGeometry->getModule(is,0);
HGeomTransform modTrans( module->getLabTransform());
modTrans.transTo(secTrans[is]);
HGeomVector r0_mod(0.0, 0.0, 0.0);
centerTofino[is]=modTrans.transFrom(r0_mod);
HGeomVector rz_mod(0.0, 0.0, 1.0);
normVecTofino[is] = modTrans.transFrom(rz_mod) - centerTofino[is];
}
if (fShowerGeometry&&fShowerGeometry->hasChanged()) {
HModGeomPar *module = fShowerGeometry->getModule(is,0);
HGeomTransform modTrans( module->getLabTransform());
modTrans.transTo(secTrans[is]);
HGeomVector r0_mod(0.0, 0.0, 0.0);
HGeomVector rz_mod(0.0, 0.0, 1.0);
normVecShower[is] = modTrans.transFrom(rz_mod) - modTrans.transFrom(r0_mod);
}
if (fTofGeometry&&fTofGeometry->hasChanged()) {
for(Int_t im=0; im<8; im++) {
HModGeomPar *module = fTofGeometry->getModule(is,im);
HGeomTransform modTrans(module->getLabTransform());
modTrans.transTo(secTrans[is]);
HGeomVector r0_mod(0.0, 0.0, 0.0);
HGeomVector rz_mod(0.0, 0.0, 1.0);
normVecTof[is][im] = modTrans.transFrom(rz_mod) - modTrans.transFrom(r0_mod);
}
}
}
return kTRUE;
}
Int_t HRKTrackBF::execute(){
//
success = kTRUE;
fMetaMatchIter->Reset();
while ((pMetaMatch=(HMetaMatch*)(fMetaMatchIter->Next()))!=0) {
sector = pMetaMatch->getSector();
system = pMetaMatch->getSystem();
pMdcTrkCand=(HMdcTrkCand*)fCatMdcTrkCand->getObject(pMetaMatch->getTrkCandInd());
if(!pMdcTrkCand) { continue; }
pMdcSeg1 = (HMdcSeg*)fCatMdcSeg->getObject(pMdcTrkCand->getSeg1Ind());
pMdcSeg2 = (HMdcSeg*)fCatMdcSeg->getObject(pMdcTrkCand->getSeg2Ind());
if (!pMdcSeg1 || !pMdcSeg2) { continue; }
sectorloc.set(1,sector);
// We calculate the initial point and direction for each segment.
// This vector is used in Runge Kutta to calculate the hit points in each MDC plane.
Double_t u1pos[3], u1dir[3], u2pos[3], u2dir[3];
Int_t nHits=calcPosDirFromSegment(pMdcSeg1,0,&u1pos[0],&u1dir[0]); // inner segment
nHits+=calcPosDirFromSegment(pMdcSeg2,1,&u2pos[0],&u2dir[0]); // outer segment
if (nHits<3) { continue; }
Int_t splineTrackIndex=-1;
Int_t kickTrackIndex123=-1;
momentumGuess=-1000000.0; //indicates the absence of initial guess
pRK=-1000000.0;
qRK=0;
if (mode==2) {
// Initial momentum guess from SplineTrack
splineTrackIndex = pMetaMatch->getSplineInd();
if (splineTrackIndex>=0) {
pSplineTrack = (HSplineTrack*)fSplineTrack->getObject(splineTrackIndex);
pRK=pSplineTrack->getP();
qRK=pSplineTrack->getPolarity();
} else {
Warning("execute()","SplineTrack did not provide information for RK");
}
} else if (mode==1 || momentumGuess==-1000000.0) {
// Initial momentum guess from KickTrack123
kickTrackIndex123 = pMetaMatch->getKick123Ind();
if (kickTrackIndex123>=0) {
pKickTrack = (HBaseTrack*)fKickTrack->getObject(kickTrackIndex123);
pRK=pKickTrack->getP();
qRK=pKickTrack->getPolarity();
} else {
Warning("execute()","KickTrack did not provide information for RK");
}
}
if (pRK>50.) {
momentumGuess=qRK*pRK;
} else if (pRK!=-1000000.0) {
momentumGuess=qRK*50.;
}
// Now do Runge-Kutta momentum tracking and fitting with momentum guess as start value
if (nHits==4) {
success=pRungeKutta->fit4Hits(u1pos,u1dir,u2pos,u2dir,multSig,sector,momentumGuess);
} else {
if (momentumGuess!=-1000000.0) {
success=pRungeKutta->fit3Hits(u1pos,u1dir,u2pos,u2dir,multSig,sector,momentumGuess);
} else {
//Runge Kutta does not work with MDC123 in case no initial guess was specified
Warning("execute()",
"HRKTrackF: MDC123 mode, but user did not provide momentum guess - RK failed!");
success=kFALSE; // this prevents from writing garbage into HRKTrackB
}
}
if (!success) {
fillData(pMdcSeg1,pMdcSeg2,pSplineTrack); //fill HRKTrack with the initial segment information
continue;
}
chiqRK=pRungeKutta->getChi2();
pRK=pRungeKutta->getPfit();
if (pRK>0) {
qRK=+1;
} else {
pRK*=-1.;
qRK=-1;
}
if (pRK>10000.) pRK=10000.0;
// Now propogate it till vertex
pRungeKutta->traceToVertex(pMSizesCells);
// Now we take into account META information if any
Int_t metaInd = pMetaMatch->getMetaHitInd();
Float_t xTof,yTof,zTof; // meta hit
HGeomVector *pathCorrPos=0, *pathCorrNorm=0;
if (metaInd<0) {
// If META does not exist, we just write tracking part into HRKTrackB
tof = -1.0;
trackLength = -1.0;
beta = -1.0;
mass2 = -1.0;
metaeloss = -1.0;
RKxyzMETA[0] = -1000.0;
RKxyzMETA[1] = -1000.0;
RKxyzMETA[2] = -1000.0;
pRungeKutta->traceToMETA(centerTofino[sector],normVecTofino[sector],pathCorrPos,pathCorrNorm);
} else { // META exists
if (system==0) { // for TOFINO/Shower
pShowerHitTofTrack=(HShowerHitTofTrack*)fCatShower->getObject(metaInd);
tof=pShowerHitTofTrack->getTof();
metaeloss=pShowerHitTofTrack->getADC();
pShowerHitTofTrack->getLabXYZ(&xTof,&yTof,&zTof);
metaNormVec=normVecShower[sector];
pathCorrPos=¢erTofino[sector];
pathCorrNorm=&normVecTofino[sector];
} //-end-if-system==0--
if (system==1) { // for TOF
if (pMetaMatch->getTofClusterSize()<=0) { //no TofCluster was found
pTofHit=(HTofHit*)fCatTof->getObject(metaInd);
tof=pTofHit->getTof();
metaeloss=pTofHit->getEdep();
pTofHit->getXYZLab(xTof,yTof,zTof);
metaNormVec=normVecTof[sector][(Int_t)pTofHit->getModule()];
} else { // RK-is in TofCluster mode and TofCluster was found
pTofCluster=(HTofCluster*)fCatTofCluster->getObject(metaInd);
tof=pTofCluster->getTof();
metaeloss=pTofCluster->getEdep();
pTofCluster->getXYZLab(xTof,yTof,zTof);
metaNormVec=normVecTof[sector][(Int_t)pTofCluster->getModule()];
}
}
// We collected META hit coordinates
// and transform it into the sector coordinate system
pointMeta.setXYZ(xTof,yTof,zTof);
pointMeta=secTrans[sector].transTo(pointMeta);
xTof=pointMeta.getX();
yTof=pointMeta.getY();
zTof=pointMeta.getZ();
// Trace with Runge Kutta from outer MDC to META
pRungeKutta->traceToMETA(pointMeta,metaNormVec,pathCorrPos,pathCorrNorm);
RKxyzMETA[0] = pRungeKutta->getXtrackOnMETA() - xTof;
RKxyzMETA[1] = pRungeKutta->getYtrackOnMETA() - yTof;
RKxyzMETA[2] = pRungeKutta->getZtrackOnMETA() - zTof;
// Calculate beta=length/tof
trackLength = pRungeKutta->getTrackLength();
beta = 1.0e6*trackLength/tof/TMath::C(); //dist [mm], tof[ns]
mass2 = pRK*pRK*(1-beta*beta)/beta/beta;
} // end if META exists
fillData(pMdcSeg1,pMdcSeg2,pSplineTrack); //finally we fill HRKTrackB
} // end while pMetaMatch loop
return 0;
}
Int_t HRKTrackBF::calcPosDirFromSegment(HMdcSeg* pSeg,Int_t ioseg, Double_t* pos, Double_t* dir) {
// calculates the initial point and direction from a MDC track segment
// If a hit index in the outer segment is -1, the error is set to -1.
// This hit will then be discarded in Runge Kutta. For not fitted outer
// segments, the hits get larger errors.
Int_t index[2]={pSeg->getHitInd(0),pSeg->getHitInd(1)};
Int_t nHits=2;
if (ioseg==0) {
for (Int_t i=0;i<2;i++) {
if (index[i]==-1) {
multSig[2*i] = multSig[2*i+1] = -1.;
nHits--;
} else multSig[2*i] = multSig[2*i+1] = 1.;
}
} else {
for (Int_t i=0;i<2;i++) {
if (index[i]==-1) {
multSig[4+2*i] = multSig[4+2*i+1] = -1.;
nHits--;
} else if (pSeg->getChi2()>=0) {
multSig[4+2*i] = multSig[4+2*i+1] = 1.;
} else {
multSig[4+2*i] = multSig[4+2*i+1] = 5.;
}
}
}
if (nHits>0) {
Double_t hpi=TMath::Pi()/2.;
pos[0] = pSeg->getR()*cos(pSeg->getPhi()+hpi); // 1st-tracklet's initial point
pos[1] = pSeg->getR()*sin(pSeg->getPhi()+hpi);
pos[2] = pSeg->getZ();
dir[0] = cos(pSeg->getPhi())*sin(pSeg->getTheta()); // 1st-tracklet's direction
dir[1] = sin(pSeg->getPhi())*sin(pSeg->getTheta());
dir[2] = cos(pSeg->getTheta());
}
return nHits;
}
HRKTrackB* HRKTrackBF::fillData(HMdcSeg* segment1,HMdcSeg* segment2,HSplineTrack* spline) {
// fills the Runge Kutta track object
TObject* slot=0;
HRKTrackB* rkt=0;
Int_t indexRK;
slot=fCatRKTrack->getNewSlot(sectorloc,&indexRK);
if (!slot) {
Error("fillData","No slot available");
} else {
pMetaMatch->setRungeKuttaInd(indexRK); // add index in METAMATCH
rkt=new(slot) HRKTrackB;
rkt->setSector(sector);
rkt->setShowerHitInd(pMetaMatch->getShowerHitInd());
rkt->setTofHitInd(pMetaMatch->getTofHitInd());
rkt->setZ( segment1->getZ() ,segment1->getErrZ() );
rkt->setR( segment1->getR() ,segment1->getErrR() );
rkt->setTheta(segment1->getTheta() ,segment1->getErrTheta() );
rkt->setPhi( segment1->getPhi() ,segment1->getErrPhi() );
rkt->setP(pRK,0.);
rkt->setPolarity(qRK);
rkt->setTof(tof);
rkt->setMetaEloss(metaeloss);
rkt->setTarDist(spline->getTarDist());
rkt->setIOMatching(spline->getIOMatching());
if (success) {
rkt->setChiq(chiqRK);
rkt->setZSeg1RK(pRungeKutta->getZSeg1());
rkt->setRSeg1RK(pRungeKutta->getRSeg1());
rkt->setThetaSeg1RK(pRungeKutta->getThetaSeg1());
rkt->setPhiSeg1RK(pRungeKutta->getPhiSeg1());
rkt->setZSeg2RK(pRungeKutta->getZSeg2());
rkt->setRSeg2RK(pRungeKutta->getRSeg2());
rkt->setThetaSeg2RK(pRungeKutta->getThetaSeg2());
rkt->setPhiSeg2RK(pRungeKutta->getPhiSeg2());
rkt->setTofDist(trackLength);
rkt->setBeta(beta);
rkt->setMass2(mass2, 0.);
rkt->setMETAdx(RKxyzMETA[0]);
rkt->setMETAdy(RKxyzMETA[1]);
rkt->setMETAdz(RKxyzMETA[2]);
} else {
//something failed, or momentum reconstruction was not even called
rkt->setChiq(1000000.);
rkt->setZSeg1RK(segment1->getZ());
rkt->setRSeg1RK(segment1->getR());
rkt->setThetaSeg1RK(segment1->getTheta());
rkt->setPhiSeg1RK(segment1->getPhi());
rkt->setZSeg2RK(segment2->getZ());
rkt->setRSeg2RK(segment2->getR());
rkt->setThetaSeg2RK(segment2->getTheta());
rkt->setPhiSeg2RK(segment2->getPhi());
rkt->setTofDist(spline->getTofDist());
rkt->setBeta( spline->getBeta());
rkt->setMass2( spline->getMass2(), 0.);
rkt->setMETAdx(-10000.);
rkt->setMETAdy(-10000.);
rkt->setMETAdz(-10000.);
}
}
return rkt;
}
ROOT page - Class index - Class Hierarchy - Top of the page
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.