Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RecoConversionEval.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file RecoConversionEval.cc
1 #include "RecoConversionEval.h"
2 #include "SVReco.h"
3 #include "VtxRegressor.h"
4 
7 #include <phool/getClass.h>
8 #include <phgenfit/Track.h>
9 #include <calobase/RawClusterContainer.h>
10 #include <calobase/RawCluster.h>
13 #include <trackbase_historic/SvtxVertexMap.h>
14 #include <trackbase_historic/SvtxVertex.h>
15 #include <trackbase_historic/SvtxHitMap.h>
16 #include <trackbase_historic/SvtxHit.h>
17 #include <trackbase_historic/SvtxClusterMap.h>
18 #include <trackbase_historic/SvtxCluster.h>
21 #include <g4eval/SvtxEvalStack.h>
22 #include <g4main/PHG4Particle.h>
23 #include <g4main/PHG4VtxPoint.h>
25 
26 
27 #include <TTree.h>
28 #include <TFile.h>
29 #include <TLorentzVector.h>
30 
31 #include <iostream>
32 #include <cmath>
33 #include <algorithm>
34 #include <sstream>
35 
36 using namespace std;
37 
39  SubsysReco("RecoConversionEval"), _fname(name)
40 {
41  _regressor = new VtxRegressor(tmvamethod,tmvapath);
42 }
43 
45  cout<<"deleting RCE"<<endl;
46  if(_vertexer) delete _vertexer;
47  if(_regressor) delete _regressor;
48 }
49 
52 }
53 
55  _vertexer = new SVReco();
56  //TODO turn this back into a subsystem and put it on the node tree
57  _vertexer->InitRun(topNode);
58  _file = new TFile( _fname.c_str(), "RECREATE");
59  _treeSignal = new TTree("recoSignal","strong saharah bush");
60  _treeSignal->SetAutoSave(300);
61  _treeSignal->Branch("photon_m", &_b_photon_m);
62  _treeSignal->Branch("photon_pT", &_b_photon_pT);
63  _treeSignal->Branch("photon_eta", &_b_photon_eta);
64  _treeSignal->Branch("photon_phi", &_b_photon_phi);
65  _treeSignal->Branch("track1_pT", &_b_track1_pT);
66  _treeSignal->Branch("track2_pT", &_b_track2_pT);
67  _treeSignal->Branch("refit", &_b_refit);
68 
69  _treeBackground = new TTree("recoBackground","friendly fern");
70  _treeBackground->SetAutoSave(300);
71  _treeBackground->Branch("total", &totalTracks);
72  _treeBackground->Branch("tracksPEQ", &passedpTEtaQ);
73  _treeBackground->Branch("tracks_clus", &passedCluster);
74  _treeBackground->Branch("pairs", &passedPair);
75  _treeBackground->Branch("vtx", &passedVtx);
76  _treeBackground->Branch("photon", &passedPhoton);
77 
79 }
80 
82  _allTracks = findNode::getClass<SvtxTrackMap>(topNode,"SvtxTrackMap");
83  _mainClusterContainer = findNode::getClass<RawClusterContainer>(topNode,"CLUSTER_CEMC");
84  /*These are deprecated
85  * _svtxClusterMap = findNode::getClass<SvtxClusterMap>(topNode,"SvtxClusterMap");
86  _hitMap = findNode::getClass<SvtxHitMap>(topNode,"SvtxHitMap");*/
87  //new version
88  _clusterMap = findNode::getClass<TrkrClusterContainer>(topNode, "TRKR_CLUSTER");
89  _vertexer->InitEvent(topNode);
90  //to check if the id is correct
91  _truthinfo = findNode::getClass<PHG4TruthInfoContainer>(topNode,"G4TruthInfo");
92 
93 }
94 
97 }
98 
100  doNodePointers(topNode);
101  /*the is not optimized but is just a nlogn process*/
102  for ( SvtxTrackMap::Iter iter = _allTracks->begin(); iter != _allTracks->end(); ++iter) {
103  //I want to now only check e tracks so check the clusters of the |charge|=1 tracks
104  totalTracks++;
105  if (abs(iter->second->get_charge())==1&&iter->second->get_pt()>_kTrackPtCut&&abs(iter->second->get_eta())<1.) //should i have the layer cut?
106  {
107  SvtxTrack* thisTrack = iter->second;
108  passedpTEtaQ++;
110  //TODO what if no cluster is found?
111  if(bestCluster&&bestCluster->get_prob()>=_kEMProbCut){
112  //loop over the following tracks
113  passedCluster++;
114  for (SvtxTrackMap::Iter jter = iter; jter != _allTracks->end(); ++jter)
115  {
116  //check that the next track is an opposite charge electron
117  if (thisTrack->get_charge()*-1==jter->second->get_charge()&&jter->second->get_pt()>_kTrackPtCut&&abs(iter->second->get_eta())<1.)
118  {
119  RawCluster* nextCluster= _mainClusterContainer->getCluster(jter->second->get_cal_cluster_id(SvtxTrack::CAL_LAYER(1)));
120  //what if no cluster is found?
121  if(nextCluster&&nextCluster->get_prob()>=_kEMProbCut&&pairCuts(thisTrack,jter->second)){
122  passedPair++;
123  genfit::GFRaveVertex* vtxCan = _vertexer->findSecondaryVertex(thisTrack,jter->second);
124  vtxCan=correctSecondaryVertex(vtxCan,thisTrack,jter->second);
125  if (vtxCan&&vtxCuts(vtxCan))
126  {
127  passedVtx++;
128  _b_refit=true;
129  std::pair<PHGenFit::Track*,PHGenFit::Track*> refit_tracks = refitTracks(vtxCan,thisTrack,jter->second);
130  //attempt to set the photon to the addition of the refit tracks may return NULL
131  TLorentzVector* photon= reconstructPhoton(refit_tracks);
132  //if photon is null attempt to set it to the addition of the original tracks may return NULL
133  if (!photon)
134  {
135  photon = reconstructPhoton(thisTrack,jter->second);
136  _b_refit=false;
137  }
138  //if the photon is reconstructed record its data
139  if(photonCuts(photon)){
140  _b_photon_m = photon->Dot(*photon);
141  _b_photon_pT = photon->Pt();
142  _b_photon_eta = photon->Eta();
143  _b_photon_phi = photon->Phi();
144  _b_track1_pT = thisTrack->get_pt();
145  _b_track2_pT = jter->second->get_pt();
146  passedPhoton++;
147  delete photon;
148  }
149  else{
150  _b_photon_m = -999.;
151  _b_photon_pT = -999.;
152  _b_photon_eta = -999.;
153  _b_photon_phi = -999.;
154  cout<<"photon not reconstructed"<<endl;
155  }
156  /*FIXME currently this is not a valid way to get the truthparticle because get_truth_track_id returns UINT_MAX
157  PHG4Particle* truthparticle = _truthinfo->GetParticle(jter->second->get_truth_track_id());
158  PHG4Particle* truthparticle2 = _truthinfo->GetParticle(thisTrack->get_truth_track_id());
159  PHG4Particle* parent;
160  if(truthparticle) {
161  parent = _truthinfo->GetParticle(truthparticle->get_parent_id());
162  if(TMath::Abs(truthparticle->get_pid())!=11||(parent&&parent->get_pid()!=22)||truthparticle->get_parent_id()!=truthparticle2->get_parent_id()){
163  _b_fake=true;
164  }
165  else if(parent&&parent->get_pid()==22){
166  TLorentzVector ptlv;
167  ptlv.SetPxPyPzE(parent->get_px(),parent->get_py(),parent->get_pz(),parent->get_e());
168  parent->identify();
169  PHG4Particle* grandparent = _truthinfo->GetParticle(parent->get_parent_id());
170  if(grandparent) grandparent->identify();
171  _b_tphoton_phi = ptlv.Phi();
172  _b_tphoton_eta = ptlv.Eta();
173  _b_tphoton_pT = ptlv.Pt();
174  }
175  else{
176  _b_tphoton_phi = -999.;
177  _b_tphoton_eta = -999.;
178  _b_tphoton_pT = -999.;
179  }
180  }//found truth particle
181  else{
182  cout<<"no truth particle"<<endl;
183  _b_tphoton_phi = -999.;
184  _b_tphoton_eta = -999.;
185  _b_tphoton_pT = -999.;
186  }*/
187  _treeSignal->Fill();
188  }//vtx cuts
189  }
190  }
191  }
192  }
193  }
194  }
196 }
197 
199  if(!(recoVertex&&reco1&&reco2)) {
200  return recoVertex;
201  }
202  TVector3 nextPos = recoVertex->getPos();
203  nextPos.SetMagThetaPhi(_regressor->regress(reco1,reco2,recoVertex),nextPos.Theta(),nextPos.Phi());
204 
205  using namespace genfit;
206  // GFRaveVertex* temp = recoVertex;
207  std::vector<GFRaveTrackParameters*> tracks;
208  for(unsigned i =0; i<recoVertex->getNTracks();i++){
209  tracks.push_back(recoVertex->getParameters(i));
210  }
211  recoVertex = new GFRaveVertex(nextPos,recoVertex->getCov(),tracks,recoVertex->getNdf(),recoVertex->getChi2(),recoVertex->getId());
212  // delete temp; //this caused outside references to seg fault //TODO shared_ptr is better
213  return recoVertex;
214 }
215 
216 TLorentzVector* RecoConversionEval::reconstructPhoton(std::pair<PHGenFit::Track*,PHGenFit::Track*> recos){
217  if (recos.first&&recos.second)
218  {
219  cout<<"reconstructing photon from refit tracks"<<endl;
220  TLorentzVector tlv1;
221  tlv1.SetVectM(recos.first->get_mom(),_kElectronRestM);
222  TLorentzVector tlv2;
223  tlv2.SetVectM(recos.second->get_mom(),_kElectronRestM);
224  return new TLorentzVector(tlv1+tlv2);
225  }
226  else return NULL;
227 }
228 
230  if (reco1&&reco2)
231  {
232  cout<<"reconstructing photon from svtx tracks"<<endl;
233  TLorentzVector tlv1(reco1->get_px(),reco1->get_py(),reco1->get_pz(),
234  sqrt(_kElectronRestM*_kElectronRestM+reco1->get_p()*reco1->get_p()));
235  TLorentzVector tlv2(reco2->get_px(),reco2->get_py(),reco2->get_pz(),
236  sqrt(_kElectronRestM*_kElectronRestM+reco2->get_p()*reco2->get_p()));
237  return new TLorentzVector(tlv1+tlv2);
238  }
239  else return NULL;
240 }
241 
242 std::pair<PHGenFit::Track*,PHGenFit::Track*> RecoConversionEval::refitTracks(genfit::GFRaveVertex* vtx,SvtxTrack* reco1,SvtxTrack* reco2){
243  std::pair<PHGenFit::Track*,PHGenFit::Track*> r;
244  if(!vtx)
245  {
246  cerr<<"WARNING: No vertex to refit tracks"<<endl;
247  r.first=NULL;
248  r.second=NULL;
249 
250  }
251  else{
252  r.first=_vertexer->refitTrack(vtx,reco1);
253  r.second=_vertexer->refitTrack(vtx,reco2);
254  }
255  return r;
256 }
257 
259  return detaCut(t1->get_eta(),t2->get_eta())&&hitCuts(t1,t2);//TODO add approach distance ?
260 }
261 
262 bool RecoConversionEval::photonCuts(TLorentzVector* photon)const{
263  return photon&&photon->Dot(*photon)>_kPhotonMmin&&photon->Dot(*photon)<_kPhotonMmax&&_kPhotonPTmin<photon->Pt();
264 }
265 
266 
270  unsigned l1 = TrkrDefs::getLayer(c1->getClusKey());
271  unsigned l2 = TrkrDefs::getLayer(c2->getClusKey());
272  //check that the first hits are close enough
273  return abs(l1-l2)<=_kDLayerCut;
274 }
275 
276 /*bool RecoConversionEval::vtxCuts(genfit::GFRaveVertex* vtxCan, SvtxTrack* t1, SvtxTrack *t2){
277 //TODO program the cuts invariant mass, pT
278 return vtxRadiusCut(vtxCan->getPos());
279 // && vtxTrackRPhiCut(vtxCan->getPos(),t1)&&vtxTrackRPhiCut(vtxCan->getPos(),t2)&&
280 //vtxTrackRZCut(vtxCan->getPos(),t1)&&vtxTrackRZCut(vtxCan->getPos(),t2)&&vtxCan->getChi2()>_kVtxChi2Cut;
281 }*/
282 
284  return vtxRadiusCut(vtxCan->getPos());
285 }
286 
287 bool RecoConversionEval::vtxTrackRZCut(TVector3 recoVertPos, SvtxTrack* track){
288  float dR = sqrt(recoVertPos.x()*recoVertPos.x()+recoVertPos.y()*recoVertPos.y())-sqrt(track->get_x()*track->get_x()+track->get_y()*track->get_y());
289  float dZ = recoVertPos.z()-track->get_z();
290  return sqrt(dR*dR+dZ*dZ)<_kVtxRZCut;
291 }
292 
293 //bool RecoConversionEval::invariantMassCut()
294 
295 bool RecoConversionEval::vtxTrackRPhiCut(TVector3 recoVertPos, SvtxTrack* track){
296  float vtxR=sqrt(recoVertPos.x()*recoVertPos.x()+recoVertPos.y()*recoVertPos.y());
297  float trackR=sqrt(track->get_x()*track->get_x()+track->get_y()*track->get_y());
298  return sqrt(vtxR*vtxR+trackR*trackR-2*vtxR*trackR*cos(recoVertPos.Phi()-track->get_phi()))<_kVtxRPhiCut;
299 }
300 
301 bool RecoConversionEval::vtxRadiusCut(TVector3 recoVertPos){
302  return sqrt(recoVertPos.x()*recoVertPos.x()+recoVertPos.y()*recoVertPos.y()) > _kVtxRCut;
303 }
304 
306  cout<<"Did RecoConversionEval with "<<totalTracks<<" total tracks\n\t";
307  cout<<1-(float)passedpTEtaQ/totalTracks<<"+/-"<<sqrt((float)passedpTEtaQ)/totalTracks<<" of tracks were rejected by pTEtaQ\n\t";
308  cout<<1-(float)passedCluster/passedpTEtaQ<<"+/-"<<sqrt((float)passedCluster)/passedpTEtaQ<<" of remaining tracks were rejected by cluster\n\t";
309  cout<<1-(float)passedPair/passedCluster<<"+/-"<<sqrt((float)passedPair)/passedCluster<<" of pairs were rejected by pair cuts\n\t";
310  cout<<1-(float)passedVtx/passedPair<<"+/-"<<sqrt((float)passedVtx)/passedPair<<" of vtx were rejected by vtx cuts\n\t";
311  _treeBackground->Fill();
312  if(_file){
313  _file->Write();
314  _file->Close();
315  }
316  cout<<"good end"<<endl;
318 }
319 
321  static const double eps = 0.000001;
322  TVector3 u(t1->get_px(),t1->get_py(),t1->get_pz());
323  TVector3 v(t2->get_px(),t2->get_py(),t2->get_pz());
324  TVector3 w(t1->get_x()-t2->get_x(),t1->get_x()-t2->get_y(),t1->get_x()-t2->get_z());
325 
326  double a = u.Dot(u);
327  double b = u.Dot(v);
328  double c = v.Dot(v);
329  double d = u.Dot(w);
330  double e = v.Dot(w);
331 
332  double D = a*c - b*b;
333  double sc, tc;
334  // compute the line parameters of the two closest points
335  if (D < eps) { // the lines are almost parallel
336  sc = 0.0;
337  tc = (b>c ? d/b : e/c); // use the largest denominator
338  }
339  else {
340  sc = (b*e - c*d) / D;
341  tc = (a*e - b*d) / D;
342  }
343  // get the difference of the two closest points
344  u*=sc;
345  v*=tc;
346  w+=u;
347  w-=v;
348  return w.Mag()<=_kApprochCut; // return the closest distance
349 }
350