98 const EventContext& ctx = Gaudi::Hive::currentContext();
102 static const bool is_sherpa = [
this]() {
103 bool is_sherpa =
false;
111 if (
m_metaStore->retrieve(truthMetaData).isSuccess() && !truthMetaData->empty()){
113 const std::string gens = truthMetaData->at(0)->generators();
114 is_sherpa = (gens.find(
"sherpa")==std::string::npos &&
115 gens.find(
"Sherpa")==std::string::npos &&
116 gens.find(
"SHERPA")==std::string::npos) ?
false :
true;
119 ATH_MSG_WARNING(
"Found xAODTruthMetaDataContainer empty! Configuring to be NOT Sherpa.");
121 ATH_MSG_INFO(
"From metadata configured: Sherpa? " << is_sherpa);
123 ATH_MSG_WARNING(
"Could not find metadata container in storegate; assuming NOT Sherpa");
130 if (!truthParticles.isValid()) {
132 return StatusCode::FAILURE;
137 ATH_CHECK(newParticlesWriteHandle.record(std::make_unique<xAOD::TruthParticleContainer>(),
138 std::make_unique<xAOD::TruthParticleAuxContainer>()));
142 unsigned int nParticles = truthParticles->size();
163 std::vector<int>
entries = m_parser->evaluateAsVector();
167 ATH_MSG_ERROR(
"Sizes incompatible! Are you sure your selection string used TruthParticles?");
168 return StatusCode::FAILURE;
177 bool SherpaW =
false;
178 bool SherpaZ =
false;
185 if ((SherpaW or SherpaZ) && is_sherpa){
192 if ((SherpaW || SherpaZ) && is_sherpa){
194 std::vector<const xAOD::TruthParticle*> status_nonPhysical;
195 for (
unsigned int i=0;
i<nParticles; ++
i) {
197 if (!truthParticles->at(
i))
continue;
201 if (!
MC::isPhysical(truthParticles->at(
i))) status_nonPhysical.push_back( truthParticles->at(
i) );
204 if ((status_nonPhysical.size()==2 || status_nonPhysical.size()==4 || status_nonPhysical.size()==6) && (SherpaZ || SherpaW)){
206 int gens[3] = {0,0,0};
207 for (
size_t i=0;
i<status_nonPhysical.size();++
i){
208 if (status_nonPhysical[
i]->absPdgId()<13) gens[0]++;
209 else if (status_nonPhysical[
i]->absPdgId()<15) gens[1]++;
213 if (gens[0]>2 || gens[0]==1 || gens[1]>2 || gens[1]==1 || gens[2]>2 || gens[2]==1){
215 ATH_MSG_VERBOSE(
"Too many leptons of one generation. Cannot make bosons. Give up");
216 return StatusCode::SUCCESS;
218 std::vector<const xAOD::TruthParticle*> boson;
219 for (
size_t i=0;
i<status_nonPhysical.size();++
i){
220 if (status_nonPhysical[
i]->absPdgId()<13) boson.push_back(status_nonPhysical[
i]);
221 else if (gens[0]==0 && status_nonPhysical[
i]->absPdgId()<15) boson.push_back(status_nonPhysical[
i]);
222 else if (gens[0]==0 && gens[1]==0) boson.push_back(status_nonPhysical[
i]);
223 if (boson.size()==2){
227 if (boson[0]->pdgId()==-boson[1]->pdgId()) pdg_id=23;
228 else if (std::abs(boson[0]->pdgId()+boson[1]->pdgId())!=1){
230 ATH_MSG_WARNING(
"Do not know how to interpret as a boson: " << boson[0]->pdgId() <<
" " << boson[1]->pdgId());
233 pdg_id=24*(boson[0]->pdgId()+boson[1]->pdgId());
235 if ( (SherpaW &&
MC::isW(pdg_id)) ||
236 (SherpaZ &&
MC::isZ(pdg_id)) ){
239 newParticlesWriteHandle->push_back( xTruthParticle );
241 if (boson[0]->hasProdVtx()) {
242 if ((boson[0]->prodVtx()->nIncomingParticles() > 0) && (boson[0]->prodVtx()->incomingParticle(0)!=
nullptr)) {
243 motherIDDecorator(*xTruthParticle) = boson[0]->prodVtx()->incomingParticle(0)->pdgId();
244 }
else {motherIDDecorator(*xTruthParticle) = 0;}
245 }
else {motherIDDecorator(*xTruthParticle) = 0;}
246 if (boson[0]->hasDecayVtx()) {
247 if ((boson[0]->decayVtx()->nOutgoingParticles() > 0) && (boson[0]->decayVtx()->outgoingParticle(0)!=
nullptr)) {
248 daughterIDDecorator(*xTruthParticle) = boson[0]->decayVtx()->outgoingParticle(0)->pdgId();
249 }
else {daughterIDDecorator(*xTruthParticle) = 0;}
250 }
else {daughterIDDecorator(*xTruthParticle) = 0;}
259 xTruthParticle->
setM(new_mom.M());
260 xTruthParticle->
setPx(new_mom.Px());
261 xTruthParticle->
setPy(new_mom.Py());
262 xTruthParticle->
setPz(new_mom.Pz());
263 xTruthParticle->
setE(new_mom.E());
268 if (gens[0]==0 && gens[1]==0) gens[2]=0;
269 else if (gens[0]==0) gens[1]=0;
274 if (status_nonPhysical.size()==1 || status_nonPhysical.size()==3 || status_nonPhysical.size()==5 || status_nonPhysical.size()>6){
275 ATH_MSG_WARNING(status_nonPhysical.size() <<
" leptons found in the Sherpa event record. Not sure how to deal with this.");
277 return StatusCode::SUCCESS;
279 for (
unsigned int i=0;
i<nParticles; ++
i) {
286 bool same_as_mother =
false;
287 bool same_as_daughter =
false;
291 same_as_mother =
true;
298 same_as_daughter =
true;
302 if (same_as_mother && same_as_daughter){
308 newParticlesWriteHandle->push_back( xTruthParticle );
313 }
else {motherIDDecorator(*xTruthParticle) = 0;}
314 }
else {motherIDDecorator(*xTruthParticle) = 0;}
318 }
else {daughterIDDecorator(*xTruthParticle) = 0;}
319 }
else {daughterIDDecorator(*xTruthParticle) = 0;}
322 *xTruthParticle=*theParticle;
324 typeDecorator(*xTruthParticle) =
325 typeReadDecor.withDefault(*theParticle, 0);
327 originDecorator(*xTruthParticle) =
328 originReadDecor.withDefault(*theParticle, 0);
330 outcomeDecorator(*xTruthParticle) =
331 outcomeReadDecor.withDefault(*theParticle, 0);
333 classificationDecorator(*xTruthParticle) =
334 classificationReadDecor.withDefault(*theParticle, 0);
338 hadronOriginDecorator(*xTruthParticle) =
339 TopHadronOriginFlagAcc.withDefault (*theParticle, 0);
350 return StatusCode::SUCCESS;