00001 #include "Bmnt.h"
00002
00003 #include "bmnt/AcnetDevice.h"
00004
00005 #include <Validity/VldContext.h>
00006 #include <RawData/RawRecord.h>
00007 #include <RawData/RawBeamMonHeader.h>
00008 #include <RawData/RawBeamMonBlock.h>
00009 #include <RawData/RawDataBlock.h>
00010 #include <RawData/RawBeamData.h>
00011
00012 #include <TFile.h>
00013 #include <TTree.h>
00014 #include <TSystem.h>
00015
00016 #include <cassert>
00017 #include <iostream>
00018 #include <vector>
00019 #include <string>
00020 #include <map>
00021 #include <algorithm>
00022 using namespace std;
00023
00024 struct BmntImp {
00025 TFile* fFile;
00026 TTree* fTree;
00027 typedef map<string,AcnetDevice*> DeviceMap;
00028 DeviceMap fDevices;
00029
00030 BmntImp() : fFile(0), fTree(0) {}
00031 ~BmntImp() { this->Stop(); }
00032 bool Start(const char* outfile);
00033 void Stop();
00034 void ProcessFile(const char* filename, bool prefill,int nentries=0);
00035 bool Fill(const RawBeamMonBlock* rbmb, bool prefill);
00036 };
00037
00038 static string acnet2branchname(string n)
00039 {
00040 string out = "";
00041 out.push_back(tolower(n[0]));
00042 for (size_t ind=2; ind<8 && ind<n.size(); ++ind) {
00043 if (n[ind] == '[') break;
00044 out.push_back(tolower(n[ind]));
00045 }
00046 out += ".";
00047 return out;
00048 }
00049 bool BmntImp::Start(const char* outfile)
00050 {
00051 this->Stop();
00052 if (!gSystem->AccessPathName(outfile,kReadPermission)) {
00053 cerr << "File already exists: " << outfile << endl;
00054 return false;
00055 }
00056 fFile = new TFile(outfile,"new");
00057 fTree = new TTree("bd", "Beam Monitoring Data");
00058 return true;
00059 }
00060 void BmntImp::Stop()
00061 {
00062 if (fFile) {
00063 fFile->Close();
00064 delete fFile;
00065 fFile = 0;
00066 fTree = 0;
00067 }
00068 }
00069 bool BmntImp::Fill(const RawBeamMonBlock* rbmb, bool prefill)
00070 {
00071 DeviceMap::iterator it, done = fDevices.end();
00072 for (it=fDevices.begin(); it != done; ++it) {
00073 it->second->clear();
00074 }
00075
00076 vector<string> namelist = rbmb->GetNames();
00077
00078
00079 for (size_t ind=0; ind<namelist.size(); ++ ind) {
00080 string name = namelist[ind];
00081 string branchname = acnet2branchname(name);
00082
00083 AcnetDevice* dev = fDevices[branchname];
00084 if (! dev) {
00085 dev = new AcnetDevice(name.c_str());
00086 fDevices[branchname] = dev;
00087
00088 this->fTree->Branch(branchname.c_str(),"AcnetDevice",
00089 &(fDevices[branchname]));
00090
00091
00092
00093 }
00094 dev->clear();
00095
00096 if (prefill) continue;
00097
00098 const RawBeamData* rbd = (*rbmb)[name];
00099 assert(rbd);
00100
00101 dev->event = rbmb->TclkTriggerEvent();
00102 dev->delay = rbmb->TclkTriggerDelay();
00103
00104 dev->sec = rbd->GetSeconds();
00105 dev->msec = rbd->GetMsecs();
00106 dev->timestamp = (1.0*dev->sec) + (dev->msec/1000.0);
00107
00108 dev->ndata = rbd->GetDataLength();
00109 dev->data = (double*)rbd->GetData();
00110
00111 }
00112
00113 if (!prefill) this->fTree->Fill();
00114
00115 return true;
00116 }
00117
00118
00119 Bmnt::Bmnt() : fImp(new BmntImp)
00120 {
00121 }
00122
00123 Bmnt::Bmnt(const char* outfile) : fImp(new BmntImp)
00124 {
00125 fImp->Start(outfile);
00126 }
00127
00128 Bmnt::~Bmnt()
00129 {
00130 if (!fImp) return;
00131
00132 delete fImp; fImp = 0;
00133 }
00134
00135 void Bmnt::ProcessFile(const char* filename, int nentries)
00136 {
00137 fImp->ProcessFile(filename, false, nentries);
00138 }
00139
00140
00141 void Bmnt::ProcessFiles(const char** filenames)
00142 {
00143 for (int ind=0; filenames[ind]; ++ind) fImp->ProcessFile(filenames[ind],true);
00144 for (int ind=0; filenames[ind]; ++ind) fImp->ProcessFile(filenames[ind],false);
00145 }
00146
00147 void Bmnt::ProcessDirectory(const char* in_directory, const char* out_directory,
00148 bool skip_last)
00149 {
00150 void *dir = gSystem->OpenDirectory(in_directory);
00151 if (!dir) {
00152 cerr << "No such directory: " << in_directory << endl;
00153 return;
00154 }
00155
00156 vector<string> files;
00157 while (const char* file = gSystem->GetDirEntry(dir)) {
00158 string filename = file;
00159 if ( filename.length() > 5
00160 && filename[0] == 'B'
00161 && filename.find(".mbeam.root") == filename.length()-11 ) {
00162 files.push_back(file);
00163 }
00164 }
00165 std::sort(files.begin(),files.end());
00166 if (skip_last) files.pop_back();
00167 for (size_t ind = 0; ind < files.size(); ++ind) {
00168
00169 string infile = in_directory;
00170 infile += "/";
00171 infile += files[ind];
00172
00173 string outfile = out_directory;
00174 size_t start = infile.rfind("/");
00175 size_t len = infile.find(".mbeam.root") - start;
00176 outfile += infile.substr(start,len);
00177 outfile += ".bmnt.root";
00178
00179 if (!fImp->Start(outfile.c_str())) continue;
00180
00181 cerr << infile << " --> " << outfile << endl;
00182
00183 fImp->ProcessFile(infile.c_str(),true);
00184 fImp->ProcessFile(infile.c_str(),false);
00185 this->Write();
00186 fImp->Stop();
00187 delete fImp;
00188 fImp = new BmntImp();
00189 }
00190 }
00191
00192 void BmntImp::ProcessFile(const char* filename, bool prefill, int nentries)
00193 {
00194 TFile file(filename,"READ");
00195 TTree* tree = (TTree*)(file.Get("BeamMon"));
00196
00197 if (!tree) {
00198 cerr << "Can not find BeamMon tree in " << filename << endl;
00199 return;
00200 }
00201
00202 RawRecord* record = 0;
00203 if (!nentries) nentries = tree->GetEntries();
00204 for ( Int_t ient = 0; ient < nentries; ient++ ) {
00205 tree -> SetBranchAddress("RawRecord",&record);
00206 tree->GetEntry(ient);
00207
00208 if (!ient) {
00209 const VldContext* vld = record->GetVldContext();
00210 cout << "Reading " << filename << ":\n"
00211 << *vld << endl;
00212 }
00213
00214 TIter itr = record->GetRawBlockIter();
00215 const RawDataBlock* rdb = 0;
00216
00217
00218
00219
00220 while ((rdb = dynamic_cast<RawDataBlock*>(itr()))) {
00221 if (! rdb->InheritsFrom("RawBeamMonBlock")) {
00222
00223 continue;
00224 }
00225 const RawBeamMonBlock* rbmb =
00226 dynamic_cast<const RawBeamMonBlock*>(rdb);
00227 assert(rbmb);
00228
00229 this->Fill(rbmb,prefill);
00230 }
00231 #if 0
00232 if (tree->GetEntries()-ient == 1) {
00233 const VldContext* vld = record->GetVldContext();
00234 cout << "finishing " << filename << ":\n"
00235 << *vld << endl;
00236 }
00237 #endif
00238 delete record; record = 0;
00239 }
00240
00241 }
00242 TTree* Bmnt::GetTree() { return fImp->fTree; }
00243
00244 void Bmnt::Write()
00245 {
00246 fImp->fFile->cd();
00247 fImp->fTree->Write();
00248 fImp->fFile->Close();
00249 }
00250
00251
00252
00253 void make_bmnt_one_per_dir(const char* indir, const char* outdir, bool skip_last)
00254 {
00255 void *dir = gSystem->OpenDirectory(indir);
00256 if (!dir) {
00257 cerr << "No such directory: " << indir << endl;
00258 return;
00259 }
00260
00261 vector<string> files;
00262 while (const char* file = gSystem->GetDirEntry(dir)) {
00263 string filename = file;
00264 if ( filename.length() > 5
00265 && filename[0] == 'B'
00266 && filename.find(".mbeam.root") == filename.length()-11 ) {
00267 files.push_back(file);
00268 }
00269 }
00270 std::sort(files.begin(),files.end());
00271 if (skip_last) files.pop_back();
00272 for (size_t ind = 0; ind < files.size(); ++ind) {
00273
00274 string infile = indir;
00275 infile += "/";
00276 infile += files[ind];
00277
00278 string outfile = outdir;
00279 size_t start = infile.rfind("/");
00280 size_t len = infile.find(".mbeam.root") - start;
00281 outfile += infile.substr(start,len);
00282 outfile += ".bmnt.root";
00283
00284 if (!gSystem->AccessPathName(outfile.c_str(),kReadPermission)) {
00285 cerr << "File already exists: " << outfile << endl;
00286 return;
00287 }
00288
00289 Bmnt* bd = new Bmnt(outfile.c_str());
00290 const char* file_array[] = { infile.c_str(), 0 };
00291 bd->ProcessFiles(file_array);
00292 bd->Write();
00293 delete bd;
00294 }
00295 }
00296