#include "htofhitf.h"
#include "hades.h"
#include "htofraw.h"
#include "htofhit.h"
#include "htofhitsim.h"
#include "htofcalpar.h"
#include "hruntimedb.h"
#include "hcategory.h"
#include "hiterator.h"
#include "hdebug.h"
#include "tofdef.h"
#include "hevent.h"
#include "heventheader.h"
#include "hspectrometer.h"
#include "hdetector.h"
#include "hgeomvolume.h"
#include "hgeomcompositevolume.h"
#include "hgeomtransform.h"
#include "htofgeompar.h"
#include "hdetgeompar.h"
#include "hgeomvector.h"
#include "hspecgeompar.h"
#include "hstart2hit.h"
#include "hstartdef.h"
#include "TMath.h"
void HTofHitF::initParContainer(HSpectrometer *spec, HRuntimeDb *rtdb) {
fCalPar=(HTofCalPar *)rtdb->getContainer("TofCalPar");
fTofGeometry=(HTofGeomPar *)rtdb->getContainer("TofGeomPar");
fSpecGeometry = (HSpecGeomPar *)rtdb->getContainer("SpecGeomPar");
}
HTofHitF::HTofHitF(void) {
fCalPar = NULL;
fCalParSim = NULL;
fRawCat = fHitCat = NULL;
fRawCatTmp = fHitCatTmp = NULL;
fStartHitCat = NULL;
fTofSimulation = kFALSE;
fLoc.set(3,0,0,0);
iter = NULL;
iterTmp = NULL;
}
HTofHitF::HTofHitF(const Text_t *name,const Text_t *title) : HReconstructor (name,title) {
fCalPar = NULL;
fCalParSim = NULL;
fRawCat = fHitCat = NULL;
fRawCatTmp = fHitCatTmp = NULL;
fStartHitCat = NULL;
fTofSimulation = kFALSE;
fLoc.set(3,0,0,0);
iter = NULL;
iterTmp = NULL;
}
HTofHitF::~HTofHitF(void) {
if(iter) delete iter;
}
HTofHit *HTofHitF::makeHit(TObject *address) {
return new(address) HTofHit;
}
void HTofHitF::fillHit(HTofHit *hit, HTofRaw *raw) {
}
Bool_t HTofHitF::init(void) {
Bool_t r=kTRUE;
HSpectrometer *spec = gHades->getSetup();
HRuntimeDb *rtdb = gHades->getRuntimeDb();
HEvent *ev = gHades->getCurrentEvent();
printf("initialization of Tof hit finder\n");
if (spec && rtdb && ev) {
HDetector *tof = spec->getDetector("Tof");
if (tof) {
initParContainer(spec,rtdb);
fRawCat = ev->getCategory(catTofRaw);
if (!fRawCat) {
fRawCat= tof->buildCategory(catTofRaw);
if (!fRawCat) return kFALSE;
else ev->addCategory(catTofRaw,fRawCat,"Tof");
}
iter=(HIterator*)fRawCat->MakeIterator("native");
fHitCat = ev->getCategory(catTofHit);
if (!fHitCat) {
fHitCat = spec->getDetector("Tof")->buildCategory(catTofHit);
if (!fHitCat) return kFALSE;
else ev->addCategory(catTofHit,fHitCat,"Tof");
}
} else {
Error("init","TOF setup is not defined");
r = kFALSE;
}
fStartHitCat = ev->getCategory(catStart2Hit);
if (!fStartHitCat) Warning("init","Start hit level not defined; setting start time to 0");
} else {
Error("init","Setup, RuntimeDb or event structure not found");
r = kFALSE;
}
return r;
}
Int_t HTofHitF::execute(void) {
#if DEBUG_LEVEL>2
gDebuger->enterFunc("HTofHitF::execute");
#endif
Bool_t sim=kFALSE;
if ( fTofSimulation) sim=kTRUE;
else if (!fTofSimulation) sim=kFALSE;
if( !( gHades->getEmbeddingMode()>0 && gHades->getEmbeddingDebug() == 1) ) fillHitCat(sim,kFALSE);
if(fTofSimulation&&gHades->getEmbeddingMode()>0){
fillHitCat(kTRUE,kTRUE);
mergeHitCats(sim,kTRUE);
}
#if DEBUG_LEVEL>2
gDebuger->leaveFunc("HTofHitF::execute");
#endif
return 0;
}
void HTofHitF::fillGeometry(HTofHit *hit) {
HGeomVector rLocal,r;
Float_t d,phi,theta;
Float_t rad2deg = 180./TMath::Pi();
HModGeomPar *module=fTofGeometry->getModule(hit->getSector(),hit->getModule());
HGeomTransform &trans = module->getLabTransform();
HGeomVolume *rodVol=module->getRefVolume()->getComponent(hit->getCell());
HGeomTransform &rodTrans=rodVol->getTransform();
r.setX(hit->getXpos());
r.setY(0.);
r.setZ(0.);
rLocal=rodTrans.transFrom(r);
r=trans.transFrom(rLocal);
HGeomVolume *tv=fSpecGeometry->getTarget(0);
if (tv) r -= tv->getTransform().getTransVector();
d = r.length();
theta = (d>0.) ? (rad2deg * TMath::ACos(r.getZ() / d)) : 0.;
phi = rad2deg * TMath::ATan2( r.getY(), r.getX());
if (phi < 0.) phi += 360.;
if (tv) r += tv->getTransform().getTransVector();
hit->setXYZLab(r.getX(), r.getY(), r.getZ());
hit->setDistance( d );
hit->setTheta(theta);
hit->setPhi(phi);
}
void HTofHitF::fillHitCat(Bool_t sim,Bool_t embed)
{
Float_t atofCorr = 0.000000276;
HTofRaw *raw=NULL;
HTofHit *hit=NULL;
HStart2Hit *sH=NULL;
Float_t atof;
Float_t axpos;
Float_t startTime=0.0;
Float_t startTimeSmearing=0.0;
Float_t subCl=0.0;
Float_t subCr=0.0;
Float_t slopeAdcL;
Float_t slopeAdcR;
Float_t xposAdc;
Float_t depE;
Float_t leftA;
Float_t rightA;
Float_t twalk,twalk_pos;
Int_t flagadc;
startTime = 0.0;
startTimeSmearing = 0.0;
if (fStartHitCat && fStartHitCat->getEntries()>0) {
if((sH = (HStart2Hit *) fStartHitCat->getObject(0)) != NULL){
startTime = sH->getTime();
if(sH->getResolution()!=-1000) startTimeSmearing = sH->getResolution();
}
}
HIterator* iterLocal;
HCategory* catHitLocal;
HTofCalPar* calparLocal;
Bool_t isRealData = kFALSE;
if((sim && !embed && gHades->getEmbeddingMode() >0) ||
(!sim && !embed)) isRealData = kTRUE;
if(sim&&embed) iterLocal=iterTmp;
else iterLocal=iter;
if(sim&&embed) catHitLocal=fHitCatTmp;
else catHitLocal=fHitCat;
if(sim&&embed) calparLocal=fCalParSim;
else calparLocal=fCalPar;
Float_t startTimeLocal = startTime;
if(!isRealData) startTimeLocal = startTimeSmearing;
iterLocal->Reset();
while ( (raw=(HTofRaw *)iterLocal->Next())!=NULL) {
fLoc[0]=raw->getSector();
fLoc[1]=raw->getModule();
fLoc[2]=raw->getCell();
if(raw->getLeftTime() && raw->getRightTime()){
hit = (HTofHit *)catHitLocal->getSlot(fLoc);
if (hit) {
hit=makeHit(hit);
HTofCalParCell& cell=(*calparLocal)[fLoc[0]][fLoc[1]][fLoc[2]];
atof = (raw->getLeftTime() * cell.getLeftK() +
raw->getRightTime()*cell.getRightK())/2.0 - cell.getTimK();
atof -= startTimeLocal;
axpos = cell.getVGroup()*(raw->getRightTime() * cell.getRightK() -
raw->getLeftTime()*cell.getLeftK())/2.0 +cell.getPosK();
if(isRealData){
atof = atof + (axpos*axpos*atofCorr);
}
xposAdc=0.0;
depE=0.0;
leftA=0.0;
rightA=0.0;
flagadc=0;
twalk=0.;
twalk_pos=0.;
if (!isRealData) {
if (raw->getLeftCharge()) subCl = (raw->getLeftCharge() - cell.getPedestalL());
if (raw->getRightCharge()) subCr = (raw->getRightCharge() - cell.getPedestalR());
}
if (isRealData) {
subCl = tot2amp(raw->getLeftCharge() - cell.getPedestalL());
subCr = tot2amp(raw->getRightCharge() - cell.getPedestalR());
}
slopeAdcL = (cell.getEdepK())*(TMath::Exp((cell.getGainAsym())/(cell.getAttLen())));
slopeAdcR = (cell.getEdepK())*(TMath::Exp(-(cell.getGainAsym())/(cell.getAttLen())));
leftA=subCl*slopeAdcL;
rightA=subCr*slopeAdcR;
if(subCl>0){
flagadc=-1;
depE=(subCl*cell.getEdepK())*(TMath::Exp((cell.getGainAsym()-axpos)/(cell.getAttLen())));
twalk=-(cell.getTimeWalkC1()/(TMath::Sqrt(leftA)));
twalk_pos=(cell.getTimeWalkC1()/(TMath::Sqrt(leftA)));
}
else {
twalk=-(cell.getTimeWalkC1()/(TMath::Sqrt(0.35)));
twalk_pos=(cell.getTimeWalkC1()/(TMath::Sqrt(0.35)));
}
if(subCr>0){
flagadc=1;
depE=(subCr*cell.getEdepK())*(TMath::Exp((axpos-cell.getGainAsym())/(cell.getAttLen())));
twalk=twalk-(cell.getTimeWalkC2()/(TMath::Sqrt(rightA)));
twalk_pos=twalk_pos-(cell.getTimeWalkC2()/(TMath::Sqrt(rightA)));
}
else {
twalk=twalk-(cell.getTimeWalkC2()/(TMath::Sqrt(0.35)));
twalk_pos=twalk_pos-(cell.getTimeWalkC2()/(TMath::Sqrt(0.35)));
}
if(subCl>0 && subCr>0) {
flagadc=2;
xposAdc=(cell.getAttLen()/2.0)*(TMath::Log(subCl/subCr)) + cell.getGainAsym();
depE=(cell.getEdepK())*(TMath::Sqrt(subCl*subCr));
}
if(isRealData){
atof = atof + twalk/2.;
axpos = axpos + cell.getVGroup()*twalk_pos/2.;
}
hit->setSector((Char_t) fLoc[0]);
hit->setModule((Char_t) fLoc[1]);
hit->setCell((Char_t) fLoc[2]);
hit->setTof(atof);
hit->setXpos(axpos);
hit->setXposAdc(xposAdc);
hit->setEdep(depE);
hit->setLeftAmp(leftA);
hit->setRightAmp(rightA);
hit->setAdcFlag(flagadc);
fillHit(hit,raw);
fillGeometry(hit);
}
}
}
}
void HTofHitF::mergeHitCats(Bool_t sim,Bool_t embed)
{
HTofHitSim* hit;
HTofHitSim* hittmp;
HTofCalPar* calparLocal;
if(sim&&embed) calparLocal=fCalParSim;
else calparLocal=fCalPar;
TIterator* hititer=fHitCatTmp->MakeIterator("native");
hititer->Reset();
while ( (hittmp=(HTofHitSim *)hititer->Next())!=NULL)
{
fLoc[0]=hittmp->getSector();
fLoc[1]=hittmp->getModule();
fLoc[2]=hittmp->getCell();
hit= (HTofHitSim*) fHitCat->getObject(fLoc);
if(hit)
{
if(gHades->getEmbeddingMode()==1)
{
HTofCalParCell& cell=(*calparLocal)[fLoc[0]][fLoc[1]][fLoc[2]];
Float_t rTime1 = hit->getXpos()/cell.getVGroup() + hit->getTof();
Float_t lTime1 = hit->getXpos()/cell.getVGroup() - hit->getTof();
Float_t rTime2 = hittmp->getXpos()/cell.getVGroup() + hittmp->getTof();
Float_t lTime2 = hittmp->getXpos()/cell.getVGroup() - hittmp->getTof();
Float_t rTime = rTime1;
Float_t lTime = lTime1;
if(rTime>rTime2) rTime = rTime2;
if(lTime>lTime2) lTime = lTime2;
Float_t tof = (lTime + rTime)/2.;
Float_t xpos = cell.getVGroup() * (rTime - lTime)/2.;
hit->setTof(tof);
hit->setXpos(xpos);
hit->setEdep (hit->getEdep() + hittmp->getEdep());
hit->setLeftAmp (hit->getLeftAmp() + hittmp->getLeftAmp());
hit->setRightAmp(hit->getRightAmp()+ hittmp->getRightAmp());
hit->setNTrack2(hittmp->getNTrack1());
}
else if(gHades->getEmbeddingMode() == 2) {
new (hit) HTofHitSim(*hittmp);
} else {
Error("mergeHitCats()","Unknow embedding mode = %i",gHades->getEmbeddingMode()) ;
}
}
else
{
hit= (HTofHitSim*) fHitCat->getSlot(fLoc);
if(hit)
{
new (hit)HTofHitSim(*hittmp);
}
else
{
Error("mergeHitCats()","Could not retrieve slot in catTofHit!");
}
}
}
delete hititer;
}
ClassImp(HTofHitF)
Float_t HTofHitF::tot2amp(Float_t tot)
{
Float_t amp = -1.;
if(tot<150) amp = 3.0 * tot;
else amp = 128. + 2.14 * tot;
return amp;
}