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;
118 return StatusCode::SUCCESS;
123 if (writeHandle.isValid()) {
124 ATH_MSG_DEBUG(
"CondHandle " << writeHandle.fullKey() <<
" is already valid."
125 <<
". In theory this should not be called, but may happen"
126 <<
" if multiple concurrent events are being processed out of order.");
127 return StatusCode::SUCCESS;
134 gran = RegionGranularity::OneRt;
136 ATH_MSG_DEBUG(
"Save one set of calibration constants per multi layer");
137 gran = RegionGranularity::OnePerMultiLayer;
138 }
else ATH_MSG_DEBUG(
"Save one set of calibration constants per chamber");
139 std::unique_ptr<MuonCalib::MdtCalibDataContainer> writeCdo = std::make_unique<MuonCalib::MdtCalibDataContainer>(
m_idHelperSvc.get(), gran);
143 ATH_CHECK(writeHandle.record(std::move(writeCdo)));
144 return StatusCode::SUCCESS;
153 return StatusCode::FAILURE;
166 for (
unsigned int n = 0;
n <
rts.nRts(); ++
n) {
167 std::unique_ptr<MuonCalib::RtDataFromFile::RtRelation> rt(
rts.getRt(
n));
174 if (
times.size() < 2) {
176 return StatusCode::FAILURE;
179 if (
times.size() != radii.size() ||
times.size() != reso.size()) {
181 return StatusCode::FAILURE;
184 double t_min =
times[0];
185 double bin_size =
times[1] - t_min;
188 return StatusCode::FAILURE;
194 rtPars.push_back(t_min);
195 rtPars.push_back(bin_size);
198 rtPars.insert(rtPars.end(), radii.begin(), radii.end());
204 resoPars.insert(resoPars.end(), reso.begin(), reso.end());
209 std::shared_ptr<MuonCalib::IRtRelation> rtRel{std::make_unique<RtRelationLookUp>(rtPars)};
210 std::shared_ptr<MuonCalib::IRtResolution> resoRel{std::make_unique<RtResolutionLookUp>(resoPars)};
220 RtRelationPtr MdtRt = std::make_unique<MuonCalib::MdtRtRelation>(rtRel, resoRel, 0.);
222 for(
auto itr = idHelper.detectorElement_begin();
223 itr!= idHelper.detectorElement_end();++itr){
234 if (idHelper.multilayer(detElId) == 2) {
235 if (writeCdo.
granularity() != RegionGranularity::OnePerMultiLayer)
continue;
236 const Identifier firstML = idHelper.multilayerID(detElId, 1);
246 if (!writeCdo.
storeData(detElId, storeMe, msgStream())) {
248 return StatusCode::FAILURE;
252 loadedRts[detElId] = MdtRt;
258 int npoints = rtRel->nPar() - 2;
260 for (
int ipt = 0; ipt <
npoints; ++ipt) {
261 double t = t_min + ipt * bin_size;
262 ATH_MSG_VERBOSE(
" " << ipt <<
" " <<
t <<
" " << rtRel->radius(
t) <<
" " << resoRel->resolution(
t));
269 return StatusCode::SUCCESS;
272 static std::atomic<bool> rtWarningPrinted =
false;
276 if (detEl) {
return std::make_optional<double>(detEl->
innerTubeRadius()); }
280 if (detEl) {
return std::make_optional<double>(detEl->
innerTubeRadius()); }
282 if (!rtWarningPrinted) {
283 ATH_MSG_WARNING(
"getInnerTubeRadius() - no Muon station known under the name "
285 rtWarningPrinted =
true;
291 std::string
data{}, delim{};
296 return StatusCode::FAILURE;
300 data = *(
static_cast<const std::string *
>((attr[
"data"]).addressOfData()));
306 return StatusCode::FAILURE;
312 unsigned int numPoints{0};
315 channel[
"appliedRT"] = rt_ts_applied;
320 if(tokensHeader.size()< 2){
321 ATH_MSG_FATAL(
"Failed to deduce extract number of points & calib Identifier from "<<
header);
322 return StatusCode::FAILURE;
324 unsigned int calibId = tokensHeader[0];
325 numPoints = tokensHeader[1];
329 return StatusCode::FAILURE;
333 ATH_MSG_WARNING(
"The translation from the calibration ID with station: "
334 <<
id.stationNameString()<<
"("<<
id.
stationName()<<
") "
335 <<
" eta:"<<
id.
eta()<<
" phi: "<<
id.
phi());
340 channel[
"ml"] = idHelper.multilayer(athenaId);
341 channel[
"layer"] = idHelper.tubeLayer(athenaId);
342 channel[
"tube"] = idHelper.tube(athenaId);
346 std::vector<double> radii{},
times{}, resos{};
347 radii.reserve(numPoints);
348 times.reserve(numPoints);
349 resos.reserve(numPoints);
353 for (
unsigned int k = 0 ;
k < dataPoints.size(); ++
k) {
354 const double value = dataPoints[
k];
357 radii.push_back(
value);
363 resos.push_back(
value);
370 if (radii.size() != numPoints ||
371 times.size() != numPoints ||
372 resos.size() != numPoints) {
373 ATH_MSG_FATAL(
"Payload "<<
payload<<
" does not lead to the expected number of points "<<numPoints<<
" vs. "<<dataPoints.size());
374 return StatusCode::FAILURE;
376 channel[
"radii"] = std::move(radii);
378 channel[
"resolutions"] = std::move(resos);
380 return StatusCode::SUCCESS;
388 if (!readHandleRt.isValid()) {
390 return StatusCode::FAILURE;
398 itr != readHandleRt->end(); ++itr) {
405 return StatusCode::FAILURE;
409 data = *(
static_cast<const std::string *
>((atr[
"data"]).addressOfData()));
413 for (
auto &
it :
yy.items()) {
415 rtCalibJson.push_back(yx);
422 itr != readHandleRt->end(); ++itr) {
429 for (
const auto&
payload : rtCalibJson) {
430 const bool rt_ts_applied =
payload[
"appliedRT"];
432 const std::string stName =
payload[
"station"];
436 std::optional<double> innerTubeRadius =
getInnerTubeRadius(idHelper.multilayerID(athenaId, 1));
437 if (!innerTubeRadius)
continue;
440 const std::vector<double> radii =
payload[
"radii"];
442 const std::vector<double> resolutions =
payload[
"resolutions"];
455 std::vector<MuonCalib::SamplePoint> tr_points{}, ts_points{};
460 for (
unsigned int k = 0;
k < radii.size(); ++
k) {
466 radius = oldradius + rshift;
467 ATH_MSG_DEBUG(
"DEFORM RT: old radius " << oldradius <<
" new radius " <<
radius <<
" shift " << rshift
482 float sigma = resolutions[
k];
486 if (tr_point.
x2() < -99) {
487 multilayer_tmax_diff = tr_point.
x1();
488 }
else if (
k == 0 || (tr_points[
k - 1].
x1() < tr_point.
x1() && tr_points[
k - 1].x2() < tr_point.
x2())) {
489 tr_points.push_back(tr_point);
490 ts_points.push_back(ts_point);
495 if (ts_points.size() < 3) {
497 return StatusCode::FAILURE;
501 float sign(rt_ts_applied ? -1.0 : 1.0);
503 for (
auto & tr_point : tr_points) {
504 int slice_number =
static_cast<int>(std::floor(tr_point.
x2() / slice_width));
505 if (slice_number < 0) slice_number = 0;
517 ATH_MSG_VERBOSE(point.x1() <<
"|" << point.x2() <<
"|" << point.error());
525 if (!reso || !rt) {
continue; }
527 if (rt->
par(1) == 0.) {
531 return StatusCode::FAILURE;
534 if (multilayer_tmax_diff > -8e8) { rt->
SetTmaxDiff(multilayer_tmax_diff); }
536 RtRelationPtr rt_rel = std::make_unique<MuonCalib::MdtRtRelation>(std::move(rt), std::move(reso), 0.);
538 if (!writeCdo.
storeData(athenaId ,rt_rel, msgStream()))
return StatusCode::FAILURE;
540 loadedRtRel[athenaId] = rt_rel;
545 if (loadedRtRel.empty()) {
546 return StatusCode::SUCCESS;
549 ATH_MSG_DEBUG(
"Initializing " << loadedRtRel.size()<<
" b-field functions");
554 if (readCondHandleDb->hasDCS()) {
555 condDbData = readCondHandleDb.cptr();
557 ATH_MSG_INFO(
"Do not retrieve the HV from DCS. Fall back to 2730 & 3080");
562 for (
const auto& [athenaId, rtRelation] : loadedRtRel) {
563 CorrectionPtr corrFuncSet = std::make_unique<MuonCalib::MdtCorFuncSet>();
566 std::vector<double> corr_params(2);
567 bool loadDefault{
false};
570 corr_params[0] = dcs.readyVolt;
572 if (corr_params[0] < std::numeric_limits<float>::epsilon()) {
576 }
else loadDefault =
true;
579 corr_params[0] = 2730.0;
581 corr_params[0] = 3080.0;
584 corr_params[1] = 0.11;
585 corrFuncSet->
setBField(std::make_unique<MuonCalib::BFieldCorFunc>(
"medium", corr_params, rtRelation->rt()));
590 if (!writeCdo.
storeData(athenaId, corrFuncSet, msgStream()))
return StatusCode::FAILURE;
593 return StatusCode::SUCCESS;
606 for (;
it != it_end; ++
it) {
617 if (!writeCdo.
storeData(*
it, tubes, msgStream()))
return StatusCode::FAILURE;
623 unsigned int nlayers = tubes->
numLayers();
624 unsigned int ntubes = tubes->
numTubes();
625 int size = nml * nlayers * ntubes;
628 <<
" size " <<
size <<
" ml " << nml <<
" l " << nlayers <<
" t " << ntubes);
629 for (
unsigned int ml = 1; ml <= nml; ++ml) {
630 for (
unsigned int l = 1;
l <= nlayers; ++
l) {
631 for (
unsigned int t = 1;
t <= ntubes; ++
t) {
636 data.inversePropSpeed = inversePropSpeed;
642 return StatusCode::SUCCESS;
652 return StatusCode::FAILURE;
656 data = *(
static_cast<const std::string *
>((attr[
"data"]).addressOfData()));
661 return StatusCode::FAILURE;
670 const std::string stName =
header.substr(2,3);
671 int eta{0},
phi{0}, nTubes{0};
674 const std::vector<std::string> headerTokens =
tokenize(
header,
",");
677 nTubes =
atoi(headerTokens[5]);
683 static std::atomic<bool> idWarningPrinted =
false;
684 if (!idWarningPrinted) {
686 <<
" is invalid. Skipping");
687 idWarningPrinted.store(
true, std::memory_order_relaxed);
689 return StatusCode::SUCCESS;
693 channel[
"appliedT0"] = t0_ts_applied;
699 std::vector<double> tzeros{}, meanAdcs{};
700 std::vector<int> statusCodes{};
703 for (
unsigned int k = 0;
k < payLoadData.size(); ++
k){
704 const double value = payLoadData[
k];
707 tzeros.push_back(
value);
710 statusCodes.push_back(
value);
713 meanAdcs.push_back(
value);
719 if (statusCodes.size() != tzeros.size() ||
720 statusCodes.size() != meanAdcs.size() ||
721 statusCodes.empty()) {
723 return StatusCode::FAILURE;
728 const int numMl = idHelper.numberOfMultilayers(chamID);
729 const Identifier secondMlID = idHelper.multilayerID(chamID, numMl);
730 const int tubesPerLay =
std::max(idHelper.tubeMax(chamID), idHelper.tubeMax(secondMlID));
731 const int numLayers =
std::max(idHelper.tubeLayerMax(chamID), idHelper.tubeLayerMax(secondMlID));
733 ATH_MSG_FATAL(
"Calibration database differs in terms of number of tubes for chamber "
735 <<
" vs. observed "<<nTubes);
736 return StatusCode::FAILURE;
739 for (
unsigned int k = 0;
k < tzeros.size(); ++
k) {
741 channelData[
"ml"] = ml;
742 channelData[
"layer"] =
layer;
743 channelData[
"tube"] =
tube;
744 channelData[
"t0"] = tzeros[
k];
745 channelData[
"meanAdc"] = meanAdcs[
k];
746 channelData[
"status"] = statusCodes[
k];
748 if (
tube > tubesPerLay){
756 calibData.push_back(std::move(channelData));
758 channel[
"calibConstants"] = std::move(calibData);
760 return StatusCode::SUCCESS;
772 itr != readHandleTube->end(); ++itr) {
779 return StatusCode::FAILURE;
783 data = *(
static_cast<const std::string *
>((atr[
"data"]).addressOfData()));
787 for (
auto &
it :
yy.items()) {
789 t0CalibJson.push_back(yx);
796 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"];
865 datatube.
adcCal = meanAdc;
866 const Identifier tubeId = idHelper.channelID(chId, ml,
l,
t);
867 tubes->
setCalib(std::move(datatube), tubeId, msgStream());
873 return StatusCode::SUCCESS;
880 std::vector<Double_t>
x(sample_points.size(),0);
881 std::vector<Double_t>
y(sample_points.size(),0);
883 for (
unsigned int i = 0;
i < sample_points.size();
i++) {
884 x[
i] = sample_points[
i].x1();
885 y[
i] = sample_points[
i].x2();
887 TSpline3 sp(
"Rt Res Tmp",
x.data(),
y.data(), sample_points.size());
891 unsigned int nb_points(100);
892 std::vector<double> res_param(nb_points + 2);
893 Double_t
bin_width = (
x[sample_points.size() - 1] -
x[0]) /
static_cast<Double_t
>(nb_points);
897 for (
unsigned int k = 0;
k < nb_points;
k++) {
899 res_param[
k + 2] = sp.Eval(xx);
900 if (std::isnan(res_param[
k + 2])) {
901 TFile outf(
"kacke.root",
"RECREATE");
904 "encountered nan element");
907 return std::make_unique<MuonCalib::RtResolutionLookUp>(std::move(res_param));