using namespace std;
#include "TRandom.h"
#include "hemcdigitizer.h"
#include "hdebug.h"
#include "hades.h"
#include "hiterator.h"
#include "hruntimedb.h"
#include "hspectrometer.h"
#include "hemcdetector.h"
#include "hgeantemc.h"
#include "hgeantkine.h"
#include "hevent.h"
#include "hlinearcategory.h"
#include "hemccalsim.h"
#include "hemcgeompar.h"
#include "hemcdigipar.h"
#include "hemccellstatuspar.h"
#include "hemcsimulpar.h"
#include "hstartdef.h"
#include "hstart2hit.h"
#include <iostream>
ClassImp(HEmcDigitizer)
HEmcDigitizer::HEmcDigitizer(void) {
initVariables();
}
HEmcDigitizer::HEmcDigitizer(const Text_t *name, const Text_t *title) : HReconstructor(name,title) {
initVariables();
}
HEmcDigitizer::~HEmcDigitizer(void) {
if (iterGeantEmc) delete iterGeantEmc;
clearCellobjects();
cellobjects.clear();
}
void HEmcDigitizer::initVariables(void) {
fGeantEmcCat = NULL;
fGeantKineCat = NULL;
fCalCat = NULL;
iterGeantEmc = NULL;
fGeomPar = NULL;
fDigiPar = NULL;
fStartHitCat = NULL;
zVertBorder = -130.;
energyDepositCut = 15.;
signalVelocity = 299.792;
halfOfCellLength = 210.;
embeddingmode = 0;
fLoc.setNIndex(2);
fLoc.set(2,0,0);
}
Bool_t HEmcDigitizer::init(void) {
fEmcDet = (HEmcDetector*)(gHades->getSetup()->getDetector("Emc"));
if(!fEmcDet){
Error("init","No Emc Detector found");
return kFALSE;
}
cellobjects.resize(cellObjectsSize(), 0 );
fGeantEmcCat = gHades->getCurrentEvent()->getCategory(catEmcGeantRaw);
if (!fGeantEmcCat) {
Error("HEmcDigitizer::init()","HGeant EMC input missing");
return kFALSE;
}
iterGeantEmc = (HIterator *)fGeantEmcCat->MakeIterator("native");
fGeantKineCat = (HLinearCategory*)gHades->getCurrentEvent()->getCategory(catGeantKine);
if(!fGeantKineCat){
Error("HEmcDigitizer::init()","No catGeantKine in input!");
return kFALSE;
}
fCalCat = gHades->getCurrentEvent()->getCategory(catEmcCal);
if (fCalCat == NULL) {
fCalCat = fEmcDet->buildMatrixCategory("HEmcCalSim",0.5);
gHades->getCurrentEvent()->addCategory(catEmcCal,fCalCat,"Emc");
}
if(fCalCat == NULL) return kFALSE;
if(gHades->getEmbeddingMode()>0) embeddingmode = 1;
fStartHitCat=gHades->getCurrentEvent()->getCategory(catStart2Hit);
if (!fStartHitCat) Warning("init","Start hit level not defined; setting start time to 0");
return setParameterContainers();
}
Bool_t HEmcDigitizer::setParameterContainers(void) {
fGeomPar=(HEmcGeomPar*)gHades->getRuntimeDb()->getContainer("EmcGeomPar");
if (!fGeomPar){
Error("initParContainer","No EmcGeomPar parameter container");
return kFALSE;
}
fDigiPar =(HEmcDigiPar *)gHades->getRuntimeDb()->getContainer("EmcDigiPar");
if (!fDigiPar){
Error("initParContainer","No EmcDigiPar parameter container");
return kFALSE;
}
fSimulPar =(HEmcSimulPar *)gHades->getRuntimeDb()->getContainer("EmcSimulPar");
if (!fSimulPar){
Error("initParContainer","No EmcSimulPar parameter container");
return kFALSE;
}
pStatuspar = (HEmcCellStatusPar*)gHades->getRuntimeDb()->getContainer("EmcCellStatusPar");
if (!pStatuspar) return kFALSE;
return kTRUE;
}
Bool_t HEmcDigitizer::reinit(void) {
sigmaT = fDigiPar->getSigmaT();
phot2Energy[0] = fDigiPar->getPhot2E();
phot2Energy[1] = fDigiPar->getPhot2E2();
Float_t sigmaEIntern = fDigiPar->getSigmaEIntern();
Float_t sigmaEReal = fDigiPar->getSigmaEReal();
Float_t sigmaEReal2 = fDigiPar->getSigmaEReal2();
facEnergSmear[0] = 1000.*TMath::Sqrt(sigmaEReal*sigmaEReal - sigmaEIntern*sigmaEIntern);
facEnergSmear[1] = 1000.*TMath::Sqrt(sigmaEReal2*sigmaEReal2 - sigmaEIntern*sigmaEIntern);
for(Int_t s=0;s<6;s++) labTrans[s] = fGeomPar->getModule(s)->getLabTransform();
return kTRUE;
}
Int_t HEmcDigitizer::execute(void) {
Float_t startTimeSmearing = 0;
if (fStartHitCat && fStartHitCat->getEntries()>0) {
HStart2Hit *pStartH = (HStart2Hit *) fStartHitCat->getObject(0);
if(pStartH != NULL && pStartH->getResolution()!=-1000) {
startTimeSmearing = pStartH->getResolution();
}
}
if(embeddingmode > 0) {
if(gHades->getEmbeddingDebug() == 1) {
fCalCat->Clear();
} else {
Int_t nentr = fCalCat->getEntries();
for(Int_t n=0;n<nentr;n++) {
HEmcCalSim* pCal = (HEmcCalSim*)fCalCat->getObject(n);
Int_t sec = pCal->getSector();
Int_t cell = pCal->getCell();
if (sec<0 || sec>5 || cell<0 || cell>=emcMaxComponents) {
Warning("HEmcDigitizer:execute","EmcCal cell address invalid: sec=%i cell=%i",sec,cell);
continue;
}
Int_t ind = cellObjectIndex(sec,cell);
if(cellobjects[ind] == NULL) {
cellobjects[ind] = new celldata;
cellobjects[ind]->reset();
}
cellobjects[ind]->isEmbeddedReal = kTRUE;
celltrack* celltr = new celltrack;
celltr->reset();
celltr->trackEn = pCal->getEnergy();
celltr->gtime = pCal->getTime();
celltr->gtrack = gHades->getEmbeddingRealTrackId();
cellobjects[ind]->ctracks.push_back(celltr);
}
}
}
iterGeantEmc->Reset();
HGeantEmc* geantemc = 0;
while ((geantemc=(HGeantEmc *)iterGeantEmc->Next())!=0) {
Int_t trackNumber = geantemc->getTrack();
Int_t sec = geantemc->getSector();
Int_t cell = geantemc->getCell();
if (sec<0 || sec>5 || cell<0 || cell>=emcMaxComponents) {
Warning("HEmcDigitizer:execute","Emc Geant cell address invalid: sec=%i cell=%i",sec,cell);
continue;
}
if(trackNumber <= 0 && trackNumber != -777) continue;
Int_t pos = HEmcDetector::getPositionFromCell(cell);
if (pStatuspar->getCellStatus(sec, pos) == 0) continue;
Float_t peHit, xHit, yHit, zHit, tofHit, momHit, trackLength;
geantemc->getHit(peHit, xHit, yHit, zHit, tofHit, momHit, trackLength);
if(peHit == 0.) continue;
Int_t pmtType = fSimulPar->getPmtType(sec,cell);
if(pmtType < 1 || pmtType > 2) continue;
Float_t energyHit = peHit * phot2Energy[pmtType-1];
Int_t ind = cellObjectIndex(sec,cell);
if(cellobjects[ind] == NULL) {
cellobjects[ind] = new celldata;
cellobjects[ind]->reset();
cellobjects[ind]->energy = 0.F;
}
celldata* cdata = cellobjects[ind];
if(trackNumber == -777) {
cdata->energy += energyHit;
} else {
HGeantEmc* pFirstEmc = getInputHit(geantemc,trackNumber);
if(trackNumber <= 0 || pFirstEmc == NULL) continue;
tofHit -= (zHit+halfOfCellLength)/signalVelocity;
Bool_t isInTheList = kFALSE;
Int_t numInpTrack = pFirstEmc->getTrack();
if(std::find((cdata->inputTracks).begin(),(cdata->inputTracks).end(),numInpTrack) != cdata->inputTracks.end()) continue;
cdata->inputTracks.push_back(numInpTrack);
Float_t tofHitD;
pFirstEmc->getHit(peHit, xHit, yHit, zHit, tofHitD, momHit, trackLength);
Int_t pmtType = fSimulPar->getPmtType(sec,cell);
energyHit = peHit * phot2Energy[pmtType-1];
for(UInt_t i=0;i<cdata->ctracks.size();i++) {
celltrack* celltr = cdata->ctracks[i];
if (celltr->gtrack == trackNumber) {
isInTheList = kTRUE;
celltr->trackEn += energyHit;
if (tofHit < celltr->gtime) celltr->gtime = tofHit;
break;
}
}
if( !isInTheList ) {
celltrack* celltr = new celltrack;
celltr->reset();
celltr->trackEn = energyHit;
celltr->gtime = tofHit;
celltr->gtrack = trackNumber;
cdata->ctracks.push_back(celltr);
}
}
}
for(UInt_t i = 0; i < cellobjects.size(); i ++) {
celldata* cdata = cellobjects[i];
if (cdata!=NULL && cdata->energy>0.) {
if(cdata->ctracks.size() == 0) continue;
Int_t cell = cellFromIndex(i);
fLoc[0] = sectorFromIndex(i);
fLoc[1] = cell;
HEmcCalSim* cal = (HEmcCalSim*) fCalCat->getSlot(fLoc);
if (cal == NULL) {
Warning("HEmcDigitizer:execute","HEmcCalSim:getSlot(loc) failed!");
continue;
}
Float_t sigmaE = 0.;
Float_t energy = 0.;
if(cdata->energy > 0.) {
Int_t pmtType = fSimulPar->getPmtType(fLoc[0],cell);
sigmaE = TMath::Sqrt(cdata->energy/1000.) * facEnergSmear[pmtType-1];
energy = gRandom->Gaus(cdata->energy,sigmaE);
}
if(!cdata->isEmbeddedReal) {
cal = new(cal) HEmcCalSim;
cal->setSector(fLoc[0]);
cal->setCell(cell);
Char_t row,col;
fEmcDet->getRowCol(cell,row,col);
cal->setRow(row);
cal->setColumn(col);
} else {
energy += cal->getEnergy();
sigmaE = TMath::Sqrt(sigmaE*sigmaE + cal->getSigmaEnergy()*cal->getSigmaEnergy());
}
cal->setEnergy(energy);
cal->setSigmaEnergy(sigmaE);
if(cal->getEnergy() < energyDepositCut) cal->setStatus(-1);
cdata->sortTime();
Float_t energySum = 0.;
celltrack* celltr = NULL;
for(UInt_t k = 0; k < cdata->ctracks.size(); k++ ) {
celltr = cdata->ctracks[k];
energySum += celltr->trackEn;
if (energySum > energyDepositCut) break;
}
if(!cdata->isEmbeddedReal || gHades->getEmbeddingRealTrackId() != celltr->gtrack) {
cal->setTime(gRandom->Gaus(celltr->gtime,sigmaT) - startTimeSmearing);
cal->setTimeTrack(celltr->gtrack);
cal->setSigmaTime(sigmaT);
}
cdata->sortEnergy();
for(UInt_t k = 0; k < cdata->ctracks.size() && k<5; k++ ) {
celltrack* celltr = cdata->ctracks[k];
cal->setTrack(celltr->gtrack, celltr->trackEn);
}
cal->setNHits(1);
cal->setTotMult(cdata->ctracks.size());
}
}
clearCellobjects();
return 0;
}
void HEmcDigitizer::clearCellobjects(){
for(UInt_t i = 0; i < cellobjects.size(); i++) {
if(cellobjects[i]) cellobjects[i]->reset();
}
}
HGeantEmc* HEmcDigitizer::getInputHit(HGeantEmc* pGeantEmc,Int_t &inputTrack) const {
Int_t track = pGeantEmc->getTrack();
inputTrack = track;
Int_t sec = pGeantEmc->getSector();
Int_t cell = pGeantEmc->getCell();
HGeantKine* kine = (HGeantKine*)fGeantKineCat->getObject(track-1);
HGeantEmc* firstHitInCell = pGeantEmc;
do {
track = kine->getTrack();
Int_t first = kine->getFirstEmcHit();
if(first != -1) {
kine->resetEmcIter();
HGeantEmc* gemc = NULL;
while( (gemc = (HGeantEmc*)kine->nextEmcHit()) != NULL) {
if(gemc->getSector() != sec) continue;
inputTrack = kine->getTrack();
if(gemc->getCell() == cell) {
Float_t peHit,xHit, yHit, zHit, tofHit, momHit, trackLength;
gemc->getHit(peHit, xHit, yHit, zHit, tofHit, momHit, trackLength);
if(peHit > 0.) {
firstHitInCell = gemc;
break;
}
}
}
}
} while((kine = kine->getParent(track,fGeantKineCat)) != NULL);
if(zVertBorder < 0.) {
HGeomVector ver;
kine = (HGeantKine*)fGeantKineCat->getObject(inputTrack-1);
while(kTRUE) {
kine->getVertex(ver);
ver = labTrans[sec].transTo(ver);
if(ver.getZ() < zVertBorder || ver.getZ()>0.) break;
kine = kine->getParent(inputTrack,fGeantKineCat);
if(kine == NULL) break;
inputTrack = kine->getTrack();
}
}
return firstHitInCell;
}