Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
/* Copyright (C) 2016-2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
SPDX-License-Identifier: GPL-3.0-only
Authors: Sergey Gorbunov, Sergei Zharko [committer] */
/************************************************************************************************************
* @file L1InitManager.cxx
* @bried Input data management class for L1Algo
* @since 19.01.2022
*
***********************************************************************************************************/
#include "L1InitManager.h"
#include <algorithm>
//-----------------------------------------------------------------------------------------------------------------------
//
void L1InitManager::AddStation(const L1BaseStationInfo& inStation)
{
// Check if other fields were defined already
// Active detector IDs
if (!fInitFlags[L1InitManager::kEactiveDetectorIDs]) {
LOG(error)
<< "L1InitManager::AddStation: station initialization called before the active detectors set had been initialized";
assert((fInitFlags[L1InitManager::kEactiveDetectorIDs]));
}
// Number of stations check
if (!fInitFlags[L1InitManager::kEstationsNumberCrosscheck]) {
LOG(error)
<< "L1InitManager::AddStation: station initialization called before the numbers of stations for each detector "
<< "had been initialized";
assert((fInitFlags[L1InitManager::kEstationsNumberCrosscheck]));
}
// Field function
if (!fInitFlags[L1InitManager::kEfieldFunction]) {
LOG(error)
<< "L1InitManager::AddStation: station initialization called before the magnetic field function was intialized";
assert((fInitFlags[L1InitManager::kEfieldFunction]));
}
// Check activeness of this station type
bool isDetectorActive = fActiveDetectorIDs.find(inStation.GetDetectorID()) != fActiveDetectorIDs.end();
if (isDetectorActive) {
// initialize magnetic field slice
L1BaseStationInfo inStationCopy = L1BaseStationInfo(inStation); // make a copy of station so it can be initialized
inStationCopy.SetFieldSlice(fFieldFunction);
bool isStationInitialized = inStationCopy.IsInitialized();
if (!isStationInitialized) {
LOG(debug) << "L1InitManager::AddStation: station init flags (original)" << inStation.GetInitFlags();
LOG(debug) << "L1InitManager::AddStation: station init flags (copy) " << inStation.GetInitFlags();
LOG(error)
<< "L1InitManager::AddStation: Trying to add incompletely initialized object with detectorID = "
<< static_cast<int>(inStationCopy.GetDetectorID()) << " and stationID = " << inStationCopy.GetStationID();
assert((isStationInitialized));
}
// insert the station in a set
auto insertionResult = fStationsInfo.insert(std::move(inStationCopy));
if (!insertionResult.second) {
LOG(error)
<< "L1InitManager::AddStation: attempt to insert a dublicating L1BaseStationInfo with StationID = "
<< inStation.GetStationID() << " and DetectorID = " << static_cast<int>(inStation.GetDetectorID()) << ":";
LOG(error) << ">>> Already inserted L1BaseStationInfo object:";
insertionResult.first->Print();
LOG(error) << ">>> A dublicating L1BaseStationInfo object:";
inStation.Print();
assert((insertionResult.second)); // TODO: rewrite the assertion
}
}
LOG(debug)
<< "L1InitManager: adding a station with stationID = " << inStation.GetStationID() << " and detectorID = "
<< static_cast<int>(inStation.GetDetectorID()) << ". Is active: " << isDetectorActive;
}
//-----------------------------------------------------------------------------------------------------------------------
//
void L1InitManager::Init() const
{ // To be implemented
// Plans:
// 1. Must make a final check of the inititalization and turn on a corresponding trigger in L1Algo class to accept
// the incoming data
}
//-----------------------------------------------------------------------------------------------------------------------
//
void L1InitManager::PrintStations(int verbosityLevel) const
{
if (verbosityLevel < 1) {
for (auto& station : fStationsInfo) {
LOG(info) << "----------- station: ";
LOG(info) << "\ttype = " << station.GetStationType(); // TMP
LOG(info) << "\tz = " << station.GetZdouble();
}
}
else {
for (auto& station : fStationsInfo) {
station.Print();
}
}
}
//-----------------------------------------------------------------------------------------------------------------------
//
void L1InitManager::TransferL1StationArray(std::array<L1Station, L1Parameters::kMaxNstations>& destinationArray)
{
/// First of all, we must check if L1Station was properly initialized
// TODO: actually, false condition will never reached (must thing about it, may be remove assertions from
// CheckStationInfo and leave only warnings and flag)
bool ifStationsInitialized = CheckStationsInfo();
if (!ifStationsInitialized) {
LOG(error) << "L1InitManager::TransferL1StationArray: attempt to pass unitialized L1Station array to L1Algo core";
assert((ifStationsInitialized));
}
/// Check if destinationArraySize is enough for the transfer
int totalStationsNumber = this->GetStationsNumber();
bool ifDestinationArraySizeOk = totalStationsNumber <= static_cast<int>(destinationArray.size());
if (!ifDestinationArraySizeOk) {
LOG(error)
<< "L1InitManager::TransferL1StationArray: destination array size (" << destinationArray.size()
<< ") is smaller then actual number of active tracking stations (" << totalStationsNumber << ")";
assert((ifDestinationArraySizeOk));
}
auto destinationArrayIterator = destinationArray.begin();
for (const auto& item: fStationsInfo) {
*destinationArrayIterator = std::move(item.GetL1Station());
++destinationArrayIterator;
}
LOG(info) << "L1InitManager: L1Station vector was successfully transfered to L1Algo core :)";
}
//
// GETTERS
//
//-----------------------------------------------------------------------------------------------------------------------
//
int L1InitManager::GetStationsNumber(L1DetectorID detectorID) const
{
auto ifDetectorIdDesired = [&detectorID](const L1BaseStationInfo& station) {
return station.GetDetectorID() == detectorID;
};
return std::count_if(fStationsInfo.begin(), fStationsInfo.end(), ifDetectorIdDesired);
}
//
// SETTERS
//
//-----------------------------------------------------------------------------------------------------------------------
//
void L1InitManager::SetActiveDetectorIDs(const std::set<L1DetectorID>& detectorIDs)
{
// TODO: To think about redifinition possibilities: should it be allowed or not?
fActiveDetectorIDs = detectorIDs;
fInitFlags[L1InitManager::kEactiveDetectorIDs] = true;
}
//-----------------------------------------------------------------------------------------------------------------------
//
void L1InitManager::SetFieldFunction(const std::function<void(const double (&xyz)[3], double (&B)[3])>& fieldFunction)
{
if (!fInitFlags[L1InitManager::kEfieldFunction]) {
fFieldFunction = fieldFunction;
fInitFlags[L1InitManager::kEfieldFunction] = true;
}
else {
LOG(warn) << "L1InitManager::SetFieldFunction: attemt to reinitialize the field function. Ignored";
}
}
//-----------------------------------------------------------------------------------------------------------------------
//
void L1InitManager::SetStationsNumberCrosscheck(L1DetectorID detectorID, int nStations)
{
// NOTE: We add and check only those detectors which will be active (?)
// For INACTIVE detectors the initialization code for it inside CbmL1/BmnL1 can (and must) be still in,
// but it will be ignored inside L1InitManager.
if (fActiveDetectorIDs.find(detectorID) != fActiveDetectorIDs.end()) {
fStationsNumberCrosscheck[detectorID] = nStations;
}
// Check if all the station numbers for active detectors are initialized now:
LOG(debug) << "SetStationsNumberCrosscheck called for detectorID = " << static_cast<int>(detectorID);
if (!fInitFlags[L1InitManager::kEstationsNumberCrosscheck]) {
bool ifInitialized = true;
for (auto item: fActiveDetectorIDs) {
if (fStationsNumberCrosscheck.find(item) == fStationsNumberCrosscheck.end()) {
LOG(warn)
<< "L1InitManager::SetStationsNumberCrosscheck: uninitialized number of stations for detectorID = "
<< static_cast<int>(item);
ifInitialized = false;
break;
}
}
fInitFlags[L1InitManager::kEstationsNumberCrosscheck] = ifInitialized;
}
LOG(debug) << "InitResult: " << fInitFlags[L1InitManager::kEstationsNumberCrosscheck];
}
//-----------------------------------------------------------------------------------------------------------------------
//
void L1InitManager::SetReferencePrimaryVertexPoints(double z0, double z1, double z2)
{
if (fInitFlags[L1InitManager::kEprimaryVertexField]) {
LOG(warn)
<< "L1InitManager::SetReferencePrimaryVertexPoints: attempt to redefine reference points for field calculation "
<< "near primary vertex. Ignore";
return;
}
// Check for field function
if (!fInitFlags[L1InitManager::kEfieldFunction]) {
LOG(error)
<< "L1InitManager::SetReferencePrimaryVertexPoints: attempt to set reference points for field calculation near "
<< "primary vertex before the magnetic field function intialization";
assert((fInitFlags[L1InitManager::kEfieldFunction]));
}
constexpr int numberOfDimensions {3};
constexpr int numberOfReferencePoints {3};
std::array<double, numberOfReferencePoints> inputZ = { z0, z1, z2 }; // tmp array to store input assigned with index
std::array<L1FieldValue, numberOfReferencePoints> B = {};
std::array<fvec, numberOfReferencePoints> z = { z0, z1, z2 };
for (int idx = 0; idx < numberOfReferencePoints; ++idx) {
double point[numberOfDimensions] = {0., 0., inputZ[idx] };
double field[numberOfDimensions] = {};
fFieldFunction(point, field);
B[idx].x = field[0];
B[idx].y = field[1];
B[idx].z = field[2];
}
fPrimaryVertexFieldRegion.Set(B[0], z[0], B[1], z[1], B[2], z[2]);
fPrimaryVertexFieldValue = B[0];
fInitFlags[L1InitManager::kEprimaryVertexField] = true;
}
//-----------------------------------------------------------------------------------------------------------------------
//
bool L1InitManager::CheckStationsInfo()
{
if (!fInitFlags[L1InitManager::kEstationsInfo]) {
bool ifInitPassed = true;
if (!fInitFlags[L1InitManager::kEifStationNumbersChecked]) {
for (const auto& itemDetector: fActiveDetectorIDs) {
int actualStationsNumber = GetStationsNumber(itemDetector);
int expectedStationsNumber = fStationsNumberCrosscheck.at(itemDetector);
if (actualStationsNumber != expectedStationsNumber) {
LOG(error)
<< "L1InitManager::CheckStationsInfo: Incorrect number of L1BaseStationInfo objects passed to the L1Manager "
<< "for L1DetectorID = " << static_cast<int>(itemDetector) << ": " << actualStationsNumber << " of "
<< expectedStationsNumber << " expected";
ifInitPassed = false;
}
}
fInitFlags[L1InitManager::kEifStationNumbersChecked] = ifInitPassed;
}
if (!ifInitPassed) {
LOG(error) << "L1InitManager::CheckStationsInfo: initialization failed";
assert((ifInitPassed));
}
// Check for maximum allowed number of stations
int totalStationsNumber = GetStationsNumber();
if (totalStationsNumber > L1Parameters::kMaxNstations) {
LOG(fatal)
<< "Actual total number of registered stations (" << totalStationsNumber << ") is larger then designed one ("
<< L1Parameters::kMaxNstations << "). Please, select another set of active tracking detectors";
// TODO: We have to provide an instruction of how to increase the kMaxNstations number keeping the code consistent
assert((totalStationsNumber <= L1Parameters::kMaxNstations));
}
fInitFlags[L1InitManager::kEstationsInfo] = true;
}
else {
LOG(warn) << "L1InitManager: L1BaseStationInfo set has already been initialized";
}
// NOTE: we return a flag here to reduce a number of calls outside the funcition. In other hands we keep this flag
// to be consistent with other class fields initialization rules
return fInitFlags[L1InitManager::kEstationsInfo];
}