CMS 3D CMS Logo

Classes | Macros | Typedefs | Enumerations | Functions | Variables
fastHadd.cc File Reference
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <vector>
#include <set>
#include <string>
#include <iostream>
#include <memory>
#include <thread>
#include <mutex>
#include <list>
#include "DQMServices/Core/src/ROOTFilePB.pb.h"
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/gzip_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <TROOT.h>
#include <TFile.h>
#include <TBufferFile.h>
#include <TObject.h>
#include <TObjString.h>
#include <TH1.h>
#include <TProfile.h>
#include <TKey.h>
#include <TClass.h>
#include <sys/prctl.h>
#include <sys/wait.h>
#include <csignal>

Go to the source code of this file.

Classes

struct  MicroME
 

Macros

#define DEBUG(x, msg)   if (debug >= x) std::cout << "DEBUG: " << msg << std::flush
 

Typedefs

using MEStore = std::set< MicroME >
 

Enumerations

enum  ErrType { ERR_BADCFG =1, ERR_NOFILE }
 
enum  TaskType { TASK_ADD, TASK_DUMP, TASK_CONVERT, TASK_ENCODE }
 

Functions

int addFile (MEStore &micromes, int fd)
 
int addFiles (const std::string &output_filename, const std::vector< std::string > &filenames, int nthreads)
 
void addFilesWithFork (int parent_fd, const int fork_id, const int fork_total, const std::vector< std::string > &filenames)
 
int convertFile (const std::string &output_filename, const std::vector< std::string > &filenames)
 
int dumpFiles (const std::vector< std::string > &filenames)
 
int encodeFile (const std::string &output_filename, const std::vector< std::string > &filenames)
 
TObject * extractNextObject (TBufferFile &buf)
 
void fillMessage (dqmstorepb::ROOTFilePB &dqmstore_output_msg, const MEStore &micromes)
 
static void get_info (const dqmstorepb::ROOTFilePB::Histo &h, std::string &dirname, std::string &objname, TObject **obj)
 
int main (int argc, char *argv[])
 
void processDirectory (TFile *file, const std::string &curdir, MEStore &micromes)
 
static int showusage ()
 
void tryRootPreload ()
 
void writeMessage (const dqmstorepb::ROOTFilePB &dqmstore_output_msg, const std::string &output_filename)
 
void writeMessageFD (const dqmstorepb::ROOTFilePB &dqmstore_output_msg, int out_fd)
 

Variables

int debug = 0
 

Macro Definition Documentation

#define DEBUG (   x,
  msg 
)    if (debug >= x) std::cout << "DEBUG: " << msg << std::flush

Copyright (c) 2013 "Marco Rovere"

This code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

This code is simple: its sole purpose is to either dump or add ProtocolBuffer-gzipped files that are meant to replace ordinary ROOT files containing only hierarchies of histograms, arranged in arbitrarily complex levels of directories. The merging logic is such that plots present in all files are added, while plots present in some of the files are anyway tracked and added, if similar ones are found in other files.

The logic of the merging algorithm is trivial and fully rely on the ordered nature of the ProtocolBuffer files read in input. An internal set container of MicroME is used to host the final results. The relational ordering of the set must be guaranteed to match the one used to order the ProtocolBuffer files for optimal performance and correctness.

A dependency on protocolbuffer is needed and should be alrady included out of the box into any recent CMSSW release.

In case the protoclBuffer package is not avaialble, you need to install it as an external toolfile. Therefore, in order to be able to compile and run the code, you need to locally install protocol buffer 2.4.1 and add it as a scram tool to your preferred CMSSW development area.

The toolfile I used is:

<tool name="protocolbuf" version="2.4.1"> <client> <environment name="PROTOCOLBUF_CLIENT_BASE" default="/afs/cern.ch/work/r/rovere/protocolbuf"> <environment name="LIBDIR" value="$PROTOCOLBUF_CLIENT_BASE/lib"> <environment name="INCLUDE" value="$PROTOCOLBUF_CLIENT_BASE/include"> <environment name="PATH" value="$PROTOCOLBUF_CLIENT_BASE/bin"> <lib name="protobuf"> <use name="zlib"> </client> <runtime name="PATH" value="$PROTOCOLBUF_CLIENT_BASE/bin"> </tool>

To register it into your development area you can simply do:

scram setup protocolbuf.xml

To verify the correctness of the information, do:

scram tool info protocolbuf. You should see an output similar to the following:

