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