Skip to content

Commit f85ac19

Browse files
authored
Merge c389c71 into sapling-pr-archive-ktf
2 parents cda0d29 + c389c71 commit f85ac19

File tree

32 files changed

+883
-88
lines changed

32 files changed

+883
-88
lines changed

CODEOWNERS

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@
2828
/DataFormats/Detectors/Common @shahor02
2929
/DataFormats/Detectors/CPV @peressounko @kharlov
3030
/DataFormats/Detectors/CTP @lietava
31-
/DataFormats/Detectors/EMCAL @mfasDa @jokonig
31+
/DataFormats/Detectors/EMCAL @nstrangm @jokonig
3232
/DataFormats/Detectors/FIT @jotwinow @afurs @andreasmolander @sahilupadhyaya92
33-
/DataFormats/Detectors/FOCAL @maxrauch @mfasDa @iarsene @matthiasrichter
33+
/DataFormats/Detectors/FOCAL @maxrauch @iarsene @matthiasrichter
3434
/DataFormats/Detectors/GlobalTracking @shahor02
3535
/DataFormats/Detectors/GlobalTrackingWorkflow @shahor02
3636
/DataFormats/Detectors/HMPID @gvolpe79
@@ -58,9 +58,9 @@
5858
/Detectors/Base @sawenzel @shahor02
5959
/Detectors/Calibration @chiarazampolli @shahor02
6060
/Detectors/CPV @peressounko @kharlov
61-
/Detectors/EMCAL @mfasDa @jokonig
61+
/Detectors/EMCAL @nstrangm @jokonig
6262
/Detectors/FIT @jotwinow @afurs @andreasmolander @sahilupadhyaya92
63-
/Detectors/FOCAL @maxrauch @mfasDa @iarsene @matthiasrichter
63+
/Detectors/FOCAL @maxrauch @iarsene @matthiasrichter
6464
/Detectors/Geometry @sawenzel @shahor02
6565
/Detectors/GlobalTracking @shahor02
6666
/Detectors/GlobalTrackingWorkflow @shahor02

DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackFwd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ class TrackParCovFwd : public TrackParFwd
161161
void propagateToZquadratic(double zEnd, double zField);
162162
void propagateToZhelix(double zEnd, double zField);
163163
void propagateToZ(double zEnd, double zField); // Parameters: helix; errors: quadratic
164+
void propagateToDCAhelix(double zField, const std::array<double, 3>& p, std::array<double, 3>& dca);
164165

165166
// Add Multiple Coulomb Scattering effects
166167
void addMCSEffect(double x2X0);

DataFormats/Reconstruction/include/ReconstructionDataFormats/Vertex.h

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,13 @@
1818

1919
#include "CommonDataFormat/TimeStamp.h"
2020
#ifndef GPUCA_GPUCODE_DEVICE
21-
#include <iosfwd>
22-
#include <string>
2321
#include <type_traits>
2422
#include <array>
23+
#ifndef GPUCA_NO_FMT
24+
#include <sstream>
25+
#include <string>
26+
#include <fmt/format.h>
27+
#endif
2528
#endif
2629

2730
namespace o2
@@ -135,6 +138,11 @@ class Vertex : public VertexBase
135138
{
136139
}
137140

141+
#if !defined(GPUCA_NO_FMT) && !defined(GPUCA_GPUCODE_DEVICE)
142+
void print() const;
143+
std::string asString() const;
144+
#endif
145+
138146
GPUd() ushort getNContributors() const { return mNContributors; }
139147
GPUd() void setNContributors(ushort v) { mNContributors = v; }
140148
GPUd() void addContributor() { mNContributors++; }
@@ -162,6 +170,49 @@ class Vertex : public VertexBase
162170

163171
#if !defined(GPUCA_GPUCODE_DEVICE) && !defined(GPUCA_NO_FMT)
164172
std::ostream& operator<<(std::ostream& os, const o2::dataformats::VertexBase& v);
173+
174+
namespace detail
175+
{
176+
template <typename T>
177+
concept Streamable = requires(std::ostream& os, const T& a) {
178+
{ os << a } -> std::same_as<std::ostream&>;
179+
};
180+
181+
template <typename T>
182+
concept HasFormattableTimeStamp = requires(const T& t) {
183+
{ fmt::format("{}", t.getTimeStamp()) } -> std::convertible_to<std::string>;
184+
};
185+
} // namespace detail
186+
187+
template <typename Stamp>
188+
inline std::string Vertex<Stamp>::asString() const
189+
{
190+
const std::string stamp = [&]() -> std::string {
191+
if constexpr (detail::Streamable<Stamp>) {
192+
std::ostringstream oss;
193+
oss << mTimeStamp;
194+
return oss.str();
195+
} else if constexpr (detail::HasFormattableTimeStamp<Stamp>) {
196+
return fmt::format("{}", mTimeStamp.getTimeStamp());
197+
} else {
198+
return "X";
199+
}
200+
}();
201+
return fmt::format("{} NContrib:{} Chi2:{:.2f} Flags:{:b} Stamp:{}", VertexBase::asString(), mNContributors, mChi2, mBits, stamp);
202+
}
203+
204+
template <typename Stamp>
205+
inline std::ostream& operator<<(std::ostream& os, const o2::dataformats::Vertex<Stamp>& v)
206+
{
207+
os << v.asString();
208+
return os;
209+
}
210+
211+
template <typename Stamp>
212+
inline void Vertex<Stamp>::print() const
213+
{
214+
std::cout << *this << '\n';
215+
}
165216
#endif
166217