Tool info as configured in location /afs/cern.ch/work/r/rovere/fastHistoMergingPB/CMSSW_7_0_X_2013-07-08-0200 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Name : protocolbuf Version : 2.4.1 ++++++++++++++++++++ SCRAM_PROJECT=no PROTOCOLBUF_CLIENT_BASE=/afs/cern.ch/work/r/rovere/protocolbuf LIB=protobuf LIBDIR=/afs/cern.ch/work/r/rovere/protocolbuf/lib INCLUDE=/afs/cern.ch/work/r/rovere/protocolbuf/include USE=zlib PATH=/afs/cern.ch/work/r/rovere/protocolbuf/bin

Definition at line 109 of file fastHadd.cc.

Referenced by MicroME::add(), addFile(), addFiles(), addFilesWithFork(), convertFile(), dumpFiles(), encodeFile(), fillMessage(), processDirectory(), and writeMessage().

Typedef Documentation

using MEStore = std::set<MicroME>

Definition at line 156 of file fastHadd.cc.

Enumeration Type Documentation

enum ErrType
Enumerator
ERR_BADCFG 
ERR_NOFILE 

Definition at line 165 of file fastHadd.cc.

165  {
166  ERR_BADCFG=1,
167  ERR_NOFILE
168 };
enum TaskType
Enumerator
TASK_ADD 
TASK_DUMP 
TASK_CONVERT 
TASK_ENCODE 

Definition at line 158 of file fastHadd.cc.

158  {
159  TASK_ADD,
160  TASK_DUMP,
161  TASK_CONVERT,
163 };

Function Documentation

int addFile ( MEStore micromes,
int  fd 
)

Definition at line 399 of file fastHadd.cc.

References MicroME::add(), gather_cfg::cout, DEBUG, ERR_NOFILE, groupFilesInBlocks::fin, dqmstorepb::ROOTFilePB_Histo::flags(), get_info(), h, dqmstorepb::ROOTFilePB::histo(), dqmstorepb::ROOTFilePB::histo_size(), mps_fire::i, input, MicroME::obj, MicroME::objname, callgraph::path, and AlCaHLTBitMon_QueryRunRegistry::string.

Referenced by addFilesWithFork().

399  {
400  dqmstorepb::ROOTFilePB dqmstore_msg;
401 
402  FileInputStream fin(fd);
403  GzipInputStream input(&fin);
404  CodedInputStream input_coded(&input);
405  input_coded.SetTotalBytesLimit(1024*1024*1024, -1);
406  if (!dqmstore_msg.ParseFromCodedStream(&input_coded)) {
407  std::cout << "Fatal decoding stream: "
408  << fd << std::endl;
409  return ERR_NOFILE;
410  }
411 
412  auto hint = micromes.begin();
413  for (int i = 0; i < dqmstore_msg.histo_size(); i++) {
415  std::string objname;
416  TObject *obj = nullptr;
417  const dqmstorepb::ROOTFilePB::Histo &h = dqmstore_msg.histo(i);
418  get_info(h, path, objname, &obj);
419 
420  MicroME mme(nullptr, path, objname, h.flags());
421  auto ir = micromes.insert(hint, mme);
422  if (ir->obj != nullptr) {
423  // new element was not added
424  // so we merge
425 
426  ir->add(obj);
427  delete obj;
428  DEBUG(2, "Merged MicroME " << mme.fullname() << std::endl);
429  } else {
430  ir->obj = obj;
431  DEBUG(2, "Inserted MicroME " << mme.fullname() << std::endl);
432  }
433 
434  hint = ir;
435  ++hint;
436  }
437 
438  return 0;
439 }
static void get_info(const dqmstorepb::ROOTFilePB::Histo &h, std::string &dirname, std::string &objname, TObject **obj)
Definition: fastHadd.cc:189
FWCore Framework interface EventSetupRecordImplementation h
Helper function to determine trigger accepts.
void add(TObject *obj_to_add) const
Definition: fastHadd.cc:135
static std::string const input
Definition: EdmProvDump.cc:45
const ::dqmstorepb::ROOTFilePB_Histo & histo(int index) const
::google::protobuf::uint32 flags() const
#define DEBUG(x, msg)
Definition: fastHadd.cc:109
int addFiles ( const std::string &  output_filename,
const std::vector< std::string > &  filenames,
int  nthreads 
)

Definition at line 536 of file fastHadd.cc.

References addFilesWithFork(), DEBUG, and tryRootPreload().

Referenced by main().

