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
00022
00023
00024
00025
00026
00027
00028
00029
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
00067 if( _filename.find(".root") == std::string::npos)
00068 _filename.append(".root");
00069
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
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
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
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
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 }