1616#include " CommonConstants/PhysicsConstants.h"
1717#include " CommonDataFormat/InteractionRecord.h"
1818
19- #include " DataFormatsFT0/LookUpTable .h"
19+ #include " DataFormatsFT0/PMLookupTable .h"
2020#include " FT0Base/Constants.h"
2121#include < map>
22- #include < array>
23- #include < unordered_map>
24- #include < regex>
25- #include < string>
2622
2723#include " TMath.h"
2824#include " TRandom.h"
@@ -317,52 +313,7 @@ void Digitizer::storeBC(BCCache& bc,
317313 if (bc.hits .empty ()) {
318314 return ;
319315 }
320- // Initialize mapping channelID -> PM hash and PM side (A/C) using FT0 LUT
321- static bool pmLutInitialized = false ;
322- static std::array<uint8_t , o2::ft0::Constants::sNCHANNELS_PM > mChID2PMhash {};
323- static std::map<uint8_t , bool > mMapPMhash2isAside ; // hashed PM -> is A side
324-
325- if (!pmLutInitialized) {
326- std::map<std::string, uint8_t > mapFEE2hash; // module name -> hashed PM id
327- uint8_t tcmHash = 0 ;
328-
329- const auto & lut = o2::ft0::SingleLUT::Instance ().getVecMetadataFEE ();
330- auto lutSorted = lut;
331- std::sort (lutSorted.begin (), lutSorted.end (),
332- [](const auto & first, const auto & second) { return first.mModuleName < second.mModuleName ; });
333-
334- uint8_t binPos = 0 ;
335- for (const auto & lutEntry : lutSorted) {
336- const auto & moduleName = lutEntry.mModuleName ;
337- const auto & moduleType = lutEntry.mModuleType ;
338- const auto & strChID = lutEntry.mChannelID ;
339-
340- auto [it, inserted] = mapFEE2hash.insert ({moduleName, binPos});
341- if (inserted) {
342- if (moduleName.find (" PMA" ) != std::string::npos) {
343- mMapPMhash2isAside .insert ({binPos, true });
344- } else if (moduleName.find (" PMC" ) != std::string::npos) {
345- mMapPMhash2isAside .insert ({binPos, false });
346- }
347- ++binPos;
348- }
349-
350- if (std::regex_match (strChID, std::regex (" ^[0-9]{1,3}$" ))) {
351- int chID = std::stoi (strChID);
352- if (chID < o2::ft0::Constants::sNCHANNELS_PM ) {
353- mChID2PMhash [chID] = mapFEE2hash[moduleName];
354- } else {
355- LOG (fatal) << " Incorrect LUT entry: chID " << strChID << " | " << moduleName;
356- }
357- } else if (moduleType != " TCM" ) {
358- LOG (fatal) << " Non-TCM module w/o numerical chID: chID " << strChID << " | " << moduleName;
359- } else { // TCM
360- tcmHash = mapFEE2hash[moduleName];
361- }
362- }
363-
364- pmLutInitialized = true ;
365- }
316+ const auto & pmLookupTable = PMLookupTable::Instance ();
366317
367318 int n_hit_A = 0 , n_hit_C = 0 , mean_time_A = 0 , mean_time_C = 0 ;
368319 int summ_ampl_A = 0 , summ_ampl_C = 0 ;
@@ -371,57 +322,25 @@ void Digitizer::storeBC(BCCache& bc,
371322 std::vector<int > sum_ampl_ipmt (nPMTs, 0 );
372323 // Per-PM summed charge (like in digits2trgFT0)
373324 std::map<uint8_t , int > mapPMhash2sumAmpl;
374- for (const auto & entry : mMapPMhash2isAside ) {
325+ for (const auto & entry : pmLookupTable. getPMs () ) {
375326 mapPMhash2sumAmpl.insert ({entry.first , 0 });
376327 }
377328
378329 int vertex_time;
379330 const auto & params = FT0DigParam::Instance ();
380-
381- static bool pmGroupsInitialized = false ;
382- static std::vector<std::array<int , 4 >> pmtChannelGroups;
383- if (!pmGroupsInitialized) {
384- std::unordered_map<uint8_t , std::vector<int >> tmpGroups;
385- for (int ch = 0 ; ch < o2::ft0::Constants::sNCHANNELS_PM ; ++ch) {
386- tmpGroups[mChID2PMhash [static_cast <uint8_t >(ch)]].push_back (ch);
387- }
388-
389- for (auto & [pmHash, chVec] : tmpGroups) {
390- std::sort (chVec.begin (), chVec.end ());
391- if (chVec.size () % 4 != 0 ) {
392- LOG (fatal) << " PM hash " << int (pmHash) << " has " << chVec.size ()
393- << " channels in LUT, expected multiplicity of 4" ;
394- }
395- for (size_t i = 0 ; i < chVec.size (); i += 4 ) {
396- std::array<int , 4 > arr = {chVec[i + 0 ], chVec[i + 1 ], chVec[i + 2 ], chVec[i + 3 ]};
397- pmtChannelGroups.push_back (arr);
398- }
399- }
400- pmGroupsInitialized = true ;
401- }
402-
403331 int first = digitsCh.size (), nStored = 0 ;
404332 auto & particles = bc.hits ;
405333 std::sort (std::begin (particles), std::end (particles));
406334 auto channel_end = particles.begin ();
407335 std::vector<float > channel_times;
408- std::vector<float > baseAmp (params.mMCPs , 0 .f );
409- std::vector<float > finalAmp (params.mMCPs , 0 .f );
410- std::vector<int > chTime (params.mMCPs , -5000 );
411- std::vector<int > chChain (params.mMCPs , 0 );
412- std::vector<bool > chValid (params.mMCPs , false );
413-
414- static const std::array<std::array<int , 3 >, 4 > localNeighbours = {{{{1 , 2 , 3 }},
415- {{0 , 3 , 2 }},
416- {{0 , 3 , 1 }},
417- {{1 , 2 , 0 }}}};
418-
419- // std::set<int> disabledChannels = {40, 41, 42, 43, 88, 89, 90, 91, 56, 57, 58, 59, 60, 61, 62, 63, 72, 73, 74, 75, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 164, 165, 166, 167, 184, 185, 186, 187, 160, 161, 162, 163, 188, 189, 190, 191, 156, 157, 158, 159, 192, 193, 194, 195, 152, 153, 154, 155, 196, 197, 198, 199, 148, 149, 150, 151, 144, 145, 146, 147, 204, 205, 206, 207, 200, 201, 202, 203}; // przykładowe kanały
336+ // std::set<int> disabledChannels = {40, 41, 42, 43, 88, 89, 90, 91, 56, 57, 58, 59, 60, 61, 62, 63, 72, 73, 74, 75, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 164, 165, 166, 167, 184, 185, 186, 187, 160, 161, 162, 163, 188, 189, 190, 191, 156, 157, 158, 159, 192, 193, 194, 195, 152, 153, 154, 155, 196, 197, 198, 199, 148, 149, 150, 151, 144, 145, 146, 147, 204, 205, 206, 207, 200, 201, 202, 203}; // przykładowe kanały
420337 for (Int_t ipmt = 0 ; ipmt < params.mMCPs ; ++ipmt) {
421338 auto channel_begin = channel_end;
422339 channel_end = std::find_if (channel_begin, particles.end (),
423340 [ipmt](BCCache::particle const & p) { return p.hit_ch != ipmt; });
424341
342+ // The hits between 'channel_begin' and 'channel_end' now contains all hits for channel 'ipmt'
343+
425344 if (channel_end - channel_begin < params.mAmp_trsh ) {
426345 continue ;
427346 }
@@ -442,98 +361,31 @@ void Digitizer::storeBC(BCCache& bc,
442361 if (mCalibOffset ) {
443362 miscalib = mCalibOffset ->mTimeOffsets [ipmt];
444363 }
445- int smeared_time = 1000 . * (*cfd.particle - params.mCfdShift ) * params.mChannelWidthInverse + miscalib;
364+ int smeared_time = 1000 . * (*cfd.particle - params.mCfdShift ) * params.mChannelWidthInverse + miscalib; // + int(1000. * mIntRecord.getTimeOffsetWrtBC() * params.mChannelWidthInverse);
446365 bool is_time_in_signal_gate = (smeared_time > -params.mTime_trg_gate && smeared_time < params.mTime_trg_gate );
447366 float charge = measure_amplitude (channel_times) * params.mCharge2amp ;
448- float amp = is_time_in_signal_gate ? params.mMV_2_Nchannels * charge : 0 . f ;
449- if (amp > 4095 . f ) {
450- amp = 4095 . f ;
367+ float amp = is_time_in_signal_gate ? params.mMV_2_Nchannels * charge : 0 ;
368+ if (amp > 4095 ) {
369+ amp = 4095 ;
451370 }
452- // if (!disabledChannels.count(ipmt)) {
453- // continue;
454- // }
455-
456- LOG (debug) << mEventID << " bc " << firstBCinDeque.bc << " orbit " << firstBCinDeque.orbit
457- << " , ipmt " << ipmt << " , smeared_time " << smeared_time
458- << " nStored " << nStored << " offset " << miscalib
459- << " base amp " << amp;
371+ // if (!disabledChannels.count(ipmt)) {
372+ // continue;
373+ // }
374+
375+ LOG (debug) << mEventID << " bc " << firstBCinDeque.bc << " orbit " << firstBCinDeque.orbit << " , ipmt " << ipmt << " , smeared_time " << smeared_time << " nStored " << nStored << " offset " << miscalib;
460376 if (is_time_in_signal_gate) {
461377 chain |= (1 << o2::ft0::ChannelData::EEventDataBit::kIsCFDinADCgate );
462378 chain |= (1 << o2::ft0::ChannelData::EEventDataBit::kIsEventInTVDC );
463- }
464-
465- baseAmp[ipmt] = amp;
466- finalAmp[ipmt] = amp;
467- chTime[ipmt] = smeared_time;
468- chChain[ipmt] = chain;
469- chValid[ipmt] = true ;
470- }
471-
472- for (const auto & channels : pmtChannelGroups) {
473- for (int localIdx = 0 ; localIdx < 4 ; ++localIdx) {
474- const int src = channels[localIdx];
475- if (!chValid[src] || baseAmp[src] <= 0 .f ) {
476- continue ;
477- }
478-
479- const int nb1 = channels[localNeighbours[localIdx][0 ]];
480- const int nb2 = channels[localNeighbours[localIdx][1 ]];
481- const int diag = channels[localNeighbours[localIdx][2 ]];
482-
483- const float directXtalk = baseAmp[src] * params.Cross_Talk_Frac ;
484- const float diagXtalk = baseAmp[src] * (params.Cross_Talk_Frac / 3 .f );
485-
486- finalAmp[nb1] += directXtalk;
487- finalAmp[nb2] += directXtalk;
488- finalAmp[diag] += diagXtalk;
489-
490- if (!chValid[nb1] && directXtalk >= params.mAmpThresholdForCrossTalkDigit ) {
491- chValid[nb1] = true ;
492- chTime[nb1] = chTime[src];
493- chChain[nb1] = chChain[src];
494- }
495-
496- if (!chValid[nb2] && directXtalk >= params.mAmpThresholdForCrossTalkDigit ) {
497- chValid[nb2] = true ;
498- chTime[nb2] = chTime[src];
499- chChain[nb2] = chChain[src];
500- }
501-
502- if (!chValid[diag] && diagXtalk >= params.mAmpThresholdForCrossTalkDigit ) {
503- chValid[diag] = true ;
504- chTime[diag] = chTime[src];
505- chChain[diag] = chChain[src];
379+ // Sum channel charge per PM (similar logic as in digits2trgFT0)
380+ if (ipmt < o2::ft0::Constants::sNCHANNELS_PM ) {
381+ mapPMhash2sumAmpl[pmLookupTable.getPMHash (static_cast <PMLookupTable::ChannelID>(ipmt))] += static_cast <int >(amp);
506382 }
507383 }
508- }
509-
510- for (Int_t ipmt = 0 ; ipmt < params.mMCPs ; ++ipmt) {
511- if (!chValid[ipmt]) {
512- continue ;
513- }
514-
515- float amp = finalAmp[ipmt];
516- if (amp > 4095 .f ) {
517- amp = 4095 .f ;
518- }
519- const bool hasPrimarySignal = (baseAmp[ipmt] > 0 .f );
520- const bool isCrossTalkOnly = (!hasPrimarySignal && amp > 0 .f );
521-
522- if (isCrossTalkOnly && amp < params.mAmpThresholdForCrossTalkDigit ) {
523- continue ;
524- }
525-
526- const int smeared_time = chTime[ipmt];
527- const int chain = chChain[ipmt];
528- const bool is_time_in_signal_gate = (smeared_time > -params.mTime_trg_gate && smeared_time < params.mTime_trg_gate );
529-
530- if (is_time_in_signal_gate && ipmt < o2::ft0::Constants::sNCHANNELS_PM ) {
531- mapPMhash2sumAmpl[mChID2PMhash [static_cast <uint8_t >(ipmt)]] += static_cast <int >(amp);
532- }
533-
534384 digitsCh.emplace_back (ipmt, smeared_time, int (amp), chain);
535385 nStored++;
536386
387+ // fill triggers
388+
537389 Bool_t is_A_side = (ipmt < 4 * mGeometry .NCellsA );
538390 if (!is_time_in_signal_gate) {
539391 continue ;
@@ -568,13 +420,10 @@ void Digitizer::storeBC(BCCache& bc,
568420 for (const auto & entry : mapPMhash2sumAmpl) {
569421 int pmAmpl = (entry.second >> 3 );
570422 sum_PM_ampl_debug += pmAmpl;
571- auto itSide = mMapPMhash2isAside .find (entry.first );
572- if (itSide != mMapPMhash2isAside .end ()) {
573- if (itSide->second ) {
574- sum_PM_ampl_A_debug += pmAmpl;
575- } else {
576- sum_PM_ampl_C_debug += pmAmpl;
577- }
423+ if (pmLookupTable.isASide (entry.first )) {
424+ sum_PM_ampl_A_debug += pmAmpl;
425+ } else {
426+ sum_PM_ampl_C_debug += pmAmpl;
578427 }
579428 }
580429 LOG (debug) << " Sum PM amplitude (LUT-based): total=" << sum_PM_ampl_debug
0 commit comments