]> git.uio.no Git - u/mrichter/AliRoot.git/blame - STEER/AliCDBLocal.cxx
Generation of Lambda1520
[u/mrichter/AliRoot.git] / STEER / AliCDBLocal.cxx
CommitLineData
fe913d8f 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
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 **************************************************************************/
15
16/* $Id$ */
17
18/////////////////////////////////////////////////////////////////////////////////////////////////
19// //
20// access class to a DB file inside an organized directory structure //
21// file name = "DBFolder/detector/dbType/detSpecType/Run#firstRun-#lastRun _v#version.root" //
22// //
23/////////////////////////////////////////////////////////////////////////////////////////////////
24
25
26#include <TFile.h>
27#include <TKey.h>
28#include <TROOT.h>
29#include <TSystem.h>
30#include <TObjArray.h>
31#include <TObjString.h>
32#include <TRegexp.h>
33
34#include "AliLog.h"
35#include "AliCDBLocal.h"
36
37
38ClassImp(AliCDBLocal)
39
40//_____________________________________________________________________________
41AliCDBLocal::AliCDBLocal(const char* DBFolder) :
42 AliCDBStorage(),
43 fDBFolder(DBFolder)
44{
45// constructor
46 gSystem->ExpandPathName(fDBFolder);
47 void *dir=0;
48 if(!(dir=gSystem->OpenDirectory(fDBFolder))){
49 AliFatal(Form("Path %s not a directory",fDBFolder.Data()));
50 }
51 gSystem->FreeDirectory(dir);
52
53 while(fDBFolder.EndsWith("/")) fDBFolder.Remove(fDBFolder.Last('/'));
54 fDBFolder+="/";
55}
56
57//_____________________________________________________________________________
58AliCDBLocal::~AliCDBLocal()
59{
60 // destructor
61
62}
63
64//_____________________________________________________________________________
65AliCDBLocal::AliCDBLocal(const AliCDBLocal& /*db*/) :
66 AliCDBStorage(),
67 fDBFolder("")
68{
69 // copy constructor
70
71 AliFatal("not implemented");
72}
73
74//_____________________________________________________________________________
75AliCDBLocal& AliCDBLocal::operator = (const AliCDBLocal& /*db*/)
76{
77// assignment operator
78
79 AliFatal("not implemented");
80 return *this;
81}
82
83//_____________________________________________________________________________
84AliCDBEntry* AliCDBLocal::GetEntry(AliCDBMetaDataSelect& selMetaData, Int_t runNumber)
85{
86// get an object from the data base
87
88 TDirectory* saveDir = gDirectory;
89
90 // Find the right file in the directory
91 TString prefix="_v"; // development mode: fileName=Run#Run1-#Run2_v#Version.root
92 if(fStorageMode==kProduction) prefix="_Prod"; // production mode: fileName=Run#Run1-#Run2_Prod#Version.root
93
94 TString buffer(fDBFolder);
95 TString name(selMetaData.GetName());
96 buffer+=name; buffer+='/';
97
98 int selVersion = selMetaData.GetVersion();
99
100 void *dir = gSystem->OpenDirectory(buffer);
101 if(!dir) {
102 AliError(Form("Directory %s not found", name.Data()));
103 AliError(Form("in DB folder %s", fDBFolder.Data()));
104 return NULL;
105 }
106
107 TString fileName="";
108 TString levelContent="";
109 int oldVers=-1;
110 // in this array the "numbers" of the retrieved fileName (Run1, Run2, Version) are stored for later usage
111 int fileNumbers[3]={-1,-1,-1};
112 while(levelContent=gSystem->GetDirEntry(dir)){
113
114 if(levelContent=="." || levelContent=="..") continue; if(levelContent=="") break;
115 if(!levelContent.Contains("Run") || !levelContent.Contains(prefix)) continue;
116
117 int numbers[3]={-1,-1,-1}; // numbers[0]=firstRun, numbers[1]=lastRun, numbers[2]=Version
118 // gets the 3 "numbers" in the file name
119 if(!DecodeFileName(levelContent,numbers, prefix)) continue; // wrong run filename format
120 if(numbers[0]>runNumber || numbers[1]<runNumber) continue; // data not valid for run number
121
122 if(selVersion == -1) {
123 if(numbers[2] >= oldVers){
124 if(numbers[2] == oldVers){
125 // more than one file valid for the run -> error!
126 AliError(Form("More than one object valid for run %d, version %d!", runNumber, oldVers));
127 AliError(Form("No object will be returned!"));
128 gSystem->FreeDirectory(dir);
129 return NULL;
130 }
131 fileName=levelContent;
132 oldVers=numbers[2];
133 fileNumbers[0]=numbers[0]; fileNumbers[1]=numbers[1]; fileNumbers[2]=numbers[2];
134 }
135 } else {
136 if(numbers[2] == selVersion){
137 if(fileName != ""){
138 // filename was already assigned, this means there is more than one file valid for the run -> error!
139 AliError(Form("More than one object valid for run %d, version %d!", runNumber, selVersion));
140 AliError(Form("No object will be returned!"));
141 gSystem->FreeDirectory(dir);
142 return NULL;
143 }
144 fileName=levelContent;
145 fileNumbers[0]=numbers[0]; fileNumbers[1]=numbers[1]; fileNumbers[2]=numbers[2];
146 }
147 }
148
149 } // end loop on runs
150
151 gSystem->FreeDirectory(dir);
152 buffer+=fileName;
153 if(!buffer.EndsWith(".root")){
154 AliError(Form("No DB file matching criteria found!"));
155 return NULL;
156 }
157
158 TFile *DBFile = new TFile(buffer.Data(),"READ");
159 if(!DBFile || !DBFile->IsOpen()) {
160 AliError(Form("could not open file %s", buffer.Data()));
161 return NULL;
162 }
163
164 AliInfo(Form("File %s succesfully opened", buffer.Data()));
165
166// get the only AliCDBEntry object from the file
167// I assume that the object in the file is a AliCDBEntry entry with
168// name="detSpecType" (set in CDBMetaDataSelect)
169
170 DBFile->cd();
171
172 AliCDBEntry *entry = (AliCDBEntry*) DBFile->Get(selMetaData.GetDetSpecType());
173
174 if(!entry || !entry->InheritsFrom(AliCDBEntry::Class())) {
175 AliError(Form("No entry named %s found!",selMetaData.GetDetSpecType()));
176 DBFile->Close(); delete DBFile; DBFile=0;
177 if (saveDir) saveDir->cd(); else gROOT->cd();
178 return NULL;
179 }
180
181// Version 1:
182// set the run range and version got from the filename
183// to the object's metadata!
184
185// entry->SetRunRange(fileNumbers[0],fileNumbers[1]);
186// entry->SetVersion(fileNumbers[2]);
187
188// Version 2: The object's metadata are not reset during storage
189// If object's metadata runRange or version do not match with filename,
190// it means that someone renamed file by hand. In this case a warning msg is issued.
191 Int_t objFirstRun=(entry->GetCDBMetaData()).GetFirstRun();
192 Int_t objLastRun=(entry->GetCDBMetaData()).GetLastRun();
193 Int_t objVersion=(entry->GetCDBMetaData()).GetVersion();
194
195 if(objFirstRun != fileNumbers[0] || objLastRun != fileNumbers[1] || objVersion != fileNumbers[2]){
196 AliWarning(Form("Either RunRange or Version in the object's metadata do noth match with fileName numbers:"));
197 AliWarning(Form("someone renamed file by hand!"));
198 }
199
200// close file, return retieved entry
201
202 DBFile->Close(); delete DBFile; DBFile=0;
203 if (saveDir) saveDir->cd(); else gROOT->cd();
204
205// if(selMetaData.GetVersion() > -1 && fileNumbers[2] != selMetaData.GetVersion())
206// AliWarning(Form("Warning: selected version (%d) not found, got version %d instead",
207// selMetaData.GetVersion(),fileNumbers[2]));
208
209 return entry;
210
211}
212
213
214//_____________________________________________________________________________
215Bool_t AliCDBLocal::PutEntry(AliCDBEntry* entry)
216{
217// puts an object into the database
218
219// AliCDBEntry entry is composed by the object and its MetaData
220// this method takes the metaData, reads the name, runRange and Version
221// creates the directory structure and the file name
222// looks for runs with same or overlapping runrange, if exist increment version
223// (therefore version should not be put in the metadata)
224// if the runrange is different (but overlapping) from a preceding version, a warning message
225// is issued.
226// sets the runrange and version in the object metadata = -1 (to avoid inconsistencies)
227// open the filem, write the entry in the file.
228// Note: the key name of the entry is "detSpecType"
229// return result
230
231 if(!entry) return kFALSE;
232 TDirectory* saveDir = gDirectory;
233
234 Int_t firstRun=entry->GetCDBMetaData().GetFirstRun();
235 Int_t lastRun=entry->GetCDBMetaData().GetLastRun();
236 if(firstRun<0 || lastRun<0 || lastRun<firstRun) {
237 AliError(Form("Run range not set or not valid: %d - %d !", firstRun, lastRun));
238 return kFALSE;
239 }
240
241 TString name(entry->GetName());
242
243
244 TString detSpecType(name(name.Last('/')+1, name.Length()-name.Last('/')));
245 TString buffer(fDBFolder);
246
247 void *dir=0;
248 Int_t index = -1;
249 name+='/'; // name=detector/dbType/detSpecType/
250
251 while ((index = name.Index("/")) >= 0) {
252 TString dirName(name(0, index+1));
253 buffer+=dirName;
254 dir=gSystem->OpenDirectory(buffer);
255 if (!dir) {
256 AliWarning(Form("Directory %s does not exist! It will be created...",buffer.Data()));
257 gSystem->mkdir(buffer.Data());
258 }
259 name.Remove(0, index+1);
260 gSystem->FreeDirectory(dir);
261 }
262
263 dir = gSystem->OpenDirectory(buffer);
264 TString levelContent="";
265 Int_t maxVersion=-1, run1=-1, run2=-1;
266 int numbers[3]={-1,-1,-1}; // numbers[0]=firstRun, numbers[1]=lastRun, numbers[2]=Version
267 while(levelContent=gSystem->GetDirEntry(dir)){
268 if(levelContent=="." || levelContent=="..") continue; if(levelContent=="") break;
269 if(levelContent.Contains("Run")){
270 if(levelContent.Contains("_Prod")) continue; //skip "Production" links
271 if(!DecodeFileName(levelContent, numbers, "_v")) continue;
272 if((firstRun>=numbers[0] && firstRun<=numbers[1]) ||
273 (lastRun>=numbers[0] && lastRun<=numbers[1]) ||
274 (firstRun<=numbers[0] && lastRun>=numbers[1])) {// overlap!
275 if(numbers[2]>maxVersion) {
276 maxVersion=numbers[2];
277 run1=numbers[0]; run2=numbers[1];
278 }
279 }
280 }
281 }
282 gSystem->FreeDirectory(dir);
283
284 if((run1!=-1 && run2!=-1) && (firstRun!=run1 || lastRun!=run2))
285 AliWarning(Form("Run range modified w.r.t. preceding version (%d, %d)",run1, run2));
286
287 TString strfName=EncodeFileName(firstRun, lastRun, maxVersion+1);
288 buffer+=strfName;
289
290 // opening file
291 TFile *DBFile = new TFile(buffer.Data(),"NEW");
292 if(!DBFile || !DBFile->IsWritable()){
293 AliError(Form("The data base file is not writable. "
294 "The object %s was not inserted", entry->GetName()));
295 if(!DBFile->IsWritable()) DBFile->Close(); DBFile->Delete(); delete DBFile; DBFile=0;
296 return kFALSE;
297 }
298
299 DBFile->cd();
300
301 entry->SetVersion(maxVersion+1);
302
303 // write object
304 Bool_t result = (entry->Write(detSpecType) != 0);
305 if (saveDir) saveDir->cd(); else gROOT->cd();
306 DBFile->Close(); DBFile->Delete(); delete DBFile; DBFile=0;
307 if(result) {
308 AliInfo(Form("Run object %s",entry->GetName()));
309 AliInfo(Form("was successfully written into file %s",buffer.Data()));
310 }
311
312 return result;
313
314}
315
316/*****************************************************************************/
317TObjArray* AliCDBLocal::FindDBFiles(const char* name, Int_t runNumber){
318// Find DataBase file name in a local directory. The filename must be in the form: Run#run1-#run2_v#version.root
319// TRegexp allowed: name can be for example: "detector/*" !!
320
321 TObjArray *FileNameColl=new TObjArray();
322
323 TString prefix="_v"; // development mode: fileName=Run#Run1-#Run2_v#Version.root
324 if(fStorageMode==kProduction) prefix="_Prod"; // production mode: fileName=Run#Run1-#Run2_Prod#Version.root
325
326 TString buffer(fDBFolder);
327// gSystem->ExpandPathName(buffer);
328
329 TString bufftInit=buffer; // buffInit="$ALICE_ROOT/DB/
330 TString levelContent="";
331
332 AliCDBMetaDataSelect selMetaData(name);
333
334 TString detector(selMetaData.GetDetector());
335 TString dbType(selMetaData.GetDBType());
336 TString detSpecType(selMetaData.GetDetSpecType());
337 int selVersion = selMetaData.GetVersion();
338
339 void *dirLevInit = gSystem->OpenDirectory(buffer);
340 while(levelContent=gSystem->GetDirEntry(dirLevInit)){ // lev0! In detector directory (ZDC, TPC...)!!
341
342 if(levelContent=="." || levelContent=="..") continue; if(levelContent=="") break;
343 if(!(detector=="*") && !levelContent.Contains(TRegexp(detector)) ) continue;
344
345 buffer=bufftInit+levelContent; buffer+='/'; // buffer="$ALICE_ROOT/DB/detector/
346 TString bufft0=buffer; // bufft0="$ALICE_ROOT/DB/detector/
347
348 void *dirLev0 = gSystem->OpenDirectory(buffer);
349 while(levelContent=gSystem->GetDirEntry(dirLev0)){ // lev1! dbType directory (Calib, Align)!!
350
351 if(levelContent=="." || levelContent=="..") continue; if(levelContent=="") break;
352 if(!(dbType=="*") && !levelContent.Contains(TRegexp(dbType))) continue;
353
354 buffer=bufft0+levelContent;buffer+='/'; // buffer="$ALICE_ROOT/DB/detector/dbType/
355 TString bufft1=buffer; // bufft1="$ALICE_ROOT/DB/detector/dbType/
356
357 void *dirLev1 = gSystem->OpenDirectory(buffer);
358 while(levelContent=gSystem->GetDirEntry(dirLev1)){ // lev2! detSpecType directory (Pedestals, gain....)!!
359
360 if(levelContent=="." || levelContent=="..") continue; if(levelContent=="") break;
361 if(!(detSpecType=="*") && !levelContent.Contains(TRegexp(detSpecType))) continue;
362
363 buffer=bufft1+levelContent;buffer+='/'; // buffer="$ALICE_ROOT/DB/detector/dbType/detSpecType/
364 TString bufft2=buffer; // bufft2="$ALICE_ROOT/DB/detector/dbType/detSpecType/
365
366 void *dirLev2 = gSystem->OpenDirectory(buffer);
367 TObjString *str=0;
368 while(levelContent=gSystem->GetDirEntry(dirLev2)){ // lev3! Run directory (Run#XXX-#YYY_v#ZZ.root)!!
369
370 if(levelContent=="." || levelContent=="..") continue; if(levelContent=="") break;
371 if(!levelContent.BeginsWith("Run")) continue;
372 if(!levelContent.Contains(prefix)) continue;
373
374 int numbers[3]={-1,-1,-1}; // numbers[0]=firstRun, numbers[1]=lastRun, numbers[2]=Version
375 if(!DecodeFileName(levelContent,numbers, prefix)) continue; // wrong run filename format!
376 if(numbers[0]>runNumber || numbers[1]<runNumber) continue; // data not valid for run number
377
378 if(numbers[2]==selVersion) {
379 buffer=bufft2+levelContent;
380 str=new TObjString(buffer.Data());
381 FileNameColl->Add(str);
382 break;
383 }
384 if(selVersion == -1) { // if version is not specified, collect all versions
385 buffer=bufft2+levelContent;
386 str=new TObjString(buffer.Data());
387 FileNameColl->Add(str);
388 }
389 } // end loop on runs
390 } // end loop in lev1
391 } // end loop in lev0
392 } // end loop in levInit
393
394 AliInfo(Form("Found %d entries matching requirements", FileNameColl->GetEntriesFast()));
395 ToAliInfo(FileNameColl->ls());
396 return FileNameColl;
397}
398
399//_____________________________________________________________________________
400void AliCDBLocal::TagForProduction(const AliCDBMetaDataSelect& selMetaData, UInt_t prodVers){
401
402TString workingDir=gSystem->pwd();
403//Build the file path
404TString buffer(fDBFolder); //gSystem->ExpandPathName() already done in ctor
405TString fName="";
406
407buffer+=selMetaData.GetName(); buffer+='/';
408//gSystem->ExpandPathName(dirName);
409
410if(!gSystem->cd(buffer))
411 {AliError(Form("Directory %s does not exist... check name!", buffer.Data())); gSystem->cd(workingDir.Data()); return;}
412
413// if version is not specified (=-1), then tag the highest version (BE CAREFUL!!)
414if(selMetaData.GetVersion() != -1){
415 //Build the filename
416 fName = EncodeFileName(selMetaData.GetFirstRun(), selMetaData.GetLastRun(), selMetaData.GetVersion());
417} else {
418 //look in directory for valid DB files, seek highest version
419 void *dir = gSystem->OpenDirectory(buffer);
420 TString levelContent="";
421 int oldVers=-1;
422 while(levelContent=gSystem->GetDirEntry(dir)){
423
424 if(levelContent=="." || levelContent=="..") continue; if(levelContent=="") break;
425 if(!levelContent.Contains("Run") || !levelContent.Contains("_v")) continue;
426
427 int numbers[3]={-1,-1,-1}; // numbers[0]=firstRun, numbers[1]=lastRun, numbers[2]=Version
428 // gets the 3 "numbers" in the file name
429 if(!DecodeFileName(levelContent,numbers, "_v")) continue; // wrong run filename format!
430 if(numbers[0] != selMetaData.GetFirstRun() || numbers[1] != selMetaData.GetLastRun()) continue;
431 if(numbers[2] >= oldVers) {
432 fName=levelContent;
433 oldVers=numbers[2];
434 }
435 } // end loop on runs
436}
437
438 //check that the flename exists
439if(!gSystem->IsFileInIncludePath(fName.Data())){
440 AliError(Form("File name %s not found... check!", fName.Data()));
441 gSystem->cd(workingDir.Data());
442 return;
443}
444
445// file exists: make symbolic link!
446TString prodfName=EncodeFileName(selMetaData.GetFirstRun(), selMetaData.GetLastRun(), prodVers, "_Prod");
447if(gSystem->Symlink(fName.Data(),prodfName.Data())<0){
448 AliError(Form("Link name already existing (%s): linkage failed!",prodfName.Data()));
449} else {
450 AliError(Form("File %s tagged for production with symlink %s",fName.Data(), prodfName.Data()));
451}
452
453gSystem->cd(workingDir);
454return;
455
456}
457
458//_____________________________________________________________________________
459Bool_t AliCDBLocal::DecodeFileName(const TString strName, int *numArray, TString prefix)
460{
461// Gets the numbers (#Run1, #Run2, #Version)
462// from the filename: Run#Run1-#Run2_v#Version.root or Run#Run1-#Run2_Prod#prodVers.root
463
464 int indexMinus=strName.Last('-');
465 int indexUScore=strName.Last('_');
466 int indexPoint=strName.Last('.');
467
468 int nSkipChar=prefix.Length(); // prefix can be either "_v" or "_Prod" depending on fStorageMode
469 //if(prefix=="_v") {nSkipChar=2;} // development mode: _v# skip 2 characters
470 //else if(prefix=="_Prod") {nSkipChar=5;} // production mode: _Prod# skip 5 characters
471
472 if(indexUScore<0 || indexPoint<0 )
473 {AliDebug(2, Form("Check sintax %s",strName.Data())); return kFALSE;}
474
475 if(indexMinus<0){ // only 1 Run number!
476 TString cRun=strName(3,indexUScore-3);
477 if(!(cRun.IsDigit()))
478 {AliDebug(2, Form("%s not a digit! Check sintax %s",cRun.Data(),strName.Data())); return kFALSE;}
479 numArray[0] = (int) strtol(cRun.Data(),0,10);
480 numArray[1] = numArray[0];
481 }else{
482 TString cFirstRun = strName(3,indexMinus-3);
483 TString cLastRun = strName(indexMinus+1,indexUScore-(indexMinus+1));
484 if(!(cFirstRun.IsDigit()) || !(cLastRun.IsDigit()))
485 {AliDebug(2, Form("%s or %s are not digit! Check sintax %s",
486 cFirstRun.Data(), cLastRun.Data(), strName.Data())); return kFALSE;}
487 numArray[0] = (int) strtol(cFirstRun.Data(),0,10);
488 numArray[1] = (int) strtol(cLastRun.Data(),0,10);
489 }
490// TString cVersion = strName(indexUScore+2,indexPoint-(indexUScore+2));
491 TString cVersion = strName(indexUScore+nSkipChar,indexPoint-(indexUScore+nSkipChar));
492 if(!(cVersion.IsDigit())){
493 AliDebug(2, Form("%s not a digit! Check sintax %s",cVersion.Data(),strName.Data())); return kFALSE;}
494 numArray[2] = (int) strtol(cVersion.Data(),0,10);
495
496 return kTRUE;
497}
498
499
500//_____________________________________________________________________________
501TString AliCDBLocal::EncodeFileName(int firstRun, int lastRun, int version, TString prefix){
502// Builds a file name of the form: Run#firstRun-#lastRun_v#Version.root
503
504TString fName="Run";
505if(firstRun==lastRun) {
506 fName+=firstRun;
507}else{
508 fName+=firstRun; fName+="-"; fName+=lastRun;
509}
510fName+=prefix; fName+=version; fName+=".root";
511
512return fName;
513}