Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-05-23 23:48:59

0001 // Authors:  Philipp Zehetner, Wahid Redjeb, Aurora Perego, Felice Pantaleo
0002 
0003 #include "TTree.h"
0004 #include "TFile.h"
0005 
0006 #include <iostream>
0007 #include <fstream>
0008 #include <sstream>
0009 #include <variant>
0010 
0011 #include <memory>  // unique_ptr
0012 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0013 #include "FWCore/ParameterSet/interface/PluginDescription.h"
0014 #include "FWCore/ParameterSet/interface/allowedValues.h"
0015 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0016 #include "FWCore/Utilities/interface/ESGetToken.h"
0017 #include "FWCore/Framework/interface/ESHandle.h"
0018 #include "FWCore/Framework/interface/Frameworkfwd.h"
0019 #include "FWCore/Framework/interface/one/EDAnalyzer.h"
0020 #include "FWCore/Framework/interface/Event.h"
0021 #include "FWCore/Framework/interface/MakerMacros.h"
0022 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0023 #include "FWCore/ServiceRegistry/interface/Service.h"
0024 
0025 #include "DataFormats/Provenance/interface/EventID.h"
0026 #include "DataFormats/CaloRecHit/interface/CaloCluster.h"
0027 #include "DataFormats/HGCalReco/interface/Trackster.h"
0028 #include "DataFormats/HGCalReco/interface/TICLCandidate.h"
0029 #include "DataFormats/MuonReco/interface/Muon.h"
0030 #include "DataFormats/TrackReco/interface/Track.h"
0031 #include "DataFormats/TrackReco/interface/TrackFwd.h"
0032 #include "DataFormats/DetId/interface/DetId.h"
0033 #include "DataFormats/Math/interface/Point3D.h"
0034 #include "DataFormats/GeometrySurface/interface/BoundDisk.h"
0035 #include "DataFormats/HGCalReco/interface/Common.h"
0036 #include "SimDataFormats/CaloAnalysis/interface/CaloParticle.h"
0037 #include "SimDataFormats/CaloAnalysis/interface/SimCluster.h"
0038 #include "DataFormats/EgammaReco/interface/SuperClusterFwd.h"
0039 #include "DataFormats/EgammaReco/interface/SuperCluster.h"
0040 
0041 #include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h"
0042 #include "RecoParticleFlow/PFProducer/interface/PFMuonAlgo.h"
0043 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
0044 #include "TrackingTools/GeomPropagators/interface/Propagator.h"
0045 #include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
0046 
0047 #include "MagneticField/Engine/interface/MagneticField.h"
0048 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
0049 
0050 #include "Geometry/HGCalCommonData/interface/HGCalDDDConstants.h"
0051 #include "Geometry/Records/interface/IdealGeometryRecord.h"
0052 #include "Geometry/CommonDetUnit/interface/GeomDet.h"
0053 
0054 #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
0055 #include "Geometry/Records/interface/CaloGeometryRecord.h"
0056 #include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h"
0057 
0058 #include "SimDataFormats/Associations/interface/TICLAssociationMap.h"
0059 
0060 // TFileService
0061 #include "FWCore/ServiceRegistry/interface/Service.h"
0062 #include "CommonTools/UtilAlgos/interface/TFileService.h"
0063 
0064 using TracksterToTracksterMap =
0065     ticl::AssociationMap<ticl::mapWithSharedEnergyAndScore, std::vector<ticl::Trackster>, std::vector<ticl::Trackster>>;
0066 // Helper class for geometry, magnetic field, etc
0067 class DetectorTools {
0068 public:
0069   DetectorTools(const HGCalDDDConstants& hgcons,
0070                 const CaloGeometry& geom,
0071                 const MagneticField& bfieldH,
0072                 const Propagator& propH)
0073       : hgcons(hgcons), rhtools(), bfield(bfieldH), propagator(propH) {
0074     rhtools.setGeometry(geom);
0075 
0076     // build disks at HGCal front & EM-Had interface for track propagation
0077     float zVal = hgcons.waferZ(1, true);
0078     std::pair<float, float> rMinMax = hgcons.rangeR(zVal, true);
0079 
0080     float zVal_interface = rhtools.getPositionLayer(rhtools.lastLayerEE()).z();
0081     std::pair<float, float> rMinMax_interface = hgcons.rangeR(zVal_interface, true);
0082 
0083     for (int iSide = 0; iSide < 2; ++iSide) {
0084       float zSide = (iSide == 0) ? (-1. * zVal) : zVal;
0085       firstDisk_[iSide] = std::make_unique<GeomDet>(
0086           Disk::build(Disk::PositionType(0, 0, zSide),
0087                       Disk::RotationType(),
0088                       SimpleDiskBounds(rMinMax.first, rMinMax.second, zSide - 0.5, zSide + 0.5))
0089               .get());
0090 
0091       zSide = (iSide == 0) ? (-1. * zVal_interface) : zVal_interface;
0092       interfaceDisk_[iSide] = std::make_unique<GeomDet>(
0093           Disk::build(Disk::PositionType(0, 0, zSide),
0094                       Disk::RotationType(),
0095                       SimpleDiskBounds(rMinMax_interface.first, rMinMax_interface.second, zSide - 0.5, zSide + 0.5))
0096               .get());
0097     }
0098   }
0099 
0100   const HGCalDDDConstants& hgcons;
0101   std::unique_ptr<GeomDet> firstDisk_[2];
0102   std::unique_ptr<GeomDet> interfaceDisk_[2];
0103   hgcal::RecHitTools rhtools;
0104   const MagneticField& bfield;
0105   const Propagator& propagator;
0106 };
0107 
0108 // Helper class that dumps a single trackster collection (either tracksters or simTracksters)
0109 class TracksterDumperHelper {
0110 public:
0111   enum class TracksterType {
0112     Trackster,       ///< Regular trackster (from RECO)
0113     SimTracksterCP,  ///< SimTrackster from CaloParticle
0114     SimTracksterSC   ///< SimTrackster from SimCluster
0115   };
0116 
0117   static TracksterType tracksterTypeFromString(std::string str) {
0118     if (str == "Trackster")
0119       return TracksterType::Trackster;
0120     if (str == "SimTracksterCP")
0121       return TracksterType::SimTracksterCP;
0122     if (str == "SimTracksterSC")
0123       return TracksterType::SimTracksterSC;
0124     throw std::runtime_error("TICLDumper : TracksterDumperHelper : Invalid trackster type " + str);
0125   }
0126 
0127   /** tracksterType : dtermines additional information that will be saved (calo truth information, track information) */
0128   TracksterDumperHelper(TracksterType tracksterType = TracksterType::Trackster) : tracksterType_(tracksterType) {}
0129 
0130   /**
0131    * To be called once after tree creation. eventId_ should be a pointer to the EventID.
0132    * *Do not copy/move or resize vector holding object after calling this function*
0133   */
0134   void initTree(TTree* trackster_tree_, edm::EventID* eventId_) {
0135     trackster_tree_->Branch("event", eventId_);
0136     trackster_tree_->Branch("NTracksters", &nTracksters);
0137     trackster_tree_->Branch("NClusters", &nClusters);
0138     trackster_tree_->Branch("time", &trackster_time);
0139     trackster_tree_->Branch("timeError", &trackster_timeError);
0140     trackster_tree_->Branch("regressed_energy", &trackster_regressed_energy);
0141     trackster_tree_->Branch("raw_energy", &trackster_raw_energy);
0142     trackster_tree_->Branch("raw_em_energy", &trackster_raw_em_energy);
0143     trackster_tree_->Branch("raw_pt", &trackster_raw_pt);
0144     trackster_tree_->Branch("raw_em_pt", &trackster_raw_em_pt);
0145     trackster_tree_->Branch("barycenter_x", &trackster_barycenter_x);
0146     trackster_tree_->Branch("barycenter_y", &trackster_barycenter_y);
0147     trackster_tree_->Branch("barycenter_z", &trackster_barycenter_z);
0148     trackster_tree_->Branch("barycenter_eta", &trackster_barycenter_eta);
0149     trackster_tree_->Branch("barycenter_phi", &trackster_barycenter_phi);
0150     trackster_tree_->Branch("EV1", &trackster_EV1);
0151     trackster_tree_->Branch("EV2", &trackster_EV2);
0152     trackster_tree_->Branch("EV3", &trackster_EV3);
0153     trackster_tree_->Branch("eVector0_x", &trackster_eVector0_x);
0154     trackster_tree_->Branch("eVector0_y", &trackster_eVector0_y);
0155     trackster_tree_->Branch("eVector0_z", &trackster_eVector0_z);
0156     trackster_tree_->Branch("sigmaPCA1", &trackster_sigmaPCA1);
0157     trackster_tree_->Branch("sigmaPCA2", &trackster_sigmaPCA2);
0158     trackster_tree_->Branch("sigmaPCA3", &trackster_sigmaPCA3);
0159     if (tracksterType_ != TracksterType::Trackster) {
0160       trackster_tree_->Branch("regressed_pt", &simtrackster_regressed_pt);
0161       trackster_tree_->Branch("pdgID", &simtrackster_pdgID);
0162       trackster_tree_->Branch("trackIdx", &simtrackster_trackIdx);
0163       trackster_tree_->Branch("trackTime", &simtrackster_trackTime);
0164       trackster_tree_->Branch("timeBoundary", &simtrackster_timeBoundary);
0165       trackster_tree_->Branch("boundaryX", &simtrackster_boundaryX);
0166       trackster_tree_->Branch("boundaryY", &simtrackster_boundaryY);
0167       trackster_tree_->Branch("boundaryZ", &simtrackster_boundaryZ);
0168       trackster_tree_->Branch("boundaryEta", &simtrackster_boundaryEta);
0169       trackster_tree_->Branch("boundaryPhi", &simtrackster_boundaryPhi);
0170       trackster_tree_->Branch("boundaryPx", &simtrackster_boundaryPx);
0171       trackster_tree_->Branch("boundaryPy", &simtrackster_boundaryPy);
0172       trackster_tree_->Branch("boundaryPz", &simtrackster_boundaryPz);
0173       trackster_tree_->Branch("track_boundaryX", &simtrackster_track_boundaryX);
0174       trackster_tree_->Branch("track_boundaryY", &simtrackster_track_boundaryY);
0175       trackster_tree_->Branch("track_boundaryZ", &simtrackster_track_boundaryZ);
0176       trackster_tree_->Branch("track_boundaryEta", &simtrackster_track_boundaryEta);
0177       trackster_tree_->Branch("track_boundaryPhi", &simtrackster_track_boundaryPhi);
0178       trackster_tree_->Branch("track_boundaryPx", &simtrackster_track_boundaryPx);
0179       trackster_tree_->Branch("track_boundaryPy", &simtrackster_track_boundaryPy);
0180       trackster_tree_->Branch("track_boundaryPz", &simtrackster_track_boundaryPz);
0181     }
0182     trackster_tree_->Branch("id_probabilities", &trackster_id_probabilities);
0183     trackster_tree_->Branch("vertices_indexes", &trackster_vertices_indexes);
0184     trackster_tree_->Branch("vertices_x", &trackster_vertices_x);
0185     trackster_tree_->Branch("vertices_y", &trackster_vertices_y);
0186     trackster_tree_->Branch("vertices_z", &trackster_vertices_z);
0187     trackster_tree_->Branch("vertices_time", &trackster_vertices_time);
0188     trackster_tree_->Branch("vertices_timeErr", &trackster_vertices_timeErr);
0189     trackster_tree_->Branch("vertices_energy", &trackster_vertices_energy);
0190     trackster_tree_->Branch("vertices_correctedEnergy", &trackster_vertices_correctedEnergy);
0191     trackster_tree_->Branch("vertices_correctedEnergyUncertainty", &trackster_vertices_correctedEnergyUncertainty);
0192     trackster_tree_->Branch("vertices_multiplicity", &trackster_vertices_multiplicity);
0193   }
0194 
0195   void clearVariables() {
0196     nTracksters = 0;
0197     nClusters = 0;
0198     trackster_time.clear();
0199     trackster_timeError.clear();
0200     trackster_regressed_energy.clear();
0201     trackster_raw_energy.clear();
0202     trackster_raw_em_energy.clear();
0203     trackster_raw_pt.clear();
0204     trackster_raw_em_pt.clear();
0205     trackster_barycenter_x.clear();
0206     trackster_barycenter_y.clear();
0207     trackster_barycenter_z.clear();
0208     trackster_EV1.clear();
0209     trackster_EV2.clear();
0210     trackster_EV3.clear();
0211     trackster_eVector0_x.clear();
0212     trackster_eVector0_y.clear();
0213     trackster_eVector0_z.clear();
0214     trackster_sigmaPCA1.clear();
0215     trackster_sigmaPCA2.clear();
0216     trackster_sigmaPCA3.clear();
0217 
0218     simtrackster_regressed_pt.clear();
0219     simtrackster_pdgID.clear();
0220     simtrackster_trackIdx.clear();
0221     simtrackster_trackTime.clear();
0222     simtrackster_timeBoundary.clear();
0223     simtrackster_boundaryX.clear();
0224     simtrackster_boundaryY.clear();
0225     simtrackster_boundaryZ.clear();
0226     simtrackster_boundaryEta.clear();
0227     simtrackster_boundaryPhi.clear();
0228     simtrackster_boundaryPx.clear();
0229     simtrackster_boundaryPy.clear();
0230     simtrackster_boundaryPz.clear();
0231     simtrackster_track_boundaryX.clear();
0232     simtrackster_track_boundaryY.clear();
0233     simtrackster_track_boundaryZ.clear();
0234     simtrackster_track_boundaryEta.clear();
0235     simtrackster_track_boundaryPhi.clear();
0236     simtrackster_track_boundaryPx.clear();
0237     simtrackster_track_boundaryPy.clear();
0238     simtrackster_track_boundaryPz.clear();
0239 
0240     trackster_barycenter_eta.clear();
0241     trackster_barycenter_phi.clear();
0242     trackster_id_probabilities.clear();
0243     trackster_vertices_indexes.clear();
0244     trackster_vertices_x.clear();
0245     trackster_vertices_y.clear();
0246     trackster_vertices_z.clear();
0247     trackster_vertices_time.clear();
0248     trackster_vertices_timeErr.clear();
0249     trackster_vertices_energy.clear();
0250     trackster_vertices_correctedEnergy.clear();
0251     trackster_vertices_correctedEnergyUncertainty.clear();
0252     trackster_vertices_multiplicity.clear();
0253   }
0254 
0255   void fillFromEvent(std::vector<ticl::Trackster> const& tracksters,
0256                      std::vector<reco::CaloCluster> const& clusters,
0257                      edm::ValueMap<std::pair<float, float>> const& layerClustersTimes,
0258                      DetectorTools const& detectorTools,
0259                      edm::Handle<std::vector<SimCluster>> simClusters_h,
0260                      edm::Handle<std::vector<CaloParticle>> caloparticles_h,
0261                      std::vector<reco::Track> const& tracks) {
0262     nTracksters = tracksters.size();
0263     nClusters = clusters.size();
0264     for (auto trackster_iterator = tracksters.begin(); trackster_iterator != tracksters.end(); ++trackster_iterator) {
0265       //per-trackster analysis
0266       trackster_time.push_back(trackster_iterator->time());
0267       trackster_timeError.push_back(trackster_iterator->timeError());
0268       trackster_regressed_energy.push_back(trackster_iterator->regressed_energy());
0269       trackster_raw_energy.push_back(trackster_iterator->raw_energy());
0270       trackster_raw_em_energy.push_back(trackster_iterator->raw_em_energy());
0271       trackster_raw_pt.push_back(trackster_iterator->raw_pt());
0272       trackster_raw_em_pt.push_back(trackster_iterator->raw_em_pt());
0273       trackster_barycenter_x.push_back(trackster_iterator->barycenter().x());
0274       trackster_barycenter_y.push_back(trackster_iterator->barycenter().y());
0275       trackster_barycenter_z.push_back(trackster_iterator->barycenter().z());
0276       trackster_barycenter_eta.push_back(trackster_iterator->barycenter().eta());
0277       trackster_barycenter_phi.push_back(trackster_iterator->barycenter().phi());
0278       trackster_EV1.push_back(trackster_iterator->eigenvalues()[0]);
0279       trackster_EV2.push_back(trackster_iterator->eigenvalues()[1]);
0280       trackster_EV3.push_back(trackster_iterator->eigenvalues()[2]);
0281       trackster_eVector0_x.push_back((trackster_iterator->eigenvectors()[0]).x());
0282       trackster_eVector0_y.push_back((trackster_iterator->eigenvectors()[0]).y());
0283       trackster_eVector0_z.push_back((trackster_iterator->eigenvectors()[0]).z());
0284       trackster_sigmaPCA1.push_back(trackster_iterator->sigmasPCA()[0]);
0285       trackster_sigmaPCA2.push_back(trackster_iterator->sigmasPCA()[1]);
0286       trackster_sigmaPCA3.push_back(trackster_iterator->sigmasPCA()[2]);
0287 
0288       if (tracksterType_ != TracksterType::Trackster) {  // is simtrackster
0289         auto const& simclusters = *simClusters_h;
0290         auto const& caloparticles = *caloparticles_h;
0291 
0292         simtrackster_timeBoundary.push_back(trackster_iterator->boundaryTime());
0293 
0294         /* SimTracksters can be built from either a CaloParticle or a SimCluster 
0295         The SimTrackster "fromCP" collection is built solely from CaloParticle (all CPs that have association to reco in HGCAL)
0296         SimTrackster "from SC" is built from either :
0297            - a CaloParticle (when the CaloParticle first SimTrack has crossedBoundary=True)
0298            - a SimCluster (other cases) 
0299         Thus trackster.seedIndex() can point to either CaloParticle or SimCluster collection (check seedID to differentiate)
0300         */
0301         using CaloObjectVariant = std::variant<CaloParticle, SimCluster>;
0302         CaloObjectVariant caloObj;
0303         if (trackster_iterator->seedID() == caloparticles_h.id()) {
0304           caloObj = caloparticles[trackster_iterator->seedIndex()];
0305         } else {
0306           caloObj = simclusters[trackster_iterator->seedIndex()];
0307         }
0308 
0309         simtrackster_pdgID.push_back(std::visit([](auto&& obj) { return obj.pdgId(); }, caloObj));
0310         auto const& simTrack = std::visit([](auto&& obj) { return obj.g4Tracks()[0]; }, caloObj);
0311         auto const& caloPt = std::visit([](auto&& obj) { return obj.pt(); }, caloObj);
0312         simtrackster_regressed_pt.push_back(caloPt);
0313         if (simTrack.crossedBoundary()) {
0314           simtrackster_boundaryX.push_back(simTrack.getPositionAtBoundary().x());
0315           simtrackster_boundaryY.push_back(simTrack.getPositionAtBoundary().y());
0316           simtrackster_boundaryZ.push_back(simTrack.getPositionAtBoundary().z());
0317           simtrackster_boundaryEta.push_back(simTrack.getPositionAtBoundary().eta());
0318           simtrackster_boundaryPhi.push_back(simTrack.getPositionAtBoundary().phi());
0319           simtrackster_boundaryPx.push_back(simTrack.getMomentumAtBoundary().x());
0320           simtrackster_boundaryPy.push_back(simTrack.getMomentumAtBoundary().y());
0321           simtrackster_boundaryPz.push_back(simTrack.getMomentumAtBoundary().z());
0322         } else {
0323           simtrackster_boundaryX.push_back(-999);
0324           simtrackster_boundaryY.push_back(-999);
0325           simtrackster_boundaryZ.push_back(-999);
0326           simtrackster_boundaryEta.push_back(-999);
0327           simtrackster_boundaryPhi.push_back(-999);
0328           simtrackster_boundaryPx.push_back(-999);
0329           simtrackster_boundaryPy.push_back(-999);
0330           simtrackster_boundaryPz.push_back(-999);
0331         }
0332 
0333         auto const trackIdx = trackster_iterator->trackIdx();
0334         simtrackster_trackIdx.push_back(trackIdx);
0335         if (trackIdx != -1) {
0336           const auto& track = tracks[trackIdx];
0337 
0338           int iSide = int(track.eta() > 0);
0339 
0340           const auto& fts = trajectoryStateTransform::outerFreeState((track), &detectorTools.bfield);
0341           // to the HGCal front
0342           const auto& tsos = detectorTools.propagator.propagate(fts, detectorTools.firstDisk_[iSide]->surface());
0343           if (tsos.isValid()) {
0344             const auto& globalPos = tsos.globalPosition();
0345             const auto& globalMom = tsos.globalMomentum();
0346             simtrackster_track_boundaryX.push_back(globalPos.x());
0347             simtrackster_track_boundaryY.push_back(globalPos.y());
0348             simtrackster_track_boundaryZ.push_back(globalPos.z());
0349             simtrackster_track_boundaryEta.push_back(globalPos.eta());
0350             simtrackster_track_boundaryPhi.push_back(globalPos.phi());
0351             simtrackster_track_boundaryPx.push_back(globalMom.x());
0352             simtrackster_track_boundaryPy.push_back(globalMom.y());
0353             simtrackster_track_boundaryPz.push_back(globalMom.z());
0354             simtrackster_trackTime.push_back(track.t0());
0355           } else {
0356             simtrackster_track_boundaryX.push_back(-999);
0357             simtrackster_track_boundaryY.push_back(-999);
0358             simtrackster_track_boundaryZ.push_back(-999);
0359             simtrackster_track_boundaryEta.push_back(-999);
0360             simtrackster_track_boundaryPhi.push_back(-999);
0361             simtrackster_track_boundaryPx.push_back(-999);
0362             simtrackster_track_boundaryPy.push_back(-999);
0363             simtrackster_track_boundaryPz.push_back(-999);
0364           }
0365         } else {
0366           simtrackster_track_boundaryX.push_back(-999);
0367           simtrackster_track_boundaryY.push_back(-999);
0368           simtrackster_track_boundaryZ.push_back(-999);
0369           simtrackster_track_boundaryEta.push_back(-999);
0370           simtrackster_track_boundaryPhi.push_back(-999);
0371           simtrackster_track_boundaryPx.push_back(-999);
0372           simtrackster_track_boundaryPy.push_back(-999);
0373           simtrackster_track_boundaryPz.push_back(-999);
0374         }
0375       }
0376 
0377       std::vector<float> id_probs;
0378       for (size_t i = 0; i < 8; i++)
0379         id_probs.push_back(trackster_iterator->id_probabilities(i));
0380       trackster_id_probabilities.push_back(id_probs);
0381 
0382       // Clusters
0383       std::vector<uint32_t> vertices_indexes;
0384       std::vector<float> vertices_x;
0385       std::vector<float> vertices_y;
0386       std::vector<float> vertices_z;
0387       std::vector<float> vertices_time;
0388       std::vector<float> vertices_timeErr;
0389       std::vector<float> vertices_energy;
0390       std::vector<float> vertices_correctedEnergy;
0391       std::vector<float> vertices_correctedEnergyUncertainty;
0392       for (auto idx : trackster_iterator->vertices()) {
0393         vertices_indexes.push_back(idx);
0394         const auto& associated_cluster = clusters[idx];
0395         vertices_x.push_back(associated_cluster.x());
0396         vertices_y.push_back(associated_cluster.y());
0397         vertices_z.push_back(associated_cluster.z());
0398         vertices_energy.push_back(associated_cluster.energy());
0399         vertices_correctedEnergy.push_back(associated_cluster.correctedEnergy());
0400         vertices_correctedEnergyUncertainty.push_back(associated_cluster.correctedEnergyUncertainty());
0401         vertices_time.push_back(layerClustersTimes.get(idx).first);
0402         vertices_timeErr.push_back(layerClustersTimes.get(idx).second);
0403       }
0404       trackster_vertices_indexes.push_back(vertices_indexes);
0405       trackster_vertices_x.push_back(vertices_x);
0406       trackster_vertices_y.push_back(vertices_y);
0407       trackster_vertices_z.push_back(vertices_z);
0408       trackster_vertices_time.push_back(vertices_time);
0409       trackster_vertices_timeErr.push_back(vertices_timeErr);
0410       trackster_vertices_energy.push_back(vertices_energy);
0411       trackster_vertices_correctedEnergy.push_back(vertices_correctedEnergy);
0412       trackster_vertices_correctedEnergyUncertainty.push_back(vertices_correctedEnergyUncertainty);
0413 
0414       // Multiplicity
0415       std::vector<float> vertices_multiplicity;
0416       for (auto multiplicity : trackster_iterator->vertex_multiplicity()) {
0417         vertices_multiplicity.push_back(multiplicity);
0418       }
0419       trackster_vertices_multiplicity.push_back(vertices_multiplicity);
0420     }
0421   }
0422 
0423 private:
0424   TracksterType tracksterType_;
0425 
0426   unsigned int nTracksters;
0427   unsigned int nClusters;
0428   std::vector<float> trackster_time;
0429   std::vector<float> trackster_timeError;
0430   std::vector<float> trackster_regressed_energy;
0431   std::vector<float> trackster_raw_energy;
0432   std::vector<float> trackster_raw_em_energy;
0433   std::vector<float> trackster_raw_pt;
0434   std::vector<float> trackster_raw_em_pt;
0435   std::vector<float> trackster_barycenter_x;
0436   std::vector<float> trackster_barycenter_y;
0437   std::vector<float> trackster_barycenter_z;
0438   std::vector<float> trackster_EV1;
0439   std::vector<float> trackster_EV2;
0440   std::vector<float> trackster_EV3;
0441   std::vector<float> trackster_eVector0_x;
0442   std::vector<float> trackster_eVector0_y;
0443   std::vector<float> trackster_eVector0_z;
0444   std::vector<float> trackster_sigmaPCA1;
0445   std::vector<float> trackster_sigmaPCA2;
0446   std::vector<float> trackster_sigmaPCA3;
0447   std::vector<float> trackster_barycenter_eta;
0448   std::vector<float> trackster_barycenter_phi;
0449 
0450   // for simtrackster
0451   std::vector<float> simtrackster_regressed_pt;
0452   std::vector<int> simtrackster_pdgID;
0453   std::vector<int> simtrackster_trackIdx;
0454   std::vector<float> simtrackster_trackTime;
0455   std::vector<float> simtrackster_timeBoundary;
0456   std::vector<float> simtrackster_boundaryX;
0457   std::vector<float> simtrackster_boundaryY;
0458   std::vector<float> simtrackster_boundaryZ;
0459   std::vector<float> simtrackster_boundaryEta;
0460   std::vector<float> simtrackster_boundaryPhi;
0461   std::vector<float> simtrackster_boundaryPx;
0462   std::vector<float> simtrackster_boundaryPy;
0463   std::vector<float> simtrackster_boundaryPz;
0464   std::vector<float> simtrackster_track_boundaryX;
0465   std::vector<float> simtrackster_track_boundaryY;
0466   std::vector<float> simtrackster_track_boundaryZ;
0467   std::vector<float> simtrackster_track_boundaryEta;
0468   std::vector<float> simtrackster_track_boundaryPhi;
0469   std::vector<float> simtrackster_track_boundaryPx;
0470   std::vector<float> simtrackster_track_boundaryPy;
0471   std::vector<float> simtrackster_track_boundaryPz;
0472 
0473   std::vector<std::vector<float>> trackster_id_probabilities;
0474   std::vector<std::vector<uint32_t>> trackster_vertices_indexes;
0475   std::vector<std::vector<float>> trackster_vertices_x;
0476   std::vector<std::vector<float>> trackster_vertices_y;
0477   std::vector<std::vector<float>> trackster_vertices_z;
0478   std::vector<std::vector<float>> trackster_vertices_time;
0479   std::vector<std::vector<float>> trackster_vertices_timeErr;
0480   std::vector<std::vector<float>> trackster_vertices_energy;
0481   std::vector<std::vector<float>> trackster_vertices_correctedEnergy;
0482   std::vector<std::vector<float>> trackster_vertices_correctedEnergyUncertainty;
0483   std::vector<std::vector<float>> trackster_vertices_multiplicity;
0484 };
0485 
0486 // Helper class to dump a TracksterToSimTrackster association map (dumps recoToSim and simToReco at the same time)
0487 class TracksterToSimTracksterAssociationHelper {
0488 public:
0489   /**
0490    * To be called once after tree creation. Output branches will be named prefix_recoToSim/simToReco_suffix_score/sharedE/
0491    * branchPrefix : for example tsCLUE3D. branchSuffix : usually one of SC or CP.
0492    * *Do not copy/move or resize vector holding object after calling this function*
0493   */
0494   void initTree(TTree* tree, std::string branchPrefix, std::string branchSuffix) {
0495     tree->Branch((branchPrefix + "_recoToSim_" + branchSuffix).c_str(), &recoToSim);
0496     tree->Branch((branchPrefix + "_recoToSim_" + branchSuffix + "_score").c_str(), &recoToSim_score);
0497     tree->Branch((branchPrefix + "_recoToSim_" + branchSuffix + "_sharedE").c_str(), &recoToSim_sharedE);
0498     tree->Branch((branchPrefix + "_simToReco_" + branchSuffix).c_str(), &simToReco);
0499     tree->Branch((branchPrefix + "_simToReco_" + branchSuffix + "_score").c_str(), &simToReco_score);
0500     tree->Branch((branchPrefix + "_simToReco_" + branchSuffix + "_sharedE").c_str(), &simToReco_sharedE);
0501   }
0502 
0503   void clearVariables() {
0504     recoToSim.clear();
0505     recoToSim_score.clear();
0506     recoToSim_sharedE.clear();
0507     simToReco.clear();
0508     simToReco_score.clear();
0509     simToReco_sharedE.clear();
0510   }
0511 
0512   void fillFromEvent(TracksterToTracksterMap const& recoToSimMap, TracksterToTracksterMap const& simToRecoMap) {
0513     // Reco -> Sim
0514     const auto numberOfTracksters = recoToSimMap.getMap().size();
0515     recoToSim.resize(numberOfTracksters);
0516     recoToSim_score.resize(numberOfTracksters);
0517     recoToSim_sharedE.resize(numberOfTracksters);
0518 
0519     for (size_t i = 0; i < numberOfTracksters; ++i) {
0520       for (const auto& simTracksterElement : recoToSimMap[i]) {
0521         recoToSim[i].push_back(simTracksterElement.index());
0522         recoToSim_sharedE[i].push_back(simTracksterElement.sharedEnergy());
0523         recoToSim_score[i].push_back(simTracksterElement.score());
0524       }
0525     }
0526 
0527     // Sim -> Reco
0528     const auto numberOfSimTracksters = simToRecoMap.getMap().size();
0529     simToReco.resize(numberOfSimTracksters);
0530     simToReco_score.resize(numberOfSimTracksters);
0531     simToReco_sharedE.resize(numberOfSimTracksters);
0532 
0533     for (size_t i = 0; i < numberOfSimTracksters; ++i) {
0534       for (const auto& recoTracksterElement : simToRecoMap[i]) {
0535         simToReco[i].push_back(recoTracksterElement.index());
0536         simToReco_sharedE[i].push_back(recoTracksterElement.sharedEnergy());
0537         simToReco_score[i].push_back(recoTracksterElement.score());
0538       }
0539     }
0540   }
0541 
0542 private:
0543   std::vector<std::vector<uint32_t>> recoToSim;
0544   std::vector<std::vector<float>> recoToSim_score;
0545   std::vector<std::vector<float>> recoToSim_sharedE;
0546   std::vector<std::vector<uint32_t>> simToReco;
0547   std::vector<std::vector<float>> simToReco_score;
0548   std::vector<std::vector<float>> simToReco_sharedE;
0549 };
0550 
0551 class TICLDumper : public edm::one::EDAnalyzer<edm::one::WatchRuns, edm::one::SharedResources> {
0552 public:
0553   explicit TICLDumper(const edm::ParameterSet&);
0554   ~TICLDumper() override;
0555   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0556   typedef ticl::Vector Vector;
0557   typedef std::vector<double> Vec;
0558 
0559 private:
0560   void beginJob() override;
0561   void beginRun(const edm::Run&, const edm::EventSetup&) override;
0562 
0563   void analyze(const edm::Event&, const edm::EventSetup&) override;
0564   void endRun(edm::Run const& iEvent, edm::EventSetup const&) override {};
0565   void endJob() override;
0566 
0567   // Define Tokens
0568   const std::vector<edm::ParameterSet>
0569       tracksters_parameterSets_;  ///< A parameter set for each trackster collection to dump (giving tree name, etc)
0570   std::vector<edm::EDGetTokenT<std::vector<ticl::Trackster>>>
0571       tracksters_token_;  ///< a token for each trackster collection to dump
0572   std::vector<TracksterDumperHelper>
0573       tracksters_dumperHelpers_;         ///< the dumper helpers for each trackster collection to dump
0574   std::vector<TTree*> tracksters_trees;  ///< TTree for each trackster collection to dump
0575 
0576   const edm::EDGetTokenT<std::vector<ticl::Trackster>> tracksters_in_candidate_token_;
0577   const edm::EDGetTokenT<std::vector<reco::CaloCluster>> layer_clusters_token_;
0578   const edm::EDGetTokenT<std::vector<TICLCandidate>> ticl_candidates_token_;
0579   const edm::EDGetTokenT<std::vector<ticl::Trackster>>
0580       ticl_candidates_tracksters_token_;  ///< trackster collection used by TICLCandidate
0581   const edm::EDGetTokenT<std::vector<reco::Track>> tracks_token_;
0582   const edm::EDGetTokenT<std::vector<bool>> tracks_mask_token_;
0583   const edm::EDGetTokenT<edm::ValueMap<float>> tracks_time_token_;
0584   const edm::EDGetTokenT<edm::ValueMap<float>> tracks_time_quality_token_;
0585   const edm::EDGetTokenT<edm::ValueMap<float>> tracks_time_err_token_;
0586   const edm::EDGetTokenT<edm::ValueMap<float>> tracks_beta_token_;
0587   const edm::EDGetTokenT<edm::ValueMap<float>> tracks_time_mtd_token_;
0588   const edm::EDGetTokenT<edm::ValueMap<float>> tracks_time_mtd_err_token_;
0589   const edm::EDGetTokenT<edm::ValueMap<GlobalPoint>> tracks_pos_mtd_token_;
0590   const edm::EDGetTokenT<std::vector<double>> hgcaltracks_x_token_;
0591   const edm::EDGetTokenT<std::vector<double>> hgcaltracks_y_token_;
0592   const edm::EDGetTokenT<std::vector<double>> hgcaltracks_z_token_;
0593   const edm::EDGetTokenT<std::vector<double>> hgcaltracks_eta_token_;
0594   const edm::EDGetTokenT<std::vector<double>> hgcaltracks_phi_token_;
0595   const edm::EDGetTokenT<std::vector<double>> hgcaltracks_px_token_;
0596   const edm::EDGetTokenT<std::vector<double>> hgcaltracks_py_token_;
0597   const edm::EDGetTokenT<std::vector<double>> hgcaltracks_pz_token_;
0598   const edm::EDGetTokenT<std::vector<reco::Muon>> muons_token_;
0599   const edm::EDGetTokenT<edm::ValueMap<std::pair<float, float>>> clustersTime_token_;
0600   const edm::EDGetTokenT<std::vector<int>> tracksterSeeds_token_;
0601   edm::EDGetTokenT<std::vector<std::vector<unsigned int>>> superclustering_linkedResultTracksters_token;
0602   edm::EDGetTokenT<reco::SuperClusterCollection> recoSuperClusters_token;
0603   edm::EDGetTokenT<reco::CaloClusterCollection> recoSuperClusters_caloClusters_token;
0604   edm::EDGetTokenT<std::vector<ticl::Trackster>> recoSuperClusters_sourceTracksters_token;
0605   edm::ESGetToken<CaloGeometry, CaloGeometryRecord> caloGeometry_token_;
0606   const edm::EDGetTokenT<std::vector<ticl::Trackster>> simTracksters_SC_token_;  // needed for simticlcandidate
0607   const edm::EDGetTokenT<std::vector<TICLCandidate>> simTICLCandidate_token_;
0608 
0609   // associators
0610   const std::vector<edm::ParameterSet>
0611       associations_parameterSets_;  ///< A parameter set for each associator collection to dump (with treeName, etc)
0612   std::vector<edm::EDGetTokenT<TracksterToTracksterMap>>
0613       associations_simToReco_token_;  ///< The tokens for each assocation
0614   std::vector<edm::EDGetTokenT<TracksterToTracksterMap>> associations_recoToSim_token_;
0615   std::vector<TracksterToSimTracksterAssociationHelper>
0616       associations_dumperHelpers_;  ///< the dumper helpers for each association map to dump
0617 
0618   TTree* associations_tree_;
0619 
0620   const edm::EDGetTokenT<std::vector<SimCluster>> simclusters_token_;
0621   const edm::EDGetTokenT<std::vector<CaloParticle>> caloparticles_token_;
0622 
0623   const edm::ESGetToken<CaloGeometry, CaloGeometryRecord> geometry_token_;
0624   const std::string detector_;
0625   const std::string propName_;
0626   const edm::ESGetToken<MagneticField, IdealMagneticFieldRecord> bfield_token_;
0627   const edm::ESGetToken<Propagator, TrackingComponentsRecord> propagator_token_;
0628   edm::ESGetToken<HGCalDDDConstants, IdealGeometryRecord> hdc_token_;
0629   std::unique_ptr<DetectorTools> detectorTools_;
0630   bool saveLCs_;
0631   bool saveSuperclustering_;
0632   bool saveSuperclusteringDNNScore_;
0633   bool saveRecoSuperclusters_;
0634   bool saveTICLCandidate_;
0635   bool saveSimTICLCandidate_;
0636   bool saveTracks_;
0637 
0638   // Output tree
0639   TTree* tree_;
0640 
0641   void clearVariables();
0642 
0643   // Variables for branches
0644   edm::EventID eventId_;
0645   unsigned int nclusters_;
0646 
0647   std::vector<std::vector<unsigned int>>
0648       superclustering_linkedResultTracksters;  // Map of indices from superclusteredTracksters collection back into ticlTrackstersCLUE3DEM collection
0649   // reco::SuperCluster dump
0650   std::vector<double> recoSuperCluster_rawEnergy;
0651   std::vector<double> recoSuperCluster_energy;
0652   std::vector<double> recoSuperCluster_correctedEnergy;
0653   std::vector<double> recoSuperCluster_position_x;
0654   std::vector<double> recoSuperCluster_position_y;
0655   std::vector<double> recoSuperCluster_position_z;
0656   std::vector<double> recoSuperCluster_position_eta;
0657   std::vector<double> recoSuperCluster_position_phi;
0658   std::vector<uint32_t>
0659       recoSuperCluster_seedTs;  ///< Index to seed trackster (into the trackster collection used to make superclusters, given by config recoSuperClusters_sourceTracksterCollection)
0660   std::vector<std::vector<uint32_t>>
0661       recoSuperCluster_constituentTs;  ///< Indices to all tracksters inside the supercluster (same)
0662 
0663   std::vector<float> simTICLCandidate_raw_energy;
0664   std::vector<float> simTICLCandidate_regressed_energy;
0665   std::vector<std::vector<int>> simTICLCandidate_simTracksterCPIndex;
0666   std::vector<float> simTICLCandidate_boundaryX;
0667   std::vector<float> simTICLCandidate_boundaryY;
0668   std::vector<float> simTICLCandidate_boundaryZ;
0669   std::vector<float> simTICLCandidate_boundaryPx;
0670   std::vector<float> simTICLCandidate_boundaryPy;
0671   std::vector<float> simTICLCandidate_boundaryPz;
0672   std::vector<float> simTICLCandidate_pt;
0673   std::vector<float> simTICLCandidate_phi;
0674   std::vector<float> simTICLCandidate_eta;
0675   std::vector<float> simTICLCandidate_caloParticleMass;
0676   std::vector<float> simTICLCandidate_time;
0677   std::vector<int> simTICLCandidate_pdgId;
0678   std::vector<int> simTICLCandidate_charge;
0679   std::vector<int> simTICLCandidate_track_in_candidate;
0680 
0681   // from TICLCandidate, product of linking
0682   size_t nCandidates;
0683   std::vector<int> candidate_charge;
0684   std::vector<int> candidate_pdgId;
0685   std::vector<float> candidate_energy;
0686   std::vector<float> candidate_raw_energy;
0687   std::vector<double> candidate_px;
0688   std::vector<double> candidate_py;
0689   std::vector<double> candidate_pz;
0690   std::vector<float> candidate_pt;
0691   std::vector<float> candidate_phi;
0692   std::vector<float> candidate_eta;
0693   std::vector<float> candidate_time;
0694   std::vector<float> candidate_time_err;
0695   std::vector<std::vector<float>> candidate_id_probabilities;
0696   std::vector<std::vector<uint32_t>> tracksters_in_candidate;
0697   std::vector<int> track_in_candidate;
0698 
0699   // Layer clusters
0700   std::vector<uint32_t> cluster_seedID;
0701   std::vector<float> cluster_energy;
0702   std::vector<float> cluster_correctedEnergy;
0703   std::vector<float> cluster_correctedEnergyUncertainty;
0704   std::vector<float> cluster_position_x;
0705   std::vector<float> cluster_position_y;
0706   std::vector<float> cluster_position_z;
0707   std::vector<float> cluster_position_eta;
0708   std::vector<float> cluster_position_phi;
0709   std::vector<unsigned int> cluster_layer_id;
0710   std::vector<int> cluster_type;
0711   std::vector<float> cluster_time;
0712   std::vector<float> cluster_timeErr;
0713   std::vector<uint32_t> cluster_number_of_hits;
0714 
0715   // Tracks
0716   std::vector<unsigned int> track_id;
0717   std::vector<float> track_hgcal_x;
0718   std::vector<float> track_hgcal_y;
0719   std::vector<float> track_hgcal_z;
0720   std::vector<float> track_hgcal_px;
0721   std::vector<float> track_hgcal_py;
0722   std::vector<float> track_hgcal_pz;
0723   std::vector<float> track_hgcal_eta;
0724   std::vector<float> track_hgcal_phi;
0725   std::vector<float> track_hgcal_pt;
0726   std::vector<float> track_pt;
0727   std::vector<float> track_p;
0728   std::vector<int> track_quality;
0729   std::vector<int> track_missing_outer_hits;
0730   std::vector<int> track_missing_inner_hits;
0731   std::vector<int> track_charge;
0732   std::vector<double> track_time;
0733   std::vector<float> track_time_quality;
0734   std::vector<float> track_time_err;
0735   std::vector<float> track_beta;
0736   std::vector<float> track_time_mtd;
0737   std::vector<float> track_time_mtd_err;
0738   std::vector<GlobalPoint> track_pos_mtd;
0739   std::vector<int> track_nhits;
0740   std::vector<int> track_isMuon;
0741   std::vector<int> track_isTrackerMuon;
0742 
0743   TTree* cluster_tree_;
0744   TTree* candidate_tree_;
0745   TTree* superclustering_tree_;
0746   TTree* tracks_tree_;
0747   TTree* simTICLCandidate_tree;
0748 };
0749 
0750 void TICLDumper::clearVariables() {
0751   // event info
0752   nclusters_ = 0;
0753 
0754   for (TracksterDumperHelper& tsDumper : tracksters_dumperHelpers_) {
0755     tsDumper.clearVariables();
0756   }
0757 
0758   superclustering_linkedResultTracksters.clear();
0759 
0760   recoSuperCluster_rawEnergy.clear();
0761   recoSuperCluster_energy.clear();
0762   recoSuperCluster_correctedEnergy.clear();
0763   recoSuperCluster_position_x.clear();
0764   recoSuperCluster_position_y.clear();
0765   recoSuperCluster_position_z.clear();
0766   recoSuperCluster_position_eta.clear();
0767   recoSuperCluster_position_phi.clear();
0768   recoSuperCluster_seedTs.clear();
0769   recoSuperCluster_constituentTs.clear();
0770 
0771   simTICLCandidate_raw_energy.clear();
0772   simTICLCandidate_regressed_energy.clear();
0773   simTICLCandidate_simTracksterCPIndex.clear();
0774   simTICLCandidate_boundaryX.clear();
0775   simTICLCandidate_boundaryY.clear();
0776   simTICLCandidate_boundaryZ.clear();
0777   simTICLCandidate_boundaryPx.clear();
0778   simTICLCandidate_boundaryPy.clear();
0779   simTICLCandidate_boundaryPz.clear();
0780   simTICLCandidate_pt.clear();
0781   simTICLCandidate_phi.clear();
0782   simTICLCandidate_eta.clear();
0783   simTICLCandidate_time.clear();
0784   simTICLCandidate_caloParticleMass.clear();
0785   simTICLCandidate_pdgId.clear();
0786   simTICLCandidate_charge.clear();
0787   simTICLCandidate_track_in_candidate.clear();
0788 
0789   nCandidates = 0;
0790   candidate_charge.clear();
0791   candidate_pdgId.clear();
0792   candidate_energy.clear();
0793   candidate_raw_energy.clear();
0794   candidate_px.clear();
0795   candidate_py.clear();
0796   candidate_pz.clear();
0797   candidate_pt.clear();
0798   candidate_phi.clear();
0799   candidate_eta.clear();
0800   candidate_time.clear();
0801   candidate_time_err.clear();
0802   candidate_id_probabilities.clear();
0803   tracksters_in_candidate.clear();
0804   track_in_candidate.clear();
0805 
0806   for (auto& helper : associations_dumperHelpers_) {
0807     helper.clearVariables();
0808   }
0809 
0810   cluster_seedID.clear();
0811   cluster_energy.clear();
0812   cluster_correctedEnergy.clear();
0813   cluster_correctedEnergyUncertainty.clear();
0814   cluster_position_x.clear();
0815   cluster_position_y.clear();
0816   cluster_position_z.clear();
0817   cluster_position_eta.clear();
0818   cluster_position_phi.clear();
0819   cluster_layer_id.clear();
0820   cluster_type.clear();
0821   cluster_time.clear();
0822   cluster_timeErr.clear();
0823   cluster_number_of_hits.clear();
0824 
0825   track_id.clear();
0826   track_hgcal_x.clear();
0827   track_hgcal_y.clear();
0828   track_hgcal_z.clear();
0829   track_hgcal_eta.clear();
0830   track_hgcal_phi.clear();
0831   track_hgcal_px.clear();
0832   track_hgcal_py.clear();
0833   track_hgcal_pz.clear();
0834   track_hgcal_pt.clear();
0835   track_quality.clear();
0836   track_pt.clear();
0837   track_p.clear();
0838   track_missing_outer_hits.clear();
0839   track_missing_inner_hits.clear();
0840   track_charge.clear();
0841   track_time.clear();
0842   track_time_quality.clear();
0843   track_time_err.clear();
0844   track_beta.clear();
0845   track_time_mtd.clear();
0846   track_time_mtd_err.clear();
0847   track_pos_mtd.clear();
0848   track_nhits.clear();
0849   track_isMuon.clear();
0850   track_isTrackerMuon.clear();
0851 };
0852 
0853 TICLDumper::TICLDumper(const edm::ParameterSet& ps)
0854     : tracksters_parameterSets_(ps.getParameter<std::vector<edm::ParameterSet>>("tracksterCollections")),
0855       tracksters_token_(),
0856       tracksters_in_candidate_token_(
0857           consumes<std::vector<ticl::Trackster>>(ps.getParameter<edm::InputTag>("trackstersInCand"))),
0858       layer_clusters_token_(consumes<std::vector<reco::CaloCluster>>(ps.getParameter<edm::InputTag>("layerClusters"))),
0859       ticl_candidates_token_(consumes<std::vector<TICLCandidate>>(ps.getParameter<edm::InputTag>("ticlcandidates"))),
0860       ticl_candidates_tracksters_token_(
0861           consumes<std::vector<ticl::Trackster>>(ps.getParameter<edm::InputTag>("ticlcandidates"))),
0862       tracks_token_(consumes<std::vector<reco::Track>>(ps.getParameter<edm::InputTag>("tracks"))),
0863       tracks_time_token_(consumes<edm::ValueMap<float>>(ps.getParameter<edm::InputTag>("tracksTime"))),
0864       tracks_time_quality_token_(consumes<edm::ValueMap<float>>(ps.getParameter<edm::InputTag>("tracksTimeQual"))),
0865       tracks_time_err_token_(consumes<edm::ValueMap<float>>(ps.getParameter<edm::InputTag>("tracksTimeErr"))),
0866       tracks_beta_token_(consumes<edm::ValueMap<float>>(ps.getParameter<edm::InputTag>("tracksBeta"))),
0867       tracks_time_mtd_token_(consumes<edm::ValueMap<float>>(ps.getParameter<edm::InputTag>("tracksTimeMtd"))),
0868       tracks_time_mtd_err_token_(consumes<edm::ValueMap<float>>(ps.getParameter<edm::InputTag>("tracksTimeMtdErr"))),
0869       tracks_pos_mtd_token_(consumes<edm::ValueMap<GlobalPoint>>(ps.getParameter<edm::InputTag>("tracksPosMtd"))),
0870       muons_token_(consumes<std::vector<reco::Muon>>(ps.getParameter<edm::InputTag>("muons"))),
0871       clustersTime_token_(
0872           consumes<edm::ValueMap<std::pair<float, float>>>(ps.getParameter<edm::InputTag>("layer_clustersTime"))),
0873       superclustering_linkedResultTracksters_token(
0874           consumes<std::vector<std::vector<unsigned int>>>(ps.getParameter<edm::InputTag>("superclustering"))),
0875       recoSuperClusters_token(
0876           consumes<reco::SuperClusterCollection>(ps.getParameter<edm::InputTag>("recoSuperClusters"))),
0877       recoSuperClusters_caloClusters_token(
0878           consumes<reco::CaloClusterCollection>(ps.getParameter<edm::InputTag>("recoSuperClusters"))),
0879       recoSuperClusters_sourceTracksters_token(consumes<std::vector<ticl::Trackster>>(
0880           ps.getParameter<edm::InputTag>("recoSuperClusters_sourceTracksterCollection"))),
0881       caloGeometry_token_(esConsumes<CaloGeometry, CaloGeometryRecord, edm::Transition::BeginRun>()),
0882       simTracksters_SC_token_(
0883           consumes<std::vector<ticl::Trackster>>(ps.getParameter<edm::InputTag>("simtrackstersSC"))),
0884       simTICLCandidate_token_(
0885           consumes<std::vector<TICLCandidate>>(ps.getParameter<edm::InputTag>("simTICLCandidates"))),
0886       associations_parameterSets_(ps.getParameter<std::vector<edm::ParameterSet>>("associators")),
0887       // The DumperHelpers should not be moved after construction (needed by TTree branch pointers), so construct them all here
0888       associations_dumperHelpers_(associations_parameterSets_.size()),
0889       simclusters_token_(consumes(ps.getParameter<edm::InputTag>("simclusters"))),
0890       caloparticles_token_(consumes(ps.getParameter<edm::InputTag>("caloparticles"))),
0891       geometry_token_(esConsumes<CaloGeometry, CaloGeometryRecord, edm::Transition::BeginRun>()),
0892       detector_(ps.getParameter<std::string>("detector")),
0893       propName_(ps.getParameter<std::string>("propagator")),
0894       bfield_token_(esConsumes<MagneticField, IdealMagneticFieldRecord, edm::Transition::BeginRun>()),
0895       propagator_token_(
0896           esConsumes<Propagator, TrackingComponentsRecord, edm::Transition::BeginRun>(edm::ESInputTag("", propName_))),
0897       saveLCs_(ps.getParameter<bool>("saveLCs")),
0898       saveSuperclustering_(ps.getParameter<bool>("saveSuperclustering")),
0899       //saveSuperclusteringDNNScore_(ps.getParameter<bool>("saveSuperclusteringDNNScore")),
0900       saveRecoSuperclusters_(ps.getParameter<bool>("saveRecoSuperclusters")),
0901       saveTICLCandidate_(ps.getParameter<bool>("saveSimTICLCandidate")),
0902       saveSimTICLCandidate_(ps.getParameter<bool>("saveSimTICLCandidate")),
0903       saveTracks_(ps.getParameter<bool>("saveTracks")) {
0904   if (saveSuperclustering_) {
0905     superclustering_linkedResultTracksters_token =
0906         consumes<std::vector<std::vector<unsigned int>>>(ps.getParameter<edm::InputTag>("superclustering"));
0907     recoSuperClusters_token =
0908         consumes<reco::SuperClusterCollection>(ps.getParameter<edm::InputTag>("recoSuperClusters"));
0909     recoSuperClusters_caloClusters_token =
0910         consumes<reco::CaloClusterCollection>(ps.getParameter<edm::InputTag>("recoSuperClusters"));
0911     recoSuperClusters_sourceTracksters_token = consumes<std::vector<ticl::Trackster>>(
0912         ps.getParameter<edm::InputTag>("recoSuperClusters_sourceTracksterCollection"));
0913   }
0914   std::string detectorName_ = (detector_ == "HFNose") ? "HGCalHFNoseSensitive" : "HGCalEESensitive";
0915   hdc_token_ =
0916       esConsumes<HGCalDDDConstants, IdealGeometryRecord, edm::Transition::BeginRun>(edm::ESInputTag("", detectorName_));
0917 
0918   for (edm::ParameterSet const& tracksterPset : tracksters_parameterSets_) {
0919     tracksters_token_.push_back(
0920         consumes<std::vector<ticl::Trackster>>(tracksterPset.getParameter<edm::InputTag>("inputTag")));
0921     tracksters_dumperHelpers_.emplace_back(
0922         TracksterDumperHelper::tracksterTypeFromString(tracksterPset.getParameter<std::string>("tracksterType")));
0923   }
0924 
0925   for (edm::ParameterSet const& associationPset : associations_parameterSets_) {
0926     associations_recoToSim_token_.push_back(consumes<TracksterToTracksterMap>(
0927         edm::InputTag(associationPset.getParameter<edm::InputTag>("associatorRecoToSimInputTag"))));
0928     associations_simToReco_token_.push_back(consumes<TracksterToTracksterMap>(
0929         edm::InputTag(associationPset.getParameter<edm::InputTag>("associatorSimToRecoInputTag"))));
0930   }
0931 };
0932 
0933 TICLDumper::~TICLDumper() { clearVariables(); };
0934 
0935 void TICLDumper::beginRun(edm::Run const&, edm::EventSetup const& es) {
0936   detectorTools_ = std::make_unique<DetectorTools>(es.getData(hdc_token_),
0937                                                    es.getData(caloGeometry_token_),
0938                                                    es.getData(bfield_token_),
0939                                                    es.getData(propagator_token_));
0940 }
0941 
0942 // Define tree and branches
0943 void TICLDumper::beginJob() {
0944   edm::Service<TFileService> fs;
0945 
0946   // Trackster trees
0947   for (unsigned int i = 0; i < tracksters_parameterSets_.size(); i++) {
0948     edm::ParameterSet const& tracksterPset = tracksters_parameterSets_[i];
0949     TTree* tree =
0950         fs->make<TTree>(tracksterPset.getParameter<std::string>("treeName").c_str(),
0951                         ("Tracksters : " + tracksterPset.getParameter<std::string>("treeName") +
0952                          " (InputTag : " + tracksterPset.getParameter<edm::InputTag>("inputTag").encode() + ")")
0953                             .c_str());
0954     tracksters_trees.push_back(tree);
0955     tracksters_dumperHelpers_[i].initTree(tree, &eventId_);
0956   }
0957   if (saveLCs_) {
0958     cluster_tree_ = fs->make<TTree>("clusters", "TICL tracksters");
0959     cluster_tree_->Branch("event", &eventId_);
0960     cluster_tree_->Branch("seedID", &cluster_seedID);
0961     cluster_tree_->Branch("energy", &cluster_energy);
0962     cluster_tree_->Branch("correctedEnergy", &cluster_correctedEnergy);
0963     cluster_tree_->Branch("correctedEnergyUncertainty", &cluster_correctedEnergyUncertainty);
0964     cluster_tree_->Branch("position_x", &cluster_position_x);
0965     cluster_tree_->Branch("position_y", &cluster_position_y);
0966     cluster_tree_->Branch("position_z", &cluster_position_z);
0967     cluster_tree_->Branch("position_eta", &cluster_position_eta);
0968     cluster_tree_->Branch("position_phi", &cluster_position_phi);
0969     cluster_tree_->Branch("cluster_layer_id", &cluster_layer_id);
0970     cluster_tree_->Branch("cluster_type", &cluster_type);
0971     cluster_tree_->Branch("cluster_time", &cluster_time);
0972     cluster_tree_->Branch("cluster_timeErr", &cluster_timeErr);
0973     cluster_tree_->Branch("cluster_number_of_hits", &cluster_number_of_hits);
0974   }
0975   if (saveTICLCandidate_) {
0976     candidate_tree_ = fs->make<TTree>("candidates", "TICL candidates");
0977     candidate_tree_->Branch("event", &eventId_);
0978     candidate_tree_->Branch("NCandidates", &nCandidates);
0979     candidate_tree_->Branch("candidate_charge", &candidate_charge);
0980     candidate_tree_->Branch("candidate_pdgId", &candidate_pdgId);
0981     candidate_tree_->Branch("candidate_id_probabilities", &candidate_id_probabilities);
0982     candidate_tree_->Branch("candidate_time", &candidate_time);
0983     candidate_tree_->Branch("candidate_timeErr", &candidate_time_err);
0984     candidate_tree_->Branch("candidate_energy", &candidate_energy);
0985     candidate_tree_->Branch("candidate_raw_energy", &candidate_raw_energy);
0986     candidate_tree_->Branch("candidate_px", &candidate_px);
0987     candidate_tree_->Branch("candidate_py", &candidate_py);
0988     candidate_tree_->Branch("candidate_pz", &candidate_pz);
0989     candidate_tree_->Branch("candidate_pt", &candidate_pt);
0990     candidate_tree_->Branch("candidate_phi", &candidate_phi);
0991     candidate_tree_->Branch("candidate_eta", &candidate_eta);
0992     candidate_tree_->Branch("track_in_candidate", &track_in_candidate);
0993     candidate_tree_->Branch("tracksters_in_candidate", &tracksters_in_candidate);
0994   }
0995   if (saveSuperclustering_ || saveRecoSuperclusters_) {
0996     superclustering_tree_ = fs->make<TTree>("superclustering", "Superclustering in HGCAL CE-E");
0997     superclustering_tree_->Branch("event", &eventId_);
0998   }
0999   if (saveSuperclustering_) {
1000     superclustering_tree_->Branch("linkedResultTracksters", &superclustering_linkedResultTracksters);
1001   }
1002   if (saveRecoSuperclusters_) {
1003     superclustering_tree_->Branch("recoSuperCluster_rawEnergy", &recoSuperCluster_rawEnergy);
1004     superclustering_tree_->Branch("recoSuperCluster_energy", &recoSuperCluster_energy);
1005     superclustering_tree_->Branch("recoSuperCluster_correctedEnergy", &recoSuperCluster_correctedEnergy);
1006     superclustering_tree_->Branch("recoSuperCluster_position_x", &recoSuperCluster_position_x);
1007     superclustering_tree_->Branch("recoSuperCluster_position_y", &recoSuperCluster_position_y);
1008     superclustering_tree_->Branch("recoSuperCluster_position_z", &recoSuperCluster_position_z);
1009     superclustering_tree_->Branch("recoSuperCluster_position_eta", &recoSuperCluster_position_eta);
1010     superclustering_tree_->Branch("recoSuperCluster_position_phi", &recoSuperCluster_position_phi);
1011     superclustering_tree_->Branch("recoSuperCluster_seedTs", &recoSuperCluster_seedTs);
1012     superclustering_tree_->Branch("recoSuperCluster_constituentTs", &recoSuperCluster_constituentTs);
1013   }
1014 
1015   if (!associations_parameterSets_.empty()) {
1016     associations_tree_ = fs->make<TTree>("associations", "Associations");
1017     associations_tree_->Branch("event", &eventId_);
1018   }
1019   for (unsigned int i = 0; i < associations_parameterSets_.size(); i++) {
1020     associations_dumperHelpers_[i].initTree(associations_tree_,
1021                                             associations_parameterSets_[i].getParameter<std::string>("branchName"),
1022                                             associations_parameterSets_[i].getParameter<std::string>("suffix"));
1023   }
1024 
1025   if (saveTracks_) {
1026     tracks_tree_ = fs->make<TTree>("tracks", "Tracks");
1027     tracks_tree_->Branch("event", &eventId_);
1028     tracks_tree_->Branch("track_id", &track_id);
1029     tracks_tree_->Branch("track_hgcal_x", &track_hgcal_x);
1030     tracks_tree_->Branch("track_hgcal_y", &track_hgcal_y);
1031     tracks_tree_->Branch("track_hgcal_z", &track_hgcal_z);
1032     tracks_tree_->Branch("track_hgcal_eta", &track_hgcal_eta);
1033     tracks_tree_->Branch("track_hgcal_phi", &track_hgcal_phi);
1034     tracks_tree_->Branch("track_hgcal_pt", &track_hgcal_pt);
1035     tracks_tree_->Branch("track_pt", &track_pt);
1036     tracks_tree_->Branch("track_p", &track_p);
1037     tracks_tree_->Branch("track_missing_outer_hits", &track_missing_outer_hits);
1038     tracks_tree_->Branch("track_missing_inner_hits", &track_missing_inner_hits);
1039     tracks_tree_->Branch("track_quality", &track_quality);
1040     tracks_tree_->Branch("track_charge", &track_charge);
1041     tracks_tree_->Branch("track_time", &track_time);
1042     tracks_tree_->Branch("track_time_quality", &track_time_quality);
1043     tracks_tree_->Branch("track_time_err", &track_time_err);
1044     tracks_tree_->Branch("track_beta", &track_beta);
1045     tracks_tree_->Branch("track_time_mtd", &track_time_mtd);
1046     tracks_tree_->Branch("track_time_mtd_err", &track_time_mtd_err);
1047     tracks_tree_->Branch("track_pos_mtd", &track_pos_mtd);
1048     tracks_tree_->Branch("track_nhits", &track_nhits);
1049     tracks_tree_->Branch("track_isMuon", &track_isMuon);
1050     tracks_tree_->Branch("track_isTrackerMuon", &track_isTrackerMuon);
1051   }
1052 
1053   if (saveSimTICLCandidate_) {
1054     simTICLCandidate_tree = fs->make<TTree>("simTICLCandidate", "Sim TICL Candidate");
1055     simTICLCandidate_tree->Branch("event", &eventId_);
1056     simTICLCandidate_tree->Branch("simTICLCandidate_raw_energy", &simTICLCandidate_raw_energy);
1057     simTICLCandidate_tree->Branch("simTICLCandidate_regressed_energy", &simTICLCandidate_regressed_energy);
1058     simTICLCandidate_tree->Branch("simTICLCandidate_simTracksterCPIndex", &simTICLCandidate_simTracksterCPIndex);
1059     simTICLCandidate_tree->Branch("simTICLCandidate_boundaryX", &simTICLCandidate_boundaryX);
1060     simTICLCandidate_tree->Branch("simTICLCandidate_boundaryY", &simTICLCandidate_boundaryY);
1061     simTICLCandidate_tree->Branch("simTICLCandidate_boundaryZ", &simTICLCandidate_boundaryZ);
1062     simTICLCandidate_tree->Branch("simTICLCandidate_boundaryPx", &simTICLCandidate_boundaryPx);
1063     simTICLCandidate_tree->Branch("simTICLCandidate_boundaryPy", &simTICLCandidate_boundaryPy);
1064     simTICLCandidate_tree->Branch("simTICLCandidate_boundaryPz", &simTICLCandidate_boundaryPz);
1065     simTICLCandidate_tree->Branch("simTICLCandidate_pt", &simTICLCandidate_pt);
1066     simTICLCandidate_tree->Branch("simTICLCandidate_phi", &simTICLCandidate_phi);
1067     simTICLCandidate_tree->Branch("simTICLCandidate_eta", &simTICLCandidate_eta);
1068     simTICLCandidate_tree->Branch("simTICLCandidate_time", &simTICLCandidate_time);
1069     simTICLCandidate_tree->Branch("simTICLCandidate_caloParticleMass", &simTICLCandidate_caloParticleMass);
1070     simTICLCandidate_tree->Branch("simTICLCandidate_pdgId", &simTICLCandidate_pdgId);
1071     simTICLCandidate_tree->Branch("simTICLCandidate_charge", &simTICLCandidate_charge);
1072     simTICLCandidate_tree->Branch("simTICLCandidate_track_in_candidate", &simTICLCandidate_track_in_candidate);
1073   }
1074 }
1075 
1076 void TICLDumper::analyze(const edm::Event& event, const edm::EventSetup& setup) {
1077   eventId_ = event.id();
1078   clearVariables();
1079 
1080   edm::Handle<std::vector<ticl::Trackster>> tracksters_in_candidate_handle;
1081   event.getByToken(tracksters_in_candidate_token_, tracksters_in_candidate_handle);
1082 
1083   //get all the layer clusters
1084   edm::Handle<std::vector<reco::CaloCluster>> layer_clusters_h;
1085   event.getByToken(layer_clusters_token_, layer_clusters_h);
1086   const auto& clusters = *layer_clusters_h;
1087 
1088   edm::Handle<edm::ValueMap<std::pair<float, float>>> clustersTime_h;
1089   event.getByToken(clustersTime_token_, clustersTime_h);
1090   const auto& layerClustersTimes = *clustersTime_h;
1091 
1092   //TICL Candidate
1093   edm::Handle<std::vector<TICLCandidate>> candidates_h;
1094   event.getByToken(ticl_candidates_token_, candidates_h);
1095   const auto& ticlcandidates = *candidates_h;
1096   edm::Handle<std::vector<ticl::Trackster>> ticlcandidates_tracksters_h =
1097       event.getHandle(ticl_candidates_tracksters_token_);
1098 
1099   //Track
1100   edm::Handle<std::vector<reco::Track>> tracks_h;
1101   event.getByToken(tracks_token_, tracks_h);
1102   const auto& tracks = *tracks_h;
1103 
1104   edm::Handle<edm::ValueMap<float>> trackTime_h;
1105   event.getByToken(tracks_time_token_, trackTime_h);
1106   const auto& trackTime = *trackTime_h;
1107 
1108   edm::Handle<edm::ValueMap<float>> trackTimeErr_h;
1109   event.getByToken(tracks_time_err_token_, trackTimeErr_h);
1110   const auto& trackTimeErr = *trackTimeErr_h;
1111 
1112   edm::Handle<edm::ValueMap<float>> trackBeta_h;
1113   event.getByToken(tracks_beta_token_, trackBeta_h);
1114   const auto& trackBeta = *trackBeta_h;
1115 
1116   edm::Handle<edm::ValueMap<float>> trackTimeQual_h;
1117   event.getByToken(tracks_time_quality_token_, trackTimeQual_h);
1118   const auto& trackTimeQual = *trackTimeQual_h;
1119 
1120   edm::Handle<edm::ValueMap<float>> trackTimeMtd_h;
1121   event.getByToken(tracks_time_mtd_token_, trackTimeMtd_h);
1122   const auto& trackTimeMtd = *trackTimeMtd_h;
1123 
1124   edm::Handle<edm::ValueMap<float>> trackTimeMtdErr_h;
1125   event.getByToken(tracks_time_mtd_err_token_, trackTimeMtdErr_h);
1126   const auto& trackTimeMtdErr = *trackTimeMtdErr_h;
1127 
1128   edm::Handle<edm::ValueMap<GlobalPoint>> trackPosMtd_h;
1129   event.getByToken(tracks_pos_mtd_token_, trackPosMtd_h);
1130   const auto& trackPosMtd = *trackPosMtd_h;
1131 
1132   // superclustering
1133   if (saveSuperclustering_)  // To support running with Mustache
1134     superclustering_linkedResultTracksters = event.get(superclustering_linkedResultTracksters_token);
1135 
1136   // muons
1137   edm::Handle<std::vector<reco::Muon>> muons_h;
1138   event.getByToken(muons_token_, muons_h);
1139   auto& muons = *muons_h;
1140 
1141   // recoSuperClusters
1142   if (saveRecoSuperclusters_) {
1143     reco::SuperClusterCollection const& recoSuperClusters = event.get(recoSuperClusters_token);
1144     // reco::CaloClusterCollection const& recoCaloClusters = event.get(recoSuperClusters_caloClusters_token);
1145     std::vector<ticl::Trackster> const& recoSuperClusters_sourceTracksters =
1146         event.get(recoSuperClusters_sourceTracksters_token);
1147 
1148     // Map for fast lookup of hit to trackster index in recoSuperClusters_sourceTracksters
1149     std::unordered_map<DetId, unsigned> hitToTracksterMap;
1150 
1151     for (unsigned ts_id = 0; ts_id < recoSuperClusters_sourceTracksters.size(); ts_id++) {
1152       for (unsigned int lc_index : recoSuperClusters_sourceTracksters[ts_id].vertices()) {
1153         for (auto [detId, fraction] : clusters[lc_index].hitsAndFractions()) {
1154           bool insertionSucceeded = hitToTracksterMap.emplace(detId, ts_id).second;
1155           assert(insertionSucceeded && "TICLDumper found tracksters sharing rechits");
1156         }
1157       }
1158     }
1159 
1160     for (auto const& recoSc : recoSuperClusters) {
1161       recoSuperCluster_rawEnergy.push_back(recoSc.rawEnergy());
1162       recoSuperCluster_energy.push_back(recoSc.energy());
1163       recoSuperCluster_correctedEnergy.push_back(recoSc.correctedEnergy());
1164       recoSuperCluster_position_x.push_back(recoSc.position().x());
1165       recoSuperCluster_position_y.push_back(recoSc.position().y());
1166       recoSuperCluster_position_z.push_back(recoSc.position().z());
1167       recoSuperCluster_position_eta.push_back(recoSc.position().eta());
1168       recoSuperCluster_position_phi.push_back(recoSc.position().phi());
1169 
1170       // Finding the trackster that was used to create the CaloCluster, using the DetId of a hit (we assume there is no sharing of rechits between tracksters)
1171 
1172       // Seed trackster of the supercluster : Using the DetId of the seed rechit of the seed CaloCluster
1173       recoSuperCluster_seedTs.push_back(hitToTracksterMap.at(recoSc.seed()->seed()));
1174       recoSuperCluster_constituentTs.emplace_back();
1175       for (edm::Ptr<reco::CaloCluster> const& caloClusterPtr : recoSc.clusters()) {
1176         // Using the DetId of the seed rechit of the CaloCluster
1177         recoSuperCluster_constituentTs.back().push_back(hitToTracksterMap.at(caloClusterPtr->seed()));
1178       }
1179     }
1180   }
1181 
1182   edm::Handle<std::vector<TICLCandidate>> simTICLCandidates_h;
1183   event.getByToken(simTICLCandidate_token_, simTICLCandidates_h);
1184   const auto& simTICLCandidates = *simTICLCandidates_h;
1185 
1186   edm::Handle<std::vector<CaloParticle>> caloparticles_h;
1187   event.getByToken(caloparticles_token_, caloparticles_h);
1188 
1189   auto simclusters_h = event.getHandle(simclusters_token_);
1190 
1191   nclusters_ = clusters.size();
1192 
1193   // Save all the trackster collections
1194   for (unsigned int i = 0; i < tracksters_dumperHelpers_.size(); i++) {
1195     edm::Handle<std::vector<ticl::Trackster>> tracksters_handle;
1196     std::vector<ticl::Trackster> const& tracksters = event.get<std::vector<ticl::Trackster>>(tracksters_token_[i]);
1197     tracksters_dumperHelpers_[i].fillFromEvent(
1198         tracksters, clusters, layerClustersTimes, *detectorTools_, simclusters_h, caloparticles_h, tracks);
1199     tracksters_trees[i]->Fill();
1200   }
1201 
1202   const auto& simTrackstersSC_h = event.getHandle(simTracksters_SC_token_);
1203   simTICLCandidate_track_in_candidate.resize(simTICLCandidates.size(), -1);
1204   for (size_t i = 0; i < simTICLCandidates.size(); ++i) {
1205     auto const& cand = simTICLCandidates[i];
1206 
1207     simTICLCandidate_raw_energy.push_back(cand.rawEnergy());
1208     simTICLCandidate_regressed_energy.push_back(cand.p4().energy());
1209     simTICLCandidate_pdgId.push_back(cand.pdgId());
1210     simTICLCandidate_charge.push_back(cand.charge());
1211     simTICLCandidate_time.push_back(cand.time());
1212     simTICLCandidate_pt.push_back(cand.pt());
1213     simTICLCandidate_phi.push_back(cand.phi());
1214     simTICLCandidate_eta.push_back(cand.eta());
1215     std::vector<int> tmpIdxVec;
1216     for (auto const& simTS : cand.tracksters()) {
1217       auto trackster_idx = simTS.get() - (edm::Ptr<ticl::Trackster>(simTrackstersSC_h, 0)).get();
1218       tmpIdxVec.push_back(trackster_idx);
1219     }
1220     simTICLCandidate_simTracksterCPIndex.push_back(tmpIdxVec);
1221     tmpIdxVec.clear();
1222     auto const& trackPtr = cand.trackPtr();
1223     if (!trackPtr.isNull()) {
1224       auto const& track = *trackPtr;
1225       int iSide = int(track.eta() > 0);
1226       int tk_idx = trackPtr.get() - (edm::Ptr<reco::Track>(tracks_h, 0)).get();
1227       simTICLCandidate_track_in_candidate[i] = tk_idx;
1228 
1229       const auto& fts = trajectoryStateTransform::outerFreeState((track), &detectorTools_->bfield);
1230       // to the HGCal front
1231       const auto& tsos = detectorTools_->propagator.propagate(fts, detectorTools_->firstDisk_[iSide]->surface());
1232       if (tsos.isValid()) {
1233         const auto& globalPos = tsos.globalPosition();
1234         const auto& globalMom = tsos.globalMomentum();
1235         simTICLCandidate_boundaryX.push_back(globalPos.x());
1236         simTICLCandidate_boundaryY.push_back(globalPos.y());
1237         simTICLCandidate_boundaryZ.push_back(globalPos.z());
1238         simTICLCandidate_boundaryPx.push_back(globalMom.x());
1239         simTICLCandidate_boundaryPy.push_back(globalMom.y());
1240         simTICLCandidate_boundaryPz.push_back(globalMom.z());
1241       } else {
1242         simTICLCandidate_boundaryX.push_back(-999);
1243         simTICLCandidate_boundaryY.push_back(-999);
1244         simTICLCandidate_boundaryZ.push_back(-999);
1245         simTICLCandidate_boundaryPx.push_back(-999);
1246         simTICLCandidate_boundaryPy.push_back(-999);
1247         simTICLCandidate_boundaryPz.push_back(-999);
1248       }
1249     } else {
1250       simTICLCandidate_boundaryX.push_back(-999);
1251       simTICLCandidate_boundaryY.push_back(-999);
1252       simTICLCandidate_boundaryZ.push_back(-999);
1253       simTICLCandidate_boundaryPx.push_back(-999);
1254       simTICLCandidate_boundaryPy.push_back(-999);
1255       simTICLCandidate_boundaryPz.push_back(-999);
1256     }
1257   }
1258 
1259   int c_id = 0;
1260 
1261   for (auto cluster_iterator = clusters.begin(); cluster_iterator != clusters.end(); ++cluster_iterator) {
1262     auto lc_seed = cluster_iterator->seed();
1263     cluster_seedID.push_back(lc_seed);
1264     cluster_energy.push_back(cluster_iterator->energy());
1265     cluster_correctedEnergy.push_back(cluster_iterator->correctedEnergy());
1266     cluster_correctedEnergyUncertainty.push_back(cluster_iterator->correctedEnergyUncertainty());
1267     cluster_position_x.push_back(cluster_iterator->x());
1268     cluster_position_y.push_back(cluster_iterator->y());
1269     cluster_position_z.push_back(cluster_iterator->z());
1270     cluster_position_eta.push_back(cluster_iterator->eta());
1271     cluster_position_phi.push_back(cluster_iterator->phi());
1272     auto haf = cluster_iterator->hitsAndFractions();
1273     auto layerId = detectorTools_->rhtools.getLayerWithOffset(haf[0].first);
1274     cluster_layer_id.push_back(layerId);
1275     uint32_t number_of_hits = cluster_iterator->hitsAndFractions().size();
1276     cluster_number_of_hits.push_back(number_of_hits);
1277     cluster_type.push_back(detectorTools_->rhtools.getCellType(lc_seed));
1278     cluster_timeErr.push_back(layerClustersTimes.get(c_id).second);
1279     cluster_time.push_back(layerClustersTimes.get(c_id).first);
1280     c_id += 1;
1281   }
1282 
1283   tracksters_in_candidate.resize(ticlcandidates.size());
1284   track_in_candidate.resize(ticlcandidates.size(), -1);
1285   nCandidates = ticlcandidates.size();
1286   for (int i = 0; i < static_cast<int>(ticlcandidates.size()); ++i) {
1287     const auto& candidate = ticlcandidates[i];
1288     candidate_charge.push_back(candidate.charge());
1289     candidate_pdgId.push_back(candidate.pdgId());
1290     candidate_energy.push_back(candidate.energy());
1291     candidate_raw_energy.push_back(candidate.rawEnergy());
1292     candidate_px.push_back(candidate.px());
1293     candidate_py.push_back(candidate.py());
1294     candidate_pz.push_back(candidate.pz());
1295     candidate_pt.push_back(candidate.pt());
1296     candidate_phi.push_back(candidate.phi());
1297     candidate_eta.push_back(candidate.eta());
1298     candidate_time.push_back(candidate.time());
1299     candidate_time_err.push_back(candidate.timeError());
1300     std::vector<float> id_probs;
1301     for (int j = 0; j < 8; j++) {
1302       ticl::Trackster::ParticleType type = static_cast<ticl::Trackster::ParticleType>(j);
1303       id_probs.push_back(candidate.id_probability(type));
1304     }
1305     candidate_id_probabilities.push_back(id_probs);
1306 
1307     auto trackster_ptrs = candidate.tracksters();
1308     auto track_ptr = candidate.trackPtr();
1309     for (const auto& ts_ptr : trackster_ptrs) {
1310       auto ts_idx = ts_ptr.get() - (edm::Ptr<ticl::Trackster>(tracksters_in_candidate_handle, 0)).get();
1311       tracksters_in_candidate[i].push_back(ts_idx);
1312     }
1313     if (track_ptr.isNull())
1314       continue;
1315     int tk_idx = track_ptr.get() - (edm::Ptr<reco::Track>(tracks_h, 0)).get();
1316     track_in_candidate[i] = tk_idx;
1317   }
1318 
1319   // trackster to simTrackster associations
1320   for (unsigned int i = 0; i < associations_dumperHelpers_.size(); i++) {
1321     associations_dumperHelpers_[i].fillFromEvent(event.get(associations_recoToSim_token_[i]),
1322                                                  event.get(associations_simToReco_token_[i]));
1323   }
1324   if (!associations_dumperHelpers_.empty())
1325     associations_tree_->Fill();
1326 
1327   //Tracks
1328   for (size_t i = 0; i < tracks.size(); i++) {
1329     const auto& track = tracks[i];
1330     reco::TrackRef trackref = reco::TrackRef(tracks_h, i);
1331     int iSide = int(track.eta() > 0);
1332     const auto& fts = trajectoryStateTransform::outerFreeState((track), &detectorTools_->bfield);
1333     // to the HGCal front
1334     const auto& tsos = detectorTools_->propagator.propagate(fts, detectorTools_->firstDisk_[iSide]->surface());
1335     if (tsos.isValid()) {
1336       const auto& globalPos = tsos.globalPosition();
1337       const auto& globalMom = tsos.globalMomentum();
1338       track_id.push_back(i);
1339       track_hgcal_x.push_back(globalPos.x());
1340       track_hgcal_y.push_back(globalPos.y());
1341       track_hgcal_z.push_back(globalPos.z());
1342       track_hgcal_eta.push_back(globalPos.eta());
1343       track_hgcal_phi.push_back(globalPos.phi());
1344       track_hgcal_px.push_back(globalMom.x());
1345       track_hgcal_py.push_back(globalMom.y());
1346       track_hgcal_pz.push_back(globalMom.z());
1347       track_hgcal_pt.push_back(globalMom.perp());
1348       track_pt.push_back(track.pt());
1349       track_p.push_back(track.p());
1350       track_quality.push_back(track.quality(reco::TrackBase::highPurity));
1351       track_missing_outer_hits.push_back(track.missingOuterHits());
1352       track_missing_inner_hits.push_back(track.missingInnerHits());
1353       track_charge.push_back(track.charge());
1354       track_time.push_back(trackTime[trackref]);
1355       track_time_quality.push_back(trackTimeQual[trackref]);
1356       track_time_err.push_back(trackTimeErr[trackref]);
1357       track_beta.push_back(trackBeta[trackref]);
1358       track_time_mtd.push_back(trackTimeMtd[trackref]);
1359       track_time_mtd_err.push_back(trackTimeMtdErr[trackref]);
1360       track_pos_mtd.push_back(trackPosMtd[trackref]);
1361       track_nhits.push_back(tracks[i].recHitsSize());
1362       int muId = PFMuonAlgo::muAssocToTrack(trackref, *muons_h);
1363       if (muId != -1) {
1364         const reco::MuonRef muonref = reco::MuonRef(muons_h, muId);
1365         track_isMuon.push_back(PFMuonAlgo::isMuon(muonref));
1366         track_isTrackerMuon.push_back(muons[muId].isTrackerMuon());
1367       } else {
1368         track_isMuon.push_back(-1);
1369         track_isTrackerMuon.push_back(-1);
1370       }
1371     }
1372   }
1373 
1374   if (saveLCs_)
1375     cluster_tree_->Fill();
1376   if (saveTICLCandidate_)
1377     candidate_tree_->Fill();
1378   if (saveSuperclustering_ || saveRecoSuperclusters_)
1379     superclustering_tree_->Fill();
1380   if (saveTracks_)
1381     tracks_tree_->Fill();
1382   if (saveSimTICLCandidate_)
1383     simTICLCandidate_tree->Fill();
1384 }
1385 
1386 void TICLDumper::endJob() {}
1387 
1388 void TICLDumper::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
1389   edm::ParameterSetDescription desc;
1390 
1391   // Settings for dumping trackster collections
1392   edm::ParameterSetDescription tracksterDescValidator;
1393   tracksterDescValidator.add<std::string>("treeName")
1394       ->setComment("Name of the output tree for the trackster collection");
1395   tracksterDescValidator.add<edm::InputTag>("inputTag")->setComment("Input tag for the trackster collection to write");
1396   tracksterDescValidator.ifValue(
1397       edm::ParameterDescription<std::string>(
1398           "tracksterType",
1399           "Trackster",
1400           true,
1401           edm::Comment("Type of trackster. Trackster=regular trackster (from RECO). SimTracksterCP=Simtrackster "
1402                        "from CaloParticle. SimTracksterSC=Simtrackster from SimCluster")),
1403       edm::allowedValues<std::string>("Trackster", "SimTracksterCP", "SimTracksterSC"));
1404   desc.addVPSet("tracksterCollections", tracksterDescValidator)->setComment("Trackster collections to dump");
1405 
1406   desc.add<edm::InputTag>("trackstersInCand", edm::InputTag("ticlTrackstersCLUE3DHigh"));
1407 
1408   desc.add<edm::InputTag>("layerClusters", edm::InputTag("hgcalMergeLayerClusters"));
1409   desc.add<edm::InputTag>("layer_clustersTime", edm::InputTag("hgcalMergeLayerClusters", "timeLayerCluster"));
1410   desc.add<edm::InputTag>("ticlcandidates", edm::InputTag("ticlTrackstersMerge"));
1411   desc.add<edm::InputTag>("tracks", edm::InputTag("generalTracks"));
1412   desc.add<edm::InputTag>("tracksTime", edm::InputTag("tofPID:t0"));
1413   desc.add<edm::InputTag>("tracksTimeQual", edm::InputTag("mtdTrackQualityMVA:mtdQualMVA"));
1414   desc.add<edm::InputTag>("tracksTimeErr", edm::InputTag("tofPID:sigmat0"));
1415   desc.add<edm::InputTag>("tracksBeta", edm::InputTag("trackExtenderWithMTD:generalTrackBeta"));
1416   desc.add<edm::InputTag>("tracksTimeMtd", edm::InputTag("trackExtenderWithMTD:generalTracktmtd"));
1417   desc.add<edm::InputTag>("tracksTimeMtdErr", edm::InputTag("trackExtenderWithMTD:generalTracksigmatmtd"));
1418   desc.add<edm::InputTag>("tracksPosMtd", edm::InputTag("trackExtenderWithMTD:generalTrackmtdpos"));
1419   desc.add<edm::InputTag>("muons", edm::InputTag("muons1stStep"));
1420   desc.add<edm::InputTag>("superclustering", edm::InputTag("ticlTracksterLinksSuperclusteringDNN"));
1421   desc.add<edm::InputTag>("recoSuperClusters", edm::InputTag("particleFlowSuperClusterHGCal"))
1422       ->setComment(
1423           "egamma supercluster collection (either from PFECALSuperClusterProducer for Mustache, or from "
1424           "TICL->Egamma converter in case of TICL DNN superclusters)");
1425   desc.add<edm::InputTag>("recoSuperClusters_sourceTracksterCollection", edm::InputTag("ticlTrackstersMerge"))
1426       ->setComment(
1427           "Trackster collection used to produce the reco::SuperCluster, used to provide a mapping back to the "
1428           "tracksters used in superclusters");
1429 
1430   desc.add<edm::InputTag>("simtrackstersSC", edm::InputTag("ticlSimTracksters"))
1431       ->setComment("SimTrackster from CaloParticle collection to use for simTICLcandidates");
1432   desc.add<edm::InputTag>("simTICLCandidates", edm::InputTag("ticlSimTracksters"));
1433 
1434   // Settings for dumping trackster associators (recoToSim & simToReco)
1435   edm::ParameterSetDescription associatorDescValidator;
1436   associatorDescValidator.add<std::string>("branchName")->setComment("Name of the output branches in the tree");
1437   associatorDescValidator.add<std::string>("suffix")->setComment("Should be CP or SC (for the output branch name)");
1438   associatorDescValidator.add<edm::InputTag>("associatorRecoToSimInputTag")
1439       ->setComment("Input tag for the RecoToSim associator to dump");
1440   associatorDescValidator.add<edm::InputTag>("associatorSimToRecoInputTag")
1441       ->setComment("Input tag for the SimToReco associator to dump");
1442   desc.addVPSet("associators", associatorDescValidator)->setComment("Tracksters to SimTracksters associators to dump");
1443 
1444   desc.add<edm::InputTag>("simclusters", edm::InputTag("mix", "MergedCaloTruth"));
1445   desc.add<edm::InputTag>("caloparticles", edm::InputTag("mix", "MergedCaloTruth"));
1446   desc.add<std::string>("detector", "HGCAL");
1447   desc.add<std::string>("propagator", "PropagatorWithMaterial");
1448 
1449   desc.add<bool>("saveLCs", true);
1450   desc.add<bool>("saveTICLCandidate", true);
1451   desc.add<bool>("saveSimTICLCandidate", true);
1452   desc.add<bool>("saveTracks", true);
1453   desc.add<bool>("saveSuperclustering", true);
1454   desc.add<bool>("saveRecoSuperclusters", true)
1455       ->setComment("Save superclustering Egamma collections (as reco::SuperCluster)");
1456   descriptions.add("ticlDumper", desc);
1457 }
1458 
1459 DEFINE_FWK_MODULE(TICLDumper);