ATLAS Offline Software
Loading...
Searching...
No Matches
TBPlaneTrackingAlgo.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
7#include "TBEvent/TBBPCCont.h"
9#include "TBEvent/TBTrack.h"
10#include "TBEvent/TBEventInfo.h"
11
13
14#include <vector>
15#include <iostream>
16#include <fstream>
17#include <cmath>
18
19class ISvcLocator;
20
21TBPlaneTrackingAlgo::TBPlaneTrackingAlgo(const std::string& name, ISvcLocator* pSvcLocator)
22 : AthAlgorithm(name, pSvcLocator),
24{
25 declareProperty("TestAlgo",m_testAlgo=false);
26 declareProperty("CalibFileName", m_calib_filename="H6HitCalib.txt");
27 declareProperty("BPCnames", m_bpc_names);
28 declareProperty("BPCposX", m_bpc_posX);
29 declareProperty("BPCposY", m_bpc_posY);
30 declareProperty("BPCposZX", m_bpc_posZX);
31 declareProperty("BPCposZY", m_bpc_posZY);
32 declareProperty("BPCerrposX", m_bpc_errposX);
33 declareProperty("BPCerrposY", m_bpc_errposY);
34 declareProperty("BPCerrposZX", m_bpc_errposZX);
35 declareProperty("BPCerrposZY", m_bpc_errposZY);
36 declareProperty("BPCerrmeasX", m_bpc_errmeasX);
37 declareProperty("BPCerrmeasY", m_bpc_errmeasY);
38
39}
40
44{
45 return StatusCode::SUCCESS;
46}
47
49StatusCode TBPlaneTrackingAlgo::execute(const EventContext& ctx)
51{
52 ATH_MSG_DEBUG ("Executing TBPlaneTracking algorithm");
53
54 if(m_testAlgo == true){
55 ATH_MSG_WARNING ("TBPlaneTrackingAlgo: " <<
56 "Using FillRandomHit method to get data");
58 }
59
60 // Check if this is not a physics event and exit OK
61 // retrieve Event Info
62 const TBEventInfo* theEventInfo;
63 StatusCode checkOut = evtStore()->retrieve(theEventInfo,"TBEventInfo");
64 if ( checkOut.isFailure() )
65 {
66 ATH_MSG_ERROR ("cannot retrieve TBEventInfo from StoreGate");
67 return StatusCode::FAILURE;
68 }
69 int evtType = theEventInfo->getEventType();
70 ATH_MSG_DEBUG ("Event Type found " << evtType);
71 if (evtType != 1) return StatusCode::SUCCESS;
72
73 StatusCode sc1;
74
75 // Get run number and get new calib constants -----------------------------
76 unsigned int thisrun=ctx.eventID().run_number();
77
78 if(thisrun != m_runnumber)
79 {
80 m_runnumber= thisrun;
82 }
83 // ------------------------------------------------------------------------
84
85
86
87 sc1 = buildHits();
88
89// sc1 = m_StoreGate->retrieve(m_hitPlaneCont_u,"HitPlaneCont_U");
90// sc2 = m_StoreGate->retrieve(m_hitPlaneCont_v,"HitPlaneCont_V");
91
92 if(sc1.isFailure()){
93 ATH_MSG_WARNING ("TBPlaneTrackingAlgo: Retrieval of HitPlane failed");
94 setFilterPassed(false, ctx);
95 return StatusCode::SUCCESS;
96 } else {
97
98 int hitPlaneNumU, hitPlaneNumV;
99 hitPlaneNumU = m_hitPlaneCont_u.size();
100 hitPlaneNumV = m_hitPlaneCont_v.size();
101
102 if( (hitPlaneNumU < 2) || (hitPlaneNumV < 2) ){
103 ATH_MSG_WARNING ("TBPlaneTrackingAlgo: "
104 << "Not enough hits in one or both planes, "
105 << "Cannot make track.");
106
107 setFilterPassed(false, ctx);
108 return StatusCode::SUCCESS;
109 }
110
111 // Setting the chi2's for the track //
112 double chi2_u = 0;
113 double chi2_v = 0;
114 std::vector<double> residual_u, residual_v;
115 double a1_u = 0;
116 double a2_u = 0;
117 double a1_v = 0;
118 double a2_v = 0;
119 bool check = true;
120
121 check = fitPlane(&m_hitPlaneCont_u, a1_u, a2_u, chi2_u, residual_u);
122 if(check == false){
123 ATH_MSG_ERROR ("TBPlaneTrackingAlgo: " << "Fit failure.");
124 setFilterPassed(false, ctx);
125 return StatusCode::SUCCESS;
126 }
127
128 check = fitPlane(&m_hitPlaneCont_v, a1_v, a2_v, chi2_v, residual_v);
129 if(check == false){
130 ATH_MSG_ERROR ("TBPlaneTrackingAlgo: " << "Fit failure.");
131 setFilterPassed(false, ctx);
132 return StatusCode::SUCCESS;
133 }
134
135 // Setting the slopes & intercepts for each track //
136 ATH_MSG_DEBUG ("Setting fit parameters of track.");
137
138 TBTrack *track = new TBTrack(hitPlaneNumU, hitPlaneNumV);
139 track->setUintercept(a1_u);
140 track->setVintercept(a1_v);
141 track->setUslope(a2_u);
142 track->setVslope(a2_v);
143
144 // Setting the residual for plane u //
145 for(int i = 0; i < hitPlaneNumU; i++){
146 track->setResidualu(i, residual_u[i]);
147 }
148
149 // Setting the residual for plane v //
150 for(int i = 0; i < hitPlaneNumV; i++){
151 track->setResidualv(i, residual_v[i]);
152 }
153
154 ATH_MSG_DEBUG ("chi2 in u: " << chi2_u);
155 ATH_MSG_DEBUG ("chi2 in v: " << chi2_v);
156 ATH_MSG_DEBUG ("Setting chi2s of track.");
157
158 track->setChi2_u(chi2_u);
159 track->setChi2_v(chi2_v);
160
161 // Record track info. into storeGate //
162 StatusCode sc = evtStore()->record(track,"Track");
163
164 if ( sc.isFailure( ) ) {
165 ATH_MSG_FATAL ("Cannot record Track");
166 }
167 }
168
169 setFilterPassed(true, ctx);
170 return StatusCode::SUCCESS;
171}
172
176{
177 ATH_MSG_INFO ("Finalizing TBTracking algorithm");
178 return StatusCode::SUCCESS;
179}
180
183double &a1, double &a2,double &chi2, std::vector<double> &residual)
185{
186 // Get number of hits in plane //
187 int hitPlaneNum = hitPlaneCont->size();
188
189 ATH_MSG_DEBUG ("The hit plane container size is: " << hitPlaneNum);
190
191 std::vector<double> vec_u;
192 std::vector<double> vec_w;
193 std::vector<double> err_vec_u;
194 std::vector<double> err_vec_w;
195
196 for (const TBHitPlane* hp : *hitPlaneCont) {
197 ATH_MSG_DEBUG ("Position in u: " << hp->getPosu());
198 ATH_MSG_DEBUG ("Position in w: " << hp->getPosw());
199 ATH_MSG_DEBUG ("Error in u: " << hp->getErroru());
200 ATH_MSG_DEBUG ("Error in w: " << hp->getErrorw());
201 vec_u.push_back(hp->getPosu());
202 vec_w.push_back(hp->getPosw());
203 err_vec_u.push_back(hp->getErroru());
204 err_vec_w.push_back(hp->getErrorw());
205 }
206
207 if(vec_u.size() != vec_w.size()){
208 ATH_MSG_ERROR ("TBPlaneTrackingAlgo: Invalid hits");
209 return false;
210 }
211
212 bool check;
213// check = fitHits(vec_u, vec_w, err_vec_u, err_vec_w, a1, a2);
214 check = fitHits(vec_u, vec_w, err_vec_u, a1, a2);
215 if(check == false){
216 ATH_MSG_ERROR ("TBPlaneTrackingAlgo: Invalid denumerator");
217 return false;
218 }
219
220// chi2 = getChi2(vec_u, vec_w, err_vec_u, err_vec_w, a1, a2);
221 chi2 = getChi2(vec_u, vec_w, err_vec_u, a1, a2);
222
223 ATH_MSG_DEBUG ("Fit results:"
224 << " intercept = " << a1
225 << " and slope = " << a2);
226
227 // Must be wrong //
228 for (int i = 0; i < hitPlaneNum; i++) {
229 residual.push_back(getResidual(vec_u[i],vec_w[i],a1, a2));
230 }
231 return true;
232}
233
235bool TBPlaneTrackingAlgo::fitHits(const std::vector<double> & v_u,
236 const std::vector<double> & v_w,
237 const std::vector<double> & v_eu,
238// const std::vector<double> & v_ew,
239 double &a1, double &a2)
241{
242 // v_u = vector of u data points
243 // v_w = vector of w data points
244 // v_eu = vector of errors in u data points
245 // v_ew = vector of errors in w data points
246 // a1 and a2 = fit parameters: u = a1 + a2*w
247
248 // *** note that the fit algorithm used (given in 'Numerical Methods
249 // in C' section 15.2) assumes that the w data points are known exactly
250 // i.e. that v_ew[i]=0 for all i
251
252 // 'Numerical Methods' notes that the task of fitting a straight
253 // line model with errors in both coordinates is "considerably harder"
254 // (section 15.3) - but clearly it could be done
255
256 double m_s = 0;
257 double m_su = 0;
258 double m_sww = 0;
259 double m_sw = 0;
260 double m_suw = 0;
261
262 int numHits = v_u.size();
263 for(int i = 0; i < numHits; i++){
264 m_s += 1 / (v_eu[i]*v_eu[i]);
265 m_su += v_u[i] / (v_eu[i]*v_eu[i]);
266 m_sww += v_w[i]*v_w[i] / (v_eu[i]*v_eu[i]);
267 m_sw += v_w[i] / (v_eu[i]*v_eu[i]);
268 m_suw += v_u[i]*v_w[i] / (v_eu[i]*v_eu[i]);
269 }
270
271 const double denom = (m_s*m_sww-m_sw*m_sw);
272 if(denom == 0){
273 return false;
274 }
275
276 // coverity[divide_by_zero]
277 const double inv_denom = 1. / denom;
278 a1 = (m_su*m_sww - m_sw*m_suw) * inv_denom;
279 a2 = (m_s*m_suw - m_su*m_sw) * inv_denom;
280 return true;
281}
282
283double TBPlaneTrackingAlgo::getResidual(const double &u, const double &w
284 , const double &a1, const double &a2)
286{
287 return (u - a1 - a2*w);
288}
289
291double TBPlaneTrackingAlgo::getChi2(const std::vector<double> &v_u,
292 const std::vector<double> &v_w,
293 const std::vector<double> &v_eu,
294// const std::vector<double> &v_ew,
295 const double &a1, const double &a2)
297{
298 // *** as in fitHits() above, the chi squared calculation below
299 // (taken from 'Numerical Methods in C' section 15.2)
300 // assumes that the w data points are known exactly i.e. that
301 // v_ew[i]=0 for all i
302
303 int numX = v_u.size();
304 double chi2 = 0;
305
306 for(int i = 0; i < numX; i++){
307 chi2 += (v_u[i] - a1 - a2*v_w[i])*(v_u[i] - a1 - a2*v_w[i])/(v_eu[i]*v_eu[i]);
308 }
309 return chi2;
310}
311
312
316{
317
318 ATH_MSG_DEBUG ("Starting FillRandom");
319
320 TBHitPlaneCont * hitPlaneCont_U = new TBHitPlaneCont();
321 TBHitPlaneCont * hitPlaneCont_V = new TBHitPlaneCont();
322
323 TBHitPlane *hitPaneU1 = new TBHitPlane();
324 hitPaneU1->setPosu(1); hitPaneU1->setPosw(1);
325 hitPlaneCont_U->push_back(hitPaneU1);
326
327
328 TBHitPlane *hitPaneU2 = new TBHitPlane();
329 hitPaneU2->setPosu(2); hitPaneU2->setPosw(2);
330 hitPlaneCont_U->push_back(hitPaneU2);
331
332 StatusCode sc1 = evtStore()->record(hitPlaneCont_U,"HitPlaneCont_U");
333 if ( sc1.isFailure( ) ) {
334 ATH_MSG_FATAL ("Cannot record HitPlaneCont_U");
335 }
336
337 TBHitPlane *hitPaneV1 = new TBHitPlane();
338 hitPaneV1->setPosu(1); hitPaneV1->setPosw(1);
339 hitPlaneCont_V->push_back(hitPaneV1);
340
341 TBHitPlane *hitPaneV2 = new TBHitPlane();
342 hitPaneV2->setPosu(2); hitPaneV2->setPosw(2);
343 hitPlaneCont_V->push_back(hitPaneV2);
344
345 StatusCode sc2 = evtStore()->record(hitPlaneCont_V,"HitPlaneCont_V");
346 if ( sc2.isFailure( ) ) {
347 ATH_MSG_FATAL ("Cannot record HitPlaneCont_V");
348 }
349
350 ATH_MSG_DEBUG ("FillRandom Done");
351
352}
353
357{
358 ATH_MSG_DEBUG (" In buildHits() ");
359 m_hitPlaneCont_u.clear();
360 m_hitPlaneCont_v.clear();
361
362 TBBPCCont * bpcCont = nullptr;
363 ATH_CHECK( evtStore()->retrieve(bpcCont, "BPCCont") );
364
365 // Loop over BPC
366 for (const TBBPC* bpc : *bpcCont) {
367 std::string name = bpc->getDetectorName();
368 ATH_MSG_DEBUG (" Hits in BPC "<< name);
369 // Find calibration index for this BPC
370 unsigned int ind=0;
371 while(ind<m_bpc_names.size())
372 {
373 if(name==m_bpc_names[ind]) break;
374 else ind++;
375 }
376 if(ind==m_bpc_names.size()){
377 ATH_MSG_ERROR ("No calibrations for BPC" << name);
378 continue;
379 }
380
381 ATH_MSG_DEBUG (" BPC number "<< ind);
382
383
384 if(!(bpc->isXPosOverflow()||bpc->isXPulseOverflow())){
385 TBHitPlane * hitu = new TBHitPlane();
386 float w = m_bpc_posZX[ind];
387 // float u =m_bpc_posX[ind] + m_bpc_invX[ind]*bpc->getXPos();
388 float u =m_bpc_posX[ind] + bpc->getXPos();
389 ATH_MSG_DEBUG ("BPC" << ind << "X =" << u);
390 hitu->setPosu(u); hitu->setPosw(w);
391 float uerr=sqrt(m_bpc_errposX[ind]*m_bpc_errposX[ind]+m_bpc_errmeasX[ind]*m_bpc_errmeasX[ind]);
392 hitu->setErroru(uerr); hitu->setErrorw(m_bpc_errposZX[ind]);
393 hitu->setValidFlag(bpc->isXPosOverflow()&&bpc->isYPosOverflow());
394 m_hitPlaneCont_u.push_back(hitu);
395 }
396
397 if(!(bpc->isYPosOverflow()||bpc->isYPulseOverflow())){
398 TBHitPlane * hitv = new TBHitPlane();
399 float w = m_bpc_posZY[ind];
400 // float v =m_bpc_posY[ind] + m_bpc_invY[ind]*bpc->getYPos();
401 float v =m_bpc_posY[ind] + bpc->getYPos();
402 ATH_MSG_DEBUG ("BPC" << ind << "Y =" << v);
403 hitv->setPosu(v); hitv->setPosw(w);
404 float verr=sqrt(m_bpc_errposY[ind]*m_bpc_errposY[ind]+m_bpc_errmeasY[ind]*m_bpc_errmeasY[ind]);
405 hitv->setErroru(verr); hitv->setErrorw(m_bpc_errposZY[ind]);
406 hitv->setValidFlag(bpc->isXPosOverflow()&&bpc->isYPosOverflow());
407 m_hitPlaneCont_v.push_back(hitv);
408 }
409 }
410
411 return StatusCode::SUCCESS;
412}
413
414
416{
417 // Get calib constant from an ASCII file with the following structure :
418 //
419 // runnumber
420 // bpcnumber1 coeff1 coeff2 ... coeff8
421 // bpcnumber2 coeff1 coeff2 ... coeff8
422 // ...
423 // bpcnumber6 coeff1 coeff2 ... coeff8
424 // runnumber
425 // ...
426 //
427 // coeff must have the following order :
428 // bpcnumber posX posY posZX posZY errposX errposY errposZX errposZY errmeasX errmeasY
429
430 ATH_MSG_DEBUG ("Get new calibs for run " << m_runnumber);
431
432 int bpcnumber= m_bpc_names.size();
433
434 m_bpc_posX.clear(); m_bpc_posX.resize(bpcnumber);
435 m_bpc_posY.clear(); m_bpc_posY.resize(bpcnumber);
436 m_bpc_posZX.clear(); m_bpc_posZX.resize(bpcnumber);
437 m_bpc_posZY.clear(); m_bpc_posZY.resize(bpcnumber);
438 m_bpc_errposX.clear(); m_bpc_errposX.resize(bpcnumber);
439 m_bpc_errposY.clear(); m_bpc_errposY.resize(bpcnumber);
440 m_bpc_errposZX.clear(); m_bpc_errposZX.resize(bpcnumber);
441 m_bpc_errposZY.clear(); m_bpc_errposZY.resize(bpcnumber);
442 m_bpc_errmeasX.clear(); m_bpc_errmeasX.resize(bpcnumber);
443 m_bpc_errmeasY.clear(); m_bpc_errmeasY.resize(bpcnumber);
444
445 int pos;
446
447 std::ifstream calibfile;
448 std::string filename = PathResolver::find_file (m_calib_filename, "DATAPATH");
449 calibfile.open(filename.c_str());
450 if(!calibfile.good()){
451 ATH_MSG_WARNING (" Problem with file named "<< m_calib_filename << " in $DATAPATH");
452 return StatusCode::FAILURE;
453 } else {
454 ATH_MSG_DEBUG (" File: "<< filename << " opened");
455 }
456 unsigned int runnumber;
457 calibfile >> runnumber;
458 pos = calibfile.tellg();
459 ATH_MSG_DEBUG (" Run number "<< runnumber);
460 while((runnumber<m_runnumber)&&(!calibfile.eof()))
461 {
462 runnumber=0;
463 pos = calibfile.tellg();
464 // discard next lines
465 for(int j=0;j<bpcnumber+1;j++) calibfile.ignore(5000,'\n');
466 // check next runnumber
467 calibfile >> runnumber;
468 if(runnumber==0) { // reached an empty line : exit.
469 ATH_MSG_DEBUG ("empty line");
470 calibfile.clear();
471 break;
472 }
473 ATH_MSG_DEBUG (" Run number "<< runnumber);
474 }
475
476 // Now we found the good set of constant (the ones following pos)
477 if(runnumber==m_runnumber) pos = calibfile.tellg();
478 ATH_MSG_DEBUG (" Pos = "<< pos);
479 calibfile.seekg(pos);
480 ATH_MSG_DEBUG (" Will use the following constants :");
481 for(int j=0;j<bpcnumber;j++)
482 {
483 int bpcn;
484 calibfile >> bpcn;
485 calibfile >> m_bpc_posX[j];
486 calibfile >> m_bpc_posY[j];
487 calibfile >> m_bpc_posZX[j];
488 calibfile >> m_bpc_posZY[j];
489 calibfile >> m_bpc_errposX[j];
490 calibfile >> m_bpc_errposY[j];
491 calibfile >> m_bpc_errposZX[j];
492 calibfile >> m_bpc_errposZY[j];
493 calibfile >> m_bpc_errmeasX[j];
494 calibfile >> m_bpc_errmeasY[j];
495
496 ATH_MSG_DEBUG (bpcn << " "<<m_bpc_posX[j]
497 << " "<< m_bpc_posY[j]
498 << " "<< m_bpc_posZX[j]
499 << " "<< m_bpc_posZY[j]
500 << " "<< m_bpc_errposX[j]
501 << " "<< m_bpc_errposY[j]
502 << " "<< m_bpc_errposZX[j]
503 << " "<< m_bpc_errposZY[j]
504 << " "<< m_bpc_errmeasX[j]
505 << " "<< m_bpc_errmeasY[j]);
506 }
507
508 calibfile.close();
509
510 return StatusCode::SUCCESS;
511
512}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
static Double_t sc
void setFilterPassed(bool state) const
AthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
value_type push_back(value_type pElem)
Add an element to the end of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
static std::string find_file(const std::string &logical_file_name, const std::string &search_path)
"TBEvent/TBBPCCont.h"
Definition TBBPCCont.h:17
Definition TBBPC.h:23
int getEventType() const
Definition TBEventInfo.h:71
Holds a set of TBHitPlane objects.
This class is used to store hit information from BPC & MWPC for one plane.
Definition TBHitPlane.h:16
void setPosw(double w)
Definition TBHitPlane.h:41
void setValidFlag(bool valid)
Definition TBHitPlane.h:45
void setErroru(double eu)
Definition TBHitPlane.h:42
void setPosu(double u)
Definition TBHitPlane.h:40
void setErrorw(double ew)
Definition TBHitPlane.h:43
std::vector< float > m_bpc_posX
double getChi2(const std::vector< double > &v_u, const std::vector< double > &v_w, const std::vector< double > &v_eu, const double &a1, const double &a2)
Calculates the chi2 += ((u_i - a1 - a2*w_i)/eu)^2.
std::vector< float > m_bpc_errmeasX
StatusCode buildHits()
Build HitPlaneCont from BPC.
virtual StatusCode initialize() override
std::vector< float > m_bpc_errposY
std::vector< float > m_bpc_posZX
bool fitPlane(const TBHitPlaneCont *hitPlaneCont, double &a1, double &a2, double &chi2, std::vector< double > &residual)
Fit data to the function u = a1 + a2*w.
std::vector< float > m_bpc_posY
virtual StatusCode execute(const EventContext &ctx) override
Execute method.
bool fitHits(const std::vector< double > &u, const std::vector< double > &w, const std::vector< double > &eu, double &a1, double &a2)
Fit data to the function u = a1 + a2*w.
std::vector< std::string > m_bpc_names
std::vector< float > m_bpc_errposZY
std::vector< float > m_bpc_errposZX
std::vector< float > m_bpc_errmeasY
std::vector< float > m_bpc_posZY
virtual StatusCode finalize() override
TBHitPlaneCont m_hitPlaneCont_u
std::vector< float > m_bpc_errposX
TBHitPlaneCont m_hitPlaneCont_v
double getResidual(const double &u, const double &w, const double &a1, const double &a2)
Calculates the residual-> r = (u_i - a1 - a2*w_i).
TBPlaneTrackingAlgo(const std::string &name, ISvcLocator *pSvcLocator)
double chi2(TH1 *h0, TH1 *h1)
static std::vector< uint32_t > runnumber
Definition iLumiCalc.h:37