1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 ///////////////////////////////////////////////////////////////////////////////
20 // access class to a DB file inside an organized directory structure //
21 // (DBFolder/detector/dbType/detSpecType) //
23 ///////////////////////////////////////////////////////////////////////////////
30 #include <TObjArray.h>
31 #include <TObjString.h>
35 #include "AliRunData.h"
36 #include "AliSelectionMetaData.h"
37 #include "AliRunDataOrganizedFile.h"
40 ClassImp(AliRunDataOrganizedFile)
42 //_____________________________________________________________________________
43 AliRunDataOrganizedFile::AliRunDataOrganizedFile(const char* DBFolder) :
48 TString buffer(fDBFolder);
49 gSystem->ExpandPathName(buffer);
50 if(!gSystem->OpenDirectory(buffer)){
51 AliError(Form("Path %s not a directory",fDBFolder.Data()));
55 //_____________________________________________________________________________
56 AliRunDataOrganizedFile::~AliRunDataOrganizedFile()
60 if (fDBFolder) fDBFolder="";
63 //_____________________________________________________________________________
64 AliRunDataOrganizedFile::AliRunDataOrganizedFile(const AliRunDataOrganizedFile& /*db*/) :
70 AliFatal("not implemented");
73 //_____________________________________________________________________________
74 AliRunDataOrganizedFile& AliRunDataOrganizedFile::operator = (const AliRunDataOrganizedFile& /*db*/)
76 // assignment operator
78 AliFatal("not implemented");
82 //_____________________________________________________________________________
83 AliRunData* AliRunDataOrganizedFile::GetEntry(AliSelectionMetaData& selMetaData, Int_t runNumber)
85 // get an object from the data base
87 TDirectory* saveDir = gDirectory;
89 // Find the right file in the directory
91 TObjArray *objarr = FindDataBaseFile(selMetaData, runNumber);
92 if(!objarr || objarr->GetEntries()==0) return NULL;
93 if(objarr->GetEntries()>1)
94 AliWarning("Warning: more than 1 file match requirements, I will open the first found!");
98 TObjString *objstr= (TObjString*) objarr->At(0); // there should be only one item
99 TString fileName(objstr->GetName());
100 TFile *dbFile = new TFile(fileName.Data(),"READ");
101 if (!dbFile || !dbFile->IsOpen()) {
102 AliError(Form("could not open file %s", fileName.Data()));
106 // get the only AliRunData object from the file
107 // I suppose that the object in the file is a AliRunData entry with
108 // name="DetSpecType" (set in SelectionMetaData)
112 AliRunData *entry = (AliRunData*) dbFile->Get(selMetaData.GetDetSpecType());
114 if(!entry || !entry->InheritsFrom(AliRunData::Class())) {
115 AliError(Form("No entry named %s found!",selMetaData.GetDetSpecType()));
116 dbFile->Close(); delete dbFile;
117 if (saveDir) saveDir->cd(); else gROOT->cd();
121 // now set the run range and version got from the filename
122 // to the object's metadata!
124 TString fileNameShort=fileName;
125 fileNameShort.Remove(0,fileNameShort.Last('/')+1);
126 int numbers[3]={-1,-1,-1}; // numbers[0]=firstRun, numbers[1]=lastRun, numbers[2]=Version
127 GetNumbers(fileNameShort, numbers);
128 entry->SetRunRange(numbers[0],numbers[1]);
129 entry->SetVersion(numbers[2]);
131 // close file, return retieved entry
133 dbFile->Close(); delete dbFile;
134 if (saveDir) saveDir->cd(); else gROOT->cd();
136 if(selMetaData.GetVersion() > -1 && numbers[2] != selMetaData.GetVersion())
137 AliWarning(Form("Warning: selected version (%d) not found, got version %d instead",
138 selMetaData.GetVersion(),numbers[2]));
144 //_____________________________________________________________________________
145 Bool_t AliRunDataOrganizedFile::PutEntry(AliRunData* entry)
147 // puts an object into the database
149 // AliRunData entry is composed by the object and its MetaData
150 // this method takes the metaData, reads the name, runRange and Version
151 // creates the directory structure and the file name
152 // looks for runs with same or overlapping runrange, if exist increment version
153 // (therefore version should not be put in the metadata)
154 // if the runrange is different (but overlapping) from a preceding version, a warning message
156 // sets the runrange and version in the object metadata = -1 (to avoid inconsistencies)
157 // open the filem, write the entry in the file.
158 // Note: the key name of the entry is "DetSpecType"
161 if(!entry) return kFALSE;
162 TDirectory* saveDir = gDirectory;
164 Int_t firstRun=entry->GetObjectMetaData().GetFirstRun();
165 Int_t lastRun=entry->GetObjectMetaData().GetLastRun();
166 if(firstRun<0 || lastRun<0 || lastRun<firstRun) {
167 AliError(Form("Run range not set or not valid: %d - %d !", firstRun, lastRun));
171 TString name(entry->GetObjectMetaData().GetName());
173 while(name.EndsWith("/")) name.Remove(name.Last('/'));
174 while(name.BeginsWith("/")) name.Remove(name.First('/'),1);
176 TString detSpecType(name(name.Last('/')+1, name.Length()-name.Last('/')));
178 TString buffer(fDBFolder);
179 gSystem->ExpandPathName(buffer);
180 while(buffer.EndsWith("/")) buffer.Remove(buffer.Last('/'));
184 name+='/'; // name=detector/dbType/detSpecType/
186 while ((index = name.Index("/")) >= 0) {
187 TString dirName(name(0, index));
188 buffer+='/'; buffer+=dirName;
189 dir=gSystem->OpenDirectory(buffer);
191 AliWarning(Form("Directory %s does not exist! It will be created...",buffer.Data()));
192 TString command = "mkdir "+ buffer;
193 gSystem->Exec(command.Data());
195 name.Remove(0, index+1);
198 TString strfName="Run";
200 TString levelContent="";
201 Int_t maxVersion=-1, run1=-1, run2=-1;
202 int numbers[3]={-1,-1,-1}; // numbers[0]=firstRun, numbers[1]=lastRun, numbers[2]=Version
203 while(levelContent=gSystem->GetDirEntry(dir)){
204 if(levelContent=="." || levelContent=="..") continue; if(levelContent=="") break;
205 if(levelContent.Contains(strfName)){
206 GetNumbers(levelContent, numbers);
207 if((firstRun>=numbers[0] && firstRun<=numbers[1]) ||
208 (lastRun>=numbers[0] && lastRun<=numbers[1]) ||
209 (firstRun<=numbers[0] && lastRun>=numbers[1])) {// overlap!
210 if(numbers[2]>maxVersion) {
211 maxVersion=numbers[2];
212 run1=numbers[0]; run2=numbers[1];
218 if((run1!=-1 && run2!=-1) && (firstRun!=run1 || lastRun!=run2))
219 AliWarning(Form("Run range modified w.r.t. preceding version (%d, %d)",run1, run2));
222 if(firstRun==lastRun) {
225 strfName+=firstRun; strfName+="-"; strfName+=lastRun;
227 strfName+="_v"; strfName+=maxVersion+1; strfName+=".root";
228 buffer+='/'; buffer+=strfName;
231 TFile *dbFile = new TFile(buffer.Data(),"NEW");
232 if(!dbFile || !dbFile->IsWritable()){
233 AliError(Form("The data base file is not writable. "
234 "The object %s was not inserted", entry->GetName()));
240 entry->SetRunRange(-1,-1); entry->SetVersion(-1);
243 Bool_t result = (entry->Write(detSpecType) != 0);
244 if (saveDir) saveDir->cd(); else gROOT->cd();
245 dbFile->Close(); delete dbFile;
248 AliInfo(Form("Run object %s",entry->GetName()));
249 AliInfo(Form("was successfully written into file %s !",buffer.Data()));
255 /*****************************************************************************/
257 TObjArray* AliRunDataOrganizedFile::FindDataBaseFile(AliSelectionMetaData& selMetaData, Int_t runNumber){
258 // Find DataBase file name in a local directory. The filename must be in the form: Run#run1-#run2_v#version.root
259 // TRegexp allowed: selMetaData's name can be for example: "detector/*" !!
261 TObjArray *fileNameColl=new TObjArray();
263 TString buffer(fDBFolder);
264 if(!(buffer.EndsWith("/"))) buffer+="/";
265 gSystem->ExpandPathName(buffer);
267 TString bufftInit=buffer; // buffInit="$ALICE_ROOT/DB/
268 TString levelContent="";
270 TString detector(selMetaData.GetDetector());
271 TString dbType(selMetaData.GetDBType());
272 TString detSpecType(selMetaData.GetDetSpecType());
273 int selVersion = selMetaData.GetVersion();
275 void *dirLevInit = gSystem->OpenDirectory(buffer);
276 while(levelContent=gSystem->GetDirEntry(dirLevInit)){ // lev0! In Detector directory (ZDC, TPC...)!!
278 if(levelContent=="." || levelContent=="..") continue; if(levelContent=="") break;
279 if(!(detector=="*") && !levelContent.Contains(TRegexp(detector)) ) continue;
281 buffer=bufftInit+levelContent; buffer+='/'; // buffer="$ALICE_ROOT/DB/detector/
282 TString bufft0=buffer; // bufft0="$ALICE_ROOT/DB/detector/
284 void *dirLev0 = gSystem->OpenDirectory(buffer);
285 while(levelContent=gSystem->GetDirEntry(dirLev0)){ // lev1! dbType directory (Calib, Align)!!
287 if(levelContent=="." || levelContent=="..") continue; if(levelContent=="") break;
288 if(!(dbType=="*") && !levelContent.Contains(TRegexp(dbType))) continue;
290 buffer=bufft0+levelContent;buffer+='/'; // buffer="$ALICE_ROOT/DB/detector/dbType/
291 TString bufft1=buffer; // bufft1="$ALICE_ROOT/DB/detector/dbType/
293 void *dirLev1 = gSystem->OpenDirectory(buffer);
294 while(levelContent=gSystem->GetDirEntry(dirLev1)){ // lev2! detSpecType directory (Pedestals, gain....)!!
296 if(levelContent=="." || levelContent=="..") continue; if(levelContent=="") break;
297 if(!(detSpecType=="*") && !levelContent.Contains(TRegexp(detSpecType))) continue;
299 buffer=bufft1+levelContent;buffer+='/'; // buffer="$ALICE_ROOT/DB/detector/dbType/detSpecType/
300 TString bufft2=buffer; // bufft2="$ALICE_ROOT/DB/detector/dbType/detSpecType/
302 void *dirLev2 = gSystem->OpenDirectory(buffer);
305 while(levelContent=gSystem->GetDirEntry(dirLev2)){ // lev3! Run directory (Run#XXX-#YYY_v#ZZ.root)!!
307 if(levelContent=="." || levelContent=="..") continue; if(levelContent=="") break;
308 if(!levelContent.BeginsWith("Run")) continue;
310 int numbers[3]={-1,-1,-1}; // numbers[0]=firstRun, numbers[1]=lastRun, numbers[2]=Version
311 GetNumbers(levelContent,numbers);
312 if(numbers[0]<0 || numbers[1]<0 || numbers[2]<0 ) continue; // wrong run filename format!
313 if(numbers[0]>runNumber || numbers[1]<runNumber) continue; // data not valid for run number
315 if((selVersion == -1 || numbers[2] <= selVersion) && numbers[2] >= oldVers) {
316 buffer=bufft2+levelContent;
317 str=new TObjString(buffer.Data());
319 if(numbers[2]==selVersion) break;
321 } // end loop on runs
322 if(str) fileNameColl->Add(str);
323 } // end loop in lev1
324 } // end loop in lev0
325 } // end loop in levInit
327 AliInfo(Form("Found %d entries matching requirements", fileNameColl->GetEntriesFast()));
328 ToAliInfo(fileNameColl->ls());
332 //_____________________________________________________________________________
334 void AliRunDataOrganizedFile::GetNumbers(const TString strName, int *numArray)
336 // Gets the numbers (#Run1, #Run2, #Version) from the filename: Run#Run1-#Run2_v#Version.root
338 int indexMinus=strName.Last('-');
339 int indexUScore=strName.Last('_');
340 int indexPoint=strName.Last('.');
342 if(indexUScore<0 || indexPoint<0 )
343 {AliError(Form("Check sintax %s",strName.Data())); return;}
345 if(indexMinus<0){ // only 1 Run number!
346 TString cRun=strName(3,indexUScore-3);
347 if(!(cRun.IsDigit()))
348 {AliError(Form("%s not a digit! Check sintax %s",cRun.Data(),strName.Data())); return;}
349 numArray[0] = (int) strtol(cRun.Data(),0,10);
350 numArray[1] = numArray[0];
352 TString cFirstRun = strName(3,indexMinus-3);
353 TString cLastRun = strName(indexMinus+1,indexUScore-(indexMinus+1));
354 if(!(cFirstRun.IsDigit()) || !(cLastRun.IsDigit()))
355 {AliError(Form("%s or %s are not digit! Check sintax %s",
356 cFirstRun.Data(), cLastRun.Data(), strName.Data())); return;}
357 numArray[0] = (int) strtol(cFirstRun.Data(),0,10);
358 numArray[1] = (int) strtol(cLastRun.Data(),0,10);
360 TString cVersion = strName(indexUScore+2,indexPoint-(indexUScore+2));
361 if(!(cVersion.IsDigit())){
362 AliError(Form("%s not a digit! Check sintax %s",cVersion.Data(),strName.Data())); return;}
363 numArray[2] = (int) strtol(cVersion.Data(),0,10);