Belle II Software development
Fitter3D.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
9//-----------------------------------------------------------------------------
10// Description : A class to fit tracks in 3D
11//-----------------------------------------------------------------------------
12
13#define TRG_SHORT_NAMES
14#define TRGCDC_SHORT_NAMES
15
16#include <iostream>
17#include <cmath>
18
19#include "trg/trg/Debug.h"
20#include "trg/cdc/Fitter3D.h"
21#include "trg/cdc/Segment.h"
22#include "trg/cdc/TRGCDCTrack.h"
23#include "trg/cdc/Link.h"
24#include "trg/trg/Time.h"
25#include "trg/trg/Signal.h"
26#include "trg/trg/Utilities.h"
27#include "trg/cdc/TRGCDC.h"
28#include "trg/cdc/Wire.h"
29#include "trg/cdc/Layer.h"
30#include "trg/cdc/WireHit.h"
31#include "trg/cdc/WireHitMC.h"
32#include "trg/cdc/SegmentHit.h"
33#include "trg/cdc/TrackMC.h"
34#include "trg/cdc/Relation.h"
35#include "trg/cdc/FrontEnd.h"
36#include "trg/cdc/Merger.h"
37#include "trg/cdc/LUT.h"
38#include "trg/trg/Constants.h"
39#include "trg/cdc/Helix.h"
40#include "trg/cdc/Fitter3DUtility.h"
41#include "trg/cdc/EventTime.h"
42#include "trg/cdc/JSignal.h"
43#include "trg/cdc/JLUT.h"
44#include "trg/cdc/JSignalData.h"
45#include "trg/cdc/FpgaUtility.h"
46#include "trg/cdc/HandleRoot.h"
47
48#include "cdc/dataobjects/CDCSimHit.h"
49#include "cdc/geometry/CDCGeometryPar.h"
50#include <framework/dataobjects/EventMetaData.h>
51#include <framework/geometry/B2Vector3.h>
52#include "mdst/dataobjects/MCParticle.h"
53
54
55using namespace std;
56namespace Belle2 {
62 TRGCDCFitter3D::TRGCDCFitter3D(const std::string& name,
63 const std::string& rootFitter3DFile,
64 const TRGCDC& TRGCDC,
65 const std::map<std::string, bool>& flags)
66 : m_name(name), m_cdc(TRGCDC),
67 m_mBool(flags), m_rootFitter3DFileName(rootFitter3DFile),
68 m_treeTrackFitter3D(), m_treeConstantsFitter3D() // 2019/07/31 by ytlai
69 {
71 m_commonData = 0;
72 }
73
75 {
76 }
77
79 {
80
82 evtMetaData.isRequired();
83
84 // If we are using Monte Carlo information.
85 m_mBool["fMc"] = 1;
86 m_mBool["fVerbose"] = 0;
87 m_mBool["fIsPrintError"] = 0;
88 m_mBool["fIsIntegerEffect"] = 1;
89 m_mBool["debugFitted"] = 1;
90 m_mBool["debugLargeZ0"] = 0;
91
92 // Init values
93 m_mConstD["Trg_PI"] = M_PI;
94
95 // Get rr,zToStraw,angleSt,nWire
97 m_mConstV["rr"] = vector<double> (9);
98 m_mConstV["nWires"] = vector<double> (9);
99 m_mConstV["nTSs"] = vector<double> (9);
100 for (unsigned iSL = 0; iSL < 9; iSL++) {
101 unsigned t_layerId = m_cdc.segment(iSL, 0).center().layerId();
102 m_mConstV["rr"][iSL] = cdcp.senseWireR(t_layerId);
103 m_mConstV["nWires"][iSL] = cdcp.nWiresInLayer(t_layerId) * 2;
104 m_mConstV["nTSs"][iSL] = cdcp.nWiresInLayer(t_layerId);
105 }
106 m_mConstV["nTSs2D"] = vector<double> (5);
107 for (unsigned iAx = 0; iAx < 5; iAx++) {
108 m_mConstV["nTSs2D"][iAx] = m_mConstV["nTSs"][2 * iAx];
109 }
110
111 m_mConstV["zToStraw"] = vector<double> (4);
112 m_mConstV["zToOppositeStraw"] = vector<double> (4);
113 m_mConstV["angleSt"] = vector<double> (4);
114 m_mConstV["nShift"] = vector<double> (4);
115 for (int iSt = 0; iSt < 4; iSt++) {
116 unsigned t_layerId = m_cdc.stereoSegment(iSt, 0).center().layerId();
117 m_mConstV["zToStraw"][iSt] = cdcp.senseWireBZ(t_layerId);
118 m_mConstV["zToOppositeStraw"][iSt] = cdcp.senseWireFZ(t_layerId);
119 m_mConstV["angleSt"][iSt] = 2 * m_mConstV["rr"][2 * iSt + 1] * sin(m_mConstD["Trg_PI"] * cdcp.nShifts(t_layerId) /
120 (2 * cdcp.nWiresInLayer(t_layerId))) / (cdcp.senseWireFZ(t_layerId) - cdcp.senseWireBZ(t_layerId));
121 m_mConstV["nShift"][iSt] = cdcp.nShifts(t_layerId);
122 }
123
124 m_mConstV["rr2D"] = vector<double> (5);
125 m_mConstV["rr3D"] = vector<double> (4);
126 for (int iAx = 0; iAx < 5; iAx++) m_mConstV["rr2D"][iAx] = m_mConstV["rr"][iAx * 2];
127 for (int iSt = 0; iSt < 4; iSt++) m_mConstV["rr3D"][iSt] = m_mConstV["rr"][iSt * 2 + 1];
128
129 m_mConstV["wirePhi2DError"] = vector<double> (5);
130 m_mConstV["driftPhi2DError"] = vector<double> (5);
132 //m_mConstD["driftResolution"] = 2 * 40 * 0.0001; // (cm)
133 //m_mConstV["cellResolution"] = vector<double> (5);
134 //for(unsigned iAx=0; iAx<5; iAx++){
135 // m_mConstV["cellResolution"][iAx] = m_mConstV["rr2D"][iAx] * 2 * m_mConstD["Trg_PI"] / (m_mConstV["nWires"][iAx*2]/2); // (cm)
136 //}
137 //for(unsigned iAx=0; iAx<5; iAx++){
138 // m_mConstV["wirePhi2DError"][iAx] = m_mConstV["cellResolution"][iAx]/m_mConstV["rr2D"][iAx] / sqrt(12);
139 //}
140 //for(unsigned iAx=0; iAx<5; iAx++){
141 // m_mConstV["driftPhi2DError"][iAx] = m_mConstD["driftResolution"]/m_mConstV["rr2D"][iAx] / sqrt(12);
142 //}
143
144 m_mConstV["wirePhi2DError"][0] = 0.00085106;
145 m_mConstV["wirePhi2DError"][1] = 0.00039841;
146 m_mConstV["wirePhi2DError"][2] = 0.00025806;
147 m_mConstV["wirePhi2DError"][3] = 0.00019084;
148 m_mConstV["wirePhi2DError"][4] = 0.0001514;
149 m_mConstV["driftPhi2DError"][0] = 0.00085106;
150 m_mConstV["driftPhi2DError"][1] = 0.00039841;
151 m_mConstV["driftPhi2DError"][2] = 0.00025806;
152 m_mConstV["driftPhi2DError"][3] = 0.00019084;
153 m_mConstV["driftPhi2DError"][4] = 0.0001514;
154
155 // (2016.06.07) study
156 //m_mConstV["wireZError"] = vector<double> ({4.752, 6.393, 6.578, 6.418});
157 //m_mConstV["driftZError"] = vector<double> ({0.4701, 0.7203, 0.8058, 0.9382});
158 m_mConstV["driftZError"] = vector<double> ({0.7676, 0.9753, 1.029, 1.372});
159 m_mConstV["wireZError"] = vector<double> ({0.7676, 0.9753, 1.029, 1.372});
160
161 // Make driftLength table for each superlayer. Up to 511 clock ticks.
162 // driftLengthTableSLX[ tdcCount (~2ns unit) ] = drift length (cm)
163 for (unsigned iSl = 0; iSl < 9; iSl++) {
164 string tableName = "driftLengthTableSL" + to_string(iSl);
165 unsigned tableSize = 512;
166 m_mConstV[tableName] = vector<double> (tableSize);
167 unsigned t_layer = m_cdc.segment(iSl, 0).center().layerId();
168 for (unsigned iTick = 0; iTick < tableSize; iTick++) {
169 double t_driftTime = iTick * 2 * cdcp.getTdcBinWidth();
170 double avgDriftLength = 0;
171 if (m_mBool["fXtSimple"] == 1) {
172 avgDriftLength = cdcp.getNominalDriftV() * t_driftTime;
173 } else {
174 double driftLength_0 = cdcp.getDriftLength(t_driftTime, t_layer, 0);
175 double driftLength_1 = cdcp.getDriftLength(t_driftTime, t_layer, 1);
176 avgDriftLength = (driftLength_0 + driftLength_1) / 2;
177 }
178 m_mConstV[tableName][iTick] = avgDriftLength;
179 }
180 }
181
182 if (m_mBool["fVerbose"]) {
183 cout << "fLRLUT: " << m_mBool["fLRLUT"] << endl;
184 cout << "fMc: " << m_mBool["fMc"] << endl;
185 cout << "fVerbose: " << m_mBool["fVerbose"] << endl;
186 if (m_mBool["fMc"]) cout << "fmcLR: " << m_mBool["fmcLR"] << endl;
187 cout << "fRoot: " << m_mBool["fRootFile"] << endl;
188 cout << "PI: " << m_mConstD["Trg_PI"] << endl;
189 cout << "rr: " << m_mConstV["rr"][0] << " " << m_mConstV["rr"][1] << " " << m_mConstV["rr"][2] << " " <<
190 m_mConstV["rr"][3] << " " << m_mConstV["rr"][4] << " " << m_mConstV["rr"][5] << " " << m_mConstV["rr"][6] << " " <<
191 m_mConstV["rr"][7] << " " << m_mConstV["rr"][8] << endl;
192 cout << "nWires: " << int(m_mConstV["nWires"][0]) << " " << int(m_mConstV["nWires"][1]) << " " << int(
193 m_mConstV["nWires"][2]) << " " << int(m_mConstV["nWires"][3]) << " " << int(m_mConstV["nWires"][4]) << " " << int(
194 m_mConstV["nWires"][5]) << " " << int(m_mConstV["nWires"][6]) << " " << int(m_mConstV["nWires"][7]) << " " << int(
195 m_mConstV["nWires"][8]) << endl;
196 cout << "zToStraw: " << m_mConstV["zToStraw"][0] << " " << m_mConstV["zToStraw"][1] << " " << m_mConstV["zToStraw"][2] << " " <<
197 m_mConstV["zToStraw"][3] << endl;
198 cout << "angleSt: " << m_mConstV["angleSt"][0] << " " << m_mConstV["angleSt"][1] << " " << m_mConstV["angleSt"][2] << " " <<
199 m_mConstV["angleSt"][3] << endl;
200 cout << "wireZError: " << m_mConstV["wireZError"][0] << " " << m_mConstV["wireZError"][1] << " " << m_mConstV["wireZError"][2] <<
201 " " << m_mConstV["wireZError"][3] << endl;
202 cout << "driftZError: " << m_mConstV["driftZError"][0] << " " << m_mConstV["driftZError"][1] << " " << m_mConstV["driftZError"][2]
203 << " " << m_mConstV["driftZError"][3] << endl;
204 cout << "wirePhiError: " << m_mConstV["wirePhi2DError"][0] << " " << m_mConstV["wirePhi2DError"][1] << " " <<
205 m_mConstV["wirePhi2DError"][2] << " " << m_mConstV["wirePhi2DError"][3] << " " << m_mConstV["wirePhi2DError"][4] << endl;
206 cout << "driftPhiError: " << m_mConstV["driftPhi2DError"][0] << " " << m_mConstV["driftPhi2DError"][1] << " " <<
207 m_mConstV["driftPhi2DError"][2] << " " << m_mConstV["driftPhi2DError"][3] << " " << m_mConstV["driftPhi2DError"][4] << endl;
208 }
209
210
211 }
212
213 int TRGCDCFitter3D::doit(std::vector<TRGCDCTrack*>& trackList)
214 {
215
216 TRGDebug::enterStage("Fitter 3D");
217
218 // Set values for saving data.
219 if (m_mBool["fRootFile"]) {
220 m_mDouble["iSave"] = 0;
221 HandleRoot::initializeEvent(m_mTClonesArray);
222 }
223
224 // Get common values for event.
225 m_mDouble["eventTime"] = m_cdc.getEventTime();
226 StoreObjPtr<EventMetaData> eventMetaDataPtr;
227 // Event starts from 0.
228 m_mDouble["eventNumber"] = eventMetaDataPtr->getEvent();
229
230 // Fitter3D
231 // Loop over all tracks
232 for (unsigned iTrack = 0; iTrack < trackList.size(); iTrack++) {
233
234 TCTrack& aTrack = * trackList[iTrack];
235
237 // Get MC values for fitter.
238 if (m_mBool["fMc"]) getMCValues(m_cdc, &aTrack, m_mConstD, m_mDouble, m_mVector);
239 // Get track ID
240 m_mDouble["trackId"] = aTrack.getTrackID();
241
244 int fit2DResult = do2DFit(aTrack, m_mBool, m_mConstD, m_mConstV, m_mDouble, m_mVector);
245 if (fit2DResult != 0) {
246 aTrack.setFitted(0);
247 if (m_mBool["fVerbose"]) cout << "Exit due to 2D fit result:" << fit2DResult << endl;
248 continue;
249 }
250
252 // 3D Fitter
253 // Print input TSs
254 if (m_mBool["fVerbose"]) {
255 for (unsigned iSt = 0; iSt < 4; iSt++) {
256 const vector<TCLink*>& links = aTrack.links(iSt * 2 + 1);
257 const unsigned nSegments = links.size();
258 cout << "iSt:" << iSt << " nSegments:" << nSegments << endl;
259 for (unsigned iTS = 0; iTS < nSegments; iTS++) {
260 const TCSegment* t_segment = dynamic_cast<const TCSegment*>(& links[iTS]->hit()->cell());
261 cout << " tsId:" << t_segment->localId()
262 << " tdc:" << t_segment->priorityTime() << " lr:" << t_segment->LUT()->getValue(t_segment->lutPattern())
263 << " priorityPosition:" << t_segment->priorityPosition() << endl;
264 }
265 }
266 }
267 // Check which stereo super layers should be used.
268 m_mVector["useStSl"] = vector<double> (4);
269 findHitStereoSuperlayers(aTrack, m_mVector["useStSl"], m_mBool["fIsPrintError"]);
271 m_mDouble["nHitStSl"] = m_mVector["useStSl"][0] + m_mVector["useStSl"][1] + m_mVector["useStSl"][2] + m_mVector["useStSl"][3];
272
273 m_mVector["useSl"] = vector<double> (9);
274 for (unsigned iAx = 0; iAx < 5; iAx++) m_mVector["useSl"][2 * iAx] = m_mVector["useAxSl"][iAx];
275 for (unsigned iSt = 0; iSt < 4; iSt++) m_mVector["useSl"][2 * iSt + 1] = m_mVector["useAxSl"][iSt];
276
277 // Fill information for stereo layers
278 for (unsigned iSt = 0; iSt < 4; iSt++) {
279 if (m_mVector["useStSl"][iSt] == 1) {
280 const vector<TCLink*>& links = aTrack.links(iSt * 2 + 1);
281 const TCSegment* t_segment = dynamic_cast<const TCSegment*>(& links[0]->hit()->cell());
282 m_mVector["tsId"][iSt * 2 + 1] = t_segment->localId();
283 m_mVector["wirePhi"][iSt * 2 + 1] = (double) t_segment->localId() / m_mConstV["nWires"][iSt * 2 + 1] * 4 * m_mConstD["Trg_PI"];
284 m_mVector["lutLR"][iSt * 2 + 1] = t_segment->LUT()->getValue(t_segment->lutPattern());
285 if (m_mBool["fMc"]) m_mVector["mcLR"][iSt * 2 + 1] = t_segment->hit()->mcLR() + 1;
286 m_mVector["driftLength"][iSt * 2 + 1] = t_segment->hit()->drift();
287 m_mVector["tdc"][iSt * 2 + 1] = t_segment->priorityTime();
288 if (m_mBool["fmcLR"] == 1) m_mVector["LR"][iSt * 2 + 1] = m_mVector["mcLR"][iSt * 2 + 1];
289 else if (m_mBool["fLRLUT"] == 1) m_mVector["LR"][iSt * 2 + 1] = m_mVector["lutLR"][iSt * 2 + 1];
290 else m_mVector["LR"][iSt * 2 + 1] = 3;
291 } else {
292 m_mVector["tsId"][iSt * 2 + 1] = 9999;
293 m_mVector["wirePhi"][iSt * 2 + 1] = 9999;
294 m_mVector["lutLR"][iSt * 2 + 1] = 0;
295 if (m_mBool["fMc"]) m_mVector["mcLR"][iSt * 2 + 1] = 9999;
296 m_mVector["driftLength"][iSt * 2 + 1] = 9999;
297 m_mVector["tdc"][iSt * 2 + 1] = 9999;
298 if (m_mBool["fmcLR"] == 1) m_mVector["LR"][iSt * 2 + 1] = 9999;
299 else if (m_mBool["fLRLUT"] == 1) m_mVector["LR"][iSt * 2 + 1] = 9999;
300 else m_mVector["LR"][iSt * 2 + 1] = 9999;
301 }
302 } // End superlayer loop
303
304 // Calculate phi3D.
305 m_mVector["phi3D"] = vector<double> (4);
306 if (m_mDouble["eventTime"] == 9999) {
307 for (unsigned iSt = 0; iSt < 4; iSt++) {
308 m_mVector["phi3D"][iSt] = m_mVector["wirePhi"][iSt * 2 + 1];
309 }
310 } else {
311 for (unsigned iSt = 0; iSt < 4; iSt++) {
312 if (m_mVector["useStSl"][iSt] == 1) {
313 // Get drift length from table.
314 string tableName = "driftLengthTableSL" + to_string(iSt * 2 + 1);
315 double t_driftTime = m_mVector["tdc"][iSt * 2 + 1] - m_mDouble["eventTime"];
316 if (t_driftTime < 0) t_driftTime = 0;
317 double t_driftLength = m_mConstV[tableName][(unsigned)t_driftTime];
318 m_mVector["phi3D"][iSt] = Fitter3DUtility::calPhi(m_mVector["wirePhi"][iSt * 2 + 1], t_driftLength, m_mConstV["rr3D"][iSt],
319 m_mVector["LR"][iSt * 2 + 1]);
320 } else {
321 m_mVector["phi3D"][iSt] = 9999;
322 }
323 }
324 }
325 // Get zerror for 3D fit
326 m_mVector["zError"] = vector<double> (4);
327 for (unsigned iSt = 0; iSt < 4; iSt++) {
328 if (m_mVector["useStSl"][iSt] == 1) {
329 // Check LR.
330 if (m_mVector["LR"][2 * iSt + 1] != 3) m_mVector["zError"][iSt] = m_mConstV["driftZError"][iSt];
331 else m_mVector["zError"][iSt] = m_mConstV["wireZError"][iSt];
332 // Check eventTime
333 if (m_mDouble["eventTime"] == 9999) m_mVector["zError"][iSt] = m_mConstV["wireZError"][iSt];
334 } else {
335 m_mVector["zError"][iSt] = 9999;
336 }
337 }
338 // Get inverse zerror ^ 2
339 m_mVector["iZError2"] = vector<double> (4);
340 for (unsigned iSt = 0; iSt < 4; iSt++) {
341 if (m_mVector["useStSl"][iSt] == 1) {
342 m_mVector["iZError2"][iSt] = 1 / pow(m_mVector["zError"][iSt], 2);
343 } else {
344 m_mVector["iZError2"][iSt] = 0;
345 }
346 }
347
348 // Calculate zz
349 m_mVector["zz"] = vector<double> (4);
350 for (unsigned iSt = 0; iSt < 4; iSt++) {
351 if (m_mVector["useStSl"][iSt] == 1) {
352 //m_mVector["zz"][iSt] = Fitter3DUtility::calZ(m_mDouble["charge"], m_mConstV["angleSt"][iSt], m_mConstV["zToStraw"][iSt], m_mConstV["rr3D"][iSt], m_mVector["phi3D"][iSt], m_mDouble["rho"], m_mDouble["phi0"]);
353 m_mVector["zz"][iSt] = Fitter3DUtility::calZ(m_mDouble["charge2D"], m_mConstV["angleSt"][iSt], m_mConstV["zToStraw"][iSt],
354 m_mConstV["rr3D"][iSt], m_mVector["phi3D"][iSt], m_mDouble["rho"], m_mDouble["phi0"]);
355 } else {
356 m_mVector["zz"][iSt] = 0;
357 }
358 }
359 // Calculate arcS
360 m_mVector["arcS"] = vector<double> (4);
361 for (unsigned iSt = 0; iSt < 4; iSt++) {
362 if (m_mVector["useStSl"][iSt] == 1) {
363 m_mVector["arcS"][iSt] = Fitter3DUtility::calS(m_mDouble["rho"], m_mConstV["rr3D"][iSt]);
364 } else {
365 m_mVector["arcS"][iSt] = 0;
366 }
367 }
368 // Fit3D
369 m_mDouble["z0"] = 0;
370 m_mDouble["cot"] = 0;
371 m_mDouble["zChi2"] = 0;
372 Fitter3DUtility::rSFit(&m_mVector["iZError2"][0], &m_mVector["arcS"][0], &m_mVector["zz"][0], m_mDouble["z0"], m_mDouble["cot"],
373 m_mDouble["zChi2"]);
374 // Change to deg
375 m_mDouble["theta"] = m_mConstD["Trg_PI"] / 2 - atan(m_mDouble["cot"]);
376 m_mDouble["theta"] = 180 / m_mConstD["Trg_PI"];
377
378 if (m_mBool["fVerbose"]) print3DInformation(iTrack);
379
380 // For failed fits. When cot is 0 or nan.
381 if (m_mDouble["cot"] == 0 || std::isnan(m_mDouble["cot"])) {
382 aTrack.setFitted(0);
383 aTrack.setDebugValue(TRGCDCTrack::EDebugValueType::fit3D, 1);
384 if (m_mBool["fVerbose"]) cout << "Exit due to 3D fit cot result:" << m_mDouble["cot"] << endl;
385 continue;
386 }
387
388 // Set track in trackList
389 if (m_mBool["fVerbose"]) cout << "Fit was done successfully." << endl;
390 // Set Helix parameters
391 TRGCDCHelix helix(ORIGIN, CLHEP::HepVector(5, 0), CLHEP::HepSymMatrix(5, 0));
392 CLHEP::HepVector a(5);
393 a = aTrack.helix().a();
394 aTrack.setFitted(1);
395 //if(m_mDouble["charge"]<0)
396 if (m_mDouble["charge2D"] < 0) {
397 a[1] = fmod(m_mDouble["phi0"] + m_mConstD["Trg_PI"], 2 * m_mConstD["Trg_PI"]);
398 } else {
399 a[1] = m_mDouble["phi0"];
400 }
401 //a[2] = 1/m_mDouble["pt"]*m_mDouble["charge"];
402 a[2] = 1 / m_mDouble["pt"] * m_mDouble["charge2D"];
403 a[3] = m_mDouble["z0"];
404 a[4] = m_mDouble["cot"];
405 helix.a(a);
406 aTrack.set2DFitChi2(m_mDouble["fit2DChi2"]);
407 aTrack.set3DFitChi2(m_mDouble["zChi2"]);
408 aTrack.setHelix(helix);
409
411 // Save values
412 if (m_mBool["fRootFile"]) {
413 if (m_fileFitter3D == 0) {
414 m_fileFitter3D = new TFile(m_rootFitter3DFileName.c_str(), "RECREATE");
415 HandleRoot::initializeRoot("fitter3D", &m_treeConstantsFitter3D, &m_treeTrackFitter3D,
419 );
420 }
421 HandleRoot::saveTrackValues("fitter3D",
423 );
424 }
425
426 } // End track loop
427
428 // Save values to file
429 // To prevent crash when there are no tracks in first event.
430 // If there is no track in first case then the ROOT saving functions might fail.
431 // This is due to bad software design.
432 // The first event that have tracks will be event 0 in ROOT file.
433 if (m_mBool["fRootFile"]) {
434 if (m_fileFitter3D != 0) m_treeTrackFitter3D->Fill();
435 }
436
437 if (m_mBool["debugFitted"]) {
438 for (unsigned iTrack = 0; iTrack < trackList.size(); iTrack++) {
439 TCTrack& aTrack = * trackList[iTrack];
440 if (aTrack.fitted() == 0) aTrack.setDebugValue(TRGCDCTrack::EDebugValueType::fit3D, 1);
441 }
442 }
443 if (m_mBool["debugLargeZ0"]) {
444 // If 3D fit z0 is larger or smaller than expected.
445 for (unsigned iTrack = 0; iTrack < trackList.size(); iTrack++) {
446 TCTrack& aTrack = *trackList[iTrack];
447 if (aTrack.fitted()) {
448 double fitZ0 = aTrack.helix().dz();
449 if (fitZ0 > 20 || fitZ0 < -20) aTrack.setDebugValue(TRGCDCTrack::EDebugValueType::fit3D, 1);
450 }
451 }
452 }
453
454
455 TRGDebug::leaveStage("Fitter 3D");
456 return 1;
457
458 }
459
460 int TRGCDCFitter3D::doitComplex(std::vector<TRGCDCTrack*>& trackList)
461 {
462
463 TRGDebug::enterStage("Fitter 3D");
464
465 // Set values for saving data.
466 if (m_mBool["fRootFile"]) {
467 m_mDouble["iSave"] = 0;
468 HandleRoot::initializeEvent(m_mTClonesArray);
469 }
470 if (m_commonData == 0) {
472 }
473
474 // Get common values for event.
475 m_mDouble["eventTime"] = m_cdc.getEventTime();
476 StoreObjPtr<EventMetaData> eventMetaDataPtr;
477 // Event starts from 0.
478 m_mDouble["eventNumber"] = eventMetaDataPtr->getEvent();
479
480 // Fitter3D
481 // Loop over all tracks
482 for (unsigned iTrack = 0; iTrack < trackList.size(); iTrack++) {
483
484 TCTrack& aTrack = * trackList[iTrack];
485
487 // Get MC values for 3D fitter
488 if (m_mBool["fMc"]) getMCValues(m_cdc, &aTrack, m_mConstD, m_mDouble, m_mVector);
489 // Get input values for 3D fitter
490 // Get event and track ID
491 m_mDouble["trackId"] = aTrack.getTrackID();
492
495 int fit2DResult = do2DFit(aTrack, m_mBool, m_mConstD, m_mConstV, m_mDouble, m_mVector);
496 if (fit2DResult != 0) {
497 aTrack.setFitted(0);
498 continue;
499 }
500
502 // Start of 3D fitter
503 // Print input TSs
504 if (m_mBool["fVerbose"]) {
505 for (unsigned iSt = 0; iSt < 4; iSt++) {
506 const vector<TCLink*>& links = aTrack.links(iSt * 2 + 1);
507 const unsigned nSegments = links.size();
508 cout << "iSt:" << iSt << " nSegments:" << nSegments << endl;
509 for (unsigned iTS = 0; iTS < nSegments; iTS++) {
510 const TCSegment* t_segment = dynamic_cast<const TCSegment*>(& links[iTS]->hit()->cell());
511 cout << " tsId:" << t_segment->localId()
512 << " tdc:" << t_segment->priorityTime() << " lr:" << t_segment->LUT()->getValue(t_segment->lutPattern())
513 << " priorityPosition:" << t_segment->priorityPosition() << endl;
514 }
515 }
516 }
517 m_mVector["useStSl"] = vector<double> (4);
518 findHitStereoSuperlayers(aTrack, m_mVector["useStSl"], m_mBool["fIsPrintError"]);
520 m_mDouble["nHitStSl"] = m_mVector["useStSl"][0] + m_mVector["useStSl"][1] + m_mVector["useStSl"][2] + m_mVector["useStSl"][3];
521
522 // Fill information for stereo layers
523 for (unsigned iSt = 0; iSt < 4; iSt++) {
524 if (m_mVector["useStSl"][iSt] == 1) {
525 const vector<TCLink*>& links = aTrack.links(iSt * 2 + 1);
526 const TCSegment* t_segment = dynamic_cast<const TCSegment*>(& links[0]->hit()->cell());
527 m_mVector["tsId"][iSt * 2 + 1] = t_segment->localId();
528 m_mVector["wirePhi"][iSt * 2 + 1] = (double) t_segment->localId() / m_mConstV["nWires"][iSt * 2 + 1] * 4 * m_mConstD["Trg_PI"];
529 m_mVector["lutLR"][iSt * 2 + 1] = t_segment->LUT()->getValue(t_segment->lutPattern());
530 if (m_mBool["fMc"]) m_mVector["mcLR"][iSt * 2 + 1] = t_segment->hit()->mcLR() + 1;
531 m_mVector["driftLength"][iSt * 2 + 1] = t_segment->hit()->drift();
532 m_mVector["tdc"][iSt * 2 + 1] = t_segment->priorityTime();
533 if (m_mBool["fmcLR"] == 1) m_mVector["LR"][iSt * 2 + 1] = m_mVector["mcLR"][iSt * 2 + 1];
534 else if (m_mBool["fLRLUT"] == 1) m_mVector["LR"][iSt * 2 + 1] = m_mVector["lutLR"][iSt * 2 + 1];
535 else m_mVector["LR"][iSt * 2 + 1] = 3;
536 } else {
537 m_mVector["tsId"][iSt * 2 + 1] = 0;
538 m_mVector["wirePhi"][iSt * 2 + 1] = 9999;
539 m_mVector["lutLR"][iSt * 2 + 1] = 0;
540 if (m_mBool["fMc"]) m_mVector["mcLR"][iSt * 2 + 1] = 9999;
541 m_mVector["driftLength"][iSt * 2 + 1] = 9999;
542 m_mVector["tdc"][iSt * 2 + 1] = 0;
543 if (m_mBool["fmcLR"] == 1) m_mVector["LR"][iSt * 2 + 1] = 9999;
544 else if (m_mBool["fLRLUT"] == 1) m_mVector["LR"][iSt * 2 + 1] = 9999;
545 else m_mVector["LR"][iSt * 2 + 1] = 9999;
546 }
547 } // End superlayer loop
549 //int minTSTdc = 9999;
550 //for(unsigned iSl=0; iSl<9; iSl++){
551 // if (minTSTdc > m_mVector["tdc"][iSl]) minTSTdc = m_mVector["tdc"][iSl];
552 //}
553 //m_mDouble["eventTime"] = minTSTdc;
554
555 // Calculate phi3D.
556 m_mVector["phi3D"] = vector<double> (4);
557 if (m_mDouble["eventTime"] == 9999) {
558 for (unsigned iSt = 0; iSt < 4; iSt++) {
559 m_mVector["phi3D"][iSt] = m_mVector["wirePhi"][iSt * 2 + 1];
560 }
561 } else {
562 for (unsigned iSt = 0; iSt < 4; iSt++) {
563 // Get drift length from table.
564 string tableName = "driftLengthTableSL" + to_string(iSt * 2 + 1);
565 double t_driftTime = m_mVector["tdc"][iSt * 2 + 1] - m_mDouble["eventTime"];
566 if (t_driftTime < 0) t_driftTime = 0;
567 double t_driftLength = m_mConstV[tableName][(unsigned)t_driftTime];
568 m_mVector["phi3D"][iSt] = Fitter3DUtility::calPhi(m_mVector["wirePhi"][iSt * 2 + 1], t_driftLength, m_mConstV["rr3D"][iSt],
569 m_mVector["LR"][iSt * 2 + 1]);
570 }
571 }
572
573 // Get zerror for 3D fit
574 m_mVector["zError"] = vector<double> (4);
575 for (unsigned iSt = 0; iSt < 4; iSt++) {
576 // Check LR.
577 if (m_mVector["LR"][2 * iSt + 1] != 3) m_mVector["zError"][iSt] = m_mConstV["driftZError"][iSt];
578 else m_mVector["zError"][iSt] = m_mConstV["wireZError"][iSt];
579 // Check eventTime
580 if (m_mDouble["eventTime"] == 9999) m_mVector["zError"][iSt] = m_mConstV["wireZError"][iSt];
581 }
582 // Get inverse zerror ^ 2
583 m_mVector["iZError2"] = vector<double> (4);
584 for (unsigned iSt = 0; iSt < 4; iSt++) {
585 if (m_mVector["useStSl"][iSt] == 1) {
586 m_mVector["iZError2"][iSt] = 1 / pow(m_mVector["zError"][iSt], 2);
587 } else {
588 m_mVector["iZError2"][iSt] = 0;
589 }
590 }
591
592 // Simple version of Fitter3D
594 //m_mVector["zz"] = vector<double> (4);
595 //for (unsigned iSt = 0; iSt < 4; iSt++) m_mVector["zz"][iSt] = Fitter3DUtility::calZ(m_mDouble["charge"], m_mConstV["angleSt"][iSt], m_mConstV["zToStraw"][iSt], m_mConstV["rr3D"][iSt], m_mVector["phi3D"][iSt], m_mDouble["rho"], m_mDouble["phi0"]);
597 //m_mVector["arcS"] = vector<double> (4);
598 //for (unsigned iSt = 0; iSt < 4; iSt++) m_mVector["arcS"][iSt] = Fitter3DUtility::calS(m_mDouble["rho"], m_mConstV["rr3D"][iSt]);
600 //m_mDouble["z0"] = 0;
601 //m_mDouble["cot"] = 0;
602 //m_mDouble["zChi2"] = 0;
603 //Fitter3DUtility::rSFit(&m_mVector["iZError2"][0], &m_mVector["arcS"][0], &m_mVector["zz"][0], m_mDouble["z0"], m_mDouble["cot"], m_mDouble["zChi2"]);
605 //m_mDouble["theta"] = m_mConstD["Trg_PI"]/2 - atan(m_mDouble["cot"]);
606 //m_mDouble["theta"] = 180 / m_mConstD["Trg_PI"];
607
608 double phiMax = m_mConstD["Trg_PI"];
609 double phiMin = -m_mConstD["Trg_PI"];
610 int phiBitSize = 13;
611 // pt = 0.3*1.5*rho*0.01;
612 //double rhoMin = 48;
613 /* cppcheck-suppress variableScope */
614 double rhoMin = 20;
615 double rhoMax = 2500;
616 //double rhoMax = 1600;
617 // 5bit (clock counter) + 4 bit (2ns resolution)
618 m_mConstD["tdcBitSize"] = 9;
619 m_mConstD["rhoBitSize"] = 11;
620 m_mConstD["iError2BitSize"] = 8;
621 m_mConstD["iError2Max"] = 1 / pow(m_mConstV["wireZError"][0], 2);
622 // LUT values
623 m_mConstD["JB"] = 0;
624 m_mConstD["driftPhiLUTOutBitSize"] = phiBitSize - 1;
625 m_mConstD["driftPhiLUTInBitSize"] = m_mConstD["tdcBitSize"];
626 m_mConstD["acosLUTOutBitSize"] = phiBitSize - 1;
627 m_mConstD["acosLUTInBitSize"] = m_mConstD["rhoBitSize"];
628 m_mConstD["zLUTInBitSize"] = phiBitSize;
629 m_mConstD["zLUTOutBitSize"] = 9;
630 m_mConstD["iDenLUTInBitSize"] = 13;
631 m_mConstD["iDenLUTOutBitSize"] = 11; // To increase wireZError = 2.5*driftZError
632 // Rotate by quadrants depending on charge and cc(circle center)
633 m_mDouble["relRefPhi"] = 0;
634 int t_quadrant = Fitter3DUtility::findQuadrant(m_mDouble["phi0"]);
635 //if (m_mDouble["charge"] == -1)
636 if (m_mDouble["charge2D"] == -1) {
637 if (t_quadrant == 1) m_mDouble["relRefPhi"] = 0;
638 else if (t_quadrant == 2) m_mDouble["relRefPhi"] = -m_mConstD["Trg_PI"] / 2;
639 else if (t_quadrant == 3) m_mDouble["relRefPhi"] = -m_mConstD["Trg_PI"];
640 else if (t_quadrant == 4) m_mDouble["relRefPhi"] = m_mConstD["Trg_PI"] / 2;
641 } else {
642 if (t_quadrant == 1) m_mDouble["relRefPhi"] = m_mConstD["Trg_PI"] / 2;
643 else if (t_quadrant == 2) m_mDouble["relRefPhi"] = 0;
644 else if (t_quadrant == 3) m_mDouble["relRefPhi"] = -m_mConstD["Trg_PI"] / 2;
645 else if (t_quadrant == 4) m_mDouble["relRefPhi"] = -m_mConstD["Trg_PI"];
646 }
647 // Rotate phi
648 m_mDouble["relPhi0"] = Fitter3DUtility::rotatePhi(m_mDouble["phi0"], m_mDouble["relRefPhi"]);
649 m_mVector["relPhi3D"] = vector<double> (4);
650 for (unsigned iSt = 0; iSt < 4;
651 iSt++) m_mVector["relPhi3D"][iSt] = Fitter3DUtility::rotatePhi(m_mVector["phi3D"][iSt], m_mDouble["relRefPhi"]);
652
653 // Rotate wirePhi
654 m_mVector["relWirePhi3D"] = vector<double> (4);
655 for (unsigned iSt = 0; iSt < 4; iSt++) {
656 double t_relWirePhi = Fitter3DUtility::rotatePhi(m_mVector["wirePhi"][2 * iSt + 1], m_mDouble["relRefPhi"]);
657 bool rangeOk = 0;
658 while (rangeOk == 0) {
659 if (t_relWirePhi < 0) t_relWirePhi += 2 * m_mConstD["Trg_PI"];
660 else if (t_relWirePhi > 2 * m_mConstD["Trg_PI"]) t_relWirePhi -= 2 * m_mConstD["Trg_PI"];
661 else rangeOk = 1;
662 }
663 m_mVector["relWirePhi3D"][iSt] = t_relWirePhi;
664 }
665
666 // Rotate tsId
667 m_mVector["relTsId3D"] = vector<double> (4);
668 for (unsigned iSt = 0; iSt < 4;
669 iSt++) m_mVector["relTsId3D"][iSt] = Fitter3DUtility::rotateTsId(m_mVector["tsId"][2 * iSt + 1],
670 m_mDouble["relRefPhi"] / m_mConstD["Trg_PI"] / 2 * m_mConstV["nTSs"][2 * iSt + 1], m_mConstV["nTSs"][2 * iSt + 1]);
671
672 // Constrain rho to rhoMax. For removing warnings when changing to signals.
673 if (m_mDouble["rho"] > rhoMax) {
674 m_mDouble["rho"] = rhoMax;
675 m_mDouble["pt"] = rhoMax * 0.3 * 1.5 * 0.01;
676 }
677
678 // Constrain event time
679 m_mDouble["eventTimeValid"] = 1;
680 if (m_mDouble["eventTime"] == 9999) m_mDouble["eventTimeValid"] = 0;
681 // Change tdc and eventTime to 9 bit unsigned value. (Ex: -1 => 511, -2 => 510)
682 m_mVector["unsignedTdc"] = vector<double> (9);
683 for (unsigned iSt = 0; iSt < 4; iSt++) {
684 //cout<<"iSt:"<<iSt<<" tdc:"<<m_mVector["tdc"][2*iSt+1]<<" unsignedTdc:"<<Fitter3DUtility::toUnsignedTdc(m_mVector["tdc"][2*iSt+1], 9)<<endl;
685 m_mVector["unsignedTdc"][2 * iSt + 1] = Fitter3DUtility::toUnsignedTdc(m_mVector["tdc"][2 * iSt + 1], m_mConstD["tdcBitSize"]);
686 }
687 m_mDouble["unsignedEventTime"] = Fitter3DUtility::toUnsignedTdc(m_mDouble["eventTime"], m_mConstD["tdcBitSize"]);
688 //cout<<"eventTime:"<<m_mDouble["eventTime"]<<" unsignedEventTime:"<<Fitter3DUtility::toUnsignedTdc(m_mDouble["eventTime"], 9)<<endl;
689
690 // Change to Signals.
691 {
692 vector<tuple<string, double, int, double, double, int> > t_values = {
693 make_tuple("phi0", m_mDouble["relPhi0"], phiBitSize, phiMin, phiMax, 0),
694 make_tuple("rho", m_mDouble["rho"], m_mConstD["rhoBitSize"], rhoMin, rhoMax, 0),
695 //make_tuple("charge",(int) (m_mDouble["charge"]==1 ? 1 : 0), 1, 0, 1.5, 0),
696 make_tuple("charge", (int)(m_mDouble["charge2D"] == 1 ? 1 : 0), 1, 0, 1.5, 0),
697 make_tuple("lr_0", m_mVector["lutLR"][1], 2, 0, 3.5, 0),
698 make_tuple("lr_1", m_mVector["lutLR"][3], 2, 0, 3.5, 0),
699 make_tuple("lr_2", m_mVector["lutLR"][5], 2, 0, 3.5, 0),
700 make_tuple("lr_3", m_mVector["lutLR"][7], 2, 0, 3.5, 0),
701 make_tuple("tsId_0", m_mVector["relTsId3D"][0], ceil(log(m_mConstV["nTSs"][1]) / log(2)), 0, pow(2, ceil(log(m_mConstV["nTSs"][1]) / log(2))) - 0.5, 0),
702 make_tuple("tsId_1", m_mVector["relTsId3D"][1], ceil(log(m_mConstV["nTSs"][3]) / log(2)), 0, pow(2, ceil(log(m_mConstV["nTSs"][3]) / log(2))) - 0.5, 0),
703 make_tuple("tsId_2", m_mVector["relTsId3D"][2], ceil(log(m_mConstV["nTSs"][5]) / log(2)), 0, pow(2, ceil(log(m_mConstV["nTSs"][5]) / log(2))) - 0.5, 0),
704 make_tuple("tsId_3", m_mVector["relTsId3D"][3], ceil(log(m_mConstV["nTSs"][7]) / log(2)), 0, pow(2, ceil(log(m_mConstV["nTSs"][7]) / log(2))) - 0.5, 0),
705 make_tuple("tdc_0", m_mVector["unsignedTdc"][1], m_mConstD["tdcBitSize"], 0, pow(2, m_mConstD["tdcBitSize"]) - 0.5, 0),
706 make_tuple("tdc_1", m_mVector["unsignedTdc"][3], m_mConstD["tdcBitSize"], 0, pow(2, m_mConstD["tdcBitSize"]) - 0.5, 0),
707 make_tuple("tdc_2", m_mVector["unsignedTdc"][5], m_mConstD["tdcBitSize"], 0, pow(2, m_mConstD["tdcBitSize"]) - 0.5, 0),
708 make_tuple("tdc_3", m_mVector["unsignedTdc"][7], m_mConstD["tdcBitSize"], 0, pow(2, m_mConstD["tdcBitSize"]) - 0.5, 0),
709 make_tuple("eventTime", m_mDouble["unsignedEventTime"], m_mConstD["tdcBitSize"], 0, pow(2, m_mConstD["tdcBitSize"]) - 0.5, 0),
710 make_tuple("eventTimeValid", (int) m_mDouble["eventTimeValid"], 1, 0, 1.5, 0),
711 };
713 }
714
721 // Change to values.
722 vector<tuple<string, double, int, double, double, int> > resultValues;
723 {
724 vector<pair<string, int> > t_chooseSignals = {
725 make_pair("z0", 0), make_pair("cot", 0), make_pair("chi2Sum", 0)
726 };
727 TRGCDCJSignal::mapSignalsToValues(m_mSignalStorage, t_chooseSignals, resultValues);
728 }
729
730 // Post handling of signals.
731 // Name all signals.
732 if ((*m_mSignalStorage.begin()).second.getName() == "") {
733 for (auto it = m_mSignalStorage.begin(); it != m_mSignalStorage.end(); ++it) {
734 (*it).second.setName((*it).first);
735 }
736 }
745
746
747 // Takes some time.
748 // Save values.
749 if (m_mBool["fRootFile"]) {
750 // Check if there is a name.
751 if ((*m_mSignalStorage.begin()).second.getName() != "") {
752
753 // Save values to root file.
754 {
755 vector<pair<string, int> > chooseValues = {
756 make_pair("zz_0", m_mBool["fIsIntegerEffect"]),
757 make_pair("zz_1", m_mBool["fIsIntegerEffect"]),
758 make_pair("zz_2", m_mBool["fIsIntegerEffect"]),
759 make_pair("zz_3", m_mBool["fIsIntegerEffect"]),
760 make_pair("arcS_0", m_mBool["fIsIntegerEffect"]),
761 make_pair("arcS_1", m_mBool["fIsIntegerEffect"]),
762 make_pair("arcS_2", m_mBool["fIsIntegerEffect"]),
763 make_pair("arcS_3", m_mBool["fIsIntegerEffect"]),
764 make_pair("z0", m_mBool["fIsIntegerEffect"]),
765 make_pair("cot", m_mBool["fIsIntegerEffect"]),
766 make_pair("zChi2", m_mBool["fIsIntegerEffect"])
767 };
768 // outValues => [name, value, bitwidth, min, max, clock]
769 vector<tuple<string, double, int, double, double, int> > outValues;
770 TRGCDCJSignal::mapSignalsToValues(m_mSignalStorage, chooseValues, outValues);
771 // Changes names with "_" to m_mVector.
772 HandleRoot::convertSignalValuesToMaps(outValues, m_mDouble, m_mVector);
773 }
774 }
775 }
776
777 m_mBool["fVHDLFile"] = 0;
778 if (m_mBool["fVHDLFile"]) {
779 // Check if there is a name.
780 if ((*m_mSignalStorage.begin()).second.getName() != "") {
781 // Saves to file only one time.
783 // Saves values to memory. Wrote to file at terminate().
786 }
787 }
788
790 // Calculate zz
791 m_mVector["float_zz"] = vector<double> (4);
792 //for (unsigned iSt = 0; iSt < 4; iSt++) m_mVector["float_zz"][iSt] = Fitter3DUtility::calZ(m_mDouble["charge"], m_mConstV["angleSt"][iSt], m_mConstV["zToStraw"][iSt], m_mConstV["rr3D"][iSt], m_mVector["phi3D"][iSt], m_mDouble["rho"], m_mDouble["phi0"]);
793 for (unsigned iSt = 0; iSt < 4;
794 iSt++) m_mVector["float_zz"][iSt] = Fitter3DUtility::calZ(m_mDouble["charge2D"], m_mConstV["angleSt"][iSt],
795 m_mConstV["zToStraw"][iSt], m_mConstV["rr3D"][iSt], m_mVector["phi3D"][iSt], m_mDouble["rho"], m_mDouble["phi0"]);
796 // Calculate arcS
797 m_mVector["float_arcS"] = vector<double> (4);
798 for (unsigned iSt = 0; iSt < 4;
799 iSt++) m_mVector["float_arcS"][iSt] = Fitter3DUtility::calS(m_mDouble["rho"], m_mConstV["rr3D"][iSt]);
800 // Fit3D
801 m_mDouble["float_z0"] = 0;
802 m_mDouble["float_cot"] = 0;
803 m_mDouble["float_zChi2"] = 0;
804 Fitter3DUtility::rSFit(&m_mVector["iZError2"][0], &m_mVector["float_arcS"][0], &m_mVector["float_zz"][0], m_mDouble["float_z0"],
805 m_mDouble["float_cot"], m_mDouble["float_zChi2"]);
806
807 if (m_mBool["fVerbose"]) {
808 for (unsigned iSt = 0; iSt < 4; iSt++) cout << "float_zz[" << iSt << "] : " << m_mVector["float_zz"][iSt] << " ";
809 cout << endl;
810 for (unsigned iSt = 0; iSt < 4; iSt++) cout << "float_arcS[" << iSt << "] : " << m_mVector["float_arcS"][iSt] << " ";
811 cout << endl;
812 cout << "float_z0: " << m_mDouble["float_z0"] << endl;
813 cout << "float_zChi2: " << m_mDouble["float_zChi2"] << endl;
814
815 print3DInformation(iTrack);
816 }
817
818 // For failed fits.
819 if (m_mDouble["cot"] == 0) {
820 aTrack.setFitted(0);
821 continue;
822 }
823
824 // Set track in trackListOut.
825 // Set Helix parameters
826 TRGCDCHelix helix(ORIGIN, CLHEP::HepVector(5, 0), CLHEP::HepSymMatrix(5, 0));
827 CLHEP::HepVector a(5);
828 a = aTrack.helix().a();
829 aTrack.setFitted(1);
830 //if(m_mDouble["charge"]<0)
831 if (m_mDouble["charge2D"] < 0) {
832 a[1] = fmod(m_mDouble["phi0"] + m_mConstD["Trg_PI"], 2 * m_mConstD["Trg_PI"]);
833 } else {
834 a[1] = m_mDouble["phi0"];
835 }
836 //a[2] = 1/m_mDouble["pt"]*m_mDouble["charge"];
837 a[2] = 1 / m_mDouble["pt"] * m_mDouble["charge2D"];
838 a[3] = m_mDouble["z0"];
839 a[4] = m_mDouble["cot"];
840 helix.a(a);
841 aTrack.setHelix(helix);
842 aTrack.set2DFitChi2(m_mDouble["fit2DChi2"]);
843 aTrack.set3DFitChi2(m_mDouble["zChi2"]);
844
846 // Save values
847 if (m_mBool["fRootFile"]) {
848 if (m_fileFitter3D == 0) {
849 m_fileFitter3D = new TFile(m_rootFitter3DFileName.c_str(), "RECREATE");
850 HandleRoot::initializeRoot("fitter3D", &m_treeConstantsFitter3D, &m_treeTrackFitter3D,
854 );
855 }
856 HandleRoot::saveTrackValues("fitter3D",
858 );
859 }
860
861 } // End track loop
862
863 // Save values to file
864 // To prevent crash when there are no tracks in first event.
865 // If there is no track in first evnet then the HandleRoot saving functions will fail.
866 // This is due to bad HandleRoot software design.
867 // The first event that have tracks will be event 0 in ROOT file.
868 if (m_mBool["fRootFile"]) {
869 if (m_fileFitter3D != 0) m_treeTrackFitter3D->Fill();
870 }
871
872 if (m_mBool["debugFitted"]) {
873 for (unsigned iTrack = 0; iTrack < trackList.size(); iTrack++) {
874 TCTrack& aTrack = * trackList[iTrack];
875 if (aTrack.fitted() == 0) aTrack.setDebugValue(TRGCDCTrack::EDebugValueType::fit3D, 1);
876 }
877 }
878 if (m_mBool["debugLargeZ0"]) {
879 // If 3D fit z0 is larger or smaller than expected.
880 for (unsigned iTrack = 0; iTrack < trackList.size(); iTrack++) {
881 TCTrack& aTrack = *trackList[iTrack];
882 if (aTrack.fitted()) {
883 double fitZ0 = aTrack.helix().dz();
884 if (fitZ0 > 20 || fitZ0 < -20) aTrack.setDebugValue(TRGCDCTrack::EDebugValueType::fit3D, 1);
885 }
886 }
887 }
888
889 TRGDebug::leaveStage("Fitter 3D");
890
891 return 1;
892
893 }
894
895 double TRGCDCFitter3D::calPhi(TRGCDCSegmentHit const* segmentHit, double eventTime)
896 {
898 unsigned localId = segmentHit->segment().center().localId();
899 unsigned layerId = segmentHit->segment().center().layerId();
900 int nWires = cdcp.nWiresInLayer(layerId) * 2;
901 double rr = cdcp.senseWireR(layerId);
902 double tdc = segmentHit->segment().priorityTime();
903 int lr = segmentHit->segment().LUT()->getValue(segmentHit->segment().lutPattern());
904 return Fitter3DUtility::calPhi(localId, nWires, tdc, eventTime, rr, lr);
905 }
906
907
911 // Functions for saving.
913 {
914 // Print Vhdl
915 if (m_commonData->getPrintedToFile() == 0) {
916 if (m_commonData->getPrintVhdl() == 0) {
917 m_commonData->setVhdlOutputFile("Fitter3D.vhd");
919 } else {
925 // Print LUTs.
926 for (map<string, TRGCDCJLUT*>::iterator it = m_mLutStorage.begin(); it != m_mLutStorage.end(); ++it) {
927 //it->second->makeCOE("./VHDL/LutData/"+it->first+".coe");
928 it->second->makeCOE(it->first + ".coe");
929 }
930 }
931 }
932 }
933
935 {
936 // Save all signals to m_mSavedSignals. Limit to 10 times.
937 if ((*m_mSavedSignals.begin()).second.size() < 10 || m_mSavedSignals.empty()) {
938 for (auto it = m_mSignalStorage.begin(); it != m_mSignalStorage.end(); ++it) {
939 m_mSavedSignals[(*it).first].push_back((*it).second.getInt());
940 }
941 }
942 }
943
945 {
946 // Save input output signals. Limit to 1024.
947 if ((*m_mSavedIoSignals.begin()).second.size() < 1025 || m_mSavedIoSignals.empty()) {
948 m_mSavedIoSignals["phi0"].push_back(m_mSignalStorage["phi0"].getInt());
949 for (unsigned iSt = 0; iSt < 4;
950 iSt++) m_mSavedIoSignals["phi_" + to_string(iSt)].push_back(m_mSignalStorage["phi_" + to_string(iSt)].getInt());
951 m_mSavedIoSignals["rho"].push_back(m_mSignalStorage["rho"].getInt());
952 for (unsigned iSt = 0; iSt < 4;
953 iSt++) m_mSavedIoSignals["iZError2_" + to_string(iSt)].push_back(m_mSignalStorage["iZError2_" + to_string(iSt)].getInt());
954 //m_mSavedIoSignals["charge"].push_back(m_mSignalStorage["charge"].getInt());
955 m_mSavedIoSignals["charge"].push_back(m_mSignalStorage["charge"].getInt());
956 m_mSavedIoSignals["z0"].push_back(m_mSignalStorage["z0"].getInt());
957 m_mSavedIoSignals["cot"].push_back(m_mSignalStorage["cot"].getInt());
958 m_mSavedIoSignals["chi2Sum"].push_back(m_mSignalStorage["chi2Sum"].getInt());
959 }
960 }
961
962
963 void TRGCDCFitter3D::getMCValues(const TRGCDC& m_cdc_in, TRGCDCTrack* aTrack, const std::map<std::string, double>& m_mConstD_in,
964 std::map<std::string, double>& m_mDouble_in, std::map<std::string, std::vector<double> >& m_mVector_in)
965 {
966 // Access to track's MC particle.
967 const TCRelation& trackRelation = aTrack->relation();
968 // Biggest contibutor is 0. Next is 1 and so on.
969 const MCParticle& trackMCParticle = trackRelation.mcParticle(0);
970
971 // Calculated impact position
972 ROOT::Math::XYZVector vertex = trackMCParticle.getVertex();
973 ROOT::Math::PxPyPzEVector vector4 = trackMCParticle.get4Vector();
974 ROOT::Math::XYVector helixCenter;
975 ROOT::Math::XYZVector impactPosition;
976 Fitter3DUtility::findImpactPosition(&vertex, &vector4, int(m_mDouble_in["mcCharge"]), helixCenter, impactPosition);
977 m_mVector_in["mcVertex"] = vector<double> ({vertex.X(), vertex.Y(), vertex.Z()});
978 m_mVector_in["mcMomentum"] = vector<double> ({vector4.Px(), vector4.Py(), vector4.Pz()});
979 m_mVector_in["helixCenter"] = vector<double> ({helixCenter.X(), helixCenter.Y()});
980 m_mVector_in["impactPosition"] = vector<double> ({impactPosition.X(), impactPosition.Y(), impactPosition.Z()});
981
982 // Access track's particle parameters
983 m_mDouble_in["mcPt"] = trackMCParticle.getMomentum().Rho();
984 m_mDouble_in["mcPhi0"] = 0;
985 if (trackMCParticle.getCharge() > 0) m_mDouble_in["mcPhi0"] = trackMCParticle.getMomentum().Phi() - m_mConstD_in.at("Trg_PI") / 2;
986 if (trackMCParticle.getCharge() < 0) m_mDouble_in["mcPhi0"] = trackMCParticle.getMomentum().Phi() + m_mConstD_in.at("Trg_PI") / 2;
987 // Change range to [0,2pi]
988 if (m_mDouble_in["mcPhi0"] < 0) m_mDouble_in["mcPhi0"] += 2 * m_mConstD_in.at("Trg_PI");
989 //m_mDouble["mcZ0"] = trackMCParticle.getVertex().Z();
990 m_mDouble_in["mcZ0"] = impactPosition.Z();
991 m_mDouble_in["mcCot"] = trackMCParticle.getMomentum().z() / trackMCParticle.getMomentum().Rho();
992 m_mDouble_in["mcCharge"] = trackMCParticle.getCharge();
993
994 // mcStatus[0]: statusbit, mcStatus[1]: pdg, mcStatus[2]: charge
995 TVectorD mcStatus(3);
996 m_mDouble_in["mcStatus"] = trackMCParticle.getStatus();
997 m_mDouble_in["pdgId"] = trackMCParticle.getPDG();
998
999 // Find position of track for each super layer
1000 //...G4 trackID...
1001 unsigned id = trackRelation.contributor(0);
1002 vector<const TCSHit*> mcAllTSList[9];
1003 vector<const TCSHit*> mcTSList(9);
1004 //...Segment loop...
1005 const vector<const TCSHit*> hits = m_cdc_in.segmentHits();
1006 for (unsigned i = 0; i < hits.size(); i++) {
1007 const TCSHit& ts = * hits[i];
1008 if (! ts.signal().active()) continue;
1009 const TCWHit* wh = ts.segment().center().hit();
1010 if (! wh) continue;
1011 const unsigned trackId = wh->iMCParticle();
1012 if (id == trackId)
1013 mcAllTSList[wh->wire().superLayerId()].push_back(& ts);
1014 }
1015 //...Select best one in each super layer...
1016 for (unsigned i = 0; i < 9; i++) {
1017 const TCSHit* best = 0;
1018 if (mcAllTSList[i].size() == 0) {
1019 } else if (mcAllTSList[i].size() == 1) {
1020 best = mcAllTSList[i][0];
1021 } else {
1022 int timeMin = 99999;
1023 for (unsigned k = 0; k < mcAllTSList[i].size(); k++) {
1024 const TRGSignal& timing = mcAllTSList[i][k]->signal();
1025 const TRGTime& t = * timing[0];
1026 if (t.time() < timeMin) {
1027 timeMin = t.time();
1028 best = mcAllTSList[i][k];
1029 }
1030 }
1031 }
1032 mcTSList[i] = best;
1033 }
1034
1035
1036 // Get mc track positions. Unit is cm.
1037 m_mVector_in["mcPosX"] = vector<double> ({9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999});
1038 m_mVector_in["mcPosY"] = vector<double> ({9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999});
1039 m_mVector_in["mcPosZ"] = vector<double> ({9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999});
1040 for (unsigned iSL = 0; iSL < 9; iSL++) {
1041 if (mcTSList[iSL] != 0) {
1042 ROOT::Math::XYZVector posTrack = mcTSList[iSL]->simHit()->getPosTrack();
1043 m_mVector_in["mcPosX"][iSL] = posTrack.X();
1044 m_mVector_in["mcPosY"][iSL] = posTrack.Y();
1045 m_mVector_in["mcPosZ"][iSL] = posTrack.Z();
1046 }
1047 }
1048 // Get mc LR
1049 m_mVector_in["simMcLR"] = vector<double> (9);
1050 for (unsigned iSL = 0; iSL < 9; iSL++) {
1051 if (mcTSList[iSL] != 0) {
1052 m_mVector_in["simMcLR"][iSL] = mcTSList[iSL]->simHit()->getPosFlag();
1053 }
1054 }
1055
1057 //for(unsigned iSL=0; iSL<9; iSL++){
1058 // if(mcTSList[iSL]!=0) {
1059 // TVectorD t_helixParameters;
1060 // TVector3 t_positionAtR;
1061 // TVector3 t_momentumAtR;
1062 // Fitter3DUtility::calHelixParameters(mcTSList[iSL]->simHit()->getPosIn(), mcTSList[iSL]->simHit()->getMomentum(),trackMCParticle.getCharge(),t_helixParameters);
1063 // //cout<<"dr: "<<helixParameters[0]<<" phi0: "<<helixParameters[1]<<" R: "<<1/helixParameters[2]/0.3/1.5*100<<" dz: "<<helixParameters[3]<<" tanLambda: "<<helixParameters[4]<<endl;
1064 // //calVectorsAtR(t_helixParameters, trackMCParticle.getCharge(), m_rr[iSL]*100, t_positionAtR, t_momentumAtR);
1065 // //cout<<" x: "<<t_positionAtR.X()<<" y: "<<t_positionAtR.Y()<<" z: "<<t_positionAtR.Z()<<endl;
1066 // //cout<<"Px: "<<t_momentumAtR.X()<<" Py: "<<t_momentumAtR.Y()<<" Pz: "<<t_momentumAtR.Z()<<endl;
1067 // }
1068 //}
1069 }
1070
1072 {
1073 bool trackFull = 1;
1074 for (unsigned iAx = 0; iAx < 5; iAx++) {
1075 // Check if all superlayers have one TS
1076 const vector<TCLink*>& links = aTrack.links(iAx * 2);
1077 const unsigned nSegments = links.size();
1078 // Find if there is a TS with a priority hit.
1079 // Loop over all TS in same superlayer.
1080 bool priorityHitTS = 0;
1081 for (unsigned iTS = 0; iTS < nSegments; iTS++) {
1082 const TCSegment* t_segment = dynamic_cast<const TCSegment*>(& links[iTS]->hit()->cell());
1083 if (t_segment->center().hit() != 0) priorityHitTS = 1;
1084 }
1085 if (nSegments != 1) {
1086 if (nSegments == 0) {
1087 trackFull = 0;
1088 if (m_mBool["fIsPrintError"]) cout << "Fitter3D::isAxialTrackFull() => There are no TS." << endl;
1089 } else {
1090 if (m_mBool["fIsPrintError"]) cout << "Fitter3D::isAxialTrackFull() => multiple TS are assigned." << endl;
1091 }
1092 } else {
1093 if (priorityHitTS == 0) {
1094 trackFull = 0;
1095 if (m_mBool["fIsPrintError"]) cout << "Fitter3D::isAxialTrackFull() => There are no priority hit TS" << endl;
1096 }
1097 }
1098 } // End superlayer loop
1099 return trackFull;
1100 }
1101
1103 {
1104 bool trackFull = 1;
1105 for (unsigned iSt = 0; iSt < 4; iSt++) {
1106 // Check if all superlayers have one TS
1107 const vector<TCLink*>& links = aTrack.links(iSt * 2 + 1);
1108 const unsigned nSegments = links.size();
1109 // Find if there is a TS with a priority hit.
1110 // Loop over all TS in same superlayer.
1111 bool priorityHitTS = 0;
1112 for (unsigned iTS = 0; iTS < nSegments; iTS++) {
1113 const TCSegment* t_segment = dynamic_cast<const TCSegment*>(& links[iTS]->hit()->cell());
1114 if (t_segment->center().hit() != 0) priorityHitTS = 1;
1115 }
1116 if (nSegments != 1) {
1117 if (nSegments == 0) {
1118 trackFull = 0;
1119 if (m_mBool["fIsPrintError"]) cout << "Fitter3D::isStereoTrackFull() => There are no TS." << endl;
1120 } else {
1121 if (m_mBool["fIsPrintError"]) cout << "Fitter3D::isStereoTrackFull() => multiple TS are assigned." << endl;
1122 }
1123 } else {
1124 if (priorityHitTS == 0) {
1125 trackFull = 0;
1126 if (m_mBool["fIsPrintError"]) cout << "Fitter3D::isStereoTrackFull() => There are no priority hit TS" << endl;
1127 }
1128 }
1129 } // End superlayer loop
1130 return trackFull;
1131 }
1132
1133 void TRGCDCFitter3D::findHitAxialSuperlayers(const TRGCDCTrack& aTrack, vector<double>& useAxSl, bool printError)
1134 {
1135 useAxSl.assign(5, 1);
1136 for (unsigned iAx = 0; iAx < 5; iAx++) {
1137 // Check if all superlayers have one TS
1138 const vector<TCLink*>& links = aTrack.links(iAx * 2);
1139 const unsigned nSegments = links.size();
1140 // Find if there is a TS with a priority hit.
1141 // Loop over all TS in same superlayer.
1142 bool priorityHitTS = 0;
1143 //cout<<"iAx:"<<iAx<<" nSegments:"<<nSegments<<endl;
1144 for (unsigned iTS = 0; iTS < nSegments; iTS++) {
1145 const TCSegment* t_segment = dynamic_cast<const TCSegment*>(& links[iTS]->hit()->cell());
1146 if (t_segment->center().hit() != 0) priorityHitTS = 1;
1147 //cout<<" iTS:"<<iTS<<" priority:"<<t_segment->center().hit()<<" tsId:"<<t_segment->localId()<<endl;
1148 }
1149 if (nSegments != 1) {
1150 if (nSegments == 0) {
1151 useAxSl[iAx] = 0;
1152 } else {
1153 if (printError) cout << "Fitter3D::findHitAxialSuperlayers() => multiple TS are assigned." << endl;
1154 }
1155 } else {
1156 if (priorityHitTS == 0) {
1157 useAxSl[iAx] = 0;
1158 if (printError) cout << "Fitter3D::findHitAxialSuperlayers() => There are no priority hit TS" << endl;
1159 }
1160 }
1161 } // End superlayer loop
1162 }
1163
1164 void TRGCDCFitter3D::findHitStereoSuperlayers(const TRGCDCTrack& aTrack, vector<double>& useStSl, bool printError)
1165 {
1166 useStSl.assign(4, 1);
1167 for (unsigned iSt = 0; iSt < 4; iSt++) {
1168 // Check if all superlayers have one TS
1169 const vector<TCLink*>& links = aTrack.links(iSt * 2 + 1);
1170 const unsigned nSegments = links.size();
1171 // Find if there is a TS with a priority hit.
1172 // Loop over all TS in same superlayer.
1173 bool priorityHitTS = 0;
1174 for (unsigned iTS = 0; iTS < nSegments; iTS++) {
1175 const TCSegment* t_segment = dynamic_cast<const TCSegment*>(& links[iTS]->hit()->cell());
1176 if (t_segment->center().hit() != 0) priorityHitTS = 1;
1177 }
1178 if (nSegments != 1) {
1179 if (nSegments == 0) {
1180 useStSl[iSt] = 0;
1181 } else {
1182 if (printError) cout << "Fitter3D::findHitStereoSuperlayers() => multiple TS are assigned." << endl;
1183 }
1184 } else {
1185 if (priorityHitTS == 0) {
1186 useStSl[iSt] = 0;
1187 if (printError) cout << "Fitter3D::findHitStereoSuperlayers() => There are no priority hit TS" << endl;
1188 }
1189 }
1190 } // End superlayer loop
1191 }
1192
1194 {
1195 for (unsigned iSt = 0; iSt < 4; iSt++) {
1196 // Check if rho is large enough for stereo super layer.
1197 if (2 * m_mDouble["rho"] < m_mConstV["rr3D"][iSt]) {
1198 useStSl[iSt] = 0;
1199 if (m_mBool["fIsPrintError"]) cout << "Fitter3D::removeImpossibleStereoSuperlayers() => pt is too low for SL." << endl;
1200 }
1201 } // End superlayer loop
1202 }
1203
1204 void TRGCDCFitter3D::selectAxialTSs(const TRGCDCTrack& aTrack, vector<int>& bestTSIndex)
1205 {
1206 bestTSIndex.resize(5);
1207 std::fill_n(bestTSIndex.begin(), 5, -1);
1208 for (unsigned iAx = 0; iAx < 5; iAx++) {
1209 // Check if all superlayers have one TS
1210 const vector<TCLink*>& links = aTrack.links(iAx * 2);
1211 const unsigned nSegments = links.size();
1212 //cout<<"iAx:"<<iAx<<" nSegments:"<<nSegments<<endl;
1213 // tsCandiateInfo[iTS] = 1st priority, tdc
1214 vector<tuple<int, double> > tsCandiateInfo(nSegments);
1215 // Get information from candidates.
1216 for (unsigned iTS = 0; iTS < nSegments; iTS++) {
1217 const TCSegment* t_segment = dynamic_cast<const TCSegment*>(& links[iTS]->hit()->cell());
1218 int firstPriority = 0;
1219 if (t_segment->center().hit() != 0) firstPriority = 1;
1220 double tdc = t_segment->priorityTime();
1221 std::get<0>(tsCandiateInfo[iTS]) = firstPriority;
1222 std::get<1>(tsCandiateInfo[iTS]) = tdc;
1223 //cout<<"Ax:"<<iAx<<" iTS:"<<iTS<<" firstPriority:"<<firstPriority<<" tdc:"<<tdc<<endl;
1224 }
1225 // Select best candidate.
1226 // bestTS => tsIndex, { 1st priority, tdc }
1227 pair<int, tuple<int, double> > bestTS = make_pair(-1, make_tuple(-1, 9999));
1228 // If there is a candidate.
1229 if (tsCandiateInfo.size() != 0) {
1231 //if (std::get<0>(tsCandiateInfo[0]) == 1) {
1232 // bestTS.first = 0;
1233 // bestTS.second = tsCandiateInfo[0];
1234 //}
1236 //int randomIndex = gRandom->Integer(nSegments);
1237 //if (std::get<0>(tsCandiateInfo[randomIndex]) == 1) {
1238 // bestTS.first = randomIndex;
1239 // bestTS.second = tsCandiateInfo[randomIndex];
1240 //}
1241 // Selection type 1st priority.
1242 for (unsigned iTS = 0; iTS < nSegments; iTS++) {
1243 if (std::get<0>(tsCandiateInfo[iTS]) == 1) {
1244 bool select = 0;
1245 if (bestTS.first == -1) select = 1;
1246 else if (std::get<1>(bestTS.second) > std::get<1>(tsCandiateInfo[iTS])) select = 1;
1247 if (select) {
1248 bestTS.first = iTS;
1249 bestTS.second = tsCandiateInfo[iTS];
1250 }
1251 }
1252 }
1253 }
1254 //cout<<"Ax:"<<iAx<<" best: iTS:"<<bestTS.first<<" firstPriority:"<<std::get<0>(bestTS.second)<<" tdc:"<<std::get<1>(bestTS.second)<<endl;
1255 bestTSIndex[iAx] = bestTS.first;
1256 } // End superlayer loop
1257 }
1258
1259 int TRGCDCFitter3D::do2DFit(TRGCDCTrack& aTrack, const std::map<std::string, bool>& m_mBool_in,
1260 const std::map<std::string, double>& m_mConstD_in,
1261 std::map<std::string, std::vector<double> >& m_mConstV_in, std::map<std::string, double>& m_mDouble_in,
1262 std::map<std::string, std::vector<double> >& m_mVector_in)
1263 {
1264 m_mVector_in["useAxSl"] = vector<double> (5);
1265 //findHitAxialSuperlayers(aTrack, useAxSl, m_mBool_in["fIsPrintError"]);
1266
1267 // Find best TS between links for each SL.
1268 vector<int> bestTSIndex(5);
1269 selectAxialTSs(aTrack, bestTSIndex);
1270 for (unsigned iAx = 0; iAx < 5; iAx++) {
1271 if (bestTSIndex[iAx] != -1) m_mVector_in["useAxSl"][iAx] = 1;
1272 //cout<<"useAxSl["<<iAx<<"]:"<<useAxSl[iAx]<<endl;
1273 }
1274
1275 // Check if number of axial super layer hits is smaller or equal to 1.
1276 m_mDouble_in["nHitAx"] = m_mVector_in["useAxSl"][0] + m_mVector_in["useAxSl"][1] + m_mVector_in["useAxSl"][2] +
1277 m_mVector_in["useAxSl"][3] +
1278 m_mVector_in["useAxSl"][4];
1279 if (m_mDouble_in["nHitAx"] <= 1) {
1280 if (m_mBool_in.at("fVerbose") == 1) cout << "[2DFit] Exiting because nHitAx is " << m_mDouble_in["nHitAx"] << endl;
1281 aTrack.setFitted(0);
1282 return 1;
1283 }
1284
1285 // Fill information for axial layers
1286 m_mVector_in["tsId"] = vector<double> (9);
1287 m_mVector_in["tsId2D"] = vector<double> (5);
1288 m_mVector_in["wirePhi"] = vector<double> (9);
1289 m_mVector_in["lutLR"] = vector<double> (9);
1290 m_mVector_in["LR"] = vector<double> (9);
1291 m_mVector_in["driftLength"] = vector<double> (9);
1292 m_mVector_in["tdc"] = vector<double> (9);
1293 if (!m_mVector_in.count("mcLR")) m_mVector_in["mcLR"] = vector<double> (9);
1294 for (unsigned iAx = 0; iAx < 5; iAx++) {
1295 if (m_mVector_in["useAxSl"][iAx] == 1) {
1296 const vector<TCLink*>& links = aTrack.links(iAx * 2);
1297 //const TCSegment * t_segment = dynamic_cast<const TCSegment *>(& links[0]->hit()->cell());
1298 const TCSegment* t_segment = dynamic_cast<const TCSegment*>(& links[bestTSIndex[iAx]]->hit()->cell());
1299 m_mVector_in["tsId"][iAx * 2] = t_segment->localId();
1300 m_mVector_in["tsId2D"][iAx] = m_mVector_in["tsId"][iAx * 2];
1301 m_mVector_in["wirePhi"][iAx * 2] = (double) t_segment->localId() / m_mConstV_in["nWires"][iAx * 2] * 4 * m_mConstD_in.at("Trg_PI");
1302 m_mVector_in["lutLR"][iAx * 2] = t_segment->LUT()->getValue(t_segment->lutPattern());
1303 // mcLR should be removed.
1304 if (m_mBool_in.at("fMc")) m_mVector_in["mcLR"][iAx * 2] = t_segment->hit()->mcLR() + 1;
1305 m_mVector_in["driftLength"][iAx * 2] = t_segment->hit()->drift();
1306 m_mVector_in["tdc"][iAx * 2] = t_segment->priorityTime();
1307 if (m_mBool_in.at("fmcLR") == 1) m_mVector_in["LR"][iAx * 2] = m_mVector_in["mcLR"][iAx * 2];
1308 else if (m_mBool_in.at("fLRLUT") == 1) m_mVector_in["LR"][iAx * 2] = m_mVector_in["lutLR"][iAx * 2];
1309 else m_mVector_in["LR"][iAx * 2] = 3;
1310 } else {
1311 m_mVector_in["tsId"][iAx * 2] = 9999;
1312 m_mVector_in["wirePhi"][iAx * 2] = 9999;
1313 m_mVector_in["lutLR"][iAx * 2] = 0;
1314 // mcLR should be removed.
1315 if (m_mBool_in.at("fMc")) m_mVector_in["mcLR"][iAx * 2] = 9999;
1316 m_mVector_in["driftLength"][iAx * 2] = 9999;
1317 m_mVector_in["tdc"][iAx * 2] = 9999;
1318 if (m_mBool_in.at("fmcLR") == 1) m_mVector_in["LR"][iAx * 2] = 9999;
1319 else if (m_mBool_in.at("fLRLUT") == 1) m_mVector_in["LR"][iAx * 2] = 9999;
1320 else m_mVector_in["LR"][iAx * 2] = 9999;
1321 }
1322 } // End superlayer loop
1324 //int minTSTdc = 9999;
1325 //for(unsigned iAx=0; iAx<9; iAx++){
1326 // if (minTSTdc > m_mVector_in["tdc"][2*iAx]) minTSTdc = m_mVector_in["tdc"][2*iAx];
1327 //}
1328 //m_mDouble_in["eventTime"] = minTSTdc;
1329
1331 // Get 2D fit values
1332 // Get 2D fit values from IW 2D fitter
1333 m_mDouble_in["phi02D"] = aTrack.helix().phi0();
1334 m_mDouble_in["pt2D"] = aTrack.pt();
1335 if (aTrack.charge() < 0) {
1336 m_mDouble_in["phi02D"] -= m_mConstD_in.at("Trg_PI");
1337 if (m_mDouble_in["phi02D"] < 0) m_mDouble_in["phi02D"] += 2 * m_mConstD_in.at("Trg_PI");
1338 }
1339 m_mDouble_in["dr2D"] = aTrack.helix().dr() * 0.01;
1340 // Get 2D fit values from JB 2D fitter
1341 // Currently using JB fitter for 3D fitting
1342 m_mDouble_in["charge"] = double(aTrack.charge());
1343 // Set phi2DError for 2D fit
1344 m_mVector_in["phi2DError"] = vector<double> (5);
1345 for (unsigned iAx = 0; iAx < 5; iAx++) {
1346 if (m_mVector_in["useAxSl"][iAx] == 1) {
1347 // Check LR.
1348 if (m_mVector_in["LR"][2 * iAx] != 3) m_mVector_in["phi2DError"][iAx] = m_mConstV_in["driftPhi2DError"][iAx];
1349 else m_mVector_in["phi2DError"][iAx] = m_mConstV_in["wirePhi2DError"][iAx];
1350 // Check event time.
1351 if (m_mDouble_in["eventTime"] == 9999) m_mVector_in["phi2DError"][iAx] = m_mConstV_in["wirePhi2DError"][iAx];
1352 } else {
1353 m_mVector_in["phi2DError"][iAx] = 9999;
1354 }
1355 }
1356 // Set invPhi2DError for 2D fit
1357 m_mVector_in["phi2DInvError"] = vector<double> (5);
1358 for (unsigned iAx = 0; iAx < 5; iAx++) {
1359 if (m_mVector_in["useAxSl"][iAx] == 1) {
1360 m_mVector_in["phi2DInvError"][iAx] = 1 / m_mVector_in["phi2DError"][iAx];
1361 } else {
1362 m_mVector_in["phi2DInvError"][iAx] = 0;
1363 }
1364 }
1365 // Calculate phi2D.
1366 m_mVector_in["phi2D"] = vector<double> (5);
1367 if (m_mBool_in.at("f2DFitDrift") == 0 || m_mDouble_in["eventTime"] == 9999) {
1368 for (unsigned iAx = 0; iAx < 5; iAx++) {
1369 m_mVector_in["phi2D"][iAx] = m_mVector_in["wirePhi"][iAx * 2];
1370 }
1371 } else {
1372 for (unsigned iAx = 0; iAx < 5; iAx++) {
1373 if (m_mVector_in["useAxSl"][iAx] == 1) {
1374 // Get drift length from table.
1375 string tableName = "driftLengthTableSL" + to_string(iAx * 2);
1376 double t_driftTime = m_mVector_in["tdc"][iAx * 2] - m_mDouble_in["eventTime"];
1377 if (t_driftTime < 0) t_driftTime = 0;
1378 if (t_driftTime > 511) t_driftTime = 511;
1379 double t_driftLength = m_mConstV_in[tableName][(unsigned)t_driftTime];
1380 m_mVector_in["phi2D"][iAx] = Fitter3DUtility::calPhi(m_mVector_in["wirePhi"][iAx * 2], t_driftLength, m_mConstV_in["rr"][iAx * 2],
1381 m_mVector_in["LR"][iAx * 2]);
1382 } else {
1383 m_mVector_in["phi2D"][iAx] = 9999;
1384 }
1385 }
1386 }
1387 // Fit2D
1388 if (m_mBool_in.at("f2DFit") == 0) {
1389 m_mDouble_in["rho"] = m_mDouble_in["pt2D"] / 0.01 / 1.5 / 0.299792458;
1390 m_mDouble_in["pt"] = 0.299792458 * 1.5 * m_mDouble_in["rho"] / 100;
1391 m_mDouble_in["phi0"] = m_mDouble_in["phi02D"];
1392 m_mDouble_in["fit2DChi2"] = 9999;
1393 } else {
1394 m_mDouble_in["rho"] = 0;
1395 m_mDouble_in["phi0"] = 0;
1396 m_mDouble_in["fit2DChi2"] = 0;
1397 Fitter3DUtility::rPhiFitter(&m_mConstV_in["rr2D"][0], &m_mVector_in["phi2D"][0], &m_mVector_in["phi2DInvError"][0],
1398 m_mDouble_in["rho"],
1399 m_mDouble_in["phi0"], m_mDouble_in["fit2DChi2"]);
1400 m_mDouble_in["pt"] = 0.3 * 1.5 * m_mDouble_in["rho"] / 100;
1401 }
1402
1403 // Find charge of particle.
1404 Fitter3DUtility::chargeFinder(&m_mConstV_in["nTSs2D"][0], &m_mVector_in["tsId2D"][0], &m_mVector_in["useAxSl"][0],
1405 m_mDouble_in["phi0"],
1406 m_mDouble_in["charge"], m_mDouble_in["charge2D"]);
1407
1408 if (m_mBool_in.at("fVerbose")) {
1409 cout << "[E" << int(m_mDouble_in["eventNumber"]) << "][T" << int(m_mDouble_in["trackId"]) << "]f2DFit: " <<
1410 m_mBool_in.at("f2DFit") <<
1411 endl;
1412 cout << "[E" << int(m_mDouble_in["eventNumber"]) << "][T" << int(m_mDouble_in["trackId"]) << "]evtTime: " <<
1413 m_mDouble_in["eventTime"]
1414 << endl;
1415 cout << "[E" << int(m_mDouble_in["eventNumber"]) << "][T" << int(m_mDouble_in["trackId"]) << "]wirePhi: " <<
1416 m_mVector_in["wirePhi"][0]
1417 << " " << m_mVector_in["wirePhi"][1] << " " << m_mVector_in["wirePhi"][2] << " " << m_mVector_in["wirePhi"][3] << " " <<
1418 m_mVector_in["wirePhi"][4] << " " << m_mVector_in["wirePhi"][5] << " " << m_mVector_in["wirePhi"][6] << " " <<
1419 m_mVector_in["wirePhi"][7] << " "
1420 << m_mVector_in["wirePhi"][8] << endl;
1421 cout << "[E" << int(m_mDouble_in["eventNumber"]) << "][T" << int(m_mDouble_in["trackId"]) << "]LR: " << int(
1422 m_mVector_in["LR"][0]) << " " << int(m_mVector_in["LR"][1]) << " " << int(m_mVector_in["LR"][2]) << " " << int(
1423 m_mVector_in["LR"][3]) << " " << int(m_mVector_in["LR"][4]) << " " << int(m_mVector_in["LR"][5]) << " " << int(
1424 m_mVector_in["LR"][6]) << " " << int(m_mVector_in["LR"][7]) << " " << int(m_mVector_in["LR"][8]) << endl;
1425 cout << "[E" << int(m_mDouble_in["eventNumber"]) << "][T" << int(m_mDouble_in["trackId"]) << "]drift: " <<
1426 m_mVector_in["driftLength"][0] << " " << m_mVector_in["driftLength"][1] << " " << m_mVector_in["driftLength"][2] << " " <<
1427 m_mVector_in["driftLength"][3] << " " << m_mVector_in["driftLength"][4] << " " << m_mVector_in["driftLength"][5] << " " <<
1428 m_mVector_in["driftLength"][6] << " " << m_mVector_in["driftLength"][7] << " " << m_mVector_in["driftLength"][8] << endl;
1429 cout << "[E" << int(m_mDouble_in["eventNumber"]) << "][T" << int(m_mDouble_in["trackId"]) << "]tdc: " <<
1430 m_mVector_in["tdc"][0] <<
1431 " " << m_mVector_in["tdc"][1] << " " << m_mVector_in["tdc"][2] << " " << m_mVector_in["tdc"][3] << " " << m_mVector_in["tdc"][4] <<
1432 " " <<
1433 m_mVector_in["tdc"][5] << " " << m_mVector_in["tdc"][6] << " " << m_mVector_in["tdc"][7] << " " << m_mVector_in["tdc"][8] << endl;
1434 cout << "[E" << int(m_mDouble_in["eventNumber"]) << "][T" << int(m_mDouble_in["trackId"]) << "]rr2D: " <<
1435 m_mConstV_in["rr2D"][0] <<
1436 " " << m_mConstV_in["rr2D"][1] << " " << m_mConstV_in["rr2D"][2] << " " << m_mConstV_in["rr2D"][3] << " " << m_mConstV_in["rr2D"][4]
1437 << endl;
1438 cout << "[E" << int(m_mDouble_in["eventNumber"]) << "][T" << int(m_mDouble_in["trackId"]) << "]Phi2D: " <<
1439 m_mVector_in["phi2D"][0]
1440 << " " << m_mVector_in["phi2D"][1] << " " << m_mVector_in["phi2D"][2] << " " << m_mVector_in["phi2D"][3] << " " <<
1441 m_mVector_in["phi2D"][4] <<
1442 endl;
1443 cout << "[E" << int(m_mDouble_in["eventNumber"]) << "][T" << int(m_mDouble_in["trackId"]) << "]Phi2DInvError: " <<
1444 m_mVector_in["phi2DInvError"][0] << " " << m_mVector_in["phi2DInvError"][1] << " " << m_mVector_in["phi2DInvError"][2] << " " <<
1445 m_mVector_in["phi2DInvError"][3] << " " << m_mVector_in["phi2DInvError"][4] << endl;
1446 cout << "[E" << int(m_mDouble_in["eventNumber"]) << "][T" << int(m_mDouble_in["trackId"]) << "]charge: " << int(
1447 m_mDouble_in["charge"]) << endl;
1448 cout << "[E" << int(m_mDouble_in["eventNumber"]) << "][T" << int(m_mDouble_in["trackId"]) << "]charge2D: " << int(
1449 m_mDouble_in["charge2D"]) << endl;
1450 cout << "[E" << int(m_mDouble_in["eventNumber"]) << "][T" << int(m_mDouble_in["trackId"]) << "]pt: " <<
1451 m_mDouble_in["pt"] <<
1452 endl;
1453 cout << "[E" << int(m_mDouble_in["eventNumber"]) << "][T" << int(m_mDouble_in["trackId"]) << "]rho: " <<
1454 m_mDouble_in["rho"] <<
1455 endl;
1456 cout << "[E" << int(m_mDouble_in["eventNumber"]) << "][T" << int(m_mDouble_in["trackId"]) << "]phi0: " <<
1457 m_mDouble_in["phi0"] <<
1458 " " << m_mDouble_in["phi0"] / m_mConstD_in.at("Trg_PI") * 180 << endl;
1459 cout << "[E" << int(m_mDouble_in["eventNumber"]) << "][T" << int(m_mDouble_in["trackId"]) << "]fit2DChi2: " <<
1460 m_mDouble_in["fit2DChi2"]
1461 << endl;
1462 cout << "[E" << int(m_mDouble_in["eventNumber"]) << "][T" << int(m_mDouble_in["trackId"]) << "]useAxSl: " << int(
1463 m_mVector_in["useAxSl"][0]) << " " << int(m_mVector_in["useAxSl"][1]) << " " << int(m_mVector_in["useAxSl"][2]) << " " << int(
1464 m_mVector_in["useAxSl"][3]) << endl;
1465 }
1466
1467 if (std::isnan(m_mDouble_in["rho"]) || std::isnan(m_mDouble_in["phi0"])) {
1468 if (m_mBool_in.at("fVerbose") == 1) cout << "[2Dfit] Exiting because rho or phi0 is nan." << endl;
1469 return 2;
1470 }
1471 return 0;
1472 }
1473
1475 {
1476 cout << "[E" << int(m_mDouble["eventNumber"]) << "][T" << iTrack << "]evtTime: " << m_mDouble["eventTime"] << endl;
1477 cout << "[E" << int(m_mDouble["eventNumber"]) << "][T" << iTrack << "]wirePhi: " << m_mVector["wirePhi"][0] << " " <<
1478 m_mVector["wirePhi"][1] << " " << m_mVector["wirePhi"][2] << " " << m_mVector["wirePhi"][3] << " " << m_mVector["wirePhi"][4] << " "
1479 << m_mVector["wirePhi"][5] << " " << m_mVector["wirePhi"][6] << " " << m_mVector["wirePhi"][7] << " " << m_mVector["wirePhi"][8] <<
1480 endl;
1481 cout << "[E" << int(m_mDouble["eventNumber"]) << "][T" << iTrack << "]LR: " << int(m_mVector["LR"][0]) << " " << int(
1482 m_mVector["LR"][1]) << " " << int(m_mVector["LR"][2]) << " " << int(m_mVector["LR"][3]) << " " << int(
1483 m_mVector["LR"][4]) << " " << int(m_mVector["LR"][5]) << " " << int(m_mVector["LR"][6]) << " " << int(
1484 m_mVector["LR"][7]) << " " << int(m_mVector["LR"][8]) << endl;
1485 cout << "[E" << int(m_mDouble["eventNumber"]) << "][T" << iTrack << "]lutLR: " << int(m_mVector["lutLR"][0]) << " " << int(
1486 m_mVector["lutLR"][1]) << " " << int(m_mVector["lutLR"][2]) << " " << int(m_mVector["lutLR"][3]) << " " << int(
1487 m_mVector["lutLR"][4]) << " " << int(m_mVector["lutLR"][5]) << " " << int(m_mVector["lutLR"][6]) << " " << int(
1488 m_mVector["lutLR"][7]) << " " << int(m_mVector["lutLR"][8]) << endl;
1489 cout << "[E" << int(m_mDouble["eventNumber"]) << "][T" << iTrack << "]useStSl: " << int(m_mVector["useStSl"][0]) << " " << int(
1490 m_mVector["useStSl"][1]) << " " << int(m_mVector["useStSl"][2]) << " " << int(m_mVector["useStSl"][3]) << endl;
1491 cout << "[E" << int(m_mDouble["eventNumber"]) << "][T" << iTrack << "]drift: " << m_mVector["driftLength"][0] << " " <<
1492 m_mVector["driftLength"][1] << " " << m_mVector["driftLength"][2] << " " << m_mVector["driftLength"][3] << " " <<
1493 m_mVector["driftLength"][4] << " " << m_mVector["driftLength"][5] << " " << m_mVector["driftLength"][6] << " " <<
1494 m_mVector["driftLength"][7] << " " << m_mVector["driftLength"][8] << endl;
1495 cout << "[E" << int(m_mDouble["eventNumber"]) << "][T" << iTrack << "]tdc: " << m_mVector["tdc"][0] << " " <<
1496 m_mVector["tdc"][1] << " " << m_mVector["tdc"][2] << " " << m_mVector["tdc"][3] << " " << m_mVector["tdc"][4] << " " <<
1497 m_mVector["tdc"][5] << " " << m_mVector["tdc"][6] << " " << m_mVector["tdc"][7] << " " << m_mVector["tdc"][8] << endl;
1498 cout << "[E" << int(m_mDouble["eventNumber"]) << "][T" << iTrack << "]Phi2D: " << m_mVector["phi2D"][0] << " " <<
1499 m_mVector["phi2D"][1] << " " << m_mVector["phi2D"][2] << " " << m_mVector["phi2D"][3] << " " << m_mVector["phi2D"][4] << endl;
1500 cout << "[E" << int(m_mDouble["eventNumber"]) << "][T" << iTrack << "]Phi3D: " << m_mVector["phi3D"][0] << " " <<
1501 m_mVector["phi3D"][1] << " " << m_mVector["phi3D"][2] << " " << m_mVector["phi3D"][3] << endl;
1502 cout << "[E" << int(m_mDouble["eventNumber"]) << "][T" << iTrack << "]zz: " << m_mVector["zz"][0] << " " << m_mVector["zz"][1]
1503 << " " << m_mVector["zz"][2] << " " << m_mVector["zz"][3] << endl;
1504 cout << "[E" << int(m_mDouble["eventNumber"]) << "][T" << iTrack << "]arcS: " << m_mVector["arcS"][0] << " " <<
1505 m_mVector["arcS"][1] << " " << m_mVector["arcS"][2] << " " << m_mVector["arcS"][3] << endl;
1506 cout << "[E" << int(m_mDouble["eventNumber"]) << "][T" << iTrack << "]zerror: " << m_mVector["zError"][0] << " " <<
1507 m_mVector["zError"][1] << " " << m_mVector["zError"][2] << " " << m_mVector["zError"][3] << endl;
1508 cout << "[E" << int(m_mDouble["eventNumber"]) << "][T" << iTrack << "]izerror: " << m_mVector["iZError2"][0] << " " <<
1509 m_mVector["iZError2"][1] << " " << m_mVector["iZError2"][2] << " " << m_mVector["iZError2"][3] << endl;
1510 cout << "[E" << int(m_mDouble["eventNumber"]) << "][T" << iTrack << "]charge: " << int(m_mDouble["charge"]) << endl;
1511 cout << "[E" << int(m_mDouble["eventNumber"]) << "][T" << iTrack << "]pt: " << m_mDouble["pt"] << endl;
1512 cout << "[E" << int(m_mDouble["eventNumber"]) << "][T" << iTrack << "]phi0: " << m_mDouble["phi0"] << endl;
1513 cout << "[E" << int(m_mDouble["eventNumber"]) << "][T" << iTrack << "]z0: " << m_mDouble["z0"] << endl;
1514 cout << "[E" << int(m_mDouble["eventNumber"]) << "][T" << iTrack << "]cot: " << m_mDouble["cot"] << endl;
1515 cout << "[E" << int(m_mDouble["eventNumber"]) << "][T" << iTrack << "]chi2: " << m_mDouble["zChi2"] << endl;
1516 if (m_mBool["fMc"]) {
1517 cout << "[E" << int(m_mDouble["eventNumber"]) << "][T" << iTrack << "]mcCharge: " << int(m_mDouble["mcCharge"]) << endl;
1518 cout << "[E" << int(m_mDouble["eventNumber"]) << "][T" << iTrack << "]mcPosZ: " << m_mVector["mcPosZ"][1] << " " <<
1519 m_mVector["mcPosZ"][3] << " " << m_mVector["mcPosZ"][5] << " " << m_mVector["mcPosZ"][7] << endl;
1520 cout << "[E" << int(m_mDouble["eventNumber"]) << "][T" << iTrack << "]mcPosZ: " << m_mVector["mcPosZ"][1] << " " <<
1521 m_mVector["mcPosZ"][3] << " " << m_mVector["mcPosZ"][5] << " " << m_mVector["mcPosZ"][7] << endl;
1522 cout << "[E" << int(m_mDouble["eventNumber"]) << "][T" << iTrack << "]mcLR: " << int(m_mVector["mcLR"][0]) << " " << int(
1523 m_mVector["mcLR"][1]) << " " << int(m_mVector["mcLR"][2]) << " " << int(m_mVector["mcLR"][3]) << " " << int(
1524 m_mVector["mcLR"][4]) << " " << int(m_mVector["mcLR"][5]) << " " << int(m_mVector["mcLR"][6]) << " " << int(
1525 m_mVector["mcLR"][7]) << " " << int(m_mVector["mcLR"][8]) << endl;
1526 }
1527 }
1528
1529
1531 {
1532 if (m_mBool["fRootFile"]) {
1533 HandleRoot::writeRoot(m_fileFitter3D);
1534 HandleRoot::terminateRoot(m_mTVectorD, m_mTClonesArray);
1535 delete m_fileFitter3D;
1536 }
1537
1538 if (m_mBool["fVHDLFile"]) {
1539 //if(m_mSavedIoSignals.size()!=0) FpgaUtility::multipleWriteCoe(10, m_mSavedIoSignals, "./VHDL/LutData/Io/");
1540 //if(m_mSavedSignals.size()!=0) FpgaUtility::writeSignals("./VHDL/signals",m_mSavedSignals);
1542 if (m_mSavedSignals.size() != 0) FpgaUtility::writeSignals("signalValues", m_mSavedSignals);
1543 }
1544
1545 if (m_commonData) delete m_commonData;
1546 }
1547
1548 string TRGCDCFitter3D::version(void) const
1549 {
1550 return string("TRGCDCFitter3D 6.0");
1551 }
1552
1553 std::string TRGCDCFitter3D::name(void) const
1554 {
1555 return m_name;
1556 }
1557
1558 void TRGCDCFitter3D::getStereoGeometry(map<string, vector<double> >& stGeometry)
1559 {
1560 stGeometry["priorityLayer"] = {10, 22, 34, 46};
1561 stGeometry["nWires"] = vector<double> (4);
1562 stGeometry["cdcRadius"] = vector<double> (4);
1563 stGeometry["zToStraw"] = vector<double> (4);
1564 stGeometry["nShift"] = vector<double> (4);
1565 stGeometry["angleSt"] = vector<double> (4);
1567 for (int iSt = 0; iSt < 4; ++iSt) {
1568 stGeometry["nWires"][iSt] = cdc.nWiresInLayer(stGeometry["priorityLayer"][iSt]) * 2;
1569 stGeometry["cdcRadius"][iSt] = cdc.senseWireR(stGeometry["priorityLayer"][iSt]);
1570 stGeometry["zToStraw"][iSt] = cdc.senseWireBZ(stGeometry["priorityLayer"][iSt]);
1571 stGeometry["nShift"][iSt] = cdc.nShifts(stGeometry["priorityLayer"][iSt]);
1572 stGeometry["angleSt"][iSt] = 2 * stGeometry["cdcRadius"][iSt] * sin(M_PI * stGeometry["nShift"][iSt] /
1573 (stGeometry["nWires"][iSt])) /
1574 (cdc.senseWireFZ(stGeometry["priorityLayer"][iSt]) - stGeometry["zToStraw"][iSt]);
1575 }
1576 }
1577
1578 void TRGCDCFitter3D::getStereoXt(vector<double> const& stPriorityLayer, vector<vector<double> >& stXts, bool isSimple)
1579 {
1580 stXts.resize(stPriorityLayer.size(), vector<double> (512));
1582 for (unsigned iSt = 0; iSt < stPriorityLayer.size(); ++iSt) {
1583 for (unsigned iTick = 0; iTick < stXts[iSt].size(); ++iTick) {
1584 double t = iTick * 2 * cdc.getTdcBinWidth();
1585 if (isSimple) {
1586 stXts[iSt][iTick] = cdc.getNominalDriftV() * t;
1587 } else {
1588 double driftLength_0 = cdc.getDriftLength(t, stPriorityLayer[iSt], 0);
1589 double driftLength_1 = cdc.getDriftLength(t, stPriorityLayer[iSt], 1);
1590 stXts[iSt][iTick] = (driftLength_0 + driftLength_1) / 2;
1591 }
1592 }
1593 }
1594 }
1595
1596 void TRGCDCFitter3D::getConstants(std::map<std::string, double>& mConstD, std::map<std::string, std::vector<double> >& mConstV,
1597 bool isXtSimple)
1598 {
1600 mConstD["Trg_PI"] = M_PI;
1601 mConstV["priorityLayer"] = {3, 10, 16, 22, 28, 34, 40, 46, 52};
1602 mConstV["rr"] = vector<double> (9);
1603 mConstV["nWires"] = vector<double> (9);
1604 mConstV["nTSs"] = vector<double> (9);
1605 for (unsigned iSL = 0; iSL < 9; iSL++) {
1606 unsigned t_layerId = mConstV["priorityLayer"][iSL];
1607 mConstV["rr"][iSL] = cdc.senseWireR(t_layerId);
1608 mConstV["nWires"][iSL] = cdc.nWiresInLayer(t_layerId) * 2;
1609 mConstV["nTSs"][iSL] = cdc.nWiresInLayer(t_layerId);
1610 }
1611 mConstV["nTSs2D"] = vector<double> (5);
1612 for (unsigned iAx = 0; iAx < 5; iAx++) {
1613 mConstV["nTSs2D"][iAx] = mConstV["nTSs"][2 * iAx];
1614 }
1615 mConstV["zToStraw"] = vector<double> (4);
1616 mConstV["zToOppositeStraw"] = vector<double> (4);
1617 mConstV["angleSt"] = vector<double> (4);
1618 mConstV["nShift"] = vector<double> (4);
1619 for (int iSt = 0; iSt < 4; iSt++) {
1620 unsigned t_layerId = mConstV["priorityLayer"][iSt * 2 + 1];
1621 mConstV["zToStraw"][iSt] = cdc.senseWireBZ(t_layerId);
1622 mConstV["zToOppositeStraw"][iSt] = cdc.senseWireFZ(t_layerId);
1623 mConstV["angleSt"][iSt] = 2 * mConstV["rr"][2 * iSt + 1] * sin(mConstD["Trg_PI"] * cdc.nShifts(t_layerId) /
1624 (2 * cdc.nWiresInLayer(t_layerId))) / (cdc.senseWireFZ(t_layerId) - cdc.senseWireBZ(t_layerId));
1625 mConstV["nShift"][iSt] = cdc.nShifts(t_layerId);
1626 }
1627
1628 mConstV["rr2D"] = vector<double> (5);
1629 mConstV["rr3D"] = vector<double> (4);
1630 for (int iAx = 0; iAx < 5; iAx++) mConstV["rr2D"][iAx] = mConstV["rr"][iAx * 2];
1631 for (int iSt = 0; iSt < 4; iSt++) mConstV["rr3D"][iSt] = mConstV["rr"][iSt * 2 + 1];
1632
1633 mConstV["wirePhi2DError"] = vector<double> (5);
1634 mConstV["driftPhi2DError"] = vector<double> (5);
1635 mConstV["wirePhi2DError"][0] = 0.00085106;
1636 mConstV["wirePhi2DError"][1] = 0.00039841;
1637 mConstV["wirePhi2DError"][2] = 0.00025806;
1638 mConstV["wirePhi2DError"][3] = 0.00019084;
1639 mConstV["wirePhi2DError"][4] = 0.0001514;
1640 mConstV["driftPhi2DError"][0] = 0.00085106;
1641 mConstV["driftPhi2DError"][1] = 0.00039841;
1642 mConstV["driftPhi2DError"][2] = 0.00025806;
1643 mConstV["driftPhi2DError"][3] = 0.00019084;
1644 mConstV["driftPhi2DError"][4] = 0.0001514;
1645 mConstV["driftZError"] = vector<double> ({0.7676, 0.9753, 1.029, 1.372});
1646 mConstV["wireZError"] = vector<double> ({0.7676, 0.9753, 1.029, 1.372});
1647
1648 // Make driftLength table for each superlayer. Up to 511 clock ticks.
1649 // driftLengthTableSLX[ tdcCount (~2ns unit) ] = drift length (cm)
1650 for (unsigned iSl = 0; iSl < 9; iSl++) {
1651 string tableName = "driftLengthTableSL" + to_string(iSl);
1652 unsigned tableSize = 512;
1653 mConstV[tableName] = vector<double> (tableSize);
1654 unsigned t_layer = mConstV["priorityLayer"][iSl];
1655 for (unsigned iTick = 0; iTick < tableSize; iTick++) {
1656 double t_driftTime = iTick * 2 * cdc.getTdcBinWidth();
1657 double avgDriftLength = 0;
1658 if (isXtSimple == 1) {
1659 avgDriftLength = cdc.getNominalDriftV() * t_driftTime;
1660 } else {
1661 double driftLength_0 = cdc.getDriftLength(t_driftTime, t_layer, 0);
1662 double driftLength_1 = cdc.getDriftLength(t_driftTime, t_layer, 1);
1663 avgDriftLength = (driftLength_0 + driftLength_1) / 2;
1664 }
1665 mConstV[tableName][iTick] = avgDriftLength;
1666 }
1667 }
1668
1669 mConstD["tdcBitSize"] = 9;
1670 mConstD["rhoBitSize"] = 11;
1671 mConstD["iError2BitSize"] = 8;
1672 mConstD["iError2Max"] = 1 / pow(mConstV["wireZError"][0], 2);
1673 // LUT values
1674 mConstD["JB"] = 0;
1675 mConstD["phiMax"] = mConstD["Trg_PI"];
1676 mConstD["phiMin"] = -mConstD["Trg_PI"];
1677 mConstD["rhoMin"] = 20;
1678 mConstD["rhoMax"] = 2500;
1679 mConstD["phiBitSize"] = 13;
1680 mConstD["driftPhiLUTOutBitSize"] = mConstD["phiBitSize"] - 1;
1681 mConstD["driftPhiLUTInBitSize"] = mConstD["tdcBitSize"];
1682 mConstD["acosLUTOutBitSize"] = mConstD["phiBitSize"] - 1;
1683 mConstD["acosLUTInBitSize"] = mConstD["rhoBitSize"];
1684 mConstD["zLUTInBitSize"] = mConstD["phiBitSize"];
1685 mConstD["zLUTOutBitSize"] = 9;
1686 mConstD["iDenLUTInBitSize"] = 13;
1687 mConstD["iDenLUTOutBitSize"] = 11; // To increase wireZError = 2.5*driftZError
1688 }
1689
1691} // namespace Belle2
The Class for CDC Geometry Parameters.
int nShifts(int layerId) const
Returns number shift.
double getTdcBinWidth() const
Return TDC bin width (nsec).
double senseWireBZ(int layerId) const
Returns backward z position of sense wire in each layer.
unsigned nWiresInLayer(int layerId) const
Returns wire numbers in a layer.
double senseWireFZ(int layerId) const
Returns forward z position of sense wire in each layer.
double getNominalDriftV() const
Return the nominal drift velocity of He-ethane gas (default: 4.0x10^-3 cm/nsec).
double getDriftLength(double dt, unsigned short layer, unsigned short lr, double alpha=0., double theta=0.5 *M_PI, bool calculateMinTime=true, double minTime=0.) const
Return the drift dength to the sense wire.
static CDCGeometryPar & Instance(const CDCGeometry *=nullptr)
Static method to get a reference to the CDCGeometryPar instance.
double senseWireR(int layerId) const
Returns radius of sense wire in each layer.
A Class to store the Monte Carlo particle information.
Definition: MCParticle.h:32
ROOT::Math::XYZVector getVertex() const
Return production vertex position, shorthand for getProductionVertex().
Definition: MCParticle.h:183
unsigned int getStatus(unsigned short int bitmask=USHRT_MAX) const
Return status code of particle.
Definition: MCParticle.h:122
float getCharge() const
Return the particle charge defined in TDatabasePDG.
Definition: MCParticle.cc:36
ROOT::Math::PxPyPzEVector get4Vector() const
Return 4Vector of particle.
Definition: MCParticle.h:207
int getPDG() const
Return PDG code of particle.
Definition: MCParticle.h:112
ROOT::Math::XYZVector getMomentum() const
Return momentum.
Definition: MCParticle.h:198
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
Type-safe access to single objects in the data store.
Definition: StoreObjPtr.h:96
std::map< std::string, TVectorD * > m_mTVectorD
TVectorD map for saving values to root file.
Definition: Fitter3D.h:159
std::map< std::string, std::vector< double > > m_mVector
Map to hold vector values for Fitter3D.
Definition: Fitter3D.h:131
std::map< std::string, bool > m_mBool
Map to hold input options.
Definition: Fitter3D.h:137
std::map< std::string, double > m_mConstD
Map to hold constant values for Fitter3D.
Definition: Fitter3D.h:133
std::map< std::string, std::vector< signed long long > > m_mSavedSignals
Array of saved signals.
Definition: Fitter3D.h:163
std::map< std::string, TRGCDCJLUT * > m_mLutStorage
Map to hold JLuts.
Definition: Fitter3D.h:142
std::map< std::string, std::vector< double > > m_mConstV
Map to hold constant vectcors for Fitter3D.
Definition: Fitter3D.h:135
std::map< std::string, double > m_mDouble
Map to hold double values for Fitter3D.
Definition: Fitter3D.h:129
const std::string m_name
Name.
Definition: Fitter3D.h:123
std::map< std::string, TRGCDCJSignal > m_mSignalStorage
Map to hold JSignals.
Definition: Fitter3D.h:140
std::map< std::string, TClonesArray * > m_mTClonesArray
TClonesArray map for saving values to root file.
Definition: Fitter3D.h:161
TFile * m_fileFitter3D
Tfile for Fitter3D root file.
Definition: Fitter3D.h:150
TRGCDCJSignalData * m_commonData
For VHDL code.
Definition: Fitter3D.h:144
TTree * m_treeTrackFitter3D
TTree for tracks of fitter3D.
Definition: Fitter3D.h:153
std::map< std::string, std::vector< signed long long > > m_mSavedIoSignals
Array of I/O signals.
Definition: Fitter3D.h:165
TTree * m_treeConstantsFitter3D
TTree for constants of fitter3D.
Definition: Fitter3D.h:156
std::string m_rootFitter3DFileName
Members for saving.
Definition: Fitter3D.h:147
const TRGCDC & m_cdc
CDCTRG.
Definition: Fitter3D.h:126
TRGCDCHelix parameter class.
Definition: Helix.h:34
A class to hold common data for JSignals.
Definition: JSignalData.h:33
A class to represent a track segment hit in CDC.
Definition: SegmentHit.h:31
A class to represent a reconstructed charged track in TRGCDC.
Definition: TRGCDCTrack.h:38
The instance of TRGCDC is a singleton.
Definition: TRGCDC.h:69
A class to represent a digitized signal. Unit is nano second.
Definition: Signal.h:23
A class to represent a signal timing in the trigger system.
Definition: Time.h:25
static double rotatePhi(double value, double refPhi)
Rotates to range [-pi, pi].
static int findQuadrant(double value)
Finds quadrant of angle. Angle is in rad.
static void rPhiFitter(double *rr, double *phi2, double *invphierror, double &rho, double &myphi0)
A circle fitter with invPhiError without fit chi2 output.
static double calZ(int charge, double anglest, double ztostraw, double rr, double phi, double rho, double phi0)
Calculates z.
static void setError(std::map< std::string, double > const &mConstD, std::map< std::string, std::vector< double > > const &mConstV, std::map< std::string, Belle2::TRGCDCJSignal > &mSignalStorage)
Sets error using JSignal class.
static double calS(double rho, double rr)
Calculates arc length.
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.
static int rotateTsId(int value, int refId, int nTSs)
Rotates to range [0, nTSs-1].
static unsigned toUnsignedTdc(int tdc, int nBits)
Changes tdc and event time to unsigned value that has # bits.
static void rSFit(double *iezz2, double *arcS, double *zz, double &z0, double &cot, double &zchi2)
3D fitter functions Fits z and arc S.
static void constrainRPerStSl(std::map< std::string, std::vector< double > > const &mConstV, std::map< std::string, Belle2::TRGCDCJSignal > &mSignalStorage)
Constrains R for each SL differently using JSignal and multiple constants.
static void findImpactPosition(ROOT::Math::XYZVector *mcPosition, ROOT::Math::PxPyPzEVector *mcMomentum, int charge, ROOT::Math::XYVector &helixCenter, ROOT::Math::XYZVector &impactPosition)
MC calculation functions Calculates the impact position of track.
static void writeSignals(std::string outFilePath, std::map< std::string, std::vector< signed long long > > &data)
COE file functions.
Definition: FpgaUtility.cc:202
static void multipleWriteCoe(int lutInBitsize, std::map< std::string, std::vector< signed long long > > &data, const std::string &fileDirectory)
Writes multiple signal values to a file in coe format.
Definition: FpgaUtility.cc:220
double atan(double a)
atan for double
Definition: beamHelpers.h:34
const TRGCDCHelix & helix(void) const
returns helix parameter.
Definition: TRGCDCTrack.h:143
const TRGCDCRelation relation(void) const
returns MC information.
Definition: TrackBase.cc:142
std::vector< const TRGCDCSegmentHit * > segmentHits(void) const
returns a list of TRGCDCSegmentHit.
Definition: TRGCDC.h:996
const TRGCDCWire & center(void) const
returns a center wire.
Definition: Segment.h:265
void printToFile()
Utilities Function to print VHDL code.
Definition: JSignalData.cc:106
static void findHitAxialSuperlayers(const TRGCDCTrack &aTrack, std::vector< double > &useAxSL, bool printError)
Finds which axial superlayers has TSs. useAxSL array indicating hit superlayers.
Definition: Fitter3D.cc:1133
static void getStereoGeometry(std::map< std::string, std::vector< double > > &stGeometry)
Get stereo geometry.
Definition: Fitter3D.cc:1558
void initialize()
Initialization.
Definition: Fitter3D.cc:78
static void valuesToMapSignals(std::vector< std::tuple< std::string, double, int, double, double, int > > const &inValues, Belle2::TRGCDCJSignalData *inCommonData, std::map< std::string, Belle2::TRGCDCJSignal > &outMap)
Values => [name, value, bitwidth, min, max, clock] Changes values to signals.
Definition: JSignal.cc:2208
double charge(void) const
returns charge.
Definition: TrackBase.h:248
static double calPhi(TRGCDCSegmentHit const *segmentHit, double eventTime)
Utility functions.
Definition: Fitter3D.cc:895
bool isStereoTrackFull(const TRGCDCTrack &aTrack)
Checks if stereo track has 4 TSs. One per each superlayer.
Definition: Fitter3D.cc:1102
void saveVhdlAndCoe()
Functions for saving.
Definition: Fitter3D.cc:912
bool getPrintVhdl() const
Gets the status of m_printVhdl.
Definition: JSignalData.cc:75
int doit(std::vector< TRGCDCTrack * > &trackList)
Does track fitting.
Definition: Fitter3D.cc:213
static void getStereoXt(std::vector< double > const &stPriorityLayer, std::vector< std::vector< double > > &stXts, bool isSimple=0)
Get stereo Xt.
Definition: Fitter3D.cc:1578
void removeImpossibleStereoSuperlayers(std::vector< double > &useStSL)
Removes TSs that are not possible with track Pt.
Definition: Fitter3D.cc:1193
unsigned layerId(void) const
returns layer id.
Definition: Cell.h:214
const TRGCDCSegment & stereoSegment(unsigned lyrId, unsigned id) const
returns a track segment in stereo layers. (lyrId is stereo #)
Definition: TRGCDC.h:947
int getValue(unsigned) const
get LUT Values
Definition: LUT.cc:47
bool getPrintedToFile() const
Gets the status of m_printedToFile.
Definition: JSignalData.cc:80
static void selectAxialTSs(const TRGCDCTrack &aTrack, std::vector< int > &bestTSIndex)
Selects priority TSs when there are multiple candidate TSs for a superlayer.
Definition: Fitter3D.cc:1204
static void enterStage(const std::string &stageName)
Declare that you enter new stage.
Definition: Debug.cc:24
void terminate()
Termination.
Definition: Fitter3D.cc:1530
void saveIoSignals()
Saves all I/O signals for debugging.
Definition: Fitter3D.cc:944
double phi0(void) const
returns phi0.
Definition: Helix.h:278
const CLHEP::HepVector & a(void) const
returns helix parameters.
Definition: Helix.h:313
TRGCDCFitter3D(const std::string &name, const std::string &rootFitter3DFile, const TRGCDC &, const std::map< std::string, bool > &flags)
Constructor.
Definition: Fitter3D.cc:62
double dr(void) const
returns dr.
Definition: Helix.h:271
void print3DInformation(int iTrack)
Print's information for debugging 3D.
Definition: Fitter3D.cc:1474
unsigned lutPattern(void) const
hit pattern containing bit for priority position
Definition: Segment.cc:571
virtual ~TRGCDCFitter3D()
Destructor.
Definition: Fitter3D.cc:74
static void findHitStereoSuperlayers(const TRGCDCTrack &aTrack, std::vector< double > &useStSL, bool printError)
Finds which stereo superlayers has TSs. useStSL array indicating hit superlayers.
Definition: Fitter3D.cc:1164
const TRGCDCSegment & segment(unsigned id) const
returns a track segment.
Definition: TRGCDC.h:933
const TRGCDCLUT * LUT(void) const
returns LUT
Definition: Segment.h:258
int getEventTime(void) const
returns bad hits(finding invalid hits).
Definition: TRGCDC.cc:2743
static int do2DFit(TRGCDCTrack &aTrack, const std::map< std::string, bool > &m_mBool_in, const std::map< std::string, double > &m_mConstD_in, std::map< std::string, std::vector< double > > &m_mConstV_in, std::map< std::string, double > &m_mDouble_in, std::map< std::string, std::vector< double > > &m_mVector_in)
Does 2D fit. Returns 0 if fit is done successfully. m_mBool should have fIsPrintError,...
Definition: Fitter3D.cc:1259
std::string name(void) const
Gets name of class.
Definition: Fitter3D.cc:1553
float priorityTime(void) const
return priority time in TSHit.
Definition: Segment.cc:463
static void leaveStage(const std::string &stageName)
Declare that you leave a stage.
Definition: Debug.cc:34
void entryVhdlCode()
Function to print entry VHDL code.
Definition: JSignalData.cc:195
static void getConstants(std::map< std::string, double > &mConstD, std::map< std::string, std::vector< double > > &mConstV, bool isXtSimple=0)
Get constants for firmwareFit.
Definition: Fitter3D.cc:1596
std::string version(void) const
Gets version of class.
Definition: Fitter3D.cc:1548
static void getMCValues(const TRGCDC &m_cdc_in, TRGCDCTrack *aTrack, const std::map< std::string, double > &m_mConstD_in, std::map< std::string, double > &m_mDouble_in, std::map< std::string, std::vector< double > > &m_mVector_in)
Function for mc debugging.
Definition: Fitter3D.cc:963
const std::vector< TRGCDCLink * > & links(void) const
returns a vector to track segments.
Definition: TrackBase.cc:123
const TRGCDCSegment & segment(void) const
returns a pointer to a track segment.
Definition: SegmentHit.cc:78
virtual double pt(void) const override
returns Pt.
Definition: TRGCDCTrack.h:165
void saveAllSignals()
Saves all signals for debugging.
Definition: Fitter3D.cc:934
void signalsVhdlCode()
Function to print definition of signal VHDL code.
Definition: JSignalData.cc:178
void setVhdlOutputFile(const std::string &)
Sets the filename for VHDL output.
Definition: JSignalData.cc:45
const HepGeom::Point3D< double > ORIGIN
Origin 3D point.
int doitComplex(std::vector< TRGCDCTrack * > &trackList)
Does track fitting using JSignals.
Definition: Fitter3D.cc:460
void buffersVhdlCode()
Function to print buffer VHDL code.
Definition: JSignalData.cc:150
void setFitted(bool fitted)
set fit status
Definition: TrackBase.h:234
bool isAxialTrackFull(const TRGCDCTrack &aTrack)
Checks if axial track has 5 TSs. One per each superlayer.
Definition: Fitter3D.cc:1071
void setPrintVhdl(bool)
Sets if to print VHDL output.
Definition: JSignalData.cc:50
unsigned localId(void) const
returns local id in a layer.
Definition: Cell.h:207
static void mapSignalsToValues(std::map< std::string, Belle2::TRGCDCJSignal >const &inMap, std::vector< std::pair< std::string, int > > const &inChoose, std::vector< std::tuple< std::string, double, int, double, double, int > > &outValues)
Choose => [signalName, FpgaEffects(=1)/NoFpgaEffects(=0)] Values => [name, value, bitwidth,...
Definition: JSignal.cc:2225
Abstract base class for different kinds of events.
STL namespace.