538  {
539 
540  tryRootPreload();
541 
542  DEBUG(1, "Writing file" << std::endl);
543  int out_fd = ::open(output_filename.c_str(),
544  O_WRONLY | O_CREAT | O_TRUNC,
545  S_IRUSR | S_IWUSR |
546  S_IRGRP | S_IWGRP |
547  S_IROTH);
548 
549  addFilesWithFork(out_fd, 1, nthreads, filenames);
550  ::close(out_fd);
551 
552  return 0;
553 }
void tryRootPreload()
Definition: fastHadd.cc:444
void addFilesWithFork(int parent_fd, const int fork_id, const int fork_total, const std::vector< std::string > &filenames)
Definition: fastHadd.cc:469
#define DEBUG(x, msg)
Definition: fastHadd.cc:109
void addFilesWithFork ( int  parent_fd,
const int  fork_id,
const int  fork_total,
const std::vector< std::string > &  filenames 
)

Definition at line 469 of file fastHadd.cc.

References addFile(), class-composition::children, gather_cfg::cout, DEBUG, ERR_NOFILE, cmsRelvalreport::exit, FrontierConditions_GlobalTag_cff::file, fillMessage(), mps_fire::i, pipe::pipe(), mps_update::status, AlCaHLTBitMon_QueryRunRegistry::string, and writeMessageFD().

Referenced by addFiles().

469  {
470  DEBUG(1, "Start process: " << fork_id << " parent: " << (fork_id / 2) << std::endl);
471 
472  std::list<std::pair<int, int> > children;
473 
474  // if this node has a subtree, start it
475  for (int i = 0; i < 2; ++i) {
476  int child_id = fork_id*2 + i;
477  if (child_id > fork_total)
478  continue;
479 
480  int fd[2];
481  ::pipe(fd);
482 
483  int child_pid = ::fork();
484  if (child_pid == 0) {
485  ::prctl(PR_SET_PDEATHSIG, SIGKILL);
486  ::close(fd[0]); // close read end
487 
488  addFilesWithFork(fd[1], child_id, fork_total, filenames);
489  ::close(fd[1]);
490 
491  ::_exit(0);
492  } else {
493  ::close(fd[1]); // close write end
494  children.push_back(std::make_pair(fd[0], child_pid));
495  }
496  }
497 
498  // merge all my files
499  MEStore microme;
500 
501  // select the filenames to process
502  // with threads=1, this just selects all the files
503  for (unsigned int fi = fork_id - 1; fi < filenames.size(); fi += fork_total) {
504  const std::string& file = filenames[fi];
505  DEBUG(1, "Adding file " << file << std::endl);
506 
507  int filedescriptor;
508  if ((filedescriptor = ::open(file.c_str(), O_RDONLY)) == -1) {
509  std::cout << "Fatal Error opening file "
510  << file << std::endl;
511 
512  exit(ERR_NOFILE);
513  }
514 
515  addFile(microme, filedescriptor);
516  ::close(filedescriptor);
517  }
518 
519  // merge all children
520  for (auto& chpair : children) {
521  int fd = chpair.first;
522  addFile(microme, fd);
523  ::close(fd);
524 
525  // collect the child, not necessary, but avoids <defunct>
526  int status;
527  ::waitpid(chpair.second, &status, 0);
528  }
529 
530  // output everything to fd
531  dqmstorepb::ROOTFilePB dqmstore_output_msg;
532  fillMessage(dqmstore_output_msg, microme);
533  writeMessageFD(dqmstore_output_msg, parent_fd);
534 };
def pipe(cmdline, input=None)
Definition: pipe.py:5
void writeMessageFD(const dqmstorepb::ROOTFilePB &dqmstore_output_msg, int out_fd)
Definition: fastHadd.cc:209
void fillMessage(dqmstorepb::ROOTFilePB &dqmstore_output_msg, const MEStore &micromes)
Definition: fastHadd.cc:239
std::set< MicroME > MEStore
Definition: fastHadd.cc:156
int addFile(MEStore &micromes, int fd)
Definition: fastHadd.cc:399
void addFilesWithFork(int parent_fd, const int fork_id, const int fork_total, const std::vector< std::string > &filenames)
Definition: fastHadd.cc:469
#define DEBUG(x, msg)
Definition: fastHadd.cc:109
int convertFile ( const std::string &  output_filename,
const std::vector< std::string > &  filenames 
)

Definition at line 306 of file fastHadd.cc.

