31 std::size_t getIndex(
const std::vector<float> &
bins,
float value)
33 auto itr = std::upper_bound(
bins.begin(),
bins.end(), value);
37 if (itr ==
bins.end())
39 if (itr ==
bins.begin())
41 return std::distance(
bins.begin(), itr) - 1;
45 float getRandom(
const std::map<float, float> &integrals, std::mt19937_64 &generator)
55 float start = integrals.begin()->first;
56 float end = integrals.rbegin()->first;
57 std::uniform_real_distribution<float> distr(start, end);
58 float r = distr(generator);
59 auto itr = integrals.lower_bound(
r);
60 if (itr == integrals.end() || itr == integrals.begin())
65 float lowBinEdge, lowBinValue, highBinEdge, highBinValue;
66 std::tie(highBinEdge, highBinValue) = *itr;
67 std::tie(lowBinEdge, lowBinValue) = *(--itr);
69 float pctDiff = (
r - lowBinEdge) / (highBinEdge - lowBinEdge);
70 return lowBinValue + pctDiff * (highBinValue - lowBinValue);
105 if (!timingFile || timingFile->IsZombie())
108 return StatusCode::FAILURE;
110 TDirectory *tdir = timingFile->GetDirectory(
"CellTiming");
114 return StatusCode::FAILURE;
118 std::regex pattern(
"Layer(\\d+)_([\\d.]+)eta([\\d.]+)_([\\d.-]+)ET([\\d.-]+)_midtrain");
119 std::map<CaloSampling::CaloSample, std::set<std::pair<float, float>>> etaBins;
120 std::map<CaloSampling::CaloSample, std::set<std::pair<float, float>>> etBins;
121 std::map<CaloSampling::CaloSample, std::map<std::pair<std::pair<float, float>, std::pair<float, float>>, TH1F *>> tmpHistMap;
122 std::set<CaloSampling::CaloSample> samples;
123 for (TObject *obj : *tdir->GetListOfKeys())
125 TKey *key =
dynamic_cast<TKey *
>(obj);
129 return StatusCode::FAILURE;
132 if (!std::regex_match(key->GetName(),
match, pattern))
136 if (std::strcmp(key->GetClassName(),
"TH1F") != 0)
138 ATH_MSG_ERROR(
"Object " << key->GetName() <<
" not histogram as expected!");
139 return StatusCode::FAILURE;
142 samples.insert(sample);
144 auto etaBin = std::make_pair(std::stof(
match.str(2)), std::stof(
match.str(3)));
145 auto etBin = std::make_pair(std::stof(
match.str(4)), std::stof(
match.str(5)));
147 etaBins[sample].insert(etaBin);
148 etBins[sample].insert(etBin);
149 tmpHistMap[sample][std::make_pair(etaBin, etBin)] = (TH1F *)key->ReadObj();
154 auto itr = etaBins[sample].begin();
155 auto end = etaBins[sample].end();
156 m_etaBins[sample].reserve(std::distance(itr, end) + 1);
158 m_etaBins[sample].push_back(itr->second);
160 for (; itr != end; ++itr)
163 if (itr->first !=
m_etaBins[sample].back())
165 ATH_MSG_ERROR(
"Eta bins do not match up for sample " << sample <<
"(" <<
m_etaBins[sample].back() <<
", " << itr->first <<
")");
166 return StatusCode::FAILURE;
168 m_etaBins[sample].push_back(itr->second);
171 itr = etBins[sample].begin();
172 end = etBins[sample].end();
173 m_etBins[sample].reserve(std::distance(itr, end) + 1);
174 m_etBins[sample].push_back(itr->first);
175 m_etBins[sample].push_back(itr->second);
177 for (; itr != end; ++itr)
180 if (itr->first !=
m_etBins[sample].back())
182 ATH_MSG_ERROR(
"Et bins do not match up for sample " << sample);
183 return StatusCode::FAILURE;
185 m_etBins[sample].push_back(itr->second);
189 for (
const auto &p : tmpHistMap[sample])
192 std::size_t etaIndex =
getEtaIndex(sample, p.first.first.first);
193 std::size_t etIndex =
getEtIndex(sample, p.first.second.first);
194 auto mapKey = std::make_tuple(sample, etaIndex, etIndex);
196 float cumulativeSum = 0;
197 TAxis *axis = p.second->GetXaxis();
198 integrals[cumulativeSum] = axis->GetBinLowEdge(1);
199 for (
int idx = 1; idx < axis->GetNbins(); ++idx)
201 cumulativeSum += p.second->GetBinContent(idx);
202 integrals[cumulativeSum] = axis->GetBinUpEdge(idx);
206 return StatusCode::SUCCESS;
212 auto superCells = std::make_unique<CaloCellContainer>();
215 if (!cells.isValid())
218 return StatusCode::FAILURE;
226 if (!handle.isValid())
229 return StatusCode::FAILURE;
231 caloBCIDAvg = handle.cptr();
239 return StatusCode::FAILURE;
241 caloNoiseSigmaDiff = handle.
cptr();
248 if (!evtInfo.isValid())
251 return StatusCode::FAILURE;
253 std::mt19937_64 generator;
255 generator.seed(evtInfo->eventNumber() * evtInfo->runNumber());
264 std::vector<float> energies(nSuperCells, 0.0);
265 std::vector<float> enTime(nSuperCells, 0.0);
266 std::vector<float> enForTime(nSuperCells, 0.0);
267 std::vector<char> timeDef(nSuperCells,
false);
268 std::vector<uint16_t>
qualities(nSuperCells, 0);
269 std::vector<float> sigmaNoisePerSuperCell(nSuperCells, 0.0);
283 float energy = cell->energy();
285 energy += caloBCIDAvg->
average(cellID);
286 energies[scIDHash] += energy;
288 sigmaNoisePerSuperCell[scIDHash] += (*caloNoiseSigmaDiff)[cellIDHash];
292 bool isTile_BAD = s >= 9 && s < 21;
293 if (cell->provenance() & 0x2000)
295 if (cell->energy() > 256)
298 timeDef[scIDHash] |=
true;
299 enForTime[scIDHash] += cell->energy();
300 enTime[scIDHash] += cell->energy() * cell->time();
302 else if (!isTile_BAD)
308 std::size_t iEta =
getEtaIndex(sample, std::abs(cell->eta()));
309 if (iEta == SIZE_MAX)
311 ATH_MSG_ERROR(
"Eta value " << cell->eta() <<
" for sampling " << sample <<
" does not fall in a bin");
312 return StatusCode::FAILURE;
314 std::size_t iEt =
getEtIndex(sample, cell->et());
317 ATH_MSG_ERROR(
"Et value " << cell->et() <<
" for sampling " << sample <<
" does not fall in a bin");
318 return StatusCode::FAILURE;
320 float cellTime = getRandom(
m_timingSamples.at(std::make_tuple(sample, iEta, iEt)), generator);
321 timeDef.at(scIDHash) |=
true;
322 enForTime.at(scIDHash) += cell->energy();
323 enTime.at(scIDHash) += cell->energy() * cellTime;
326 uint16_t &quality =
qualities.at(scIDHash);
328 if ((std::numeric_limits<uint16_t>::max() + 1 - quality) < cell->quality())
329 quality = std::numeric_limits<uint16_t>::max();
331 quality += cell->quality();
337 int side = tileCellID->
side(cellID);
338 int module = tileCellID->module(cellID);
339 int tower = tileCellID->
tower(cellID);
347 int tower2 = tower - 1;
355 else if (tower == 10)
365 energies.at(superCellIDHelper->
calo_cell_hash(scID1)) += cell->energy() * 0.5;
366 energies.at(superCellIDHelper->
calo_cell_hash(scID2)) += cell->energy() * 0.5;
370 for (std::size_t idx = 0; idx < energies.size(); ++idx)
380 bool isTile_BAD = s >= 9 && s < 21;
383 float energy = energies.at(idx);
384 float sigmaNoise = sigmaNoisePerSuperCell.at(dde->
calo_hash());
385 if (!dde->
is_tile() && sigmaNoise > 0.0)
387 std::normal_distribution<double> distribution(0.0, sigmaNoise);
388 energy += distribution(generator);
390 auto superCell = std::make_unique<CaloCell>();
391 superCell->setCaloDDE(dde);
392 superCell->setEnergy(energy);
394 if (timeDef.at(idx) && enForTime.at(idx) != 0)
396 float time = enTime.at(idx) / enForTime.at(idx);
397 superCell->setTime(time);
398 float et = superCell->et();
400 if ((
et > 10e3 && time > -8 && time < 18) || (
et <= 10e3 && std::abs(time) < 8))
404 superCell->setTime(999.0);
405 superCell->setProvenance(prov);
407 superCells->push_back(superCell.release());
410 ATH_CHECK(superCellHandle.record(std::move(superCells)));
411 return StatusCode::SUCCESS;
Scalar eta() const
pseudorapidity method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
Helper class for offline supercell identifiers.
std::vector< float > CaloNoiseSigmaDiff
NAME : CaloNoiseSigmaDiff.h PACKAGE : Calorimeter/CaloConditions.
static const std::vector< std::string > bins
static const std::vector< std::string > qualities
Handle class for reading from StoreGate.
Handle class for recording to StoreGate.
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
const ServiceHandle< StoreGateSvc > & detStore() const
An algorithm that can be simultaneously executed in multiple threads.
float average(const Identifier &id) const
size_type calo_cell_hash_max() const
cell 'global' hash table max size
IdentifierHash calo_cell_hash(const Identifier cellId) const
create hash id from 'global' cell id
Helper class for offline cell identifiers.
Helper class for offline supercell identifiers.
Data object for each calorimeter readout cell.
This class groups all DetDescr information related to a CaloCell.
IdentifierHash calo_hash() const
cell calo hash
bool is_tile() const
cell belongs to Tile
CaloCell_ID::CaloSample getSampling() const
cell sampling
const CaloDetDescrElement * get_element(const Identifier &cellId) const
get element by its identifier
This is a "hash" representation of an Identifier.
bool is_valid() const
Check if id is in a valid state.
SG::ReadCondHandleKey< CaloNoiseSigmaDiff > m_caloNoiseSigmaDiffKey
SG::ReadHandleKey< xAOD::EventInfo > m_evtInfoKey
std::size_t getEtaIndex(CaloSampling::CaloSample sample, float eta) const
virtual StatusCode execute(const EventContext &ctx) const override
std::map< CaloSampling::CaloSample, std::vector< float > > m_etaBins
eta binning read from timing file
virtual ~SCEmulation() override
SG::ReadHandleKey< CaloBCIDAverage > m_caloBCIDAverageKey
SG::ReadCondHandleKey< CaloSuperCellDetDescrManager > m_caloSuperCellMgrKey
Super cell manager key.
std::map< std::tuple< CaloSampling::CaloSample, std::size_t, std::size_t >, std::map< float, float > > m_timingSamples
Timing distributions.
SG::WriteHandleKey< CaloCellContainer > m_outputSuperCellsKey
const CaloIdManager * m_caloIdMgr
Calo ID helpers.
virtual StatusCode initialize() override
std::size_t getEtIndex(CaloSampling::CaloSample sample, float et) const
SG::ReadHandleKey< CaloCellContainer > m_inputCellsKey
bool m_useBCID
Compensate for BCIDs.
SCEmulation(const std::string &name, ISvcLocator *pSvcLocator)
std::string m_cellTimingFile
The cell timing file.
ToolHandle< ICaloSuperCellIDTool > m_scidTool
Offline<->supercell mapping tool.
bool m_useNoise
Use noise values.
std::map< CaloSampling::CaloSample, std::vector< float > > m_etBins
Et binning read from timing file.
static std::string find_calib_file(const std::string &logical_file_name)
const_pointer_type cptr()
Helper class for TileCal offline identifiers.
int tower(const Identifier &id) const
Identifier cell_id(const Identifier &any_id) const
int side(const Identifier &id) const
int section(const Identifier &id) const
int sampling(const Identifier &id) const
Helper class for Tile offline identifiers for supercells.
bool match(std::string s1, std::string s2)
match the individual directories of two strings
eFexTowerBuilder creates xAOD::eFexTowerContainer from supercells (LATOME) and triggerTowers (TREX) i...
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
Extra patterns decribing particle interation process.