New calibration classes (A.Colla)
[u/mrichter/AliRoot.git] / STEER / AliRunDataFile.cxx
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 classes for a data base in a LOCAL file                            //
21 //                                                                           //
22 ///////////////////////////////////////////////////////////////////////////////
23
24
25 #include <TFile.h>
26 #include <TKey.h>
27 #include <TROOT.h>
28 #include "AliLog.h"
29 #include "AliRunData.h"
30 #include "AliSelectionMetaData.h"
31 #include "AliObjectMetaData.h"
32 #include "AliRunDataFile.h"
33
34
35 ClassImp(AliRunDataFile)
36
37
38 //_____________________________________________________________________________
39 AliRunDataFile::AliRunDataFile(const char* fileName, Bool_t readOnly) :
40   AliRunDataStorage(),
41   fFile(NULL)
42 {
43 // constructor
44
45   if (!fileName) {
46     AliError("no file name given");
47     return;
48   }
49   TDirectory* saveDir = gDirectory;
50   fFile = TFile::Open(fileName, ((readOnly) ? "READ" : "UPDATE"));
51   if (saveDir) saveDir->cd(); else gROOT->cd();
52   if (!fFile || !fFile->IsOpen()) {
53     AliError(Form("could not open file %s", fileName));
54     fFile = NULL;
55   }
56 }
57
58 //_____________________________________________________________________________
59 AliRunDataFile::~AliRunDataFile()
60 {
61 // destructor
62
63   if (fFile) {
64     fFile->Close();
65     delete fFile;
66   }
67 }
68
69 //_____________________________________________________________________________
70 AliRunDataFile::AliRunDataFile(const AliRunDataFile& /*db*/) :
71   AliRunDataStorage(),
72   fFile(NULL)
73 {
74 // copy constructor
75
76   AliFatal("not implemented");
77 }
78
79 //_____________________________________________________________________________
80 AliRunDataFile& AliRunDataFile::operator = (const AliRunDataFile& /*db*/)
81 {
82 // assignment operator
83
84   AliFatal("not implemented");
85   return *this;
86 }
87
88
89 //_____________________________________________________________________________
90 AliRunData* AliRunDataFile::GetEntry(AliSelectionMetaData& selMetaData, Int_t runNumber)
91 {
92 // get an object from the data base
93
94   // go to the directory
95   TDirectory* saveDir = gDirectory;
96   TDirectory *dir = fFile;
97   TString name(selMetaData.GetName());
98   Int_t last = name.Last('/');
99   if (last < 0) {
100     fFile->cd();
101   } else {
102     TString dirName(name(0, last));
103       if (!dir->cd(dirName)) {
104       AliError(Form("no directory %s found", dirName.Data()));
105       if (saveDir) saveDir->cd(); else gROOT->cd();
106       return NULL;
107     }
108     name.Remove(0, last+1);
109   }
110
111   dir = gDirectory;
112   TKey* key = dir->GetKey(name); 
113   if (!key) {
114     AliError(Form("no object with name %s found", selMetaData.GetName()));
115     if (saveDir) saveDir->cd(); else gROOT->cd();
116     return NULL;
117   }
118   Int_t nCycles = key->GetCycle();
119
120   // find the closest entry
121   AliRunData* closestEntry = NULL;
122   for (Int_t iCycle = nCycles; iCycle > 0; iCycle--) {
123     key = dir->GetKey(name, iCycle);
124     
125     if (!key) continue;
126     AliRunData* entry = (AliRunData*) key->ReadObj();
127     if (!entry) continue;
128     if (!entry->InheritsFrom(AliRunData::Class())) {
129       AliObjectMetaData objMetaData;
130       entry = new AliRunData(entry, objMetaData);
131     }
132     if (!entry->GetObjectMetaData().IsValid(runNumber, &selMetaData) ||
133         (entry->Compare(closestEntry) <= 0)) {
134       delete entry;
135       continue;
136     }
137     delete closestEntry;
138     closestEntry = entry;
139   }
140   if (saveDir) saveDir->cd(); else gROOT->cd();
141   if(!closestEntry) AliError(Form("No valid entry found for: name %s, version %d, run %d!!!",
142             selMetaData.GetName(),selMetaData.GetVersion(),runNumber));
143   if (!closestEntry) return NULL;
144   if(selMetaData.GetVersion() > -1 && (closestEntry->GetObjectMetaData()).GetVersion() != selMetaData.GetVersion()) 
145      AliWarning(Form("Warning: selected version (%d) not found, got version %d instead",
146             selMetaData.GetVersion(),(closestEntry->GetObjectMetaData()).GetVersion()));
147   return closestEntry;
148 }
149
150 //_____________________________________________________________________________
151 Bool_t AliRunDataFile::PutEntry(AliRunData* entry)
152 {
153 // puts an object into the database
154
155 // AliRunData entry is composed by the object and its MetaData
156 // this method takes the metaData, reads the name, runRange and Version
157 // creates the TDirectory structure into the file
158 // looks for runs with same name, if exist increment version
159 // (therefore version should not be put in the metadata)
160 // Note: the key name of the entry is "DetSpecType"
161 // return result 
162
163   if (!entry || !fFile) return kFALSE;
164   if (!fFile->IsWritable()) {
165     AliError(Form("The data base file was opened in read only mode. "
166                   "The object %s was not inserted", entry->GetName()));
167     return kFALSE;
168   }
169   
170   fFile->cd();
171   TDirectory* saveDir = gDirectory;
172
173   // go to or create the directory
174   TString name(entry->GetName());
175   while (name.BeginsWith("/")) name.Remove(0);
176   TDirectory* dir = fFile;
177   Int_t index = -1;
178   while ((index = name.Index("/")) >= 0) {
179     TString dirName(name(0, index));
180     if ((index > 0) && !dir->Get(dirName)) dir->mkdir(dirName);
181     dir->cd(dirName);
182     dir = gDirectory;
183     name.Remove(0, index+1);
184   } 
185
186   // determine the version number
187   Int_t version = 0;
188   TKey* key = dir->GetKey(name); 
189   if (key) {
190     Int_t nCycles = key->GetCycle();
191     for (Int_t iCycle = nCycles; iCycle > 0; iCycle--) {
192       key = dir->GetKey(name, iCycle); 
193       if (!key) continue;
194       AliRunData* oldEntry = (AliRunData*) key->ReadObj();
195       if (!oldEntry) continue;
196       if (oldEntry->InheritsFrom(AliRunData::Class())) {
197         if (version <= oldEntry->GetObjectMetaData().GetVersion()) {
198           version = oldEntry->GetObjectMetaData().GetVersion()+1;
199         }
200       }
201       delete oldEntry;
202     }
203   }
204   entry->SetVersion(version);
205
206   Bool_t result = (entry->Write(name) != 0);
207   if (saveDir) saveDir->cd(); else gROOT->cd();
208   return result;
209 }