8 #include "trg/cdc/modules/fitting/CDCTrigger3DFitterModule.h"
10 #include <framework/datastore/RelationVector.h>
12 #include <cdc/geometry/CDCGeometryPar.h>
13 #include <trg/cdc/Fitter3DUtility.h>
14 #include <trg/cdc/Fitter3D.h>
15 #include <trg/cdc/JSignal.h>
16 #include <trg/cdc/JSignalData.h>
25 CDCTrigger3DFitterModule::CDCTrigger3DFitterModule() :
Module::
Module()
28 "The 3D fitter module of the CDC trigger.\n"
29 "Selects stereo hits around a given 2D track and performs a linear fit "
30 "in the s-z plane (s: 2D arclength).\n"
34 "Name of the input StoreArray of CDCTriggerSegmentHits.",
37 "Name of the event time object.",
40 "Name of the StoreArray holding the input tracks from the 2D fitter.",
41 string(
"TRGCDC2DFitterTracks"));
43 "Name of the StoreArray holding the 3D output tracks.",
44 string(
"TRGCDC3DFitterTracks"));
46 "Fitter mode: 1: fast, 2: firmware",
49 "Minimal number of hits required for the fitting.",
52 "If true, use nominal drift velocity, otherwise use table "
56 "If true, prints detail information.",
91 vector<unsigned> iL = {10, 22, 34, 46};
92 for (
int iSt = 0; iSt < 4; ++iSt) {
93 nWires.push_back(cdc.nWiresInLayer(iL[iSt]));
94 rr.push_back(cdc.senseWireR(iL[iSt]));
95 zToStraw.push_back(cdc.senseWireBZ(iL[iSt]));
96 nShift.push_back(cdc.nShifts(iL[iSt]));
98 (cdc.senseWireFZ(iL[iSt]) -
zToStraw.back()));
99 vector<double> xt(512);
100 for (
unsigned iTick = 0; iTick < xt.size(); ++iTick) {
101 double t = iTick * 2 * cdc.getTdcBinWidth();
103 xt[iTick] = cdc.getNominalDriftV() * t;
105 double driftLength_0 = cdc.getDriftLength(t, iL[iSt], 0);
106 double driftLength_1 = cdc.getDriftLength(t, iL[iSt], 1);
107 xt[iTick] = (driftLength_0 + driftLength_1) / 2;
121 cout <<
"Event" << endl;
123 cout <<
"----Stereo TS----" << endl;
125 if (
m_hits[iHit]->getISuperLayer() % 2 != 0)
126 cout <<
"sl-iWire:" <<
m_hits[iHit]->getISuperLayer() <<
"-" <<
m_hits[iHit]->getIWire() <<
" pr:" <<
127 m_hits[iHit]->getPriorityPosition() <<
" lr:" <<
m_hits[iHit]->getLeftRight() <<
" rt:" <<
m_hits[iHit]->getTDCCount() <<
" dt:" <<
128 m_hits[iHit]->priorityTime() << endl;
130 cout <<
"----Stereo TS----" << endl;
131 cout <<
"----EventTime----" << endl;
136 cout <<
"----EventTime----" << endl;
137 cout <<
"----2D----" << endl;
140 cout <<
"2D charge: " <<
m_tracks2D[iTrack]->getChargeSign() <<
" pt: " << 1. / abs(
m_tracks2D[iTrack]->getOmega()) * 1.5 * 0.3 *
141 0.01 <<
" phi0_i: " <<
m_tracks2D[iTrack]->getPhi0() << endl;
143 cout <<
"----2D----" << endl;
147 int charge =
m_tracks2D[itrack]->getChargeSign();
148 double rho = 1. / abs(
m_tracks2D[itrack]->getOmega());
149 double phi =
m_tracks2D[itrack]->getPhi0() - charge * M_PI_2;
152 vector<int> bestTSIndex(4, -1);
153 vector<double> bestTSPhi(4, 9999);
154 finder(charge, rho, phi, bestTSIndex, bestTSPhi);
157 cout <<
"----Found Stereo TS----" << endl;
158 for (
unsigned iSt = 0; iSt < 4; ++iSt) {
159 if (bestTSIndex[iSt] == -1)
continue;
160 cout <<
"sl-iWire:" << iSt * 2 + 1 <<
"-" <<
m_hits[bestTSIndex[iSt]]->getIWire() <<
" pr:" <<
161 m_hits[bestTSIndex[iSt]]->getPriorityPosition() <<
" lr:" <<
m_hits[bestTSIndex[iSt]]->getLeftRight() <<
" rt:" <<
162 m_hits[bestTSIndex[iSt]]->getTDCCount() <<
" dt:" <<
m_hits[bestTSIndex[iSt]]->priorityTime() << endl;
164 cout <<
"----Found Stereo TS----" << endl;
165 cout <<
"----2D----" << endl;
166 cout <<
"charge: " << charge <<
" radius: " << rho <<
" phi0_c: " << phi << endl;
167 cout <<
"----2D----" << endl;
172 for (
unsigned iSt = 0; iSt < 4; ++iSt) {
173 if (bestTSIndex[iSt] != -1) {
178 B2DEBUG(100,
"Not enough hits to do 3D fit (" <<
m_minHits <<
" needed, got " << nHits <<
")");
186 fitter(bestTSIndex, bestTSPhi, charge, rho, phi, z0, cot, chi2);
191 if (isnan(z0) || isnan(cot) || isnan(chi2)) {
192 B2DEBUG(100,
"3D fit failed");
202 m_tracks2D[itrack]->addRelationTo(fittedTrack);
204 for (
unsigned iSt = 0; iSt < 4; ++iSt) {
205 if (bestTSIndex[iSt] != -1)
206 fittedTrack->addRelationTo(
m_hits[bestTSIndex[iSt]]);
211 for (
unsigned ihit = 0; ihit < axialHits.
size(); ++ihit) {
212 fittedTrack->addRelationTo(axialHits[ihit]);
219 vector<int>& bestTSIndex, vector<double>& bestTSPhi)
221 vector<double> stAxPhi(4);
222 for (
int iSt = 0; iSt < 4; ++iSt) {
227 vector<vector<int>> candidatesIndex(4, vector<int>());
228 vector<vector<double>> candidatesPhi(4, vector<double>());
229 vector<vector<double>> candidatesDiffStWires(4, vector<double>());
235 if (
m_hits[ihit]->getPriorityPosition() != 3)
continue;
237 unsigned iSL =
m_hits[ihit]->getISuperLayer();
238 if (iSL % 2 == 0)
continue;
240 if (2 * rho <
rr[iSL / 2])
continue;
242 double wirePhi =
m_hits[ihit]->getIWire() * 2. * M_PI /
nWires[iSL / 2];
243 double tsDiffSt = stAxPhi[iSL / 2] - wirePhi;
244 if (tsDiffSt > M_PI) tsDiffSt -= 2 * M_PI;
245 if (tsDiffSt < -M_PI) tsDiffSt += 2 * M_PI;
246 tsDiffSt = tsDiffSt / 2 / M_PI *
nWires[iSL / 2];
248 if ((iSL / 2) % 2 == 0) {
249 if (tsDiffSt > 0 && tsDiffSt <= 10) {
250 candidatesIndex[iSL / 2].push_back(ihit);
251 candidatesPhi[iSL / 2].push_back(wirePhi);
252 candidatesDiffStWires[iSL / 2].push_back(tsDiffSt);
255 if (tsDiffSt < 0 && tsDiffSt >= -10) {
256 candidatesIndex[iSL / 2].push_back(ihit);
257 candidatesPhi[iSL / 2].push_back(wirePhi);
258 candidatesDiffStWires[iSL / 2].push_back(tsDiffSt);
265 const double meanWireDiff[4] = { 3.68186, 3.3542, 3.9099, 4.48263 };
266 for (
int iSt = 0; iSt < 4; ++iSt) {
269 double bestDiff = 9999;
270 for (
int iTS = 0; iTS < int(candidatesIndex[iSt].size()); ++iTS) {
271 double diff = abs(abs(candidatesDiffStWires[iSt][iTS]) - meanWireDiff[iSt]);
273 if (diff < bestDiff) {
275 bestTSPhi[iSt] = candidatesPhi[iSt][iTS];
276 bestTSIndex[iSt] = candidatesIndex[iSt][iTS];
292 int charge,
double rho,
double phi,
293 double& z0,
double& cot,
double& chi2)
299 vector<vector<int> > rawStTSs(4, vector<int> (3));
300 for (
unsigned iSt = 0; iSt < 4; ++iSt) {
301 if (bestTSIndex[iSt] == -1)
continue;
302 rawStTSs[iSt][0] =
m_hits[bestTSIndex[iSt]]->getIWire();
303 rawStTSs[iSt][1] =
m_hits[bestTSIndex[iSt]]->getLeftRight();
304 rawStTSs[iSt][2] =
m_hits[bestTSIndex[iSt]]->priorityTime();
306 int eventTimeValid = 0;
315 if (phi_c > M_PI) phi_c -= 2 * M_PI;
316 if (phi_c < -M_PI) phi_c += 2 * M_PI;
318 vector<double> arcS(4, 0);
319 vector<double> zz(4, 0);
320 vector<double> invZError2(4, 0);
324 z0, cot, chi2, arcS, zz, invZError2);
332 for (
int iSt = 0; iSt < 4; iSt++) {
333 invZError2[iSt] =
m_mSignalStorage[
"iZError2_" + to_string(iSt)].getRealInt();
340 cout <<
"----3D----" << endl;
341 cout <<
"arcS [0]: " << arcS[0] <<
" [1]: " << arcS[1] <<
" [2]: " << arcS[2] <<
" [3]: " << arcS[3] << endl;
342 cout <<
"zz [0]: " << zz[0] <<
" [1]: " << zz[1] <<
" [2]: " << zz[2] <<
" [3]: " << zz[3] << endl;
343 cout <<
"invZError2 [0]: " << invZError2[0] <<
" [1]: " << invZError2[1] <<
" [2]: " << invZError2[2] <<
" [3]: " << invZError2[3]
345 cout <<
"z0: " << z0 <<
" cot: " << cot <<
" chi2: " << chi2 << endl;
346 cout <<
"----3D----" << endl;
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.
virtual ~CDCTrigger3DFitterModule()
Destructor.
std::string m_EventTimeName
name of the event time StoreObjPtr
StoreArray< CDCTriggerTrack > m_tracks2D
list of 2D input tracks
std::map< std::string, std::vector< double > > m_stGeometry
map of geometry constants
Belle2::TRGCDCJSignalData * m_commonData
Datastore for firmware simulation.
std::map< std::string, double > m_mConstD
Constants for firmware simulation.
virtual void initialize() override
Initialize the module and register DataStore arrays.
virtual void event() override
Run the 3D fitter for an event.
std::string m_outputCollectionName
Name of the StoreArray containing the resulting 3D tracks.
StoreArray< CDCTriggerSegmentHit > m_hits
list of track segment hits
std::vector< double > angleSt
geometry constants: stereo angle
std::map< std::string, std::vector< double > > m_mConstV
Constants for firmware simulation.
void finder(int charge, double rho, double phi, std::vector< int > &bestTSIndex, std::vector< double > &bestTSPhi)
Select stereo hits.
std::map< std::string, Belle2::TRGCDCJSignal > m_mSignalStorage
Signalstore for firmware simulation.
bool m_isVerbose
Switch printing detail information.
std::string m_inputCollectionName
Name of the StoreArray containing the input tracks from the 2D fitter.
std::vector< std::vector< double > > xtTables
geometry constants: drift length - drift time relation
unsigned m_fitterMode
Fitter mode: 1: fast, 2: firmware.
bool m_xtSimple
Switch between nominal drift velocity and xt table.
unsigned m_minHits
Minimal number of hits required for fitting.
StoreArray< CDCTriggerTrack > m_tracks3D
list of 3D output tracks
StoreObjPtr< BinnedEventT0 > m_eventTime
StoreObjPtr containing the event time.
std::vector< int > nShift
geometry constants: wire shift of stereo layers
std::vector< double > nWires
geometry constants: number of wires per super layer
std::vector< double > rr
geometry constants: radius of priority layers
std::vector< double > zToStraw
geometry constants: backward z of priority layers
void fitter(const std::vector< int > &bestTSIndex, std::vector< double > &bestTSPhi, int charge, double rho, double phi, double &z0, double &cot, double &chi2)
Perform the 3D fit.
std::string m_hitCollectionName
Name of the StoreArray containing the input track segment hits.
std::map< std::string, Belle2::TRGCDCJLUT * > m_mLutStorage
Lutstore for firmware simulation.
std::vector< std::vector< double > > m_stXts
stereo xt tables
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.
void setDescription(const std::string &description)
Sets the description of the module.
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Class for type safe access to objects that are referred to in relations.
size_t size() const
Get number of 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.
T * appendNew()
Construct a new T object at the end of the array.
int getEntries() const
Get the number of objects in the array.
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.
A class to hold common data for JSignals.
static double calStAxPhi(int charge, double anglest, double ztostraw, double rr, double rho, double phi0)
Calculates the fitted axial phi for the stereo super layer.
static void fitter3DFirm(std::map< std::string, double > &mConstD, const std::map< std::string, std::vector< double > > &mConstV, int eventTimeValid, int eventTime, std::vector< std::vector< int > > const &rawStTSs, int charge, double radius, double phi_c, Belle2::TRGCDCJSignalData *commonData, std::map< std::string, Belle2::TRGCDCJSignal > &mSignalStorage, std::map< std::string, Belle2::TRGCDCJLUT * > &mLutStorage)
Combines several functions for fitter3D firmware.
static void fitter3D(std::map< std::string, std::vector< double > > &stGeometry, std::vector< std::vector< double > > const &stXts, int eventTimeValid, int eventTime, std::vector< std::vector< int > > const &rawStTSs, int charge, double radius, double phi_c, double &z0, double &cot, double &chi2)
Combines several functions for fitter3D.
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
static void getStereoGeometry(std::map< std::string, std::vector< double > > &stGeometry)
Get stereo geometry.
static void getStereoXt(std::vector< double > const &stPriorityLayer, std::vector< std::vector< double > > &stXts, bool isSimple=0)
Get stereo Xt.
static void getConstants(std::map< std::string, double > &mConstD, std::map< std::string, std::vector< double > > &mConstV, bool isXtSimple=0)
Get constants for firmwareFit.
Abstract base class for different kinds of events.