18 template <
typename TILES>
24 theGraph_(std::make_unique<
HGCGraphT<TILES>>()),
25 oneTracksterPerTrackSeed_(conf.getParameter<bool>(
"oneTracksterPerTrackSeed")),
26 promoteEmptyRegionToTrackster_(conf.getParameter<bool>(
"promoteEmptyRegionToTrackster")),
27 out_in_dfs_(conf.getParameter<bool>(
"out_in_dfs")),
28 max_out_in_hops_(conf.getParameter<int>(
"max_out_in_hops")),
29 min_cos_theta_(conf.getParameter<double>(
"min_cos_theta")),
30 min_cos_pointing_(conf.getParameter<double>(
"min_cos_pointing")),
31 root_doublet_max_distance_from_seed_squared_(
32 conf.getParameter<double>(
"root_doublet_max_distance_from_seed_squared")),
33 etaLimitIncreaseWindow_(conf.getParameter<double>(
"etaLimitIncreaseWindow")),
34 skip_layers_(conf.getParameter<int>(
"skip_layers")),
35 max_missing_layers_in_trackster_(conf.getParameter<int>(
"max_missing_layers_in_trackster")),
36 check_missing_layers_(max_missing_layers_in_trackster_ < 100),
37 shower_start_max_layer_(conf.getParameter<int>(
"shower_start_max_layer")),
38 min_layers_per_trackster_(conf.getParameter<int>(
"min_layers_per_trackster")),
39 filter_on_categories_(conf.getParameter<std::
vector<int>>(
"filter_on_categories")),
40 pid_threshold_(conf.getParameter<double>(
"pid_threshold")),
41 energy_em_over_total_threshold_(conf.getParameter<double>(
"energy_em_over_total_threshold")),
42 max_longitudinal_sigmaPCA_(conf.getParameter<double>(
"max_longitudinal_sigmaPCA")),
43 min_clusters_per_ntuplet_(min_layers_per_trackster_),
44 max_delta_time_(conf.getParameter<double>(
"max_delta_time")),
45 eidInputName_(conf.getParameter<std::
string>(
"eid_input_name")),
46 eidOutputNameEnergy_(conf.getParameter<std::
string>(
"eid_output_name_energy")),
47 eidOutputNameId_(conf.getParameter<std::
string>(
"eid_output_name_id")),
48 eidMinClusterEnergy_(conf.getParameter<double>(
"eid_min_cluster_energy")),
49 eidNLayers_(conf.getParameter<int>(
"eid_n_layers")),
50 eidNClusters_(conf.getParameter<int>(
"eid_n_clusters")),
51 eidSession_(nullptr) {
54 if (trackstersCache ==
nullptr || trackstersCache->
eidGraphDef ==
nullptr) {
56 <<
"PatternRecognitionbyCA received an empty graph definition from the global cache";
61 template <
typename TILES>
64 template <
typename TILES>
67 std::vector<Trackster> &
result,
68 std::unordered_map<
int, std::vector<int>> &seedToTracksterAssociation) {
75 rhtools_.setGeometry(geom);
80 LogDebug(
"HGCPatternRecoByCA") <<
"Making Tracksters with CA" << std::endl;
87 bool isRegionalIter = (input.
regions[0].index != -1);
89 std::vector<int> seedIndices;
90 std::vector<uint8_t> layer_cluster_usage(input.
layerClusters.size(), 0);
91 theGraph_->makeAndConnectDoublets(input.
tiles,
102 root_doublet_max_distance_from_seed_squared_,
103 etaLimitIncreaseWindow_,
105 rhtools_.lastLayer(isHFnose),
108 theGraph_->findNtuplets(foundNtuplets, seedIndices, min_clusters_per_ntuplet_, out_in_dfs_, max_out_in_hops_);
110 const auto &
doublets = theGraph_->getAllDoublets();
111 int tracksterId = -1;
114 std::vector<Trackster> tmpTracksters;
115 tmpTracksters.reserve(foundNtuplets.size());
117 for (
auto const &
ntuplet : foundNtuplets) {
120 std::set<unsigned int> effective_cluster_idx;
122 for (
auto const &doublet :
ntuplet) {
123 auto innerCluster =
doublets[doublet].innerClusterId();
124 auto outerCluster =
doublets[doublet].outerClusterId();
126 effective_cluster_idx.insert(innerCluster);
127 effective_cluster_idx.insert(outerCluster);
130 LogDebug(
"HGCPatternRecoByCA") <<
" New doublet " << doublet <<
" for trackster: " << result.size()
131 <<
" InnerCl " << innerCluster <<
" " << input.
layerClusters[innerCluster].x()
133 << input.
layerClusters[innerCluster].z() <<
" OuterCl " << outerCluster <<
" "
136 << input.
layerClusters[outerCluster].z() <<
" " << tracksterId << std::endl;
139 unsigned showerMinLayerId = 99999;
140 std::vector<unsigned int> uniqueLayerIds;
141 uniqueLayerIds.reserve(effective_cluster_idx.size());
142 std::vector<std::pair<unsigned int, unsigned int>> lcIdAndLayer;
143 lcIdAndLayer.reserve(effective_cluster_idx.size());
144 for (
auto const i : effective_cluster_idx) {
146 auto layerId = rhtools_.getLayerWithOffset(haf[0].
first);
147 showerMinLayerId =
std::min(layerId, showerMinLayerId);
148 uniqueLayerIds.push_back(layerId);
149 lcIdAndLayer.emplace_back(
i, layerId);
151 std::sort(uniqueLayerIds.begin(), uniqueLayerIds.end());
152 uniqueLayerIds.erase(
std::unique(uniqueLayerIds.begin(), uniqueLayerIds.end()), uniqueLayerIds.end());
153 unsigned int numberOfLayersInTrackster = uniqueLayerIds.size();
154 if (check_missing_layers_) {
155 int numberOfMissingLayers = 0;
156 unsigned int j = showerMinLayerId;
157 unsigned int indexInVec = 0;
158 for (
const auto &
layer : uniqueLayerIds) {
160 numberOfMissingLayers++;
162 if (numberOfMissingLayers > max_missing_layers_in_trackster_) {
163 numberOfLayersInTrackster = indexInVec;
164 for (
auto &llpair : lcIdAndLayer) {
165 if (llpair.second >=
layer) {
166 effective_cluster_idx.erase(llpair.first);
177 if ((numberOfLayersInTrackster >= min_layers_per_trackster_) and (showerMinLayerId <= shower_start_max_layer_)) {
180 tmp.vertices().reserve(effective_cluster_idx.size());
181 tmp.vertex_multiplicity().resize(effective_cluster_idx.size(), 1);
184 tmp.setSeed(input.
regions[0].collectionID, seedIndices[tracksterId]);
187 tmpTracksters.push_back(tmp);
193 rhtools_.getPositionLayer(rhtools_.lastLayerEE(isHFnose), isHFnose).z());
203 auto filter_on_pids = [&](
Trackster &
t) ->
bool {
204 auto cumulative_prob = 0.;
205 for (
auto index : filter_on_categories_) {
206 cumulative_prob +=
t.id_probabilities(
index);
208 return (cumulative_prob <= pid_threshold_) &&
209 (
t.raw_em_energy() < energy_em_over_total_threshold_ *
t.raw_energy());
212 std::vector<unsigned int> selectedTrackstersIds;
213 for (
unsigned i = 0;
i < tmpTracksters.size(); ++
i) {
214 if (!filter_on_pids(tmpTracksters[
i]) and tmpTracksters[
i].sigmasPCA()[0] < max_longitudinal_sigmaPCA_) {
215 selectedTrackstersIds.push_back(i);
219 result.reserve(selectedTrackstersIds.size());
221 for (
unsigned i = 0;
i < selectedTrackstersIds.size(); ++
i) {
222 const auto &
t = tmpTracksters[selectedTrackstersIds[
i]];
223 for (
auto const lcId :
t.vertices()) {
224 layer_cluster_usage[lcId]++;
226 LogDebug(
"HGCPatternRecoByCA") <<
"LayerID: " << lcId <<
" count: " << (int)layer_cluster_usage[lcId]
229 if (isRegionalIter) {
230 seedToTracksterAssociation[
t.seedIndex()].push_back(
i);
235 for (
auto &trackster : result) {
236 assert(trackster.vertices().size() <= trackster.vertex_multiplicity().size());
237 for (
size_t i = 0;
i < trackster.vertices().size(); ++
i) {
238 trackster.vertex_multiplicity()[
i] = layer_cluster_usage[trackster.vertices(
i)];
240 LogDebug(
"HGCPatternRecoByCA") <<
"LayerID: " << trackster.vertices(
i)
241 <<
" count: " << (int)trackster.vertex_multiplicity(
i) << std::endl;
245 if (oneTracksterPerTrackSeed_) {
246 std::vector<Trackster>
tmp;
247 mergeTrackstersTRK(result, input.
layerClusters, tmp, seedToTracksterAssociation);
254 rhtools_.getPositionLayer(rhtools_.lastLayerEE(isHFnose), isHFnose).z());
261 if (promoteEmptyRegionToTrackster_) {
262 emptyTrackstersFromSeedsTRK(result, seedToTracksterAssociation, input.
regions[0].collectionID);
266 for (
auto &trackster : result) {
267 LogDebug(
"HGCPatternRecoByCA") <<
"Trackster characteristics: " << std::endl;
268 LogDebug(
"HGCPatternRecoByCA") <<
"Size: " << trackster.vertices().size() << std::endl;
270 for (
auto const &
p : trackster.id_probabilities()) {
278 template <
typename TILES>
280 const std::vector<Trackster> &
input,
281 const std::vector<reco::CaloCluster> &layerClusters,
282 std::vector<Trackster> &
output,
283 std::unordered_map<
int, std::vector<int>> &seedToTracksterAssociation)
const {
284 output.reserve(input.size());
285 for (
auto &thisSeed : seedToTracksterAssociation) {
286 auto &tracksters = thisSeed.second;
287 if (!tracksters.empty()) {
288 auto numberOfTrackstersInSeed = tracksters.size();
289 output.emplace_back(input[tracksters[0]]);
290 auto &outTrackster = output.back();
291 tracksters[0] = output.size() - 1;
292 auto updated_size = outTrackster.vertices().size();
293 for (
unsigned int j = 1;
j < numberOfTrackstersInSeed; ++
j) {
294 auto &thisTrackster = input[tracksters[
j]];
295 updated_size += thisTrackster.vertices().size();
297 LogDebug(
"HGCPatternRecoByCA") <<
"Updated size: " << updated_size << std::endl;
299 outTrackster.vertices().reserve(updated_size);
300 outTrackster.vertex_multiplicity().reserve(updated_size);
303 std::back_inserter(outTrackster.vertices()));
305 std::end(thisTrackster.vertex_multiplicity()),
306 std::back_inserter(outTrackster.vertex_multiplicity()));
308 tracksters.resize(1);
311 output.shrink_to_fit();
314 template <
typename TILES>
316 std::vector<Trackster> &tracksters,
317 std::unordered_map<
int, std::vector<int>> &seedToTracksterAssociation,
319 for (
auto &thisSeed : seedToTracksterAssociation) {
320 if (thisSeed.second.empty()) {
322 t.setRegressedEnergy(0.
f);
323 t.zeroProbabilities();
325 t.setSeed(collectionID, thisSeed.first);
326 tracksters.emplace_back(t);
327 thisSeed.second.emplace_back(tracksters.size() - 1);
332 template <
typename TILES>
334 std::vector<Trackster> &tracksters) {
358 std::vector<int> tracksterIndices;
359 for (
int i = 0;
i < (int)tracksters.size();
i++) {
363 float sumClusterEnergy = 0.;
364 for (
const unsigned int &vertex : tracksters[
i].
vertices()) {
365 sumClusterEnergy += (float)layerClusters[vertex].
energy();
367 if (sumClusterEnergy >= eidMinClusterEnergy_) {
369 tracksters[
i].setRegressedEnergy(0.
f);
370 tracksters[
i].zeroProbabilities();
371 tracksterIndices.push_back(
i);
378 int batchSize = (int)tracksterIndices.size();
379 if (batchSize == 0) {
384 tensorflow::TensorShape shape({batchSize, eidNLayers_, eidNClusters_, eidNFeatures_});
385 tensorflow::Tensor
input(tensorflow::DT_FLOAT, shape);
388 std::vector<tensorflow::Tensor> outputs;
389 std::vector<std::string> outputNames;
390 if (!eidOutputNameEnergy_.empty()) {
391 outputNames.push_back(eidOutputNameEnergy_);
393 if (!eidOutputNameId_.empty()) {
394 outputNames.push_back(eidOutputNameId_);
398 for (
int i = 0;
i < batchSize;
i++) {
399 const Trackster &trackster = tracksters[tracksterIndices[
i]];
404 std::vector<int> clusterIndices(trackster.vertices().size());
405 for (
int k = 0;
k < (int)trackster.vertices().size();
k++) {
406 clusterIndices[
k] =
k;
408 sort(clusterIndices.begin(), clusterIndices.end(), [&layerClusters, &trackster](
const int &
a,
const int &
b) {
409 return layerClusters[trackster.vertices(a)].energy() > layerClusters[trackster.vertices(
b)].energy();
413 std::vector<int> seenClusters(eidNLayers_);
416 for (
const int &
k : clusterIndices) {
420 if (j < eidNLayers_ && seenClusters[j] < eidNClusters_) {
422 float *
features = &input.tensor<float, 4>()(
i, j, seenClusters[j], 0);
425 *(features++) =
float(cluster.
energy() / float(trackster.vertex_multiplicity(
k)));
435 for (
int j = 0;
j < eidNLayers_;
j++) {
436 for (
int k = seenClusters[
j];
k < eidNClusters_;
k++) {
437 float *
features = &input.tensor<float, 4>()(
i,
j,
k, 0);
438 for (
int l = 0;
l < eidNFeatures_;
l++) {
449 if (!eidOutputNameEnergy_.empty()) {
451 float *
energy = outputs[0].flat<
float>().
data();
453 for (
const int &
i : tracksterIndices) {
454 tracksters[
i].setRegressedEnergy(*(energy++));
459 if (!eidOutputNameId_.empty()) {
461 int probsIdx = eidOutputNameEnergy_.empty() ? 0 : 1;
462 float *probs = outputs[probsIdx].flat<
float>().
data();
464 for (
const int &
i : tracksterIndices) {
465 tracksters[
i].setProbabilities(probs);
466 probs += tracksters[
i].id_probabilities().size();
471 template <
typename TILES>
473 iDesc.
add<
int>(
"algo_verbosity", 0);
474 iDesc.
add<
bool>(
"oneTracksterPerTrackSeed",
false);
475 iDesc.
add<
bool>(
"promoteEmptyRegionToTrackster",
false);
476 iDesc.
add<
bool>(
"out_in_dfs",
true);
477 iDesc.
add<
int>(
"max_out_in_hops", 10);
478 iDesc.
add<
double>(
"min_cos_theta", 0.915);
479 iDesc.
add<
double>(
"min_cos_pointing", -1.);
480 iDesc.
add<
double>(
"root_doublet_max_distance_from_seed_squared", 9999);
481 iDesc.
add<
double>(
"etaLimitIncreaseWindow", 2.1);
482 iDesc.
add<
int>(
"skip_layers", 0);
483 iDesc.
add<
int>(
"max_missing_layers_in_trackster", 9999);
484 iDesc.
add<
int>(
"shower_start_max_layer", 9999)->setComment(
"make default such that no filtering is applied");
485 iDesc.
add<
int>(
"min_layers_per_trackster", 10);
486 iDesc.
add<std::vector<int>>(
"filter_on_categories", {0});
487 iDesc.
add<
double>(
"pid_threshold", 0.)->
setComment(
"make default such that no filtering is applied");
488 iDesc.
add<
double>(
"energy_em_over_total_threshold", -1.)
489 ->
setComment(
"make default such that no filtering is applied");
490 iDesc.
add<
double>(
"max_longitudinal_sigmaPCA", 9999);
491 iDesc.
add<
double>(
"max_delta_time", 3.)->
setComment(
"nsigma");
493 iDesc.
add<
std::string>(
"eid_output_name_energy",
"output/regressed_energy");
494 iDesc.
add<
std::string>(
"eid_output_name_id",
"output/id_probabilities");
495 iDesc.
add<
double>(
"eid_min_cluster_energy", 1.);
496 iDesc.
add<
int>(
"eid_n_layers", 50);
497 iDesc.
add<
int>(
"eid_n_clusters", 10);
PatternRecognitionbyCA(const edm::ParameterSet &conf, const CacheBase *cache, edm::ConsumesCollector iC)
Session * createSession(SessionOptions &sessionOptions)
void setComment(std::string const &value)
std::vector< NamedTensor > NamedTensorList
auto const & foundNtuplets
void emptyTrackstersFromSeedsTRK(std::vector< Trackster > &tracksters, std::unordered_map< int, std::vector< int >> &seedToTracksterAssociation, const edm::ProductID &collectionID) const
~PatternRecognitionbyCA() override
void makeTracksters(const typename PatternRecognitionAlgoBaseT< TILES >::Inputs &input, std::vector< Trackster > &result, std::unordered_map< int, std::vector< int >> &seedToTracksterAssociation) override
double eta() const
pseudorapidity of cluster centroid
constexpr std::array< uint8_t, layerIndexSize > layer
static std::string const input
bool getData(T &iHolder) const
void assignPCAtoTracksters(std::vector< Trackster > &, const std::vector< reco::CaloCluster > &, const edm::ValueMap< std::pair< float, float >> &, double, bool energyWeight=true)
const std::vector< std::pair< DetId, float > > & hitsAndFractions() const
void energyRegressionAndID(const std::vector< reco::CaloCluster > &layerClusters, std::vector< Trackster > &result)
std::vector< float > features(const reco::PreId &ecal, const reco::PreId &hcal, double rho, const reco::BeamSpot &spot, noZS::EcalClusterLazyTools &ecalTools)
void run(Session *session, const NamedTensorList &inputs, const std::vector< std::string > &outputNames, std::vector< Tensor > *outputs, const thread::ThreadPoolOptions &threadPoolOptions)
Abs< T >::type abs(const T &t)
std::atomic< tensorflow::GraphDef * > eidGraphDef
double energy() const
cluster energy
void mergeTrackstersTRK(const std::vector< Trackster > &, const std::vector< reco::CaloCluster > &, std::vector< Trackster > &, std::unordered_map< int, std::vector< int >> &seedToTracksterAssociation) const
ParameterDescriptionBase * add(U const &iLabel, T const &value)
char data[epos_bytes_allocation]
static void fillPSetDescription(edm::ParameterSetDescription &iDesc)
static std::atomic< unsigned int > counter
double phi() const
azimuthal angle of cluster centroid
tensorflow::Session * eidSession_