Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding SONIC ParticleNet Producer to CMSSW #37964

Merged
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Configuration/ProcessModifiers/python/allSonicTriton_cff.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import FWCore.ParameterSet.Config as cms

from Configuration.ProcessModifiers.enableSonicTriton_cff import enableSonicTriton
from Configuration.ProcessModifiers.particleNetSonicTriton_cff import particleNetSonicTriton
from Configuration.ProcessModifiers.particleNetPTSonicTriton_cff import particleNetPTSonicTriton

# collect all SonicTriton-related process modifiers here
allSonicTriton = cms.ModifierChain(enableSonicTriton)
allSonicTriton = cms.ModifierChain(enableSonicTriton,particleNetSonicTriton)
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import FWCore.ParameterSet.Config as cms

particleNetPTSonicTriton = cms.Modifier()
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import FWCore.ParameterSet.Config as cms

particleNetSonicTriton = cms.Modifier()
2 changes: 2 additions & 0 deletions RecoBTag/FeatureTools/BuildFile.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
<use name="DataFormats/ParticleFlowCandidate"/>
<use name="TrackingTools/IPTools"/>
<use name="RecoBTag/TrackProbability"/>
<use name="PhysicsTools/ONNXRuntime"/>
<use name="json"/>
<export>
<lib name="1"/>
</export>
42 changes: 42 additions & 0 deletions RecoBTag/FeatureTools/interface/deep_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,17 @@
#include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
#include "DataFormats/PatCandidates/interface/Jet.h"

#include "FWCore/Framework/interface/Event.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"

#include "PhysicsTools/ONNXRuntime/interface/ONNXRuntime.h"

#include <iostream>
#include <fstream>
#include <algorithm>
#include <numeric>
#include <nlohmann/json.hpp>

namespace btagbtvdeep {

// remove infs and NaNs with value (adapted from DeepNTuples)
Expand Down Expand Up @@ -104,5 +115,36 @@ namespace btagbtvdeep {
VarInfo info(const std::string &name) const { return var_info_map.at(name); }
};

int center_norm_pad(const std::vector<float> &input,
float center,
float scale,
unsigned min_length,
unsigned max_length,
std::vector<float> &datavec,
int startval,
float pad_value = 0,
float replace_inf_value = 0,
float min = 0,
float max = -1);

int center_norm_pad_halfRagged(const std::vector<float> &input,
float center,
float scale,
unsigned target_length,
std::vector<float> &datavec,
int startval,
float pad_value = 0,
float replace_inf_value = 0,
float min = 0,
float max = -1);

void ParticleNetConstructor(const edm::ParameterSet &Config_,
bool doExtra,
std::vector<std::string> &input_names_,
std::unordered_map<std::string, PreprocessParams> &prep_info_map_,
std::vector<std::vector<int64_t>> &input_shapes_,
std::vector<unsigned> &input_sizes_,
cms::Ort::FloatArrays *data_);

} // namespace btagbtvdeep
#endif //RecoBTag_FeatureTools_deep_helpers_h
127 changes: 127 additions & 0 deletions RecoBTag/FeatureTools/src/deep_helpers.cc
Original file line number Diff line number Diff line change
Expand Up @@ -143,4 +143,131 @@ namespace btagbtvdeep {
}
return features;
}

int center_norm_pad(const std::vector<float> &input,
float center,
float norm_factor,
unsigned min_length,
unsigned max_length,
std::vector<float> &datavec,
int startval,
float pad_value,
float replace_inf_value,
float min,
float max) {
// do variable shifting/scaling/padding/clipping in one go

assert(min <= pad_value && pad_value <= max);
assert(min_length <= max_length);

unsigned target_length = std::clamp((unsigned)input.size(), min_length, max_length);
for (unsigned i = 0; i < target_length; ++i) {
if (i < input.size()) {
datavec[i + startval] = std::clamp((catch_infs(input[i], replace_inf_value) - center) * norm_factor, min, max);
} else {
datavec[i + startval] = pad_value;
}
}
return target_length;
}