References gather_cfg::cout, DEBUG, end, ERR_NOFILE, extractNextObject(), groupFilesInBlocks::fin, dqmstorepb::ROOTFilePB_Histo::full_pathname(), get_info(), h, dqmstorepb::ROOTFilePB::histo(), dqmstorepb::ROOTFilePB::histo_size(), mps_fire::i, input, MicroME::obj, MicroME::objname, convertSQLitetoXML_cfg::output, callgraph::path, dqmstorepb::ROOTFilePB_Histo::size(), dqmstorepb::ROOTFilePB_Histo::streamed_histo(), and AlCaHLTBitMon_QueryRunRegistry::string.

Referenced by main().

307  {
308  assert(filenames.size() == 1);
309  TFile output(output_filename.c_str(), "RECREATE");
310  DEBUG(0, "Converting file " << filenames[0] << std::endl);
311  dqmstorepb::ROOTFilePB dqmstore_message;
312 
313  int filedescriptor = ::open(filenames[0].c_str(), O_RDONLY);
314  FileInputStream fin(filedescriptor);
315  GzipInputStream input(&fin);
316  CodedInputStream input_coded(&input);
317  input_coded.SetTotalBytesLimit(1024*1024*1024, -1);
318  if (!dqmstore_message.ParseFromCodedStream(&input_coded)) {
319  std::cout << "Fatal Error opening file "
320  << filenames[0] << std::endl;
321  return ERR_NOFILE;
322  }
323  ::close(filedescriptor);
324 
325  for (int i = 0; i < dqmstore_message.histo_size(); i++) {
326  const dqmstorepb::ROOTFilePB::Histo& h = dqmstore_message.histo(i);
327  DEBUG(1, h.full_pathname() << std::endl);
328  DEBUG(1, h.size() << std::endl);
329  TBufferFile buf(TBufferFile::kRead, h.size(),
330  (void*)h.streamed_histo().data(),
331  kFALSE);
332  buf.Reset();
333  TObject *obj = extractNextObject(buf);
334  std::string path,objname;
335  get_info(h, path, objname, &obj);
336  gDirectory->cd("/");
337  // Find the first path component.
338  size_t start = 0;
339  size_t end = path.find('/', start);
340  if (end == std::string::npos)
341  end = path.size();
342  while (true)
343  {
344  std::string part(path, start, end-start);
345  if (! gDirectory->Get(part.c_str()))
346  gDirectory->mkdir(part.c_str());
347  gDirectory->cd(part.c_str());
348  // Stop if we reached the end, ignoring any trailing '/'.
349  if (end+1 >= path.size())
350  break;
351  // Find the next path component.
352  start = end+1;
353  end = path.find('/', start);
354  if (end == std::string::npos)
355  end = path.size();
356  }
357  obj->Write();
358  DEBUG(1, obj->GetName() << std::endl);
359  }
360  output.Close();
361  return 0;
362 }
Definition: start.py:1
::google::protobuf::uint32 size() const
const ::std::string & full_pathname() const
static void get_info(const dqmstorepb::ROOTFilePB::Histo &h, std::string &dirname, std::string &objname, TObject **obj)
Definition: fastHadd.cc:189
FWCore Framework interface EventSetupRecordImplementation h
Helper function to determine trigger accepts.
TObject * extractNextObject(TBufferFile &buf)
Definition: fastHadd.cc:181
const ::std::string & streamed_histo() const
static std::string const input
Definition: EdmProvDump.cc:45
#define end
Definition: vmac.h:39
const ::dqmstorepb::ROOTFilePB_Histo & histo(int index) const
part
Definition: HCALResponse.h:20
#define DEBUG(x, msg)
Definition: fastHadd.cc:109
int dumpFiles ( const std::vector< std::string > &  filenames)

Definition at line 364 of file fastHadd.cc.

References gather_cfg::cout, DEBUG, MillePedeFileConverter_cfg::e, ERR_NOFILE, extractNextObject(), groupFilesInBlocks::fin, dqmstorepb::ROOTFilePB_Histo::flags(), dqmstorepb::ROOTFilePB_Histo::full_pathname(), h, dqmstorepb::ROOTFilePB::histo(), dqmstorepb::ROOTFilePB::histo_size(), mps_fire::i, input, MicroME::obj, dqmstorepb::ROOTFilePB_Histo::size(), and dqmstorepb::ROOTFilePB_Histo::streamed_histo().

Referenced by main().

