]>
Commit | Line | Data |
---|---|---|
f05209ee | 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 | // (DBFolder/detector/dbType/detSpecType) // | |
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 "AliRunData.h" | |
36 | #include "AliSelectionMetaData.h" | |
37 | #include "AliRunDataOrganizedFile.h" | |
38 | ||
39 | ||
40 | ClassImp(AliRunDataOrganizedFile) | |
41 | ||
42 | //_____________________________________________________________________________ | |
43 | AliRunDataOrganizedFile::AliRunDataOrganizedFile(const char* DBFolder) : | |
44 | AliRunDataStorage(), | |
45 | fDBFolder(DBFolder) | |
46 | { | |
47 | // constructor | |
48 | TString buffer(fDBFolder); | |
49 | gSystem->ExpandPathName(buffer); | |
50 | if(!gSystem->OpenDirectory(buffer)){ | |
51 | AliError(Form("Path %s not a directory",fDBFolder.Data())); | |
52 | } | |
53 | } | |
54 | ||
55 | //_____________________________________________________________________________ | |
56 | AliRunDataOrganizedFile::~AliRunDataOrganizedFile() | |
57 | { | |
58 | // destructor | |
59 | ||
60 | if (fDBFolder) fDBFolder=""; | |
61 | } | |
62 | ||
63 | //_____________________________________________________________________________ | |
64 | AliRunDataOrganizedFile::AliRunDataOrganizedFile(const AliRunDataOrganizedFile& /*db*/) : | |
65 | AliRunDataStorage(), | |
66 | fDBFolder("") | |
67 | { | |
68 | // copy constructor | |
69 | ||
70 | AliFatal("not implemented"); | |
71 | } | |
72 | ||
73 | //_____________________________________________________________________________ | |
74 | AliRunDataOrganizedFile& AliRunDataOrganizedFile::operator = (const AliRunDataOrganizedFile& /*db*/) | |
75 | { | |
76 | // assignment operator | |
77 | ||
78 | AliFatal("not implemented"); | |
79 | return *this; | |
80 | } | |
81 | ||
82 | //_____________________________________________________________________________ | |
83 | AliRunData* AliRunDataOrganizedFile::GetEntry(AliSelectionMetaData& selMetaData, Int_t runNumber) | |
84 | { | |
85 | // get an object from the data base | |
86 | ||
87 | TDirectory* saveDir = gDirectory; | |
88 | ||
89 | // Find the right file in the directory | |
90 | ||
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!"); | |
95 | ||
96 | // Open the file | |
97 | ||
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())); | |
103 | return NULL; | |
104 | } | |
105 | ||
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) | |
109 | ||
110 | dbFile->cd(); | |
111 | ||
112 | AliRunData *entry = (AliRunData*) dbFile->Get(selMetaData.GetDetSpecType()); | |
113 | ||
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(); | |
118 | return NULL; | |
119 | } | |
120 | ||
121 | // now set the run range and version got from the filename | |
122 | // to the object's metadata! | |
123 | ||
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]); | |
130 | ||
131 | // close file, return retieved entry | |
132 | ||
133 | dbFile->Close(); delete dbFile; | |
134 | if (saveDir) saveDir->cd(); else gROOT->cd(); | |
135 | ||
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])); | |
139 | return entry; | |
140 | ||
141 | } | |
142 | ||
143 | ||
144 | //_____________________________________________________________________________ | |
145 | Bool_t AliRunDataOrganizedFile::PutEntry(AliRunData* entry) | |
146 | { | |
147 | // puts an object into the database | |
148 | ||
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 | |
155 | // is issued. | |
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" | |
159 | // return result | |
160 | ||
161 | if(!entry) return kFALSE; | |
162 | TDirectory* saveDir = gDirectory; | |
163 | ||
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)); | |
168 | return kFALSE; | |
169 | } | |
170 | ||
171 | TString name(entry->GetObjectMetaData().GetName()); | |
172 | ||
173 | while(name.EndsWith("/")) name.Remove(name.Last('/')); | |
174 | while(name.BeginsWith("/")) name.Remove(name.First('/'),1); | |
175 | ||
176 | TString detSpecType(name(name.Last('/')+1, name.Length()-name.Last('/'))); | |
177 | ||
178 | TString buffer(fDBFolder); | |
179 | gSystem->ExpandPathName(buffer); | |
180 | while(buffer.EndsWith("/")) buffer.Remove(buffer.Last('/')); | |
181 | ||
182 | void *dir=0; | |
183 | Int_t index = -1; | |
184 | name+='/'; // name=detector/dbType/detSpecType/ | |
185 | ||
186 | while ((index = name.Index("/")) >= 0) { | |
187 | TString dirName(name(0, index)); | |
188 | buffer+='/'; buffer+=dirName; | |
189 | dir=gSystem->OpenDirectory(buffer); | |
190 | if (!dir) { | |
191 | AliWarning(Form("Directory %s does not exist! It will be created...",buffer.Data())); | |
192 | TString command = "mkdir "+ buffer; | |
193 | gSystem->Exec(command.Data()); | |
194 | } | |
195 | name.Remove(0, index+1); | |
196 | } | |
197 | ||
198 | TString strfName="Run"; | |
199 | ||
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]; | |
213 | } | |
214 | } | |
215 | } | |
216 | } | |
217 | ||
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)); | |
220 | ||
221 | ||
222 | if(firstRun==lastRun) { | |
223 | strfName+=firstRun; | |
224 | }else{ | |
225 | strfName+=firstRun; strfName+="-"; strfName+=lastRun; | |
226 | } | |
227 | strfName+="_v"; strfName+=maxVersion+1; strfName+=".root"; | |
228 | buffer+='/'; buffer+=strfName; | |
229 | ||
230 | // opening file | |
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())); | |
235 | return kFALSE; | |
236 | } | |
237 | ||
238 | dbFile->cd(); | |
239 | ||
240 | entry->SetRunRange(-1,-1); entry->SetVersion(-1); | |
241 | ||
242 | // write object | |
243 | Bool_t result = (entry->Write(detSpecType) != 0); | |
244 | if (saveDir) saveDir->cd(); else gROOT->cd(); | |
245 | dbFile->Close(); delete dbFile; | |
246 | ||
247 | if(result) { | |
248 | AliInfo(Form("Run object %s",entry->GetName())); | |
249 | AliInfo(Form("was successfully written into file %s !",buffer.Data())); | |
250 | } | |
251 | ||
252 | return result; | |
253 | } | |
254 | ||
255 | /*****************************************************************************/ | |
256 | ||
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/*" !! | |
260 | ||
261 | TObjArray *fileNameColl=new TObjArray(); | |
262 | ||
263 | TString buffer(fDBFolder); | |
264 | if(!(buffer.EndsWith("/"))) buffer+="/"; | |
265 | gSystem->ExpandPathName(buffer); | |
266 | ||
267 | TString bufftInit=buffer; // buffInit="$ALICE_ROOT/DB/ | |
268 | TString levelContent=""; | |
269 | ||
270 | TString detector(selMetaData.GetDetector()); | |
271 | TString dbType(selMetaData.GetDBType()); | |
272 | TString detSpecType(selMetaData.GetDetSpecType()); | |
273 | int selVersion = selMetaData.GetVersion(); | |
274 | ||
275 | void *dirLevInit = gSystem->OpenDirectory(buffer); | |
276 | while(levelContent=gSystem->GetDirEntry(dirLevInit)){ // lev0! In Detector directory (ZDC, TPC...)!! | |
277 | ||
278 | if(levelContent=="." || levelContent=="..") continue; if(levelContent=="") break; | |
279 | if(!(detector=="*") && !levelContent.Contains(TRegexp(detector)) ) continue; | |
280 | ||
281 | buffer=bufftInit+levelContent; buffer+='/'; // buffer="$ALICE_ROOT/DB/detector/ | |
282 | TString bufft0=buffer; // bufft0="$ALICE_ROOT/DB/detector/ | |
283 | ||
284 | void *dirLev0 = gSystem->OpenDirectory(buffer); | |
285 | while(levelContent=gSystem->GetDirEntry(dirLev0)){ // lev1! dbType directory (Calib, Align)!! | |
286 | ||
287 | if(levelContent=="." || levelContent=="..") continue; if(levelContent=="") break; | |
288 | if(!(dbType=="*") && !levelContent.Contains(TRegexp(dbType))) continue; | |
289 | ||
290 | buffer=bufft0+levelContent;buffer+='/'; // buffer="$ALICE_ROOT/DB/detector/dbType/ | |
291 | TString bufft1=buffer; // bufft1="$ALICE_ROOT/DB/detector/dbType/ | |
292 | ||
293 | void *dirLev1 = gSystem->OpenDirectory(buffer); | |
294 | while(levelContent=gSystem->GetDirEntry(dirLev1)){ // lev2! detSpecType directory (Pedestals, gain....)!! | |
295 | ||
296 | if(levelContent=="." || levelContent=="..") continue; if(levelContent=="") break; | |
297 | if(!(detSpecType=="*") && !levelContent.Contains(TRegexp(detSpecType))) continue; | |
298 | ||
299 | buffer=bufft1+levelContent;buffer+='/'; // buffer="$ALICE_ROOT/DB/detector/dbType/detSpecType/ | |
300 | TString bufft2=buffer; // bufft2="$ALICE_ROOT/DB/detector/dbType/detSpecType/ | |
301 | ||
302 | void *dirLev2 = gSystem->OpenDirectory(buffer); | |
303 | int oldVers=-1; | |
304 | TObjString *str=0; | |
305 | while(levelContent=gSystem->GetDirEntry(dirLev2)){ // lev3! Run directory (Run#XXX-#YYY_v#ZZ.root)!! | |
306 | ||
307 | if(levelContent=="." || levelContent=="..") continue; if(levelContent=="") break; | |
308 | if(!levelContent.BeginsWith("Run")) continue; | |
309 | ||
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 | |
314 | ||
315 | if((selVersion == -1 || numbers[2] <= selVersion) && numbers[2] >= oldVers) { | |
316 | buffer=bufft2+levelContent; | |
317 | str=new TObjString(buffer.Data()); | |
318 | oldVers=numbers[2]; | |
319 | if(numbers[2]==selVersion) break; | |
320 | } | |
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 | |
326 | ||
327 | AliInfo(Form("Found %d entries matching requirements", fileNameColl->GetEntriesFast())); | |
328 | ToAliInfo(fileNameColl->ls()); | |
329 | return fileNameColl; | |
330 | } | |
331 | ||
332 | //_____________________________________________________________________________ | |
333 | ||
334 | void AliRunDataOrganizedFile::GetNumbers(const TString strName, int *numArray) | |
335 | { | |
336 | // Gets the numbers (#Run1, #Run2, #Version) from the filename: Run#Run1-#Run2_v#Version.root | |
337 | ||
338 | int indexMinus=strName.Last('-'); | |
339 | int indexUScore=strName.Last('_'); | |
340 | int indexPoint=strName.Last('.'); | |
341 | ||
342 | if(indexUScore<0 || indexPoint<0 ) | |
343 | {AliError(Form("Check sintax %s",strName.Data())); return;} | |
344 | ||
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]; | |
351 | }else{ | |
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); | |
359 | } | |
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); | |
364 | ||
365 | return; | |
366 | } |