CMS 3D CMS Logo

XGBooster.cc
Go to the documentation of this file.
1 #include <algorithm>
2 #include <cassert>
3 #include <cmath>
4 #include <cstdio> // For std::snprintf
5 #include <fstream>
6 #include <iostream>
7 #include <sstream>
8 #include <stdexcept>
9 #include <stdexcept>
10 #include <vector>
11 
13 
14 using namespace pat;
15 
16 std::vector<std::string> read_features(const std::string& content) {
17  std::vector<std::string> result;
18 
19  std::istringstream stream(content);
20  char ch;
21 
22  // Expect opening '['
23  stream >> ch;
24  if (ch != '[') {
25  throw std::runtime_error("Expected '[' at the beginning of the JSON array!");
26  }
27 
28  while (stream) {
29  stream >> ch;
30 
31  if (ch == ']') {
32  break;
33  } else if (ch == ',') {
34  continue;
35  } else if (ch == '"') {
36  std::string feature;
37  std::getline(stream, feature, '"');
38  result.push_back(feature);
39  } else {
40  throw std::runtime_error("Unexpected character in the JSON array!");
41  }
42  }
43 
44  return result;
45 }
46 
48  int status = XGBoosterCreate(nullptr, 0, &booster_);
49  if (status != 0)
50  throw std::runtime_error("Failed to create XGBooster");
51  status = XGBoosterLoadModel(booster_, model_file.c_str());
52  if (status != 0)
53  throw std::runtime_error("Failed to load XGBoost model");
54  XGBoosterSetParam(booster_, "nthread", "1");
55 }
56 
57 XGBooster::XGBooster(std::string model_file, std::string model_features) : XGBooster(model_file) {
58  std::ifstream file(model_features);
59  if (!file.is_open())
60  throw std::runtime_error("Failed to open file: " + model_features);
61 
62  std::string content((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
63  file.close();
64 
65  std::vector<std::string> features = read_features(content);
66 
67  for (const auto& feature : features) {
68  addFeature(feature);
69  }
70 }
71 
72 void XGBooster::reset() { std::fill(features_.begin(), features_.end(), std::nan("")); }
73 
75  features_.push_back(0);
77 }
78 
80 
81 float XGBooster::predict(const int iterationEnd) {
82  // check if all feature values are set properly
83  for (unsigned int i = 0; i < features_.size(); ++i)
84  if (std::isnan(features_.at(i))) {
85  std::string feature_name;
86  for (const auto& pair : feature_name_to_index_) {
87  if (pair.second == i) {
88  feature_name = pair.first;
89  break;
90  }
91  }
92  throw std::runtime_error("Feature is not set: " + feature_name);
93  }
94 
95  float const ret = predict(features_, iterationEnd);
96 
97  reset();
98 
99  return ret;
100 }
101 
102 float XGBooster::predict(const std::vector<float>& features, const int iterationEnd) const {
103  float result{-999.};
104 
105  if (features.empty()) {
106  throw std::runtime_error("Vector of input features is empty");
107  }
108 
109  if (feature_name_to_index_.size() != features.size())
110  throw std::runtime_error("Feature size mismatch");
111 
112  DMatrixHandle dvalues;
113  XGDMatrixCreateFromMat(&features[0], 1, features.size(), 9e99, &dvalues);
114 
115  bst_ulong out_len = 0;
116  const float* score = nullptr;
117 
118  char json[256]; // Make sure the buffer is large enough to hold the resulting JSON string
119 
120  // Use snprintf to format the JSON string with the external value
121  std::snprintf(json,
122  sizeof(json),
123  R"({
124  "type": 0,
125  "training": false,
126  "iteration_begin": 0,
127  "iteration_end": %d,
128  "strict_shape": false
129  })",
130  iterationEnd);
131 
132  // Shape of output prediction
133  bst_ulong const* out_shape = nullptr;
134 
135  auto ret = XGBoosterPredictFromDMatrix(booster_, dvalues, json, &out_shape, &out_len, &score);
136 
137  if (ret == 0) {
138  assert(out_len == 1 && "Unexpected prediction format");
139  result = score[0];
140  }
141 
142  XGDMatrixFree(dvalues);
143 
144  return result;
145 }
void reset()
Reset feature values.
Definition: XGBooster.cc:72
def isnan(num)
XGBooster(std::string model_file)
Definition: XGBooster.cc:47
ret
prodAgent to be discontinued
uint32_t T const *__restrict__ uint32_t const *__restrict__ int32_t int Histo::index_type cudaStream_t stream
assert(be >=bs)
BoosterHandle booster_
Definition: XGBooster.h:31
nlohmann::json json
Definition: HeavyIon.h:7
float predict(const int iterationEnd=0)
Definition: XGBooster.cc:81
std::vector< float > features(const reco::PreId &ecal, const reco::PreId &hcal, double rho, const reco::BeamSpot &spot, noZS::EcalClusterLazyTools &ecalTools)
Definition: value.py:1
std::vector< float > features_
Definition: XGBooster.h:29
std::vector< std::string > read_features(const std::string &content)
Definition: XGBooster.cc:16
void set(std::string name, float value)
Definition: XGBooster.cc:79
std::map< std::string, unsigned int > feature_name_to_index_
Definition: XGBooster.h:30
void addFeature(std::string name)
Definition: XGBooster.cc:74