//*-- Author : M.Sanchez (14.06.2000)
#include "hmdcvertexfind.h"
#include "hcategory.h"
#include "hmdcgeompar.h"
#include "hades.h"
#include "hevent.h"
#include "hiterator.h"
#include "hruntimedb.h"
#include "hspectrometer.h"
#include "hgeomvector.h"
#include "mdcsdef.h"
#include "hmdcseg.h"
#include "hmdchit.h"
#include "hgeomvolume.h"
#include "hrecevent.h"
#include "hpartialevent.h"
#include <TNtuple.h>
//_HADES_CLASS_DESCRIPTION
//////////////////////////////////////
// HMdcVertexFind
//
// Vertex finder using weighted LSM with optional Tukey weights
//
// To use it in a macro just add
//
// taskset->add(new HMdcVertexFind("name","title",input_mode,tukey)
//
// where
//
// input_mode is one of HMdcVertexFind::kSegments or HMdcVertexFind::kHits.
// In the first case HMdcSeg objecst will be used as input (recomended for
// now) while in the secon HMdcHit objects will be used
//
// As for 'tukey' it can be kTRUE or kFALSE depending on if Tukey weights
// should be used in the minimization. For low multiplicity environments
// like C+C I would recomend kFALSE; at least until I have found better
// parameters for the Tukey weigths minimization.
/////////////////////////////////////////
HMdcVertexFind::HMdcVertexFind(Text_t name[],Text_t title[],EInputMode m,
Bool_t tukey) :
HReconstructor(name,title),fPos("HGeomVector",200),
fAlpha("HGeomVector",200) {
initVars();
useTukeyWeights(tukey);
fInputMode=m;
}
HMdcVertexFind::~HMdcVertexFind(void) {
initVars();
}
void HMdcVertexFind::initVars(void) {
fInput=0;
fGeometry=0;
fIter=0;
fMaxIterations=100;
fTukeyConst=6.0;
fEpsilon=.3;
fUsingTukey = kFALSE;
fDebugMode = kFALSE;
}
Bool_t HMdcVertexFind::init(void) {
HRuntimeDb *rtdb=gHades->getRuntimeDb();
HRecEvent *ev = dynamic_cast<HRecEvent *>(gHades->getCurrentEvent());
if (!ev) return kFALSE;
switch (fInputMode) {
case kSegments:
fInput=gHades->getCurrentEvent()->getCategory(catMdcSeg);
break;
case kHits:
fInput=gHades->getCurrentEvent()->getCategory(catMdcHit);
break;
default:
fInput=0;
}
if (!fInput) return kFALSE;
// else fIter=(HIterator *)fInput->MakeIterator();
fGeometry=(HMdcGeomPar *)gHades->getRuntimeDb()->getContainer("MdcGeomPar");
fSpecGeometry = (HSpecGeomPar *)rtdb->getContainer("SpecGeomPar");
if (gHades->getOutputFile()) {
gHades->getOutputFile()->cd();
//fData----
// x,y,z,n : posicion del vertice en la iteracion n
// con : converged??
//fData=new TNtuple("Data","Data","x:y:z:n:con");
if (fDebugMode)
fControl=new TNtuple("con","control","rho:dx:dy:dz:sector:module");
}
return kTRUE;
}
Bool_t HMdcVertexFind::finalize(void) {
return kTRUE;
}
Bool_t HMdcVertexFind::pointsToTarget(const HGeomVector &r,HGeomVector &alpha,
Int_t sector,Int_t module) {
//Gilipollas el HMdcSeg ya tiene esta informacion.....
Double_t bx=alpha.getX()/alpha.getZ();
Double_t by=alpha.getY()/alpha.getZ();
HGeomVector rmin;
Bool_t res=kTRUE;
//Evaluate maximum approach to z axis
rmin.setZ(r.getZ() - (r.getX() * bx + r.getY() * by) / (bx * bx + by * by));
rmin.setX(r.getX() + bx * (rmin.getZ() - r.getZ()));
rmin.setY(r.getY() + by * (rmin.getZ() - r.getZ()));
Double_t rhomin=TMath::Sqrt(rmin.getX() * rmin.getX() +
rmin.getY() * rmin.getY());
//Impose condition
//cout << rmin.getZ() << endl;
if (fDebugMode)
fControl->Fill(rhomin,rmin.getX(),rmin.getY(),rmin.getZ(),sector,module);
if (rmin.getZ()<100 && rmin.getZ()>-150 && rhomin<200) res=kTRUE;
else res=kFALSE;
return res;
}
void HMdcVertexFind::transform(HMdcSeg *hit,
HGeomVector &r,HGeomVector &alpha) {
//Calculates position and direction vector for a HMdcHit
Float_t theta,phi;
Double_t pi2=TMath::Pi()/2.;
theta=hit->getTheta();
phi=hit->getPhi();
r.setZ(hit->getZ());
r.setX(hit->getR()*TMath::Cos(phi+pi2));
r.setY(hit->getR()*TMath::Sin(phi+pi2));
alpha.setZ(TMath::Cos(theta));
alpha.setY(TMath::Sin(theta)*TMath::Sin(phi));
alpha.setX(TMath::Sin(theta)*TMath::Cos(phi));
}
Bool_t HMdcVertexFind::readSegments(HGeomVector &estimate) {
HGeomVector *r,*alpha,rLocal,alphaLocal;
HMdcSeg *data=0;
Int_t count=0;
fInput=gHades->getCurrentEvent()->getCategory(catMdcSeg);
// r = new(fPos[count]) HGeomVector(0,0,0);
// alpha = new(fAlpha[count]) HGeomVector(0,0,1);
// count++;
if (fInput) {
//First vertex estimation and filling of fPos, fAlpha.
fIter=(HIterator *)fInput->MakeIterator();
fIter->Reset();
fFitter.reset();
while ( (data=(HMdcSeg *)fIter->Next()) != 0) {
// Transform from MDC system to LAB system
if (data->getIOSeg()==0&&data->getChi2()>=0) {
HGeomTransform &trans=fSpecGeometry->getSector(data->getSec())->getTransform();
transform(data,rLocal,alphaLocal);
r=new(fPos[count]) HGeomVector(trans.transFrom(rLocal));
alpha=new(fAlpha[count]) HGeomVector(trans.getRotMatrix() *
alphaLocal);
//Feed to LSM fitter.
if (pointsToTarget(*r,*alpha,data->getSec(),0)) {
fFitter.addLine(*r,*alpha); //Default weigth =1.0
count++;
}
}
}
delete fIter;
if (count > 1)
fFitter.getVertex(estimate);
else
estimate.setXYZ(-1000,-1000,-1000);
} else return kFALSE;
return kTRUE;
}
Bool_t HMdcVertexFind::readHits(HGeomVector &estimate) {
HGeomVector *r,*alpha,rLocal,alphaLocal;
HMdcHit *data=0;
Int_t count=0,sector,module;
Double_t dx,dy;
fInput=gHades->getCurrentEvent()->getCategory(catMdcHit);
if (fInput) {
//First vertex estimation and filling of fPos, fAlpha.
fIter=(HIterator *)fInput->MakeIterator();
fIter->Reset();
fFitter.reset();
while ( (data=(HMdcHit *)fIter->Next()) != 0) {
// Transform from MDC system to LAB system
data->getSecMod(sector,module);
HGeomTransform &trans=fGeometry->
getModule(sector,module)->getLabTransform();
rLocal.setX(data->getX());
rLocal.setY(data->getY());
rLocal.setZ(0.);
dx=data->getXDir();
dy=data->getYDir();
alphaLocal.setX(dx);
alphaLocal.setY(dy);
alphaLocal.setZ(TMath::Sqrt(1. - dx*dx - dy*dy));
r=new(fPos[count]) HGeomVector(trans.transFrom(rLocal));
alpha=new(fAlpha[count]) HGeomVector(trans.getRotMatrix() *
alphaLocal);
//Feed to LSM fitter.
if (pointsToTarget(*r,*alpha,sector,module)) {
fFitter.addLine(*r,*alpha); //Default weigth =1.0
count++;
}
}
if (count>1)
fFitter.getVertex(estimate);
else
estimate.setXYZ(-1000,-1000,-1000);
} else return kFALSE;
return kTRUE;
}
Int_t HMdcVertexFind::execute(void) {
HGeomVector *r,*alpha;
HGeomVector oldVertex;
HVertex &event_vertex = gHades->getCurrentEvent()->getHeader()->getVertex();
HGeomVector &vertex = event_vertex.getPos();
Int_t count=0,i=0,iteration=0;
Double_t weight,residual2,temp; //Weight and residual^2
switch (fInputMode) {
case kSegments:
if (!readSegments(vertex)) return 1;
break;
case kHits:
if (!readHits(vertex)) return 1;
break;
default:
Error("execute","Unrecognized mode");
}
if (fUsingTukey) {
count=fPos.GetEntriesFast();
if (count > 1) {
//Iteration on weights
Float_t sumOfResiduals = 0;
Float_t sumOfWeights = 0;
for (i=0;i<count;i++) {
r = (HGeomVector *)fPos.UncheckedAt(i);
alpha = (HGeomVector *)fAlpha.UncheckedAt(i);
temp = ((r->getY() - vertex.getY()) * alpha->getZ() -
(r->getZ() - vertex.getZ()) * alpha->getY());
residual2 = temp * temp;
temp = ((r->getZ() - vertex.getZ()) * alpha->getX() -
(r->getX() - vertex.getX()) * alpha->getZ());
residual2 += temp * temp;
temp = ((r->getX() - vertex.getX()) * alpha->getY() -
(r->getY() - vertex.getY()) * alpha->getX());
residual2 += temp * temp;
sumOfResiduals += residual2;
}
Float_t width = fTukeyConst*sqrt(sumOfResiduals);
iteration=0;
do {
sumOfResiduals = 0;
sumOfWeights = 0;
oldVertex=vertex;
//fData->Fill(vertex(0),vertex(1),vertex(2),iteration,0.);
iteration++;
fFitter.reset();
for (i=0;i<count;i++) {
r = (HGeomVector *)fPos.UncheckedAt(i);
alpha = (HGeomVector *)fAlpha.UncheckedAt(i);
temp = ((r->getY() - oldVertex.getY()) * alpha->getZ() -
(r->getZ() - oldVertex.getZ()) * alpha->getY());
residual2 = temp * temp;
temp = ((r->getZ() - oldVertex.getZ()) * alpha->getX() -
(r->getX() - oldVertex.getX()) * alpha->getZ());
residual2 += temp * temp;
temp = ((r->getX() - oldVertex.getX()) * alpha->getY() -
(r->getY() - oldVertex.getY()) * alpha->getX());
residual2 += temp * temp;
temp = sqrt(residual2);
weight = (temp < width)?((1. - (temp/width)*(temp/width)) *
(1. - (temp/width)*(temp/width))):0.0;
sumOfResiduals += weight*residual2;
sumOfWeights += weight;
fFitter.addLine(*r,*alpha,weight);
}
width = fTukeyConst*sqrt(sumOfResiduals/sumOfWeights);
fFitter.getVertex(vertex);
}
while (!hasConverged(vertex,oldVertex) && (iteration < fMaxIterations));
if (iteration<fMaxIterations) {
event_vertex.setIterations(iteration);
event_vertex.setChi2(sumOfResiduals/sumOfWeights);
event_vertex.setSumOfWeights(sumOfWeights);
}
else {
event_vertex.setIterations(-2);
event_vertex.setChi2(-1);
event_vertex.setSumOfWeights(-1);
}
}
else {
event_vertex.setIterations(-1);
event_vertex.setChi2(-1);
event_vertex.setSumOfWeights(-1);
}
//fData->Fill(vertex(0),vertex(1),vertex(2),iteration,temp);
} else {
event_vertex.setIterations(1);
event_vertex.setChi2(-1);
event_vertex.setSumOfWeights(-1);
//fData->Fill(vertex(0),vertex(1),vertex(2),0,1);
}
fPos.Clear();
fAlpha.Clear();
return 0;
}
Bool_t HMdcVertexFind::hasConverged(HGeomVector &v,HGeomVector &oldV) {
Bool_t r=((v-oldV).length() < fEpsilon)?kTRUE:kFALSE;
return r;
}
ClassImp(HMdcVertexFind)
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.