43 std::unique_ptr<TFile>
f( TFile::Open(
fileName.c_str()) );
45 TTree*
t =
f->Get<TTree>(
"mapping");
47 unsigned long long scid = 0;
48 std::pair<int,int>
coord = {0,0};
49 std::pair<int,int> slot;
50 t->SetBranchAddress(
"scid",&scid);
51 t->SetBranchAddress(
"etaIndex",&
coord.first);
52 t->SetBranchAddress(
"phiIndex",&
coord.second);
53 t->SetBranchAddress(
"slot1",&slot.first);
54 t->SetBranchAddress(
"slot2",&slot.second);
55 for(Long64_t
i=0;
i<
t->GetEntries();
i++) {
57 m_scMap[scid] = std::make_pair(
coord,slot);
61 if (m_scMap.empty()) {
68 return StatusCode::SUCCESS;
78 return StatusCode::FAILURE;
83 return StatusCode::FAILURE;
89 return StatusCode::FAILURE;
94 std::map<std::pair<int,int>,std::array<int,11>>
towers;
96 constexpr
int INVALID_VALUE = -99999;
99 for (
auto digi: *scells) {
100 const auto itr = m_scMap.find(digi->ID().get_compact());
101 if (itr == m_scMap.end()) {
continue; }
102 int val =
std::round(digi->energy()/(12.5*std::cosh(digi->eta())));
104 bool isSaturated = (!
isMC) ? (digi->quality()) :
false;
105 bool isMasked =
m_applyMasking ? ((digi)->provenance()&0x80) :
false;
106 bool isInvalid =
m_applyMasking ? ((digi)->provenance()&0x40) :
false;
111 val = SATURATED_VALUE;
114 auto& tower =
towers[itr->second.first];
115 if (itr->second.second.second<11) {
117 if (!isMasked &&
val!=INVALID_VALUE) {
120 tower.at(itr->second.second.first) = SATURATED_VALUE;
121 tower.at(itr->second.second.second) = SATURATED_VALUE;
123 if(tower.at(itr->second.second.first)!=(SATURATED_VALUE)) {
126 tower.at(itr->second.second.first)=0;
128 tower.at(itr->second.second.first) +=
val >> 1;
130 if(tower.at(itr->second.second.second)!=(SATURATED_VALUE)) {
133 tower.at(itr->second.second.second)=0;
135 tower.at(itr->second.second.second) += (
val - (
val >> 1));
142 auto&
v = tower.at(itr->second.second.first);
146 }
else if(isSaturated) {
156 static const auto etaIndex = [](
float eta) {
return int( eta*10 ) + ((eta<0) ? -1 : 1); };
157 static const auto phiIndex = [](
float phi) {
return int( phi*32./
M_PI ) + (phi<0 ? -1 : 1); };
159 if (std::abs(tTower->eta()) > 1.5)
continue;
160 if (tTower->sampling() != 1)
continue;
161 double phi = tTower->phi();
if(phi >
M_PI) phi -= 2.*
M_PI;
162 towers[std::pair(etaIndex(tTower->eta()),
phiIndex(phi))][10] = tTower->cpET();
167 ATH_CHECK( eTowers.
record(std::make_unique<xAOD::eFexTowerContainer>(),std::make_unique<xAOD::eFexTowerAuxContainer>()) );
169 static const auto calToFex = [](
int calEt) {
171 if(calEt == SATURATED_VALUE)
return 1023;
172 if( calEt == INVALID_VALUE )
return 1022;
173 if(calEt<448)
return std::max((calEt&~1)/2+32,1);
174 if(calEt<1472)
return (calEt-448)/4+256;
175 if(calEt<3520)
return (calEt-1472)/8+512;
176 if(calEt<11584)
return (calEt-3520)/32+768;
182 size_t ni = (std::abs(
coord.first)<=15) ? 10 : 11;
183 for(
size_t i=0;
i<ni;++
i) counts[
i] = (scells->empty() ? 1025 : calToFex(counts[
i]));
184 eTowers->
push_back( std::make_unique<xAOD::eFexTower>() );
185 eTowers->
back()->initialize( ( (
coord.first<0 ? 0.5:-0.5) +
coord.first)*0.1 ,
187 std::vector<uint16_t>(counts.begin(), counts.end()),
193 return StatusCode::SUCCESS;
205 return StatusCode::FAILURE;
207 if (scells->
size() != 34048) {
208 ATH_MSG_FATAL(
"Cannot fill sc -> eFexTower mapping with an incomplete sc collection");
209 return StatusCode::FAILURE;
212 std::vector<unsigned long long> ps;
213 std::vector<std::pair<float,unsigned long long>>
l1;
214 std::vector<std::pair<float,unsigned long long>>
l2;
215 std::vector<unsigned long long> l3;
216 std::vector<unsigned long long> had;
217 std::vector<unsigned long long>
other;
219 static const auto etaIndex = [](
float eta) {
return int( eta*10 ) + ((eta<0) ? -1 : 1); };
220 static const auto phiIndex = [](
float phi) {
return int( phi*32./ROOT::Math::Pi() ) + (phi<0 ? -1 : 1); };
221 std::map<std::pair<int,int>,TowerSCells>
towers;
222 std::map<unsigned long long,int> eTowerSlots;
224 for (
auto digi: *scells) {
227 if (
auto elem = ddm->get_element(
id); elem && std::abs(elem->eta_raw())<2.5) {
228 float eta = elem->eta_raw();
229 int sampling = elem->getSampling();
230 if(sampling==6 && ddm->getCaloCell_ID()->region(
id)==0 && eta<0) eta-=0.01;
232 unsigned long long val =
id.get_compact();
234 int towerid = -1;
int slot = -1;
bool issplit =
false;
236 eTowerSlots[
id.get_compact()] = slot;
241 sc.ps.push_back(
val);
244 sc.l1.push_back({elem->eta(),
val});
break;
246 sc.l2.push_back({elem->eta(),
val});
break;
248 sc.l3.push_back(
val);
break;
249 case 8:
case 9:
case 10:
case 11:
250 sc.had.push_back(
val);
break;
252 sc.other.push_back(
val);
break;
260 std::vector<size_t> slotVector(11);
262 std::sort(
sc.l1.begin(),
sc.l1.end());
263 std::sort(
sc.l2.begin(),
sc.l2.end());
265 if (
sc.l2.size()==5) {
266 if (
coord.first >= 0) {
267 sc.l3.push_back(
sc.l2.front().second);
268 sc.l2.erase(
sc.l2.begin());
270 sc.l3.push_back(
sc.l2.back().second);
271 sc.l2.resize(
sc.l2.size()-1);
274 if (std::abs(
coord.first)==15) {
281 if (
sc.l1.size()==6) {
282 m_scMap[
sc.l1.at(0).second] = std::pair(
coord,std::pair(1,11));
283 m_scMap[
sc.l1.at(1).second] = std::pair(
coord,std::pair(1,2));
284 m_scMap[
sc.l1.at(2).second] = std::pair(
coord,std::pair(2,11));
285 m_scMap[
sc.l1.at(3).second] = std::pair(
coord,std::pair(3,11));
286 m_scMap[
sc.l1.at(4).second] = std::pair(
coord,std::pair(3,4));
287 m_scMap[
sc.l1.at(5).second] = std::pair(
coord,std::pair(4,11));
288 slotVector[1] = eTowerSlots[
sc.l1.at(0).second];
289 slotVector[2] = eTowerSlots[
sc.l1.at(2).second];
290 slotVector[3] = eTowerSlots[
sc.l1.at(3).second];
291 slotVector[4] = eTowerSlots[
sc.l1.at(5).second];
295 if (
sc.l1.size()==1) {
296 m_scMap[
sc.l1.at(0).second] = std::pair(
coord,std::pair(4,11));
297 slotVector[1] = 1; slotVector[2] = 2; slotVector[3] = 3; slotVector[4] = eTowerSlots[
sc.l1.at(0).second];
301 if (!
sc.ps.empty()) {m_scMap[
sc.ps.at(0)] = std::pair(
coord,std::pair(0,11)); slotVector[0] = eTowerSlots[
sc.ps.at(0)]; }
302 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]; }
303 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]; }
304 if (!
sc.l3.empty()) {m_scMap[
sc.l3.at(0)] = std::pair(
coord,std::pair(9,11)); slotVector[9] = eTowerSlots[
sc.l3.at(0)]; }
305 if (!
sc.had.empty()) {m_scMap[
sc.had.at(0)] = std::pair(
coord,std::pair(10,11));slotVector[10] = eTowerSlots[
sc.had.at(0)]; }
319 TFile
f(
"scToEfexTowers.root",
"RECREATE");
320 TTree*
t =
new TTree(
"mapping",
"mapping");
321 unsigned long long scid = 0;
322 std::pair<int,int>
coord = {0,0};
323 std::pair<int,int> slot = {-1,-1};
324 t->Branch(
"scid",&scid);
325 t->Branch(
"etaIndex",&
coord.first);
326 t->Branch(
"phiIndex",&
coord.second);
327 t->Branch(
"slot1",&slot.first);
328 t->Branch(
"slot2",&slot.second);
329 for(
auto& [
id,
val] : m_scMap) {
336 return StatusCode::SUCCESS;
347 std::lock_guard lock(m_fillMapMutex);