167218
} // namespace dataformats

DataFormats/Reconstruction/src/TrackFwd.cxx

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include "ReconstructionDataFormats/TrackFwd.h"
1313
#include "Math/MatrixFunctions.h"
14+
#include <GPUCommonLogger.h>
1415

1516
namespace o2
1617
{
@@ -503,5 +504,73 @@ bool TrackParCovFwd::getCovXYZPxPyPzGlo(std::array<float, 21>& cv) const
503504
return true;
504505
}
505506

507+
//________________________________________________________________
508+
509+
void TrackParCovFwd::propagateToDCAhelix(double zField, const std::array<double, 3>& p, std::array<double, 3>& dca)
510+
{
511+
// Computing DCA of fwd track w.r.t vertex in helix track model, using Newton-Raphson minimization
512+
513+
auto x0 = mParameters(0);
514+
auto y0 = mParameters(1);
515+
auto z0 = mZ;
516+
auto phi0 = mParameters(2);
517+
auto tanl = mParameters(3);
518+
auto qOverPt = mParameters(4);
519+
auto k = TMath::Abs(o2::constants::math::B2C * zField);
520+
auto qpt = 1.0 / qOverPt;
521+
auto qR = qpt / std::fabs(k);
522+
auto invtanl = 1.0 / tanl;
523+
auto Hz = std::copysign(1, zField);
524+
525+
auto xPV = p[0];
526+
auto yPV = p[1];
527+
auto zPV = p[2];
528+
529+
auto qRtanl = qR * tanl;
530+
auto invqRtanl = 1.0 / qRtanl;
531+
auto [sinp, cosp] = o2::math_utils::sincosd(phi0);
532+
533+
auto z = zPV;
534+
double tol = 1e-4;
535+
int max_iter = 10;
536+
int iter = 0;
537+
538+
while (iter++ < max_iter) {
539+
double theta = (z0 - z) * invqRtanl;
540+
double phi_theta = phi0 + Hz * theta;
541+
double sin_phi_theta = sin(phi_theta);
542+
double cos_phi_theta = cos(phi_theta);
543+
544+
double DX = x0 - Hz * qR * (sin_phi_theta - sinp) - xPV;
545+
double DY = y0 + Hz * qR * (cos_phi_theta - cosp) - yPV;
546+
double DZ = z - zPV;
547+
548+
double dD2_dZ =
549+
2 * DX * cos_phi_theta * invtanl +
550+
2 * DY * sin_phi_theta * invtanl +
551+
2 * DZ;
552+
553+
double d2D2_dZ2 =
554+
2 * invtanl * invtanl +
555+
2 * invtanl * (DX * Hz * sin_phi_theta - DY * Hz * cos_phi_theta) * invqRtanl +
556+
2;
557+
558+
double z_new = z - dD2_dZ / d2D2_dZ2;
559+
560+
if (std::abs(z_new - z) < tol) {
561+
z = z_new;
562+
this->propagateToZhelix(z, zField);
563+
dca[0] = this->getX() - xPV;
564+
dca[1] = this->getY() - yPV;
565+
dca[2] = this->getZ() - zPV;
566+
LOG(debug) << "Converged after " << iter << " iterations for vertex X=" << p[0] << ", Y=" << p[1] << ", Z = " << p[2];
567+
return;
568+
}
569+
z = z_new;
570+
}
571+
LOG(debug) << "Failed to converge after " << iter << " iterations for vertex X=" << p[0] << ", Y=" << p[1] << ", Z = " << p[2];
572+
return;
573+
}
574+
506575
} // namespace track
507576
} // namespace o2

DataFormats/Reconstruction/src/Vertex.cxx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
// or submit itself to any jurisdiction.
1111

1212
#include "ReconstructionDataFormats/Vertex.h"
13-
#include <iostream>
1413
#ifndef GPUCA_NO_FMT
15-
#include <fmt/printf.h>
14+
#include <iostream>
15+
#include <fmt/format.h>
1616
#endif
1717

1818
namespace o2

