ATLAS Offline Software
Loading...
Searching...
No Matches
LArTBH6BeamInfo.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "LArTBH6BeamInfo.h"
6
9
10// Gaudi Includes
11#include "GaudiKernel/SystemOfUnits.h"
13
14using namespace Gaudi::Units;
15
16LArTBH6BeamInfo::LArTBH6BeamInfo(const std::string& name, ISvcLocator* pSvcLocator)
17 : AthAlgorithm(name, pSvcLocator)
18 , m_theEventInfo("TBEventInfo")
19{
20 for (const auto &it : m_HitsCollNames){
22 }
23}
24
25//****************************************************************************
26//* Initialization
27//****************************************************************************
28
30{
31
32 if((!m_Primary) && (m_pcode == 999)) {
33 ATH_MSG_ERROR ( "Pcode should be in jO, if not PrimaryTrackOnly !" );
34 return StatusCode::FAILURE;
35 }
36
37// End of Initialization
38 ATH_MSG_INFO ( "LArTBH6BeamInfo initialisation completed" );
39 return StatusCode::SUCCESS;
40}
41
42//****************************************************************************
43//* Execution
44//****************************************************************************
45
47{
48 ATH_MSG_INFO ( "LArTBH6BeamInfo in execute" );
49 CLHEP::Hep3Vector pos;
50
51 if ( m_numEv == 0 ){
52 m_cryoX = m_theEventInfo->getCryoX();
53 }
54
55 dVect v_x;
56 dVect v_y;
57 dVect v_xz;
58 dVect v_yz;
59 dVect v_ex;
60 dVect v_ey;
61
62// loop hit containers
63 for (auto &it : m_hitcoll) {
64
65 ATH_MSG_INFO (" hit container: "<< it->Name() <<" size: "<<it->size() );
66
67 for (const LArG4H6FrontHit* hit : *it){
68 // loop over hits, find track==0 and make a fit, store a TBTrack to StoreGate
69 if(hit->GetSC() > 0) continue; // scintilator hit
70 if(m_Primary) {
71 if(hit->GetTrackID() != 1) continue; // not a primary particle
72 } else {
73 if(hit->GetPcode() != m_pcode) continue; // not a beam particle
74 }
75 pos = hit->GetPos();
76 if(hit->GetX() > 0) { // X-coordinate
77 v_x.push_back(pos.x());
78 v_xz.push_back(pos.z()+21600.*mm);
79 v_ex.push_back(0.01); // take the error from somewhere !!!
80 } else {
81 v_y.push_back(pos.y());
82 v_yz.push_back(pos.z()+21600.*mm);
83 v_ey.push_back(0.01); // take the error from somewhere !!!
84 }
85 }
86
87 }
88
89 if(v_x.size() < 2 || v_y.size() < 2) { // Could not fit
90 ATH_MSG_DEBUG ( "Could not fit, setting zero. "<<v_x.size()<<"/"<<v_y.size() );
91 m_track = std::make_unique<TBTrack>(0,0);
92 m_track->setUintercept(0.);
93 m_track->setVintercept(0.);
94 m_track->setUslope(0.);
95 m_track->setVslope(0.);
96// m_track->setResidualu(0, 0);
97// m_track->setResidualv(0, 0);
98 m_track->setChi2_u(1000.);
99 m_track->setChi2_v(1000.);
100 m_track->setCryoHitu(0.);
101 m_track->setCryoHitv(0.);
102 m_track->setCryoHitw(30000.);
103 return StatusCode::FAILURE;
104 }
105 // Now fit somehow
106 double chi2_x = 0;
107 double chi2_y = 0;
108 std::vector<double> residual_x, residual_y;
109 double a1_x = 0;
110 double a2_x = 0;
111 double a1_y = 0;
112 double a2_y = 0;
113 bool check = true;
114
115 check = fitVect(v_x, v_xz, v_ex, a1_x, a2_x, chi2_x, residual_x);
116
117 if(!check){
118 ATH_MSG_ERROR ( "Fit in X-coordinate failure." );
119 return StatusCode::FAILURE;
120 }
121
122 check = fitVect(v_y, v_yz, v_ey, a1_y, a2_y, chi2_y, residual_y);
123 if(!check){
124 ATH_MSG_ERROR ( "Fit in Y-coordinate failure." );
125 return StatusCode::FAILURE;
126 }
127
128 // Setting the slopes & intercepts for each track //
129 ATH_MSG_DEBUG ( "Setting fit parameters of track." );
130 ATH_MSG_DEBUG ( "Intercepts: "<<a1_x<<" "<<a1_y );
131 ATH_MSG_DEBUG ( "Slopes: "<<a2_x<<" "<<a2_y );
132
133 m_track = std::make_unique<TBTrack>(v_x.size(), v_y.size());
134
135 m_track->setUintercept(a1_x);
136 m_track->setVintercept(a1_y);
137 m_track->setUslope(a2_x);
138 m_track->setVslope(a2_y);
139
140 // Setting the residual for plane u //
141 for(size_t i = 0; i < v_x.size(); ++i){
142 m_track->setResidualu(i, residual_x[i]);
143 }
144
145 // Setting the residual for plane v //
146 for(size_t i = 0; i < v_y.size(); ++i){
147 m_track->setResidualv(i, residual_y[i]);
148 }
149
150 ATH_MSG_DEBUG ( "chi2 in X: " << chi2_x );
151 ATH_MSG_DEBUG ( "chi2 in Y: " << chi2_y );
152 ATH_MSG_DEBUG ( "Setting chi2s of track." );
153
154 m_track->setChi2_u(chi2_x);
155 m_track->setChi2_v(chi2_y);
156
157 // Setting the cryo plane (30000 mm in TB coordinate)
158 m_track->setCryoHitu(a2_x*30000.+a1_x+m_cryoX);
159 m_track->setCryoHitv(a2_y*30000.+a1_y);
160 m_track->setCryoHitw(30000.);
161
162 return StatusCode::SUCCESS;
163}
164
165//****************************************************************************
166//* Finalize
167//****************************************************************************
168
170{
171 ATH_MSG_INFO ( "LArTBH6BeamInfo::finalize()" );
172 return StatusCode::SUCCESS;
173}
174
176bool LArTBH6BeamInfo::fitVect(const dVect &vec, const dVect &vec_z, const dVect &vec_e,
177 double &a1, double &a2,double &chi2, dVect &residual)
179{
180 // v_u = vector of u data points
181 // v_w = vector of w data points
182 // v_eu = vector of errors in u data points
183 // v_ew = vector of errors in w data points
184 // a1 and a2 = fit parameters: u = a1 + a2*w
185
186 // *** note that the fit algorithm used (given in 'Numerical Methods
187 // in C' section 15.2) assumes that the w data points are known exactly
188 // i.e. that v_ew[i]=0 for all i
189
190 // 'Numerical Methods' notes that the task of fitting a straight
191 // line model with errors in both coordinates is "considerably harder"
192 // (section 15.3) - but clearly it could be done
193
194 int i;
195 double s = 0;
196 double su = 0;
197 double sww = 0;
198 double sw = 0;
199 double suw = 0;
200
201 int hitNum = vec.size();
202 for(i = 0; i < hitNum; ++i){
203
204 ATH_MSG_DEBUG ( "Position in X: " << vec[i] );
205 ATH_MSG_DEBUG ( "Position in Z: " << vec_z[i] );
206 ATH_MSG_DEBUG ( "Error in X: " << vec_e[i] );
207
208 s += 1 / (vec_e[i]*vec_e[i]);
209 su += vec[i] / (vec_e[i]*vec_e[i]);
210 sww += vec_z[i]*vec_z[i] / (vec_e[i]*vec_e[i]);
211 sw += vec_z[i] / (vec_e[i]*vec_e[i]);
212 suw += vec[i]*vec_z[i] / (vec_e[i]*vec_e[i]);
213 }
214
215 const double denom = (s*sww-sw*sw);
216 if(denom == 0){
217 ATH_MSG_ERROR ( " Invalid denominator" );
218 return false;
219 }
220
221 // coverity[divide_by_zero] // false positive
222 const double inv_denom = 1. / denom;
223 a1 = (su*sww - sw*suw) * inv_denom;
224 a2 = (s*suw - su*sw) * inv_denom;
225 ATH_MSG_DEBUG ( "Fit results:" << " intercept = " << a1 << " and slope = " << a2 );
226
227 // Fill residual
228 residual.clear();
229 for (i = 0; i < hitNum; ++i) {
230 residual.push_back(vec[i] - a1 - a2*vec_z[i]);
231 }
232 // Fill Chi2
233 chi2 = 0;
234 for(i = 0; i < hitNum; ++i){
235 chi2 += (vec[i] - a1 - a2*vec_z[i])*(vec[i] - a1 - a2*vec_z[i])/(vec_e[i]*vec_e[i]);
236 }
237
238 return true;
239}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
std::vector< size_t > vec
defines an "iterator" over instances of a given type in StoreGateSvc
AthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor with parameters:
Gaudi::Property< int > m_pcode
virtual StatusCode execute() override
virtual StatusCode finalize() override
Gaudi::Property< bool > m_Primary
LArTBH6BeamInfo(const std::string &name, ISvcLocator *pSvcLocator)
bool fitVect(const dVect &vec_x, const dVect &vec_xz, const dVect &vec_ex, double &a1, double &a2, double &chi2, dVect &residual)
Fit data to the function u = a1 + a2*w.
std::vector< SG::ReadHandle< AthenaHitsVector< LArG4H6FrontHit > > > m_hitcoll
virtual StatusCode initialize() override
SG::WriteHandle< TBTrack > m_track
std::vector< double > dVect
SG::ReadHandle< TBEventInfo > m_theEventInfo
Gaudi::Property< std::vector< std::string > > m_HitsCollNames
double chi2(TH1 *h0, TH1 *h1)