Skip to content
Snippets Groups Projects
Commit 4a77dfa6 authored by Whitney Armstrong's avatar Whitney Armstrong
Browse files

new file: src/Io/lcio2/include/ACTFW/Io/lcio2/Lcio2TrackerHitWriter.hpp

	new file:   src/Io/lcio2/src/Lcio2TrackerHitWriter.cpp
parent e53e912d
No related branches found
No related tags found
No related merge requests found
Pipeline #2982 passed
// This file is part of the Acts project.
//
// Copyright (C) 2018 CERN for the benefit of the Acts project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#pragma once
#include <cstdint>
#include <mutex>
#include <string>
#include "ACTFW/EventData/SimHit.hpp"
#include "ACTFW/Framework/WriterT.hpp"
#include "lcio2/TrackerHitData.h"
class TFile;
class TTree;
namespace FW {
/// Write out simulated hits as a flat TTree.
///
/// Each entry in the TTree corresponds to one hit for optimum writing
/// speed. The event number is part of the written data.
///
/// Safe to use from multiple writer threads. To avoid thread-saftey issues,
/// the writer must be the sole owner of the underlying file. Thus, the
/// output file pointer can not be given from the outside.
class Lcio2TrackerHitWriter final : public WriterT<SimHitContainer> {
public:
struct Config {
/// Input particle collection to write.
std::string inputSimulatedHits;
/// Path to the output file.
std::string filePath;
/// Output file access mode.
std::string fileMode = "RECREATE";
/// Name of the tree within the output file.
std::string treeName = "hits";
};
/// Construct the particle writer.
///
/// @params cfg is the configuration object
/// @params lvl is the logging level
Lcio2TrackerHitWriter(const Config& cfg, Acts::Logging::Level lvl);
/// Ensure underlying file is closed.
~Lcio2TrackerHitWriter() final override;
/// End-of-run hook
ProcessCode endRun() final override;
protected:
/// Type-specific write implementation.
///
/// @param[in] ctx is the algorithm context
/// @param[in] hits are the hits to be written
ProcessCode writeT(const AlgorithmContext& ctx,
const SimHitContainer& hits) final override;
private:
Config m_cfg;
std::mutex m_writeMutex;
TFile* m_outputFile = nullptr;
TTree* m_outputTree = nullptr;
/// Event identifier.
uint32_t m_eventId;
/// Hit surface identifier.
uint64_t m_geometryId;
/// Event-unique particle identifier a.k.a. barcode.
uint64_t m_particleId;
/// True global hit position components in mm.
float m_tx, m_ty, m_tz;
// True global hit time in ns.
float m_tt;
/// True particle four-momentum in GeV at hit position before interaction.
float m_tpx, m_tpy, m_tpz, m_te;
/// True change in particle four-momentum in GeV due to interactions.
float m_deltapx, m_deltapy, m_deltapz, m_deltae;
/// Hit index along the particle trajectory
int32_t m_index;
// Decoded hit surface identifier components.
uint32_t m_volumeId;
uint32_t m_boundaryId;
uint32_t m_layerId;
uint32_t m_approachId;
uint32_t m_sensitiveId;
TrackerHitData
};
} // namespace FW
// This file is part of the Acts project.
//
// Copyright (C) 2017-2018 CERN for the benefit of the Acts project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include "ACTFW/Io/Root/Lcio2TrackerHitWriter.hpp"
#include <TFile.h>
#include <TTree.h>
#include <ios>
#include <stdexcept>
#include "Acts/Utilities/Units.hpp"
FW::Lcio2TrackerHitWriter::Lcio2TrackerHitWriter(const FW::Lcio2TrackerHitWriter::Config& cfg,
Acts::Logging::Level lvl)
: WriterT(cfg.inputSimulatedHits, "Lcio2TrackerHitWriter", lvl), m_cfg(cfg) {
// inputParticles is already checked by base constructor
if (m_cfg.filePath.empty()) {
throw std::invalid_argument("Missing file path");
}
if (m_cfg.treeName.empty()) {
throw std::invalid_argument("Missing tree name");
}
// open root file and create the tree
m_outputFile = TFile::Open(m_cfg.filePath.c_str(), m_cfg.fileMode.c_str());
if (m_outputFile == nullptr) {
throw std::ios_base::failure("Could not open '" + m_cfg.filePath + "'");
}
m_outputFile->cd();
m_outputTree = new TTree(m_cfg.treeName.c_str(), m_cfg.treeName.c_str());
if (m_outputTree == nullptr) {
throw std::bad_alloc();
}
// setup the branches
m_outputTree->Branch("event_id", &m_eventId);
m_outputTree->Branch("geometry_id", &m_geometryId, "geometry_id/l");
m_outputTree->Branch("particle_id", &m_particleId, "particle_id/l");
m_outputTree->Branch("tx", &m_tx);
m_outputTree->Branch("ty", &m_ty);
m_outputTree->Branch("tz", &m_tz);
m_outputTree->Branch("tt", &m_tt);
m_outputTree->Branch("tpx", &m_tpx);
m_outputTree->Branch("tpy", &m_tpy);
m_outputTree->Branch("tpz", &m_tpz);
m_outputTree->Branch("te", &m_te);
m_outputTree->Branch("deltapx", &m_deltapx);
m_outputTree->Branch("deltapy", &m_deltapy);
m_outputTree->Branch("deltapz", &m_deltapz);
m_outputTree->Branch("deltae", &m_deltae);
m_outputTree->Branch("index", &m_index);
m_outputTree->Branch("volume_id", &m_volumeId);
m_outputTree->Branch("boundary_id", &m_boundaryId);
m_outputTree->Branch("layer_id", &m_layerId);
m_outputTree->Branch("approach_id", &m_approachId);
m_outputTree->Branch("sensitive_id", &m_sensitiveId);
}
FW::Lcio2TrackerHitWriter::~Lcio2TrackerHitWriter() {
if (m_outputFile) {
m_outputFile->Close();
}
}
FW::ProcessCode FW::Lcio2TrackerHitWriter::endRun() {
if (m_outputFile) {
m_outputFile->cd();
m_outputTree->Write();
ACTS_VERBOSE("Wrote hits to tree '" << m_cfg.treeName << "' in '"
<< m_cfg.filePath << "'");
}
return ProcessCode::SUCCESS;
}
FW::ProcessCode FW::Lcio2TrackerHitWriter::writeT(const AlgorithmContext& ctx,
const FW::SimHitContainer& hits) {
if (not m_outputFile) {
ACTS_ERROR("Missing output file");
return ProcessCode::ABORT;
}
// ensure exclusive access to tree/file while writing
std::lock_guard<std::mutex> lock(m_writeMutex);
// Get the event number
m_eventId = ctx.eventNumber;
for (const auto& hit : hits) {
m_particleId = hit.particleId().value();
m_geometryId = hit.geometryId().value();
// write hit position
m_tx = hit.position4().x() / Acts::UnitConstants::mm;
m_ty = hit.position4().y() / Acts::UnitConstants::mm;
m_tz = hit.position4().z() / Acts::UnitConstants::mm;
m_tt = hit.position4().w() / Acts::UnitConstants::ns;
// write four-momentum before interaction
m_tpx = hit.momentum4Before().x() / Acts::UnitConstants::GeV;
m_tpy = hit.momentum4Before().y() / Acts::UnitConstants::GeV;
m_tpz = hit.momentum4Before().z() / Acts::UnitConstants::GeV;
m_te = hit.momentum4Before().w() / Acts::UnitConstants::GeV;
// write four-momentum change due to interaction
const auto delta4 = hit.momentum4After() - hit.momentum4Before();
m_deltapx = delta4.x() / Acts::UnitConstants::GeV;
m_deltapy = delta4.y() / Acts::UnitConstants::GeV;
m_deltapz = delta4.z() / Acts::UnitConstants::GeV;
m_deltae = delta4.w() / Acts::UnitConstants::GeV;
// write hit index along trajectory
m_index = hit.index();
// decoded geometry for simplicity
m_volumeId = hit.geometryId().volume();
m_boundaryId = hit.geometryId().boundary();
m_layerId = hit.geometryId().layer();
m_approachId = hit.geometryId().approach();
m_sensitiveId = hit.geometryId().sensitive();
// Fill the tree
m_outputTree->Fill();
}
return FW::ProcessCode::SUCCESS;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment