Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-10-24 08:19:48

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #include "ActsExamples/Io/Root/RootClusterWriter.hpp"
0010 
0011 #include "ActsExamples/EventData/Index.hpp"
0012 #include "ActsExamples/Framework/AlgorithmContext.hpp"
0013 
0014 #include <ios>
0015 
0016 #include <TFile.h>
0017 #include <TTree.h>
0018 
0019 namespace ActsExamples {
0020 
0021 RootClusterWriter::RootClusterWriter(const RootClusterWriter::Config& config,
0022                                      Acts::Logging::Level level)
0023     : WriterT(config.inputClusters, "RootClusterWriter", level), m_cfg(config) {
0024   // Input container for clusters is already checked by base constructor
0025 
0026   // Setup ROOT File
0027   m_outputFile = TFile::Open(m_cfg.filePath.c_str(), m_cfg.fileMode.c_str());
0028   if (m_outputFile == nullptr) {
0029     throw std::ios_base::failure("Could not open '" + m_cfg.filePath + "'");
0030   }
0031 
0032   m_outputFile->cd();
0033   m_outputTree = new TTree(m_cfg.treeName.c_str(), "Clusters");
0034 
0035   m_outputTree->Branch("event_nr", &m_eventNr);
0036   m_outputTree->Branch("cluster_id", &m_clusterId);
0037   m_outputTree->Branch("volume_id", &m_volumeId);
0038   m_outputTree->Branch("layer_id", &m_layerId);
0039   m_outputTree->Branch("surface_id", &m_surfaceId);
0040   m_outputTree->Branch("extra_id", &m_extraId);
0041 
0042   m_outputTree->Branch("clus_size", &m_clusterSize);
0043   m_outputTree->Branch("clus_size_loc0", &m_clusterSizeLoc0);
0044   m_outputTree->Branch("clus_size_loc1", &m_clusterSizeLoc1);
0045   m_outputTree->Branch("channel_loc0", &m_channelLoc0);
0046   m_outputTree->Branch("channel_loc1", &m_channelLoc1);
0047   m_outputTree->Branch("channel_value", &m_channelValue);
0048 
0049   m_outputTree->Branch("clus_gx", &m_globalX);
0050   m_outputTree->Branch("clus_gy", &m_globalY);
0051   m_outputTree->Branch("clus_gz", &m_globalZ);
0052 
0053   // Only filled for digitization inputs that provide the cluster shape,
0054   // e.g. the Athena dump reader
0055   m_outputTree->Branch("loc_direction_x", &m_localDirectionX);
0056   m_outputTree->Branch("loc_direction_y", &m_localDirectionY);
0057   m_outputTree->Branch("loc_direction_z", &m_localDirectionZ);
0058   m_outputTree->Branch("length_direction_x", &m_lengthDirectionX);
0059   m_outputTree->Branch("length_direction_y", &m_lengthDirectionY);
0060   m_outputTree->Branch("length_direction_z", &m_lengthDirectionZ);
0061   m_outputTree->Branch("loc_eta", &m_localEta);
0062   m_outputTree->Branch("loc_phi", &m_localPhi);
0063   m_outputTree->Branch("glob_eta", &m_globalEta);
0064   m_outputTree->Branch("glob_phi", &m_globalPhi);
0065   m_outputTree->Branch("eta_angle", &m_etaAngle);
0066   m_outputTree->Branch("phi_angle", &m_phiAngle);
0067 }
0068 
0069 RootClusterWriter::~RootClusterWriter() {
0070   if (m_outputFile != nullptr) {
0071     m_outputFile->Close();
0072   }
0073 }
0074 
0075 ProcessCode RootClusterWriter::finalize() {
0076   m_outputFile->cd();
0077   m_outputTree->Write();
0078   m_outputFile->Close();
0079 
0080   return ProcessCode::SUCCESS;
0081 }
0082 
0083 ProcessCode RootClusterWriter::writeT(const AlgorithmContext& ctx,
0084                                       const ClusterContainer& clusters) {
0085   // Exclusive access to the tree while writing
0086   std::lock_guard<std::mutex> lock(m_writeMutex);
0087 
0088   for (Index clusterIdx = 0u; clusterIdx < clusters.size(); ++clusterIdx) {
0089     const Cluster& cluster = clusters[clusterIdx];
0090 
0091     m_eventNr = static_cast<int>(ctx.eventNumber);
0092     m_clusterId = clusterIdx;
0093     m_volumeId = static_cast<int>(cluster.geometryId.volume());
0094     m_layerId = static_cast<int>(cluster.geometryId.layer());
0095     m_surfaceId = static_cast<int>(cluster.geometryId.sensitive());
0096     m_extraId = static_cast<int>(cluster.geometryId.extra());
0097 
0098     m_clusterSize = static_cast<int>(cluster.channels.size());
0099     m_clusterSizeLoc0 = static_cast<int>(cluster.sizeLoc0);
0100     m_clusterSizeLoc1 = static_cast<int>(cluster.sizeLoc1);
0101     for (const auto& channel : cluster.channels) {
0102       m_channelLoc0.push_back(static_cast<int>(channel.bin[0]));
0103       m_channelLoc1.push_back(static_cast<int>(channel.bin[1]));
0104       m_channelValue.push_back(static_cast<float>(channel.activation));
0105     }
0106 
0107     m_globalX = static_cast<float>(cluster.globalPosition.x());
0108     m_globalY = static_cast<float>(cluster.globalPosition.y());
0109     m_globalZ = static_cast<float>(cluster.globalPosition.z());
0110     m_localDirectionX = static_cast<float>(cluster.localDirection.x());
0111     m_localDirectionY = static_cast<float>(cluster.localDirection.y());
0112     m_localDirectionZ = static_cast<float>(cluster.localDirection.z());
0113     m_lengthDirectionX = static_cast<float>(cluster.lengthDirection.x());
0114     m_lengthDirectionY = static_cast<float>(cluster.lengthDirection.y());
0115     m_lengthDirectionZ = static_cast<float>(cluster.lengthDirection.z());
0116     m_localEta = cluster.localEta;
0117     m_localPhi = cluster.localPhi;
0118     m_globalEta = cluster.globalEta;
0119     m_globalPhi = cluster.globalPhi;
0120     m_etaAngle = cluster.etaAngle;
0121     m_phiAngle = cluster.phiAngle;
0122 
0123     m_outputTree->Fill();
0124 
0125     m_channelLoc0.clear();
0126     m_channelLoc1.clear();
0127     m_channelValue.clear();
0128   }
0129 
0130   return ProcessCode::SUCCESS;
0131 }
0132 
0133 }  // namespace ActsExamples