ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitPhysics/Utils/src/VertexTools.cc
Revision: 1.7
Committed: Fri Nov 18 00:07:17 2011 UTC (13 years, 5 months ago) by bendavid
Content type: text/plain
Branch: MAIN
Changes since 1.6: +210 -39 lines
Log Message:
8 cat energy smearing and scaling, bdt vertex selection and probability, scaled pt cuts for photons

File Contents

# User Rev Content
1 bendavid 1.7 // $Id: VertexTools.cc,v 1.6 2011/07/15 19:42:36 fabstoec Exp $
2 bendavid 1.1
3     #include "MitPhysics/Utils/interface/VertexTools.h"
4     #include "MitPhysics/Utils/interface/ElectronTools.h"
5 fabstoec 1.5 #include "MitPhysics/Utils/interface/PhotonTools.h"
6 bendavid 1.1 #include "MitAna/DataTree/interface/StableData.h"
7     #include <TFile.h>
8 maxi 1.2 #include <TVector3.h>
9 bendavid 1.7 #include <TSystem.h>
10 bendavid 1.1
11     ClassImp(mithep::VertexTools)
12    
13     using namespace mithep;
14    
15 maxi 1.2 VertexTools* VertexTools::meobject = NULL;
16    
17 bendavid 1.1 //--------------------------------------------------------------------------------------------------
18 bendavid 1.7 VertexTools::VertexTools() :
19     fIsInitMvaM(kFALSE),
20     fIsInitMvaP(kFALSE),
21     reader(0),
22     readervtx(0),
23     readerevt(0)
24 bendavid 1.1 {
25 bendavid 1.7
26     }
27    
28     //--------------------------------------------------------------------------------------------------
29     void VertexTools::InitM(const char* str)
30     {
31    
32 maxi 1.2 relname = str;
33     reader = new TMVA::Reader( "!Color:!Silent" );
34     reader->AddVariable( "var1", &tmvar1 );
35     reader->AddVariable( "var2", &tmvar2 );
36     reader->AddVariable( "var3", &tmvar3 );
37     reader->AddVariable( "var4", &tmvar4 );
38     reader->AddVariable( "var5", &tmvar5 );
39     reader->AddVariable( "var6", &tmvar6 );
40     reader->BookMVA( "BDTG method",relname + TString("/src/MitPhysics/data/TMVAClassification_BDTG.weights.xml").Data());
41     reader->BookMVA( "BDTD method",relname + TString("/src/MitPhysics/data/TMVAClassification_BDTD.weights.xml" ).Data());
42     //reader->BookMVA( "CFMlpANN method", "/home/maxi/cms/root/TMVAClassification_CFMlpANN.weights.xml" );
43     reader->BookMVA( "MLP method", relname + TString("/src/MitPhysics/data/TMVAClassification_MLP.weights.xml").Data());
44     reader->BookMVA( "MLPBFGS method",relname + TString("/src/MitPhysics/data/TMVAClassification_MLPBFGS.weights.xml" ).Data());
45 bendavid 1.7
46     fIsInitMvaM = kTRUE;
47    
48 maxi 1.2 }
49    
50 bendavid 1.7 //--------------------------------------------------------------------------------------------------
51     void VertexTools::InitP()
52     {
53    
54     readervtx = new TMVA::Reader( "!Color:!Silent" );
55     readerevt = new TMVA::Reader( "!Color:!Silent" );
56    
57     readervtx->AddVariable( "ptbal", &fMvaPVars[0] );
58     readervtx->AddVariable( "ptasym", &fMvaPVars[1] );
59     readervtx->AddVariable( "logsumpt2", &fMvaPVars[2] );
60     readervtx->AddVariable( "limPullToConv", &fMvaPVars[3] );
61     readervtx->AddVariable( "nConv", &fMvaPVars[4] );
62     readervtx->BookMVA( "BDTCat", gSystem->Getenv("CMSSW_BASE") + TString("/src/MitPhysics/data/TMVAClassification_BDTCat_conversions_tmva_407.weights.xml") );
63    
64     readerevt->AddVariable( "diphoPt0", &fMvaPEvtVars[0] );
65     readerevt->AddVariable( "nVert", &fMvaPEvtVars[1] );
66     readerevt->AddVariable( "MVA0", &fMvaPEvtVars[2] );
67     readerevt->AddVariable( "MVA1", &fMvaPEvtVars[3] );
68     readerevt->AddVariable( "dZ1", &fMvaPEvtVars[4] );
69     readerevt->AddVariable( "MVA2", &fMvaPEvtVars[5] );
70     readerevt->AddVariable( "dZ2", &fMvaPEvtVars[6] );
71     readerevt->AddVariable( "nConv", &fMvaPEvtVars[7] );
72     readerevt->BookMVA( "BDTEvt", gSystem->Getenv("CMSSW_BASE") + TString("/src/MitPhysics/data/TMVAClassification_evtBDTG_conversions_tmva_407.weights.xml") );
73    
74     fIsInitMvaP = kTRUE;
75     }
76    
77    
78 maxi 1.2 double VertexTools::NewMass(const Photon* ph1, const Photon* ph2, const BaseVertex* vert)
79     {
80 maxi 1.3 ThreeVector drv1 = (ThreeVector(ph1->CaloPos()) - vert->Position()).Unit();
81     //ThreeVector drv1 = (ThreeVector(ph1->SCluster()->Point()) - vert->Position()).Unit();
82 maxi 1.2 FourVector pho1c(drv1.X()*ph1->E(),drv1.Y()*ph1->E(),drv1.Z()*ph1->E(),ph1->E());
83 maxi 1.3 ThreeVector drv2 = (ThreeVector(ph2->CaloPos()) - vert->Position()).Unit();
84 maxi 1.2 FourVector pho2c(drv2.X()*ph2->E(),drv2.Y()*ph2->E(),drv2.Z()*ph2->E(),ph2->E());
85    
86     FourVector diboso = pho1c+pho2c;
87     return diboso.M();
88 bendavid 1.1 }
89    
90     //--------------------------------------------------------------------------------------------------
91 maxi 1.2 VertexZarray VertexTools::ExtractZarray(const VertexCol* vcol, float zmin, float zmax, const BaseVertex *fBeamSpot)
92     {
93     VertexZarray zs;
94     if(vcol == NULL) return zs;
95    
96     for(unsigned vv = 0; vv < vcol->GetEntries(); vv++){
97     const Vertex* vert = vcol->At(vv);
98     double zpos = vert->Z();
99     if(fBeamSpot != NULL)
100     zpos = zpos - fBeamSpot->Z();
101     if(zpos > zmin && zpos > zmin)
102     zs.push_back(zpos);
103     }
104     return zs;
105     }
106    
107     VertexZarray VertexTools::ExtractZarray(float zmin, float zmax, float step)
108     {
109     VertexZarray zs;
110     for(float zpos = zmin; zpos < zmax+step; zpos = zpos+step){
111     zs.push_back(zpos);
112     }
113     return zs;
114     }
115    
116     const Vertex* VertexTools::BestVtx( const PFCandidateCol *fPFJets, const VertexCol *c,
117     const BaseVertex *fBeamSpot, FourVector diboso) {
118    
119     if (!c || !c->GetEntries()) return NULL;
120    
121     double bestprob = -100.;
122     const Vertex* bestvert = NULL;
123     for(unsigned vv = 0; vv < c->GetEntries(); vv++){
124    
125     const Vertex* vert = c->At(vv);
126     double zpos = vert->Z();
127     double prob = Prob(fPFJets, zpos, fBeamSpot, diboso);
128     if(prob > bestprob){
129     bestprob = prob;
130     bestvert = vert;
131     }
132     }
133     return bestvert;
134     }
135    
136     double VertexTools::BestVtx( const PFCandidateCol *fPFJets, VertexZarray zcol,
137     const BaseVertex *fBeamSpot, FourVector diboso){
138    
139     double bestprob = -100.;
140     double bestz = -100.;
141     for(unsigned vv = 0; vv < zcol.size(); vv++){
142     double zpos = zcol[vv];
143     double prob = Prob(fPFJets, zpos, fBeamSpot, diboso);
144     if(prob > bestprob){
145     bestprob = prob;
146     bestz = zpos;
147     }
148     }
149     return bestz;
150    
151     }
152 bendavid 1.1
153 maxi 1.2 double VertexTools::Prob(const PFCandidateCol *fPFJets, double zpos,
154     const BaseVertex *fBeamSpot, FourVector diboso){
155    
156     double bosophi = diboso.Phi();
157     double bosopt = diboso.Pt();
158    
159     Vertex* vert = new Vertex(0,0,zpos);
160     double ZVC = vert->Z()-fBeamSpot->Z();
161 maxi 1.3 VertexTools* vtool = VertexTools::instance("");
162 maxi 1.2
163     Double_t sinsum = 0.;
164     Double_t cossum = 0.;
165     Double_t sumpt = 0.;
166     Double_t ntrks = 0.;
167     Double_t ntplus = 0.;
168     Double_t ortminus = 0.;
169     Double_t ortplus = 0.;
170     Double_t bdplus = 0.;
171     Double_t bdminus = 0.;
172     Double_t zmean = 0.;
173     Double_t zmeansq = 0.;
174     Double_t ww = 0.;
175    
176     for(unsigned pfj = 0; pfj < fPFJets->GetEntries(); pfj++){
177     const PFCandidate* pfca = fPFJets->At(pfj);
178     if(! pfca->HasTrk()) continue;
179     if(!(pfca->PFType() == PFCandidate::eX ||
180     pfca->PFType() == PFCandidate::eHadron ||
181     pfca->PFType() == PFCandidate::eElectron ||
182     pfca->PFType() == PFCandidate::eMuon) ) continue;
183     const Track *t = pfca->Trk();
184     if(fabs(t->DzCorrected(*fBeamSpot) - ZVC ) > 0.2) continue;
185    
186     if(pfca->Pt()<0.3 || pfca->Pt()>200) continue;
187 maxi 1.3
188     std::vector<const Track*>::iterator itt;
189     itt = find ((vtool->excluded).begin(), (vtool->excluded).end(), t);
190     if(itt != (vtool->excluded).end()) continue;
191 maxi 1.2
192     zmean = zmean + pfca->Pt()* t->DzCorrected(*fBeamSpot);
193     zmeansq = zmeansq + pfca->Pt()*t->DzCorrected(*fBeamSpot)*t->DzCorrected(*fBeamSpot);
194     ntrks++;
195     sumpt = sumpt + pfca->Pt()*pfca->Pt();
196     ww = ww + pfca->Pt();
197    
198     sinsum = sinsum + pfca->Pt()*TMath::Sin(t->Phi());
199     cossum = cossum + pfca->Pt()*TMath::Cos(t->Phi());
200     }
201     if(ntrks < 2 || !(sumpt > 0.) ) return 0;
202    
203     Double_t phim = TMath::ATan2(sinsum,cossum);
204     zmean = zmean/ww;
205     zmeansq = sqrt(zmeansq/ww - zmean*zmean);
206    
207     //--------------------
208     Double_t bosoproj = 0.;
209     Float_t ymean = 0.;
210     Float_t ymsq = 0.;
211     for(unsigned pfj = 0; pfj < fPFJets->GetEntries(); pfj++){
212     const PFCandidate* pfca = fPFJets->At(pfj);
213     if(! pfca->HasTrk()) continue;
214     if(!(pfca->PFType() == PFCandidate::eX ||
215     pfca->PFType() == PFCandidate::eHadron ||
216     pfca->PFType() == PFCandidate::eElectron ||
217     pfca->PFType() == PFCandidate::eMuon) ) continue;
218    
219     const Track *t = pfca->Trk();
220     if(fabs(t->DzCorrected(*fBeamSpot) - ZVC ) > 0.2) continue;
221     //if(fabs(t->DzCorrected(*fBeamSpot) - ZVC ) > 3*zwidth) continue;
222     if(pfca->Pt()<0.3 || pfca->Pt()>200) continue;
223 maxi 1.3
224     std::vector<const Track*>::iterator itt;
225     itt = find ((vtool->excluded).begin(), (vtool->excluded).end(), t);
226     if(itt != (vtool->excluded).end()) continue;
227 maxi 1.2
228     //Float_t phid = phim - t->Phi();
229     Float_t phid = bosophi+3.14 - t->Phi();
230     ymean = ymean + pfca->Pt()*TMath::Sin(phid);
231     ymsq = ymsq + pow(pfca->Pt()*TMath::Sin(phid),2);
232     bosoproj = bosoproj + pfca->Pt()*TMath::Cos(bosophi-t->Phi());
233     if(TMath::Sin(phid) > 0.) ortplus = ortplus + pfca->Pt()*TMath::Sin(phid);
234     else ortminus = ortminus + pfca->Pt()*fabs(TMath::Sin(phid));
235     if(TMath::Cos(phid) > 0.) bdplus = bdplus + pfca->Pt()*TMath::Cos(phid);
236     else bdminus = bdminus + pfca->Pt()*fabs(TMath::Cos(phid));
237     if(TMath::Cos(phid) > 0.) ntplus = ntplus + TMath::Cos(phid);
238     }
239 bendavid 1.1
240 maxi 1.2 Float_t phimsq = sqrt(ymsq/ntrks - pow(ymean/ntrks,2))*180/3.14;
241 fabstoec 1.4 // not used... commented out by Fabian
242     //Double_t A2n = (ortplus+ortminus) > 0.01 ? (bdplus+bdminus)/(ortplus+ortminus) : (bdplus+bdminus)/0.01;
243 maxi 1.2 Double_t A1n = bdplus/bosopt;
244     Double_t A3n = ntplus > 0 ? bdplus/ntplus : 0.;
245     //-------------------
246     Double_t angle = 180/3.14*TVector2::Phi_0_2pi(bosophi-phim);
247 bendavid 1.1
248 maxi 1.2 vtool->tmvar1 = ntrks;
249     vtool->tmvar2 = sumpt;
250     vtool->tmvar3 = A1n;
251     vtool->tmvar4 = angle;
252     vtool->tmvar5 = phimsq;
253     vtool->tmvar6 = A3n;
254    
255     double p1 = vtool->reader->GetProba ( "BDTD method" );
256     double p2 = vtool->reader->GetProba ( "BDTG method" );
257     double p3 = vtool->reader->GetProba ( "MLP method");
258     double p4 = vtool->reader->GetProba ( "MLPBFGS method");
259    
260     double retval = p1*p2*p3*p4;
261    
262     return retval;
263     }
264    
265     double VertexTools::VertexWidth(const Vertex* vert, const BaseVertex *fBeamSpot){
266     double width = 0.;
267     double zmean = 0.;
268     double zmeansq = 0.;
269     double ww = 0.;
270     if(vert == NULL) return width;
271     for(unsigned i = 0; i < vert->NTracks(); i++){
272     const Track *t = vert->Trk(i);
273     if(t->Pt() < 0.3 ) continue;
274     if(t->Pt() > 500.) continue;
275     ww = ww + t->Pt();
276     zmean = zmean + t->Pt()*t->DzCorrected(*fBeamSpot);
277     zmeansq = zmeansq + t->Pt()*t->DzCorrected(*fBeamSpot)*t->DzCorrected(*fBeamSpot);
278     }
279     if( !(ww > 0.) ) return width;
280     zmean = zmean/ww;
281    
282     width = sqrt(zmeansq/ww - zmean*zmean);
283     return width;
284    
285     }
286 maxi 1.3
287     void VertexTools::BanThisTrack(const Track* track){
288     VertexTools* vtool = VertexTools::instance("");
289     (vtool->excluded).push_back(track);
290     }
291     void VertexTools::Reset(){
292     VertexTools* vtool = VertexTools::instance("");
293     (vtool->excluded).clear();
294     }
295 fabstoec 1.5
296    
297     //------------------------------------------------------------------------------------
298     // The below tools are from the H->2photons EPS2011 BaseLine (common) Selection
299     const Vertex* VertexTools::findVtxBasicRanking(const Photon* ph1,
300     const Photon* ph2,
301     const BaseVertex* bsp,
302     const VertexCol* vtcs,
303 bendavid 1.7 const DecayParticleCol* conv, Bool_t useMva, Double_t &vtxProb) {
304    
305     //if (useMva) printf("using mva vertex selection\n");
306 fabstoec 1.5
307     // check if all input is valid
308     if( !ph1 || !ph2 || !bsp || !vtcs ) return NULL;
309     // CAUTION: We allow for passing NULL for the Conversions, in that case only the simple Ranking is used.
310    
311     // here we will store the idx of the best Vtx
312     unsigned int bestIdx = 0;
313 bendavid 1.7 UInt_t bestidxmva = 0;
314 fabstoec 1.6
315 fabstoec 1.5 // using asd much as possible 'Globe' naming schemes...
316     int* ptbal_rank = new int [vtcs->GetEntries()];
317     int* ptasym_rank = new int [vtcs->GetEntries()];
318     int* total_rank = new int [vtcs->GetEntries()];
319     double* ptbal = new double[vtcs->GetEntries()];
320     double* ptasym = new double[vtcs->GetEntries()];
321 bendavid 1.7 double* sumpt2 = new double[vtcs->GetEntries()];
322     double* limPullToConv = new double[vtcs->GetEntries()];
323     double* mvaval = new double[vtcs->GetEntries()];
324    
325 fabstoec 1.5
326     unsigned int numVertices = vtcs->GetEntries();
327     double ptgg = 0.; // stored for later in the conversion
328    
329     // loop over all the vertices...
330     for(unsigned int iVtx = 0; iVtx < numVertices; ++iVtx) {
331    
332     const Vertex* tVtx = vtcs->At(iVtx);
333     ptbal [iVtx] = 0.0;
334     ptasym [iVtx] = 0.0;
335 bendavid 1.7 sumpt2 [iVtx] = 0.0;
336     limPullToConv [iVtx] = -1.0;
337 fabstoec 1.5 ptbal_rank [iVtx] = 1;
338     ptasym_rank[iVtx] = 1;
339    
340     // compute the photon momenta with respect to this Vtx
341     FourVectorM newMomFst = ph1->MomVtx(tVtx->Position());
342     FourVectorM newMomSec = ph2->MomVtx(tVtx->Position());
343    
344     FourVectorM higgsMom = newMomFst+newMomSec;
345    
346     double ph1Eta = newMomFst.Eta();
347     double ph2Eta = newMomSec.Eta();
348    
349     double ph1Phi = newMomFst.Phi();
350     double ph2Phi = newMomSec.Phi();
351    
352     // loop over all tracks and computew variables for ranking...
353     FourVectorM totTrkMom(0,0,0,0);
354     for(unsigned int iTrk = 0; iTrk < tVtx->NTracks(); ++iTrk) {
355     const Track* tTrk = tVtx->Trk(iTrk);
356    
357 bendavid 1.7 sumpt2[iVtx] += tTrk->Pt()*tTrk->Pt();
358    
359 fabstoec 1.5 // compute distance between Trk and the Photons
360     double tEta = tTrk->Eta();
361     double tPhi = tTrk->Phi();
362     double dEta1 = TMath::Abs(tEta-ph1Eta);
363     double dEta2 = TMath::Abs(tEta-ph2Eta);
364     double dPhi1 = TMath::Abs(tPhi-ph1Phi);
365     double dPhi2 = TMath::Abs(tPhi-ph2Phi);
366     if(dPhi1 > M_PI) dPhi1 = 2*M_PI - dPhi1;
367     if(dPhi2 > M_PI) dPhi2 = 2*M_PI - dPhi2;
368    
369     double dR1 = TMath::Sqrt(dEta1*dEta1+dPhi1*dPhi1);
370     double dR2 = TMath::Sqrt(dEta2*dEta2+dPhi2*dPhi2);
371    
372     if(dR1 < 0.05 || dR2 < 0.05) continue;
373     totTrkMom = totTrkMom + tTrk->Mom4(0);
374     }
375    
376     // compute the ranking variables for this Vtx
377     double ptvtx = totTrkMom.Pt();
378     double pthiggs = higgsMom.Pt();
379 fabstoec 1.6 if(iVtx == 0) ptgg = pthiggs;
380 fabstoec 1.5 ptbal [iVtx] = (totTrkMom.Px()*(newMomFst.Px()+newMomSec.Px()));
381     ptbal [iVtx] += (totTrkMom.Py()*(newMomFst.Py()+newMomSec.Py()));
382     ptbal [iVtx] = -ptbal[iVtx]/pthiggs;
383     ptasym[iVtx] = (ptvtx - pthiggs)/(ptvtx + pthiggs);
384    
385     // do the little ranking acrobatics...
386     for(unsigned int cVtx =0; cVtx < iVtx; ++cVtx) {
387     if(ptbal [iVtx] > ptbal [cVtx])
388     ptbal_rank[cVtx]++;
389     else
390     ptbal_rank[iVtx]++;
391     if(ptasym [iVtx] > ptasym [cVtx])
392     ptasym_rank[cVtx]++;
393     else
394     ptasym_rank[iVtx]++;
395     }
396     }
397    
398     // loop again over all Vertcices (*sigh*), compute total score and final rank
399     // CAUTION: Total rank starts at '0', so the best ranked Vtx has RANK 0
400     for(unsigned int iVtx = 0; iVtx < numVertices; ++iVtx) {
401     ptasym_rank [iVtx] = ptbal_rank [iVtx]*ptasym_rank [iVtx]*(iVtx+1);
402     total_rank [iVtx] = 0;
403     for(unsigned int cVtx =0; cVtx < iVtx; ++cVtx) {
404     if(ptasym_rank [iVtx] > ptasym_rank [cVtx]) total_rank[iVtx]++;
405     else if(ptasym_rank [iVtx] == ptasym_rank [cVtx]) { // use 'ptbal' as the tie-breaker
406     if(ptbal_rank [iVtx] > ptbal_rank [cVtx]) total_rank[iVtx]++;
407     else total_rank[cVtx]++;
408     }
409     else total_rank[cVtx]++;
410     }
411     }
412    
413    
414     // find the best ranked Vertex so far....
415     for(unsigned int iVtx = 0; iVtx < numVertices; ++iVtx) {
416     if(total_rank[iVtx] == 0) bestIdx = iVtx;
417     }
418    
419     // check if there's a conversion among the pre-selected photons
420     // ...this will return NULL in case conv==NULL
421     const DecayParticle* conv1 = PhotonTools::MatchedCiCConversion(ph1, conv, 0.1, 0.1, 0.1);
422     const DecayParticle* conv2 = PhotonTools::MatchedCiCConversion(ph2, conv, 0.1, 0.1, 0.1);
423    
424     if( conv1 && ( conv1->Prob() < 0.0005) ) conv1 = NULL;
425     if( conv2 && ( conv2->Prob() < 0.0005) ) conv2 = NULL;
426    
427     double zconv = 0.;
428     double dzconv = 0.;
429 bendavid 1.7 int nConv = 0;
430    
431     if (conv1) nConv += 1;
432     if (conv2) nConv += 1;
433    
434    
435     const double dzpxb = 0.016;
436     const double dztib = 0.331;
437     const double dztob = 1.564;
438     const double dzpxf = 0.082;
439     const double dztid = 0.321;
440     const double dztec = 0.815;
441 fabstoec 1.5
442     //--------------------------------------------------------------------
443     // start doing the Conversion acrobatics... 'copied' from the Globe...
444     if(conv1 || conv2) {
445     if( !conv2 ){
446     const mithep::ThreeVector caloPos1(ph1->CaloPos());
447 bendavid 1.7 double zconvsc = conv1->Z0EcalVtx(bsp->Position(), caloPos1);
448     double zconvtrk = conv1->DzCorrected(bsp->Position()) + bsp->Z();
449 fabstoec 1.5 if( ph1->IsEB() ) {
450     double rho = conv1->Position().Rho();
451 bendavid 1.7 if ( rho < 15. ) { dzconv = dzpxb; zconv = zconvtrk; }
452     else if( rho < 60. ) { dzconv = dztib; zconv = zconvsc; }
453     else { dzconv = dztob; zconv = zconvsc; }
454 fabstoec 1.5 } else {
455     double z = conv1->Position().Z();
456 bendavid 1.7 if ( TMath::Abs(z) < 50. ) { dzconv = dzpxf; zconv = zconvtrk; }
457     else if( TMath::Abs(z) < 100.) { dzconv = dztid; zconv = zconvtrk; }
458     else { dzconv = dztec; zconv = zconvsc; }
459 fabstoec 1.5 }
460     } else if( !conv1 ) {
461     const mithep::ThreeVector caloPos2(ph2->CaloPos());
462 bendavid 1.7 double zconvsc = conv2->Z0EcalVtx(bsp->Position(), caloPos2);
463     double zconvtrk = conv2->DzCorrected(bsp->Position()) + bsp->Z();
464 fabstoec 1.5 if( ph2->IsEB() ) {
465     double rho = conv2->Position().Rho();
466 bendavid 1.7 if ( rho < 15. ) { dzconv = dzpxb; zconv = zconvtrk; }
467     else if( rho < 60. ) { dzconv = dztib; zconv = zconvsc; }
468     else { dzconv = dztob; zconv = zconvsc; }
469 fabstoec 1.5 } else {
470     double z = conv2->Position().Z();
471 bendavid 1.7 if ( TMath::Abs(z) < 50. ) { dzconv = dzpxf; zconv = zconvtrk; }
472     else if( TMath::Abs(z) < 100.) { dzconv = dztid; zconv = zconvtrk; }
473     else { dzconv = dztec; zconv = zconvsc; }
474 fabstoec 1.5 }
475     } else {
476     const mithep::ThreeVector caloPos1(ph1->CaloPos());
477 bendavid 1.7 double z1=0.;
478     double z1sc = conv1->Z0EcalVtx(bsp->Position(), caloPos1);
479     double z1trk = conv1->DzCorrected(bsp->Position()) + bsp->Z();
480 fabstoec 1.5 double dz1 = 0.;
481     if( ph1->IsEB() ) {
482     double rho = conv1->Position().Rho();
483 bendavid 1.7 if ( rho < 15. ) { dz1 = dzpxb; z1 = z1trk; }
484     else if( rho < 60. ) { dz1 = dztib; z1 = z1sc; }
485     else { dz1 = dztob; z1 = z1sc; }
486 fabstoec 1.5 } else {
487     double z = conv1->Position().Z();
488 bendavid 1.7 if ( TMath::Abs(z) < 50. ) { dz1 = dzpxf; z1 = z1trk; }
489     else if( TMath::Abs(z) < 100.) { dz1 = dztid; z1 = z1trk; }
490     else { dz1 = dztec; z1 = z1sc; }
491 fabstoec 1.5 }
492     const mithep::ThreeVector caloPos2(ph2->CaloPos());
493 bendavid 1.7 double z2 = 0.;
494     double z2sc = conv2->Z0EcalVtx(bsp->Position(), caloPos2);
495     double z2trk = conv2->DzCorrected(bsp->Position()) + bsp->Z();
496 fabstoec 1.5 double dz2 = 0.;
497     if( ph2->IsEB() ) {
498     double rho = conv2->Position().Rho();
499 bendavid 1.7 if ( rho < 15. ) { dz2 = dzpxb; z2 = z2trk; }
500     else if( rho < 60. ) { dz2 = dztib; z2 = z2sc; }
501     else { dz2 = dztob; z2 = z2sc; }
502 fabstoec 1.5 } else {
503     double z = conv2->Position().Z();
504 bendavid 1.7 if ( TMath::Abs(z) < 50. ) { dz2 = dzpxf; z2 = z1trk; }
505     else if( TMath::Abs(z) < 100.) { dz2 = dztid; z2 = z1trk; }
506     else { dz2 = dztec; z2 = z1sc; }
507 fabstoec 1.5 }
508 fabstoec 1.6
509 fabstoec 1.5 zconv = ( 1./(1./dz1/dz1 + 1./dz2/dz2 )*(z1/dz1/dz1 + z2/dz2/dz2) ) ; // weighted average
510     dzconv = TMath::Sqrt( 1./(1./dz1/dz1 + 1./dz2/dz2)) ;
511     }
512    
513 fabstoec 1.6
514 fabstoec 1.5 // loop over all ranked Vertices and choose the closest to the Conversion one
515     int maxVertices = ( ptgg > 30 ? 3 : 5);
516 fabstoec 1.6 double minDz = -1.;
517    
518 bendavid 1.7
519    
520 fabstoec 1.5 for(unsigned int iVtx =0; iVtx < numVertices; ++iVtx) {
521 fabstoec 1.6
522 bendavid 1.7 limPullToConv[iVtx] = TMath::Abs(vtcs->At(iVtx)->Z()-zconv)/dzconv;
523    
524 fabstoec 1.5 if(total_rank[iVtx] < maxVertices) {
525     const Vertex* tVtx = vtcs->At(iVtx);
526     double tDz = TMath::Abs(zconv - tVtx->Z());
527 fabstoec 1.6
528 fabstoec 1.5 if( (minDz < 0. || tDz < minDz) && ( tDz < dzconv ) ) {
529     minDz = tDz;
530     bestIdx = iVtx;
531     }
532     }
533     }
534     }
535     // END of Conversion Acrobatics
536     //--------------------------------------------------------------------
537    
538 bendavid 1.7 //final loop to compute mva values
539     double mvamax = -1e6;
540     for(unsigned int iVtx =0; iVtx < numVertices; ++iVtx) {
541     double mva = VtxMvaP(ptbal[iVtx],ptasym[iVtx],log(sumpt2[iVtx]),limPullToConv[iVtx],nConv);
542     mvaval[iVtx] = mva;
543     if (mva>mvamax) {
544     mvamax = mva;
545     bestidxmva = iVtx;
546     }
547     }
548    
549     //find second and third ranked vertices for event mva;
550     UInt_t mvaidx1 = 0;
551     mvamax = -1e6;
552     for(unsigned int iVtx =0; iVtx < numVertices; ++iVtx) {
553     if (iVtx!=bestidxmva && mvaval[iVtx]>mvamax) {
554     mvamax = mvaval[iVtx];
555     mvaidx1 = iVtx;
556     }
557     }
558    
559     UInt_t mvaidx2 = 0;
560     mvamax = -1e6;
561     for(unsigned int iVtx =0; iVtx < numVertices; ++iVtx) {
562     if (iVtx!=bestidxmva && iVtx!=mvaidx1 && mvaval[iVtx]>mvamax) {
563     mvamax = mvaval[iVtx];
564     mvaidx2 = iVtx;
565     }
566     }
567    
568     //compute per event mva output
569     FourVectorM newMomFst = ph1->MomVtx(vtcs->At(bestidxmva)->Position());
570     FourVectorM newMomSec = ph2->MomVtx(vtcs->At(bestidxmva)->Position());
571     FourVectorM higgsMom = newMomFst+newMomSec;
572    
573     fMvaPEvtVars[0] = higgsMom.Pt();
574     fMvaPEvtVars[1] = numVertices;
575     fMvaPEvtVars[2] = mvaval[bestidxmva];
576     fMvaPEvtVars[3] = mvaval[mvaidx1];
577     fMvaPEvtVars[4] = vtcs->At(mvaidx1)->Z() - vtcs->At(bestidxmva)->Z();
578     fMvaPEvtVars[5] = mvaval[mvaidx2];
579     fMvaPEvtVars[6] = vtcs->At(mvaidx2)->Z() - vtcs->At(bestidxmva)->Z();
580     fMvaPEvtVars[7] = nConv;
581    
582     Double_t evtmva = readerevt->EvaluateMVA("BDTEvt");
583     vtxProb = 1.-0.49*(evtmva+1.0);
584    
585     // delete the auxiliary dynamic arrays
586     delete[] ptbal_rank ;
587     delete[] ptasym_rank ;
588     delete[] ptbal ;
589     delete[] ptasym ;
590     delete[] sumpt2 ;
591     delete[] limPullToConv;
592     delete[] mvaval;
593    
594 fabstoec 1.5 delete[] total_rank ;
595 bendavid 1.7
596    
597     if (useMva) return vtcs->At(bestidxmva);
598     else return vtcs->At(bestIdx);
599     }
600    
601     //------------------------------------------------------------------------------------
602     double VertexTools::VtxMvaP(float ptbal, float ptasym, float logsumpt2, float limPullToConv, float nConv) const
603     {
604     fMvaPVars[0] = ptbal;
605     fMvaPVars[1] = ptasym;
606     fMvaPVars[2] = logsumpt2;
607     fMvaPVars[3] = limPullToConv;
608     fMvaPVars[4] = nConv;
609    
610     return readervtx->EvaluateMVA("BDTCat");
611    
612 fabstoec 1.5 }
613 bendavid 1.7
614     //------------------------------------------------------------------------------------
615     //Compute contribution to relative uncertainty sigma_m/m from primary vertex location
616     //given ecal shower positions of two photons, plus the beasmpot z width dz
617     //code from Y. Gershtein
618     Double_t VertexTools::DeltaMassVtx(Double_t x1, Double_t y1, Double_t z1,
619     Double_t x2, Double_t y2, Double_t z2,
620     Double_t dz)
621     {
622    
623     Double_t r1 = sqrt(x1*x1+y1*y1+z1*z1);
624     Double_t r2 = sqrt(x2*x2+y2*y2+z2*z2);
625     Double_t phi1 = atan2(y1,x1);
626     Double_t theta1 = atan2(sqrt(x1*x1+y1*y1),z1);
627     Double_t phi2 = atan2(y2,x2);
628     Double_t theta2 = atan2(sqrt(x2*x2+y2*y2),z2);
629    
630     Double_t sech1 = sin(theta1);
631     Double_t tanh1 = cos(theta1);
632     Double_t sech2 = sin(theta2);
633     Double_t tanh2 = cos(theta2);
634     Double_t cos12 = cos(phi1-phi2);
635    
636     Double_t rad1 = sech1*(sech1*tanh2-tanh1*sech2*cos12)/(1-tanh1*tanh2-sech1*sech2*cos12);
637     Double_t rad2 = sech2*(sech2*tanh1-tanh2*sech1*cos12)/(1-tanh2*tanh1-sech2*sech1*cos12);
638    
639     return dz * fabs(rad1/r1 + rad2/r2);
640    
641     }