12 #include "CLHEP/Random/RandGaussZiggurat.h"
13 #include "CoralBase/Attribute.h"
14 #include "CoralBase/AttributeListSpecification.h"
15 #include "GaudiKernel/PhysicalConstants.h"
41 #include "GeoModelKernel/throwExcept.h"
69 ATH_MSG_DEBUG(
" initialize Random Number Service: running with t0 shift "
74 ATH_MSG_ERROR(
"Could not get random number engine from AthRNGSvc. Abort.");
75 return StatusCode::FAILURE;
80 ATH_MSG_INFO(
"************************************" << std::endl
81 <<
" Running with Calibration Deformations! " << std::endl
82 <<
" For performance studies only!" << std::endl
83 <<
" **************************************");
94 return StatusCode::SUCCESS;
101 if (
key.empty())
continue;
103 if (!readHandle.isValid()) {
104 ATH_MSG_FATAL(
"Failed to retrieve conditions object "<<readHandle.fullKey());
105 return StatusCode::FAILURE;
108 ATH_MSG_INFO(
"Size of CondAttrListCollection " << readHandle.fullKey() <<
" readCdoRt->size()= " << readHandle->size());
109 ATH_MSG_INFO(
"Range of input is " << readHandle.getRange());
113 if (!readHandle.isValid()) {
115 return StatusCode::FAILURE;
117 if (readHandle->hasDCS()) {
120 return StatusCode::SUCCESS;
125 if (writeHandle.isValid()) {
126 ATH_MSG_DEBUG(
"CondHandle " << writeHandle.fullKey() <<
" is already valid."
127 <<
". In theory this should not be called, but may happen"
128 <<
" if multiple concurrent events are being processed out of order.");
129 return StatusCode::SUCCESS;
136 gran = RegionGranularity::OneRt;
138 ATH_MSG_DEBUG(
"Save one set of calibration constants per multi layer");
139 gran = RegionGranularity::OnePerMultiLayer;
140 }
else ATH_MSG_DEBUG(
"Save one set of calibration constants per chamber");
141 std::unique_ptr<MuonCalib::MdtCalibDataContainer> writeCdo = std::make_unique<MuonCalib::MdtCalibDataContainer>(
m_idHelperSvc.get(), gran);
145 ATH_CHECK(writeHandle.record(std::move(writeCdo)));
146 return StatusCode::SUCCESS;
155 return StatusCode::FAILURE;
168 for (
unsigned int n = 0;
n <
rts.nRts(); ++
n) {
169 std::unique_ptr<MuonCalib::RtDataFromFile::RtRelation> rt(
rts.getRt(
n));
176 if (
times.size() < 2) {
178 return StatusCode::FAILURE;
181 if (
times.size() != radii.size() ||
times.size() != reso.size()) {
183 return StatusCode::FAILURE;
186 double t_min =
times[0];
187 double bin_size =
times[1] - t_min;
190 return StatusCode::FAILURE;
196 rtPars.push_back(t_min);
197 rtPars.push_back(bin_size);
200 rtPars.insert(rtPars.end(), radii.begin(), radii.end());
206 resoPars.insert(resoPars.end(), reso.begin(), reso.end());
211 std::shared_ptr<MuonCalib::IRtRelation> rtRel{std::make_shared<RtRelationLookUp>(rtPars)};
212 std::shared_ptr<MuonCalib::IRtResolution> resoRel{std::make_shared<RtResolutionLookUp>(resoPars)};
222 RtRelationPtr MdtRt = std::make_shared<MuonCalib::MdtRtRelation>(rtRel, resoRel);
224 for(
auto itr = idHelper.detectorElement_begin();
225 itr!= idHelper.detectorElement_end();++itr){
236 if (idHelper.multilayer(detElId) == 2) {
237 if (writeCdo.
granularity() != RegionGranularity::OnePerMultiLayer)
continue;
238 const Identifier firstML = idHelper.multilayerID(detElId, 1);
248 if (!writeCdo.
storeData(detElId, storeMe, msgStream())) {
250 return StatusCode::FAILURE;
254 loadedRts[detElId] = MdtRt;
260 int npoints = rtRel->nPar() - 2;
262 for (
int ipt = 0; ipt <
npoints; ++ipt) {
263 double t = t_min + ipt * bin_size;
264 ATH_MSG_VERBOSE(
" " << ipt <<
" " <<
t <<
" " << rtRel->radius(
t) <<
" " << resoRel->resolution(
t));
271 return StatusCode::SUCCESS;
274 static std::atomic<bool> rtWarningPrinted =
false;
278 if (detEl) {
return std::make_optional<double>(detEl->
innerTubeRadius()); }
282 if (detEl) {
return std::make_optional<double>(detEl->
innerTubeRadius()); }
284 if (!rtWarningPrinted) {
285 ATH_MSG_WARNING(
"getInnerTubeRadius() - no Muon station known under the name "
287 rtWarningPrinted =
true;
293 std::string
data{}, delim{};
298 return StatusCode::FAILURE;
302 data = *(
static_cast<const std::string *
>((attr[
"data"]).addressOfData()));
308 return StatusCode::FAILURE;
314 unsigned int numPoints{0};
317 channel[
"appliedRT"] = rt_ts_applied;
322 if(tokensHeader.size()< 2){
323 ATH_MSG_FATAL(
"Failed to deduce extract number of points & calib Identifier from "<<
header);
324 return StatusCode::FAILURE;
326 unsigned int calibId = tokensHeader[0];
327 numPoints = tokensHeader[1];
331 return StatusCode::FAILURE;
335 ATH_MSG_WARNING(
"The translation from the calibration ID with station: "
336 <<
id.stationNameString()<<
"("<<
id.
stationName()<<
") "
337 <<
" eta:"<<
id.
eta()<<
" phi: "<<
id.
phi());
342 channel[
"ml"] = idHelper.multilayer(athenaId);
343 channel[
"layer"] = idHelper.tubeLayer(athenaId);
344 channel[
"tube"] = idHelper.tube(athenaId);
348 std::vector<double> radii{},
times{}, resos{};
349 radii.reserve(numPoints);
350 times.reserve(numPoints);
351 resos.reserve(numPoints);
355 for (
unsigned int k = 0 ;
k < dataPoints.size(); ++
k) {
356 const double value = dataPoints[
k];
359 radii.push_back(
value);
365 resos.push_back(
value);
372 if (radii.size() != numPoints ||
373 times.size() != numPoints ||
374 resos.size() != numPoints) {
375 ATH_MSG_FATAL(
"Payload "<<
payload<<
" does not lead to the expected number of points "<<numPoints<<
" vs. "<<dataPoints.size());
376 return StatusCode::FAILURE;
378 channel[
"radii"] = std::move(radii);
380 channel[
"resolutions"] = std::move(resos);
382 return StatusCode::SUCCESS;
390 if (!readHandleRt.isValid()) {
392 return StatusCode::FAILURE;
400 itr != readHandleRt->end(); ++itr) {
407 return StatusCode::FAILURE;
411 data = *(
static_cast<const std::string *
>((atr[
"data"]).addressOfData()));
415 for (
auto &
it :
yy.items()) {
417 rtCalibJson.push_back(yx);
424 itr != readHandleRt->end(); ++itr) {
431 for (
const auto&
payload : rtCalibJson) {
432 const bool rt_ts_applied =
payload[
"appliedRT"];
438 std::optional<double> innerTubeRadius =
getInnerTubeRadius(idHelper.multilayerID(athenaId, 1));
439 if (!innerTubeRadius)
continue;
442 const std::vector<double> radii =
payload[
"radii"];
444 const std::vector<double> resolutions =
payload[
"resolutions"];
457 std::vector<MuonCalib::SamplePoint> tr_points{}, ts_points{};
462 for (
unsigned int k = 0;
k < radii.size(); ++
k) {
468 radius = oldradius + rshift;
469 ATH_MSG_DEBUG(
"DEFORM RT: old radius " << oldradius <<
" new radius " <<
radius <<
" shift " << rshift
484 float sigma = resolutions[
k];
488 if (tr_point.
x2() < -99) {
489 multilayer_tmax_diff = tr_point.
x1();
490 }
else if (tr_points.empty() || (tr_points.back().x1() < tr_point.
x1() && tr_points.back().x2() < tr_point.
x2())) {
491 tr_points.push_back(tr_point);
492 ts_points.push_back(ts_point);
497 if (ts_points.size() < 3) {
499 return StatusCode::FAILURE;
503 float sign(rt_ts_applied ? -1.0 : 1.0);
505 for (
auto & tr_point : tr_points) {
506 int slice_number =
static_cast<int>(std::floor(tr_point.
x2() / slice_width));
507 if (slice_number < 0) slice_number = 0;
519 ATH_MSG_VERBOSE(point.x1() <<
"|" << point.x2() <<
"|" << point.error());
527 if (!reso || !rt) {
continue; }
529 if (rt->
par(1) == 0.) {
533 return StatusCode::FAILURE;
536 if (multilayer_tmax_diff > -8e8) { rt->
SetTmaxDiff(multilayer_tmax_diff); }
538 RtRelationPtr rt_rel = std::make_shared<MuonCalib::MdtRtRelation>(std::move(rt), std::move(reso));
540 if (!writeCdo.
storeData(athenaId ,rt_rel, msgStream()))
return StatusCode::FAILURE;
542 loadedRtRel[athenaId] = rt_rel;
547 if (loadedRtRel.empty()) {
548 return StatusCode::SUCCESS;
551 ATH_MSG_DEBUG(
"Initializing " << loadedRtRel.size()<<
" b-field functions");
556 if (readCondHandleDb->hasDCS()) {
557 condDbData = readCondHandleDb.cptr();
559 ATH_MSG_INFO(
"Do not retrieve the HV from DCS. Fall back to 2730 & 3080");
564 for (
const auto& [athenaId, rtRelation] : loadedRtRel) {
565 CorrectionPtr corrFuncSet = std::make_unique<MuonCalib::MdtCorFuncSet>();
568 std::vector<double> corr_params(2);
569 bool loadDefault{
false};
572 corr_params[0] = dcs.readyVolt;
574 if (corr_params[0] < std::numeric_limits<float>::epsilon()) {
578 }
else loadDefault =
true;
581 corr_params[0] = 2730.0;
583 corr_params[0] = 3080.0;
586 corr_params[1] = 0.11;
587 corrFuncSet->
setBField(std::make_unique<MuonCalib::BFieldCorFunc>(
"medium", corr_params, rtRelation->rt()));
592 if (!writeCdo.
storeData(athenaId, corrFuncSet, msgStream()))
return StatusCode::FAILURE;
595 return StatusCode::SUCCESS;
605 for (;
it != it_end; ++
it) {
616 if (!writeCdo.
storeData(*
it, tubes, msgStream()))
return StatusCode::FAILURE;
622 unsigned int nlayers = tubes->
numLayers();
623 unsigned int ntubes = tubes->
numTubes();
624 int size = nml * nlayers * ntubes;
627 <<
" size " <<
size <<
" ml " << nml <<
" l " << nlayers <<
" t " << ntubes);
628 for (
unsigned int ml = 1; ml <= nml; ++ml) {
629 for (
unsigned int l = 1;
l <= nlayers; ++
l) {
630 for (
unsigned int t = 1;
t <= ntubes; ++
t) {
640 return StatusCode::SUCCESS;
650 return StatusCode::FAILURE;
654 data = *(
static_cast<const std::string *
>((attr[
"data"]).addressOfData()));
659 return StatusCode::FAILURE;
669 int eta{0},
phi{0}, nTubes{0};
672 const std::vector<std::string> headerTokens =
tokenize(
header,
",");
675 nTubes =
atoi(headerTokens[5]);
681 static std::atomic<bool> idWarningPrinted =
false;
682 if (!idWarningPrinted) {
684 <<
" is invalid. Skipping");
685 idWarningPrinted.store(
true, std::memory_order_relaxed);
687 return StatusCode::SUCCESS;
691 channel[
"appliedT0"] = t0_ts_applied;
697 std::vector<double> tzeros{}, meanAdcs{};
698 std::vector<int> statusCodes{};
701 for (
unsigned int k = 0;
k < payLoadData.size(); ++
k){
702 const double value = payLoadData[
k];
705 tzeros.push_back(
value);
708 statusCodes.push_back(
value);
711 meanAdcs.push_back(
value);
717 if (statusCodes.size() != tzeros.size() ||
718 statusCodes.size() != meanAdcs.size() ||
719 statusCodes.empty()) {
721 return StatusCode::FAILURE;
726 const int numMl = idHelper.numberOfMultilayers(chamID);
727 const Identifier secondMlID = idHelper.multilayerID(chamID, numMl);
728 const int tubesPerLay =
std::max(idHelper.tubeMax(chamID), idHelper.tubeMax(secondMlID));
729 const int numLayers =
std::max(idHelper.tubeLayerMax(chamID), idHelper.tubeLayerMax(secondMlID));
731 ATH_MSG_FATAL(
"Calibration database differs in terms of number of tubes for chamber "
733 <<
" vs. observed "<<nTubes);
734 return StatusCode::FAILURE;
737 for (
unsigned int k = 0;
k < tzeros.size(); ++
k) {
739 channelData[
"ml"] = ml;
740 channelData[
"layer"] =
layer;
741 channelData[
"tube"] =
tube;
742 channelData[
"t0"] = tzeros[
k];
743 channelData[
"meanAdc"] = meanAdcs[
k];
744 channelData[
"status"] = statusCodes[
k];
746 if (
tube > tubesPerLay){
754 calibData.push_back(std::move(channelData));
756 channel[
"calibConstants"] = std::move(calibData);
758 return StatusCode::SUCCESS;
770 itr != readHandleTube->end(); ++itr) {
777 return StatusCode::FAILURE;
781 data = *(
static_cast<const std::string *
>((atr[
"data"]).addressOfData()));
785 for (
auto &
it :
yy.items()) {
787 t0CalibJson.push_back(yx);
794 itr != readHandleTube->end(); ++itr) {
806 for (
const auto& chambChannel : t0CalibJson) {
807 const std::string
stName = chambChannel[
"station"];
808 const int ieta = chambChannel[
"eta"];
809 const int iphi = chambChannel[
"phi"];
810 const bool t0_ts_applied = chambChannel[
"appliedT0"];
816 static std::atomic<bool> idWarningPrinted =
false;
817 if (!idWarningPrinted) {
818 ATH_MSG_WARNING(
"Element Identifier " << chId.get_compact() <<
" retrieved for station name " <<
stName
819 <<
" is not valid, skipping");
820 idWarningPrinted.store(
true, std::memory_order_relaxed);
834 if (!writeCdo.
storeData(chId, tubes, msgStream())) {
836 <<
" ID fields: "<<
stName<<
","<<ieta<<
","<<iphi);
837 return StatusCode::FAILURE;
840 const nlohmann::json& tubeConstants = chambChannel[
"calibConstants"];
841 for (
const auto& tubeChannel : tubeConstants) {
842 const int ml = tubeChannel[
"ml"];
843 const int l = tubeChannel[
"layer"];
844 const int t = tubeChannel[
"tube"];
845 double tzero = tubeChannel[
"t0"];
852 double sh = CLHEP::RandGaussZiggurat::shoot(engine, 0.,
m_t0Spread);
854 ATH_MSG_VERBOSE(
"T0 spread " <<
sh <<
" t0 " << tzero <<
" id " << ml <<
" " <<
l <<
" " <<
t);
860 const double meanAdc = tubeChannel[
"meanAdc"];
864 datatube.adcCal = meanAdc;
865 const Identifier tubeId = idHelper.channelID(chId, ml,
l,
t);
866 tubes->
setCalib(std::move(datatube), tubeId, msgStream());
872 return StatusCode::SUCCESS;
879 std::vector<Double_t>
x(sample_points.size(),0);
880 std::vector<Double_t>
y(sample_points.size(),0);
882 for (
unsigned int i = 0;
i < sample_points.size();
i++) {
883 x[
i] = sample_points[
i].x1();
884 y[
i] = sample_points[
i].x2();
886 TSpline3 sp(
"Rt Res Tmp",
x.data(),
y.data(), sample_points.size());
890 unsigned int nb_points(100);
891 std::vector<double> res_param(nb_points + 2);
892 Double_t
bin_width = (
x[sample_points.size() - 1] -
x[0]) /
static_cast<Double_t
>(nb_points);
896 for (
unsigned int k = 0;
k < nb_points;
k++) {
898 res_param[
k + 2] = sp.Eval(
xx);
899 if (std::isnan(res_param[
k + 2])) {
900 TFile outf(
"kacke.root",
"RECREATE");
903 "encountered nan element");
906 return std::make_unique<MuonCalib::RtResolutionLookUp>(std::move(res_param));