Detectors/EMCAL/calibration/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ o2_add_library(EMCALCalibration
2020
src/PedestalCalibDevice.cxx
2121
src/PedestalProcessorDevice.cxx
2222
src/PedestalProcessorData.cxx
23+
src/EMCALTempCalibExtractor.cxx
2324
PUBLIC_LINK_LIBRARIES O2::CCDB O2::EMCALBase
2425
O2::EMCALCalib
2526
O2::EMCALReconstruction
@@ -46,6 +47,7 @@ o2_target_root_dictionary(EMCALCalibration
4647
include/EMCALCalibration/EMCDCSProcessor.h
4748
include/EMCALCalibration/EMCALPedestalHelper.h
4849
include/EMCALCalibration/PedestalProcessorData.h
50+
include/EMCALCalibration/EMCALTempCalibExtractor.h
4951
LINKDEF src/EMCALCalibrationLinkDef.h)
5052

5153
o2_add_executable(emcal-channel-calib-workflow
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
/// \class EMCALTempCalibExtractor
13+
/// \brief Calculate gain correction factors based on the temperature and the cell-by-cell temperature dependent correction factors (slope and intercept)
14+
/// \author Joshua König
15+
/// \ingroup EMCALCalib
16+
/// \since June 30, 2025
17+
18+
#ifndef EMCALTEMPCALIBEXTRACTOR_H_
19+
#define EMCALTEMPCALIBEXTRACTOR_H_
20+
21+
#include <algorithm>
22+
#include <cmath>
23+
#include <iostream>
24+
#include "CCDB/BasicCCDBManager.h"
25+
#include "EMCALCalib/ElmbData.h"
26+
#include "EMCALCalib/TempCalibrationParams.h"
27+
#include "EMCALBase/Geometry.h"
28+
29+
namespace o2
30+
{
31+
namespace emcal
32+
{
33+
34+
class EMCALTempCalibExtractor
35+
{
36+
37+
public:
38+
/// \brief Constructor
39+
EMCALTempCalibExtractor()
40+
{
41+
LOG(info) << "initialized EMCALTempCalibExtractor";
42+
try {
43+
// Try to access geometry initialized ountside
44+
mGeometry = o2::emcal::Geometry::GetInstance();
45+
} catch (o2::emcal::GeometryNotInitializedException& e) {
46+
mGeometry = o2::emcal::Geometry::GetInstanceFromRunNumber(300000); // fallback option
47+
}
48+
};
49+
/// \brief Destructor
50+
~EMCALTempCalibExtractor() = default;
51+
52+
/// \brief Initialize temperature data and slope for each cell from the ccdb
53+
/// \param path path to the slope data
54+
/// \param timestamp timestamp for the ccdb objects or runnumber (will detect automatically if its a runnumber and convert it)
55+
void InitializeFromCCDB(std::string path, uint64_t timestamp);
56+
57+
/// \brief get average temperature in a supermodule
58+
/// \param iSM SM number
59+
/// \param ElmbData object where temperature sensor values are stored
60+
/// \return average temperature in a supermodule
61+
float getTemperatureForSM(const unsigned short iSM, o2::emcal::ElmbData* ElmbData) const;
62+
63+
/// \brief get gain calibration factor depending on the temperature and the slope of the cell
64+
/// \param cellID cell ID
65+
/// \return gain calibration factor
66+
float getGainCalibFactor(const unsigned short cellID) const;
67+
68+
/// \brief set temperature range in which sensor ddata is assumed to be good
69+
/// \param low lower temperature
70+
/// \param high upper temperature
71+
void setAcceptedEnergyRange(float low, float high);
72+
73+
/// \brief set if median (true) or mean (false) should be used for averaging of the temperature in a SM
74+
void setUseMedian(const bool tmp) { mUseMedian = tmp; }
75+
76+
/// \brief get sensor IDs for a specific supermodule
77+
/// \param iSM SM number
78+
/// \return vector of sensor IDs
79+
std::vector<unsigned short> getSensorsForSM(const unsigned short iSM) const;
80+
81+
private:
82+
static constexpr unsigned short mNCells = 17664; ///< Number of EMCal cells
83+
std::array<float, mNCells> mGainCalibFactors; ///< gain calibration factors that are calculated based on the temperature and the slopes for each cell
84+
o2::emcal::Geometry* mGeometry; ///< pointer to the EMCal geometry
85+
std::array<float, 2> mAcceptedTempRange = {15., 30.}; ///< Temperature range where sensors are believed to send good data. Temperatures outside this range will be rejected
86+
bool mUseMedian = true; /// switch to decide if temperature within a SM should be calculated as the mean or the median of the individual sensor data
87+
};
88+
89+
} // namespace emcal
90+
91+
} // namespace o2
92+
93+
#endif

0 commit comments

Comments
 (0)