//*-- Author : Damir Buskulic 20/05/99//////////////////////////////////////////////////////////////////////////// //// Local data base //// //// The local database is used to quickly access frame data contained in //// a handful of different frame files. //// ////////////////////////////////////////////////////////////////////////////
#include "VFrUtil.h"
#include "TSystem.h"
#include "TStorage.h"
#include "TRegexp.h"
#include "TArrayD.h"
#include "TBenchmark.h"
#include <iostream.h>
#include "VFrameMetaDB.h"
// need XOPEN for strptime()
#ifndef _XOPEN_SOURCE
# define __USE_XOPEN
# define _XOPEN_SOURCE
# include <time.h>
# undef __USE_XOPEN
# undef _XOPEN_SOURCE
#else
# include <time.h>
#endif
// _USE_FRDIRECT is defined if one uses a framelib version>=3.80 which// implements the direct frame access within a file
#define _USE_FRDIRECT
#define SMSSTAMAX 128
#define SMSVALMAX 512
#define MAXCONDITIONS 512
// TString spDebug = "";//______________________________________________________________________________//||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||//------------------------------------------------------------------------------
ClassImp(VFrFileIndex)
//______________________________________________________________________________VFrFileIndex::VFrFileIndex()
{
mStartTime = 0;
mEndTime = 0;
mFirstMetaIndex = 0;
mLastMetaIndex = 0;
mConditionsIndex = 0;
mFirstGroup = 0;
mLastGroup = 0;
}
//______________________________________________________________________________//||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||//------------------------------------------------------------------------------
ClassImp(VMetaDataFMDB)
//______________________________________________________________________________VMetaDataFMDB::VMetaDataFMDB(TString fileName, UInt_t runNumber,
UInt_t frameNumber, VGPSTime startTime,
VGPSTime localStartTime, Double_t length, TString detector,
TString state, Int_t quality, Int_t trigger) : TObject()
{
// Metadata constructormRunNumber = runNumber;
mFrameNumber = frameNumber;
mStartTime = startTime;
mLength = length;
mQuality = quality;
mTrigger = trigger;
mGroup = 0;
}
//______________________________________________________________________________VMetaDataFMDB::VMetaDataFMDB() : TObject()
{
// Metadata default constructormRunNumber = 0;
mFrameNumber = 0;
mStartTime = VGPSTime(0,0);
mLength = 0;
mQuality = 0;
mTrigger = 0;
mGroup = 0;
}
//______________________________________________________________________________VMetaDataFMDB::~VMetaDataFMDB()
{
// Metadata destructor
}
//______________________________________________________________________________voidVMetaDataFMDB::Streamer(TBuffer &R__b)
{
// Custom stream an object of class VMetaDataFMDBUInt_t R__s, R__c;
VGPSTime temptime;
if (R__b.IsReading()) {
Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
if (R__v > 1) {
VMetaDataFMDB::Class()->ReadBuffer(R__b, this, R__v, R__s, R__c);
return;
}
// process old versions before automatic schema evolution
TObject::Streamer(R__b);
R__b >> mRunNumber;
R__b >> mFrameNumber;
mStartTime.Streamer(R__b);
temptime.Streamer(R__b); // this object is not used anymore
R__b >> mLength;
R__b >> mQuality;
R__b >> mTrigger;
R__b >> mGroup;
R__b.CheckByteCount(R__s, R__c, VMetaDataFMDB::IsA());
// end of old versions
} else {
VMetaDataFMDB::Class()->WriteBuffer(R__b, this);
}
}
//______________________________________________________________________________//||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||//------------------------------------------------------------------------------
ClassImp(VFrameMetaDB)
//______________________________________________________________________________VFrameMetaDB::VFrameMetaDB() : VVirtualFrameInfoDB()
{
//// Local frame data base constructor//
mPathToDB = "";
mDBFile = 0;
mOption = "";
mIsOpened = 0;
mMetaTree = 0;
mConditionTree = new THashList();
mConditionsIndex = 0;
mTmpConditions = new VFrCondition*[MAXCONDITIONS];
memset(mTmpConditions,0,sizeof(VFrCondition*)*MAXCONDITIONS);
mNConditions = 0;
mTmpCondIndex = new CondIndex_t[MAXCONDITIONS];
mHashTable = 0;
mCurMetaIndex = 0;
mCurCondTreeIndex = new Int_t[MAXCONDITIONS];
mCurFrameStart = 0;
mCurFrameEnd = 0;
mCurVectName = "";
mTmpMeta = new VMetaDataFMDB();
mTmpMetaString = new VMetaString();
mLastFrNumber = 0;
mLastRunNumber = 0;
mConditionNames = new VConditionNames();
mGroupList = 0;
mTmpGroupInfo = new VGroupInfo();
mLastGroupInfo = 0;
mPlayer = 0;
}
//______________________________________________________________________________VFrameMetaDB::VFrameMetaDB(char* filename, Option_t* mode,char* frfilenames, Option_t* option)
: VVirtualFrameInfoDB()
{
// Local frame data base constructor// filename is the name of the database file.// The mode may be "read" to open a DB, or "create" to build a new one// If "create" is used, frfilenames contains the path/names of the files to// include in the database.// option is either "R" or "S" (recursive search for files or simple)// see AddFiles().//
TString modeS = mode;
modeS.ToLower();
mPathToDB = "";
mDBFile = 0;
mOption = "";
mIsOpened = 0;
mMetaTree = 0;
mConditionTree = new THashList();
mConditionsIndex = 0;
mTmpConditions = new VFrCondition*[MAXCONDITIONS];
memset(mTmpConditions,0,sizeof(VFrCondition*)*MAXCONDITIONS);
mNConditions = 0;
mTmpCondIndex = new CondIndex_t[MAXCONDITIONS];
mHashTable = 0;
mCurMetaIndex = 0;
mCurCondTreeIndex = new Int_t[MAXCONDITIONS];
mCurFrameStart = 0;
mCurFrameEnd = 0;
mCurVectName = "";
mTmpMeta = new VMetaDataFMDB();
mTmpMetaString = new VMetaString();
mLastFrNumber = 0;
mLastRunNumber = 0;
mConditionNames = new VConditionNames();
mGroupList = 0;
mTmpGroupInfo = new VGroupInfo();
mLastGroupInfo = 0;
mPlayer = 0;
if (!modeS.CompareTo("create")) {
Build(frfilenames, filename, option);
} else if (!modeS.CompareTo("read") || !modeS.CompareTo("update")) {
Open(filename, mode);
}
}
//______________________________________________________________________________VFrameMetaDB::~VFrameMetaDB()
{
//// Local frame data base destructor//
if (mMetaTree) delete mMetaTree;
if (mConditionTree) {
mConditionTree->Delete();
delete mConditionTree;
}
if (mConditionsIndex) delete mConditionsIndex;
if (mGroupList) delete mGroupList;
delete mTmpMeta;
delete mTmpMetaString;
if (mTmpConditions) {
for (int i=0;i<MAXCONDITIONS;i++) if (mTmpConditions[i]) delete mTmpConditions[i];
delete [] mTmpConditions;
}
if (mTmpCondIndex) delete [] mTmpCondIndex;
if (mHashTable) delete mHashTable;
if (mDBFile) delete mDBFile;
delete mConditionNames;
delete [] mCurCondTreeIndex;
if (mTmpGroupInfo) delete mTmpGroupInfo;
if (mLastGroupInfo) delete mLastGroupInfo;
if (mPlayer) delete mPlayer;
}
//______________________________________________________________________________voidVFrameMetaDB::Build(char* pathtofiles, char* filename, Option_t* option)
{
// Builds the frame database// pathtofiles is the path to the directory containing the frame files// used to build the DB// filename is the name of the ROOT file that is the DB. It will be created// in the current directoryInt_t nbfiles = 0;
// Test if DB is already opened
if (mIsOpened) {
Warning("Build","Data base already opened, cannot build");
return;
}
// Open a new file to store the database
if (!Open(filename,"RECREATE")) {
Warning("Build","Cannot create database file");
return;
}
// Define a new tree containing the metadata
if (mMetaTree) {delete mMetaTree;}
mMetaTree = new TTree("FrameDBTree","Local DB tree");
mMetaTree->Branch("detector","VMetaDataFMDB",&mTmpMeta,64000,1);
mMetaTree->Branch("detectorstrings","VMetaString",&mTmpMetaString,64000,0);
// Define a new tree containing the conditions index// (the condition trees are build "on demand" when needed
if (mConditionsIndex) delete mConditionsIndex;
mConditionsIndex = new TTree("ConditionsIndex","Conditions Index");
// Define a new tree to hold the group information
if (mGroupList) delete mGroupList;
mGroupList = new TTree("GroupList","Group information");
mGroupList->Branch("groupinfo","VGroupInfo",&mTmpGroupInfo);
if (mLastGroupInfo) delete mLastGroupInfo;
mLastGroupInfo = new VGroupInfo();
// Add the files defined by the user
nbfiles = AddFiles(pathtofiles, option);
mDBFile->Delete("FrameDBTree;1"); // Delete the old keys
mDBFile->Delete("ConditionsIndex;1");
mDBFile->Delete("GroupList;1");
char* cname = new char[255];
for (int i=0;i<mConditionNames->GetNCNames();i++) {
sprintf(cname,"%s;1",mConditionNames->GetConditionName(i));
mDBFile->Delete(cname);
}
delete [] cname;
mDBFile->Write(); // Rewrite the new keys/headers
if (nbfiles) {
printf("nCreated database file from %d files n",nbfiles);
} else {
printf("n Did not create the database, no input frame filesn");
}
mDBFile->Close();
delete mDBFile; // deletes also tree and mHashTable structures
// (these are in the directory corresponding to the file)
mDBFile = 0;
mHashTable = 0; // needed since deleted but not set to 0 by the file deletion
mConditionNames = 0;
mMetaTree = 0; // idem
mConditionsIndex = 0; // idem
mGroupList = 0; // idem
mConditionTree->Clear(); // remove the ref. to obsolete trees
for (int i=0;i<MAXCONDITIONS;i++) {if (mTmpConditions[i]) delete mTmpConditions[i]; mTmpConditions[i]=0;}
mIsOpened = kFALSE;
if (nbfiles) Open(filename,"READ");
}
//______________________________________________________________________________Bool_tVFrameMetaDB::Open(char* pathtoDB, Option_t* openopt)
{
// Open the Frame database "pathtoDB"
TFile* tmpfile;
TTree* tmptree;
TTree* tmpcondindex;
TTree* tmpcond;
TTree* tmpgrouplist;
VHashTable* tmphash;
TBranch* tmpbranch;
TBranch* tmpbranchstr;
TObjArray* listofcondindex;
TBranch* tmpcondindexbranch;
TBranch* tmpcondbranch;
TBranch* tmpgroupbranch;
Int_t i;
VFrCondition* tmpcondobject;
VGroupInfo* tmpgroupinfo;
if (mIsOpened) {
Warning("Open","Data base already opened with file %s",mPathToDB.Data());
return kFALSE;
}
// Test and set the option (update or read)
mOption = openopt;
Bool_t update = mOption.CompareTo("UPDATE", TString::kIgnoreCase)
? kFALSE : kTRUE;
Bool_t read = mOption.CompareTo("READ", TString::kIgnoreCase)
? kFALSE : kTRUE;
Bool_t recreate = mOption.CompareTo("RECREATE", TString::kIgnoreCase)
? kFALSE : kTRUE;
if (!update && !read && !recreate) {
read = kTRUE;
mOption = "READ";
}
// Opens the file in selected mode
if (recreate) {
tmpfile = new TFile(pathtoDB, mOption.Data(),"Local database");
} else {
tmpfile = new TFile(pathtoDB, mOption.Data());
}
if (!(tmpfile->IsOpen())) {
Warning("Open","Cannot open or create database file");
delete tmpfile;
mOption = "";
return kFALSE;
}
if (recreate) {
// ============== Open a new file to store the database if creation =====
if (mDBFile) {delete mDBFile;}
mDBFile = tmpfile;
mIsOpened = kTRUE;
if (mHashTable) {delete mHashTable;}
mHashTable = 0;
mPathToDB = gSystem->DirName(pathtoDB);
return kTRUE;
}
mPathToDB = gSystem->DirName(pathtoDB);
// ============== Loads the metadata tree ===============================
tmptree = (TTree*)(gDirectory->Get("FrameDBTree"));
if (!tmptree) {
Warning("Open","No database tree present in this DB file");
return kFALSE;
}
if (mMetaTree) {delete mMetaTree;}
mMetaTree = tmptree;
tmpbranch = mMetaTree->GetBranch("detector");
tmpbranch->SetAddress(&mTmpMeta);
tmpbranchstr = mMetaTree->GetBranch("detectorstrings");
tmpbranchstr->SetAddress(&mTmpMetaString);
// ============== Loads the condition names =============================// Can work without conditions if necessaryVConditionNames* tmpcondnames = (VConditionNames*)gDirectory->Get("ConditionNames");
if (mConditionNames) delete mConditionNames;
if (tmpcondnames) {
mConditionNames = tmpcondnames;
} else {
mConditionNames = new VConditionNames();
}
// ============== Loads the condition index tree ========================
tmpcondindex = (TTree*)gDirectory->Get("ConditionsIndex");
if (!tmpcondindex) {
Warning("Open","No condition index tree present in this DB file");
return kFALSE;
}
if (mConditionsIndex) {delete mConditionsIndex;}
mConditionsIndex = tmpcondindex;
// Finds the branches for the conditions index tree
listofcondindex = mConditionsIndex->GetListOfBranches();
// Builds the various variables
mNConditions = listofcondindex->GetEntriesFast();
// Loads and sets the conditions index branches
for (i=0;i<mNConditions;i++) {
tmpcondindexbranch = (TBranch*)(listofcondindex->UncheckedAt(i));
tmpcondindexbranch->SetAddress(&mTmpCondIndex[i]);
}
if (mNConditions != mConditionNames->GetNCNames()) {
Warning("Open","Inconsistency, number of conditions not equal to number of condition names");
}
// ============== Loads the group information tree ======================
tmpgrouplist = (TTree*)gDirectory->Get("GroupList");
if (!tmpgrouplist) {
Warning("Open","No group information tree present in this DB file");
return kFALSE;
}
if (mGroupList) {delete mGroupList;}
mGroupList = tmpgrouplist;
tmpgroupbranch = mGroupList->GetBranch("groupinfo");
tmpgroupbranch->SetAddress(&mTmpGroupInfo);
// Loads the last group information
tmpgroupinfo = (VGroupInfo*)gDirectory->Get("LastGroupInfo");
if (!tmpgroupinfo) {
Warning("Open","No last group information present in this DB file");
return kFALSE;
}
if (mLastGroupInfo) delete mLastGroupInfo;
mLastGroupInfo = tmpgroupinfo;
// ============== Loads the condition trees =============================
if (mNConditions>0 && mNConditions == mConditionNames->GetNCNames()) {
for (i=0;i<MAXCONDITIONS;i++) {if (mTmpConditions[i]) delete mTmpConditions[i]; mTmpConditions[i]=0;}
for (i=0;i<mNConditions;i++) {
tmpcond = (TTree*)gDirectory->Get(mConditionNames->GetConditionName(i));
if (!tmpcond) {
Warning("Open","No condition %s in this database",mConditionNames->GetConditionName(i));
}
mConditionTree->AddLast(tmpcond);
tmpcondobject = new VFrCondition();
mTmpConditions[i] = tmpcondobject;
tmpcondbranch = tmpcond->GetBranch("condition");
if (tmpcondbranch) {
tmpcondbranch->SetAddress(&(mTmpConditions[i]));
} else {
Warning("Open","No branch for condition %s in this database",mConditionNames->GetConditionName(i));
}
}
} else {
Warning("Open","No conditions trees loaded");
}
// ============== Loads the hashtable ===================================
tmphash = (VHashTable*)gDirectory->Get("FileHashTable");
if (!tmphash) {
Warning("Open","No file hash table present in this DB file");
return kFALSE;
}
if (mHashTable) {delete mHashTable;}
mHashTable = tmphash;
if (mDBFile) {mDBFile->Close(); delete mDBFile;}
mDBFile = tmpfile;
mIsOpened = kTRUE;
return kTRUE;
}
//______________________________________________________________________________voidVFrameMetaDB::Close()
{
// Closes this metadb
mDBFile->Close();
delete mDBFile; // deletes also tree and mHashTable structures
// (these are in the directory corresponding to the file)
mDBFile = 0;
mHashTable = 0; // needed since deleted but not set to 0 by the file deletion
mConditionNames = 0;
mMetaTree = 0; // idem
mConditionsIndex = 0; // idem
mGroupList = 0; // idem
mConditionTree->Clear(); // remove the ref. to obsolete trees
for (int i=0;i<MAXCONDITIONS;i++) {if (mTmpConditions[i]) delete mTmpConditions[i]; mTmpConditions[i]=0;}
mIsOpened = kFALSE;
}
//______________________________________________________________________________Bool_tVFrameMetaDB::BuildNewCondition(char* name, const char* varnames)
{
// Add a condition to this database. Builds a new condition tree and adds// a branch in the index tree. If the index tree already has entries, fill// the newly created branch with 0's for the size of the index tree.// "name" is the name of the new condition tree.// The consistency of the structure is maintained so that the same index is// used in Condition Names, tree list, TmpConditions objects, TmpCondIndex.// On return, 0 = error, 1 = OK
TTree* condtree;
VFrCondition* condobject;
Int_t i;
char subbrname[512];
// Test and set the DB opened option (create, update or read) Bool_t read = mOption.CompareTo("READ", TString::kIgnoreCase)
? kFALSE : kTRUE;
// Test if DB is opened in update mode
if (!mIsOpened || read) {
Warning("AddCondition","Data base closed or opened in read mode, cannot add condition");
return 0;
}
// Test of existence of condition index tree
if (!mConditionsIndex) {
Warning("AddCondition","No conditions index, cannot build index");
return 0;
}
// Test for max number of conditions reached
if (mNConditions >= MAXCONDITIONS-1) {
Warning("AddCondition","Max number of conditions(%d) reached",MAXCONDITIONS);
return 0;
}
// cd to the file (just in case)
TDirectory* olddirectory = gDirectory;
if(mDBFile) mDBFile->cd();
// ================== Build the new condition Tree ==========================
condtree = new TTree(name,name);
mConditionTree->AddLast(condtree);
condobject = new VFrCondition();
mTmpConditions[mNConditions] = condobject;
condtree->Branch("condition","VFrCondition",&(mTmpConditions[mNConditions]),32000,0);
printf("Create condition %s, %p, %pn",name,(&(mTmpConditions[mNConditions])),(((TTree*)mConditionTree->FindObject(name))->GetBranch("condition")->GetAddress()));
mNConditions++;
mConditionNames->AddConditionName(name,varnames);
// Make the updated pieces persistent (well, save them...)
mConditionNames->Write("ConditionNames",kOverwrite);
// ================== Add a branch to the index tree ========================
mTmpCondIndex[mNConditions-1].first = 0;
mTmpCondIndex[mNConditions-1].last = 0;
// Name the subbranches "namefirst" and "namelast" to ensure different names// for each subbranch. If not done, can confuse the tree mechanism.
strcpy(subbrname,name);
strcat(subbrname,"first/I:");
strcat(subbrname,name);
strcat(subbrname,"last/I");
TBranch* newindexbranch = mConditionsIndex->Branch(name,&mTmpCondIndex[mNConditions-1],subbrname);
Int_t nentries = Int_t(mConditionsIndex->GetEntries());
// Fill with 0's the already existing entries of the tree
for (i=0; i<nentries; i++) newindexbranch->Fill();
// Update the tree header on disk
mDBFile->Delete("ConditionsIndex;1");
mConditionsIndex->Write();
olddirectory->cd();
return 1;
}
//______________________________________________________________________________Int_tVFrameMetaDB::AddFiles(const char* filenames, Option_t* option)
{
// Add files described by "filenames" in the database// The options are :// "R" means a recursive search will be done. This is the default.// "S" a simple search is performed, not looking at directories.
TString opt = option;
opt = opt + "P";
Int_t nbfiles = AddFiles(filenames,"",opt.Data());
return nbfiles;
}
//______________________________________________________________________________FrameH* VFrameMetaDB::FrameReadHeader(FrFile* iFile, int frnum)
{
// Reads only the frame header for the frame number// frnum in the specified file. Builds a frame structure (temporary)// Builds a frame structure (temporary)// This routine takes code from the relevant parts of the Framelib.// (Thanks, Benoit !)// if no TOC information available, return null
if (!(iFile->toc)) {
FrTOCReadFull(iFile);
if (!(iFile->toc)) return (NULL);
}
// To avoid relocation problems
iFile->relocation = FR_NO; /*--- to avoid relloaction problems---*/
// TOC information available but no frame for this number
if (frnum >=iFile->toc->nFrame || frnum<0) return(NULL);
// the frame has been found in the TOC: direct read
if(FrTOCSetPos(iFile, iFile->toc->positionH[frnum]) != 0) return (NULL);
FrameHRead(iFile);
return(iFile->curFrame);
}
//______________________________________________________________________________Int_tVFrameMetaDB::AddFiles(const char* filenames, const char* extrapath, Option_t* option)
{
// Add files described by "filenames" in the database// The options are :// "R" means a recursive search will be done. This is the default.// "S" a simple search is performed, not looking at directories.// if option contains "P" then it is a primary call, not the result// of a recursive one// extrapath is put in front of the filenames, needed in the database
const char* workingdirB;
const char* pathtofilesB, * renamesB;
char* workingdir;
char* pathtofiles, * renames;
TRegexp* regexp = 0;
FrFile* framefile;
FrTOC* filetoc;
// FrameH* framecur;
const char* frfilename;
char* tmpfilename;
TString extrapathS, frfilenameS, detectorS;
Long_t id,size,flags,modtime;
Int_t nbfiles = 0;
Int_t nbfilestot = 0;
Double_t ftimestart, ftimeend, lastftimeend;
Float_t trigtbefore, trigtafter;
Int_t lastgroup, iframe;
Int_t* framegroup;
Int_t ffirstind, flastind;
TArrayF condarray;
TString condnames;
Int_t condindex, iconditionnumber;
#if FR_VERS<6000
FrTrigData* curtrig;
FrTrigData* firsttrig;
#else
FrEvent* curtrig;
FrEvent* firsttrig;
#endif
FrTOCevt* curtrigtoc;
TString slash="/";
TString star="*";
Int_t i;
TString opt;
opt = option;
opt.ToLower();
// Test and set the DB opened option (create, update or read) // Bool_t update = mOption.CompareTo("UPDATE", TString::kIgnoreCase)// ? kFALSE : kTRUE;Bool_t read = mOption.CompareTo("READ", TString::kIgnoreCase)
? kFALSE : kTRUE;
Bool_t recreate = mOption.CompareTo("RECREATE", TString::kIgnoreCase)
? kFALSE : kTRUE;
// Test if DB is opened in update mode
if (!mIsOpened || read) {
Warning("AddFiles","Data base closed or opened in read mode, cannot update");
return 0;
}
// Reads the last metadata and set the last group number, last frame end time
mMetaTree->GetEntry(mMetaTree->GetEntries()-1);
lastgroup = mTmpMeta->GetGroup();
lastftimeend = mTmpMeta->GetStartTime().GetTimeD() + mTmpMeta->GetLength();
workingdirB = gSystem->WorkingDirectory();
workingdir = new char[strlen(workingdirB)+1];
strcpy(workingdir,workingdirB); // need this because the original string is
// handled by the TSystem methods, can change// Set directory to the one containing the frame files
renamesB = gSystem->BaseName(filenames);
renames = new char[strlen(renamesB)+3]; // +3 to allow add * if no names
strcpy(renames,renamesB);
pathtofilesB = gSystem->DirName(filenames);
pathtofiles = new char[strlen(pathtofilesB)+3]; // +3 to allow replace by ./ in the test below
strcpy(pathtofiles,pathtofilesB);
if (!strcmp(renames,filenames)) strcpy(pathtofiles,".");
// Veto . and .. directories if it is not the primary call to AddFiles (recursive)
if ( (!strcmp(pathtofiles,".") || !strcmp(pathtofiles,"..")) && !opt.Contains("p") ) {
delete [] workingdir;
delete [] pathtofiles;
delete [] renames;
return 0;
}
if (!strlen(renames)) strcpy(renames,"*");
if (!gSystem->ChangeDirectory(pathtofiles)) {
Error("AddFiles","Could not open directory %s",pathtofiles);
delete [] workingdir;
delete [] pathtofiles;
delete [] renames;
return 0;
}
extrapathS = extrapath; // Init the TString version
// ==== Loop on the files and put them in the database ====
regexp = 0;
if (renames && strlen(renames)) regexp = new TRegexp(renames,kTRUE);
void* dirp = gSystem->OpenDirectory("./");
frfilename = gSystem->GetDirEntry(dirp);
while(frfilename) {
Int_t goodfile = 0;
if (regexp) {
TString s = frfilename;
if (s.Index(*regexp) != kNPOS) goodfile = 1;
} else { goodfile = 1; }
if (goodfile) {
gSystem->GetPathInfo(frfilename,&id,&size,&flags,&modtime);
// Searches frames only in plain files or executable files (windows case !)
if (flags <= 1) {
tmpfilename = new char[strlen(frfilename)+1];
strcpy(tmpfilename,frfilename);
framefile = FrFileINew(tmpfilename);
filetoc=0;
if (framefile) {
// Reads the table of contents of the file for further use
if (!(framefile->toc)) {
filetoc = FrTOCReadFull(framefile);
}
}
if (!filetoc && framefile) {
printf("Cannot read file %s, it has no table of contentsn",frfilename);
} else if (framefile && filetoc) {
nbfiles++;
frfilenameS = extrapathS + pathtofiles + slash + frfilename;
// printf("Browsing file %s, size = %dn",frfilename,size);
framegroup = new Int_t[framefile->toc->nFrame];
// int iframegroup = 0;
ftimestart = 1.e20; ftimeend = 0;
ffirstind = -1; flastind = 0;
// while ((framecur = FrameReadHeader(framefile,iframegroup))!=0) {
for (iframe = 0; iframe<framefile->toc->nFrame;iframe++) {
// Protects against frame start time = 0
if (filetoc->GTimeS[iframe] == 0) {
framegroup[iframe] = -1;
break;
}
// Loads a Frame and saves information in the tree
mTmpMetaString->SetFileName(frfilenameS);
mTmpMeta->SetRunNumber(filetoc->runs[iframe]);
mTmpMeta->SetFrameNumber(filetoc->frame[iframe]);
VGPSTime gpsti(filetoc->GTimeS[iframe],filetoc->GTimeN[iframe]);
mTmpMeta->SetStartTime(gpsti);
mTmpMeta->SetLength(filetoc->dt[iframe]);
// detectorS = filetoc->name;
detectorS = "";
mTmpMetaString->SetDetector(detectorS);
mTmpMetaString->SetState("L");
mTmpMeta->SetQuality(1);
mTmpMeta->SetTrigger(1);
// Updates the group information
if (fabs(gpsti.GetTimeD() - lastftimeend) > 1e-4) {
lastgroup++;
mLastGroupInfo->Copy(*mTmpGroupInfo);
mGroupList->Fill(); // fill the group tree
mLastGroupInfo->Reset();
mLastGroupInfo->SetFirstIndex(mMetaTree->GetEntries());
mLastGroupInfo->SetLastIndex(mMetaTree->GetEntries()-1);
mLastGroupInfo->SetBeginTime(gpsti.GetTimeD());
}
lastftimeend = gpsti.GetTimeD() + filetoc->dt[iframe];
mTmpMeta->SetGroup(lastgroup);
mLastGroupInfo->Increment(lastftimeend, filetoc->dt[iframe]);
framegroup[iframe] = lastgroup;
// Fills the metadata tree
mMetaTree->Fill();
if (ffirstind==-1) ffirstind = (Int_t)(mMetaTree->GetEntries()-1);
Double_t ftimefrs = filetoc->GTimeS[iframe] + 1.e-9 * filetoc->GTimeN[iframe];
if (ftimestart > ftimefrs) ftimestart = ftimefrs;
Double_t ftimefre = ftimefrs + filetoc->dt[iframe];
if (ftimeend < ftimefre) ftimeend = ftimefre;
// FrameFree(framecur);
}
// Saves the triggers as conditions in relevant condition trees// First, deletes the old content of the temp standard conditions// mTmpStandardCond->Delete();// Then adds the triggers
for (i=0;i<mNConditions;i++) {mTmpCondIndex[i].first=-1; mTmpCondIndex[i].last=-1;}
curtrigtoc=0;
#if FR_VERS<6000
if (framefile->toc) curtrigtoc = framefile->toc->trig;
#else
if (framefile->toc) curtrigtoc = framefile->toc->event;
#endif
int itrig = 0;
framefile->error = FR_OK;
firsttrig=0;
#if FR_VERS<6000
firsttrig = FrTrigDataReadT(framefile,"*",0,999999999);
#else
firsttrig = FrEventReadT(framefile,"*",0,999999999,-1e100, 1e100);
#endif
curtrig = firsttrig;
while (curtrig) {
// Find the relevant group by finding the frame in the file// that was owning this trigger. To do this, compare the positions// in the file of the frames and of the trigger.int iframe = (framefile->toc->nFrame-1)/2; // for 1 frame in file case
int iframeup = framefile->toc->nFrame-1;
int iframedown = 0;
while (iframeup != iframedown) {
if (iframeup == iframedown+1) { // to solve rounding pb
iframe = iframeup;
} else {
iframe = (iframeup+iframedown)/2;
}
if (framefile->toc->positionH[iframe] > curtrigtoc->position[itrig]) {
iframeup = iframe-1;
} else {
iframedown = iframe;
}
}
// Protect against null frame start time
if (framegroup[iframedown] > 0) {
VGPSTime condtime = VGPSTime(curtrig->GTimeS,curtrig->GTimeN);
condarray = AnalyzeTriggerString(curtrig->statistics,condnames);
// If condition length = 0, set timeBefore and after to match the frame length
if (curtrig->timeBefore==0 && curtrig->timeAfter==0) {
double frametime = framefile->toc->GTimeS[iframedown]+1e-9*framefile->toc->GTimeN[iframedown];
trigtbefore = condtime.GetTimeD() - frametime;
trigtafter = frametime + framefile->toc->dt[iframedown] - condtime.GetTimeD();
} else {
trigtbefore = curtrig->timeBefore;
trigtafter = curtrig->timeAfter;
}
// Add the condition in the relevant tree and update various indices
#if FR_VERS<6000
condindex = AddCondition(curtrig->name,condtime, trigtbefore, trigtafter,
curtrig->triggerStatus, curtrig->amplitude,
curtrig->probability, condnames, condarray, framegroup[iframedown]);
#else
condindex = AddCondition(curtrig->name,condtime, trigtbefore, trigtafter,
curtrig->eventStatus, curtrig->amplitude,
curtrig->probability, condnames, condarray, framegroup[iframedown]);
#endif
iconditionnumber = mConditionNames->IndexOf(curtrig->name);
// Sets the condition indices
if (mTmpCondIndex[iconditionnumber].first==-1) {
mTmpCondIndex[iconditionnumber].first = condindex;
}
mTmpCondIndex[iconditionnumber].last = condindex;
}
// printf("******** condition : index, first,last %d, %d, %dn",iconditionnumber, condindex, mTmpCondIndex[iconditionnumber].first, mTmpCondIndex[iconditionnumber].last);
curtrig = curtrig->next;
itrig++;
}
if (firsttrig) FrEventFree(firsttrig);
// printf("Loaded frame file %sn",frfilename);
FrFileIEnd(framefile);
flastind = (Int_t)(mMetaTree->GetEntries()-1);
// For the first file, create the hash table// Define a new hash table used for fast access
if (!mHashTable && recreate) {
Double_t filetlength = ftimeend - ftimestart;
// The length of the hash table is chosen so that the file sits// in only one slot.Int_t optimalcol = 5;
mHashTable = new VHashTable(10, ftimestart - filetlength*5*optimalcol, ftimeend + filetlength*5*optimalcol, optimalcol);
}
// Puts the file into the hash table
mHashTable->Add(ftimestart,ftimeend, ffirstind, flastind,mConditionsIndex->GetEntries(), framegroup[0], lastgroup);
// Fills the conditions index for this file
mConditionsIndex->Fill();
delete [] framegroup;
}
delete [] tmpfilename;
// If a directory, search recursively if desired ("R" option)
} else if ((flags & 2) && opt.Contains("r") && strcmp(renames,".") && strcmp(renames,"..")) {
frfilenameS = frfilename + slash + star;
TString p = extrapathS + pathtofiles + slash;
nbfilestot += AddFiles(frfilenameS.Data(),p.Data(),"R");
}
}
// Get the next file in the directory
frfilename = gSystem->GetDirEntry(dirp);
}
// Update the file on disk// mDBFile->Delete("FileHashTable;1");
mDBFile->Delete("FrameDBTree;1");
mDBFile->Delete("ConditionsIndex;1");
char* cname = new char[255];
for (int i=0;i<mConditionNames->GetNCNames();i++) {
sprintf(cname,"%s;1",mConditionNames->GetConditionName(i));
mDBFile->Delete(cname);
}
delete [] cname;
if (mHashTable) mHashTable->Write("FileHashTable",kOverwrite);
if (mConditionNames) mConditionNames->Write("ConditionNames",kOverwrite);
if (mLastGroupInfo) mLastGroupInfo->Write("LastGroupInfo",kOverwrite);
mDBFile->Write(); // also write the meta-data header in this operation
gSystem->ChangeDirectory(workingdir);
gSystem->FreeDirectory(dirp);
if(nbfiles) printf("nUpdated database file from %d file(s) in %sn\n",nbfiles,pathtofiles);
nbfilestot += nbfiles;
delete [] workingdir;
delete [] pathtofiles;
delete [] renames;
delete regexp;
return nbfilestot;
}
//______________________________________________________________________________Int_tVFrameMetaDB::AddCondition(char* name, VGPSTime time, Float_t timebefore, Float_t timeafter,
Bool_t triggerStatus, Float_t amplitude,
Float_t prob, TString varNames, TArrayF tvars, Int_t group)
{
// Add a defined condition to the database. Fills the corresponding tree,// and if the condition type (name) doesn't exist, builds a new tree and// a new index branch.// return the index of the new entry in the condition treeInt_t iconditionnumber;
TTree* tree;
iconditionnumber = mConditionNames->IndexOf(name);
// In case there is no trigger with this name, build a new condition type
if (iconditionnumber < 0) {
BuildNewCondition(name,varNames.Data());
iconditionnumber = mConditionNames->IndexOf(name);
}
// Update the condition object// printf("Write condition %s, %x, group %dn",name,mTmpConditions[iconditionnumber], group);
mTmpConditions[iconditionnumber]->SetActive(1);
mTmpConditions[iconditionnumber]->SetTime(time);
mTmpConditions[iconditionnumber]->SetTimeBefore(timebefore);
mTmpConditions[iconditionnumber]->SetTimeAfter(timeafter);
mTmpConditions[iconditionnumber]->SetTriggerStatus(triggerStatus);
mTmpConditions[iconditionnumber]->SetAmplitude(amplitude);
mTmpConditions[iconditionnumber]->SetProbability(prob);
mTmpConditions[iconditionnumber]->SetVarNames(varNames.Data());
mTmpConditions[iconditionnumber]->SetVar(tvars);
mTmpConditions[iconditionnumber]->SetGroup(group);
// Fills the condition tree
tree = (TTree*)mConditionTree->FindObject(name);
tree->Fill();
return (Int_t)tree->GetEntries()-1;
}
//______________________________________________________________________________
TArrayF VFrameMetaDB::AnalyzeTriggerString(char* string, TString& outputnames)
{
// Analyze the inputs or statistics string in predefined format// used in the FrameLib.char* onevar, *posequal, *curvar;
Int_t eofcheck;
Float_t* resval;
Int_t resvalindex;
if (string==0) {
TArrayF nullarray(0);
return nullarray;
}
outputnames="";
resval = new Float_t[100];
resvalindex = 0;
onevar = new char[100];
curvar = string;
eofcheck = sscanf(curvar,"%s",onevar);
while (eofcheck!=EOF) {
curvar += strlen(onevar);
while (*curvar==' ') curvar++;
posequal = strstr(onevar,"=");
*posequal=0;
posequal++;
// Fill name and value
if (outputnames.Length()) outputnames += " ";
outputnames += onevar;
sscanf(posequal,"%f",&resval[resvalindex]);
resvalindex++;
eofcheck = sscanf(curvar,"%s",onevar);
}
TArrayF valarray(resvalindex,resval);
delete onevar;
delete resval;
return valarray;
}
//______________________________________________________________________________Double_tVFrameMetaDB::GetStart()
{
// Returns the start time of the first frame in the metadatabaseDouble_t frbegin,frend;
Int_t index = FindNearestGEIndex(GetDBStart(),frbegin,frend);
if (index>=0) return frbegin;
return 0;
}
//______________________________________________________________________________Double_tVFrameMetaDB::GetEnd()
{
// Returns the end time of the last frame in the metadatabaseDouble_t frend=0;
Int_t ihash = mHashTable->GetCapacity()-1;
// Search from last to first slot
while (ihash>=0) {
TObjArray* filearray = mHashTable->GetFilesInfoDirect(ihash);
if (filearray) {
if (filearray->GetSize()) {
// Search in the list of files for this slot
for (int ifile=0;ifile<filearray->GetSize();ifile++) {
VFrFileIndex* fileindex = (VFrFileIndex*)(filearray->At(ifile));
if (fileindex) {
if (frend < fileindex->GetEndTime())
frend = fileindex->GetEndTime();
}
}
if (frend>0) return frend;
}
}
ihash--;
}
return 0;
}
//______________________________________________________________________________Int_tVFrameMetaDB::FindIndex(Int_t approxindex, Double_t gpstime)
{
// Finds the index of the frame meta corresponding to time "gpstime"// in the metadata tree. approxindex is an approximate value of the index.// (usually the right one !)// The search is made in the same group of frames (consecutive frames)Double_t beginf, endf;
Int_t searchindex;
Int_t group;
if (approxindex<0) {
Warning("FindIndex","The approximate index is negative. It shouldn't be.");
return -1;
}
searchindex = approxindex;
mMetaTree->GetEntry(searchindex);
beginf = mTmpMeta->GetStartTime().GetTimeD();
endf = beginf + mTmpMeta->GetLength();
group = mTmpMeta->GetGroup();
// printf("searching frame index ... group-index=%d-%d, beginf = %20f, endf = %20fn",group,searchindex, beginf,endf);// The approximate index is the right one
if (gpstime>=beginf && gpstime<endf) return searchindex;
// If not, run to the right index, forward
if (gpstime>endf) {
while (gpstime>=endf) {
searchindex++;
mMetaTree->GetEntry(searchindex);
// printf("searching frame index ... group-index=%d-%dn",mTmpMeta->GetGroup(),searchindex);
if (mTmpMeta->GetGroup() != group) {
Warning("FindIndex","Time %20f not in this group",gpstime);
return -1;
}
endf=mTmpMeta->GetStartTime().GetTimeD() + mTmpMeta->GetGroup();
}
return searchindex;
// If not, run to the right index, backward
} else {
while (gpstime<beginf && searchindex>0) {
searchindex--;
mMetaTree->GetEntry(searchindex);
if (mTmpMeta->GetGroup() != group) {
Warning("FindIndex","Time %20f not in this group of frames",gpstime);
return -1;
}
beginf=mTmpMeta->GetStartTime().GetTimeD();
}
return searchindex;
}
}
//______________________________________________________________________________Int_tVFrameMetaDB::FindIndex(Double_t gpstime, Double_t& frbegin, Double_t& frend)
{
// Finds the index of the frame meta corresponding to time "gpstime"// in the metadata tree// returns also the begin and end time of the frameInt_t imetamin, imetamax, imeta;
Double_t beginf=0;
Double_t endf=0;
TObjArray* searchfiles;
VGroupInfo* groupInfo;
Double_t begingr, endgr;
Int_t approxindex;
// ----- Search in the file hash table ------
searchfiles = mHashTable->GetFilesInfo(gpstime);
if (!searchfiles) {
Warning("FindIndex","Requested time not in the database");
return -1;
}
// ----- Search the frame in the meta data tree ------// first, switch on only relevant branches (to speed things up)
mMetaTree->SetBranchStatus("*",0); // disable all branches
mMetaTree->SetBranchStatus("mStartTime*",1); // activate start time
mMetaTree->SetBranchStatus("mLength",1); // activate frame length
mMetaTree->SetBranchStatus("mGroup",1); // active group number
VFrFileIndex* fileindex;
Int_t filenum=searchfiles->GetEntriesFast()-1;
fileindex = (VFrFileIndex*)(searchfiles->At(filenum));
Int_t gosearch = 1;
imeta=-1;
while (fileindex && gosearch) {
// Search in the meta data tree
imetamin = fileindex->GetFirstMetaIndex();
imetamax = fileindex->GetLastMetaIndex();
imeta = -1;
// In case there is a fair number of metadata to scan, look if they// are consecutive, in which case try to access quickly the right meta
if (imetamax-imetamin>15) {
// Loop on all groups that belong to this file
for (int igroup = fileindex->GetFirstGroup();igroup<fileindex->GetLastGroup()+1;igroup++) {
Int_t err = mGroupList->GetEntry(igroup);
if (!err) {
groupInfo = mLastGroupInfo;
} else {
groupInfo = mTmpGroupInfo;
}
begingr = groupInfo->GetBeginTime();
endgr = groupInfo->GetEndTime();
// If requested time inside a group, must be able to find metadata
if (gpstime>=begingr && gpstime<endgr) {
approxindex = groupInfo->ApproximateIndex(gpstime);
if (approxindex>=0) {
imeta = FindIndex(approxindex, gpstime);
mMetaTree->GetEntry(imeta);
beginf = mTmpMeta->GetStartTime().GetTimeD();
endf = beginf + mTmpMeta->GetLength();
gosearch = 0;
break;
} else {
Warning("FindIndex","Impossible to find index");
break;
}
// If before the group beginning, store the distance to find the smallest
}
}
} else {
imeta = imetamin - 1;
while (imeta<=imetamax && gosearch) {
imeta++;
mMetaTree->GetEntry(imeta);
beginf = mTmpMeta->GetStartTime().GetTimeD();
endf = beginf + mTmpMeta->GetLength();
if ( gpstime >= beginf && gpstime <= endf) gosearch = 0;
}
}
filenum--;
if (filenum<0) break;
fileindex = (VFrFileIndex*)(searchfiles->At(filenum));
}
if (gosearch) {
Warning("FindIndex","Requested time not in the database");
// switch on all branches before exit
mMetaTree->SetBranchStatus("*",1); // enable all branches
return -1;
}
frbegin = beginf;
frend = endf;
// switch on all branches before exit
mMetaTree->SetBranchStatus("*",1); // enable all branches
return imeta;
}
//______________________________________________________________________________Int_tVFrameMetaDB::FindNearestGEIndex(Double_t gpstime, VConditionFormula* condf,
Double_t& frbegin, Double_t& frend,
Double_t& cobegin, Double_t& coend,
Int_t& cogroup)
{
// Finds the index of the frame that contains data for time "gpstime"// or the frame that is the nearest next one and that satisfies the selection// formula "condf". (GE stands for Greater or Equal)// The time is a GPS time expressed as a double : seconds.nanoseconds// If the pointer to condition is null, suppose no condition asked, will return// the next nearest frame index.Double_t gpstimet, frbegint, frendt;
Int_t index, cok;
VConditionSetFMDB* condset;
// ----- Search the condition time if needed -------// and load the relevant conditions
if (condf) {
condset = new VConditionSetFMDB(this, condf); // Build a temporary condition set
cok = condset->NearestGESet(gpstime); // Search and load the next set of conditions
if (!cok) {delete condset; return -1;}
// Search the conditions for a set that matches the selection expression
while (1) {
if (condf->EvalInstance(condset)) {
break;
}
if (!condset->NextSet()) {delete condset; return -1;}
}
gpstimet = condset->GetIntersectionStart();
index = FindNearestGEIndex(gpstimet, frbegint, frendt);
if (index == -1) {delete condset; return index;}
frbegin = frbegint;
frend = frendt;
cobegin = gpstimet;
coend = condset->GetIntersectionEnd();
cogroup = condset->GetGroup();
delete condset;
return index;
}
return FindNearestGEIndex(gpstime,frbegin,frend);
}
//______________________________________________________________________________Int_tVFrameMetaDB::FindNearestGEIndex(Double_t gpstime, Double_t& frbegin, Double_t& frend)
{
// Finds the index of the frame that contains data for time "gpstime"// or the frame that is the nearest next one (GE stands for Greater or Equal)// The time is a GPS time expressed as a double : seconds.nanoseconds// the next nearest frame index.
TObjArray* searchfiles;
Int_t searchhashv;
Double_t slotbegin, slotend;
VFrFileIndex* fileindex;
Int_t imetamin, imetamax, imeta;
Double_t beginf,endf, beginfok,endfok;
Int_t nearestimeta;
Double_t nearestgetime;
Int_t gosearch;
VGroupInfo* groupInfo;
Double_t begingr, endgr;
Double_t nearBegin, nearBeginTime; //nearest begin time of a group inside a file
Int_t nearApproxIndex, approxindex;
if (!mIsOpened || !mOption.CompareTo("update", TString::kIgnoreCase)) {
Warning("FindNearestGEIndex","Data base not opened or in update mode");
return -1;
}
// ----- Search in the file hash table ------// first, switch on only relevant branches (to speed things up)
mMetaTree->SetBranchStatus("*",0); // disable all branches
mMetaTree->SetBranchStatus("mStartTime*",1); // activate start time
mMetaTree->SetBranchStatus("mLength",1); // activate frame length
searchhashv = mHashTable->GetHashValue(gpstime);
if (searchhashv<0) searchhashv=0;
// Gets slot begin and end times to protect the search
slotbegin = mHashTable->GetSlotBegin(searchhashv);
slotend = mHashTable->GetSlotEnd(searchhashv);
nearestimeta=-1;
nearestgetime = 1e20;
gosearch = 1;
beginfok=0;
endfok=0;
// ---- Loop on the relevant slots. May have to search on more than one ----// if a condition set
while (gosearch) {
searchfiles = mHashTable->GetFilesInfoDirect(searchhashv);
if (searchfiles) {
Int_t filenum=searchfiles->GetEntriesFast()-1;
fileindex = (VFrFileIndex*)(searchfiles->At(filenum));
// ---- Loop on all the files of a given slot ----
nearBegin = 1e20; //nearest begin time of a group inside a file
nearBeginTime = 0;
nearApproxIndex = -1;
while (fileindex && gosearch) {
// Check that the time asked is not behind the last frame in this file
if (fileindex->GetEndTime() > gpstime) {
// ----- Loop on all the metadata entries corresponding to one file -----
imetamin = fileindex->GetFirstMetaIndex();
imetamax = fileindex->GetLastMetaIndex();
imeta = imetamin;
// ----- In case there is a fair number of metadata to scan, look if they -----// ----- are consecutive, in which case try to access quickly the right meta -----// ----- use the group information to check it -----
if (imetamax-imetamin>15) {
// Loop on all groups that belong to this file
for (int igroup = fileindex->GetFirstGroup();igroup<fileindex->GetLastGroup()+1;igroup++) {
Int_t err = mGroupList->GetEntry(igroup);
if (!err) {
groupInfo = mLastGroupInfo;
} else {
groupInfo = mTmpGroupInfo;
}
begingr = groupInfo->GetBeginTime();
endgr = groupInfo->GetEndTime();
// If requested time inside a group, must be able to find metadata
if (gpstime>=begingr && gpstime<endgr) {
approxindex = groupInfo->ApproximateIndex(gpstime);
if (approxindex>=0) {
nearestimeta = FindIndex(approxindex, gpstime);
mMetaTree->GetEntry(nearestimeta);
beginfok = mTmpMeta->GetStartTime().GetTimeD();
endfok = beginfok + mTmpMeta->GetLength();
gosearch = 0;
break;
} else {
Warning("FindNearestGEIndex","Impossible to find index");
break;
}
// If before the group beginning, store the distance to find the smallest
} else {
if ( gpstime<begingr && (begingr - gpstime) < nearBegin
&& (begingr - gpstime) < nearestgetime
&& begingr>=slotbegin && begingr<slotend) {
nearBegin = begingr - gpstime;
nearBeginTime = begingr+1e-4;
nearApproxIndex = groupInfo->ApproximateIndex(begingr+1e-4);
}
}
}
if (gosearch != 0) {
// If not found right metadata, search for the closest one
if (nearApproxIndex>=0) {
nearestimeta = FindIndex(nearApproxIndex, nearBeginTime);
mMetaTree->GetEntry(nearestimeta);
beginfok = mTmpMeta->GetStartTime().GetTimeD();
nearestgetime = beginfok;
endfok = beginfok + mTmpMeta->GetLength();
} else {
Warning("FindNearestGEIndex","Impossible to find index of start of group");
break;
}
}
} else {
// ----- If a small number of frames is in the file, do a scan of metadata -----
while (imeta<=imetamax && gosearch) {
mMetaTree->GetEntry(imeta);
beginf = mTmpMeta->GetStartTime().GetTimeD();
endf = beginf + mTmpMeta->GetLength();
// Have to look only at frames that are in the slot, not outside it// this may happen if files span more than one slot
if (endf>slotbegin && beginf<slotend) {
if ( gpstime >= beginf && gpstime < endf) {
gosearch = 0;
nearestimeta = imeta;
nearestgetime = beginf;
beginfok = beginf;
endfok = endf;
} else if (gpstime < beginf && nearestgetime > beginf) {
nearestimeta = imeta;
nearestgetime = beginf;
beginfok = beginf;
endfok = endf;
}
}
imeta++;
}
}
}
filenum--;
if (filenum<0) break;
fileindex = (VFrFileIndex*)(searchfiles->At(filenum));
} // end loop on files of a slot
}
if (nearestimeta>=0) gosearch = 0;
searchhashv++;
if (searchhashv> mHashTable->GetCapacity()-1 && nearestimeta<0) {
Warning("FindNearestGEIndex","Trying to access frame outside bounds of the Database");
// switch on all branches before exit
mMetaTree->SetBranchStatus("*",1); // enable all branches
return -1;
}
slotbegin = mHashTable->GetSlotBegin(searchhashv);
slotend = mHashTable->GetSlotEnd(searchhashv);
} // end loop on slots
frbegin = beginfok;
frend = endfok;
// switch on all branches before exit
mMetaTree->SetBranchStatus("*",1); // enable all branches
return nearestimeta;
}
//______________________________________________________________________________Int_tVFrameMetaDB::FindNearestLEIndex(Double_t gpstime, Double_t& frbegin, Double_t& frend)
{
// Finds the index of the frame that contains data for time "gpstime"// or the frame that is the nearest PREVIOUS one (LE stands for Lower or Equal)// The time is a GPS time expressed as a double : seconds.nanoseconds// returns the next nearest frame index.
TObjArray* searchfiles;
Int_t searchhashv;
Double_t slotbegin, slotend;
VFrFileIndex* fileindex;
Int_t imetamin, imetamax, imeta;
Double_t beginf,endf, beginfok,endfok;
Int_t nearestimeta;
Double_t nearestletime;
Int_t gosearch;
if (!mIsOpened || !mOption.CompareTo("update", TString::kIgnoreCase)) {
Warning("FindNearestLEIndex","Data base not opened or in update mode");
return -1;
}
// ----- Search in the file hash table ------// first, switch on only relevant branches (to speed things up)
mMetaTree->SetBranchStatus("*",0); // disable all branches
mMetaTree->SetBranchStatus("mStartTime*",1); // activate start time
mMetaTree->SetBranchStatus("mLength",1); // activate frame length
searchhashv = mHashTable->GetHashValue(gpstime);
if (searchhashv<0) searchhashv=0;
// Gets slot begin and end times to protect the search
slotbegin = mHashTable->GetSlotBegin(searchhashv);
slotend = mHashTable->GetSlotEnd(searchhashv);
nearestimeta=-1;
nearestletime = 0.;
gosearch = 1;
beginfok=0;
endfok=0;
// ---- Loop on the relevant slots. May have to search on more than one ----// if a condition set
while (gosearch) {
searchfiles = mHashTable->GetFilesInfoDirect(searchhashv);
if (searchfiles) {
Int_t filenum=searchfiles->GetEntriesFast()-1;
fileindex = (VFrFileIndex*)(searchfiles->At(filenum));
// ---- Loop on all the files of a given slot ----
while (fileindex && gosearch) {
// Check that the time asked is not before the first frame in this file
if (fileindex->GetStartTime() < gpstime) {
// ----- Loop on all the metadata entries corresponding to one file -----
imetamin = fileindex->GetFirstMetaIndex();
imetamax = fileindex->GetLastMetaIndex();
imeta = imetamin;
while (imeta<=imetamax && gosearch) {
mMetaTree->GetEntry(imeta);
beginf = mTmpMeta->GetStartTime().GetTimeD();
endf = beginf + mTmpMeta->GetLength();
// Have to look only at frames that are in the slot, not outside it// this may happen if files span more than one slot
if (endf>slotbegin && endf<slotend) {
if ( gpstime >= beginf && gpstime < endf) {
gosearch = 0;
nearestimeta = imeta;
nearestletime = beginf;
beginfok = beginf;
endfok = endf;
} else if (gpstime > endf && nearestletime < endf) {
nearestimeta = imeta;
nearestletime = beginf;
beginfok = beginf;
endfok = endf;
}
}
imeta++;
}
}
filenum--;
if (filenum<0) break;
fileindex = (VFrFileIndex*)(searchfiles->At(filenum));
} // end loop on files of a slot
}
if (nearestimeta>=0) gosearch = 0;
searchhashv--;
if (searchhashv<0 && nearestimeta<0) {
Warning("FindNearestLEIndex","Trying to access frame outside bounds of the Database");
// switch on all branches before exit
mMetaTree->SetBranchStatus("*",1); // enable all branches
return -1;
}
slotbegin = mHashTable->GetSlotBegin(searchhashv);
slotend = mHashTable->GetSlotEnd(searchhashv);
} // end loop on slots
frbegin = beginfok;
frend = endfok;
// switch on all branches before exit
mMetaTree->SetBranchStatus("*",1); // enable all branches
return nearestimeta;
}
//______________________________________________________________________________Int_tVFrameMetaDB::FindNearestGECondIndex(const char* condname, Double_t gpstime, Double_t& condbegin, Double_t& condend)
{
// Finds the index of the condition that contains data for time "gpstime"// or the condition that is the nearest next one.// (GE stands for Greater or Equal)// The time is a GPS time expressed as a double : seconds.nanoseconds// returns the index searched for.Int_t conditionnumber = mConditionNames->IndexOf(condname);
if (conditionnumber<0) return -1;
return FindNearestGECondIndex(conditionnumber, gpstime, condbegin, condend);
}
//______________________________________________________________________________Int_tVFrameMetaDB::FindNearestGECondIndex(Int_t conditionnumber, Double_t gpstime, Double_t& condbegin, Double_t& condend)
{
// Finds the index of the condition that contains data for time "gpstime"// or the condition that is the nearest next one.// (GE stands for Greater or Equal)// The time is a GPS time expressed as a double : seconds.nanoseconds// returns the index searched for.
TObjArray* searchfiles;
Int_t searchhashv;
Double_t slotbegin, slotend;
VFrFileIndex* fileindex;
Int_t icondmin, icondmax, icond;
Double_t timec, beginc,endc, begincok,endcok;
Int_t nearesticond;
Double_t nearestgetime;
Int_t gosearch;
TTree* conditiontree;
if (!mIsOpened || !mOption.CompareTo("update", TString::kIgnoreCase)) {
Warning("FindNearestGECondIndex","Data base not opened or in update mode");
return -1;
}
// ----- Get the condition number, tree, and pointer to condition object -----
conditiontree = (TTree*)(mConditionTree->At(conditionnumber));
// In case do not want to process this tree//// *********************** BE CAREFUL, I'm not sure it works in split mode ****************//
if (conditiontree->GetBranch("condition")->TestBit(kDoNotProcess)) return -1;
// ----- Search in the file hash table ------
searchhashv = mHashTable->GetHashValue(gpstime);
if (searchhashv<0) searchhashv=0;
// Gets slot begin and end times to protect the search
slotbegin = mHashTable->GetSlotBegin(searchhashv);
slotend = mHashTable->GetSlotEnd(searchhashv);
nearesticond=-1;
nearestgetime = 1e20;
gosearch = 1;
begincok=0;
endcok=0;
// ---- Loop on the relevant slots. May have to search in more than one ----
while (gosearch) {
searchfiles = mHashTable->GetFilesInfoDirect(searchhashv);
if (searchfiles) {
Int_t filenum=searchfiles->GetEntriesFast()-1;
fileindex = (VFrFileIndex*)(searchfiles->At(filenum));
// ---- Loop on all the files of a given slot ----
while (fileindex && gosearch) {
// Check that the time asked is not behind the last frame in this file
if (fileindex->GetEndTime() > gpstime) {
// ----- Loop on all the condition entries corresponding to one file -----
mConditionsIndex->GetEntry(fileindex->GetConditionsIndex());
icondmin = mTmpCondIndex[conditionnumber].first;
icondmax = mTmpCondIndex[conditionnumber].last;
icond = icondmin;
while (icond<=icondmax && gosearch) {
conditiontree->GetEntry(icond);
timec = mTmpConditions[conditionnumber]->GetTime().GetTimeD();
beginc = timec - mTmpConditions[conditionnumber]->GetTimeBefore();
endc = timec + mTmpConditions[conditionnumber]->GetTimeAfter();
// Have to look only at conditions that are in the slot, not outside it// this may happen if files span more than one slot
if (timec>slotbegin && timec<slotend) {
if ( gpstime >= beginc && gpstime <= endc) {
gosearch = 0;
nearesticond = icond;
nearestgetime = beginc;
begincok = beginc;
endcok = endc;
} else if (gpstime < beginc && nearestgetime > beginc) {
nearesticond = icond;
nearestgetime = beginc;
begincok = beginc;
endcok = endc;
}
}
icond++;
}
}
filenum--;
if (filenum<0) break;
fileindex = (VFrFileIndex*)(searchfiles->At(filenum));
} // end loop on files of a slot
}
if (nearesticond>=0) gosearch = 0;
searchhashv++;
if (searchhashv> mHashTable->GetCapacity()-1 && nearesticond<0) {
Warning("FindNearestGECondIndex","Trying to access frame outside bounds of the Database");
return -1;
}
slotbegin = mHashTable->GetSlotBegin(searchhashv);
slotend = mHashTable->GetSlotEnd(searchhashv);
} // end loop on slots
condbegin = begincok;
condend = endcok;
return nearesticond;
}
//______________________________________________________________________________Int_tVFrameMetaDB::LoadNearestGECondition(Double_t gpstime, const char* name)
{
// Loads the condition "name" that is nearest next to the time "gpstime"// The reference is the start time of the condition, i.e. the time of the// maximum - timeBefore.// If name = "*", loads all the present conditions. To load only relevant// conditions, one should set the branches in the condition trees to active// or inactive state.// These conditions are loaded into variables internal to the database// return the index.Int_t conditionnumber = mConditionNames->IndexOf(name);
if (conditionnumber < 0) return -1;
if (*name=='*') conditionnumber = -2;
return LoadNearestGECondition(gpstime, conditionnumber);
}
//______________________________________________________________________________Int_tVFrameMetaDB::LoadNearestGECondition(Double_t gpstime, Int_t conditionnumber)
{
// Loads the condition corresponding to number "conditionnumber",// that is nearest next to the time "gpstime"// The reference is the start time of the condition, i.e. the time of the// maximum - timeBefore.// If conditionnumber = -2, loads all the present conditions. To load only relevant// conditions, one should set the branches in the condition trees to active// or inactive state.// These conditions are loaded into variables internal to the database// return the index.Double_t beginc, endc;
Int_t icond;
TTree* conditiontree;
icond=-1;
if (conditionnumber==-2) {
for (int i=0; i<mNConditions; i++) {
conditiontree=(TTree*) mConditionTree->At(i);
icond = FindNearestGECondIndex(mConditionNames->GetConditionName(i),gpstime, beginc, endc);
if (icond>=0) conditiontree->GetEntry(icond);
mCurCondTreeIndex[i]=icond; // update the conditions tree indices
}
} else {
conditiontree=(TTree*) mConditionTree->At(conditionnumber);
icond = FindNearestGECondIndex(conditionnumber,gpstime, beginc, endc);
if (icond>=0) conditiontree->GetEntry(icond);
mCurCondTreeIndex[conditionnumber] = icond;
}
return icond;
}
//______________________________________________________________________________Int_tVFrameMetaDB::LoadNextCondition(char* name)
{
// Loads the condition named "name" and nearest// next one to the previously loaded. This method should only be called// in conjunction with LoadNearestGECondition(). Using LoadNearestGECondition()// in one function and LoadNextCondition() in another should be avoided in// order to keep the consistency of the conditions loading.// The condition is loaded into variables internal to the database// return the index.Int_t conditionnumber = mConditionNames->IndexOf(name);
if (conditionnumber<0) return -1;
return LoadNextCondition(conditionnumber);
}
//______________________________________________________________________________Int_tVFrameMetaDB::LoadNextCondition(Int_t conditionnumber)
{
// Loads the condition that is defined by "condition number" and nearest// next one to the previously loaded. This method should only be called// in conjunction with LoadNearestGECondition(). Using LoadNearestGECondition()// in one function and LoadNextCondition() in another should be avoided in// order to keep the consistency of the conditions loading.// The condition is loaded into variables internal to the database// return the index.Int_t previousgroup;
Double_t gpstime;
Int_t icond;
if (mCurCondTreeIndex[conditionnumber] <0) return -1;
TTree* conditiontree = (TTree*)mConditionTree->At(conditionnumber);
if (mCurCondTreeIndex[conditionnumber] >= conditiontree->GetEntries()-1) return -1;
gpstime = mTmpConditions[conditionnumber]->GetTime().GetTimeD() + mTmpConditions[conditionnumber]->GetTimeAfter();
// If the next entry in the tree corresponds to a condition with the same group// number, then it is the right one. This is way faster than searching through// the hash table.
previousgroup = mTmpConditions[conditionnumber]->GetGroup();
mCurCondTreeIndex[conditionnumber] ++;
conditiontree->GetEntry(mCurCondTreeIndex[conditionnumber]);
if (mTmpConditions[conditionnumber]->GetGroup() == previousgroup) return mCurCondTreeIndex[conditionnumber];
icond = LoadNearestGECondition(gpstime+1e-4,conditionnumber);
return icond;
}
//______________________________________________________________________________VFrCondition* VFrameMetaDB::GetLoadedCondition(const char* name)
{
// Returns the condition "name" just loaded (have to do a // LoadNearestGECondition or LoadNextCondition() before calling this methodInt_t conditionnumber = mConditionNames->IndexOf(name);
return mTmpConditions[conditionnumber];
}
//______________________________________________________________________________voidVFrameMetaDB::Draw(const char* selexp, const char* selection, Option_t* option, Double_t start, Double_t length)
{
// Draws expression selexp for conditions defined in the database// Builds a TGraph representing selexp over time, vetoed by selection//// selexp is an expression (formula) referencing a combination of conditions// Example:// selexp = trig.amp simplest case: draw a plot of amplitude of // condition named trig// = sqrt(trig.p) : draw distribution of sqrt(trig.p)// = x*y/z : where x, y and z are conditions// defined in the database// Note that selexp may contain a selection.// example, if selexp= x*(y<0), the value plotted will be x if y<0// and will be 0 otherwise.// // selection is an expression with a combination of the conditions.// In a selection all the C++ operators are authorized.// The value corresponding to the selection expression is used as a veto // to plot the points. If it is not 0, the point is plotted.// The value returned is not relevant, only relevant is// (selection==0) -> point skipped or (selection!=0) -> point plotted//// Examples:// selection1 = "x<y && sqrt(z)>3.2"// selection2 = "(x+y)*(sqrt(z)>3.2"// selection1 returns a value = 0 or 1// selection2 returns a value = x+y if sqrt(z)>3.2// returns a value = 0 otherwise.// Warning : if there is no selection (selection=""), selexp itself// will be taken as selection expression, i.e. only points where// selexp != 0 will be plotted// // option is the drawing option// see TGraph::Draw for the list of all drawing options.// // start is the start time of the first conditions to process// (default is beginning of database values)// length is the length in time of the data to process (default is all data)//
GetPlayer();
if (mPlayer) {
mPlayer->Draw(selexp, selection, option, start, length);
return;
}
else {
Warning("VFrameMetaDB::Draw","Couldn't open a player");
return;
}
}
//______________________________________________________________________________voidVFrameMetaDB::Print(Option_t* opt)
{
// Prints information about the database and it's contents// option :// "full" : prints all the database info. VERY LONG. mainly for test// "conditions" : prints only conditions names
TString sopt = opt;
sopt.ToLower();
printf(" ____________________________ n");
printf(" | | n");
printf(" | Frame information database | n");
printf(" |____________________________| n");
// Prints trigger names if asked for
if (!sopt.CompareTo("conditions", TString::kIgnoreCase)) {
printf("nList of conditions present in this databasen");
printf( "___________________________________________n\n");
mConditionNames->Print();
return;
}
// Gets the first frame
printf("n First frame start time (GPS) : %14.4fn",GetStart());
printf(" =============================================n");
printf("n Global start time (GPS) : %14.4fn",GetDBStart());
printf(" Global end time (GPS) : %14.4fn",GetDBEnd());
if (sopt.Contains("full")) {
GetDBHash()->Print("full");
printf("n\n Scan of the Meta tree contents n");
printf( " ______________________________n\n");
mMetaTree->Scan("mRunNumber:mFrameNumber:mGroup:mStartTime.mSec");
} else {
GetDBHash()->Print("small");
}
}
//______________________________________________________________________________VVirtualMetaDBPlayer *VFrameMetaDB::GetPlayer()
{
// Load the VMetaDBPlayer (if not already done) // Pointer to player is mPlayer
if (mPlayer) return mPlayer;
mPlayer = VVirtualMetaDBPlayer::MetaDBPlayer(this);
return mPlayer;
}
//______________________________________________________________________________voidVFrameMetaDB::GetMetaData(VMetaData* meta, Double_t gpstime)
{
// Retrieve the meta data corresponding to timeDouble_t beginf,endf;
Int_t imeta;
if (!mIsOpened) {
Warning("GetMetaData","Data base not opened");
meta->Clear();
return;
}
// Finds the index of the meta in the metadata tree// returns also the begin and end time of the frame
imeta = FindIndex(gpstime, beginf, endf);
if (imeta < 0) {
meta->Clear();
return;
}
mCurMetaIndex = imeta;
mCurFrameStart = beginf;
mCurFrameEnd = endf;
// ---- Get the metadata and transfer it to VMetaData object ----
mMetaTree->GetEntry(imeta);
meta->SetRun(mTmpMeta->GetRunNumber());
meta->SetFrame(mTmpMeta->GetFrameNumber());
meta->SetStartTime(mTmpMeta->GetStartTime().GetTimeD());
meta->SetLocalStartTime(0);
meta->SetLength(mTmpMeta->GetLength());
meta->SetQuality(mTmpMeta->GetQuality());
meta->SetTrigger(mTmpMeta->GetTrigger());
meta->SetFileName(mTmpMetaString->GetFileName().Data());
meta->SetDetector(mTmpMetaString->GetDetector().Data());
meta->SetState(mTmpMetaString->GetState().Data());
return;
}
//______________________________________________________________________________voidVFrameMetaDB::NextMetaData(VMetaData* meta)
{
// Retrieve the next meta dataDouble_t beginf, endf;
if (!mIsOpened) {
Warning("NextMetaData","Data base not opened");
meta->Clear();
return;
}
// First, search the metadata to see if the next meta is the right one
if (meta->GetRun() == mTmpMeta->GetRunNumber() &&
meta->GetFrame() == mTmpMeta->GetFrameNumber() &&
!strcmp(meta->GetFileName(),mTmpMetaString->GetFileName().Data()) &&
mCurMetaIndex+1 < mMetaTree->GetEntries()) {
mMetaTree->GetEntry(mCurMetaIndex+1);
beginf = mTmpMeta->GetStartTime().GetTimeD();
endf = beginf + mTmpMeta->GetLength();
if (beginf >= mCurFrameEnd && beginf < mCurFrameEnd+1e-4) {
mCurMetaIndex++;
mCurFrameStart = beginf;
mCurFrameEnd = endf;
meta->SetRun(mTmpMeta->GetRunNumber());
meta->SetFrame(mTmpMeta->GetFrameNumber());
meta->SetStartTime(mTmpMeta->GetStartTime().GetTimeD());
meta->SetLocalStartTime(0);
meta->SetLength(mTmpMeta->GetLength());
meta->SetQuality(mTmpMeta->GetQuality());
meta->SetTrigger(mTmpMeta->GetTrigger());
meta->SetFileName(mTmpMetaString->GetFileName().Data());
meta->SetDetector(mTmpMetaString->GetDetector().Data());
meta->SetState(mTmpMetaString->GetState().Data());
return;
}
}
NextMetaData(meta,meta->GetEndTime()+1e-4);
return;
}
//______________________________________________________________________________voidVFrameMetaDB::PreviousMetaData(VMetaData* meta)
{
// Retrieve the previous meta dataDouble_t beginf, endf;
Int_t nearestimeta;
if (!mIsOpened) {
Warning("PreviousMetaData","Data base not opened");
meta->Clear();
return;
}
// First, search the metadata to see if the previous meta is the good one
if (meta->GetRun() == mTmpMeta->GetRunNumber() &&
meta->GetFrame() == mTmpMeta->GetFrameNumber() &&
!strcmp(meta->GetFileName(),mTmpMetaString->GetFileName().Data()) &&
mCurMetaIndex > 0) {
mMetaTree->GetEntry(mCurMetaIndex-1);
beginf = mTmpMeta->GetStartTime().GetTimeD();
endf = beginf + mTmpMeta->GetLength();
if (endf <= mCurFrameStart && endf > mCurFrameStart-1e-4) {
mCurMetaIndex--;
mCurFrameStart = beginf;
mCurFrameEnd = endf;
meta->SetRun(mTmpMeta->GetRunNumber());
meta->SetFrame(mTmpMeta->GetFrameNumber());
meta->SetStartTime(mTmpMeta->GetStartTime().GetTimeD());
meta->SetLocalStartTime(0);
meta->SetLength(mTmpMeta->GetLength());
meta->SetQuality(mTmpMeta->GetQuality());
meta->SetTrigger(mTmpMeta->GetTrigger());
meta->SetFileName(mTmpMetaString->GetFileName().Data());
meta->SetDetector(mTmpMetaString->GetDetector().Data());
meta->SetState(mTmpMetaString->GetState().Data());
return;
}
}
nearestimeta = FindNearestLEIndex(meta->GetStartTime().GetTimeD()-1e-4, beginf, endf);
if (nearestimeta==-1) {
meta->Clear();
return;
}
mCurMetaIndex = nearestimeta;
mCurFrameStart = beginf;
mCurFrameEnd = endf;
// ---- Get the metadata and transfer it to VMetaData object ----
mMetaTree->GetEntry(nearestimeta);
meta->SetRun(mTmpMeta->GetRunNumber());
meta->SetFrame(mTmpMeta->GetFrameNumber());
meta->SetStartTime(mTmpMeta->GetStartTime().GetTimeD());
meta->SetLocalStartTime(0);
meta->SetLength(mTmpMeta->GetLength());
meta->SetQuality(mTmpMeta->GetQuality());
meta->SetTrigger(mTmpMeta->GetTrigger());
meta->SetFileName(mTmpMetaString->GetFileName().Data());
meta->SetDetector(mTmpMetaString->GetDetector().Data());
meta->SetState(mTmpMetaString->GetState().Data());
return;
}
//______________________________________________________________________________voidVFrameMetaDB::NextMetaData(VMetaData* meta, VConditionSet* condset0)
{
// Retrieve the next meta data with condition setInt_t gosearch;
Int_t condgroup, nextcondgroup;
Int_t approxindex;
Double_t nextcostart;
VGroupInfo* groupinfo; // needed in case the group is the last one (not yet
// recorded in the group info tree)VConditionSetFMDB* condset;
if (!mIsOpened) {
Warning("NextMetaData","Data base not opened");
meta->Clear();
return;
}
if (!condset0) {
Warning("NextMetaData","No condition set defined");
meta->Clear();
return;
}
// Transform VConditionSet into VConditionSetFMDB
condset = (VConditionSetFMDB*)condset0;
// First, search the condition trees to see if the next condition// belongs to the same group as the previous one. If this is the case,// it is much faster to search the metadata in the same group.
condgroup = condset->GetGroup();
gosearch = 1;
while (gosearch) {
// Jump to the next valid set of conditions
if (!condset->NextFormSet()) {
meta->Clear();
return;
}
nextcondgroup = condset->GetGroup();
if (condgroup == nextcondgroup) { // if the same group of conditions
int err = mGroupList->GetEntry(nextcondgroup); // Get info from the group list
if (!err) {
// if no group info loaded, means we are looking at the last// group info, wich is not yet recorded in the group info tree
groupinfo = mLastGroupInfo;
} else {
groupinfo = mTmpGroupInfo;
}
// Get the approximate index of the right frame metadata
nextcostart = condset->GetIntersectionStart();
approxindex = groupinfo->ApproximateIndex(nextcostart);
// Find the right index and return the frame
mCurMetaIndex = FindIndex(approxindex, nextcostart);
mMetaTree->GetEntry(mCurMetaIndex);
mCurFrameStart = mTmpMeta->GetStartTime().GetTimeD();
mCurFrameEnd = mCurFrameStart + mTmpMeta->GetLength();
// ---- Get the metadata and transfer it to VMetaData object ----
mMetaTree->GetEntry(mCurMetaIndex);
meta->SetRun(mTmpMeta->GetRunNumber());
meta->SetFrame(mTmpMeta->GetFrameNumber());
meta->SetStartTime(mTmpMeta->GetStartTime().GetTimeD());
meta->SetLocalStartTime(0);
meta->SetLength(mTmpMeta->GetLength());
meta->SetQuality(mTmpMeta->GetQuality());
meta->SetTrigger(mTmpMeta->GetTrigger());
meta->SetFileName(mTmpMetaString->GetFileName().Data());
meta->SetDetector(mTmpMetaString->GetDetector().Data());
meta->SetState(mTmpMetaString->GetState().Data());
return;
} else {
gosearch=0;
}
}
NextMetaData(meta,condset->GetIntersectionStart()+1e-4);
return;
}
//______________________________________________________________________________voidVFrameMetaDB::NextMetaData(VMetaData* meta, Double_t time, VConditionSet* condset0)
{
// Retrieve the next meta data after time "time" with condition set condsetInt_t gosearch;
Int_t condgroup, nextcondgroup;
Int_t approxindex;
Double_t nextcostart;
VGroupInfo* groupinfo; // needed in case the group is the last one (not yet
// recorded in the group info tree)VConditionSetFMDB* condset;
if (!mIsOpened) {
Warning("NextMetaData","Data base not opened");
meta->Clear();
return;
}
if (!condset0) {
NextMetaData(meta,time);
return;
}
// Transform VConditionSet into VConditionSetFMDB
condset = (VConditionSetFMDB*)condset0;
// First, search the condition trees to see if the next condition// belongs to the same group as the previous one. If this is the case,// it is much faster to search the metadata in the same group.
condgroup = condset->GetGroup();
gosearch = 1;
while (gosearch) {
// Jump to the next valid set of conditions
if (!condset->NearestGEFormSet(time)) {
meta->Clear();
return;
}
nextcondgroup = condset->GetGroup();
if (condgroup == nextcondgroup) { // if the same group of conditions
int err = mGroupList->GetEntry(nextcondgroup); // Get info from the group list
if (!err) {
// if no group info loaded, means we are looking at the last// group info, wich is not yet recorded in the group info tree
groupinfo = mLastGroupInfo;
} else {
groupinfo = mTmpGroupInfo;
}
// Get the approximate index of the right frame metadata
nextcostart = condset->GetIntersectionStart();
approxindex = groupinfo->ApproximateIndex(nextcostart);
// Find the right index and return the frame
mCurMetaIndex = FindIndex(approxindex, nextcostart);
mMetaTree->GetEntry(mCurMetaIndex);
mCurFrameStart = mTmpMeta->GetStartTime().GetTimeD();
mCurFrameEnd = mCurFrameStart + mTmpMeta->GetLength();
// ---- Get the metadata and transfer it to VMetaData object ----
mMetaTree->GetEntry(mCurMetaIndex);
meta->SetRun(mTmpMeta->GetRunNumber());
meta->SetFrame(mTmpMeta->GetFrameNumber());
meta->SetStartTime(mTmpMeta->GetStartTime().GetTimeD());
meta->SetLocalStartTime(0);
meta->SetLength(mTmpMeta->GetLength());
meta->SetQuality(mTmpMeta->GetQuality());
meta->SetTrigger(mTmpMeta->GetTrigger());
meta->SetFileName(mTmpMetaString->GetFileName().Data());
meta->SetDetector(mTmpMetaString->GetDetector().Data());
meta->SetState(mTmpMetaString->GetState().Data());
return;
} else {
gosearch=0;
}
}
NextMetaData(meta,condset->GetIntersectionStart()+1e-4);
return;
}
//______________________________________________________________________________voidVFrameMetaDB::NextMetaData(VMetaData* meta, Double_t gpstime, VConditionFormula* condf)
{
// Retrieve the next meta data with time greater or equal to "time"// and selection conditionDouble_t beginfok,endfok,begincok, endcok;
Int_t groupcok;
Int_t nearestimeta;
if (!mIsOpened) {
Warning("GetNextMetaData","Data base not opened");
meta->Clear();
return;
}
nearestimeta = FindNearestGEIndex(gpstime, condf,
beginfok, endfok, begincok,endcok, groupcok);
if (nearestimeta==-1) {
meta->Clear();
return;
}
mCurMetaIndex = nearestimeta;
mCurFrameStart = beginfok;
mCurFrameEnd = endfok;
// ---- Get the metadata and transfer it to VMetaData object ----
mMetaTree->GetEntry(nearestimeta);
meta->SetRun(mTmpMeta->GetRunNumber());
meta->SetFrame(mTmpMeta->GetFrameNumber());
meta->SetStartTime(mTmpMeta->GetStartTime().GetTimeD());
meta->SetLocalStartTime(0);
meta->SetLength(mTmpMeta->GetLength());
meta->SetQuality(mTmpMeta->GetQuality());
meta->SetTrigger(mTmpMeta->GetTrigger());
meta->SetFileName(mTmpMetaString->GetFileName().Data());
meta->SetDetector(mTmpMetaString->GetDetector().Data());
meta->SetState(mTmpMetaString->GetState().Data());
return;
}
//______________________________________________________________________________voidVFrameMetaDB::NextMetaData(VMetaData* meta, Double_t gpstime, const char* selection)
{
// Retrieve the next meta data with time greater or equal to "time"// and selection conditionVConditionFormula* condf;
if (!selection) {
NextMetaData(meta, gpstime, (VConditionFormula*)0);
return;
}
condf = new VConditionFormula("condf",selection,this);
NextMetaData(meta,gpstime,condf);
delete condf;
return;
}
//______________________________________________________________________________VConditionSet* VFrameMetaDB::CreateConditionSet(const char* condfs, const char* selfs)
{
// Creates a condition set adapted to this Frame Info DBVConditionSetFMDB* cs = new VConditionSetFMDB(this,condfs,selfs);
return (VConditionSet*)cs;
}
- ROOT page - VEGA page - Class index - Top of the page This page has been automatically generated. If you have any comments or suggestions
about the page layout send a mail to
, or
contact
with any questions or problems regarding ROOT or VEGA.