45 std::unique_ptr <TFile>
f(TFile::Open(
fileName.c_str()));
47 TTree *
t =
f->Get<TTree>(
"mapping");
49 unsigned long long scid = 0;
50 std::pair<int, int>
coord = {0, 0};
51 std::pair<int, int> slot;
52 t->SetBranchAddress(
"scid", &scid);
53 t->SetBranchAddress(
"etaIndex", &
coord.first);
54 t->SetBranchAddress(
"phiIndex", &
coord.second);
55 t->SetBranchAddress(
"slot1", &slot.first);
56 t->SetBranchAddress(
"slot2", &slot.second);
57 for (Long64_t
i = 0;
i <
t->GetEntries();
i++) {
59 m_scMap[scid] = std::make_pair(
coord, slot);
63 if (m_scMap.empty()) {
71 return StatusCode::SUCCESS;
81 return StatusCode::FAILURE;
86 return StatusCode::FAILURE;
92 return StatusCode::FAILURE;
97 std::map<std::pair<int,int>,std::array<int,11>>
towers;
99 constexpr
int INVALID_VALUE = -99999;
102 constexpr
int MISSING_VALUE = -99998;
104 for (
auto digi: *scells) {
105 const auto itr = m_scMap.find(digi->ID().get_compact());
106 if (itr == m_scMap.end()) {
continue; }
107 int val =
std::round(digi->energy()/(12.5*std::cosh(digi->eta())));
109 bool isSaturated = (!
isMC) ? (digi->quality()) :
false;
110 bool isMasked = ((digi)->provenance()&0x80);
111 bool isInvalid =
m_applyMasking ? ((digi)->provenance()&0x40) :
false;
117 val = SATURATED_VALUE;
120 auto towerItr =
towers.emplace(itr->second.first,std::array<int,11>{});
121 if(towerItr.second) {
122 towerItr.first->second.fill(MISSING_VALUE);
124 auto& tower = (towerItr.first->second);
125 if (itr->second.second.second<11) {
127 if (!isMasked &&
val!=INVALID_VALUE) {
130 tower.at(itr->second.second.first) = SATURATED_VALUE;
131 tower.at(itr->second.second.second) = SATURATED_VALUE;
133 if(tower.at(itr->second.second.first)!=(SATURATED_VALUE)) {
135 if (tower.at(itr->second.second.first)==MASKED_VALUE || tower.at(itr->second.second.first)==INVALID_VALUE || tower.at(itr->second.second.first)==MISSING_VALUE) {
136 tower.at(itr->second.second.first)=0;
138 tower.at(itr->second.second.first) +=
val >> 1;
140 if(tower.at(itr->second.second.second)!=(SATURATED_VALUE)) {
142 if (tower.at(itr->second.second.second)==MASKED_VALUE || tower.at(itr->second.second.second)==INVALID_VALUE || tower.at(itr->second.second.second)==MISSING_VALUE) {
143 tower.at(itr->second.second.second)=0;
145 tower.at(itr->second.second.second) += (
val - (
val >> 1));
152 auto&
v = tower.at(itr->second.second.first);
155 if(
v==MISSING_VALUE)
v = MASKED_VALUE;
156 }
else if(isSaturated) {
159 if(
v==INVALID_VALUE ||
v==MISSING_VALUE)
v = 0;
167 static const auto etaIndex = [](
float eta) {
return int(
eta*10 ) + ((
eta<0) ? -1 : 1); };
170 if (std::abs(tTower->eta()) > 1.5)
continue;
171 if (tTower->sampling() != 1)
continue;
173 auto towerItr =
towers.emplace(std::pair(etaIndex(tTower->eta()),
phiIndex(
phi)),std::array<int,11>{});
174 if(towerItr.second) {
175 towerItr.first->second.fill(MISSING_VALUE);
177 (towerItr.first->second).at(10) = tTower->cpET();
182 ATH_CHECK( eTowers.
record(std::make_unique<xAOD::eFexTowerContainer>(),std::make_unique<xAOD::eFexTowerAuxContainer>()) );
184 static const auto calToFex = [](
int calEt) {
185 if(calEt == MASKED_VALUE)
return 0;
186 if(calEt == SATURATED_VALUE)
return 1023;
187 if( calEt == INVALID_VALUE )
return 1022;
188 if( calEt == MISSING_VALUE )
return 1025;
189 if(calEt<448)
return std::max((calEt&~1)/2+32,1);
190 if(calEt<1472)
return (calEt-448)/4+256;
191 if(calEt<3520)
return (calEt-1472)/8+512;
192 if(calEt<11584)
return (calEt-3520)/32+768;
201 size_t ni = (std::abs(
coord.first)<=15) ? 10 : 11;
202 for(
size_t i=0;
i<ni;++
i)
counts[
i] = (scells->empty() ? 1025 : calToFex(
counts[
i]));
203 eTowers->
push_back( std::make_unique<xAOD::eFexTower>() );
204 eTowers->
back()->initialize( ( (
coord.first<0 ? 0.5:-0.5) +
coord.first)*0.1 ,
212 return StatusCode::SUCCESS;
216 StatusCode eFexTowerBuilder::fillMap(
const EventContext& ctx)
const {
223 ATH_MSG_FATAL(
"Could not retrieve collection " << m_scellKey.key() );
224 return StatusCode::FAILURE;
226 if (scells->
size() != 34048 && !m_mappingFile.empty()) {
227 ATH_MSG_FATAL(
"Cannot fill sc -> eFexTower mapping with an incomplete sc collection");
228 return StatusCode::FAILURE;
232 bool doV6Mapping = m_v6Mapping;
234 if(!m_LArLatomeHeaderContainerKey.empty()) {
238 doV6Mapping = (hit->FWversion()>1600);
240 if (doV6Mapping != m_v6Mapping) {
241 ATH_MSG_WARNING(
"Used LATOME Hardware to determine mapping different to python configuration (use V6 Mapping = " << doV6Mapping <<
" )");
247 std::vector<unsigned long long>
ps;
248 std::vector<std::pair<float,unsigned long long>>
l1;
249 std::vector<std::pair<float,unsigned long long>>
l2;
250 std::vector<unsigned long long> l3;
251 std::vector<unsigned long long> had;
252 std::vector<unsigned long long>
other;
254 static const auto etaIndex = [](
float eta) {
return int(
eta*10 ) + ((
eta<0) ? -1 : 1); };
255 static const auto phiIndex = [](
float phi) {
return int(
phi*32./ROOT::Math::Pi() ) + (
phi<0 ? -1 : 1); };
256 std::map<std::pair<int,int>,TowerSCells>
towers;
257 std::map<unsigned long long,int> eTowerSlots;
259 for (
auto digi: *scells) {
262 if (
auto elem = ddm->get_element(
id);
elem && std::abs(
elem->eta_raw())<2.5) {
264 int sampling =
elem->getSampling();
265 if(sampling==6 && ddm->getCaloCell_ID()->region(
id)==0 &&
eta<0)
eta-=0.01;
267 unsigned long long val =
id.get_compact();
269 int towerid = -1;
int slot = -1;
bool issplit =
false;
270 CHECK(m_eFEXSuperCellTowerIdProviderTool->geteTowerIDandslot(
id.get_compact(), towerid, slot, issplit));
271 eTowerSlots[
id.get_compact()] = slot;
276 sc.ps.push_back(
val);
279 sc.l1.push_back({
elem->eta(),
val});
break;
281 sc.l2.push_back({
elem->eta(),
val});
break;
283 sc.l3.push_back(
val);
break;
284 case 8:
case 9:
case 10:
case 11:
285 sc.had.push_back(
val);
break;
287 sc.other.push_back(
val);
break;
295 std::vector<size_t> slotVector(11);
297 std::sort(
sc.l1.begin(),
sc.l1.end());
298 std::sort(
sc.l2.begin(),
sc.l2.end());
300 if (
sc.l2.size()==5) {
301 if (
coord.first >= 0) {
302 sc.l3.push_back(
sc.l2.front().second);
303 sc.l2.erase(
sc.l2.begin());
305 sc.l3.push_back(
sc.l2.back().second);
306 sc.l2.resize(
sc.l2.size()-1);
309 if (std::abs(
coord.first)==15) {
316 if (
sc.l1.size()==6) {
317 m_scMap[
sc.l1.at(0).second] = std::pair(
coord,std::pair(1,11));
318 m_scMap[
sc.l1.at(1).second] = std::pair(
coord,(doV6Mapping &&
coord.first < 0) ? std::pair(2,1) : std::pair(1,2));
319 m_scMap[
sc.l1.at(2).second] = std::pair(
coord,std::pair(2,11));
320 m_scMap[
sc.l1.at(3).second] = std::pair(
coord,std::pair(3,11));
321 m_scMap[
sc.l1.at(4).second] = std::pair(
coord,(doV6Mapping &&
coord.first < 0) ? std::pair(4,3) : std::pair(3,4));
322 m_scMap[
sc.l1.at(5).second] = std::pair(
coord,std::pair(4,11));
323 slotVector[1] = eTowerSlots[
sc.l1.at(0).second];
324 slotVector[2] = eTowerSlots[
sc.l1.at(2).second];
325 slotVector[3] = eTowerSlots[
sc.l1.at(3).second];
326 slotVector[4] = eTowerSlots[
sc.l1.at(5).second];
330 if (
sc.l1.size()==1) {
331 m_scMap[
sc.l1.at(0).second] = std::pair(
coord,std::pair(4,11));
332 slotVector[1] = 1; slotVector[2] = 2; slotVector[3] = 3; slotVector[4] = eTowerSlots[
sc.l1.at(0).second];
336 if (!
sc.ps.empty()) {m_scMap[
sc.ps.at(0)] = std::pair(
coord,std::pair(0,11)); slotVector[0] = eTowerSlots[
sc.ps.at(0)]; }
337 if(
sc.l1.size()==4)
for(
size_t i=0;
i<4;
i++)
if(
sc.l1.size() >
i) {m_scMap[
sc.l1.at(
i).second] = std::pair(
coord,std::pair(
i+1,11)); slotVector[
i+1] = eTowerSlots[
sc.l1.at(
i).second]; }
338 for(
size_t i=0;
i<4;
i++)
if(
sc.l2.size() >
i) { m_scMap[
sc.l2.at(
i).second] = std::pair(
coord,std::pair(
i+5,11)); slotVector[
i+5] = eTowerSlots[
sc.l2.at(
i).second]; }
339 if (!
sc.l3.empty()) {m_scMap[
sc.l3.at(0)] = std::pair(
coord,std::pair(9,11)); slotVector[9] = eTowerSlots[
sc.l3.at(0)]; }
340 if (!
sc.had.empty()) {m_scMap[
sc.had.at(0)] = std::pair(
coord,std::pair(10,11));slotVector[10] = eTowerSlots[
sc.had.at(0)]; }
354 if(!m_mappingFile.empty()) {
355 TFile
f(m_mappingFile.value().c_str(),
"RECREATE");
356 TTree *
t =
new TTree(
"mapping",
"mapping");
357 unsigned long long scid = 0;
358 std::pair<int, int>
coord = {0, 0};
359 std::pair<int, int> slot = {-1, -1};
360 t->Branch(
"scid", &scid);
361 t->Branch(
"etaIndex", &
coord.first);
362 t->Branch(
"phiIndex", &
coord.second);
363 t->Branch(
"slot1", &slot.first);
364 t->Branch(
"slot2", &slot.second);
365 for (
auto &[
id,
val]: m_scMap) {
374 return StatusCode::SUCCESS;
381 setFilterPassed(
true, ctx);
385 std::lock_guard
lock(m_fillMapMutex);
386 if (m_scMap.empty())
CHECK( fillMap(ctx) );
389 return fillTowers(ctx);