15#include "TGraphErrors.h"
37 return StatusCode::SUCCESS;
43 return StatusCode::SUCCESS;
50 auto writeCdo = std::make_unique<MdtCalibDataContainer>(
m_idHelperSvc.get(), readHandle->granularity());
57 std::unordered_set<Identifier> missedElements{};
60 if (!readHandle->hasDataForChannel(detId, msgStream())){
62 missedElements.insert(detId);
65 const MdtFullCalibData* copyMe = readHandle->getCalibData(detId, msgStream());
68 return StatusCode::FAILURE;
71 const std::vector<Identifier> tubes =
tubeIds(detId);
72 if (std::ranges::none_of(tubes, [copyMe](
const Identifier& tubeId){
76 if (!writeCdo->storeData(detId, copyMe->
tubeCalib, msgStream())) {
77 return StatusCode::FAILURE;
81 missedElements.insert(detId);
89 dummyFillerRt = translated;
92 if (!writeCdo->storeData(detId, translated, msgStream())) {
94 return StatusCode::FAILURE;
98 missedElements.clear();
100 for (
const Identifier& detId: missedElements) {
102 <<
". Insert instead the first translated rt-relation for those channels");
103 const bool fillRt = !writeCdo->hasDataForChannel(detId, msgStream()) ||
104 !writeCdo->getCalibData(detId, msgStream())->rtRelation;
106 if (!writeCdo->storeData(detId, dummyFillerRt, msgStream())) {
108 return StatusCode::FAILURE;
110 if (dummyFillerCorr && !writeCdo->storeData(detId, dummyFillerCorr, msgStream())) {
111 return StatusCode::FAILURE;
114 if (writeCdo->getCalibData(detId, msgStream())->tubeCalib) {
121 if (!dummyT0cont->
setCalib(dummyT0Calib, tubeId, msgStream())) {
122 return StatusCode::FAILURE;
125 if (!writeCdo->storeData(detId, std::move(dummyT0cont), msgStream())) {
126 return StatusCode::FAILURE;
130 return StatusCode::SUCCESS;
133 std::vector<Identifier> tubes{};
137 for (
int layer = 1; layer <= idHelper.
tubeLayerMax(detId); ++layer) {
138 for (
int tube = 1; tube <= idHelper.
tubeMax(detId); ++tube) {
139 tubes.emplace_back(idHelper.
channelID(detId, ml, layer, tube));
154 unsigned int order{0};
157 <<
" using a polynomial of order "<<order);
171 const unsigned rtNdoF = rtPoints.size() - rt->
nDoF();
182 const std::vector<SamplePoint> trPoints =
swapCoordinates(rtPoints, *rt);
186 <<
" using a polynomial of order "<<order);
200 const unsigned trNdoF = rtPoints.size() - tr->
nDoF();
203 ATH_MSG_VERBOSE(
"T-R fit resulted in a chi2/nDoF for tr: "<<trChi2<<
" ("<<trNdoF<<
")");
214 std::unique_ptr<IRtResolution> fittedReso{};
219 <<
" using a polynomial of order "<<order);
221 const unsigned nDoF = rtResoPoints.size() - fittedReso->nDoF();
234 rtReso = std::move(fittedReso);
237 <<
" no rt resolution function could be fitted for "<<
m_idHelperSvc->toStringDetEl(detId));
240 auto finalRt = std::make_unique<MdtRtRelation>(std::move(rt), rtReso, std::move(tr));
241 drawRt(ctx, detId, rtPoints, *finalRt);
246 const std::vector<SamplePoint>& rtPoints,
251 const std::string
chName = std::format(
"{:}{:d}{:}{:d}M{:1d}",
258 canvas->setAxisTitles(
"drift time [ns]",
"drift radius [mm]");
259 auto dataGraph = std::make_unique<TGraphErrors>();
261 dataGraph->SetPoint(dataGraph->GetN(), dataPoint.x1(), dataPoint.x2());
262 dataGraph->SetPointError(dataGraph->GetN()-1, 0., dataPoint.error());
263 canvas->expandPad(dataPoint.x1(), dataPoint.x2());
267 auto rtGraph = std::make_unique<TGraph>();
268 auto trGraph = std::make_unique<TGraph>();
270 double driftTime{inRel.
rt()->
tLower()};
271 while (driftTime <= inRel.
rt()->
tUpper()) {
272 const double radius = inRel.
rt()->
radius(driftTime);
274 const double backTime = inRel.
tr()->
driftTime(backRadius).value_or(-666.);
275 rtGraph->SetPoint(rtGraph->GetN(), driftTime, radius);
276 trGraph->SetPoint(trGraph->GetN(), backTime, radius);
277 canvas->expandPad(driftTime, radius);
278 canvas->expandPad(backTime, radius);
282 const unsigned rtNDoF= rtPoints.size() - inRel.
rt()->
nDoF();
283 const unsigned trNDoF= rtPoints.size() - inRel.
tr()->
nDoF();
287 auto legend = std::make_unique<TLegend>(0.2,0.7,0.6, 0.9,
chName.c_str());
288 legend->SetFillStyle(0);
289 legend->SetBorderSize(0);
290 legend->AddEntry(rtGraph.get(),std::format(
"{:}, order: {:d}, #chi^{{2}}: {:.3f}({:d})",
291 inRel.
rt()->
name(), inRel.
rt()->
nDoF(), rtChi2, rtNDoF).c_str(),
"L");
293 legend->AddEntry(trGraph.get(),std::format(
"{:}, order: {:d}, #chi^{{2}}: {:.3f}({:d})",
294 inRel.
tr()->
name(), inRel.
tr()->
nDoF(), trChi2, trNDoF).c_str(),
"L");
296 dataGraph->SetMarkerSize(0);
297 rtGraph->SetLineColor(kRed);
298 trGraph->SetLineColor(kBlue);
300 canvas->add(std::move(dataGraph),
"P");
301 canvas->add(std::move(rtGraph),
"C");
302 canvas->add(std::move(trGraph),
"C");
303 canvas->add(std::move(legend));
308 const std::vector<SamplePoint>& resoPoints,
311 const std::string
chName = std::format(
"{:}{:d}{:}{:d}M{:1d}",
319 canvas->setAxisTitles(
"drift time [ns]",
"#sigma(r_{drift}) [mm]");
320 auto dataGraph = std::make_unique<TGraphErrors>();
322 dataGraph->SetPoint(dataGraph->GetN(), dataPoint.x1(), dataPoint.x2());
323 dataGraph->SetPointError(dataGraph->GetN()-1, 0., dataPoint.error());
324 canvas->expandPad(dataPoint.x1(), dataPoint.x2());
326 auto resoGraph = std::make_unique<TGraph>();
327 const auto [tLow, tHigh] =
interval(resoPoints);
328 const auto [resoLow, resoHigh] =
minMax(resoPoints);
329 canvas->expandPad(tLow, resoLow);
330 canvas->expandPad(tHigh, resoHigh);
331 double driftTime{tLow};
332 while (driftTime <= tHigh) {
333 const double evalReso = inReso.
resolution(driftTime);
334 resoGraph->SetPoint(resoGraph->GetN(), driftTime, evalReso);
337 canvas->add(std::move(dataGraph),
"P");
338 canvas->add(std::move(resoGraph),
"C");
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
void reset(std::unique_ptr< DerivType > newObj)
Overload the pointer.
Identifier multilayerID(const Identifier &channeldID) const
static int tubeLayerMax()
static int multilayerMax()
Identifier channelID(int stationName, int stationEta, int stationPhi, int multilayer, int tubeLayer, int tube) const
Gaudi::Property< bool > m_fillMissingCh
At the end of the translation, it's checked whether all channels have been assigned.
Gaudi::Property< unsigned > m_precCutOff
Precision cut-off to treat two incoming rt-relations as equivalent.
virtual StatusCode execute(const EventContext &ctx) const override final
Gaudi::Property< float > m_missingT0
Default t0 constant to use, in case there's.
Gaudi::Property< unsigned > m_maxOrder
Maximum order of the polynomial in use.
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
void drawRt(const EventContext &ctx, const Identifier &detId, const std::vector< MuonCalib::SamplePoint > &rtPoints, const MuonCalib::MdtRtRelation &inRel) const
SG::WriteCondHandleKey< MuonCalib::MdtCalibDataContainer > m_writeKey
Gaudi::Property< bool > m_fitRtReso
Toggle whether the resolution shall be also converted into a polynomial.
Gaudi::Property< double > m_relUncReso
Assignment of the relative uncertainty on each resolution data point.
MuonCalib::MdtFullCalibData::RtRelationPtr RtRelationPtr
void drawResoFunc(const EventContext &ctx, const Identifier &detId, const std::vector< MuonCalib::SamplePoint > &resoPoints, const MuonCalib::IRtResolution &inReso) const
ServiceHandle< MuonValR4::IRootVisualizationService > m_visualSvc
Service handle of the visualization service.
Gaudi::Property< bool > m_saveDiagnostic
Save diagnostic histograms.
Gaudi::Property< unsigned > m_maxOrderReso
Maximal order to use for the resolution.
Gaudi::Property< int > m_polyTypeRt
Toggle the polynomial for the Rt-relation: ChebyChev or Legendre.
Gaudi::Property< int > m_polyTypeTr
Toggle the polynomial for the Rt-relation: ChebyChev or Legendre.
MuonValR4::IRootVisualizationService::ClientToken m_clientToken
Token to be presented to the visualization service.
Gaudi::Property< float > m_chiCutOff
Stop incrementing the order once the chi2CutOff is reached.
virtual StatusCode initialize() override final
RtRelationPtr translateRt(const EventContext &ctx, const Identifier &detId, const MuonCalib::MdtRtRelation &inRel) const
Translates the rt / tr & resolution relation from a look-up table into the requested polynomial type.
std::vector< Identifier > tubeIds(const Identifier &chId) const
SG::ReadCondHandleKey< MuonCalib::MdtCalibDataContainer > m_readKey
virtual std::string name() const =0
virtual unsigned nDoF() const =0
Returns the number of degrees of freedom of the relation function.
virtual double tLower() const =0
Returns the lower time covered by the r-t.
virtual double radius(double t) const =0
returns drift radius for a given time
virtual double tUpper() const =0
Returns the upper time covered by the r-t.
Generic interface to retrieve the resolution on the drift radius as a function of the drift time.
virtual unsigned nDoF() const =0
Returns the number of degrees of freedom of the relation function.
virtual double resolution(double t, double bgRate=0.0) const =0
returns resolution for a give time and background rate
virtual double maxRadius() const =0
Returns the maximum drift-radius.
virtual unsigned nDoF() const =0
Returns the number of degrees of freedom of the tr relation.
virtual std::optional< double > driftTime(const double r) const =0
Interface method for fetching the drift-time from the radius Returns a nullopt if the time is out of ...
virtual double minRadius() const =0
Returns the minimum drift-radius.
MdtFullCalibData::TubeContainerPtr TubeContainerPtr
class which holds calibration constants per rt-region
const ITrRelation * tr() const
t(r) relationship
const IRtResolutionPtr & smartReso() const
const IRtResolution * rtRes() const
resolution
const IRtRelation * rt() const
rt relation
const SingleTubeCalib * getCalib(const Identifier &tubeId) const
return calibration constants of a single tube
bool setCalib(SingleTubeCalib val, const Identifier &tubeId, MsgStream &msg)
set the calibration constants of a single tube
static std::unique_ptr< ITrRelation > getTrLegendre(const std::vector< SamplePoint > &dataPoints, const unsigned order)
Converts a list of t(r) data points into a t(r) relation expressed as a series of legendre polynomial...
static std::unique_ptr< IRtRelation > getRtChebyshev(const std::vector< SamplePoint > &dataPoints, const unsigned order)
Converts a list of r-t data points into a r(t) relation expressed as a series of chebychev polynomial...
static std::unique_ptr< ITrRelation > getTrChebyshev(const std::vector< SamplePoint > &dataPoints, const unsigned order)
Converts a list of r-t data points into a t(r) relation expressed as a series of chebychev polynomial...
static std::unique_ptr< IRtRelation > getRtSimplePoly(const std::vector< SamplePoint > &dataPoints, const unsigned order)
Converts a list of r(t) data points into a r(t) relation expressed as a series of elementary monomoni...
static std::unique_ptr< IRtResolution > getResoChebyshev(const std::vector< SamplePoint > &dataPoints, const unsigned order)
Converts a list of reso - t into a reso(t) relation expressed as a series of chebychev polynomials.
static std::unique_ptr< IRtRelation > getRtLegendre(const std::vector< SamplePoint > &dataPoints, const unsigned order)
Converts a list of r-t data points into a r(t) relation expressed as a series of legendre polynomials...
static std::unique_ptr< ITrRelation > getTrSimplePoly(const std::vector< SamplePoint > &dataPoints, const unsigned order)
Converts a list of t(r) data points into a t(r) relation expressed as a series of elementary monomoni...
This class provides a sample point for the BaseFunctionFitter.
const_id_iterator detectorElement_begin() const
Iterators over full set of ids.
const_id_iterator detectorElement_end() const
void addDependency(const EventIDRange &range)
StatusCode record(const EventIDRange &range, T *t)
record handle, with explicit range DEPRECATED
const DataObjID & fullKey() const
double chi2(TH1 *h0, TH1 *h1)
CscCalcPed - algorithm that finds the Cathode Strip Chamber pedestals from an RDO.
std::pair< double, double > interval(const std::vector< SamplePoint > &points)
Returns the interval covered by the sample points.
std::pair< double, double > minMax(const std::vector< SamplePoint > &points)
Returns the minimum & maximum values covered by the sample points.
GeoModel::TransientConstSharedPtr< IRtRelation > IRtRelationPtr
GeoModel::TransientConstSharedPtr< ITrRelation > ITrRelationPtr
std::vector< SamplePoint > swapCoordinates(const std::vector< SamplePoint > &points, const IRtRelation &rtRel)
Creates a new vector of samples points with x1 exchanged by x2 and vice-versa.
double calculateChi2(const std::vector< SamplePoint > &dataPoints, const IRtRelation &rtRel)
Returns the chi2 of the rt-relation w.r.t.
std::vector< SamplePoint > fetchResolution(const std::vector< SamplePoint > &points, const double uncert)
Creates a new vector of sample points where the x2 is assigned to the uncertainty and the uncertainty...
std::vector< SamplePoint > fetchDataPoints(const IRtRelation &rtRel, const double relUnc)
Constructs a list of sample points from the rt-relation.
std::unique_ptr< TLatex > drawLabel(const std::string &text, const double xPos, const double yPos, const unsigned int fontSize=18)
Create a TLatex label,.
const std::string & chName(ChIndex index)
convert ChIndex into a string
Helper struct to group Mdt calibration constants which are equivalent within the target precision.
class which holds the full set of calibration constants for a given tube
TubeContainerPtr tubeCalib
GeoModel::TransientConstSharedPtr< MdtCorFuncSet > CorrectionPtr
CorrectionPtr corrections
float t0
< relative t0 in chamber (ns)