#include "htofhitf2.h"
#include "hades.h"
#include "htofraw.h"
#include "htofrawsim.h"
#include "htofhit.h"
#include "htofhitsim.h"
#include "htofcalpar.h"
#include "htofwalkpar.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 "htofdetector.h"
#include "hgeomvolume.h"
#include "hgeomcompositevolume.h"
#include "hgeomtransform.h"
#include "htofgeompar.h"
#include "htofdigipar.h"
#include "hdetgeompar.h"
#include "hgeomvector.h"
#include "hspecgeompar.h"
#include "hstart2hit.h"
#include "hstartdef.h"
#include "TMath.h"
using namespace std;
#include <fstream>
#include <iomanip>
ClassImp(HTofHitF2)
Bool_t HTofHitF2::bforceKeepGeant=kFALSE;
HTofHitF2::HTofHitF2(void)
{
fCalPar = NULL;
fCalParSim = NULL;
fTofWalkPar = NULL;
fRawCat = fHitCat = NULL;
fRawCatTmp = fHitCatTmp = NULL;
fStartHitCat = NULL;
fTofSimulation = kFALSE;
fLoc.set(3,0,0,0);
iter = NULL;
iterTmp = NULL;
fDigiPar = NULL;
}
HTofHitF2::HTofHitF2(const Text_t *name,const Text_t *title) : HReconstructor (name,title)
{
fCalPar = NULL;
fCalParSim = NULL;
fTofWalkPar = NULL;
fDigiPar = NULL;
fRawCat = fHitCat = NULL;
fRawCatTmp = fHitCatTmp = NULL;
fStartHitCat = NULL;
fTofSimulation = kFALSE;
fLoc.set(3,0,0,0);
iter = NULL;
iterTmp = NULL;
}
HTofHitF2::~HTofHitF2(void)
{
if(iter) delete iter;
if(iterTmp) delete iterTmp;
}
void HTofHitF2::initParContainer(HSpectrometer *spec, HRuntimeDb *rtdb)
{
fCalPar = (HTofCalPar *) rtdb->getContainer("TofCalPar");
fTofGeometry = (HTofGeomPar *) rtdb->getContainer("TofGeomPar");
fSpecGeometry = (HSpecGeomPar *)rtdb->getContainer("SpecGeomPar");
fDigiPar = (HTofDigiPar *) rtdb->getContainer("TofDigiPar");
if(!fTofSimulation || ( fTofSimulation && gHades->getEmbeddingMode()>0) ){
fTofWalkPar = (HTofWalkPar *) rtdb->getContainer("TofWalkPar");
fTofWalkPar->getContainers();
}
return;
}
Bool_t HTofHitF2::init(void)
{
Bool_t r=kTRUE;
HSpectrometer *spec = gHades->getSetup();
HRuntimeDb *rtdb = gHades->getRuntimeDb();
HEvent *ev = gHades->getCurrentEvent();
if (spec && rtdb && ev) {
HTofDetector *tof =(HTofDetector*) spec->getDetector("Tof");
if(ev->getCategory(catGeantKine)) fTofSimulation=kTRUE;
if (tof) {
initParContainer(spec,rtdb);
fRawCat = ev->getCategory(catTofRaw);
if (!fRawCat) {
if (!fRawCat) return kFALSE;
}
iter=(HIterator*)fRawCat->MakeIterator("native");
fStartHitCat = ev->getCategory(catStart2Hit);
if (!fStartHitCat) Warning("init","Start hit level not defined; setting start time to 0");
if(!fTofSimulation){
fHitCat = ev->getCategory(catTofHit);
if (!fHitCat) {
fHitCat = tof->buildCategory(catTofHit);
if (!fHitCat) return kFALSE;
else ev->addCategory(catTofHit,fHitCat,"Tof");
}
} else {
fHitCat=ev->getCategory(catTofHit);
if (!fHitCat) {
fHitCat=tof->buildMatrixCategory("HTofHitSim",0.5F);
if (!fHitCat) return kFALSE;
else ev->addCategory(catTofHit,fHitCat,"Tof");
} else {
if (fHitCat->getClass()!=HTofHitSim::Class()) {
Error("HTofHitfSim::init()","Misconfigured output category");
return kFALSE;
}
}
}
if(fTofSimulation && gHades->getEmbeddingMode()>0)
{
fRawCatTmp =ev->getCategory(catTofRawTmp);
if(!fRawCatTmp){
Error("init()","No catTofRawTmp in input! You are in embedding mode!");
return kFALSE;
}
iterTmp = (HIterator*)fRawCatTmp->MakeIterator();
fHitCatTmp=ev->getCategory(catTofHitTmp);
if (!fHitCatTmp) {
fHitCatTmp=tof->buildMatrixCategory("HTofHitSimTmp",0.5F);
if (!fHitCatTmp) {
Error("init()","Could no build catTofHitTmp !");
return kFALSE;
}
else ev->addCategory(catTofHitTmp,fHitCatTmp,"Tof");
fHitCatTmp->setPersistency(kFALSE);
}
fCalParSim = new HTofCalPar("TofCalPar_Sim_Embedding","","TofCalProductionSimEmbedding");
if(fCalParSim)rtdb->addContainer(fCalParSim);
else {
Error("init()","Could no create HTofCalPar for sim params, needed for embedding !");
}
}
} else {
Error("init","TOF setup is not defined");
r = kFALSE;
}
} else {
Error("init","Setup, RuntimeDb or event structure not found");
r = kFALSE;
}
return r;
}
Int_t HTofHitF2::execute(void)
{
#if DEBUG_LEVEL>2
gDebuger->enterFunc("HTofHitF2::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("HTofHitF2::execute");
#endif
return 0;
}
void HTofHitF2::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 HTofHitF2::fillHitCat(Bool_t sim,Bool_t embed)
{
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) {
if(fTofSimulation) hit=new (hit) HTofHitSim;
else hit=new (hit) HTofHit;
HTofCalParCell& cell =(*calparLocal)[fLoc[0]][fLoc[1]][fLoc[2]];
if (isRealData) {
fTofWalkPar->getTofPos(raw, atof, axpos, 0., startTimeLocal);
Float_t postemp = axpos;
fTofWalkPar->getTofPos(raw, atof, axpos, postemp, startTimeLocal);
postemp = axpos;
fTofWalkPar->getTofPos(raw, atof, axpos, postemp, startTimeLocal);
postemp = axpos;
fTofWalkPar->getTofPos(raw, atof, axpos, postemp, startTimeLocal);
postemp = axpos;
fTofWalkPar->getTofPos(raw, atof, axpos, postemp, startTimeLocal);
postemp = axpos;
fTofWalkPar->getTofPos(raw, atof, axpos, postemp, startTimeLocal);
} else {
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();
}
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));
}
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);
if(fTofSimulation) {
HTofHitSim *hs=(HTofHitSim *)hit;
HTofRawSim *rs=(HTofRawSim *)raw;
hs->setNTrack1(rs->getNTrack1());
hs->setNTrack2(rs->getNTrack2());
}
fillGeometry(hit);
}
}
}
}
void HTofHitF2::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 && !bforceKeepGeant)
{
HTofCalParCell& cell =(*calparLocal)[fLoc[0]][fLoc[1]][fLoc[2]];
HTofDigiParCell& celldigi=(*fDigiPar) [fLoc[0]][fLoc[1]][fLoc[2]];
Float_t rTime1 = (celldigi.getHalfLen() + hit->getXpos())/cell.getVGroup() + hit->getTof();
Float_t lTime1 = (celldigi.getHalfLen() - hit->getXpos())/cell.getVGroup() + hit->getTof();
Float_t rTime2 = (celldigi.getHalfLen() + hittmp->getXpos())/cell.getVGroup() + hittmp->getTof();
Float_t lTime2 = (celldigi.getHalfLen() - 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. - celldigi.getHalfLen()/cell.getVGroup();
Float_t xpos = cell.getVGroup() * (rTime - lTime)/2.;
hit->setTof(tof);
hit->setXpos(xpos);
fillGeometry(hit);
hit->setEdep (hit->getEdep() + hittmp->getEdep());
hit->setLeftAmp (hit->getLeftAmp() + hittmp->getLeftAmp());
hit->setRightAmp(hit->getRightAmp()+ hittmp->getRightAmp());
if(hittmp->getNTrack1()==hittmp->getNTrack2()){
hit->setNTrack2(hittmp->getNTrack1());
} else {
hit->setNTrack1(hittmp->getNTrack1());
hit->setNTrack2(hittmp->getNTrack2());
}
}
else if(gHades->getEmbeddingMode() == 2 || (gHades->getEmbeddingMode()==1 && bforceKeepGeant) ) {
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;
}
Float_t HTofHitF2::tot2amp(Float_t tot)
{
Float_t amp = -1.;
if(tot<150) amp = 3.0 * tot;
else amp = 128. + 2.14 * tot;
return amp;
}