364  {
365  assert(!filenames.empty());
366  for (int i = 0, e = filenames.size(); i != e; ++i) {
367  DEBUG(0, "Dumping file " << filenames[i] << std::endl);
368  dqmstorepb::ROOTFilePB dqmstore_message;
369 
370  int filedescriptor = ::open(filenames[0].c_str(), O_RDONLY);
371  FileInputStream fin(filedescriptor);
372  GzipInputStream input(&fin);
373  CodedInputStream input_coded(&input);
374  input_coded.SetTotalBytesLimit(1024*1024*1024, -1);
375  if (!dqmstore_message.ParseFromCodedStream(&input_coded)) {
376  std::cout << "Fatal Error opening file "
377  << filenames[0] << std::endl;
378  return ERR_NOFILE;
379  }
380  ::close(filedescriptor);
381 
382  for (int i = 0; i < dqmstore_message.histo_size(); i++) {
383  const dqmstorepb::ROOTFilePB::Histo& h = dqmstore_message.histo(i);
384  DEBUG(1, h.full_pathname() << std::endl);
385  DEBUG(1, h.size() << std::endl);
386  TBufferFile buf(TBufferFile::kRead, h.size(),
387  (void*)h.streamed_histo().data(),
388  kFALSE);
389  buf.Reset();
390  TObject *obj = extractNextObject(buf);
391  DEBUG(1, obj->GetName() << std::endl);
392  DEBUG(1, "Flags: " << h.flags() << std::endl);
393  }
394  }
395 
396  return 0;
397 }
::google::protobuf::uint32 size() const
const ::std::string & full_pathname() const
FWCore Framework interface EventSetupRecordImplementation h
Helper function to determine trigger accepts.
TObject * extractNextObject(TBufferFile &buf)
Definition: fastHadd.cc:181
const ::std::string & streamed_histo() const
static std::string const input
Definition: EdmProvDump.cc:45
const ::dqmstorepb::ROOTFilePB_Histo & histo(int index) const
::google::protobuf::uint32 flags() const
#define DEBUG(x, msg)
Definition: fastHadd.cc:109
int encodeFile ( const std::string &  output_filename,
const std::vector< std::string > &  filenames 
)

Definition at line 291 of file fastHadd.cc.

References DEBUG, fillMessage(), input, processDirectory(), and writeMessage().

Referenced by main().

292  {
293  assert(filenames.size() == 1);
294  TFile input(filenames[0].c_str());
295  DEBUG(0, "Encoding file " << filenames[0] << std::endl);
296  MEStore micromes;
297  dqmstorepb::ROOTFilePB dqmstore_message;
298 
299  processDirectory(&input, "", micromes);
300  fillMessage(dqmstore_message, micromes);
301  writeMessage(dqmstore_message, output_filename);
302 
303  return 0;
304 }
void processDirectory(TFile *file, const std::string &curdir, MEStore &micromes)
Definition: fastHadd.cc:260
static std::string const input
Definition: EdmProvDump.cc:45
void fillMessage(dqmstorepb::ROOTFilePB &dqmstore_output_msg, const MEStore &micromes)
Definition: fastHadd.cc:239
void writeMessage(const dqmstorepb::ROOTFilePB &dqmstore_output_msg, const std::string &output_filename)
Definition: fastHadd.cc:223
std::set< MicroME > MEStore
Definition: fastHadd.cc:156
#define DEBUG(x, msg)
Definition: fastHadd.cc:109
TObject* extractNextObject ( TBufferFile &  buf)
inline

Extract the next serialised ROOT object from buf. Returns null if there are no more objects in the buffer, or a null pointer was serialised at this location.

Definition at line 181 of file fastHadd.cc.

Referenced by convertFile(), dumpFiles(), get_info(), DQMStore::mtEnabled(), and DQMNet::unpackQualityData().

181  {
182  if (buf.Length() == buf.BufferSize())
183  return nullptr;
184 
185  buf.InitMap();
186  return reinterpret_cast<TObject *>(buf.ReadObjectAny(nullptr));
187 }
void fillMessage ( dqmstorepb::ROOTFilePB dqmstore_output_msg,
const MEStore micromes 
)

Definition at line 239 of file fastHadd.cc.

References dqmstorepb::ROOTFilePB::add_histo(), edmScanValgrind::buffer, DEBUG, h, dqmstorepb::ROOTFilePB_Histo::set_flags(), dqmstorepb::ROOTFilePB_Histo::set_full_pathname(), dqmstorepb::ROOTFilePB_Histo::set_size(), and dqmstorepb::ROOTFilePB_Histo::set_streamed_histo().

Referenced by addFilesWithFork(), and encodeFile().

