RootWriter.cc

00001 #include "Message.hh"
00002 #include "RootWriter.hh"
00003 #include "ConfigHandler.hh"
00004 #include "CommandSwitchFunctions.hh"
00005 #include "TClass.h"
00006 #include "TDataMember.h"
00007 #include "TROOT.h"
00008 #include "TMacro.h"
00009 
00010 #include "TFile.h"
00011 #include "TTree.h"
00012 #include <string>
00013 #include <sstream>
00014 
00015 
00016 RootWriter::RootWriter() : 
00017   BaseModule("RootWriter","Save processed data into a ROOT tree"), 
00018   _filename(), _mode(), _outfile(0), _tree(0), 
00019   enabler(this), disabler(this)
00020 {
00021   //default initialize filename
00022   /*
00023   time_t rawtime;
00024   time(&rawtime);
00025   struct tm *timeinfo;
00026   timeinfo = localtime(&rawtime);
00027   char fbuf[40];
00028   strftime(fbuf,40,"processed_%y%m%d_%H%M.root",timeinfo);
00029   _filename = fbuf;
00030   */
00031   _filename = GetDefaultFilename();
00032   RegisterParameter("filename",_filename, 
00033                     "Name of the output root filename");
00034   RegisterParameter("directory",_directory=".",
00035                     "Directory in which to place the output root file");
00036   RegisterParameter("mode",_mode="RECREATE",
00037                     "Mode in which to create the rootfile (see TFile)");
00038   RegisterParameter("default_saveall", default_saveall = false);
00039   RegisterParameter("enable_branch" , enabler,
00040                     "Allows the user to enable writing a certain branch");
00041   RegisterParameter("disable_branch", disabler,
00042                     "Allows the user to disable writing a certain branch");
00043   ConfigHandler* config = ConfigHandler::GetInstance();
00044   config->
00045     AddCommandSwitch(' ',"rootfile","Set output ROOT filename to <file>",
00046                      CommandSwitch::DefaultRead<std::string>(_filename),
00047                      "file");
00048   config->AddCommandSwitch(' ',"rootdir","Set output ROOT directory to <dir>",
00049                            CommandSwitch::DefaultRead<std::string>(_directory),
00050                            "dir");
00051   
00052 }
00053 
00054 RootWriter::~RootWriter()
00055 {
00056   Finalize();
00057   if(_outfile){
00058     _outfile->Close();
00059     delete _outfile;
00060     _outfile = 0;
00061   }
00062 }
00063 
00064 int RootWriter::Initialize()
00065 {
00066   //append the .root suffix if necessary
00067   if( _filename.find(".root") == std::string::npos)
00068     _filename.append(".root");
00069   //add the directory prefix if not specified
00070   if( _filename.find("/") == std::string::npos)
00071     _filename.insert(0, _directory + "/");
00072   
00073   Message(INFO)<<"Saving output to file "<<_filename<<std::endl;
00074   _outfile = new TFile(_filename.c_str(), _mode.c_str());
00075   if(!_outfile || !_outfile->IsOpen() || _outfile->IsZombie()){
00076     Message(ERROR)<<"Unable to open ROOT file for writing.\n";
00077     enabled = false;
00078     return 1;
00079   }
00080   _tree = new TTree("Events","Processed data for each event");
00081   EventData* ptr = new EventData;
00082   _tree->Branch(EventData::GetBranchName(),&ptr);
00083   delete ptr;
00084   
00085   SaveConfig();
00086   return 0;
00087 }
00088 
00089 void RootWriter::SaveConfig()
00090 {
00091   ConfigHandler* cfghandler = ConfigHandler::GetInstance();
00092   //save the configuration to the tree as a TMacro
00093   TMacro cfg;
00094   std::stringstream cfgstream;
00095   cfgstream << *cfghandler; 
00096   cfgstream.seekg(std::ios::beg);
00097   std::string line;
00098   while( std::getline(cfgstream, line) ) 
00099     cfg.AddLine(line.c_str());
00100   cfg.Write("Configuration");
00101   //also save the daq configuration
00102   if(cfghandler->GetSavedCfgFile() != ""){
00103     TMacro daqcfg(cfghandler->GetSavedCfgFile().c_str());
00104     if(daqcfg.GetListOfLines()->GetEntries())
00105       daqcfg.Write("DAQConfiguration");
00106   }
00107     
00108 }
00109 
00110 int RootWriter::Process(EventPtr event)
00111 {
00112   EventDataPtr data = event->GetEventData();
00113   EventData* ptr = data.get();
00114   _tree->SetBranchAddress(EventData::GetBranchName(), &ptr );
00115   _tree->Fill();
00116   //_tree->Write();
00117   return 0;
00118 }
00119 
00120 int RootWriter::Finalize()
00121 {
00122   if(_tree){
00123     _tree->SetEntries();
00124     if(_tree->GetEntries()>0 && _outfile && _outfile->IsOpen())
00125       _tree->Write();
00126     delete _tree;
00127     _tree = 0;
00128   }
00129   if(_outfile){
00130     //save config again to get changes
00131     SaveConfig();
00132     _outfile->Close();
00133     delete _outfile;
00134     _outfile = 0;
00135   }
00136   return 0;
00137 }
00138     
00139 void RootWriter::EnableBranch(const char* classname, const char* branchname,
00140                               bool enable)
00141 {
00142   TClass* cl = gROOT->GetClass(classname);
00143   if(!cl){
00144     Message(ERROR)<<"ROOT doesn't know about any class "<<classname<<"\n";
00145     return;
00146   }
00147   TDataMember* mem = cl->GetDataMember(branchname);
00148   if(!mem){
00149     Message(ERROR)<<"Class "<<classname<<" has no member named "
00150                   <<branchname<<"\n";
00151     return;
00152   }
00153   mem->SetBit(TObject::kWriteDelete, enable);
00154   
00155 }
00156 
00157 void RootWriter::DisableBranch(const char* classname, const char* branchname) 
00158 {
00159   EnableBranch(classname, branchname, false);
00160 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines

Generated on 20 Jun 2014 for daqman by  doxygen 1.6.1