Class Reference for E1039 Core & Analysis Software
SQVertexing.cxx
Go to the documentation of this file.
1 #include "SQVertexing.h"
2 
3 #include <phfield/PHFieldConfig_v3.h>
4 #include <phfield/PHFieldUtility.h>
5 #include <phgeom/PHGeomUtility.h>
6 
8 #include <phool/PHNodeIterator.h>
9 #include <phool/PHIODataNode.h>
10 #include <phool/PHRandomSeed.h>
11 #include <phool/getClass.h>
12 #include <phool/recoConsts.h>
13 #include <interface_main/SQEvent.h>
18 #include <GenFit/FieldManager.h>
19 #include <GenFit/MaterialEffects.h>
20 #include <GenFit/TGeoMaterialInterface.h>
21 
22 #include "SRecEvent.h"
23 #include "GFTrack.h"
24 #include <TGeoManager.h>
25 #include <iostream>
26 #include <vector>
27 
28 namespace
29 {
30  //static flag to indicate the initialized has been done
31  static bool inited = false;
32 
33  static double Z_TARGET;
34  static double Z_DUMP;
35  static double Z_UPSTREAM;
36 
37  static double X_BEAM;
38  static double Y_BEAM;
39  static double SIGX_BEAM;
40  static double SIGY_BEAM;
41 
42  //initialize global variables
43  void initGlobalVariables()
44  {
45  if(!inited)
46  {
47  inited = true;
48 
50  Z_TARGET = rc->get_DoubleFlag("Z_TARGET");
51  Z_DUMP = rc->get_DoubleFlag("Z_DUMP");
52  Z_UPSTREAM = rc->get_DoubleFlag("Z_UPSTREAM");
53 
54  X_BEAM = rc->get_DoubleFlag("X_BEAM");
55  Y_BEAM = rc->get_DoubleFlag("Y_BEAM");
56  SIGX_BEAM = rc->get_DoubleFlag("SIGX_BEAM");
57  SIGY_BEAM = rc->get_DoubleFlag("SIGY_BEAM");
58  }
59  }
60 };
61 
62 SQVertexing::SQVertexing(const std::string& name, int sign1, int sign2):
63  SubsysReco(name),
64  legacyContainer_in(false),
65  legacyContainer_out(false),
66  enableSingleRetracking(false),
67  gfield(nullptr),
68  geom_file_name(""),
69  recEvent(nullptr),
70  recTrackVec(nullptr),
71  recDimuonVec(nullptr),
72  charge1(sign1),
73  charge2(sign2)
74 {}
75 
77 {}
78 
80 {
81  initGlobalVariables();
83 }
84 
86 {
87  int ret;
88  if (topNode) {
89  ret = GetNodes(topNode);
90  if(ret != Fun4AllReturnCodes::EVENT_OK) return ret;
91 
92  ret = MakeNodes(topNode);
93  if(ret != Fun4AllReturnCodes::EVENT_OK) return ret;
94  }
95 
96  ret = InitField(topNode);
97  if(ret != Fun4AllReturnCodes::EVENT_OK) return ret;
98 
99  ret = InitGeom(topNode);
100  if(ret != Fun4AllReturnCodes::EVENT_OK) return ret;
101 
102  //Initialize random seed
104  rndm.SetSeed(rc->get_IntFlag("RUNNUMBER"));
105 
107 }
108 
110 {
111  if(legacyContainer_out) recEvent->clearDimuons();
112  else recDimuonVec->clear();
113 
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)
119  {
120  SRecTrack* recTrack = legacyContainer_in ? &(recEvent->getTrack(i)) : dynamic_cast<SRecTrack*>(recTrackVec->at(i));
121  if(!recTrack->isKalmanFitted()) continue;
122 
123  processOneMuon(recTrack);
124 
125  if(recTrack->getCharge() == charge1) trackIDs1.push_back(i);
126  if(recTrack->getCharge() == charge2) trackIDs2.push_back(i);
127  }
128 
129  if(trackIDs1.empty() || trackIDs2.empty()) return Fun4AllReturnCodes::EVENT_OK;
130  if(Verbosity() > 10) std::cout << " N of trackIDs1 & trackIDs1 = " << trackIDs1.size() << " & " << trackIDs2.size() << std::endl;
131 
132  for(int i = 0; i < trackIDs1.size(); ++i)
133  {
134  for(int j = charge1 == charge2 ? i+1 : 0; j < trackIDs2.size(); ++j)
135  {
136  //A protection, probably not really needed
137  if(trackIDs1[i] == trackIDs2[j]) continue;
138 
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]));
141 
142  SRecDimuon recDimuon;
143  if(processOneDimuon(recTrack1, recTrack2, recDimuon))
144  {
145  //recDimuon.set_rec_dimuon_id(legacyContainer ? recEvent->getNDimuons() : recDimuonVec->size());
146  recDimuon.set_track_id_pos(trackIDs1[i]);
147  recDimuon.set_track_id_neg(trackIDs2[j]);
148 
149  if(legacyContainer_out)
150  recEvent->insertDimuon(recDimuon);
151  else
152  recDimuonVec->push_back(&recDimuon);
153  }
154  }
155  }
156 
158 }
159 
161 {
163 }
164 
165 int SQVertexing::GetNodes(PHCompositeNode* topNode)
166 {
167  if(legacyContainer_in || legacyContainer_out)
168  {
169  recEvent = findNode::getClass<SRecEvent>(topNode, "SRecEvent");
170  if(!recEvent)
171  {
172  std::cerr << Name() << ": failed finding SRecEvent node, abort." << std::endl;
174  }
175  }
176  else
177  {
178  recTrackVec = findNode::getClass<SQTrackVector>(topNode, "SQRecTrackVector");
179  if(!recTrackVec)
180  {
181  std::cerr << Name() << ": failed finding SQRecTrackVector node, abort." << std::endl;
183  }
184  }
185 
187 }
188 
189 int SQVertexing::MakeNodes(PHCompositeNode* topNode)
190 {
191  if(!legacyContainer_out)
192  {
193  PHNodeIterator iter(topNode);
194  PHCompositeNode* dstNode = static_cast<PHCompositeNode*>(iter.findFirst("PHCompositeNode", "DST"));
195  if(!dstNode)
196  {
197  std::cerr << Name() << ": cannot locate DST node, abort." << std::endl;
199  }
200 
201  TString dimuonVecName = TString::Format("SQRecDimuonVector_%s%s", (charge1 == 1 ? "P" : "M"), (charge2 == 1 ? "P" : "M"));
202  recDimuonVec = findNode::getClass<SQDimuonVector>(dstNode, dimuonVecName.Data());
203  if (!recDimuonVec) {
204  recDimuonVec = new SQDimuonVector_v1();
205  dstNode->addNode(new PHIODataNode<PHObject>(recDimuonVec, dimuonVecName.Data(), "PHObject"));
206  }
207  //recDimuonVec = new SQDimuonVector_v1();
208  //TString dimuonVecName = TString::Format("SQRecDimuonVector_%s%s", (charge1 == 1 ? "P" : "M"), (charge2 == 1 ? "P" : "M"));
209  //dstNode->addNode(new PHIODataNode<PHObject>(recDimuonVec, dimuonVecName.Data(), "PHObject"));
210  }
212 }
213 
214 double SQVertexing::swimTrackToVertex(SQGenFit::GFTrack& track, double z, TVector3* pos, TVector3* mom)
215 {
216  double chi2 = track.swimToVertex(z, pos, mom);
217  return chi2;
218 }
219 
220 double SQVertexing::refitTrkToVtx(SQGenFit::GFTrack& track, double z, TVector3* pos, TVector3* mom)
221 {
222  if(Verbosity() > 10) std::cout << "SQVertexing::refitTrkToVtx(): z = " << z << std::endl;
223  gfield->setOffset(0.);
224 
225  double z_offset_prev = 1.E9;
226  double z_offset_curr = 0.;
227  double chi2 = 0.;
228  const int n_iter_max = 100;
229  int n_iter = 0;
230  while(fabs(z_offset_curr - z_offset_prev) > 0.1)
231  {
232  chi2 = swimTrackToVertex(track, z, pos, mom);
233 
234  //update scatter plane location
235  z_offset_prev = z_offset_curr;
236  z_offset_curr = calcZsclp(mom->Mag());
237 
238  gfield->setOffset(-z_offset_curr);
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;
242  break;
243  }
244  }
245  if(Verbosity() > 10) {
246  std::cout << " n_iter = " << n_iter << ", pos = (" << pos->X() << ", " << pos->Y() << ", " << pos->Z() << "), mom = (" << mom->X() << ", " << mom->Y() << ", " << mom->Z() << ")" << std::endl;
247  }
248 
249  //re-adjust FMag bend plane here
250  gfield->setOffset(0.);
251 
252  return chi2;
253 }
254 
255 double SQVertexing::refitTrkToVtx(SRecTrack* track, double z, TVector3* pos, TVector3* mom)
256 {
257  SQGenFit::GFTrack gtrk(*track);
258  return refitTrkToVtx(gtrk, z, pos, mom);
259 }
260 
261 double SQVertexing::calcZsclp(double p)
262 {
263  if(p < 5.) p = 5.;
264  else if(p > 120.) p = 120.;
265 
266  return 301.84 - 1.27137*p + 0.0218294*p*p - 0.000170711*p*p*p + 4.94683e-07*p*p*p*p - 271.;
267 }
268 
270 {
271  SQGenFit::GFTrack gtrk(*track);
272 
273  //Swim to various places and save info
274  track->swimToVertex(nullptr, nullptr, false);
275 
276  //Hypothesis test should be implemented here
277  //test Z_UPSTREAM
278  track->setChisqUpstream(swimTrackToVertex(gtrk, Z_UPSTREAM));
279 
280  //test Z_TARGET
281  if(enableSingleRetracking)
282  track->setChisqTarget(refitTrkToVtx(gtrk, Z_TARGET));
283  else
284  track->setChisqTarget(swimTrackToVertex(gtrk, Z_TARGET));
285  // if(track->getChisqTarget() > 0.)
286  // {
287  // track->setTargetPos(pos);
288  // track->setTargetMom(mom);
289  // }
290 
291  //test Z_DUMP
292  track->setChisqDump(swimTrackToVertex(gtrk, Z_DUMP));
293  // if(track->getChisqDump() > 0.)
294  // {
295  // track->setDumpPos(pos);
296  // track->setDumpMom(mom);
297  // }
298 
299  //test Z_VERTEX
300  TVector3 pos, mom;
301  if(enableSingleRetracking)
302  track->setChisqVertex(refitTrkToVtx(gtrk, track->getVertexPos().Z(), &pos, &mom));
303  else
304  track->setChisqVertex(swimTrackToVertex(gtrk, track->getVertexPos().Z(), &pos, &mom));
305  track->setVertexFast(mom, pos);
306 
307  /*
308  //Find POCA to beamline -- it seems to be funky and mostly found some place way upstream or downstream
309  // most likely because the cross product of the track direction and beam line direction is way too small
310  // z axis to provide reasonable calculation of the POCA location. It's disabled for now.
311  TVector3 ep1(0., 0., -499.);
312  TVector3 ep2(0., 0., 0.);
313  try
314  {
315  extrapolateToLine(ep1, ep2);
316  TVectorD beamR(1); beamR(0) = 0.;
317  TMatrixDSym beamC(1); beamC(0, 0) = 1000.;
318  strack.setChisqVertex(updatePropState(beamR, beamC));
319  }
320  catch(genfit::Exception& e)
321  {
322  std::cerr << "Hypothesis test failed at beamline: " << e.what() << std::endl;
323  print(0);
324  }
325  */
326 
327  return true;
328 }
329 
331 {
332  if(Verbosity() > 10) std::cout << " SQVertexing::processOneDimuon(): " << std::endl;
333  if(Verbosity() > 20) {
334  track1->printGF();
335  track2->printGF();
336  }
337 
338  //Pre-calculated variables
339  dimuon.proj_target_pos = track1->getTargetPos();
340  dimuon.proj_dump_pos = track1->getDumpPos();
341  dimuon.proj_target_neg = track2->getTargetPos();
342  dimuon.proj_dump_neg = track2->getDumpPos();
343  dimuon.chisq_target = track1->getChisqTarget() + track2->getChisqTarget();
344  dimuon.chisq_dump = track1->getChisqDump() + track2->getChisqDump();
345  dimuon.chisq_upstream = track1->getChisqUpstream() + track2->getChisqUpstream();
346  dimuon.chisq_single = 0.; //no longer used
347  dimuon.chisq_vx = 0.; //no longer used
348 
349  //Vertexing part
350  SQGenFit::GFTrack gtrk1(*track1);
351  SQGenFit::GFTrack gtrk2(*track2);
352  double z_vtx = findDimuonZVertex(dimuon, gtrk1, gtrk2);
353  dimuon.vtx.SetXYZ(0., 0., z_vtx);
354 
355  //Vertex info based on the dimuon vertex
356  //TODO: consider using addjustable bend-plane for vertex test as well
357  TVector3 pos, mom;
358  dimuon.chisq_kf = swimTrackToVertex(gtrk1, z_vtx, &pos, &mom);
359  dimuon.p_pos.SetVectM(mom, M_MU);
360  dimuon.vtx_pos = pos;
361 
362  dimuon.chisq_kf += swimTrackToVertex(gtrk2, z_vtx, &pos, &mom);
363  dimuon.p_neg.SetVectM(mom, M_MU);
364  dimuon.vtx_neg = pos;
365 
366  //Test target hypothesis
367  refitTrkToVtx(gtrk1, Z_TARGET, &pos, &mom);
368  dimuon.p_pos_target.SetVectM(mom, M_MU);
369  refitTrkToVtx(gtrk2, Z_TARGET, &pos, &mom);
370  dimuon.p_neg_target.SetVectM(mom, M_MU);
371 
372  //Test dump hypothesis
373  //TODO: consider using addjustable bend-plane for dump test as well
374  swimTrackToVertex(gtrk1, Z_DUMP, &pos, &mom);
375  dimuon.p_pos_dump.SetVectM(mom, M_MU);
376  swimTrackToVertex(gtrk2, Z_DUMP, &pos, &mom);
377  dimuon.p_neg_dump.SetVectM(mom, M_MU);
378 
379  //Randomly flip the sign of Px of one of the muons if processing like-sign muons
380  if(charge1 == charge2)
381  {
382  if(rndm.Rndm() < 0.5)
383  {
384  dimuon.p_pos.SetPx(-dimuon.p_pos.Px());
385  dimuon.p_pos_target.SetPx(-dimuon.p_pos_target.Px());
386  dimuon.p_pos_dump.SetPx(-dimuon.p_pos_dump.Px());
387  }
388  else
389  {
390  dimuon.p_neg.SetPx(-dimuon.p_neg.Px());
391  dimuon.p_neg_target.SetPx(-dimuon.p_neg_target.Px());
392  dimuon.p_neg_dump.SetPx(-dimuon.p_neg_dump.Px());
393  }
394  }
395 
396  return true;
397 }
398 
399 double SQVertexing::findDimuonZVertex(SRecDimuon& dimuon, SQGenFit::GFTrack& track1, SQGenFit::GFTrack& track2)
400 {
401  //TODO: consider using addjustable bend-plane for vertex finding as well
402  double stepsize[3] = {25., 5., 1.};
403 
404  double z_min = 300.;
405  double chi2_min = 1.E9;
406  for(int i = 0; i < 3; ++i)
407  {
408  double z_start, z_end;
409  if(i == 0)
410  {
411  z_start = z_min;
412  z_end = Z_UPSTREAM;
413  }
414  else
415  {
416  z_start = z_min + stepsize[i-1];
417  z_end = z_min - stepsize[i-1];
418  }
419 
420  for(double z = z_start; z > z_end; z = z - stepsize[i])
421  {
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;
425  if(chi2 < chi2_min)
426  {
427  z_min = z;
428  chi2_min = chi2;
429  }
430  }
431  }
432 
433  return z_min;
434 }
435 
436 int SQVertexing::InitField(PHCompositeNode* topNode)
437 {
438  try
439  {
440  gfield = dynamic_cast<SQGenFit::GFField*>(genfit::FieldManager::getInstance()->getField());
441  }
442  catch(const std::exception& e)
443  {
444  std::cout << "SQVertexing::InitField - Caught an exception " << std::endl;
445  gfield = nullptr;
446  }
447 
448  if(gfield == nullptr)
449  {
451 
452  std::unique_ptr<PHFieldConfig> default_field_cfg(new PHFieldConfig_v3(rc->get_CharFlag("fMagFile"), rc->get_CharFlag("kMagFile"), rc->get_DoubleFlag("FMAGSTR"), rc->get_DoubleFlag("KMAGSTR"), 5.));
453  PHField* phfield;
454  if (topNode) phfield = PHFieldUtility::GetFieldMapNode(default_field_cfg.get(), topNode, 0);
455  else phfield = PHFieldUtility::BuildFieldMap(default_field_cfg.get(), 0);
456 
457  std::cout << "SQVertexing::InitField - creating new GenFit field map" << std::endl;
458  gfield = new SQGenFit::GFField(phfield);
459  genfit::FieldManager::getInstance()->init(gfield);
460  }
461  else
462  {
463  std::cout << "SQVertexing::InitField - reading existing GenFit field map" << std::endl;
464  }
465 
467 }
468 
469 int SQVertexing::InitGeom(PHCompositeNode* topNode)
470 {
471  if(geom_file_name != "")
472  {
473  std::cout << "SQVertexing::InitGeom - create geom from " << geom_file_name << std::endl;
474  if (topNode) {
475  int ret = PHGeomUtility::ImportGeomFile(topNode, geom_file_name);
476  if (ret != Fun4AllReturnCodes::EVENT_OK) return ret;
477  } else {
478  TGeoManager* geom = TGeoManager::Import(geom_file_name.c_str());
479  if (!geom) return Fun4AllReturnCodes::ABORTEVENT;
480  }
481  genfit::MaterialEffects::getInstance()->init(new genfit::TGeoMaterialInterface());
482  }
483  else
484  {
485  std::cout << "SQVertexing::InitGeom - rely on existing TGeo geometry" << std::endl;
486  }
487 
489 }
#define M_MU
Definition: GlobalConsts.h:12
virtual const std::string Name() const
Returns the name of this module.
Definition: Fun4AllBase.h:23
virtual int Verbosity() const
Gets the verbosity of this module.
Definition: Fun4AllBase.h:64
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
Definition: PHField.h:14
virtual double get_DoubleFlag(const std::string &name) const
Definition: PHFlag.cc:49
virtual int get_IntFlag(const std::string &name) const
Definition: PHFlag.cc:117
virtual const std::string get_CharFlag(const std::string &flag) const
Definition: PHFlag.cc:13
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 clear()=0
virtual void push_back(const SQDimuon *dim)=0
void setOffset(double offset=0.)
Definition: GFField.h:21
double swimToVertex(double z, TVector3 *pos=nullptr, TVector3 *mom=nullptr, TMatrixDSym *cov=nullptr)
Definition: GFTrack.cxx:304
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)
Definition: SQVertexing.cxx:79
SQVertexing(const std::string &name="SQVertexing", int sign1=1, int sign2=-1)
Definition: SQVertexing.cxx:62
int InitRun(PHCompositeNode *topNode=0)
Definition: SQVertexing.cxx:85
bool processOneMuon(SRecTrack *track)
int End(PHCompositeNode *topNode)
Called at the end of all processing.
bool processOneDimuon(SRecTrack *track1, SRecTrack *track2, SRecDimuon &dimuon)
Double_t chisq_single
Definition: SRecEvent.h:398
TVector3 vtx
3-vector vertex position
Definition: SRecEvent.h:379
TLorentzVector p_neg_target
Definition: SRecEvent.h:370
Double_t chisq_dump
Definition: SRecEvent.h:406
Double_t chisq_upstream
Definition: SRecEvent.h:407
TVector3 proj_target_neg
Definition: SRecEvent.h:386
Double_t chisq_vx
Definition: SRecEvent.h:402
virtual void set_track_id_pos(const int a)
Definition: SRecEvent.h:321
Double_t chisq_target
Chisq of three test position.
Definition: SRecEvent.h:405
TVector3 proj_dump_pos
Definition: SRecEvent.h:385
TVector3 proj_dump_neg
Definition: SRecEvent.h:387
TLorentzVector p_pos_target
Track momentum projections at different location.
Definition: SRecEvent.h:369
TLorentzVector p_neg
Definition: SRecEvent.h:366
Double_t chisq_kf
Vertex fit chisqs.
Definition: SRecEvent.h:401
TLorentzVector p_pos
4-momentum of the muon tracks after vertex fit
Definition: SRecEvent.h:365
TVector3 vtx_neg
Definition: SRecEvent.h:381
TVector3 vtx_pos
Definition: SRecEvent.h:380
TVector3 proj_target_pos
Track projections at different location.
Definition: SRecEvent.h:384
TLorentzVector p_pos_dump
Definition: SRecEvent.h:371
TLorentzVector p_neg_dump
Definition: SRecEvent.h:372
void insertDimuon(SRecDimuon dimuon)
Insert dimuon.
Definition: SRecEvent.h:470
Int_t getNTracks()
Get tracks.
Definition: SRecEvent.h:455
void clearDimuons()
Clear the dimuon list.
Definition: SRecEvent.cxx:824
SRecTrack & getTrack(Int_t i)
Definition: SRecEvent.h:456
TVector3 getTargetPos()
Definition: SRecEvent.h:188
Int_t getCharge() const
Gets.
Definition: SRecEvent.h:101
Double_t getChisqTarget()
Definition: SRecEvent.h:199
TVector3 getVertexPos()
Definition: SRecEvent.h:196
void setChisqDump(Double_t chisq)
Definition: SRecEvent.h:215
Double_t getChisqDump()
Definition: SRecEvent.h:198
void setChisqTarget(Double_t chisq)
Definition: SRecEvent.h:216
Double_t getChisqUpstream()
Definition: SRecEvent.h:200
void printGF(std::ostream &os=std::cout) const
Definition: SRecEvent.cxx:593
void setChisqUpstream(Double_t chisq)
Definition: SRecEvent.h:217
Bool_t isKalmanFitted()
Fit status.
Definition: SRecEvent.h:147
void swimToVertex(TVector3 *pos=nullptr, TVector3 *mom=nullptr, bool hyptest=true)
Simple swim to vertex.
Definition: SRecEvent.cxx:402
TVector3 getDumpPos()
Get mom/pos at a given location.
Definition: SRecEvent.h:186
void setVertexFast(TVector3 mom, TVector3 pos)
Plain setting, no KF-related stuff.
Definition: SRecEvent.cxx:227
void setChisqVertex(Double_t chisq)
Definition: SRecEvent.h:218
static recoConsts * instance()
Definition: recoConsts.cc:7