Belle II Software  release-08-01-10
CDCTrigger2DFitterModule.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 #include "trg/cdc/modules/fitting/CDCTrigger2DFitterModule.h"
9 
10 #include <framework/datastore/RelationVector.h>
11 
12 #include <cdc/geometry/CDCGeometryPar.h>
13 #include <trg/cdc/Fitter3DUtility.h>
14 
15 using namespace std;
16 using namespace Belle2;
17 
18 //this line registers the module with the framework and actually makes it available
19 //in steering files or the the module list (basf2 -m).
20 REG_MODULE(CDCTrigger2DFitter);
21 
22 CDCTrigger2DFitterModule::CDCTrigger2DFitterModule() : Module::Module()
23 {
25  "The 2D fitter module of the CDC trigger.\n"
26  "Performs a circle fit on a given set of axial CDCTriggerSegmentHits.\n"
27  "Requires a preceding track finder to sort hits to tracks.\n"
28  );
30  addParam("hitCollectionName", m_hitCollectionName,
31  "Name of the input StoreArray of CDCTriggerSegmentHits.",
32  string(""));
33  addParam("EventTimeName", m_EventTimeName,
34  "Name of the event time object.",
35  string(""));
36  addParam("inputCollectionName", m_inputCollectionName,
37  "Name of the StoreArray holding the input tracks from the track finder.",
38  string("TRGCDC2DFinderTracks"));
39  addParam("outputCollectionName", m_outputCollectionName,
40  "Name of the StoreArray holding the fitted output tracks.",
41  string("TRGCDC2DFitterTracks"));
42  addParam("minHits", m_minHits,
43  "Minimal number of hits required for the fitting.",
44  unsigned(2));
45  addParam("xtSimple", m_xtSimple,
46  "If true, use nominal drift velocity, otherwise use table "
47  "for non-linear xt.",
48  false);
49  addParam("useDriftTime", m_useDriftTime,
50  "If true, use drift time, otherwise only wire position.",
51  true);
52 }
53 
54 void
56 {
57  // register DataStore elements
61  segmentHits.isRequired(m_hitCollectionName);
62  if (m_useDriftTime)
64  // register relations
66  m_finderTracks.requireRelationTo(segmentHits);
68 
69  // get geometry constants for first priority layers
71  // TODO: avoid hard coding the priority layers here
72  vector<unsigned> iL = {3, 16, 28, 40, 52};
73  for (int iAx = 0; iAx < 5; ++iAx) {
74  nWires.push_back(cdc.nWiresInLayer(iL[iAx]));
75  rr.push_back(cdc.senseWireR(iL[iAx]));
76  vector<double> xt(512);
77  for (unsigned iTick = 0; iTick < xt.size(); ++iTick) {
78  double t = iTick * 2 * cdc.getTdcBinWidth();
79  if (m_xtSimple) {
80  xt[iTick] = cdc.getNominalDriftV() * t;
81  } else {
82  double driftLength_0 = cdc.getDriftLength(t, iL[iAx], 0);
83  double driftLength_1 = cdc.getDriftLength(t, iL[iAx], 1);
84  xt[iTick] = (driftLength_0 + driftLength_1) / 2;
85  }
86  }
87  xtTables.push_back(xt);
88  }
89 }
90 
91 void
93 {
94  int T0 = (m_eventTime->hasBinnedEventT0(Const::CDC))
95  ? m_eventTime->getBinnedEventT0(Const::CDC)
96  : 9999;
97 
98  vector<double> wirePhi2DError({0.00085106,
99  0.00039841,
100  0.00025806,
101  0.00019084,
102  0.0001514
103  });
104  vector<double> driftPhi2DError({0.00085106,
105  0.00039841,
106  0.00025806,
107  0.00019084,
108  0.0001514
109  });
110 
111  for (int itrack = 0; itrack < m_finderTracks.getEntries(); ++itrack) {
112  // get selected hits (positive relation weight)
114  m_finderTracks[itrack]->getRelationsTo<CDCTriggerSegmentHit>(m_hitCollectionName);
115  unsigned nHits = 0;
116  vector<double> tsId(5, -1.);
117  vector<double> wirePhi(5, 0.);
118  vector<int> driftTime(5, 0);
119  vector<double> driftLength(5, 0.);
120  vector<unsigned> LR(5, 0);
121  vector<int> hitIds(5, -1);
122  vector<double> useSL(5, 0.);
123  for (unsigned ihit = 0; ihit < hits.size(); ++ihit) {
124  if (hits.weight(ihit) > 0) {
125  // use only first priority hits
126  if (hits[ihit]->getPriorityPosition() != 3) continue;
127  unsigned iSL = hits[ihit]->getISuperLayer();
128  // skip stereo hits (should not be related, but check anyway)
129  if (iSL % 2) continue;
130  // the track finder should have selected a single hit per super layer
131  // if that is not the case, select the fastest hit
132  if (hitIds[iSL / 2] != -1) {
133  B2WARNING("got multiple hits for SL " << iSL);
134  if (hits[ihit]->priorityTime() >= driftTime[iSL / 2])
135  continue;
136  } else {
137  nHits += 1;
138  }
139  useSL[iSL / 2] = 1.;
140  hitIds[iSL / 2] = ihit;
141  tsId[iSL / 2] = hits[ihit]->getIWire();
142  wirePhi[iSL / 2] = hits[ihit]->getIWire() * 2. * M_PI / nWires[iSL / 2];
143  LR[iSL / 2] = hits[ihit]->getLeftRight();
144  driftTime[iSL / 2] = hits[ihit]->priorityTime();
145  int t = hits[ihit]->priorityTime() - T0;
146  if (t < 0) t = 0;
147  if (t > 511) t = 511;
148  driftLength[iSL / 2] = xtTables[iSL / 2][t];
149  }
150  }
151  if (nHits < m_minHits) {
152  B2DEBUG(20, "Not enough hits to do 2D fit (" << m_minHits << " needed, got " << nHits << ")");
153  continue;
154  }
155 
156  // Set phi2DError for 2D fit
157  vector<double> phi2DInvError(5, 0.);
158  for (unsigned iAx = 0; iAx < 5; ++iAx) {
159  if (LR[iAx] == 0) continue;
160  if (LR[iAx] != 3 && T0 != 9999)
161  phi2DInvError[iAx] = 1. / driftPhi2DError[iAx];
162  else
163  phi2DInvError[iAx] = 1. / wirePhi2DError[iAx];
164  }
165  // Calculate phi2D using driftLength.
166  vector<double> phi2D(5, 0.);
167  for (unsigned iAx = 0; iAx < 5; ++iAx) {
168  if (hitIds[iAx] < 0) continue;
169  if (T0 == 9999 || !m_useDriftTime)
170  phi2D[iAx] = wirePhi[iAx];
171  else
172  phi2D[iAx] = Fitter3DUtility::calPhi(wirePhi[iAx], driftLength[iAx], rr[iAx], LR[iAx]);
173  }
174  // Fit2D
175  double rho = 0;
176  double phi0 = 0;
177  double chi2 = 0;
178  Fitter3DUtility::rPhiFitter(&rr[0], &phi2D[0], &phi2DInvError[0], rho, phi0, chi2);
179  double charge = m_finderTracks[itrack]->getChargeSign();
180  double chargeFit = 0;
181  Fitter3DUtility::chargeFinder(&nWires[0], &tsId[0], &useSL[0], phi0,
182  charge, chargeFit);
183  double omega = chargeFit / rho;
184 
185  // save track
186  CDCTriggerTrack* fittedTrack =
187  m_fitterTracks.appendNew(remainder(phi0 + chargeFit * M_PI_2, 2. * M_PI),
188  omega, chi2);
189  // make relation to finder track
190  m_finderTracks[itrack]->addRelationTo(fittedTrack);
191  // make relation to hits
192  for (unsigned iAx = 0; iAx < 5; ++iAx) {
193  if (hitIds[iAx] >= 0)
194  fittedTrack->addRelationTo(hits[hitIds[iAx]]);
195  }
196  }
197 }
bool hasBinnedEventT0(const Const::EDetector detector) const
Check if one of the detectors in the given set has a binned t0 estimation.
int getBinnedEventT0(const Const::EDetector detector) const
Return the stored binned event t0 for the given detector or 0 if nothing stored.
std::string m_EventTimeName
name of the event time StoreObjPtr
virtual void initialize() override
Initialize the module and register DataStore arrays.
virtual void event() override
Run the 2D fitter for an event.
std::string m_outputCollectionName
Name of the StoreArray containing the resulting fitted tracks.
StoreArray< CDCTriggerTrack > m_finderTracks
list of input tracks from finder
std::string m_inputCollectionName
Name of the StoreArray containing the input tracks from the finder.
std::vector< std::vector< double > > xtTables
geometry constants: drift length - drift time relation
bool m_xtSimple
Switch between nominal drift velocity and xt table.
bool m_useDriftTime
Switch between drift time and wire position for phi.
StoreArray< CDCTriggerTrack > m_fitterTracks
list of output tracks from fitter
unsigned m_minHits
Minimal number of hits required for fitting.
StoreObjPtr< BinnedEventT0 > m_eventTime
StoreObjPtr contraining the event time.
std::vector< double > nWires
geometry constants: number of wires per super layer
std::vector< double > rr
geometry constants: radius of priority layers
std::string m_hitCollectionName
Name of the StoreArray containing the input track segment hits.
Combination of several CDCHits to a track segment hit for the trigger.
Track created by the CDC trigger.
The Class for CDC Geometry Parameters.
static CDCGeometryPar & Instance(const CDCGeometry *=nullptr)
Static method to get a reference to the CDCGeometryPar instance.
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition: Module.cc:208
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition: Module.h:80
Class for type safe access to objects that are referred to in relations.
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
bool requireRelationTo(const StoreArray< TO > &toArray, DataStore::EDurability durability=DataStore::c_Event, const std::string &namedRelation="") const
Produce error if no relation from this array to 'toArray' has been registered.
Definition: StoreArray.h:155
T * appendNew()
Construct a new T object at the end of the array.
Definition: StoreArray.h:246
int getEntries() const
Get the number of objects in the array.
Definition: StoreArray.h:216
bool registerRelationTo(const StoreArray< TO > &toArray, DataStore::EDurability durability=DataStore::c_Event, DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut, const std::string &namedRelation="") const
Register a relation to the given StoreArray.
Definition: StoreArray.h:140
static void rPhiFitter(double *rr, double *phi2, double *invphierror, double &rho, double &myphi0)
A circle fitter with invPhiError without fit chi2 output.
static double calPhi(double wirePhi, double driftLength, double rr, int lr)
Pre 3D fitter functions. rr is in cm scale. driftLength is in cm scale.
static void chargeFinder(double *nTSs, double *tsIds, double *tsHitmap, double phi0, double inCharge, double &outCharge)
Charge finder using circle fitter output and axial TSs.
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition: Module.h:560
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
Abstract base class for different kinds of events.