int center_norm_pad_halfRagged(const std::vector<float> &input,
float center,
float norm_factor,
unsigned target_length,
std::vector<float> &datavec,
int startval,
float pad_value,
float replace_inf_value,
float min,
float max) {
// do variable shifting/scaling/padding/clipping in one go

assert(min <= pad_value && pad_value <= max);

for (unsigned i = 0; i < std::min(static_cast<unsigned int>(input.size()), target_length); ++i) {
datavec.push_back(std::clamp((catch_infs(input[i], replace_inf_value) - center) * norm_factor, min, max));
}
if (input.size() < target_length)
datavec.insert(datavec.end(), target_length - input.size(), pad_value);

return target_length;
}

void ParticleNetConstructor(const edm::ParameterSet &Config_,
bool doExtra,
std::vector<std::string> &input_names_,
std::unordered_map<std::string, PreprocessParams> &prep_info_map_,
std::vector<std::vector<int64_t>> &input_shapes_,
std::vector<unsigned> &input_sizes_,
cms::Ort::FloatArrays *data_) {
// load preprocessing info
auto json_path = Config_.getParameter<std::string>("preprocess_json");
if (!json_path.empty()) {
// use preprocessing json file if available
std::ifstream ifs(edm::FileInPath(json_path).fullPath());
nlohmann::json js = nlohmann::json::parse(ifs);
js.at("input_names").get_to(input_names_);
for (const auto &group_name : input_names_) {
const auto &group_pset = js.at(group_name);
auto &prep_params = prep_info_map_[group_name];
group_pset.at("var_names").get_to(prep_params.var_names);
if (group_pset.contains("var_length")) {
prep_params.min_length = group_pset.at("var_length");
prep_params.max_length = prep_params.min_length;
} else {
prep_params.min_length = group_pset.at("min_length");
prep_params.max_length = group_pset.at("max_length");
input_shapes_.push_back({1, (int64_t)prep_params.var_names.size(), -1});
}
const auto &var_info_pset = group_pset.at("var_infos");
for (const auto &var_name : prep_params.var_names) {
const auto &var_pset = var_info_pset.at(var_name);
double median = var_pset.at("median");
double norm_factor = var_pset.at("norm_factor");
double replace_inf_value = var_pset.at("replace_inf_value");
double lower_bound = var_pset.at("lower_bound");
double upper_bound = var_pset.at("upper_bound");
double pad = var_pset.contains("pad") ? double(var_pset.at("pad")) : 0;
prep_params.var_info_map[var_name] =
PreprocessParams::VarInfo(median, norm_factor, replace_inf_value, lower_bound, upper_bound, pad);
}

if (doExtra && data_ != nullptr) {
// create data storage with a fixed size vector initialized w/ 0
const auto &len = input_sizes_.emplace_back(prep_params.max_length * prep_params.var_names.size());
data_->emplace_back(len, 0);
}
}
} else {
// otherwise use the PSet in the python config file
const auto &prep_pset = Config_.getParameterSet("preprocessParams");
input_names_ = prep_pset.getParameter<std::vector<std::string>>("input_names");
for (const auto &group_name : input_names_) {
const edm::ParameterSet &group_pset = prep_pset.getParameterSet(group_name);
auto &prep_params = prep_info_map_[group_name];
prep_params.var_names = group_pset.getParameter<std::vector<std::string>>("var_names");
prep_params.min_length = group_pset.getParameter<unsigned>("var_length");
prep_params.max_length = prep_params.min_length;
const auto &var_info_pset = group_pset.getParameterSet("var_infos");
for (const auto &var_name : prep_params.var_names) {
const edm::ParameterSet &var_pset = var_info_pset.getParameterSet(var_name);
double median = var_pset.getParameter<double>("median");
double norm_factor = var_pset.getParameter<double>("norm_factor");
double replace_inf_value = var_pset.getParameter<double>("replace_inf_value");
double lower_bound = var_pset.getParameter<double>("lower_bound");
double upper_bound = var_pset.getParameter<double>("upper_bound");
prep_params.var_info_map[var_name] =
PreprocessParams::VarInfo(median, norm_factor, replace_inf_value, lower_bound, upper_bound, 0);
}

if (doExtra && data_ != nullptr) {
// create data storage with a fixed size vector initialized w/ 0
const auto &len = input_sizes_.emplace_back(prep_params.max_length * prep_params.var_names.size());
data_->emplace_back(len, 0);
}
}
}
}

} // namespace btagbtvdeep
124 changes: 16 additions & 108 deletions RecoBTag/ONNXRuntime/plugins/BoostedJetONNXJetTagsProducer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,6 @@ class BoostedJetONNXJetTagsProducer : public edm::stream::EDProducer<edm::Global

