#include "htofclusterf.h"
#include "htofcluster.h"
#include "hades.h"
#include "htofhit.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 "htofclusterfpar.h"
#include <TMath.h>
//*-- Author : 1/12/2001 D.Zovinec
//*-- Modified: 06/03/2002 D.Zovinec
//*-- Modified: 23/09/2002 D.Zovinec
//_HADES_CLASS_DESCRIPTION
//////////////////////////////////////////////////////////////////////////////////////
// HTofClusterF Tof cluster finder
//
// Iterates over the hit level of Tof data and finds a cluster-candidates.
// The cluster-candidate is constructed from set of hits when the following
// binary conditions are satisfied for each pair of hits consecutively
// read from HTofHit based category:
//
// 1.) the hits are close to each other (same sector, adjacent rod)
// 2.) time difference of two hits is less than value taken from HTofClusterFPar
// 3.) xposition difference (in module coordinate system) of two hits is
// less than value taken from HTofClusterFPar
//
// Above binary conditions construct the chain of clustered hits
// from which the output information stored in the HTofCluster category
// is calculated.
//
// The data members inherited from HTofHit class, i.e. tof, xpos, xposAdc,
// lAmp, rAmp, xlab, ylab, zlab is calculated for the cluster here as a weighted
// mean of values appropriate to individual hits participating on cluster-candidate.
// The weight is energy deposited in the rod, i.e. edep.
// The edep of the cluster is sum of the edep's of hits.
// The flagAdc is 2 when all flagAdc flags of appropriate hits
// participating on cluster are = 2. In opposite case flagAdc = 0.
//
// !!! Important: Since the tof rod coordinate systems are shifted each
// other the weighted mean results concerning xpos data member
// would be wrong as it is evaluated in HTofHit relative to this
// reference system. Therefore the appropriate HTofCluster data
// member is evaluated from the position of individual hits
// relative to module reference system. The result stored in
// the HTofCluster is thus given also in module reference system.
// Therefore do not combine the xpos from HTofHit and HTofCluster
// objects without appropriate transformation.
//
// Additional data member is evaluated, i.e. cluster-candidate size
// (clustSize see HTofCluster) that is defined as the number of the hits
// participating on cluster-candidate.
//
// "Simple" hits are also included in the output as the cluster-candidates
// with clustSize = 1.
//
// The probability function for the cluster-candidates of clustSize = 2 with
// tof < tLimit is calculated by using energy deposited of the cluster-candidate.
// Two probability numbers are thus provided, i.e. clustProbAll for
// cluster-candidates related to all ToF hits and clustProbLep for those
// cluster-candidates related to ToF-RICH correlated hits (leptons).
// Both the probability numbers depend on the parameters stored in
// parameter container HTofClusterFPar.
//
//////////////////////////////////////////////////////////////////////////////////////
HTofClusterF::HTofClusterF(void) {
fHitCat = fClusterCat = NULL;
fLoc.set(3,0,0,0);
fpLoc.set(3,0,0,0);
fCLoc.set(3,0,0,0);
iterh = NULL;
iterc = NULL;
}
HTofClusterF::HTofClusterF(Text_t *name,Text_t *title) : HReconstructor (name,title) {
fHitCat = fClusterCat = NULL;
fLoc.set(3,0,0,0);
fpLoc.set(3,0,0,0);
fCLoc.set(3,0,0,0);
iterh = NULL;
iterc = NULL;
}
HTofClusterF::~HTofClusterF(void) {
if(iterh) delete iterh;
if(iterc) delete iterc;
}
Int_t HTofClusterF::execute(void) {
#if DEBUG_LEVEL>2
gDebuger->enterFunc("HTofClusterF::execute");
#endif
Float_t maxTd, maxXd;
cluster=NULL;
hit=NULL;
fpLoc[0] = -1;
fpLoc[1] = -1;
fpLoc[2] = -1;
size_c=1;
tof_ph =0; // in first loop this value has to have default value!
xposMod_ph =0; // in first loop this value has to have default value!
iterh->Reset();
while ( (hit=(HTofHit *)iterh->Next())!=NULL) {
readHit();
maxTd=fClusterFPar->getMaxTDiff();
maxXd=fClusterFPar->getMaxXDiff();
absTd_h=TMath::Abs(tof_h-tof_ph);
absXd_h=TMath::Abs(xposMod_h-xposMod_ph);
if((fLoc[0] == fpLoc[0])&&
(((fLoc[1]*8)+fLoc[2])==((fpLoc[1]*8)+fpLoc[2]+1))&&
(absTd_h < maxTd)&&
(absXd_h < maxXd)){
if(size_c==1){ // If cluster has been found its location is identical with 1st hit in cluster.
fCLoc[0]=fpLoc[0];
fCLoc[1]=fpLoc[1];
fCLoc[2]=fpLoc[2];
}
calcWeightedMean();
size_c++;
} else {
if(size_c > 1){
writeCluster(1);
}
writeCluster(0);
size_c=1;
fillClusterData();
}
fillPreviousData();
}
// if the last hit sentence was cluster than store it
if(size_c>1){
writeCluster(1);
}
writeProb();
#if DEBUG_LEVEL>2
gDebuger->leaveFunc("HTofClusterF::execute");
#endif
return 0;
}
void HTofClusterF::writeProb(void){
// Call the function
// Float_t HTofClusterF::calcProb(Float_t edep, char* aset)
// that calculates probability to be a cluster for cluster-candidates
// of size = 2 and tof < mipLimit stored in HTofClusterFPar.
// Default probabilitites are delivered in this version for
// cluster-candidates of size = 2 that are not in MIP region.
// clustProbAll = 0.896
// clustProbLep = 0.948
// The numbers have been evaluated from the simulation.
// Probability is 1 when cluster-candidate size = 1.
// Probability is -1 when cluster-candidate size > 2.
// Probability is -1 when (cluster-candidate size = 2) & (flagAdc != 2)
//
Float_t probAll_c, probLep_c, dist_c, tofcorr_c, tlimit;
tlimit=fClusterFPar->getMIPLimit();
iterc->Reset();
while ((cluster=(HTofCluster *)iterc->Next())!=NULL) {
probAll_c=-1.0;
probLep_c=-1.0;
size_c=cluster->getClusterSize();
flagAdc_c=cluster->getAdcFlag();
if(size_c==1){
probAll_c=1.0;
probLep_c=1.0;
}
if((size_c==2)&&(flagAdc_c==2)){
tof_c=cluster->getTof();
cluster->getDistance(dist_c);
tofcorr_c = tof_c - (dist_c-2098.5472)/299.792458; // correction on different distances.
if(tofcorr_c<tlimit){
edep_c=cluster->getEdep();
probAll_c=calcProb(edep_c,"all");
probLep_c=calcProb(edep_c,"lep");
} else {
probAll_c=0.896; // hardwired default number from sim
probLep_c=0.948; // hardwired default number from sim
}
}
cluster->setClusterProbAll(probAll_c);
cluster->setClusterProbLep(probLep_c);
}
}
Float_t HTofClusterF::calcProb(Float_t edep, char* aset) {
// Calculates the probability for the cluster-candidates of clustSize = 2
// with tof < mipLimit parameter of HTofClusterFPar.
// The probability is evaluated from the energy deposited in the
// cluster-candidate. Evaluation is based on idea that two hits
// caused by two MIP will deposit energy = 2 in ADC calibrated
// spectrum while in case of one incident MIP causing two hits
// the energy deposited is = 1.
// Two probability numbers are stored in the HTofCluster,
// i.e. clustProbAll (evaluated for all hits in ToF)
// and clustProbLep (evaluated for ToF-RICH correlated hits).
// Both the probability numbers depend on the parameters stored
// in HTofClusterFPar that is used here as input.
//
Float_t sL1=0.0, mL1=0.0, sL2=0.0, mL2=0.0, ratC=0.0, prob;
if(aset=="all"){
sL1=fClusterFPar->getSigma1("all");
mL1=fClusterFPar->getMPV1("all");
sL2=fClusterFPar->getSigma2("all");
mL2=fClusterFPar->getMPV2("all");
ratC=fClusterFPar->getConstRatio("all");
}
if(aset=="lep"){
sL1=fClusterFPar->getSigma1("lep");
mL1=fClusterFPar->getMPV1("lep");
sL2=fClusterFPar->getSigma2("lep");
mL2=fClusterFPar->getMPV2("lep");
ratC=fClusterFPar->getConstRatio("lep");
}
if((TMath::Landau(edep,mL1,sL1))!=0.0){
prob=(1.0/(1.0+ratC*((TMath::Landau(edep,mL2,sL2))/(TMath::Landau(edep,mL1,sL1)))));
} else {
prob=0.0;
}
return prob;
}
void HTofClusterF::readHit(void) {
// Auxiliary function.
// It reads data from HTofHit based category.
//
HGeomVector vecRod, vecMod;
fLoc[0]=hit->getSector();
fLoc[1]=hit->getModule();
fLoc[2]=hit->getCell();
tof_h=hit->getTof();
flagAdc_h=hit->getAdcFlag();
HModGeomPar *module=fTofGeometry->getModule(fLoc[0],fLoc[1]);
HGeomVolume *rodVol=module->getRefVolume()->getComponent(fLoc[2]);
HGeomTransform &rodTrans=rodVol->getTransform();
vecRod.setXYZ((hit->getXpos()),0.0,0.0);
vecMod=rodTrans.transFrom(vecRod);
xposMod_h=vecMod.getX();
if(flagAdc_h==2){
vecRod.setXYZ((hit->getXposAdc()),0.0,0.0);
vecMod=rodTrans.transFrom(vecRod);
xposModAdc_h=vecMod.getX();
} else {
xposModAdc_h=0.0;
}
hit->getXYZLab(xlab_h, ylab_h, zlab_h);
edep_h=hit->getEdep();
lAmp_h=hit->getLeftAmp();
rAmp_h=hit->getRightAmp();
}
void HTofClusterF::writeCluster(Int_t mode) {
// Auxiliary function.
// It stores the date into the HTofCluster based category.
//
if(mode==0){
Float_t phi_h, theta_h, distance_h;
hit->getPhi(phi_h);
hit->getTheta(theta_h);
hit->getDistance(distance_h);
cluster = (HTofCluster *)fClusterCat->getSlot(fLoc);
if(cluster){
cluster = new(cluster) HTofCluster;
cluster->setSector(fLoc[0]);
cluster->setModule(fLoc[1]);
cluster->setCell(fLoc[2]);
cluster->setTof(tof_h);
cluster->setXpos(xposMod_h);
cluster->setXposAdc(xposModAdc_h);
cluster->setEdep(edep_h);
cluster->setLeftAmp(lAmp_h);
cluster->setRightAmp(rAmp_h);
cluster->setXYZLab(xlab_h, ylab_h, zlab_h);
cluster->setDistance(distance_h);
cluster->setTheta(theta_h);
cluster->setPhi(phi_h);
cluster->setClusterSize(1);
cluster->setAdcFlag(flagAdc_h);
}
}
if(mode==1){
HGeomVector r;
Float_t distance_c, theta_c, phi_c;
Float_t rad2deg = 180./TMath::Pi();
r.setX(xlab_c);
r.setY(ylab_c);
r.setZ(zlab_c);
distance_c = r.length();
theta_c = (distance_c>0.) ? (rad2deg * TMath::ACos(r.getZ() / distance_c)) : 0.;
phi_c = rad2deg * TMath::ATan2( r.getY(), r.getX());
if (phi_c < 0.) phi_c += 360.;
cluster = (HTofCluster *)fClusterCat->getSlot(fCLoc);
if(cluster){
cluster = new(cluster) HTofCluster;
cluster->setSector(fCLoc[0]);
cluster->setModule(fCLoc[1]);
cluster->setCell(fCLoc[2]);
cluster->setTof(tof_c);
cluster->setXpos(xposMod_c);
cluster->setXposAdc(xposModAdc_c);
cluster->setEdep(edep_c);
cluster->setLeftAmp(lAmp_c);
cluster->setRightAmp(rAmp_c);
cluster->setXYZLab(xlab_c, ylab_c, zlab_c);
cluster->setDistance(distance_c);
cluster->setTheta(theta_c);
cluster->setPhi(phi_c);
cluster->setClusterSize(size_c);
cluster->setAdcFlag(flagAdc_c);
}
}
if((mode!=0) && (mode!=1)){
Warning("writeCluster","wrong scenario of cluster writing has been chosen !!!ncluster not written!!!n");
}
}
void HTofClusterF::calcWeightedMean() {
// Auxiliary function.
// Calculates weighted mean.
Float_t w1, w2;
if((edep_c != 0.0) && (edep_h != 0.0)) {
w1=edep_c;
w2=edep_h;
edep_c=edep_c+edep_h;
} else {
w1=1.0;
w2=1.0;
}
tof_c=((tof_c*w1)+(tof_h*w2))/(w1+w2);
xposMod_c=((xposMod_c*w1)+(xposMod_h*w2))/(w1+w2);
xposModAdc_c=((xposModAdc_c*w1)+(xposModAdc_h*w2))/(w1+w2);
lAmp_c=((lAmp_c*w1)+(lAmp_h*w2))/(w1+w2);
rAmp_c=((rAmp_c*w1)+(rAmp_h*w2))/(w1+w2);
xlab_c=((xlab_c*w1)+(xlab_h*w2))/(w1+w2);
ylab_c=((ylab_c*w1)+(ylab_h*w2))/(w1+w2);
zlab_c=((zlab_c*w1)+(zlab_h*w2))/(w1+w2);
if((flagAdc_c==2)&&(flagAdc_h==2)) flagAdc_c=2;
else flagAdc_c=0;
}
void HTofClusterF::fillPreviousData(void) {
// Auxiliary function.
//
fpLoc=fLoc;
tof_ph=tof_h;
xposMod_ph=xposMod_h;
}
void HTofClusterF::fillClusterData(void) {
// Auxiliary function.
//
tof_c=tof_h;
xposMod_c=xposMod_h;
xposModAdc_c=xposModAdc_h;
edep_c=edep_h;
lAmp_c=lAmp_h;
rAmp_c=rAmp_h;
xlab_c=xlab_h;
ylab_c=ylab_h;
zlab_c=zlab_h;
flagAdc_c=flagAdc_h;
}
void HTofClusterF::initParContainer(HSpectrometer *spec, HRuntimeDb *rtdb) {
// Adds to the runtime database "rtdb" the containers needed by the Cluster Finder
//spec is used to get information of the spectrometer setup.
fTofGeometry=(HTofGeomPar *)rtdb->getContainer("TofGeomPar");
fClusterFPar=(HTofClusterFPar *)rtdb->getContainer("TofClusterFPar");
}
Bool_t HTofClusterF::init(void) {
Bool_t r=kTRUE; // Function's return value
HSpectrometer *spec = gHades->getSetup();
HRuntimeDb *rtdb = gHades->getRuntimeDb();
HEvent *ev = gHades->getCurrentEvent(); // Event structure
if (spec && rtdb && ev) {
HDetector *tof = spec->getDetector("Tof");
if (tof) {
// Parameter containers initialization.
initParContainer(spec,rtdb);
fHitCat = ev->getCategory(catTofHit);
if (!fHitCat) {
fHitCat = tof->buildCategory(catTofHit);
if (!fHitCat) return kFALSE;
else ev->addCategory(catTofHit,fHitCat,"Tof");
}
iterh=(HIterator*)fHitCat->MakeIterator("native");
fClusterCat = ev->getCategory(catTofCluster);
if (!fClusterCat) {
fClusterCat = tof->buildCategory(catTofCluster);
if (!fClusterCat) return kFALSE;
else ev->addCategory(catTofCluster,fClusterCat,"Tof");
}
iterc=(HIterator*)fClusterCat->MakeIterator("native");
} else {
Error("init","TOF setup is not defined");
r = kFALSE; // Notify error to task manager
}
} else {
Error("init","Setup, RuntimeDb or Event structure not found");
r = kFALSE; // Notify error to task manager
}
return r;
}
ClassImp(HTofClusterF)
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.