3 #include <phfield/PHFieldConfig_v3.h>
4 #include <phfield/PHFieldUtility.h>
5 #include <phgeom/PHGeomUtility.h>
18 #include <GenFit/FieldManager.h>
19 #include <GenFit/MaterialEffects.h>
20 #include <GenFit/TGeoMaterialInterface.h>
24 #include <TGeoManager.h>
31 static bool inited =
false;
33 static double Z_TARGET;
35 static double Z_UPSTREAM;
39 static double SIGX_BEAM;
40 static double SIGY_BEAM;
43 void initGlobalVariables()
64 legacyContainer_in(false),
65 legacyContainer_out(false),
66 enableSingleRetracking(false),
71 recDimuonVec(nullptr),
81 initGlobalVariables();
89 ret = GetNodes(topNode);
92 ret = MakeNodes(topNode);
96 ret = InitField(topNode);
99 ret = InitGeom(topNode);
112 else recDimuonVec->
clear();
114 std::vector<int> trackIDs1;
115 std::vector<int> trackIDs2;
116 int nTracks = legacyContainer_in ? recEvent->
getNTracks() : recTrackVec->
size();
117 if(
Verbosity() > 10) std::cout <<
"SQVertexing::process_event(): nTracks = " << nTracks << std::endl;
118 for(
int i = 0; i < nTracks; ++i)
125 if(recTrack->
getCharge() == charge1) trackIDs1.push_back(i);
126 if(recTrack->
getCharge() == charge2) trackIDs2.push_back(i);
130 if(
Verbosity() > 10) std::cout <<
" N of trackIDs1 & trackIDs1 = " << trackIDs1.size() <<
" & " << trackIDs2.size() << std::endl;
132 for(
int i = 0; i < trackIDs1.size(); ++i)
134 for(
int j = charge1 == charge2 ? i+1 : 0; j < trackIDs2.size(); ++j)
137 if(trackIDs1[i] == trackIDs2[j])
continue;
139 SRecTrack* recTrack1 = legacyContainer_in ? &(recEvent->
getTrack(trackIDs1[i])) :
dynamic_cast<SRecTrack*
>(recTrackVec->
at(trackIDs1[i]));
140 SRecTrack* recTrack2 = legacyContainer_in ? &(recEvent->
getTrack(trackIDs2[j])) :
dynamic_cast<SRecTrack*
>(recTrackVec->
at(trackIDs2[j]));
147 recDimuon.set_track_id_neg(trackIDs2[j]);
149 if(legacyContainer_out)
167 if(legacyContainer_in || legacyContainer_out)
169 recEvent = findNode::getClass<SRecEvent>(topNode,
"SRecEvent");
172 std::cerr <<
Name() <<
": failed finding SRecEvent node, abort." << std::endl;
178 recTrackVec = findNode::getClass<SQTrackVector>(topNode,
"SQRecTrackVector");
181 std::cerr <<
Name() <<
": failed finding SQRecTrackVector node, abort." << std::endl;
191 if(!legacyContainer_out)
197 std::cerr <<
Name() <<
": cannot locate DST node, abort." << std::endl;
201 TString dimuonVecName = TString::Format(
"SQRecDimuonVector_%s%s", (charge1 == 1 ?
"P" :
"M"), (charge2 == 1 ?
"P" :
"M"));
202 recDimuonVec = findNode::getClass<SQDimuonVector>(dstNode, dimuonVecName.Data());
214 double SQVertexing::swimTrackToVertex(
SQGenFit::GFTrack& track,
double z, TVector3* pos, TVector3* mom)
220 double SQVertexing::refitTrkToVtx(
SQGenFit::GFTrack& track,
double z, TVector3* pos, TVector3* mom)
222 if(
Verbosity() > 10) std::cout <<
"SQVertexing::refitTrkToVtx(): z = " << z << std::endl;
225 double z_offset_prev = 1.E9;
226 double z_offset_curr = 0.;
228 const int n_iter_max = 100;
230 while(fabs(z_offset_curr - z_offset_prev) > 0.1)
232 chi2 = swimTrackToVertex(track, z, pos, mom);
235 z_offset_prev = z_offset_curr;
236 z_offset_curr = calcZsclp(mom->Mag());
239 if(
Verbosity() > 20) std::cout <<
" i_iter = " << n_iter <<
": p = " << mom->Mag() <<
", dz = " << z_offset_curr <<
" - " << z_offset_prev <<
" = " << z_offset_curr - z_offset_prev << std::endl;
240 if (++n_iter == n_iter_max) {
241 std::cout <<
"!WARNING! SQVertexing::refitTrkToVtx(): Give up the iteration." << std::endl;
246 std::cout <<
" n_iter = " << n_iter <<
", pos = (" << pos->X() <<
", " << pos->Y() <<
", " << pos->Z() <<
"), mom = (" << mom->X() <<
", " << mom->Y() <<
", " << mom->Z() <<
")" << std::endl;
255 double SQVertexing::refitTrkToVtx(
SRecTrack* track,
double z, TVector3* pos, TVector3* mom)
258 return refitTrkToVtx(gtrk, z, pos, mom);
261 double SQVertexing::calcZsclp(
double p)
264 else if(p > 120.) p = 120.;
266 return 301.84 - 1.27137*p + 0.0218294*p*p - 0.000170711*p*p*p + 4.94683e-07*p*p*p*p - 271.;
281 if(enableSingleRetracking)
301 if(enableSingleRetracking)
332 if(
Verbosity() > 10) std::cout <<
" SQVertexing::processOneDimuon(): " << std::endl;
352 double z_vtx = findDimuonZVertex(dimuon, gtrk1, gtrk2);
353 dimuon.
vtx.SetXYZ(0., 0., z_vtx);
358 dimuon.
chisq_kf = swimTrackToVertex(gtrk1, z_vtx, &pos, &mom);
362 dimuon.
chisq_kf += swimTrackToVertex(gtrk2, z_vtx, &pos, &mom);
367 refitTrkToVtx(gtrk1, Z_TARGET, &pos, &mom);
369 refitTrkToVtx(gtrk2, Z_TARGET, &pos, &mom);
374 swimTrackToVertex(gtrk1, Z_DUMP, &pos, &mom);
376 swimTrackToVertex(gtrk2, Z_DUMP, &pos, &mom);
380 if(charge1 == charge2)
382 if(rndm.Rndm() < 0.5)
402 double stepsize[3] = {25., 5., 1.};
405 double chi2_min = 1.E9;
406 for(
int i = 0; i < 3; ++i)
408 double z_start, z_end;
416 z_start = z_min + stepsize[i-1];
417 z_end = z_min - stepsize[i-1];
420 for(
double z = z_start; z > z_end; z = z - stepsize[i])
422 double chi2_1 = swimTrackToVertex(track1, z);
423 double chi2_2 = swimTrackToVertex(track2, z);
424 double chi2 = chi2_1 > 0 && chi2_2 > 0 ? chi2_1 + chi2_2 : 1.E9;
440 gfield =
dynamic_cast<SQGenFit::GFField*
>(genfit::FieldManager::getInstance()->getField());
442 catch(
const std::exception& e)
444 std::cout <<
"SQVertexing::InitField - Caught an exception " << std::endl;
448 if(gfield ==
nullptr)
457 std::cout <<
"SQVertexing::InitField - creating new GenFit field map" << std::endl;
459 genfit::FieldManager::getInstance()->init(gfield);
463 std::cout <<
"SQVertexing::InitField - reading existing GenFit field map" << std::endl;
471 if(geom_file_name !=
"")
473 std::cout <<
"SQVertexing::InitGeom - create geom from " << geom_file_name << std::endl;
478 TGeoManager* geom = TGeoManager::Import(geom_file_name.c_str());
481 genfit::MaterialEffects::getInstance()->init(
new genfit::TGeoMaterialInterface());
485 std::cout <<
"SQVertexing::InitGeom - rely on existing TGeo geometry" << std::endl;
virtual const std::string Name() const
Returns the name of this module.
virtual int Verbosity() const
Gets the verbosity of this module.
PHBoolean addNode(PHNode *)
PHFieldConfig_v3 implements field configuration information for input a field map file.
static PHField * GetFieldMapNode(const PHFieldConfig *default_config=nullptr, PHCompositeNode *topNode=nullptr, const int verbosity=0)
Get transient PHField from DST nodes. If not found, make a new one based on default_config.
static PHField * BuildFieldMap(const PHFieldConfig *field_config, const int verbosity=0)
Build or build field map with a configuration object.
transient DST object for field storage and access
virtual double get_DoubleFlag(const std::string &name) const
virtual int get_IntFlag(const std::string &name) const
virtual const std::string get_CharFlag(const std::string &flag) const
static int ImportGeomFile(PHCompositeNode *topNode, const std::string &geometry_file)
TGeo ROOT/GDML/Macro file -> DST node with automatic file type discrimination based on file names.
virtual void push_back(const SQDimuon *dim)=0
void setOffset(double offset=0.)
double swimToVertex(double z, TVector3 *pos=nullptr, TVector3 *mom=nullptr, TMatrixDSym *cov=nullptr)
virtual const SQTrack * at(const size_t id) const =0
virtual size_t size() const =0
int process_event(PHCompositeNode *topNode)
int Init(PHCompositeNode *topNode=0)
SQVertexing(const std::string &name="SQVertexing", int sign1=1, int sign2=-1)
int InitRun(PHCompositeNode *topNode=0)
bool processOneMuon(SRecTrack *track)
int End(PHCompositeNode *topNode)
Called at the end of all processing.
bool processOneDimuon(SRecTrack *track1, SRecTrack *track2, SRecDimuon &dimuon)
TVector3 vtx
3-vector vertex position
TLorentzVector p_neg_target
virtual void set_track_id_pos(const int a)
Double_t chisq_target
Chisq of three test position.
TLorentzVector p_pos_target
Track momentum projections at different location.
Double_t chisq_kf
Vertex fit chisqs.
TLorentzVector p_pos
4-momentum of the muon tracks after vertex fit
TVector3 proj_target_pos
Track projections at different location.
TLorentzVector p_pos_dump
TLorentzVector p_neg_dump
void insertDimuon(SRecDimuon dimuon)
Insert dimuon.
Int_t getNTracks()
Get tracks.
void clearDimuons()
Clear the dimuon list.
SRecTrack & getTrack(Int_t i)
Int_t getCharge() const
Gets.
Double_t getChisqTarget()
void setChisqDump(Double_t chisq)
void setChisqTarget(Double_t chisq)
Double_t getChisqUpstream()
void printGF(std::ostream &os=std::cout) const
void setChisqUpstream(Double_t chisq)
Bool_t isKalmanFitted()
Fit status.
void swimToVertex(TVector3 *pos=nullptr, TVector3 *mom=nullptr, bool hyptest=true)
Simple swim to vertex.
TVector3 getDumpPos()
Get mom/pos at a given location.
void setVertexFast(TVector3 mom, TVector3 pos)
Plain setting, no KF-related stuff.
void setChisqVertex(Double_t chisq)
static recoConsts * instance()