240  {
241  auto mi = micromes.begin();
242  auto me = micromes.end();
243 
244  DEBUG(1, "Streaming ROOT objects" << std::endl);
245  for (; mi != me; ++mi) {
246  dqmstorepb::ROOTFilePB::Histo* h = dqmstore_output_msg.add_histo();
247  DEBUG(2, "Streaming ROOT object " << mi->fullname() << "\n");
248  h->set_full_pathname(mi->fullname());
249  TBufferFile buffer(TBufferFile::kWrite);
250  buffer.WriteObject(mi->obj);
251  h->set_size(buffer.Length());
252  h->set_flags(mi->flags);
253  h->set_streamed_histo((const void*)buffer.Buffer(),
254  buffer.Length());
255  delete mi->obj;
256  }
257 }
FWCore Framework interface EventSetupRecordImplementation h
Helper function to determine trigger accepts.
void set_flags(::google::protobuf::uint32 value)
void set_size(::google::protobuf::uint32 value)
void set_full_pathname(const ::std::string &value)
::dqmstorepb::ROOTFilePB_Histo * add_histo()
#define DEBUG(x, msg)
Definition: fastHadd.cc:109
void set_streamed_histo(const ::std::string &value)
static void get_info ( const dqmstorepb::ROOTFilePB::Histo h,
std::string &  dirname,
std::string &  objname,
TObject **  obj 
)
static

Definition at line 189 of file fastHadd.cc.

References MessageLogger_cfi::cerr, extractNextObject(), dqmstorepb::ROOTFilePB_Histo::full_pathname(), dqmstorepb::ROOTFilePB_Histo::size(), pickleFileParser::slash, and dqmstorepb::ROOTFilePB_Histo::streamed_histo().

Referenced by addFile(), convertFile(), external::HEPTopTaggerV2_fixed_R::fat_initial(), DQMStore::mtEnabled(), and tryRootPreload().

192  {
193 
194  size_t slash = h.full_pathname().rfind('/');
195  size_t dirpos = (slash == std::string::npos ? 0 : slash);
196  size_t namepos = (slash == std::string::npos ? 0 : slash+1);
197  dirname.assign(h.full_pathname(), 0, dirpos);
198  objname.assign(h.full_pathname(), namepos, std::string::npos);
199  TBufferFile buf(TBufferFile::kRead, h.size(),
200  (void*)h.streamed_histo().data(),
201  kFALSE);
202  buf.Reset();
203  *obj = extractNextObject(buf);
204  if (!*obj) {
205  std::cerr << "Error reading element: " << h.full_pathname() << std::endl;
206  }
207 }
::google::protobuf::uint32 size() const
const ::std::string & full_pathname() const
TObject * extractNextObject(TBufferFile &buf)
Definition: fastHadd.cc:181
const ::std::string & streamed_histo() const
int main ( int  argc,
char *  argv[] 
)

Definition at line 569 of file fastHadd.cc.

References addFiles(), dir2webdir::argc, MessageLogger_cfi::cerr, convertFile(), debug, dumpFiles(), encodeFile(), cmsPerfCommons::filenames, mps_setup::jobs, showusage(), AlCaHLTBitMon_QueryRunRegistry::string, TASK_ADD, TASK_CONVERT, TASK_DUMP, and TASK_ENCODE.

