diff --git a/GPU/BinaryDumpers/options/dump_MC_info.py b/GPU/BinaryDumpers/options/dump_MC_info.py index 96c92758756b5faed484e60ff6ff076cdaac9f1d..ecf8c76e2a145e8d335e08db5b5c95c96b51a505 100644 --- a/GPU/BinaryDumpers/options/dump_MC_info.py +++ b/GPU/BinaryDumpers/options/dump_MC_info.py @@ -66,10 +66,11 @@ appendPostConfigAction(modifySequences) def AddDumpers(): - from Configurables import PrTrackerDumper, DumpVeloUTState + from Configurables import PrTrackerDumper, DumpVeloUTState, PVDumper dump_mc = PrTrackerDumper("DumpMCInfo", DumpToBinary=True) - dump_vut = DumpVeloUTState("DumpVUT") - GaudiSequencer("MCLinksTrSeq").Members += [dump_mc, dump_vut] + dump_pvmc = PVDumper("DumpPVMCInfo") + #dump_vut = DumpVeloUTState("DumpVUT") + GaudiSequencer("MCLinksTrSeq").Members += [dump_mc, dump_pvmc] appendPostConfigAction(AddDumpers) diff --git a/GPU/BinaryDumpers/options/dump_banks.py b/GPU/BinaryDumpers/options/dump_banks.py index 0d51dd0bc33c625f2ae477051defb8378f5c6db6..57f377dec5e50c62490cb548d804a6820ce4859d 100644 --- a/GPU/BinaryDumpers/options/dump_banks.py +++ b/GPU/BinaryDumpers/options/dump_banks.py @@ -60,12 +60,12 @@ ApplicationMgr().ExtSvc += [DumpUTGeometry()] # Dump raw banks and UT, FT and muon hits dump_banks = DumpRawBanks(BankTypes=["VP", "UT", "FTCluster", "Muon"]) -dump_ut = DumpUTHits() -dump_ft = DumpFTHits() +#dump_ut = DumpUTHits() +#dump_ft = DumpFTHits() dump_muon_coords = DumpMuonCoords() dump_muon_hits = DumpMuonCommonHits() dump_seq = GaudiSequencer("DumpSeq") -dump_seq.Members += [dump_banks, dump_ut, dump_ft, dump_muon_coords, dump_muon_hits] +dump_seq.Members += [dump_banks, dump_muon_coords, dump_muon_hits] ApplicationMgr().TopAlg = [dec_seq, dump_seq] diff --git a/GPU/BinaryDumpers/src/PVDumper.cpp b/GPU/BinaryDumpers/src/PVDumper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..790676d5d062be05b0de9233357aed76729a81cb --- /dev/null +++ b/GPU/BinaryDumpers/src/PVDumper.cpp @@ -0,0 +1,149 @@ +/*****************************************************************************\ +* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration * +* * +* This software is distributed under the terms of the GNU General Public * +* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". * +* * +* In applying this licence, CERN does not waive the privileges and immunities * +* granted to it by virtue of its status as an Intergovernmental Organization * +* or submit itself to any jurisdiction. * +\*****************************************************************************/ +// Include files + +// local +#include "Event/RawEvent.h" +#include "PrKernel/UTHit.h" +#include "PrKernel/PrHit.h" +#include "Associators/Associators.h" +#include "PVDumper.h" +#include <TTree.h> +#include <TFile.h> +#include <TString.h> +#include <boost/filesystem.hpp> + +namespace { + using std::vector; + using std::fstream; + using std::ofstream; + using std::ios; + using std::string; + using std::to_string; + + namespace fs = boost::filesystem; +} + +// Declaration of the Algorithm Factory +DECLARE_COMPONENT( PVDumper ) + +//============================================================================= +// Standard constructor, initializes variables +//============================================================================= + + +PVDumper::PVDumper(const string& name, + ISvcLocator* pSvcLocator) : +Consumer(name, pSvcLocator, + {KeyValue{"MCVerticesLocation", LHCb::MCVertexLocation::Default }, + KeyValue{"ODINLocation", LHCb::ODINLocation::Default} }){ +} + +StatusCode PVDumper::initialize() +{ + auto dir = fs::path{m_outputDirectory.value()}; + if (!fs::exists(dir)) { + boost::system::error_code ec; + bool success = fs::create_directories(dir, ec); + success &= !ec; + if (!success) { + error() << "Failed to create directory " << dir.string() << ": " + << ec.message() << endmsg; + return StatusCode::FAILURE; + } + } + return StatusCode::SUCCESS; +} + + void PVDumper::write_MCPV_info_to_binary_file( + const int number_rec_tracks, + const double pv_x, + const double pv_y, + const double pv_z, + ofstream& outfile ) const { + + outfile.write( (char*) &number_rec_tracks, sizeof(int) ); + outfile.write( (char*) &pv_x, sizeof(double) ); + outfile.write( (char*) &pv_y, sizeof(double) ); + outfile.write( (char*) &pv_z, sizeof(double) ); + } + +void PVDumper::operator()(const LHCb::MCVertices& MCVertices, const LHCb::ODIN& odin) const +{ + std::optional<ofstream> outfile_PV; + // Binary file to dump MC PVs info + string filename = ( m_outputDirectory.value() + "/" + + to_string(odin.runNumber()) + "_" + + to_string(odin.eventNumber()) + ".bin"); + outfile_PV = ofstream{filename.c_str(), ofstream::out | ios::binary}; + int n_PVs = 0; + for(LHCb::MCVertices::const_iterator itMCV = MCVertices.begin(); MCVertices.end() != itMCV; itMCV++) { + const LHCb::MCParticle* motherPart = (*itMCV)->mother(); + if(0 == motherPart) { + if((*itMCV)->type() == LHCb::MCVertex::MCVertexType::ppCollision) n_PVs++; + } + } + outfile_PV->write((char*)&n_PVs, sizeof(int)); + + for(LHCb::MCVertices::const_iterator itMCV = MCVertices.begin(); MCVertices.end() != itMCV; itMCV++) { + const LHCb::MCParticle* motherPart = (*itMCV)->mother(); + if(0 == motherPart) { + if((*itMCV)->type() == LHCb::MCVertex::MCVertexType::ppCollision) { + //MC PV position + double pv_x = (*itMCV)->position().X(); + double pv_y = (*itMCV)->position().Y(); + double pv_z = (*itMCV)->position().Z(); + //MC PV number of reconstructible particles + int number_rec_tracks = count_reconstructible_mc_particles(*(itMCV)); + write_MCPV_info_to_binary_file(number_rec_tracks, pv_x, pv_y, pv_z, *outfile_PV ); + } + } + } +} + + +// count number reconstructible tracks in the same way as PrimaryVertexChecker +int PVDumper::count_reconstructible_mc_particles(LHCb::MCVertex* avtx) const { + const MCTrackInfo trInfo = make_MCTrackInfo(eventSvc(), msgSvc()); + std::vector<LHCb::MCParticle*> mcPartInMCPV; + SmartRefVector<LHCb::MCParticle> parts = avtx->products(); + std::vector<LHCb::MCParticle*> allproducts; + collectProductss(avtx, avtx, allproducts); + std::vector<LHCb::MCParticle*>::iterator imcp; + + for(imcp = allproducts.begin(); allproducts.end() != imcp; imcp++) { + LHCb::MCParticle* pmcp = *imcp; + if(pmcp->particleID().threeCharge() != 0 && trInfo.hasVelo(pmcp)) { + double dv2 = (avtx->position() - pmcp->originVertex()->position()).Mag2(); + if(dv2 < 0.0000001 && pmcp->p() > 100.* Gaudi::Units::MeV) { + mcPartInMCPV.push_back(pmcp); + } + } + } + return mcPartInMCPV.size(); +} + +void PVDumper::collectProductss(LHCb::MCVertex* mcpv, LHCb::MCVertex* mcvtx, + std::vector<LHCb::MCParticle*>& allprods) const { + SmartRefVector<LHCb::MCParticle> daughters = mcvtx->products(); + SmartRefVector<LHCb::MCParticle>::iterator idau; + for(idau = daughters.begin(); idau != daughters.end(); idau++) { + double dv2 = (mcpv->position() - (*idau)->originVertex()->position()).Mag2(); + if(dv2 > (100.* Gaudi::Units::mm) * (100.* Gaudi::Units::mm)) continue; + LHCb::MCParticle* pmcp = *idau; + allprods.push_back(pmcp); + SmartRefVector<LHCb::MCVertex> decays = (*idau)->endVertices(); + SmartRefVector<LHCb::MCVertex>::iterator ivtx; + for(ivtx = decays.begin(); ivtx != decays.end(); ivtx++) { + collectProductss(mcpv, *ivtx, allprods); + } + } +} \ No newline at end of file diff --git a/GPU/BinaryDumpers/src/PVDumper.h b/GPU/BinaryDumpers/src/PVDumper.h new file mode 100644 index 0000000000000000000000000000000000000000..cf7855eb552ccc043aa2ebb099e81504fc7d522d --- /dev/null +++ b/GPU/BinaryDumpers/src/PVDumper.h @@ -0,0 +1,61 @@ +/*****************************************************************************\ +* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration * +* * +* This software is distributed under the terms of the GNU General Public * +* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". * +* * +* In applying this licence, CERN does not waive the privileges and immunities * +* granted to it by virtue of its status as an Intergovernmental Organization * +* or submit itself to any jurisdiction. * +\*****************************************************************************/ +#ifndef PVDUMPER_H +#define PVDUMPER_H 1 + +#include <fstream> +#include <string> +#include <cstring> + +// Include files +#include "GaudiAlg/Consumer.h" +#include "Event/MCTrackInfo.h" +#include "Event/MCParticle.h" +#include "Linker/LinkerWithKey.h" +#include "Event/MCVertex.h" +#include "Event/ODIN.h" + +/** @class PVDumper PVDumper.h + * tool to dump the MC truth informaiton for PVs + * based on the PrTrackerDumper code + * + * @author Florian Reiss + * @date 2018-12-17 + */ +/* + +*/ + +class PVDumper : public Gaudi::Functional::Consumer<void(const LHCb::MCVertices& MCVertices, const LHCb::ODIN&)> { + public: + /// Standard constructor + PVDumper( const std::string& name, ISvcLocator* pSvcLocator ); + + StatusCode initialize() override; + + void write_MCPV_info_to_binary_file( + const int number_rec_tracks, + const double pv_x, + const double pv_y, + const double pv_z, + std::ofstream& outfile ) const ; + + void operator()(const LHCb::MCVertices& MCVertices, const LHCb::ODIN& odin) const override; + + int count_reconstructible_mc_particles(LHCb::MCVertex* avtx) const; + + void collectProductss(LHCb::MCVertex* mcpv, LHCb::MCVertex* mcvtx, + std::vector<LHCb::MCParticle*>& allprods) const; + + private: + Gaudi::Property<std::string> m_outputDirectory{this, "OutputDirectory", "MC_info/PVs"}; +}; +#endif // PVDUMPER_H diff --git a/GPU/readme.md b/GPU/readme.md index 84914c2ae84c8c6aa6de8f4cc0382b2125205b4e..71ce90f2475e003e819ec08d4abaeb9ee5278e87 100644 --- a/GPU/readme.md +++ b/GPU/readme.md @@ -1,7 +1,7 @@ Produce input for HLT1 on GPUs ------------------------------- -These are instructions for how to produce input for [HLT1 on GPUs](https://gitlab.cern.ch/lhcb-parallelization/cuda_hlt) +These are instructions for how to produce input for [Allen](https://gitlab.cern.ch/lhcb-parallelization/Allen) (the HLT1 on GPUs project) using the nightlies with lb-dev. After logging in to lxplus7: @@ -35,7 +35,8 @@ By default, the following output directories will be created in the current dire * `banks`: all raw banks (VP, UT, FTCluster, Muon) * `muon_coords`, `muon_common_hits`: muon hit ojbects * `geometry`: geometry description for the different sub-detectors needed within HLT1 on GPUs -* `MC_info`: binary files containing MC information for all dumped MCParticles +* `MC_info/tracks`: binary files containing MC information needed to calculate track reconstruction efficiencies +* `MC_info/PVs`: binary files containing MC information needed to calculate PV reconstruction efficiencies * `TrackerDumper`: ROOT files containing MC information for all dumped MCParticles as well as all hits in every sub-detector For changing the output location, the OutputDirectory can be set in the configuration script, for example in dump_banks.py: diff --git a/Pr/PrMCTools/src/PrTrackerDumper.h b/Pr/PrMCTools/src/PrTrackerDumper.h index 78ee21f1bf74d69957566201905a2e6477f26119..15b260de0993de101326eb2073e63a6649f4de29 100644 --- a/Pr/PrMCTools/src/PrTrackerDumper.h +++ b/Pr/PrMCTools/src/PrTrackerDumper.h @@ -86,7 +86,7 @@ public: private: Gaudi::Property<std::string> m_outputDirectory{this, "OutputDirectory", "TrackerDumper"}; - Gaudi::Property<std::string> m_MCOutputDirectory{this, "MCOutputDirectory", "MC_info"}; + Gaudi::Property<std::string> m_MCOutputDirectory{this, "MCOutputDirectory", "MC_info/tracks"}; Gaudi::Property<bool> m_writeBinary{this, "DumpToBinary", false}; };