Skip to content

Commit 0a8f385

Browse files
authored
Merge c04a597 into sapling-pr-archive-ktf
2 parents 2f3574e + c04a597 commit 0a8f385

File tree

24 files changed

+1075
-85
lines changed

24 files changed

+1075
-85
lines changed

CODEOWNERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
/Detectors/TPC @davidrohr @wiechula @shahor02
7474
/Detectors/TRD @f3sch @bazinski @wille10
7575
/Detectors/Upgrades @mconcas
76-
/Detectors/Upgrades/ALICE3 @mconcas @njacazio
76+
/Detectors/Upgrades/ALICE3 @mconcas @njacazio @fcolamar
7777
/Detectors/Upgrades/ITS3 @fgrosa @arossi81 @mconcas @f3sch
7878
/Detectors/ZDC @coppedis @cortesep
7979
/Detectors/CTF @shahor02

Detectors/DCS/include/DetectorsDCS/DataPointCompositeObject.h

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ struct DataPointCompositeObject final {
4747
*
4848
* @see ADAPRO::ADAPOS::DataPointIdentifier
4949
*/
50-
const DataPointIdentifier id;
50+
DataPointIdentifier id;
5151

5252
/**
5353
* The DataPointValue object, which occupies the last 64 bytes of the
@@ -83,15 +83,9 @@ struct DataPointCompositeObject final {
8383
/**
8484
* Copy constructor
8585
*/
86-
DataPointCompositeObject(const DataPointCompositeObject& src) noexcept : DataPointCompositeObject(src.id, src.data) {}
86+
DataPointCompositeObject(const DataPointCompositeObject& src) noexcept = default;
8787

88-
DataPointCompositeObject& operator=(const DataPointCompositeObject& src) noexcept
89-
{
90-
if (&src != this) {
91-
memcpy(this, &src, sizeof(DataPointCompositeObject));
92-
}
93-
return *this;
94-
}
88+
DataPointCompositeObject& operator=(const DataPointCompositeObject& src) noexcept = default;
9589

9690
/**
9791
* Bit-by bit equality comparison of DataPointCompositeObjects.

Detectors/DCS/include/DetectorsDCS/DataPointIdentifier.h

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,14 @@ namespace dcs
4141
*/
4242
class DataPointIdentifier final
4343
{
44-
const uint64_t pt1;
45-
const uint64_t pt2;
46-
const uint64_t pt3;
47-
const uint64_t pt4;
48-
const uint64_t pt5;
49-
const uint64_t pt6;
50-
const uint64_t pt7;
51-
const uint64_t pt8; // Contains the last 6 chars of alias and the type.
52-
53-
DataPointIdentifier(
54-
const uint64_t pt1, const uint64_t pt2, const uint64_t pt3,
55-
const uint64_t pt4, const uint64_t pt5, const uint64_t pt6,
56-
const uint64_t pt7, const uint64_t pt8) noexcept : pt1(pt1), pt2(pt2), pt3(pt3), pt4(pt4), pt5(pt5), pt6(pt6), pt7(pt7), pt8(pt8) {}
44+
uint64_t pt1;
45+
uint64_t pt2;
46+
uint64_t pt3;
47+
uint64_t pt4;
48+
uint64_t pt5;
49+
uint64_t pt6;
50+
uint64_t pt7;
51+
uint64_t pt8; // Contains the last 6 chars of alias and the type.
5752

5853
public:
5954
/**
@@ -85,15 +80,9 @@ class DataPointIdentifier final
8580
/**
8681
* A copy constructor for DataPointIdentifier.
8782
*/
88-
DataPointIdentifier(const DataPointIdentifier& src) noexcept : DataPointIdentifier(src.pt1, src.pt2, src.pt3, src.pt4, src.pt5, src.pt6, src.pt7, src.pt8) {}
83+
DataPointIdentifier(const DataPointIdentifier& src) noexcept = default;
8984

90-
DataPointIdentifier& operator=(const DataPointIdentifier& src) noexcept
91-
{
92-
if (&src != this) {
93-
memcpy(this, &src, sizeof(DataPointIdentifier));
94-
}
95-
return *this;
96-
}
85+
DataPointIdentifier& operator=(const DataPointIdentifier& src) noexcept = default;
9786

9887
/**
9988
* This stati procedure fills the given DataPointIdentifier object with

Detectors/FIT/FT0/base/include/FT0Base/FT0DigParam.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ struct FT0DigParam : o2::conf::ConfigurableParamHelper<FT0DigParam> {
3131
float mAmpRecordUp = 15; // to [ns]
3232
float hitTimeOffsetA = 0; ///< hit time offset on the A side [ns]
3333
float hitTimeOffsetC = 0; ///< hit time offset on the C side [ns]
34-
int mtrg_central_trh = 600.; // channels
35-
int mtrg_semicentral_trh = 300.; // channels
34+
int mtrg_central_trh = 40; // Tclu units (40 for pp and 1433 for PbPb in Run3)
35+
int mtrg_semicentral_trh = 20; // Tclu units (20 for pp and 35 for PbPb in Run3)
3636

3737
float mMip_in_V = 7; // MIP to mV
3838
float mPe_in_mip = 0.004; // invserse Np.e. in MIP 1./250.
@@ -43,11 +43,12 @@ struct FT0DigParam : o2::conf::ConfigurableParamHelper<FT0DigParam> {
4343
float mNoiseVar = 0.1; // noise level
4444
float mNoisePeriod = 1 / 0.9; // GHz low frequency noise period;
4545
short mTime_trg_gate = 153; // #channels as in TCM as in Pilot beams ('OR gate' setting in TCM tab in ControlServer)
46+
short mTime_trg_vertex_gate = 100; // #channels as in TCM as in Pilot beams ('OR gate' setting in TCM tab in ControlServer)
4647
float mAmpThresholdForReco = 5; // only channels with amplitude higher will participate in calibration and collision time: 0.3 MIP
4748
short mTimeThresholdForReco = 1000; // only channels with time below will participate in calibration and collision time
4849

49-
float mMV_2_Nchannels = 2.2857143; // amplitude channel 7 mV ->16channels
50-
float mMV_2_NchannelsInverse = 0.437499997; // inverse amplitude channel 7 mV ->16channels
50+
float mMV_2_Nchannels = 2.; // amplitude channel 7 mV ->14channels
51+
float mMV_2_NchannelsInverse = 0.5; // inverse amplitude channel 7 mV ->14channels (nowhere used)
5152

5253
O2ParamDef(FT0DigParam, "FT0DigParam");
5354
};

Detectors/FIT/FT0/simulation/src/Digitizer.cxx

Lines changed: 172 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@
1616
#include "CommonConstants/PhysicsConstants.h"
1717
#include "CommonDataFormat/InteractionRecord.h"
1818

19+
#include "DataFormatsFT0/LookUpTable.h"
20+
#include "FT0Base/Constants.h"
21+
#include <map>
22+
#include <array>
23+
#include <regex>
24+
#include <string>
25+
1926
#include "TMath.h"
2027
#include "TRandom.h"
2128
#include <TH1F.h>
@@ -35,24 +42,84 @@ namespace o2::ft0
3542
template <typename Float>
3643
Float signalForm_i(Float x)
3744
{
38-
using namespace std;
39-
Float const a = -0.45458;
40-
Float const b = -0.83344945;
41-
return x > Float(0) ? -(exp(b * x) - exp(a * x)) / Float(7.8446501) : Float(0);
45+
float p0, p1, p2, p3, p4, p5, p6, p7;
46+
p0 = 1.30853;
47+
p1 = 0.516807;
48+
p2 = 3.36714;
49+
p3 = -1.01206;
50+
p4 = 1.42832;
51+
p5 = 1.1589;
52+
p6 = 1.22019;
53+
p7 = 0.426818;
54+
55+
Double_t val = 0;
56+
57+
if (x > p3) {
58+
Double_t x1 = x - p3;
59+
Double_t arg1 = (log(x1) - p0) / p1;
60+
val += p2 * (1.0 / (x1 * p1 * sqrt(2 * TMath::Pi()))) * exp(-0.5 * arg1 * arg1);
61+
}
62+
63+
if (x > p7) {
64+
Double_t x2 = x - p7;
65+
Double_t arg2 = (log(x2) - p4) / p5;
66+
val += p6 * (1.0 / (x2 * p5 * sqrt(2 * TMath::Pi()))) * exp(-0.5 * arg2 * arg2);
67+
}
68+
69+
return val;
4270
};
4371

4472
// integrated signal shape function
4573
inline float signalForm_integral(float x)
4674
{
47-
using namespace std;
48-
double const a = -0.45458;
49-
double const b = -0.83344945;
50-
if (x < 0) {
51-
x = 0;
75+
float p0, p1, p2, p3, p4, p5, p6, p7;
76+
p0 = 1.30853;
77+
p1 = 0.516807;
78+
p2 = 3.36714;
79+
p3 = -1.01206;
80+
p4 = 1.42832;
81+
p5 = 1.1589;
82+
p6 = 1.22019;
83+
p7 = 0.426818;
84+
Double_t val = 0;
85+
86+
if (x > p3) {
87+
Double_t x1 = x - p3;
88+
Double_t z1 = (log(x1) - p0) / (sqrt(2) * p1);
89+
val += p2 * 0.5 * (1 + TMath::Erf(z1)); // norm1 * CDF1
5290
}
53-
return -(exp(b * x) / b - exp(a * x) / a) / 7.8446501;
91+
92+
if (x > p7) {
93+
Double_t x2 = x - p7;
94+
Double_t z2 = (log(x2) - p4) / (sqrt(2) * p5);
95+
val += p6 * 0.5 * (1 + TMath::Erf(z2)); // norm2 * CDF2
96+
}
97+
98+
return val;
99+
};
100+
/*
101+
// signal shape function
102+
template <typename Float>
103+
Float signalForm_i(Float x)
104+
{
105+
using namespace std;
106+
Float const a = -0.45458;
107+
Float const b = -0.83344945;
108+
return x > Float(0) ? -(exp(b * x) - exp(a * x)) / Float(7.8446501) : Float(0);
54109
};
55110
111+
// integrated signal shape function
112+
inline float signalForm_integral(float x)
113+
{
114+
using namespace std;
115+
double const a = -0.45458;
116+
double const b = -0.83344945;
117+
if (x < 0) {
118+
x = 0;
119+
}
120+
return -(exp(b * x) / b - exp(a * x) / a) / 7.8446501;
121+
};
122+
*/
56123
// SIMD version of the integrated signal shape function
57124
inline Vc::float_v signalForm_integralVc(Vc::float_v x)
58125
{
@@ -249,8 +316,64 @@ void Digitizer::storeBC(BCCache& bc,
249316
if (bc.hits.empty()) {
250317
return;
251318
}
319+
// Initialize mapping channelID -> PM hash and PM side (A/C) using FT0 LUT
320+
static bool pmLutInitialized = false;
321+
static std::array<uint8_t, o2::ft0::Constants::sNCHANNELS_PM> mChID2PMhash{};
322+
static std::map<uint8_t, bool> mMapPMhash2isAside; // hashed PM -> is A side
323+
324+
if (!pmLutInitialized) {
325+
std::map<std::string, uint8_t> mapFEE2hash; // module name -> hashed PM id
326+
uint8_t tcmHash = 0;
327+
328+
const auto& lut = o2::ft0::SingleLUT::Instance().getVecMetadataFEE();
329+
auto lutSorted = lut;
330+
std::sort(lutSorted.begin(), lutSorted.end(),
331+
[](const auto& first, const auto& second) { return first.mModuleName < second.mModuleName; });
332+
333+
uint8_t binPos = 0;
334+
for (const auto& lutEntry : lutSorted) {
335+
const auto& moduleName = lutEntry.mModuleName;
336+
const auto& moduleType = lutEntry.mModuleType;
337+
const auto& strChID = lutEntry.mChannelID;
338+
339+
auto [it, inserted] = mapFEE2hash.insert({moduleName, binPos});
340+
if (inserted) {
341+
if (moduleName.find("PMA") != std::string::npos) {
342+
mMapPMhash2isAside.insert({binPos, true});
343+
} else if (moduleName.find("PMC") != std::string::npos) {
344+
mMapPMhash2isAside.insert({binPos, false});
345+
}
346+
++binPos;
347+
}
348+
349+
if (std::regex_match(strChID, std::regex("^[0-9]{1,3}$"))) {
350+
int chID = std::stoi(strChID);
351+
if (chID < o2::ft0::Constants::sNCHANNELS_PM) {
352+
mChID2PMhash[chID] = mapFEE2hash[moduleName];
353+
} else {
354+
LOG(fatal) << "Incorrect LUT entry: chID " << strChID << " | " << moduleName;
355+
}
356+
} else if (moduleType != "TCM") {
357+
LOG(fatal) << "Non-TCM module w/o numerical chID: chID " << strChID << " | " << moduleName;
358+
} else { // TCM
359+
tcmHash = mapFEE2hash[moduleName];
360+
}
361+
}
362+
363+
pmLutInitialized = true;
364+
}
365+
252366
int n_hit_A = 0, n_hit_C = 0, mean_time_A = 0, mean_time_C = 0;
253367
int summ_ampl_A = 0, summ_ampl_C = 0;
368+
int sum_A_ampl = 0, sum_C_ampl = 0;
369+
int nPMTs = mGeometry.NCellsA * 4 + mGeometry.NCellsC * 4;
370+
std::vector<int> sum_ampl_ipmt(nPMTs, 0);
371+
// Per-PM summed charge (like in digits2trgFT0)
372+
std::map<uint8_t, int> mapPMhash2sumAmpl;
373+
for (const auto& entry : mMapPMhash2isAside) {
374+
mapPMhash2sumAmpl.insert({entry.first, 0});
375+
}
376+
254377
int vertex_time;
255378
const auto& params = FT0DigParam::Instance();
256379
int first = digitsCh.size(), nStored = 0;
@@ -297,6 +420,10 @@ void Digitizer::storeBC(BCCache& bc,
297420
if (is_time_in_signal_gate) {
298421
chain |= (1 << o2::ft0::ChannelData::EEventDataBit::kIsCFDinADCgate);
299422
chain |= (1 << o2::ft0::ChannelData::EEventDataBit::kIsEventInTVDC);
423+
// Sum channel charge per PM (similar logic as in digits2trgFT0)
424+
if (ipmt < o2::ft0::Constants::sNCHANNELS_PM) {
425+
mapPMhash2sumAmpl[mChID2PMhash[static_cast<uint8_t>(ipmt)]] += static_cast<int>(amp);
426+
}
300427
}
301428
digitsCh.emplace_back(ipmt, smeared_time, int(amp), chain);
302429
nStored++;
@@ -308,6 +435,8 @@ void Digitizer::storeBC(BCCache& bc,
308435
continue;
309436
}
310437

438+
sum_ampl_ipmt[ipmt] += amp;
439+
311440
if (is_A_side) {
312441
n_hit_A++;
313442
summ_ampl_A += amp;
@@ -318,17 +447,47 @@ void Digitizer::storeBC(BCCache& bc,
318447
mean_time_C += smeared_time;
319448
}
320449
}
450+
451+
for (size_t i = 0; i < sum_ampl_ipmt.size(); i++) {
452+
sum_ampl_ipmt[i] = sum_ampl_ipmt[i] >> 3;
453+
if (i < 4 * mGeometry.NCellsA) {
454+
sum_A_ampl += sum_ampl_ipmt[i];
455+
} else {
456+
sum_C_ampl += sum_ampl_ipmt[i];
457+
}
458+
}
459+
460+
// Sum over PMs (using per-PM map) for debug/monitoring
461+
int sum_PM_ampl_debug = 0;
462+
int sum_PM_ampl_A_debug = 0;
463+
int sum_PM_ampl_C_debug = 0;
464+
for (const auto& entry : mapPMhash2sumAmpl) {
465+
int pmAmpl = (entry.second >> 3);
466+
sum_PM_ampl_debug += pmAmpl;
467+
auto itSide = mMapPMhash2isAside.find(entry.first);
468+
if (itSide != mMapPMhash2isAside.end()) {
469+
if (itSide->second) {
470+
sum_PM_ampl_A_debug += pmAmpl;
471+
} else {
472+
sum_PM_ampl_C_debug += pmAmpl;
473+
}
474+
}
475+
}
476+
LOG(debug) << "Sum PM amplitude (LUT-based): total=" << sum_PM_ampl_debug
477+
<< " A-side=" << sum_PM_ampl_A_debug
478+
<< " C-side=" << sum_PM_ampl_C_debug;
479+
321480
Bool_t is_A, is_C, isVertex, is_Central, is_SemiCentral = 0;
322481
is_A = n_hit_A > 0;
323482
is_C = n_hit_C > 0;
324-
is_Central = summ_ampl_A + summ_ampl_C >= params.mtrg_central_trh;
325-
is_SemiCentral = summ_ampl_A + summ_ampl_C >= params.mtrg_semicentral_trh;
483+
is_Central = sum_PM_ampl_A_debug + sum_PM_ampl_C_debug >= 2 * params.mtrg_central_trh;
484+
is_SemiCentral = sum_PM_ampl_A_debug + sum_PM_ampl_C_debug >= 2 * params.mtrg_semicentral_trh && !is_Central;
326485
uint32_t amplA = is_A ? summ_ampl_A * 0.125 : -5000; // sum amplitude A side / 8 (hardware)
327486
uint32_t amplC = is_C ? summ_ampl_C * 0.125 : -5000; // sum amplitude C side / 8 (hardware)
328487
int timeA = is_A ? mean_time_A / n_hit_A : -5000; // average time A side
329488
int timeC = is_C ? mean_time_C / n_hit_C : -5000; // average time C side
330489
vertex_time = (timeC - timeA) * 0.5;
331-
isVertex = is_A && is_C && (vertex_time > -params.mTime_trg_gate && vertex_time < params.mTime_trg_gate);
490+
isVertex = is_A && is_C && (vertex_time > -params.mTime_trg_vertex_gate && vertex_time < params.mTime_trg_vertex_gate);
332491
LOG(debug) << " A " << is_A << " timeA " << timeA << " mean_time_A " << mean_time_A << " n_hit_A " << n_hit_A << " C " << is_C << " timeC " << timeC << " mean_time_C " << mean_time_C << " n_hit_C " << n_hit_C << " vertex_time " << vertex_time;
333492
Triggers triggers;
334493
bool isLaser = false;

Detectors/FIT/FV0/simulation/include/FV0Simulation/FV0DigParam.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ struct FV0DigParam : o2::conf::ConfigurableParamHelper<FV0DigParam> {
6969
uint8_t defaultChainQtc = 0x48; // only 2 flags are set by default in simulation: kIsCFDinADCgate and kIsEventInTVDC
7070
float mAmpThresholdForReco = 24; // only channels with amplitude higher will participate in calibration and collision time
7171
short mTimeThresholdForReco = 1000; // only channels with time below will participate in calibration and collision time
72+
int NchannelsLevel = 2; // trigger Nchannels
73+
float InnerChargeLevel = 4; // InnerRingsChargeLevel
74+
float OuterChargeLevel = 4; // OuterRingsChargeLevel
75+
float ChargeLevel = 8; // ChargeLevel
7276

7377
O2ParamDef(FV0DigParam, "FV0DigParam");
7478
};

0 commit comments

Comments
 (0)