1 #include "trg/cdc/modules/fitting/CDCTrigger2DFitterModule.h"
3 #include <framework/datastore/RelationVector.h>
5 #include <cdc/geometry/CDCGeometryPar.h>
6 #include <trg/cdc/Fitter3DUtility.h>
15 CDCTrigger2DFitterModule::CDCTrigger2DFitterModule() :
Module::
Module()
18 "The 2D fitter module of the CDC trigger.\n"
19 "Performs a circle fit on a given set of axial CDCTriggerSegmentHits.\n"
20 "Requires a preceding track finder to sort hits to tracks.\n"
24 "Name of the input StoreArray of CDCTriggerSegmentHits.",
27 "Name of the event time object.",
30 "Name of the StoreArray holding the input tracks from the track finder.",
31 string(
"TRGCDC2DFinderTracks"));
33 "Name of the StoreArray holding the fitted output tracks.",
34 string(
"TRGCDC2DFitterTracks"));
36 "Minimal number of hits required for the fitting.",
39 "If true, use nominal drift velocity, otherwise use table "
43 "If true, use drift time, otherwise only wire position.",
65 vector<unsigned> iL = {3, 16, 28, 40, 52};
66 for (
int iAx = 0; iAx < 5; ++iAx) {
67 nWires.push_back(cdc.nWiresInLayer(iL[iAx]));
68 rr.push_back(cdc.senseWireR(iL[iAx]));
69 vector<double> xt(512);
70 for (
unsigned iTick = 0; iTick < xt.size(); ++iTick) {
71 double t = iTick * 2 * cdc.getTdcBinWidth();
73 xt[iTick] = cdc.getNominalDriftV() * t;
75 double driftLength_0 = cdc.getDriftLength(t, iL[iAx], 0);
76 double driftLength_1 = cdc.getDriftLength(t, iL[iAx], 1);
77 xt[iTick] = (driftLength_0 + driftLength_1) / 2;
87 int T0 = (
m_eventTime->hasBinnedEventT0(Const::CDC))
91 vector<double> wirePhi2DError({0.00085106,
97 vector<double> driftPhi2DError({0.00085106,
104 for (
int itrack = 0; itrack <
m_finderTracks.getEntries(); ++itrack) {
109 vector<double> tsId(5, -1.);
110 vector<double> wirePhi(5, 0.);
111 vector<int> driftTime(5, 0);
112 vector<double> driftLength(5, 0.);
113 vector<unsigned> LR(5, 0);
114 vector<int> hitIds(5, -1);
115 vector<double> useSL(5, 0.);
116 for (
unsigned ihit = 0; ihit < hits.size(); ++ihit) {
117 if (hits.weight(ihit) > 0) {
119 if (hits[ihit]->getPriorityPosition() != 3)
continue;
120 unsigned iSL = hits[ihit]->getISuperLayer();
122 if (iSL % 2)
continue;
125 if (hitIds[iSL / 2] != -1) {
126 B2WARNING(
"got multiple hits for SL " << iSL);
127 if (hits[ihit]->priorityTime() >= driftTime[iSL / 2])
133 hitIds[iSL / 2] = ihit;
134 tsId[iSL / 2] = hits[ihit]->getIWire();
135 wirePhi[iSL / 2] = hits[ihit]->getIWire() * 2. * M_PI /
nWires[iSL / 2];
136 LR[iSL / 2] = hits[ihit]->getLeftRight();
137 driftTime[iSL / 2] = hits[ihit]->priorityTime();
138 int t = hits[ihit]->priorityTime() - T0;
140 if (t > 511) t = 511;
141 driftLength[iSL / 2] =
xtTables[iSL / 2][t];
145 B2DEBUG(20,
"Not enough hits to do 2D fit (" <<
m_minHits <<
" needed, got " << nHits <<
")");
150 vector<double> phi2DInvError(5, 0.);
151 for (
unsigned iAx = 0; iAx < 5; ++iAx) {
152 if (LR[iAx] == 0)
continue;
153 if (LR[iAx] != 3 && T0 != 9999)
154 phi2DInvError[iAx] = 1. / driftPhi2DError[iAx];
156 phi2DInvError[iAx] = 1. / wirePhi2DError[iAx];
159 vector<double> phi2D(5, 0.);
160 for (
unsigned iAx = 0; iAx < 5; ++iAx) {
161 if (hitIds[iAx] < 0)
continue;
163 phi2D[iAx] = wirePhi[iAx];
173 double chargeFit = 0;
176 double omega = chargeFit / rho;
180 m_fitterTracks.appendNew(remainder(phi0 + chargeFit * M_PI_2, 2. * M_PI),
185 for (
unsigned iAx = 0; iAx < 5; ++iAx) {
186 if (hitIds[iAx] >= 0)
187 fittedTrack->addRelationTo(hits[hitIds[iAx]]);