#include "hkickdetdigi.h"
#include "hades.h"
#include "hcategory.h"
#include "hmatrixcategory.h"
#include "hdetector.h"
#include "hevent.h"
#include "htofdetector.h"
#include "hspectrometer.h"
#include "hruntimedb.h"
#include "hmdcgeompar.h"
#include "hmdchitsim.h"
#include "hdetector.h"
#include "htofhitsim2.h"
#include "hgeantmdc.h"
#include "hgeanttof.h"
#include "hgeantkine.h"
#include "hgeomtransform.h"
#include "hgeomvolume.h"
#include "hgeomcompositevolume.h"
#include "hgeomvector.h"
#include "hiterator.h"
#include "hgeomrotation.h"
#include "hmdcsegsim.h"
#include "hspecgeompar.h"
#include "hmdcdef.h"
#include "TRandom.h"
#include "TF1.h"
HKickDetDigi::HKickDetDigi(const Text_t name[],const Text_t title[]) :
HReconstructor(name,title) {
fMdcInput=0;
fMdcOut=0;
fMdcIter=0;
fTofInput=0;
fTofOut=0;
fTofIter=0;
fFillTof=kTRUE;
fIsTofPerfect = fIsMdcPerfect = kFALSE;
setMdcAngErrConst(kFALSE);
fFillSegments[0] = fFillSegments[1] = kTRUE;
fFillMdc = kTRUE;
fMomPos = 0;
fSimulateTails = kFALSE;
fFillMdcHits = kTRUE;
for (Int_t i=0;i<4;i++) {
probDistrX[i]=0;
probDistrY[i]=0;
}
fMdcResolX[0] = .16;
fMdcResolX[1] = .16;
fMdcResolX[2] = .16;
fMdcResolX[3] = .16;
fMdcResolY[0] = .08;
fMdcResolY[1] = .08;
fMdcResolY[2] = .08;
fMdcResolY[3] = .08;
fMdcTailX[0] = 3;
fMdcTailX[1] = 3;
fMdcTailX[2] = 3;
fMdcTailX[3] = 3;
fMdcTailY[0] = 1;
fMdcTailY[1] = 1;
fMdcTailY[2] = 1;
fMdcTailY[3] = 1;
}
HKickDetDigi::~HKickDetDigi(void) {
if (fMdcIter) delete fMdcIter;
if (fTofIter) delete fTofIter;
}
Int_t HKickDetDigi::execute(void) {
if (fMdcInput) digiMdc2();
if (fTofInput && isFillingTof()) digiTof();
return 0;
}
Int_t HKickDetDigi::digiTof(void) {
HGeantTof *geTof=0;
HTofHitSim2 *tofHit=0;
Float_t x,y,en,tof,tofResol=0.1;
Float_t posResol = 15.5;
HLocation loc;
HGeantKine *geKine=0;
Int_t trackN,pid;
Float_t px=0,py=0,pz=0,mom,len;
loc.set(3,0,0,0);
fTofIter->Reset();
while ( (geTof=(HGeantTof *)fTofIter->Next()) != 0) {
geTof->getHit(en,x,y,tof,mom,len);
if (!isTofPerfect()) x+=gRandom->Gaus(0,posResol);
loc[0]=geTof->getSector();
loc[1]=21 - geTof->getModule();
loc[2]=7 - geTof->getCell();
if (loc[1]<0) continue;
if (tof>50) continue;
tofHit=(HTofHitSim2 *)fTofOut->getObject(loc);
if (!tofHit) {
tofHit=(HTofHitSim2 *)fTofOut->getSlot(loc);
if (tofHit) {
tofHit=new (tofHit) HTofHitSim2;
tofHit->setNHits(1);
tofHit->setXpos(x);
if (isTofPerfect()) tofHit->setY(y);
tofHit->setTof(tof+gRandom->Gaus(0,tofResol));
tofHit->setSector(loc[0]);
tofHit->setModule(loc[1]);
tofHit->setCell(loc[2]);
if (tofHit->getNTrack1() > 0) {
tofHit->setNTrack2(geTof->getTrack());
} else {
tofHit->setNTrack1(geTof->getTrack());
}
geKine=(HGeantKine *)fCatKine->getObject(geTof->getTrack()-1);
if (geKine) {
geKine->getMomentum(px,py,pz);
geKine->getParticle(trackN,pid);
tofHit->setPid(pid);
tofHit->setMomentum(mom);
}
}
} else {
geKine=(HGeantKine *)fCatKine->getObject(geTof->getTrack()-1);
if (geKine) {
Int_t parent,medium,mech;
geKine->getCreator(parent,medium,mech);
if (tof < tofHit->getTof()) {
tofHit->setXpos(x);
tofHit->setTof(tof);
if (isTofPerfect()) tofHit->setY(y);
tofHit->setSector(loc[0]);
tofHit->setModule(loc[1]);
tofHit->setCell(loc[2]);
if (tofHit->getNTrack1()==0) {
tofHit->setNTrack1(geTof->getTrack());
} else
tofHit->setNTrack2(geTof->getTrack());
geKine->getMomentum(px,py,pz);
geKine->getParticle(trackN,pid);
tofHit->setPid(pid);
tofHit->setMomentum(TMath::Sqrt(px*px+py*py+pz*pz));
}
}
}
}
return 0;
}
Int_t HKickDetDigi::digiMdc2(void) {
const Int_t theModule=0,theLayer=6;
HGeantMdc *geMdc=0,*geMdc2;
HGeantKine *geKine=0;
Int_t mdcSector=0,mdcModule=0,mdcLayer=0;
Int_t trackN,pid;
Float_t x=0,y=0,tof=0,px=0,py=0,pz=0;
Float_t x2=0,y2=0,mom=0,mom2=0;
HGeomVector rLocal,r,alpha;
fMdcIter->Reset();
while ( (geMdc=(HGeantMdc *)fMdcIter->Next()) != 0) {
mdcSector=geMdc->getSector();
mdcModule=geMdc->getModule();
mdcLayer=geMdc->getLayer();
if (mdcModule % 2 == theModule && mdcLayer == theLayer) {
geMdc2 = findPartner(geMdc,mdcSector,mdcModule+1,mdcLayer);
if (geMdc2) {
geMdc->getHit(x,y,tof,mom);
geMdc2->getHit(x2,y2,tof,mom2);
if (!isMdcPerfect()) {
x += probDistrX[(Int_t)geMdc->getModule()]->GetRandom();
y += probDistrY[(Int_t)geMdc->getModule()]->GetRandom();
x2 += probDistrX[(Int_t)geMdc2->getModule()]->GetRandom();
y2 += probDistrY[(Int_t)geMdc2->getModule()]->GetRandom();
}
fMdcSectorLoc[0]=mdcSector;
fMdcSecModLoc[0]=mdcSector; fMdcSecModLoc[1]=mdcModule / 2;
calcPosDir(geMdc,geMdc2,x,y,x2,y2,r,alpha);
geKine=(HGeantKine *)fCatKine->getObject(geMdc->getTrack()-1);
if (geKine) {
if (fFillSegments[fMdcSecModLoc[1]]) {
geKine->getParticle(trackN,pid);
if (trackN != geMdc->getTrack())
Warning("digiMdc","Inconsistent trackN");
geKine->getMomentum(px,py,pz);
switch (fMomPos) {
case 0:
fillData(r,alpha,TMath::Sqrt(px*px + py*py + pz*pz),
geMdc->getTrack());
break;
case 1:
fillData(r,alpha,mom,geMdc->getTrack());
break;
case 2:
fillData(r,alpha,mom2,geMdc->getTrack());
break;
default:
Warning("","Momentum determination position unknown");
}
}
if (fFillMdcHits) {
fMdcSecModLoc[1]=geMdc->getModule();
fillHit(geMdc, x, y,TMath::Sqrt(px*px + py*py + pz*pz));
fMdcSecModLoc[1]=geMdc2->getModule();
fillHit(geMdc2, x2, y2,TMath::Sqrt(px*px + py*py + pz*pz));
}
} else { Error("digiMdc","Inconsistent track number"); return 1;}
} else {
fMdcSecModLoc[1]=geMdc->getModule();
geMdc->getHit(x,y,tof,mom);
if (!isMdcPerfect()) {
x += probDistrX[(Int_t)geMdc->getModule()]->GetRandom();
y += probDistrY[(Int_t)geMdc->getModule()]->GetRandom();
}
if (fFillMdcHits) {
fillHit(geMdc,x,y,TMath::Sqrt(px*px+py*py+pz*pz));
}
}
}
}
return 0;
}
void HKickDetDigi::fillHit(HGeantMdc *geMdc, Float_t x, Float_t y, Float_t p) {
Float_t xDir, yDir,zDir;
Float_t theta,phi;
Float_t sigma_sx = 0.01;
Float_t sigma_sy = 0.01;
Double_t k = TMath::Pi() / 180.;
TObject *slot = 0;
HMdcHitSim *hit;
HGeomVector alpha;
Int_t lsTracks[5];
UChar_t lsTimes[5];
Double_t Sx,Sy;
geMdc->getIncidence(theta,phi);
if (!isMdcPerfect()) {
if(isMdcAngErrConst()){
Float_t resTheta = 0.02;
Float_t t2,p2;
HGeomRotation rot;
rot.setElement( cos(k*theta)*cos(k*phi) , 0);
rot.setElement( -sin(k*phi) , 1);
rot.setElement( sin(k*theta)*cos(k*phi) , 2);
rot.setElement( cos(k*theta)*sin(k*phi) , 3);
rot.setElement( cos(k*phi) , 4);
rot.setElement( sin(k*theta)*sin(k*phi) , 5);
rot.setElement( -sin(k*theta) , 6);
rot.setElement( 0 , 7);
rot.setElement( cos(k*theta) , 8);
t2 = gRandom->Gaus(0,resTheta);
p2 = gRandom->Uniform(2*360);
HGeomVector
withError(sin(k*t2)*cos(k*p2),sin(k*t2)*sin(k*p2),cos(k*t2));
HGeomVector withErrorInMDC = rot * withError;
theta = acos(withErrorInMDC.getZ()) / k;
phi = atan2(withErrorInMDC.getY(),withErrorInMDC.getX()) / k;
}
}
theta *= k;
phi *= k;
slot = fMdcHitOut->getNewSlot(fMdcSecModLoc);
if (slot != 0) {
hit = new(slot) HMdcHitSim;
alpha.setX(TMath::Sin(theta) * TMath::Cos(phi));
alpha.setY(TMath::Sin(theta) * TMath::Sin(phi));
alpha.setZ(TMath::Cos(theta));
Sx = alpha.getX() / alpha.getZ();
Sy = alpha.getY() / alpha.getZ();
if (!isMdcPerfect()) {
Sy += gRandom->Gaus(0,sigma_sy);
Sx += gRandom->Gaus(0,sigma_sx);
}
xDir = Sx / sqrt(1+Sx*Sx+Sy*Sy);
yDir = Sy / sqrt(1+Sx*Sx+Sy*Sy);
zDir = 1. / sqrt(1+Sx*Sx+Sy*Sy);
Float_t cov_x_x, cov_y_y, cov_ax_ax, cov_ay_ay,cov_ax_ay;
if (isMdcPerfect()) {
cov_x_x = cov_y_y = cov_ax_ax = cov_ay_ay = cov_ax_ay = 0;
} else {
Float_t d_ax_sx = (1-xDir)*zDir;
Float_t d_ax_sy = Sx*Sy*zDir;
Float_t d_ay_sy = (1-yDir)*zDir;
cov_x_x = fMdcResolX[fMdcSecModLoc[1]] * fMdcResolX[fMdcSecModLoc[1]];
cov_y_y = fMdcResolY[fMdcSecModLoc[1]] * fMdcResolY[fMdcSecModLoc[1]];
cov_ax_ax = pow(d_ax_sx*sigma_sx,2) + pow(d_ax_sy*sigma_sy,2);
cov_ay_ay = pow(d_ax_sy*sigma_sx,2) + pow(d_ay_sy*sigma_sy,2);
cov_ax_ay = sigma_sx*sigma_sx*d_ax_sx*d_ax_sy + sigma_sy*sigma_sy*d_ay_sy*d_ax_sy;
}
hit->getCovariance().Clear();
hit->setX(x, sqrt(cov_x_x));
hit->setY(y, sqrt(cov_y_y));
hit->setXDir( xDir, sqrt(cov_ax_ax));
hit->setYDir( yDir, sqrt(cov_ay_ay));
hit->getCovariance().setElement(2,3,cov_ax_ay);
hit->setSecMod( fMdcSecModLoc[0], fMdcSecModLoc[1]);
lsTracks[0] = geMdc->getTrack();
lsTimes[0] = 6;
hit->setNTracks(1,lsTracks,lsTimes);
}
}
void HKickDetDigi::fillData(HGeomVector &r,HGeomVector &alpha,
Double_t p,Int_t track) {
HMdcSegSim *mdcSeg=0;
UChar_t nTimes = 12;
TObject *slot=0;
Float_t theta,phi;
slot=fMdcOut->getNewSlot(fMdcSecModLoc);
if (slot != 0) {
mdcSeg = new(slot) HMdcSegSim;
mdcSeg->setSec(fMdcSectorLoc[0]);
mdcSeg->setIOSeg(fMdcSecModLoc[1]);
theta=TMath::ACos(alpha.getZ());
phi=TMath::ATan2(alpha.getY(),alpha.getX());
mdcSeg->setR(r.getY()*TMath::Cos(phi) - r.getX()*TMath::Sin(phi),0.1);
mdcSeg->setZ(-(r.getY()*TMath::Sin(phi) + r.getX()*TMath::Cos(phi))*
alpha.getZ()/TMath::Sin(theta),0.1);
mdcSeg->setThetaPhi(theta,0.1,
phi,0.1);
mdcSeg->getCovariance().setCov(fMdcSegCov);
mdcSeg->setNTracks(1,&track,&nTimes);
} else { Warning("fillData","No slot available"); fMdcSecModLoc.Dump(); }
}
void HKickDetDigi::calcPosDir(HGeantMdc *data, HGeantMdc *data2,
Float_t x, Float_t y, Float_t x2, Float_t y2,
HGeomVector &r,HGeomVector &dir) {
HGeomVector r1,r2,rLocal;
HModGeomPar *module=fGeometry->getModule(data->getSector(), data->getModule());
if (!module) Error("calcDir",
"Module %i:%i invalid\n",
data->getSector(),data->getModule());
HGeomTransform &transMod = module->getLabTransform();
HGeomTransform &transSec = fSpecGeometry->getSector(data->getSector())->getTransform();
HGeomTransform modTrans(transMod);
modTrans.transTo(transSec);
HModGeomPar *module2=fGeometry->
getModule(data2->getSector(),data2->getModule());
if (!module2) Error("calcDir","Module %i:%i invalid\n",
data2->getSector(),data2->getModule());
HGeomTransform &transMod2 = module2->getLabTransform();
HGeomTransform &transSec2 = fSpecGeometry->getSector(data2->getSector())->getTransform();
HGeomTransform modTrans2(transMod2);
modTrans2.transTo(transSec2);
rLocal.setX(x);
rLocal.setY(y);
rLocal.setZ(0.0);
r1 = modTrans.transFrom(rLocal);
rLocal.setX(x2);
rLocal.setY(y2);
rLocal.setZ(0.0);
r2 = modTrans2.transFrom(rLocal);
dir = r2 -r1;
dir /= dir.length();
r.setX( r1.getX() - (dir.getX() / dir.getZ()) * r1.getZ());
r.setY( r1.getY() - (dir.getY() / dir.getZ()) * r1.getZ());
r.setZ( 0. );
Float_t sx = fMdcResolX[(Int_t)data->getModule()] + fMdcResolX[(Int_t)data2->getModule()];
Float_t sy = fMdcResolY[(Int_t)data->getModule()] + fMdcResolY[(Int_t)data2->getModule()];
Float_t dz = r2.getZ() - r1.getZ();
Float_t zadz = r1.getZ() / dz;
sx = sx*sx/4.;
sy = sy*sy/4.;
fMdcSegCov(0,0) = sx*(1+2*zadz*(1+zadz));
fMdcSegCov(0,1) = 0;
fMdcSegCov(0,2) = -(sx/dz)*(1+2*zadz);
fMdcSegCov(0,3) = 0;
fMdcSegCov(1,1) = sy*(1+2*zadz*(1+zadz));
fMdcSegCov(1,2) = 0;
fMdcSegCov(1,3) = -(sy/dz)*(1+2*zadz);
fMdcSegCov(2,2) = 2 * sx / (dz*dz);
fMdcSegCov(2,3) = 0;
fMdcSegCov(3,3) = 2 * sy / (dz*dz);
}
HGeantMdc *HKickDetDigi::findPartner(HGeantMdc *geMdc, Int_t sector,
Int_t mod, Int_t layer) {
HGeantKine *geKine;
HGeantMdc *gePart;
geKine=(HGeantKine *)fCatKine->getObject(geMdc->getTrack()-1);
geKine->resetMdcIter();
while ( (gePart = (HGeantMdc *)geKine->nextMdcHit()) != 0) {
if (gePart->getSector() == sector &&
gePart->getModule() == mod &&
gePart->getLayer() == layer) return gePart;
}
return 0;
}
void HKickDetDigi::setMdcResolution(Float_t x1,Float_t y1,Float_t x2,Float_t y2,
Float_t x3,Float_t y3,Float_t x4,Float_t y4) {
fMdcResolX[0] = x1;
fMdcResolX[1] = x2;
fMdcResolX[2] = x3;
fMdcResolX[3] = x4;
fMdcResolY[0] = y1;
fMdcResolY[1] = y2;
fMdcResolY[2] = y3;
fMdcResolY[3] = y4;
}
void HKickDetDigi::setMdcTails(Float_t x1,Float_t y1,Float_t x2,Float_t y2,
Float_t x3,Float_t y3,Float_t x4,Float_t y4) {
fMdcTailX[0] = x1;
fMdcTailX[1] = x2;
fMdcTailX[2] = x3;
fMdcTailX[3] = x4;
fMdcTailY[0] = y1;
fMdcTailY[1] = y2;
fMdcTailY[2] = y3;
fMdcTailY[3] = y4;
}
Bool_t HKickDetDigi::init(void) {
fMdcSectorLoc.set(1,0);
fMdcSecModLoc.set(2,0,0);
if (gHades) {
HRuntimeDb *rtdb=gHades->getRuntimeDb();
HSpectrometer *spec=gHades->getSetup();
HEvent *event=gHades->getCurrentEvent();
if (rtdb && spec && event) {
HDetector *mdc=spec->getDetector("Mdc");
HTofDetector *tof=(HTofDetector *)spec->getDetector("Tof");
fSpecGeometry = (HSpecGeomPar *)rtdb->getContainer("SpecGeomPar");
if (mdc) {
fCatKine=event->getCategory(catGeantKine);
if (!fCatKine) {
Error("init","catKine not found");
return kFALSE;
}
if (fFillMdc) {
const Float_t tailIntensity = 0.1;
if (fSimulateTails) {
for (Int_t idi=0;idi<4;idi++) {
Char_t buffer[256];
sprintf(buffer,"modx%i",idi);
probDistrX[idi] = new TF1(buffer,"gaus(0)+gaus(3)",-4*fMdcTailX[idi],
4*fMdcTailX[idi]);
probDistrX[idi]->SetParameters(1,0,fMdcResolX[idi],
tailIntensity,0,fMdcTailX[idi]);
sprintf(buffer,"mody%i",idi);
probDistrY[idi] = new TF1(buffer,"gaus(0)+gaus(3)",-4*fMdcTailY[idi],
4*fMdcTailY[idi]);
probDistrY[idi]->SetParameters(1,0,fMdcResolY[idi],
tailIntensity,0,fMdcTailY[idi]);
}
} else {
for (Int_t idi=0;idi<4;idi++) {
Char_t buffer[256];
sprintf(buffer,"modx%i",idi);
probDistrX[idi] = new TF1(buffer,"gaus",-4*fMdcResolX[idi],
4*fMdcResolX[idi]);
probDistrX[idi]->SetParameters(1,0,fMdcResolX[idi]);
sprintf(buffer,"mody%i",idi);
probDistrY[idi] = new TF1(buffer,"gaus(0)",-4*fMdcResolY[idi],
4*fMdcResolY[idi]);
probDistrY[idi]->SetParameters(1,0,fMdcResolY[idi]);
}
}
fMdcInput=event->getCategory(catMdcGeantRaw);
if (!fMdcInput) {
Error("init","MDC input not found");
return kFALSE;
}
if ( (fMdcIter=(HIterator *)fMdcInput->MakeIterator("")) == 0 ) {
Error("init","Unable to build mdc iterator");
return kFALSE;
}
if (fFillSegments[0] || fFillSegments[1]) {
fMdcOut=event->getCategory(catMdcSeg);
if (!fMdcOut) {
Int_t sizes[]={6,2,100};
fMdcOut=new HMatrixCategory("HMdcSegSim",3,sizes,0.5);
if (!event->addCategory(catMdcSeg,fMdcOut,"Mdc")) {
Error("init","Unable to add catMdcSeg to event");
return kFALSE;
}
}
}
fMdcHitOut = event->getCategory(catMdcHit);
if (!fMdcHitOut) {
Int_t sizes[]={6,4,100};
fMdcHitOut=new HMatrixCategory("HMdcHitSim",3,sizes,0.5);
if (!event->addCategory(catMdcHit,fMdcHitOut,"Mdc")) {
Error("init","Unable to add catMdcHit to event");
return kFALSE;
}
}
fGeometry=(HMdcGeomPar *)rtdb->getContainer("MdcGeomPar");
} else fMdcInput=0;
} else fMdcInput=0;
if (tof) {
if (isFillingTof()) {
fTofInput=event->getCategory(catTofGeantRaw);
if (!fTofInput) {
Error("init","No TOF input data from Geant");
return kFALSE;
}
if ((fTofIter=fTofInput->MakeIterator()) == 0) {
Error("init","Unable to build TOF iterator");
return kFALSE;
}
fTofOut=event->getCategory(catTofHit);
if (!fTofOut) {
fTofOut=tof->buildMatrixCategory("HTofHitSim2",0.5);
if (!fTofOut) {
Error("init","Unable to build catTofHit for output");
return kFALSE;
}
event->addCategory(catTofHit,fTofOut,"Tof");
}
}
} else fTofInput=0;
} else {
Error("init","is Framework initialized?");
return kFALSE;
}
} else {
Error("init","gHades not found: panic!");
return kFALSE;
}
return kTRUE;
}
Bool_t HKickDetDigi::finalize(void) {
for (Int_t idi=0;idi<4;idi++) {
delete probDistrX[idi];
probDistrX[idi] = 0;
delete probDistrY[idi];
probDistrY[idi]=0;
}
return kTRUE;
}
ClassImp(HKickDetDigi)
Last change: Sat May 22 12:58:17 2010
Last generated: 2010-05-22 12:58
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.