42 return StatusCode::SUCCESS;
50 auto bccd=std::make_unique<BunchCrossingCondData>();
58 return StatusCode::FAILURE;
65 if (bgs->
size() >= 2) {
68 bccd->m_beam1.set(pos);
69 bccd->m_beam2.set(pos);
70 bccd->m_luminous.set(pos);
78 if (bgs->
size() >= 15) {
80 bccd->m_beam1.set(pos);
83 bccd->m_beam2.set(pos);
89 const auto& thisevt = ctx.eventID();
90 EventIDRange range = EventIDRange(EventIDBase(thisevt.run_number(), EventIDBase::UNDEFEVT,
91 EventIDBase::UNDEFNUM, 0, thisevt.lumi_block()),
92 EventIDBase(thisevt.run_number(), EventIDBase::UNDEFEVT,
93 EventIDBase::UNDEFNUM, 0, thisevt.lumi_block()+1));
102 float avMu = prefLumiHdl->lbAverageInteractionsPerCrossing();
103 const auto& lumiVec = prefLumiHdl->lbLuminosityPerBCIDVector();
104 float cutLumi = avMu/1000.f*prefLumiHdl->muToLumi();
107 if (lumiVec[bcid] > cutLumi) {
108 bccd->m_beam1.set(bcid);
109 bccd->m_beam2.set(bcid);
110 bccd->m_luminous.set(bcid);
119 std::string sbunches;
125 bool foundInDigitization =
false;
133 ATH_MSG_INFO(
"Got AttributeList with size " << attrList->size());
135 const coral::Attribute& attr=(*attrList)[std::string(
"BeamIntensityPattern")];
136 if (!attr.isNull()) {
137 sbunches = attr.data< std::string >();
138 foundInDigitization =
true;
139 ATH_MSG_DEBUG(
"Read BeamIntensityPattern from Digitization folder");
141 }
catch (coral::AttributeListException& e) {
142 ATH_MSG_DEBUG(
"Could not read from Digitization folder: " << e.what());
148 if (!foundInDigitization) {
151 if (bsMetadata.
isValid() && !bsMetadata->empty()) {
153 const std::vector<std::string>& freeStrings = metadata->getFreeMetaDataStrings();
155 for (
const std::string&
str : freeStrings) {
156 if (
str.starts_with(
"IOVMeta./Digitization/Parameters=")) {
157 size_t eqPos =
str.find(
'=');
158 if (eqPos != std::string::npos && eqPos + 1 <
str.size()) {
159 std::string jsonStr =
str.substr(eqPos + 1);
162 nlohmann::json iovMetadata = nlohmann::json::parse(jsonStr);
164 if (iovMetadata.contains(
"iovs") && iovMetadata[
"iovs"].is_array() && !iovMetadata[
"iovs"].empty()) {
165 const auto& firstIov = iovMetadata[
"iovs"][0];
166 if (firstIov.contains(
"attrs")) {
167 for (
const auto& chanItem : firstIov[
"attrs"].items()) {
168 const auto& chanAttrs = chanItem.value();
169 if (chanAttrs.contains(
"BeamIntensityPattern")) {
170 sbunches = chanAttrs[
"BeamIntensityPattern"].get<std::string>();
171 ATH_MSG_INFO(
"Read BeamIntensityPattern from ByteStream metadata");
175 if (!sbunches.empty())
break;
178 }
catch (
const std::exception& e) {
179 ATH_MSG_WARNING(
"Failed to parse IOV metadata from ByteStream: " << e.what());
186 if (sbunches.empty()) {
187 ATH_MSG_ERROR(
"Could not read BeamIntensityPattern from either Digitization folder or ByteStream metadata");
188 return StatusCode::FAILURE;
192 const float minBunchIntensity=0.001;
193 std::vector<float> bunches=
tokenize(sbunches);
194 if (!bunches.empty()) {
203 const int pos1 = i % bunches.size();
204 const int pos2 = bunches.size() - 1 - ( i % bunches.size() );
205 if( bunches[ pos1 ] > minBunchIntensity) {
206 bccd->m_beam1.set(i);
207 bccd->m_beam2.set(i);
208 bccd->m_luminous.set(i);
210 if( bunches[ pos2 ] > minBunchIntensity) {
222 const int pos = i % bunches.size();
223 if( bunches[ pos ] > minBunchIntensity) {
224 bccd->m_beam1.set(i);
225 bccd->m_beam2.set(i);
226 bccd->m_luminous.set(i);
234 ATH_MSG_INFO(
"Bunch structure information not found in metadata");
235 ATH_MSG_INFO(
"Will consider all BCIDs as single filled bunches (no trains)");
238 bccd->m_luminous.set();
244 attrList = *fillParamsHdl;
246 if ((*attrList)[
"BCIDmasks"].isNull()) {
248 return StatusCode::FAILURE;
253 cool::UInt32 nb1 = (*attrList)[
"Beam1Bunches"].data<cool::UInt32>();
254 cool::UInt32 nb2 = (*attrList)[
"Beam2Bunches"].data<cool::UInt32>();
255 cool::UInt32 ncol = (*attrList)[
"LuminousBunches"].data<cool::UInt32>();
261 const coral::Blob& blob = (*attrList)[
"BCIDmasks"].data<coral::Blob>();
266 if (
static_cast<cool::UInt32
>( blob.size() ) != 2 * (nb1 + nb2 + ncol)) {
267 ATH_MSG_WARNING(
"BCIDmasks length " << blob.size() <<
" != 2 * " << (nb1+nb2+ncol) );
268 return StatusCode::SUCCESS;
270 const uint16_t* blobAddr=
static_cast<const uint16_t*
>(blob.startingAddress());
272 for (
size_t idx=0;idx<nb1;++idx) {
273 const uint32_t bcid=blobAddr[idx];
274 bccd->m_beam1.set(bcid);
278 for (
size_t idx=nb1;idx<nb2;++idx) {
279 const uint32_t bcid=blobAddr[idx];
280 bccd->m_beam2.set(bcid);
284 for (
size_t idx=nb2;idx<ncol;++idx) {
285 const uint32_t bcid=blobAddr[idx];
286 bccd->m_luminous.set(bcid);
295 return StatusCode::FAILURE;
297 const uint8_t* blobAddr=
static_cast<const uint8_t*
>(blob.startingAddress());
299 if (blobAddr[bcid] & 0x1) {
300 bccd->m_beam1.set(bcid);
302 if (blobAddr[bcid] & 0x2) {
303 bccd->m_beam2.set(bcid);
305 if ((blobAddr[bcid] & 0x3) == 0x3) {
306 bccd->m_luminous.set(bcid);
311 if (bccd->m_beam1.count()!= nb1) {
312 ATH_MSG_WARNING(
"Found " << bccd->m_beam1.count() <<
" bunches in beam1, expected " << nb1);
315 if (bccd->m_beam2.count()!= nb2) {
316 ATH_MSG_WARNING(
"Found " << bccd->m_beam2.count() <<
" bunches in beam2, expected " << nb2);
319 if (bccd->m_luminous.count()!= ncol) {
320 ATH_MSG_WARNING(
"Found " << bccd->m_luminous.count() <<
" colliding bunches, expected " << ncol);
329 return StatusCode::SUCCESS;
333std::vector<BunchCrossingCondData::bunchTrain_t>
BunchCrossingCondAlg::findTrains(
const std::bitset< BunchCrossingCondData::m_MAX_BCID>& collidingBCIDs,
const int maxSpacingInTrain,
const unsigned minBunchesPerTrain)
const {
335 const int MAX_BCID=collidingBCIDs.size();
336 std::vector<bunchTrain_t>
result;
338 std::vector<std::pair<int,int> > holes;
342 while (stop<MAX_BCID) {
343 for (start=stop;stop<MAX_BCID && !collidingBCIDs.test(stop); ++stop) {};
345 if ((stop-start)>maxSpacingInTrain) {
346 holes.emplace_back(start,stop);
352 ATH_MSG_DEBUG(
"Found " << holes.size() <<
" gaps larger than " << maxSpacingInTrain <<
" in the bunch structure");
353 if (
msgLvl(MSG::VERBOSE)) {
354 for (
auto&
h : holes) {
355 msg(MSG::VERBOSE) <<
"Hole: " <<
h.first <<
" - " <<
h.second <<
endmsg;
361 ATH_MSG_ERROR(
"Looks like we have bunch train spanning the entire ring w/o any gap. Really?");
366 if (holes.size()>1) {
368 for (
unsigned i=0;i<holes.size()-1;++i) {
371 for (
int idx=holes[i].second;idx<holes[i+1].first-1;++idx) {
372 if (collidingBCIDs.test(idx)) {
376 result.emplace_back(holes[i].second,holes[i+1].first-1,ncoll);
380 if (holes.size()==1 || (holes.front().first!=0 && holes.back().second!=MAX_BCID-1)) {
389 for (
int idx=0;idx<holes.front().first;++idx) {
390 if (collidingBCIDs.test(idx)) {
394 for (
int idx=holes.back().second;idx<MAX_BCID;++idx) {
395 if (collidingBCIDs.test(idx)) {
403 result.push_back(lasttrain);
407 ATH_MSG_DEBUG(
"Found " <<
result.size() <<
" Bunch trains separated by gaps of at least " << maxSpacingInTrain <<
" bcids ");
410 std::vector<bunchTrain_t> result1;
411 result1.reserve(
result.size());
413 if (train.m_nColl >= minBunchesPerTrain) {
414 result1.emplace_back(train);
418 ATH_MSG_INFO(
"Found " << result1.size() <<
" Bunch trains having at least " << minBunchesPerTrain <<
" colliding bunches and separated by at least " << maxSpacingInTrain <<
" bcids");
421 if (
msgLvl(MSG::VERBOSE)) {
422 for (
auto&
r : result1) {
423 msg(MSG::VERBOSE) <<
"Train " <<
r.m_first <<
" - " <<
r.m_last <<
", " <<
r.m_nColl <<
" colliding bcids" <<
endmsg;