File indexing completed on 2025-08-03 08:15:03
0001 #include "RecoConversionEval.h"
0002 #include "SVReco.h"
0003 #include "VtxRegressor.h"
0004
0005 #include <fun4all/Fun4AllReturnCodes.h>
0006 #include <phool/PHCompositeNode.h>
0007 #include <phool/getClass.h>
0008 #include <phgenfit/Track.h>
0009 #include <calobase/RawClusterContainer.h>
0010 #include <calobase/RawCluster.h>
0011 #include <trackbase_historic/SvtxTrack.h>
0012 #include <trackbase_historic/SvtxTrackMap.h>
0013 #include <trackbase_historic/SvtxVertexMap.h>
0014 #include <trackbase_historic/SvtxVertex.h>
0015 #include <trackbase_historic/SvtxHitMap.h>
0016 #include <trackbase_historic/SvtxHit.h>
0017 #include <trackbase_historic/SvtxClusterMap.h>
0018 #include <trackbase_historic/SvtxCluster.h>
0019 #include <trackbase/TrkrClusterContainer.h>
0020 #include <trackbase/TrkrClusterv1.h>
0021 #include <g4eval/SvtxEvalStack.h>
0022 #include <g4main/PHG4Particle.h>
0023 #include <g4main/PHG4VtxPoint.h>
0024 #include <g4main/PHG4TruthInfoContainer.h>
0025
0026
0027 #include <TTree.h>
0028 #include <TFile.h>
0029 #include <TLorentzVector.h>
0030
0031 #include <iostream>
0032 #include <cmath>
0033 #include <algorithm>
0034 #include <sstream>
0035
0036 using namespace std;
0037
0038 RecoConversionEval::RecoConversionEval(const std::string &name,std::string tmvamethod,std::string tmvapath) :
0039 SubsysReco("RecoConversionEval"), _fname(name)
0040 {
0041 _regressor = new VtxRegressor(tmvamethod,tmvapath);
0042 }
0043
0044 RecoConversionEval::~RecoConversionEval(){
0045 cout<<"deleting RCE"<<endl;
0046 if(_vertexer) delete _vertexer;
0047 if(_regressor) delete _regressor;
0048 }
0049
0050 int RecoConversionEval::Init(PHCompositeNode *topNode) {
0051 return Fun4AllReturnCodes::EVENT_OK;
0052 }
0053
0054 int RecoConversionEval::InitRun(PHCompositeNode *topNode) {
0055 _vertexer = new SVReco();
0056
0057 _vertexer->InitRun(topNode);
0058 _file = new TFile( _fname.c_str(), "RECREATE");
0059 _treeSignal = new TTree("recoSignal","strong saharah bush");
0060 _treeSignal->SetAutoSave(300);
0061 _treeSignal->Branch("photon_m", &_b_photon_m);
0062 _treeSignal->Branch("photon_pT", &_b_photon_pT);
0063 _treeSignal->Branch("photon_eta", &_b_photon_eta);
0064 _treeSignal->Branch("photon_phi", &_b_photon_phi);
0065 _treeSignal->Branch("track1_pT", &_b_track1_pT);
0066 _treeSignal->Branch("track2_pT", &_b_track2_pT);
0067 _treeSignal->Branch("refit", &_b_refit);
0068
0069 _treeBackground = new TTree("recoBackground","friendly fern");
0070 _treeBackground->SetAutoSave(300);
0071 _treeBackground->Branch("total", &totalTracks);
0072 _treeBackground->Branch("tracksPEQ", &passedpTEtaQ);
0073 _treeBackground->Branch("tracks_clus", &passedCluster);
0074 _treeBackground->Branch("pairs", &passedPair);
0075 _treeBackground->Branch("vtx", &passedVtx);
0076 _treeBackground->Branch("photon", &passedPhoton);
0077
0078 return Fun4AllReturnCodes::EVENT_OK;
0079 }
0080
0081 void RecoConversionEval::doNodePointers(PHCompositeNode *topNode){
0082 _allTracks = findNode::getClass<SvtxTrackMap>(topNode,"SvtxTrackMap");
0083 _mainClusterContainer = findNode::getClass<RawClusterContainer>(topNode,"CLUSTER_CEMC");
0084
0085
0086
0087
0088 _clusterMap = findNode::getClass<TrkrClusterContainer>(topNode, "TRKR_CLUSTER");
0089 _vertexer->InitEvent(topNode);
0090
0091 _truthinfo = findNode::getClass<PHG4TruthInfoContainer>(topNode,"G4TruthInfo");
0092
0093 }
0094
0095 bool RecoConversionEval::hasNodePointers()const{
0096 return _allTracks &&_mainClusterContainer && _vertexer;
0097 }
0098
0099 int RecoConversionEval::process_event(PHCompositeNode *topNode) {
0100 doNodePointers(topNode);
0101
0102 for ( SvtxTrackMap::Iter iter = _allTracks->begin(); iter != _allTracks->end(); ++iter) {
0103
0104 totalTracks++;
0105 if (abs(iter->second->get_charge())==1&&iter->second->get_pt()>_kTrackPtCut&&abs(iter->second->get_eta())<1.)
0106 {
0107 SvtxTrack* thisTrack = iter->second;
0108 passedpTEtaQ++;
0109 RawCluster* bestCluster= _mainClusterContainer->getCluster(thisTrack->get_cal_cluster_id(SvtxTrack::CAL_LAYER(1)));
0110
0111 if(bestCluster&&bestCluster->get_prob()>=_kEMProbCut){
0112
0113 passedCluster++;
0114 for (SvtxTrackMap::Iter jter = iter; jter != _allTracks->end(); ++jter)
0115 {
0116
0117 if (thisTrack->get_charge()*-1==jter->second->get_charge()&&jter->second->get_pt()>_kTrackPtCut&&abs(iter->second->get_eta())<1.)
0118 {
0119 RawCluster* nextCluster= _mainClusterContainer->getCluster(jter->second->get_cal_cluster_id(SvtxTrack::CAL_LAYER(1)));
0120
0121 if(nextCluster&&nextCluster->get_prob()>=_kEMProbCut&&pairCuts(thisTrack,jter->second)){
0122 passedPair++;
0123 genfit::GFRaveVertex* vtxCan = _vertexer->findSecondaryVertex(thisTrack,jter->second);
0124 vtxCan=correctSecondaryVertex(vtxCan,thisTrack,jter->second);
0125 if (vtxCan&&vtxCuts(vtxCan))
0126 {
0127 passedVtx++;
0128 _b_refit=true;
0129 std::pair<PHGenFit::Track*,PHGenFit::Track*> refit_tracks = refitTracks(vtxCan,thisTrack,jter->second);
0130
0131 TLorentzVector* photon= reconstructPhoton(refit_tracks);
0132
0133 if (!photon)
0134 {
0135 photon = reconstructPhoton(thisTrack,jter->second);
0136 _b_refit=false;
0137 }
0138
0139 if(photonCuts(photon)){
0140 _b_photon_m = photon->Dot(*photon);
0141 _b_photon_pT = photon->Pt();
0142 _b_photon_eta = photon->Eta();
0143 _b_photon_phi = photon->Phi();
0144 _b_track1_pT = thisTrack->get_pt();
0145 _b_track2_pT = jter->second->get_pt();
0146 passedPhoton++;
0147 delete photon;
0148 }
0149 else{
0150 _b_photon_m = -999.;
0151 _b_photon_pT = -999.;
0152 _b_photon_eta = -999.;
0153 _b_photon_phi = -999.;
0154 cout<<"photon not reconstructed"<<endl;
0155 }
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187 _treeSignal->Fill();
0188 }
0189 }
0190 }
0191 }
0192 }
0193 }
0194 }
0195 return Fun4AllReturnCodes::EVENT_OK;
0196 }
0197
0198 genfit::GFRaveVertex* RecoConversionEval::correctSecondaryVertex(genfit::GFRaveVertex* recoVertex,SvtxTrack* reco1,SvtxTrack* reco2){
0199 if(!(recoVertex&&reco1&&reco2)) {
0200 return recoVertex;
0201 }
0202 TVector3 nextPos = recoVertex->getPos();
0203 nextPos.SetMagThetaPhi(_regressor->regress(reco1,reco2,recoVertex),nextPos.Theta(),nextPos.Phi());
0204
0205 using namespace genfit;
0206
0207 std::vector<GFRaveTrackParameters*> tracks;
0208 for(unsigned i =0; i<recoVertex->getNTracks();i++){
0209 tracks.push_back(recoVertex->getParameters(i));
0210 }
0211 recoVertex = new GFRaveVertex(nextPos,recoVertex->getCov(),tracks,recoVertex->getNdf(),recoVertex->getChi2(),recoVertex->getId());
0212
0213 return recoVertex;
0214 }
0215
0216 TLorentzVector* RecoConversionEval::reconstructPhoton(std::pair<PHGenFit::Track*,PHGenFit::Track*> recos){
0217 if (recos.first&&recos.second)
0218 {
0219 cout<<"reconstructing photon from refit tracks"<<endl;
0220 TLorentzVector tlv1;
0221 tlv1.SetVectM(recos.first->get_mom(),_kElectronRestM);
0222 TLorentzVector tlv2;
0223 tlv2.SetVectM(recos.second->get_mom(),_kElectronRestM);
0224 return new TLorentzVector(tlv1+tlv2);
0225 }
0226 else return NULL;
0227 }
0228
0229 TLorentzVector* RecoConversionEval::reconstructPhoton(SvtxTrack* reco1,SvtxTrack* reco2){
0230 if (reco1&&reco2)
0231 {
0232 cout<<"reconstructing photon from svtx tracks"<<endl;
0233 TLorentzVector tlv1(reco1->get_px(),reco1->get_py(),reco1->get_pz(),
0234 sqrt(_kElectronRestM*_kElectronRestM+reco1->get_p()*reco1->get_p()));
0235 TLorentzVector tlv2(reco2->get_px(),reco2->get_py(),reco2->get_pz(),
0236 sqrt(_kElectronRestM*_kElectronRestM+reco2->get_p()*reco2->get_p()));
0237 return new TLorentzVector(tlv1+tlv2);
0238 }
0239 else return NULL;
0240 }
0241
0242 std::pair<PHGenFit::Track*,PHGenFit::Track*> RecoConversionEval::refitTracks(genfit::GFRaveVertex* vtx,SvtxTrack* reco1,SvtxTrack* reco2){
0243 std::pair<PHGenFit::Track*,PHGenFit::Track*> r;
0244 if(!vtx)
0245 {
0246 cerr<<"WARNING: No vertex to refit tracks"<<endl;
0247 r.first=NULL;
0248 r.second=NULL;
0249
0250 }
0251 else{
0252 r.first=_vertexer->refitTrack(vtx,reco1);
0253 r.second=_vertexer->refitTrack(vtx,reco2);
0254 }
0255 return r;
0256 }
0257
0258 bool RecoConversionEval::pairCuts(SvtxTrack* t1, SvtxTrack* t2)const{
0259 return detaCut(t1->get_eta(),t2->get_eta())&&hitCuts(t1,t2);
0260 }
0261
0262 bool RecoConversionEval::photonCuts(TLorentzVector* photon)const{
0263 return photon&&photon->Dot(*photon)>_kPhotonMmin&&photon->Dot(*photon)<_kPhotonMmax&&_kPhotonPTmin<photon->Pt();
0264 }
0265
0266
0267 bool RecoConversionEval::hitCuts(SvtxTrack* reco1, SvtxTrack* reco2)const {
0268 TrkrCluster *c1 = _clusterMap->findCluster(*(reco1->begin_cluster_keys()));
0269 TrkrCluster *c2 = _clusterMap->findCluster(*(reco2->begin_cluster_keys()));
0270 unsigned l1 = TrkrDefs::getLayer(c1->getClusKey());
0271 unsigned l2 = TrkrDefs::getLayer(c2->getClusKey());
0272
0273 return abs(l1-l2)<=_kDLayerCut;
0274 }
0275
0276
0277
0278
0279
0280
0281
0282
0283 bool RecoConversionEval::vtxCuts(genfit::GFRaveVertex* vtxCan){
0284 return vtxRadiusCut(vtxCan->getPos());
0285 }
0286
0287 bool RecoConversionEval::vtxTrackRZCut(TVector3 recoVertPos, SvtxTrack* track){
0288 float dR = sqrt(recoVertPos.x()*recoVertPos.x()+recoVertPos.y()*recoVertPos.y())-sqrt(track->get_x()*track->get_x()+track->get_y()*track->get_y());
0289 float dZ = recoVertPos.z()-track->get_z();
0290 return sqrt(dR*dR+dZ*dZ)<_kVtxRZCut;
0291 }
0292
0293
0294
0295 bool RecoConversionEval::vtxTrackRPhiCut(TVector3 recoVertPos, SvtxTrack* track){
0296 float vtxR=sqrt(recoVertPos.x()*recoVertPos.x()+recoVertPos.y()*recoVertPos.y());
0297 float trackR=sqrt(track->get_x()*track->get_x()+track->get_y()*track->get_y());
0298 return sqrt(vtxR*vtxR+trackR*trackR-2*vtxR*trackR*cos(recoVertPos.Phi()-track->get_phi()))<_kVtxRPhiCut;
0299 }
0300
0301 bool RecoConversionEval::vtxRadiusCut(TVector3 recoVertPos){
0302 return sqrt(recoVertPos.x()*recoVertPos.x()+recoVertPos.y()*recoVertPos.y()) > _kVtxRCut;
0303 }
0304
0305 int RecoConversionEval::End(PHCompositeNode *topNode) {
0306 cout<<"Did RecoConversionEval with "<<totalTracks<<" total tracks\n\t";
0307 cout<<1-(float)passedpTEtaQ/totalTracks<<"+/-"<<sqrt((float)passedpTEtaQ)/totalTracks<<" of tracks were rejected by pTEtaQ\n\t";
0308 cout<<1-(float)passedCluster/passedpTEtaQ<<"+/-"<<sqrt((float)passedCluster)/passedpTEtaQ<<" of remaining tracks were rejected by cluster\n\t";
0309 cout<<1-(float)passedPair/passedCluster<<"+/-"<<sqrt((float)passedPair)/passedCluster<<" of pairs were rejected by pair cuts\n\t";
0310 cout<<1-(float)passedVtx/passedPair<<"+/-"<<sqrt((float)passedVtx)/passedPair<<" of vtx were rejected by vtx cuts\n\t";
0311 _treeBackground->Fill();
0312 if(_file){
0313 _file->Write();
0314 _file->Close();
0315 }
0316 cout<<"good end"<<endl;
0317 return Fun4AllReturnCodes::EVENT_OK;
0318 }
0319
0320 bool RecoConversionEval::approachDistance(SvtxTrack *t1,SvtxTrack* t2)const{
0321 static const double eps = 0.000001;
0322 TVector3 u(t1->get_px(),t1->get_py(),t1->get_pz());
0323 TVector3 v(t2->get_px(),t2->get_py(),t2->get_pz());
0324 TVector3 w(t1->get_x()-t2->get_x(),t1->get_x()-t2->get_y(),t1->get_x()-t2->get_z());
0325
0326 double a = u.Dot(u);
0327 double b = u.Dot(v);
0328 double c = v.Dot(v);
0329 double d = u.Dot(w);
0330 double e = v.Dot(w);
0331
0332 double D = a*c - b*b;
0333 double sc, tc;
0334
0335 if (D < eps) {
0336 sc = 0.0;
0337 tc = (b>c ? d/b : e/c);
0338 }
0339 else {
0340 sc = (b*e - c*d) / D;
0341 tc = (a*e - b*d) / D;
0342 }
0343
0344 u*=sc;
0345 v*=tc;
0346 w+=u;
0347 w-=v;
0348 return w.Mag()<=_kApprochCut;
0349 }
0350