569  {
570  int arg;
571  int ret = 0;
572  int jobs = 1;
573  std::string output_file;
574  std::vector<std::string> filenames;
575  TaskType task;
576 
577  filenames.reserve(argc);
578 
579  for (arg = 1; arg < argc; ++arg) {
580  if (! strcmp(argv[arg], "--no-debug"))
581  debug = 0;
582  else if (! strcmp(argv[arg], "--debug")
583  || ! strcmp(argv[arg], "-d"))
584  debug++;
585  else
586  break;
587  }
588 
589  if (arg < argc) {
590  if (! strcmp(argv[arg], "add")) {
591  ++arg;
592  task = TASK_ADD;
593  } else if (! strcmp(argv[arg], "dump")) {
594  ++arg;
595  task = TASK_DUMP;
596  } else if (! strcmp(argv[arg], "convert")) {
597  ++arg;
598  task = TASK_CONVERT;
599  } else if (! strcmp(argv[arg], "encode")) {
600  ++arg;
601  task = TASK_ENCODE;
602  } else {
603  std::cerr << "Unknown action: " << argv[arg] << std::endl;
604  return showusage();
605  }
606  } else {
607  std::cerr << "Not enough arguments\n";
608  return showusage();
609  }
610 
611  if (task == TASK_ADD) {
612  if ((arg != argc) && (strcmp(argv[arg], "-j") == 0)) {
613  jobs = atoi(argv[arg+1]);
614 
615  if ((jobs < 1) || (jobs > 128)) {
616  std::cerr << "Invalid argument for -j\n";
617  return showusage();
618  };
619 
620  arg += 2;
621  }
622  }
623 
624  if (task == TASK_ADD || task == TASK_CONVERT || task == TASK_ENCODE) {
625  if (arg == argc) {
626  std::cerr << "add|convert|encode actions requires a -o option to be set\n";
627  return showusage();
628  }
629  if (! strcmp(argv[arg], "-o")) {
630  if (arg < argc-1) {
631  output_file = argv[++arg];
632  } else {
633  std::cerr << " -o option requires a value\n";
634  return showusage();
635  }
636  }
637  } else if (task == TASK_DUMP) {
638  if (arg == argc) {
639  std::cerr << "Missing input file(s)\n";
640  return showusage();
641  }
642  for (; arg < argc; ++arg) {
643  filenames.emplace_back(argv[arg]);
644  }
645  }
646 
647  if (task == TASK_ADD || task == TASK_CONVERT || task == TASK_ENCODE) {
648  if (++arg == argc) {
649  std::cerr << "Missing input file(s)\n";
650  return showusage();
651  }
652  for (; arg < argc; ++arg) {
653  filenames.emplace_back(argv[arg]);
654  }
655  }
656 
657  if (task == TASK_ADD)
658  ret = addFiles(output_file, filenames, jobs);
659  else if (task == TASK_DUMP)
660  ret = dumpFiles(filenames);
661  else if (task == TASK_CONVERT)
662  ret = convertFile(output_file, filenames);
663  else if (task == TASK_ENCODE)
664  ret = encodeFile(output_file, filenames);
665 
666 
667  google::protobuf::ShutdownProtobufLibrary();
668  return ret;
669 }
A arg
Definition: Factorize.h:37
int debug
Definition: fastHadd.cc:111
TaskType
Definition: fastHadd.cc:158
int encodeFile(const std::string &output_filename, const std::vector< std::string > &filenames)
Definition: fastHadd.cc:291
int convertFile(const std::string &output_filename, const std::vector< std::string > &filenames)
Definition: fastHadd.cc:306
int addFiles(const std::string &output_filename, const std::vector< std::string > &filenames, int nthreads)
Definition: fastHadd.cc:536
static int showusage()
Definition: fastHadd.cc:556
int dumpFiles(const std::vector< std::string > &filenames)
Definition: fastHadd.cc:364
void processDirectory ( TFile *  file,
const std::string &  curdir,
MEStore micromes 
)

Definition at line 260 of file fastHadd.cc.

References DEBUG, crabWrapper::key, GetRecoTauVFromDQM_MC_cff::next, MicroME::obj, and AlCaHLTBitMon_QueryRunRegistry::string.

Referenced by encodeFile().

262  {
263  DEBUG(1, "Processing directory " << curdir << "\n");
264  file->cd(curdir.c_str());
265  TKey *key;
266  TIter next (gDirectory->GetListOfKeys());
267  while ((key = (TKey *) next())) {
268  TObject * obj = key->ReadObj();
269  if (dynamic_cast<TDirectory *>(obj)) {
270  std::string subdir;
271  subdir.reserve(curdir.size() + strlen(obj->GetName()) + 2);
272  subdir += curdir;
273  if (! curdir.empty())
274  subdir += '/';
275  subdir += obj->GetName();
276  processDirectory(file, subdir, micromes);
277  } else if ((dynamic_cast<TH1 *>(obj)) || (dynamic_cast<TObjString *>(obj))) {
278  if (dynamic_cast<TH1 *>(obj)) {
279  dynamic_cast<TH1 *>(obj)->SetDirectory(nullptr);
280  }
281 
282  DEBUG(2, curdir << "/" << obj->GetName() << "\n");
283  MicroME mme(obj, curdir, obj->GetName());
284 
285  micromes.insert(mme);
286  }
287  }
288 }
void processDirectory(TFile *file, const std::string &curdir, MEStore &micromes)
Definition: fastHadd.cc:260
#define DEBUG(x, msg)
Definition: fastHadd.cc:109
static int showusage ( )
static

Definition at line 556 of file fastHadd.cc.

References MessageLogger_cfi::cerr, ERR_BADCFG, and AlCaHLTBitMon_QueryRunRegistry::string.

Referenced by main().

