ATLAS Offline Software
Loading...
Searching...
No Matches
CascadeDefinition.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7#include <cmath>
8#include <iostream>
9
16
17namespace {
18// internal methods
19
20using namespace Trk;
21VKVertex *startCascade(std::unique_ptr<VKVertex> vk) {
22 auto *ptr = vk.get();
23 ptr->vk_fitterControl->getCascadeEvent()->cascadeNV = 1;
24 ptr->vk_fitterControl->getCascadeEvent()->nearPrmVertex = 0;
25 ptr->vk_fitterControl->getCascadeEvent()->cascadeVertexList.clear();
26 ptr->vk_fitterControl->getCascadeEvent()->cascadeVertexList.push_back(
27 std::move(vk));
28 return ptr->vk_fitterControl->getCascadeEvent()
29 ->cascadeVertexList.back()
30 .get();
31}
32
33VKVertex *addCascadeEntry(std::unique_ptr<VKVertex> vk) {
34 auto *ptr = vk.get();
35 ptr->vk_fitterControl->getCascadeEvent()->cascadeNV++;
36 ptr->vk_fitterControl->getCascadeEvent()->cascadeVertexList.push_back(
37 std::move(vk));
38 return ptr->vk_fitterControl->getCascadeEvent()
39 ->cascadeVertexList.back()
40 .get();
41}
42
43VKVertex *addCascadeEntry(std::unique_ptr<VKVertex> vk,
44 const std::vector<int> &index) {
45 for (int i = 0; i < (int)index.size(); i++) {
46 VKVertex *predecessor = vk->vk_fitterControl->getCascadeEvent()
47 ->cascadeVertexList.at(index[i])
48 .get();
49 if (predecessor->nextCascadeVrt)
50 std::cout << "VKalVrtCore: ERROR 1 in CASCADE creation !!!" << '\n';
51 predecessor->nextCascadeVrt = vk.get();
52 vk->includedVrt.push_back(predecessor);
53 }
54 //
55 auto *ptr = vk.get();
56 ptr->vk_fitterControl->getCascadeEvent()->cascadeNV++;
57 ptr->vk_fitterControl->getCascadeEvent()->cascadeVertexList.push_back(
58 std::move(vk));
59 return ptr->vk_fitterControl->getCascadeEvent()
60 ->cascadeVertexList.back()
61 .get();
62}
63//==================================================================================
64// Creation of VKalVrtCore arrays and structures needed for fit and first fit
65// without any constraints to get approximate vertices and track parameters
66//
67int initCascadeEngine(CascadeEvent &cascadeEvent_) {
68 VKVertex *VRT;
69 long int IERR = 0, iv, i;
70 // ---------------- Fisrt fit without any constraints at all, just vertices
71 for (i = 0; i < 4; i++) {
72 for (iv = 0; iv < cascadeEvent_.cascadeNV; iv++) {
73 VRT = cascadeEvent_.cascadeVertexList[iv].get();
74 IERR = fitVertexCascade(VRT, 0);
75 if (IERR)
76 return IERR; // fit
77 IERR = setVTrackMass(VRT);
78 if (IERR)
79 return IERR; // mass of combined particle
80 if (!VRT->includedVrt
81 .empty()) { // Save fitted vertex as target for "pass near"
82 // constraint in previous vertex
83 for (int pseu = 0; pseu < (int)VRT->includedVrt.size(); pseu++) {
84 VRT->includedVrt[pseu]->FVC.vrt[0] = VRT->refIterV[0] + VRT->fitV[0];
85 VRT->includedVrt[pseu]->FVC.vrt[1] = VRT->refIterV[1] + VRT->fitV[1];
86 VRT->includedVrt[pseu]->FVC.vrt[2] = VRT->refIterV[2] + VRT->fitV[2];
87 std::copy(VRT->fitVcov, VRT->fitVcov + 6,
88 VRT->includedVrt[pseu]->FVC.covvrt);
89 }
90 }
91 }
92 IERR = translateToFittedPos(cascadeEvent_);
93 if (IERR)
94 return IERR;
95 }
96 return IERR;
97}
98
99} // namespace
100
101namespace Trk {
102//=================================================================================================
103// Main cascade definition entry
104//
105// Reference and iteration reference points are set to (0,0,0). Track weight
106// matrices are computed.
107//
108// If predessor vertices point to current one, container tracks are created for
109// combined particles
110// from them.
111//
112// vertexDefinition[iv][it] - list of real track to vertex associacion
113// cascadeDefinition[iv][ipv] - for given vertex IV the list of previous
114// vertices pointing to it.
115//
116int makeCascade(VKalVrtControl &FitCONTROL, long int NTRK, const long int *ich,
117 double *wm, double *inp_Trk5, double *inp_CovTrk5,
118 const std::vector<std::vector<int> > &vertexDefinition,
119 const std::vector<std::vector<int> > &cascadeDefinition,
120 double definedCnstAccuracy /*=1.e-4*/) {
121 long int tk;
122 int iv, it;
123 if (vertexDefinition.size() != cascadeDefinition.size()) {
124 std::cout << " WRONG INPUT!!!" << '\n';
125 return -1;
126 }
127
128 long int IERR;
129 int NV = vertexDefinition.size();
130 double xyz[3] = {0.};
131 double tmp[15] = {0.};
132 double tmpWgt[15], out[3];
133 double vBx, vBy, vBz;
134 VKTrack *trk;
135 int vEstimDone = 0;
136
137 for (iv = 0; iv < NV; iv++) {
138 auto VRT = std::make_unique<VKVertex>(FitCONTROL);
139 VRT->setRefV(xyz); // ref point
140 VRT->setRefIterV(xyz); // iteration ref. point
141 VRT->setIniV(xyz);
142 VRT->setCnstV(xyz); // initial guess. 0 of course.
143 auto arr = std::make_unique<double[]>(vertexDefinition[iv].size() * 5);
144 int NTv = vertexDefinition[iv].size();
145 for (it = 0; it < NTv; it++) {
146 tk = vertexDefinition[iv][it];
147 if (tk >= NTRK) {
148 return -1;
149 }
150 VRT->TrackList.emplace_back(new VKTrack(
151 tk, &inp_Trk5[tk * 5], &inp_CovTrk5[tk * 15], VRT.get(), wm[tk]));
152 VRT->tmpArr.emplace_back(new TWRK());
153 trk = VRT->TrackList[it].get();
154 trk->Charge = ich[tk];
155 trk->iniP[0] = trk->cnstP[0] = trk->fitP[0] =
156 inp_Trk5[tk * 5 + 2]; // initial guess
157 trk->iniP[1] = trk->cnstP[1] = trk->fitP[1] = inp_Trk5[tk * 5 + 3];
158 trk->iniP[2] = trk->cnstP[2] = trk->fitP[2] = inp_Trk5[tk * 5 + 4];
159 IERR = cfInv5(&inp_CovTrk5[tk * 15], tmpWgt);
160 if (IERR)
161 IERR = cfdinv(&inp_CovTrk5[tk * 15], tmpWgt, 5);
162 if (IERR) {
163 return -1;
164 }
165 trk->setCurrent(&inp_Trk5[tk * 5], tmpWgt);
166 arr[it * 5] = inp_Trk5[tk * 5];
167 arr[it * 5 + 1] = inp_Trk5[tk * 5 + 1];
168 arr[it * 5 + 2] = inp_Trk5[tk * 5 + 2];
169 arr[it * 5 + 3] = inp_Trk5[tk * 5 + 3];
170 arr[it * 5 + 4] = inp_Trk5[tk * 5 + 4];
171 }
172 if (NTv > 1) { // First estimation of vertex position if vertex has more
173 // than 2 tracks
174 vEstimDone = 1;
176 VRT->refIterV[2], vBx, vBy, vBz,
177 (VRT->vk_fitterControl).get());
178 double aVrt[3] = {0., 0., 0.};
179 for (int i = 0; i < NTv - 1; i++)
180 for (int j = i + 1; j < NTv; j++) {
181 vkvFastV(&arr[i * 5], &arr[j * 5], xyz, vBz, out);
182 aVrt[0] += out[0];
183 aVrt[1] += out[1];
184 aVrt[2] += out[2];
185 }
186 aVrt[0] /= (NTv * (NTv - 1) / 2);
187 aVrt[1] /= (NTv * (NTv - 1) / 2);
188 aVrt[2] /= (NTv * (NTv - 1) / 2);
189 VRT->setRefIterV(aVrt); // iteration ref. point
190 }
191 if (iv == 0) { // start cascade creation
192 startCascade(std::move(VRT));
193 continue;
194 }
195 int includeNV = cascadeDefinition[iv].size();
196 if (!includeNV) { // no predecessors
197 addCascadeEntry(std::move(VRT));
198 } else {
199 auto *vrttemp = addCascadeEntry(std::move(VRT), cascadeDefinition[iv]);
200 for (it = 0; it < includeNV;
201 it++) { // tracks created out of predecessing vertices
202 vrttemp->TrackList.emplace_back(
203 new VKTrack(-999, tmp, tmp, vrttemp, 0.));
204 vrttemp->tmpArr.emplace_back(new TWRK());
205 }
206 }
207 }
208 //
209 // ---------------- If some vertex positions are different from (0,0,0) -
210 // move tracks there
211 if (vEstimDone) {
212 IERR = translateToFittedPos(*(FitCONTROL.getCascadeEvent()), 1.);
213 if (IERR)
214 return IERR;
215 for (iv = 0; iv < FitCONTROL.getCascadeEvent()->cascadeNV; iv++) {
216 auto *VRT = FitCONTROL.getCascadeEvent()->cascadeVertexList[iv].get();
217 int NTv = VRT->TrackList.size(); // Number of tracks at vertex
218 for (it = 0; it < NTv; it++) {
219 trk = VRT->TrackList[it].get();
220 if (trk->Id < 0)
221 continue; // pseudo-track from cascade vertex
222 trk->cnstP[0] = trk->iniP[0] = trk->fitP[0] = trk->Perig[2];
223 trk->cnstP[1] = trk->iniP[1] = trk->fitP[1] = trk->Perig[3];
224 trk->cnstP[2] = trk->iniP[2] = trk->fitP[2] = trk->Perig[4];
225 }
226 }
227 }
228 // ---------------- Init engine
229
230 IERR = initCascadeEngine(*FitCONTROL.getCascadeEvent());
231 FitCONTROL.getCascadeEvent()->setAccuracyConstraint(definedCnstAccuracy);
232
233 return IERR;
234}
235
236//==================================================================================
237// Mass constraints for DEFINED cascade. So may be called only after
238// makeCascade!!!
239//
240// For complete vertex
241int setCascadeMassConstraint(CascadeEvent &cascadeEvent_, long int IV,
242 double Mass) {
243 if (IV > cascadeEvent_.cascadeNV - 1) {
244 return -1; // error in format
245 }
246 if (IV < 0) {
247 return -1;
248 }
249 VKVertex *vk = cascadeEvent_.cascadeVertexList[IV].get(); // target vertex
250 int NTRK = vk->TrackList.size();
251 vk->ConstraintList.emplace_back(new VKMassConstraint(NTRK, Mass, vk));
252 return 0;
253}
254//-----------------------------------------
255// For subset of tracks in vertex.
256// trkInVrt,pseudoInVrt - list of indexes of participating tracks/pseudos in
257// given vertex Tracks and pseudotracks are in the common list - tracks first,
258// pseudotracks after
259//
260int setCascadeMassConstraint(CascadeEvent &cascadeEvent_, long int IV,
261 std::vector<int> &trkInVrt,
262 std::vector<int> &pseudoInVrt, double Mass) {
263 std::vector<int> tmpIndex;
264 int it;
265 if (IV > cascadeEvent_.cascadeNV - 1)
266 return -1; // error in format
267 if (IV < 0)
268 return -1;
269 VKVertex *vk = cascadeEvent_.cascadeVertexList[IV].get(); // target vertex
270 int NTRK = vk->TrackList.size(); // tracks+pseudotracks
271 int nRealTrk = 0; // number of real tracks
272 for (it = 0; it < (int)trkInVrt.size(); it++) {
273 if (vk->TrackList[it]->Id >= 0) {
274 nRealTrk++;
275 }
276 }
277 //
278 //-- Real tracks
279 //
280 if ((int)trkInVrt.size() > NTRK) {
281 return -1; // checks...
282 }
283 for (it = 0; it < (int)trkInVrt.size(); it++) {
284 if (trkInVrt[it] < 0) {
285 return -1;
286 }
287 if (trkInVrt[it] >= NTRK) {
288 return -1;
289 }
290 tmpIndex.push_back(trkInVrt[it]);
291 }
292 //
293 //-- Pseudo tracks
294 //
295 if ((int)pseudoInVrt.size() > NTRK) {
296 return -1; // checks...
297 }
298 for (int it = 0; it < (int)pseudoInVrt.size(); it++) {
299 if (pseudoInVrt[it] < 0) {
300 return -1;
301 }
302 if (pseudoInVrt[it] >= NTRK) {
303 return -1;
304 }
305 tmpIndex.push_back(pseudoInVrt[it] + nRealTrk);
306 }
307
308 vk->ConstraintList.emplace_back(
309 new VKMassConstraint(NTRK, Mass, std::move(tmpIndex), vk));
310 return 0;
311}
312
313} // namespace Trk
#define xyz
void setAccuracyConstraint(double C)
std::vector< std::unique_ptr< VKVertex > > cascadeVertexList
void setCurrent(const double[], const double[])
void setRefIterV(double v[]) noexcept
void setCnstV(double v[3]) noexcept
std::vector< VKVertex * > includedVrt
void setIniV(double v[3]) noexcept
std::vector< std::unique_ptr< VKTrack > > TrackList
std::vector< std::unique_ptr< VKConstraintBase > > ConstraintList
void setRefV(double v[3]) noexcept
std::vector< std::unique_ptr< TWRK > > tmpArr
VKVertex * nextCascadeVrt
std::unique_ptr< VKalVrtControl > vk_fitterControl
const CascadeEvent * getCascadeEvent() const
static void getMagFld(const double, const double, const double, double &, double &, double &, const VKalVrtControlBase *)
Ensure that the ATLAS eigen extensions are properly loaded.
int translateToFittedPos(CascadeEvent &cascadeEvent_, double Step)
int cfInv5(double *cov, double *wgt)
int setCascadeMassConstraint(CascadeEvent &cascadeEvent_, long int IV, double Mass)
int cfdinv(double *cov, double *wgt, long int NI)
int setVTrackMass(VKVertex *vk)
int makeCascade(VKalVrtControl &FitCONTROL, long int NTRK, const long int *ich, double *wm, double *inp_Trk5, double *inp_CovTrk5, const std::vector< std::vector< int > > &vertexDefinition, const std::vector< std::vector< int > > &cascadeDefinition, double definedCnstAccuracy)
int fitVertexCascade(VKVertex *vk, int Pointing)
double vkvFastV(double *p1, double *p2, const double *vRef, double dbmag, double *out)
Definition VKvFast.cxx:42
void * ptr(T *p)
Definition SGImplSvc.cxx:74
Definition index.py:1