171 {
173
174
177 ATH_MSG_DEBUG(
"Retrieved " << truth_particles->size() <<
" truth_particles...");
178
179
180 SG::ReadHandle<xAOD::TruthVertexContainer> truth_PVs(
m_TruthPVsKey, ctx);
182 if ( truth_PVs->size() != 1 ) {
184 return StatusCode::FAILURE;
185 }
187
188
191 std::vector<const xAOD::TruthVertex*> all_truth_vertices;
192 for ( auto vert : *truth_vertices ) { all_truth_vertices.push_back(vert); }
194 if (pvs.empty()) {
196 return StatusCode::FAILURE;
197 }
199
200 std::vector<const xAOD::TruthParticle*> sorted_truth_particles;
201 for ( const auto tp : *truth_particles ) { sorted_truth_particles.push_back(tp); }
203 sorted_truth_particles.begin(), sorted_truth_particles.end(),
204 [](const xAOD::IParticle* p1, const xAOD::IParticle* p2) {
205 return p1->pt() < p2->pt();
206 }
207 );
208
209
210
212
213
214
215
218 initial_particles
219 );
220
221
222 for(auto& fat_vertex : fat_vertices){
223 fat_vertex.doParentChildLinks(fat_vertices);
224 }
225
226
227 std::vector<FatVertex::FatVertex> hpt_fat_vertices;
228 for ( auto& fat_vertex : fat_vertices ) {
229 if ( fat_vertex.getPT() > 0 || fat_vertex.is_pv ) hpt_fat_vertices.push_back(fat_vertex);
230 }
231
232
233
234
235 SG::WriteDecorHandle<xAOD::TruthParticleContainer, int> vertexValid(
m_vertexValid, ctx);
238 SG::WriteDecorHandle<xAOD::TruthParticleContainer, int> vertexDecayID(
m_vertexDecayID, ctx);
239 SG::WriteDecorHandle<xAOD::TruthParticleContainer, int> vertexDecayParentID(
m_vertexDecayParentID, ctx);
240 SG::WriteDecorHandle<xAOD::TruthParticleContainer, int> vertexDecayNCharged(
m_vertexDecayNCharged, ctx);
241 SG::WriteDecorHandle<xAOD::TruthParticleContainer, int> vertexDecayNNeutral(
m_vertexDecayNNeutral, ctx);
245 SG::WriteDecorHandle<xAOD::TruthParticleContainer, float> vertexDecayDistance(
m_vertexDecayDistance, ctx);
246 SG::WriteDecorHandle<xAOD::TruthParticleContainer, int> vertexIsVertex(
m_vertexIsVertex, ctx);
247
248
249 std::vector<const xAOD::TruthParticle*> stable_neutrals;
250 std::vector<const xAOD::TruthParticle*> stable_charged;
251 std::unordered_map<int, int> barcode_to_other_id;
252
253
254
255
256 for ( const auto& truth_particle : sorted_truth_particles ) {
257 vertexValid(*truth_particle) = 0;
259 vertexSimpleType(*truth_particle) = -1;
260 vertexDecayID(*truth_particle) = -1;
261 vertexDecayParentID(*truth_particle) = -1;
262 vertexDecayPVDistance(*truth_particle) = NAN;
263 vertexDecayDistance(*truth_particle) = NAN;
264 vertexDecayNCharged(*truth_particle) = -1;
265 vertexDecayNNeutral(*truth_particle) = -1;
266 vertexDecayAllNCharged(*truth_particle) = -1;
267 vertexDecayAllNNeutral(*truth_particle) = -1;
268 vertexIsVertex(*truth_particle) = 0;
269 }
270
271 std::unordered_map<int, int> barcode_to_vertex_id;
273 for ( auto fat_vertex : hpt_fat_vertices ) {
274 for ( auto part : fat_vertex.internal ) {
276 vertexDecayID(*part) =
counter;
277 }
278 for ( auto part : fat_vertex.inparts ) {
279
280 FatVertex::VertexType
vt = fat_vertex.getType(
m_acc_uid);
281
282
283
285 continue;
286 }
287
288 vertexValid(*part) = 1;
290 vertexSimpleType(*part) =
int(
vt.getSimpleType());
291 vertexDecayID(*part) =
counter;
292
295 vertexDecayAllNCharged(*part) = fat_vertex.getNumChargedDecays();
296 vertexDecayAllNNeutral(*part) = fat_vertex.getNumNeutralDecays();
297
298 vertexIsVertex(*part) = 1;
300 }
301
302 for ( auto part : fat_vertex.outparts ) {
303 if (!part){
304 ATH_MSG_ERROR(
"Found a null particle in the out parts of a fat vertex, skipping it - this should never happen");
305 continue;
306 }
307
308 vertexDecayParentID(*part) =
counter;
310
311
312
313
314
315
316
319 vertexDecayPVDistance(*part) = pvDist;
320
321 if (
part->hasProdVtx() &&
part->prodVtx() ) {
323 }
324
325
326 }else{
327
328 if (
part->isCharged()){
329 stable_charged.push_back(part);
331 vertexValid(*part) = 1;
332 }
333 }
334 else{
335 stable_neutrals.push_back(part);
337 vertexValid(*part) = 1;
338 }
339 }
340 }
341 }
342
344 }
345
346
349 std::vector<const xAOD::TrackParticle*> tracks_vector(tracks->begin(), tracks->end());
350
352
353 using TrackIntWriter = SG::WriteDecorHandle<xAOD::TrackParticleContainer, int>;
359
360 for ( auto track : tracks_vector ) {
361
362
363 trackTPDecayVertexID(*track) = -1;
364 trackTPDecayVertexType(*track) = -1;
365 trackTPDecaySimpleVertexType(*track) = -1;
366 trackPDGID(*track) = 0;
367 trackParentPDGID(*track) = 0;
369
370 if ( !truth ){
371 trackTPDecayVertexType(*track) = -2;
372 trackTPDecaySimpleVertexType(*track) = -2;
373 continue;
374 }
376
378
379 trackTPDecayVertexType(*track) = -3;
380 trackTPDecaySimpleVertexType(*track) = -3;
381 continue;
382 }
383
384
385
387 stable_charged.erase(
388 std::remove(stable_charged.begin(), stable_charged.end(), truth),
389 stable_charged.end()
390 );
391 }
392 trackPDGID(*track) = truth->pdgId();
393
394 if ( truth->hasProdVtx() && truth->prodVtx() ) {
395 auto parent = truth->prodVtx()->incomingParticle(0);
396 if ( parent ) {
397 trackParentPDGID(*track) =
parent->pdgId();
398 }
399 }
400
401
402 if ( barcode_to_vertex_id.find(
m_acc_uid(*truth)) != barcode_to_vertex_id.end() ) {
403 int vertex_id = barcode_to_vertex_id[
m_acc_uid(*truth)];
404 trackTPDecayVertexID(*track) = vertex_id;
405 FatVertex::VertexType
vt = hpt_fat_vertices[vertex_id].getType(
m_acc_uid);
406 trackTPDecayVertexType(*track) =
int(
vt.detailedType);
407 trackTPDecaySimpleVertexType(*track) =
int(
vt.getSimpleType());
408 } else {
409
410 if(barcode_to_other_id.find(
m_acc_uid(*truth)) != barcode_to_other_id.end()){
411 ATH_MSG_DEBUG(
"Found a track which is truth matched to an internal particle, not an out part ");
412 int vertex_id = barcode_to_other_id[
m_acc_uid(*truth)];
413 trackTPDecayVertexID(*track) = vertex_id;
414 FatVertex::VertexType
vt = hpt_fat_vertices[vertex_id].getType(
m_acc_uid);
415 trackTPDecayVertexType(*track) =
int(
vt.detailedType);
416 trackTPDecaySimpleVertexType(*track) =
int(
vt.getSimpleType());
417 }else{
418
419
420
421 }
422
423 }
424 }
425
427 for(auto stable_charged_tp : stable_charged){
428 vertexValid(*stable_charged_tp) = 1;
429 }
430
431 }
432
433
434
435 return StatusCode::SUCCESS;
436}
#define ATH_CHECK
Evaluate an expression and check for errors.
SG::WriteDecorHandleKey< xAOD::TruthParticleContainer > m_vertexDecayType
Gaudi::Property< float > m_truthParticleMinimumPt
SG::WriteDecorHandleKey< xAOD::TrackParticleContainer > m_trackTPDecayVertexType
SG::WriteDecorHandleKey< xAOD::TruthParticleContainer > m_vertexDecayDistance
SG::WriteDecorHandleKey< xAOD::TruthParticleContainer > m_vertexDecayNCharged
SG::WriteDecorHandleKey< xAOD::TruthParticleContainer > m_vertexDecayPVDistance
SG::ReadDecorHandleKey< xAOD::TruthParticleContainer > m_acc_truth_particle_vertex_id
SG::WriteDecorHandleKey< xAOD::TruthParticleContainer > m_vertexValid
SG::WriteDecorHandleKey< xAOD::TruthParticleContainer > m_vertexDecayNNeutral
SG::WriteDecorHandleKey< xAOD::TrackParticleContainer > m_trackTPDecayVertexID
Gaudi::Property< float > m_truthMatchProbabilityCut
SG::ReadHandleKey< xAOD::TruthParticleContainer > m_TruthContainerKey
SG::ReadHandleKey< xAOD::TruthVertexContainer > m_TruthVertexContainerKey
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_TrackContainerKey
ToolHandle< InDet::InDetTrackTruthOriginTool > m_trackTruthOriginTool
SG::WriteDecorHandleKey< xAOD::TruthParticleContainer > m_vertexDecayID
SG::AuxElement::ConstAccessor< float > m_truthMatchProbabilityAcc
SG::WriteDecorHandleKey< xAOD::TruthParticleContainer > m_vertexDecayParentID
SG::ReadHandleKey< xAOD::TruthVertexContainer > m_TruthPVsKey
SG::WriteDecorHandleKey< xAOD::TruthParticleContainer > m_vertexDecayAllNCharged
SG::WriteDecorHandleKey< xAOD::TrackParticleContainer > m_trackPDGID
SG::WriteDecorHandleKey< xAOD::TruthParticleContainer > m_vertexDecayAllNNeutral
Gaudi::Property< bool > m_alwaysKeepStableCharged
SG::WriteDecorHandleKey< xAOD::TruthParticleContainer > m_vertexSimpleDecayType
Gaudi::Property< float > m_truthVertexMergeDistance
SG::WriteDecorHandleKey< xAOD::TruthParticleContainer > m_vertexIsVertex
SG::WriteDecorHandleKey< xAOD::TrackParticleContainer > m_trackTPDecaySimpleVertexType
Gaudi::Property< bool > m_alwaysKeepTracklessStableCharged
Gaudi::Property< bool > m_alwaysKeepStableNeutrals
SG::WriteDecorHandleKey< xAOD::TrackParticleContainer > m_trackParentPDGID
SG::ConstAccessor< int > m_acc_uid
bool has_valid_child(const xAOD::TruthParticle *part)
float vertex_distance(const xAOD::TruthVertex *v1, const xAOD::TruthVertex *v2)
std::vector< FatVertex > generateFatVertices(const xAOD::TruthVertex *pv, const float truthVertexMergeDistance, const std::vector< const xAOD::TruthParticle * > &truth_particles)
std::vector< const xAOD::TruthVertex * > get_matched_primary_vertices(const xAOD::TruthVertex *pv, const std::vector< const xAOD::TruthVertex * > &truth_vertices, float selection_distance=0.001, SG::ConstAccessor< int > acc_uid=SG::ConstAccessor< int >("barcode"))
Get the matched primary vertex for a given truth vertex.
std::vector< const xAOD::TruthParticle * > get_all_initial_particles(const std::vector< const xAOD::TruthParticle * > &truth_particles)
DataModel_detail::iterator< DVL > remove(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end, const T &value)
Specialization of remove for DataVector/List.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
TruthVertex_v1 TruthVertex
Typedef to implementation.