557 {
558  static const std::string app_name("fasthadd");
559 
560  std::cerr << "Usage: " << app_name
561  << " [--[no-]debug] TASK OPTIONS\n\n "
562  << app_name << " [OPTIONS] add [-j NUM_THREADS] -o OUTPUT_FILE [DAT FILE...]\n "
563  << app_name << " [OPTIONS] convert -o ROOT_FILE DAT_FILE\n "
564  << app_name << " [OPTIONS] encode -o DAT_FILE ROOT_FILE\n "
565  << app_name << " [OPTIONS] dump [DAT FILE...]\n ";
566  return ERR_BADCFG;
567 }
void tryRootPreload ( )

Definition at line 444 of file fastHadd.cc.

References dqmstorepb::ROOTFilePB::add_histo(), get_info(), dqmstorepb::ROOTFilePB::histo(), AnalysisDataFormats_SUSYBSMObjects::hr, MicroME::obj, MicroME::objname, callgraph::path, dqmstorepb::ROOTFilePB_Histo::set_flags(), dqmstorepb::ROOTFilePB_Histo::set_size(), dqmstorepb::ROOTFilePB_Histo::set_streamed_histo(), and AlCaHLTBitMon_QueryRunRegistry::string.

Referenced by addFiles().

444  {
445  // write a single histogram
446  TH1F obj_th1f("preload_th1f", "preload_th1f", 2, 0, 1);
447 
448  TBufferFile write_buffer(TBufferFile::kWrite);
449  write_buffer.WriteObject(&obj_th1f);
450 
451  dqmstorepb::ROOTFilePB preload_file;
452  dqmstorepb::ROOTFilePB::Histo* hw = preload_file.add_histo();
453  hw->set_size(write_buffer.Length());
454  hw->set_flags(0);
455  hw->set_streamed_histo((const void*)write_buffer.Buffer(), write_buffer.Length());
456 
457  // now load this th1f
458  const dqmstorepb::ROOTFilePB::Histo &hr = preload_file.histo(0);
460  std::string objname;
461  TObject *obj = nullptr;
462  get_info(hr, path, objname, &obj);
463  delete obj;
464 
465  // all done
466 }
static void get_info(const dqmstorepb::ROOTFilePB::Histo &h, std::string &dirname, std::string &objname, TObject **obj)
Definition: fastHadd.cc:189
void set_flags(::google::protobuf::uint32 value)
susybsm::HSCParticleRef hr
Definition: classes.h:26
const ::dqmstorepb::ROOTFilePB_Histo & histo(int index) const
void set_size(::google::protobuf::uint32 value)
::dqmstorepb::ROOTFilePB_Histo * add_histo()
void set_streamed_histo(const ::std::string &value)
void writeMessage ( const dqmstorepb::ROOTFilePB dqmstore_output_msg,
const std::string &  output_filename 
)

Definition at line 223 of file fastHadd.cc.

References DEBUG, and writeMessageFD().

Referenced by encodeFile().

224  {
225 
226  DEBUG(1, "Writing file" << std::endl);
227 
228  int out_fd = ::open(output_filename.c_str(),
229  O_WRONLY | O_CREAT | O_TRUNC,
230  S_IRUSR | S_IWUSR |
231  S_IRGRP | S_IWGRP |
232  S_IROTH);
233 
234  writeMessageFD(dqmstore_output_msg, out_fd);
235  ::close(out_fd);
236 }
void writeMessageFD(const dqmstorepb::ROOTFilePB &dqmstore_output_msg, int out_fd)
Definition: fastHadd.cc:209
#define DEBUG(x, msg)
Definition: fastHadd.cc:109
void writeMessageFD ( const dqmstorepb::ROOTFilePB dqmstore_output_msg,
int  out_fd 
)

Definition at line 209 of file fastHadd.cc.

References AlcaSiPixelAliHarvester0T_cff::options.

Referenced by addFilesWithFork(), and writeMessage().

209  {
210  FileOutputStream out_stream(out_fd);
212  options.format = GzipOutputStream::GZIP;
213  options.compression_level = 2;
214  GzipOutputStream gzip_stream(&out_stream,
215  options);
216  dqmstore_output_msg.SerializeToZeroCopyStream(&gzip_stream);
217 
218  // make sure we flush before close
219  gzip_stream.Close();
220  out_stream.Close();
221 }
std::vector< std::shared_ptr< fireworks::OptionNode > > Options

Variable Documentation

int debug = 0

Definition at line 111 of file fastHadd.cc.

Referenced by main().