CMS 3D CMS Logo

TMVAZipReader.cc
Go to the documentation of this file.
3 
4 #include <cstdio>
5 #include <cstdlib>
6 #include <zlib.h>
7 
8 using namespace std;
9 
10 // From http://stackoverflow.com/questions/874134/find-if-string-endswith-another-string-in-c
11 bool reco::details::hasEnding(std::string const& fullString, std::string const& ending)
12 {
13  if (fullString.length() >= ending.length()) {
14  return (0 == fullString.compare(fullString.length() - ending.length(), ending.length(), ending));
15  } else {
16  return false;
17  }
18 }
19 
21 {
22  FILE* f = fopen(weightFile.c_str(), "r");
23  if (f == nullptr) {
24  throw cms::Exception("InvalidFileState") << "Failed to open MVA file = " << weightFile << " !!\n";
25  }
26  int magic;
27  int size;
28  fread(&magic, 4, 1, f);
29  fseek(f, -4, SEEK_END);
30  fread(&size, 4, 1, f);
31  fclose(f);
32  // printf("%x, %i\n", magic, size);
33 
34  gzFile file = gzopen(weightFile.c_str(), "r");
35 
36  int bytes_read;
37  char* buffer = (char*)malloc(size);
38  bytes_read = gzread(file, buffer, size - 1);
39  buffer[bytes_read] = '\0';
40  if (!gzeof(file)) {
41  int err;
42  const char* error_string;
43  error_string = gzerror(file, &err);
44  if (err) {
45  free(buffer);
46  throw cms::Exception("InvalidFileState") << "Error while reading gzipped file = "
47  << weightFile << " !!\n" << error_string;
48  }
49  }
50  gzclose(file);
51  return buffer;
52 }
53 
55  TMVA::Reader* reader, const std::string& method, const std::string& weightFile, bool verbose)
56 {
57 
58  TMVA::IMethod* ptr = nullptr;
59 
60  verbose = false;
61  if (verbose)
62  std::cout << "Booking TMVA Reader with " << method << " and weight file: " << weightFile << std::endl;
63 
64  if (reco::details::hasEnding(weightFile, ".xml")) {
65  if (verbose)
66  std::cout << "Weight file is pure xml." << std::endl;
67  // Let TMVA read the file
68  ptr = reader->BookMVA(method, weightFile);
69  } else if (reco::details::hasEnding(weightFile, ".gz") || reco::details::hasEnding(weightFile, ".gzip")) {
70  if (verbose)
71  std::cout << "Unzipping file." << std::endl;
72  char* c = readGzipFile(weightFile);
73 
74  // We can't use tmpnam, gcc emits a warning about security.
75  // This is also technically insecure in the same way, since we append
76  // a suffix and then open another file.
77  char tmpFilename[] = "/tmp/tmva.XXXXXX";
78  int fdToUselessFile = mkstemp(tmpFilename);
79  std::string weight_file_name(tmpFilename);
80  weight_file_name += ".xml";
81  FILE* theActualFile = fopen(weight_file_name.c_str(), "w");
82  if (theActualFile != nullptr) {
83  // write xml
84  fputs(c, theActualFile);
85  fputs("\n", theActualFile);
86  fclose(theActualFile);
87  close(fdToUselessFile);
88  } else {
89  throw cms::Exception("CannotWriteFile") << "Error while writing file = " << weight_file_name << " !!\n";
90  }
91  if (verbose)
92  std::cout << "Booking MvA" << std::endl;
93  ptr = reader->BookMVA(method, weight_file_name);
94  if (verbose)
95  std::cout << "Cleaning up" << std::endl;
96  remove(weight_file_name.c_str());
97  remove(tmpFilename);
98 
99  // Someday this will work.
100  // reader->BookMVA(TMVA::Types::Instance().GetMethodType(TString(method)), c);
101  if (verbose) {
102  std::cout << "Reader booked" << std::endl;
103  }
104  free(c);
105  } else {
106  throw cms::Exception("BadTMVAWeightFilename")
107  << "I don't understand the extension on the filename: " << weightFile
108  << ", it should be .xml, .gz, or .gzip" << std::endl;
109  }
110 
111  return ptr;
112 }
size
Write out results.
bool hasEnding(std::string const &fullString, std::string const &ending)
double f[11][100]
char * readGzipFile(const std::string &weightFile)
TMVA::IMethod * loadTMVAWeights(TMVA::Reader *reader, const std::string &method, const std::string &weightFile, bool verbose=false)