ATLAS Offline Software
Loading...
Searching...
No Matches
LArCaliWaveFromTuple.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6
11
12#include "TFile.h"
13#include "TBranch.h"
14#include "TTree.h"
15#include "TChain.h"
16
17#include <vector>
18#include <map>
19#include <algorithm> //for std::find
20#include <string>
21#include <ranges>
22#include <cmath> //for sqrt
23#include <ios> //for hex, dec
24#include <memory>
25
26
28{
29 ATH_MSG_INFO ( "... in stop()" );
30
31 const std::vector<int> FEBs={0x39000000, 0x39010000, 0x39018000, 0x39020000, 0x39028000, 0x39030000, 0x39038000, 0x39040000, 0x39048000, 0x39050000, 0x39058000, 0x39060000, 0x39068000};
32
33 TChain* outfit = new TChain(m_ntuple_name.value().c_str());
34 outfit->Add(m_root_file_name.value().c_str());
35
36 // This algorithm assumes the input NTuple in contains less than 32
37 // points. If the NTuple contains less than 32 points, the
38 // remaining points are automatically initialized to 0.
39 // Catch potential array index out of range error.
40 if ( m_NPoints > 32 ) {
41 ATH_MSG_WARNING ( " Too many points specified vs the expected content of the ntuple ! " );
42 ATH_MSG_WARNING ( " Only 32 will be used !");
43 m_NPoints = 32;
44 }
45
46 // loop over delay branch and find number of existing delays
47 Int_t delay;
48 Int_t febid;
49 outfit->SetBranchAddress("delay", &delay);
50 outfit->SetBranchAddress("febId", &febid);
51 Long64_t nentries = outfit->GetEntries();
52 std::map<int,int> tmpmap;
53 std::vector<int> febvec;
54 for(Long64_t i = 0; i < nentries; ++i ){
55 outfit->GetEntry(i);
56 tmpmap[delay]=delay;
57 if(std::find(febvec.begin(), febvec.end(), febid) == febvec.end()) febvec.push_back(febid);
58 }
59 unsigned ndelays = tmpmap.size();
60 if(febvec.size() > 13) {
61 ATH_MSG_ERROR("Too many FEBs in the ntuple, fix the code");
62 return StatusCode::FAILURE;
63 }
64
65 // variable names as in the Ntuple
66 Int_t febchannel;
67 Int_t gain;
68 Int_t dac;
69 std::vector<int> *Amplitude = nullptr;
70 outfit->SetBranchAddress("febChannel", &febchannel);
71 outfit->SetBranchAddress("gain", &gain);
72 outfit->SetBranchAddress("dac", &dac);
73 outfit->SetBranchAddress("ADC", &Amplitude);
74
75 // Create new LArCaliWaveContainer
76 auto larCaliWaveContainerNew = std::make_unique<LArCaliWaveContainer>();
77 ATH_CHECK ( larCaliWaveContainerNew->setGroupingType(m_groupingType, msg()) );
78 ATH_CHECK ( larCaliWaveContainerNew->initialize() );
79
80 // loop over entries in the Tuple, fill the waves sum and sum2
81 typedef std::map<HWIdentifier,std::map<std::pair<short, int> , std::vector<long int> > > Wavesmap_t;
82 Wavesmap_t wavesum;
83 Wavesmap_t wavesum2;
84 Wavesmap_t wavensum;
85 for ( Long64_t iev = 0; iev < nentries; ++iev ) {
86 outfit->GetEvent(iev);
87 //check gain validity
88 if(gain < CaloGain::LARHIGHGAIN || gain >= CaloGain::LARNGAINR4) continue; // bad gain value
89 // hack until real febId in ntuple:
90 auto it = std::find(febvec.begin(), febvec.end(), febid);
91 unsigned int index= it - febvec.begin();
92 HWIdentifier id( FEBs[index] | ((febchannel&0x7F)<<8) );
93 ATH_MSG_DEBUG ( "onlineid created " << std::hex << id << std::dec);
94 std::pair<short, int> idpair=std::make_pair(gain,dac);
95 // check if we have this HWid and gain.dac pair already
96 if( ! wavesum.count(id) || ! wavesum[id].count(idpair)) { // we have new combination
97 wavesum[id][idpair].reserve((m_NPoints + m_prefixPoints) * ndelays);
98 wavesum2[id][idpair].reserve((m_NPoints + m_prefixPoints) * ndelays);
99 wavensum[id][idpair].reserve((m_NPoints + m_prefixPoints) * ndelays);
100 for ( unsigned int i = 0; i < (m_NPoints + m_prefixPoints) * ndelays; ++i ){
101 wavesum[id][idpair][i]=0;
102 wavesum2[id][idpair][i]=0;
103 wavensum[id][idpair][i]=0;
104 }
105 }
106 unsigned upper = m_NPoints.value() > Amplitude->size() ? Amplitude->size() : m_NPoints.value();
107 for ( unsigned int i = 0; i < upper; ++i) {
108 if ( m_skipPoints > 0 && m_skipPoints <= i+1 ) continue;
109 wavesum[id][idpair][(m_prefixPoints+delay)*ndelays*m_NPoints + i] += Amplitude->at(i);
110 wavesum2[id][idpair][(m_prefixPoints+delay)*ndelays*m_NPoints + i] += Amplitude->at(i)*Amplitude->at(i);
111 wavensum[id][idpair][(m_prefixPoints+delay)*ndelays*m_NPoints + i] += 1;
112 }
113
114 }// loop over ntuple
115 ATH_MSG_INFO("Loop done");
116
117 // compute the average and fill LArCaliWaveVec
118 double dt=m_dt.value();
119 for(auto & [hwid, wmap] : wavesum) {
120 std::vector<LArCaliWaveVec> waveVec(CaloGain::LARNGAINR4);
121 for(auto dgkey : std::views::keys(wavesum[hwid])) {
122 auto dac = dgkey.second;
123 auto gain = dgkey.first;
124 std::vector<double> amp((m_NPoints + m_prefixPoints) * ndelays, 0.);
125 std::vector<double> err((m_NPoints + m_prefixPoints) * ndelays, 0.);
126 std::vector<int> ntrig((m_NPoints + m_prefixPoints) * ndelays, 0);
127 for(unsigned int i=0; i< (m_NPoints + m_prefixPoints) * ndelays; ++i) {
128 if(wavensum[hwid][dgkey][i] > 0) {
129 amp[i] = (double)wavesum[hwid][dgkey][i] / wavensum[hwid][dgkey][i];
130 err[i] = std::sqrt((double)wavesum2[hwid][dgkey][i] / wavensum[hwid][dgkey][i] - amp[i]*amp[i]);
131 ntrig[i] = wavensum[hwid][dgkey][i];
132 }
133 }
134 waveVec[gain].push_back(LArCaliWave(amp, err, ntrig, dt, dac,1, LArWave::meas));
135 }
136 // Add waveVec to container
137 for(unsigned ig = CaloGain::LARHIGHGAIN; ig < CaloGain::LARNGAINR4; ++ ig) {
138 larCaliWaveContainerNew->setPdata(hwid, waveVec[ig], (CaloGain::CaloGain)ig);
139 }
140 }
141
142
143 ATH_CHECK( detStore()->record(std::move(larCaliWaveContainerNew),m_store_key) );
144 ATH_MSG_INFO ( "LArCaliWaveFromTuple finalized!" );
145 return StatusCode::SUCCESS;
146}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_INFO(x,...)
double delay(std::size_t d)
int upper(int c)
const ServiceHandle< StoreGateSvc > & detStore() const
Gaudi::Property< std::string > m_ntuple_name
ntuple name
StatusCode stop() override
Gaudi::Property< unsigned int > m_NPoints
max number of points of the waveform in the ntuple
Gaudi::Property< std::string > m_root_file_name
input file name
Gaudi::Property< float > m_dt
Gaudi::Property< unsigned int > m_skipPoints
the first m_skipPoints points of the waveform in the ntuple are skipped
Gaudi::Property< std::string > m_groupingType
Grouping type. Default is Feedthrough.
Gaudi::Property< unsigned int > m_prefixPoints
make a PhysWave with the first m_prefixPoints as zeros
Gaudi::Property< std::string > m_store_key
key of the PhysWave collection in Storegate
@ LARNGAINR4
Definition CaloGain.h:20
@ LARHIGHGAIN
Definition CaloGain.h:18
Definition index.py:1