Belle II Software development
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
15using namespace std;
16using 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).
20REG_MODULE(CDCTrigger2DFitter);
21
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
54void
56{
57 // register DataStore elements
64 // register relations
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
91void
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)
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.
CDCTrigger2DFitterModule()
Constructor, for setting module description and parameters.
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.
Accessor to arrays stored in the data store.
Definition: StoreArray.h:113
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.
STL namespace.