void produce(edm::Event &, const edm::EventSetup &) override;

std::vector<float> center_norm_pad(const std::vector<float> &input,
float center,
float scale,
unsigned min_length,
unsigned max_length,
float pad_value = 0,
float replace_inf_value = 0,
float min = 0,
float max = -1);
void make_inputs(const reco::DeepBoostedJetTagInfo &taginfo);

const edm::EDGetTokenT<TagInfoCollection> src_;
Expand All @@ -69,69 +60,7 @@ BoostedJetONNXJetTagsProducer::BoostedJetONNXJetTagsProducer(const edm::Paramete
: src_(consumes<TagInfoCollection>(iConfig.getParameter<edm::InputTag>("src"))),
flav_names_(iConfig.getParameter<std::vector<std::string>>("flav_names")),
debug_(iConfig.getUntrackedParameter<bool>("debugMode", false)) {
// load preprocessing info
auto json_path = iConfig.getParameter<std::string>("preprocess_json");
if (!json_path.empty()) {
// use preprocessing json file if available
std::ifstream ifs(edm::FileInPath(json_path).fullPath());
nlohmann::json js = nlohmann::json::parse(ifs);
js.at("input_names").get_to(input_names_);
for (const auto &group_name : input_names_) {
const auto &group_pset = js.at(group_name);
auto &prep_params = prep_info_map_[group_name];
group_pset.at("var_names").get_to(prep_params.var_names);
if (group_pset.contains("var_length")) {
prep_params.min_length = group_pset.at("var_length");
prep_params.max_length = prep_params.min_length;
} else {
prep_params.min_length = group_pset.at("min_length");
prep_params.max_length = group_pset.at("max_length");
input_shapes_.push_back({1, (int64_t)prep_params.var_names.size(), -1});
}
const auto &var_info_pset = group_pset.at("var_infos");
for (const auto &var_name : prep_params.var_names) {
const auto &var_pset = var_info_pset.at(var_name);
double median = var_pset.at("median");
double norm_factor = var_pset.at("norm_factor");
double replace_inf_value = var_pset.at("replace_inf_value");
double lower_bound = var_pset.at("lower_bound");
double upper_bound = var_pset.at("upper_bound");
double pad = var_pset.contains("pad") ? double(var_pset.at("pad")) : 0;
prep_params.var_info_map[var_name] =
PreprocessParams::VarInfo(median, norm_factor, replace_inf_value, lower_bound, upper_bound, pad);
}

// create data storage with a fixed size vector initilized w/ 0
const auto &len = input_sizes_.emplace_back(prep_params.max_length * prep_params.var_names.size());
data_.emplace_back(len, 0);
}
} else {
// otherwise use the PSet in the python config file
const auto &prep_pset = iConfig.getParameterSet("preprocessParams");
input_names_ = prep_pset.getParameter<std::vector<std::string>>("input_names");
for (const auto &group_name : input_names_) {
const auto &group_pset = prep_pset.getParameterSet(group_name);
auto &prep_params = prep_info_map_[group_name];
prep_params.var_names = group_pset.getParameter<std::vector<std::string>>("var_names");
prep_params.min_length = group_pset.getParameter<unsigned>("var_length");
prep_params.max_length = prep_params.min_length;
const auto &var_info_pset = group_pset.getParameterSet("var_infos");
for (const auto &var_name : prep_params.var_names) {
const auto &var_pset = var_info_pset.getParameterSet(var_name);
double median = var_pset.getParameter<double>("median");
double norm_factor = var_pset.getParameter<double>("norm_factor");
double replace_inf_value = var_pset.getParameter<double>("replace_inf_value");
double lower_bound = var_pset.getParameter<double>("lower_bound");
double upper_bound = var_pset.getParameter<double>("upper_bound");
prep_params.var_info_map[var_name] =
PreprocessParams::VarInfo(median, norm_factor, replace_inf_value, lower_bound, upper_bound, 0);
}

// create data storage with a fixed size vector initiliazed w/ 0
const auto &len = input_sizes_.emplace_back(prep_params.max_length * prep_params.var_names.size());
data_.emplace_back(len, 0);
}
}
ParticleNetConstructor(iConfig, true, input_names_, prep_info_map_, input_shapes_, input_sizes_, &data_);

if (debug_) {
for (unsigned i = 0; i < input_names_.size(); ++i) {
Expand Down Expand Up @@ -261,28 +190,6 @@ void BoostedJetONNXJetTagsProducer::produce(edm::Event &iEvent, const edm::Event
}
}

std::vector<float> BoostedJetONNXJetTagsProducer::center_norm_pad(const std::vector<float> &input,
float center,
float norm_factor,
unsigned min_length,
unsigned max_length,
float pad_value,
float replace_inf_value,
float min,
float max) {
// do variable shifting/scaling/padding/clipping in one go

assert(min <= pad_value && pad_value <= max);
assert(min_length <= max_length);

unsigned target_length = std::clamp((unsigned)input.size(), min_length, max_length);
std::vector<float> out(target_length, pad_value);
for (unsigned i = 0; i < input.size() && i < target_length; ++i) {
out[i] = std::clamp((catch_infs(input[i], replace_inf_value) - center) * norm_factor, min, max);
}
return out;
}

void BoostedJetONNXJetTagsProducer::make_inputs(const reco::DeepBoostedJetTagInfo &taginfo) {
for (unsigned igroup = 0; igroup < input_names_.size(); ++igroup) {
const auto &group_name = input_names_[igroup];
Expand All @@ -297,26 +204,27 @@ void BoostedJetONNXJetTagsProducer::make_inputs(const reco::DeepBoostedJetTagInf
const auto &varname = prep_params.var_names[i];
const auto &raw_value = taginfo.features().get(varname);
const auto &info = prep_params.info(varname);
auto val = center_norm_pad(raw_value,
info.center,
info.norm_factor,
prep_params.min_length,
prep_params.max_length,
info.pad,
info.replace_inf_value,
info.lower_bound,
info.upper_bound);
std::copy(val.begin(), val.end(), group_values.begin() + curr_pos);
curr_pos += val.size();
int insize = center_norm_pad(raw_value,
info.center,
info.norm_factor,
prep_params.min_length,
prep_params.max_length,
group_values,
curr_pos,
info.pad,
info.replace_inf_value,
info.lower_bound,
info.upper_bound);
curr_pos += insize;
if (i == 0 && (!input_shapes_.empty())) {
input_shapes_[igroup][2] = val.size();
input_shapes_[igroup][2] = insize;
}

if (debug_) {
std::cout << " -- var=" << varname << ", center=" << info.center << ", scale=" << info.norm_factor
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please move to LogDebug? Thanks

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed

<< ", replace=" << info.replace_inf_value << ", pad=" << info.pad << std::endl;
for (const auto &v : val) {
std::cout << v << ",";
for (unsigned i = curr_pos - insize; i < curr_pos; i++) {
std::cout << group_values[i] << ",";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed all instances here

}
std::cout << std::endl;
}
Expand Down
1 change: 1 addition & 0 deletions RecoBTag/ONNXRuntime/plugins/BuildFile.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
<use name="PhysicsTools/ONNXRuntime"/>
<use name="RecoBTag/FeatureTools"/>
<use name="RecoBTag/ONNXRuntime"/>
<use name="HeterogeneousCore/SonicTriton"/>
<flags EDM_PLUGIN="1"/>
</library>
Loading