31 static std::unique_ptr<TrackstersCache> initializeGlobalCache(
const edm::ParameterSet &);
37 void fillTile(
TICLTracksterTiles &,
const std::vector<Trackster> &, TracksterIterIndex);
39 void energyRegressionAndID(
const std::vector<reco::CaloCluster> &
layerClusters, std::vector<Trackster> &
result)
const;
40 void printTrackstersDebug(
const std::vector<Trackster> &,
const char *
label)
const;
41 void assignTimeToCandidates(std::vector<TICLCandidate> &resultCandidates)
const;
42 void dumpTrackster(
const Trackster &)
const;
81 static constexpr
int eidNFeatures_ = 3;
95 optimiseAcrossTracksters_(ps.getParameter<
bool>(
"optimiseAcrossTracksters")),
96 eta_bin_window_(ps.getParameter<
int>(
"eta_bin_window")),
97 phi_bin_window_(ps.getParameter<
int>(
"phi_bin_window")),
98 pt_sigma_high_(ps.getParameter<double>(
"pt_sigma_high")),
99 pt_sigma_low_(ps.getParameter<double>(
"pt_sigma_low")),
100 halo_max_distance2_(ps.getParameter<double>(
"halo_max_distance2")),
101 track_min_pt_(ps.getParameter<double>(
"track_min_pt")),
102 track_min_eta_(ps.getParameter<double>(
"track_min_eta")),
103 track_max_eta_(ps.getParameter<double>(
"track_max_eta")),
104 track_max_missing_outerhits_(ps.getParameter<
int>(
"track_max_missing_outerhits")),
105 cosangle_align_(ps.getParameter<double>(
"cosangle_align")),
106 e_over_h_threshold_(ps.getParameter<double>(
"e_over_h_threshold")),
107 pt_neutral_threshold_(ps.getParameter<double>(
"pt_neutral_threshold")),
108 resol_calo_offset_had_(ps.getParameter<double>(
"resol_calo_offset_had")),
109 resol_calo_scale_had_(ps.getParameter<double>(
"resol_calo_scale_had")),
110 resol_calo_offset_em_(ps.getParameter<double>(
"resol_calo_offset_em")),
111 resol_calo_scale_em_(ps.getParameter<double>(
"resol_calo_scale_em")),
112 debug_(ps.getParameter<
bool>(
"debug")),
113 eidInputName_(ps.getParameter<
std::
string>(
"eid_input_name")),
114 eidOutputNameEnergy_(ps.getParameter<
std::
string>(
"eid_output_name_energy")),
115 eidOutputNameId_(ps.getParameter<
std::
string>(
"eid_output_name_id")),
116 eidMinClusterEnergy_(ps.getParameter<double>(
"eid_min_cluster_energy")),
117 eidNLayers_(ps.getParameter<
int>(
"eid_n_layers")),
118 eidNClusters_(ps.getParameter<
int>(
"eid_n_clusters")),
119 eidSession_(nullptr) {
122 if (trackstersCache ==
nullptr || trackstersCache->
eidGraphDef ==
nullptr) {
124 <<
"TrackstersMergeProducer received an empty graph definition from the global cache";
128 produces<std::vector<Trackster>>();
129 produces<std::vector<TICLCandidate>>();
133 const std::vector<Trackster> &tracksters,
136 for (
auto const &
t : tracksters) {
137 tracksterTile.
fill(tracksterIteration,
t.barycenter().eta(),
t.barycenter().phi(), tracksterId);
138 LogDebug(
"TrackstersMergeProducer") <<
"Adding tracksterId: " << tracksterId <<
" into bin [eta,phi]: [ "
139 << tracksterTile[tracksterIteration].etaBin(
t.barycenter().eta()) <<
", "
140 << tracksterTile[tracksterIteration].
phiBin(
t.barycenter().phi())
141 <<
"] for iteration: " << tracksterIteration << std::endl;
148 auto e_over_h = (
t.raw_em_pt() / ((
t.raw_pt() -
t.raw_em_pt()) != 0. ? (
t.raw_pt() -
t.raw_em_pt()) : 1.));
150 <<
"\nTrackster raw_pt: " <<
t.raw_pt() <<
" raw_em_pt: " <<
t.raw_em_pt() <<
" eoh: " << e_over_h
151 <<
" barycenter: " <<
t.barycenter() <<
" eta,phi (baricenter): " <<
t.barycenter().eta() <<
", "
152 <<
t.barycenter().phi() <<
" eta,phi (eigen): " <<
t.eigenvectors(0).eta() <<
", " <<
t.eigenvectors(0).phi()
153 <<
" pt(eigen): " <<
std::sqrt(
t.eigenvectors(0).Unit().perp2()) *
t.raw_energy() <<
" seedID: " <<
t.seedID()
154 <<
" seedIndex: " <<
t.seedIndex() <<
" size: " <<
t.vertices().size() <<
" average usage: "
155 << (std::accumulate(std::begin(
t.vertex_multiplicity()),
std::end(
t.vertex_multiplicity()), 0.) /
156 (
float)
t.vertex_multiplicity().size())
157 <<
" raw_energy: " <<
t.raw_energy() <<
" regressed energy: " <<
t.regressed_energy()
158 <<
" probs(ga/e/mu/np/cp/nh/am/unk): ";
159 for (
auto const &
p :
t.id_probabilities()) {
162 LogDebug(
"TrackstersMergeProducer") <<
" sigmas: ";
163 for (
auto const &
s :
t.sigmas()) {
164 LogDebug(
"TrackstersMergeProducer") <<
s <<
" ";
166 LogDebug(
"TrackstersMergeProducer") << std::endl;
172 auto resultTrackstersMerged = std::make_unique<std::vector<Trackster>>();
173 auto resultCandidates = std::make_unique<std::vector<TICLCandidate>>();
176 std::vector<bool> usedTrackstersMerged;
177 std::vector<int> indexInMergedCollTRKEM;
178 std::vector<int> indexInMergedCollEM;
179 std::vector<int> indexInMergedCollTRK;
180 std::vector<int> indexInMergedCollHAD;
181 std::vector<bool> usedSeeds;
184 std::map<int, std::vector<std::pair<int, TracksterIterIndex>>> seedToTracksterAssociator;
185 std::vector<TracksterIterIndex> iterMergedTracksters;
188 const auto &
tracks = *track_h;
196 const auto &layerClustersTimes = *clustersTime_h;
200 const auto &trackstersEM = *trackstersem_h;
204 const auto &trackstersTRKEM = *tracksterstrkem_h;
208 const auto &trackstersTRK = *tracksterstrk_h;
212 const auto &trackstersHAD = *trackstershad_h;
217 usedSeeds.resize(
tracks.size(),
false);
219 fillTile(tracksterTile, trackstersTRKEM, TracksterIterIndex::TRKEM);
220 fillTile(tracksterTile, trackstersEM, TracksterIterIndex::EM);
221 fillTile(tracksterTile, trackstersTRK, TracksterIterIndex::TRK);
222 fillTile(tracksterTile, trackstersHAD, TracksterIterIndex::HAD);
224 auto totalNumberOfTracksters =
225 trackstersTRKEM.size() + trackstersTRK.size() + trackstersEM.size() + trackstersHAD.size();
226 resultTrackstersMerged->reserve(totalNumberOfTracksters);
227 iterMergedTracksters.reserve(totalNumberOfTracksters);
228 usedTrackstersMerged.resize(totalNumberOfTracksters,
false);
229 indexInMergedCollTRKEM.reserve(trackstersTRKEM.size());
230 indexInMergedCollEM.reserve(trackstersEM.size());
231 indexInMergedCollTRK.reserve(trackstersTRK.size());
232 indexInMergedCollHAD.reserve(trackstersHAD.size());
241 for (
auto const &
t : trackstersTRKEM) {
242 indexInMergedCollTRKEM.push_back(resultTrackstersMerged->size());
243 seedToTracksterAssociator[
t.seedIndex()].emplace_back(resultTrackstersMerged->size(), TracksterIterIndex::TRKEM);
244 resultTrackstersMerged->push_back(
t);
245 iterMergedTracksters.push_back(TracksterIterIndex::TRKEM);
248 for (
auto const &
t : trackstersEM) {
249 indexInMergedCollEM.push_back(resultTrackstersMerged->size());
250 resultTrackstersMerged->push_back(
t);
251 iterMergedTracksters.push_back(TracksterIterIndex::EM);
254 for (
auto const &
t : trackstersTRK) {
255 indexInMergedCollTRK.push_back(resultTrackstersMerged->size());
256 seedToTracksterAssociator[
t.seedIndex()].emplace_back(resultTrackstersMerged->size(), TracksterIterIndex::TRK);
257 resultTrackstersMerged->push_back(
t);
258 iterMergedTracksters.push_back(TracksterIterIndex::TRK);
261 for (
auto const &
t : trackstersHAD) {
262 indexInMergedCollHAD.push_back(resultTrackstersMerged->size());
263 resultTrackstersMerged->push_back(
t);
264 iterMergedTracksters.push_back(TracksterIterIndex::HAD);
275 auto trackstersMergedHandle = evt.
put(
std::move(resultTrackstersMerged));
281 for (
unsigned i = 0;
i < trackstersEM.size(); ++
i) {
282 auto mergedIdx = indexInMergedCollEM[
i];
283 usedTrackstersMerged[mergedIdx] =
true;
284 const auto &
t = trackstersEM[
i];
291 t.raw_energy() *
t.barycenter().unit().y(),
292 t.raw_energy() *
t.barycenter().unit().z(),
295 resultCandidates->push_back(tmpCandidate);
299 constexpr
float mpion2 = 0.13957f * 0.13957f;
300 for (
unsigned i = 0;
i < trackstersHAD.size(); ++
i) {
301 auto mergedIdx = indexInMergedCollHAD[
i];
302 usedTrackstersMerged[mergedIdx] =
true;
303 const auto &
t = trackstersHAD[
i];
309 float momentum =
std::sqrt(
t.raw_energy() *
t.raw_energy() - mpion2);
311 momentum *
t.barycenter().unit().y(),
312 momentum *
t.barycenter().unit().z(),
315 resultCandidates->push_back(tmpCandidate);
319 for (
unsigned i = 0;
i < trackstersTRKEM.size(); ++
i) {
320 auto mergedIdx = indexInMergedCollTRKEM[
i];
321 if (!usedTrackstersMerged[mergedIdx]) {
322 const auto &
t = trackstersTRKEM[
i];
323 auto trackIdx =
t.seedIndex();
325 if (!usedSeeds[trackIdx] and
t.raw_energy() > 0) {
326 usedSeeds[trackIdx] =
true;
327 usedTrackstersMerged[mergedIdx] =
true;
329 std::vector<int> trackstersTRKwithSameSeed;
330 std::vector<int> trackstersTRKEMwithSameSeed;
332 for (
const auto &tracksterIterationPair : seedToTracksterAssociator[trackIdx]) {
333 if (tracksterIterationPair.first != mergedIdx and !usedTrackstersMerged[tracksterIterationPair.first] and
334 trackstersMergedHandle->at(tracksterIterationPair.first).raw_energy() > 0.) {
335 if (tracksterIterationPair.second == TracksterIterIndex::TRKEM) {
336 trackstersTRKEMwithSameSeed.push_back(tracksterIterationPair.first);
337 }
else if (tracksterIterationPair.second == TracksterIterIndex::TRK) {
338 trackstersTRKwithSameSeed.push_back(tracksterIterationPair.first);
343 float tracksterTotalRawPt =
t.raw_pt();
344 std::vector<int> haloTrackstersTRKIdx;
345 bool foundCompatibleTRK =
false;
347 for (
auto otherTracksterIdx : trackstersTRKwithSameSeed) {
348 usedTrackstersMerged[otherTracksterIdx] =
true;
349 tracksterTotalRawPt += trackstersMergedHandle->at(otherTracksterIdx).raw_pt();
352 if ((
t.barycenter() - trackstersMergedHandle->at(otherTracksterIdx).barycenter()).
mag2() <
354 haloTrackstersTRKIdx.push_back(otherTracksterIdx);
357 foundCompatibleTRK =
true;
362 if (trackstersTRKEMwithSameSeed.empty()) {
363 if (foundCompatibleTRK) {
366 double raw_energy =
t.raw_energy();
371 for (
auto otherTracksterIdx : trackstersTRKwithSameSeed) {
373 raw_energy += trackstersMergedHandle->at(otherTracksterIdx).raw_energy();
377 raw_energy *
track.momentum().unit().y(),
378 raw_energy *
track.momentum().unit().z(),
381 resultCandidates->push_back(tmpCandidate);
386 double raw_energy =
t.raw_energy();
389 for (
auto otherTracksterIdx : trackstersTRKwithSameSeed) {
391 raw_energy += trackstersMergedHandle->at(otherTracksterIdx).raw_energy();
397 raw_energy *
track.momentum().unit().y(),
398 raw_energy *
track.momentum().unit().z(),
401 resultCandidates->push_back(tmpCandidate);
406 int closestTrackster = mergedIdx;
408 for (
auto otherTracksterIdx : trackstersTRKEMwithSameSeed) {
409 auto thisPt = tracksterTotalRawPt + trackstersMergedHandle->at(otherTracksterIdx).raw_pt() -
t.raw_pt();
410 closestTrackster =
std::abs(thisPt -
track.pt()) < minPtDiff ? otherTracksterIdx : closestTrackster;
412 usedTrackstersMerged[closestTrackster] =
true;
414 if (foundCompatibleTRK) {
417 double raw_energy = trackstersMergedHandle->at(closestTrackster).raw_energy();
422 for (
auto otherTracksterIdx : trackstersTRKwithSameSeed) {
424 raw_energy += trackstersMergedHandle->at(otherTracksterIdx).raw_energy();
427 float momentum =
std::sqrt(raw_energy * raw_energy - mpion2);
429 momentum *
track.momentum().unit().y(),
430 momentum *
track.momentum().unit().z(),
433 resultCandidates->push_back(tmpCandidate);
438 double raw_energy = trackstersMergedHandle->at(closestTrackster).raw_energy();
442 for (
auto otherTracksterIdx : trackstersTRKwithSameSeed) {
444 raw_energy += trackstersMergedHandle->at(otherTracksterIdx).raw_energy();
449 raw_energy *
track.momentum().unit().y(),
450 raw_energy *
track.momentum().unit().z(),
453 resultCandidates->push_back(tmpCandidate);
456 for (
auto otherTracksterIdx : trackstersTRKEMwithSameSeed) {
457 auto tmpIndex = (otherTracksterIdx != closestTrackster) ? otherTracksterIdx : mergedIdx;
459 const auto &otherTrackster = trackstersMergedHandle->at(tmpIndex);
460 auto gammaEnergy = otherTrackster.raw_energy();
465 gammaEnergy * otherTrackster.barycenter().unit().y(),
466 gammaEnergy * otherTrackster.barycenter().unit().z(),
468 photonCandidate.
setP4(gammaP4);
470 resultCandidates->push_back(photonCandidate);
477 for (
unsigned i = 0;
i < trackstersTRK.size(); ++
i) {
478 auto mergedIdx = indexInMergedCollTRK[
i];
479 const auto &
t = trackstersTRK[
i];
481 if (!usedTrackstersMerged[mergedIdx] and
t.raw_energy() > 0) {
482 auto trackIdx =
t.seedIndex();
484 if (!usedSeeds[trackIdx]) {
485 usedSeeds[trackIdx] =
true;
486 usedTrackstersMerged[mergedIdx] =
true;
493 float momentum =
std::sqrt(
t.raw_energy() *
t.raw_energy() - mpion2);
495 momentum *
track.momentum().unit().y(),
496 momentum *
track.momentum().unit().z(),
499 resultCandidates->push_back(tmpCandidate);
505 if (usedSeeds[
s.index] ==
false) {
516 resultCandidates->push_back(tmpCandidate);
517 usedSeeds[
s.index] =
true;
522 for (
unsigned i = 0;
i <
tracks.size(); ++
i) {
536 resultCandidates->push_back(tmpCandidate);
548 std::vector<Trackster> &tracksters)
const {
572 std::vector<int> tracksterIndices;
573 for (
int i = 0;
i < (
int)tracksters.size();
i++) {
578 float sumClusterEnergy = 0.;
584 tracksters[
i].setRegressedEnergy(0.
f);
585 tracksters[
i].zeroProbabilities();
586 tracksterIndices.push_back(
i);
593 int batchSize = (
int)tracksterIndices.size();
594 if (batchSize == 0) {
600 tensorflow::Tensor
input(tensorflow::DT_FLOAT, shape);
602 static constexpr
int inputDimension = 4;
604 std::vector<tensorflow::Tensor>
outputs;
614 for (
int i = 0;
i < batchSize;
i++) {
615 const Trackster &trackster = tracksters[tracksterIndices[
i]];
621 std::vector<int> clusterIndices(trackster.
vertices().size());
623 clusterIndices[
k] =
k;
625 sort(clusterIndices.begin(), clusterIndices.end(), [&
layerClusters, &trackster](
const int &
a,
const int &
b) {
633 for (
const int &
k : clusterIndices) {
670 for (
const int &
i : tracksterIndices) {
671 tracksters[
i].setRegressedEnergy(*(
energy++));
679 float *probs =
outputs[probsIdx].flat<
float>().
data();
681 for (
const int &
i : tracksterIndices) {
682 tracksters[
i].setProbabilities(probs);
683 probs += tracksters[
i].id_probabilities().size();
689 for (
auto &
cand : resultCandidates) {
690 if (
cand.tracksters().size() > 1) {
693 for (
const auto &tr :
cand.tracksters()) {
694 if (tr->timeError() > 0) {
695 auto invTimeESq =
pow(tr->timeError(), -2);
696 time += tr->time() * invTimeESq;
697 timeErr += invTimeESq;
701 timeErr = 1. / timeErr;
712 std::unique_ptr<TrackstersCache>
cache = std::make_unique<TrackstersCache>(
params);
716 if (!graphPath.empty()) {
725 delete cache->eidGraphDef;
726 cache->eidGraphDef =
nullptr;
734 for (
auto const &
t : tracksters) {
736 <<
counter++ <<
" TrackstersMergeProducer (" <<
label <<
") obj barycenter: " <<
t.barycenter()
737 <<
" eta,phi (baricenter): " <<
t.barycenter().eta() <<
", " <<
t.barycenter().phi()
738 <<
" eta,phi (eigen): " <<
t.eigenvectors(0).eta() <<
", " <<
t.eigenvectors(0).phi()
739 <<
" pt(eigen): " <<
std::sqrt(
t.eigenvectors(0).Unit().perp2()) *
t.raw_energy() <<
" seedID: " <<
t.seedID()
740 <<
" seedIndex: " <<
t.seedIndex() <<
" size: " <<
t.vertices().size() <<
" average usage: "
741 << (std::accumulate(std::begin(
t.vertex_multiplicity()),
std::end(
t.vertex_multiplicity()), 0.) /
742 (
float)
t.vertex_multiplicity().size())
743 <<
" raw_energy: " <<
t.raw_energy() <<
" regressed energy: " <<
t.regressed_energy()
744 <<
" probs(ga/e/mu/np/cp/nh/am/unk): ";
745 for (
auto const &
p :
t.id_probabilities()) {
748 LogDebug(
"TrackstersMergeProducer") <<
" sigmas: ";
749 for (
auto const &
s :
t.sigmas()) {
750 LogDebug(
"TrackstersMergeProducer") <<
s <<
" ";
752 LogDebug(
"TrackstersMergeProducer") << std::endl;
766 desc.add<
bool>(
"optimiseAcrossTracksters",
true);
767 desc.add<
int>(
"eta_bin_window", 1);
768 desc.add<
int>(
"phi_bin_window", 1);
769 desc.add<
double>(
"pt_sigma_high", 2.);
770 desc.add<
double>(
"pt_sigma_low", 2.);
771 desc.add<
double>(
"halo_max_distance2", 4.);
772 desc.add<
double>(
"track_min_pt", 1.);
773 desc.add<
double>(
"track_min_eta", 1.48);
774 desc.add<
double>(
"track_max_eta", 3.);
775 desc.add<
int>(
"track_max_missing_outerhits", 5);
776 desc.add<
double>(
"cosangle_align", 0.9945);
777 desc.add<
double>(
"e_over_h_threshold", 1.);
778 desc.add<
double>(
"pt_neutral_threshold", 2.);
779 desc.add<
double>(
"resol_calo_offset_had", 1.5);
780 desc.add<
double>(
"resol_calo_scale_had", 0.15);
781 desc.add<
double>(
"resol_calo_offset_em", 1.5);
782 desc.add<
double>(
"resol_calo_scale_em", 0.15);
783 desc.add<
bool>(
"debug",
true);
784 desc.add<
std::string>(
"eid_graph_path",
"RecoHGCal/TICL/data/tf_models/energy_id_v0.pb");
786 desc.add<
std::string>(
"eid_output_name_energy",
"output/regressed_energy");
787 desc.add<
std::string>(
"eid_output_name_id",
"output/id_probabilities");
788 desc.add<
double>(
"eid_min_cluster_energy", 1.);
789 desc.add<
int>(
"eid_n_layers", 50);
790 desc.add<
int>(
"eid_n_clusters", 10);
791 descriptions.
add(
"trackstersMergeProducer",
desc);