]> git.uio.no Git - u/mrichter/AliRoot.git/blob - RAW/AliRawDB.cxx
1b991564cedb76b747c8fcaaf7dfcf36793a82ef
[u/mrichter/AliRoot.git] / RAW / AliRawDB.cxx
1 // @(#)alimdc:$Name$:$Id$
2 // Author: Fons Rademakers  26/11/99
3
4 /**************************************************************************
5  * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
6  *                                                                        *
7  * Author: The ALICE Off-line Project.                                    *
8  * Contributors are mentioned in the code where appropriate.              *
9  *                                                                        *
10  * Permission to use, copy, modify and distribute this software and its   *
11  * documentation strictly for non-commercial purposes is hereby granted   *
12  * without fee, provided that the above copyright notice appears in all   *
13  * copies and that both the copyright notice and this permission notice   *
14  * appear in the supporting documentation. The authors make no claims     *
15  * about the suitability of this software for any purpose. It is          *
16  * provided "as is" without express or implied warranty.                  *
17  **************************************************************************/
18
19 //////////////////////////////////////////////////////////////////////////
20 //                                                                      //
21 // AliRawDB                                                             //
22 //                                                                      //
23 //////////////////////////////////////////////////////////////////////////
24
25 #include <errno.h>
26
27 #include <TSystem.h>
28
29 #ifdef ALI_DATE
30 #include "event.h"
31 #endif
32
33 #include "AliRawEvent.h"
34 #include "AliRawEventHeader.h"
35 #include "AliStats.h"
36 #include "AliMDC.h"
37
38 #ifdef USE_HLT
39 #include "AliESD.h"
40 #endif
41
42 #include "AliRawDB.h"
43
44
45 ClassImp(AliRawDB)
46
47
48 //______________________________________________________________________________
49 AliRawDB::AliRawDB(AliRawEvent *event,
50 #ifdef USE_HLT
51                    AliESD *esd, 
52 #endif
53                    Double_t maxsize, Int_t compress,
54                    Bool_t create)
55 {
56    // Create a new raw DB containing at most maxsize bytes.
57
58    fEvent    = event;
59 #ifdef USE_HLT
60    fESD      = esd;
61 #endif
62    fMaxSize  = maxsize;
63    fCompress = compress;
64
65    // Consistency check with DATE header file
66 #ifdef ALI_DATE
67    if (fEvent->GetHeader()->HeaderSize() != EVENT_HEAD_BASE_SIZE) {
68       Error("AliRawDB", "inconsistency between DATE and AliRawEvent headers");
69       MakeZombie();
70       return;
71    }
72 #endif
73
74    if (create) {
75       if (!Create())
76          MakeZombie();
77    }
78 }
79
80 //______________________________________________________________________________
81 AliRawDB::AliRawDB(const AliRawDB& rawDB): TObject(rawDB)
82 {
83 // copy constructor
84
85   Fatal("AliRawDB", "copy constructor not implemented");
86 }
87
88 //______________________________________________________________________________
89 AliRawDB& AliRawDB::operator = (const AliRawDB& /*rawDB*/)
90 {
91 // assignment operator
92
93   Fatal("operator =", "assignment operator not implemented");
94   return *this;
95 }
96
97 //______________________________________________________________________________
98 Bool_t AliRawDB::FSHasSpace(const char *fs) const
99 {
100    // Check for at least fMaxSize bytes of free space on the file system.
101    // If the space is not available return kFALSE, kTRUE otherwise.
102
103    Long_t id, bsize, blocks, bfree;
104
105    if (gSystem->GetFsInfo(fs, &id, &bsize, &blocks, &bfree) == 1) {
106       Error("FSHasSpace", "could not stat file system %s", fs);
107       return kFALSE;
108    }
109
110    // Leave 5 percent of diskspace free
111    Double_t avail = Double_t(bfree) * 0.95;
112    if (avail*bsize > fMaxSize)
113       return kTRUE;
114
115    Warning("FSHasSpace", "no space on file system %s", fs);
116    return kFALSE;
117 }
118
119 //______________________________________________________________________________
120 const char *AliRawDB::GetFileName() const
121 {
122    // Return filename based on hostname and date and time. This will make
123    // each file unique. Also makes sure (via FSHasSpace()) that there is
124    // enough space on the file system to store the file. Returns 0 in
125    // case of error or interrupt signal.
126
127    static TString fname;
128    static Bool_t  fstoggle = kFALSE;
129
130    TString fs = fstoggle ? AliMDC::RawDBFS(1) : AliMDC::RawDBFS(0);
131    TDatime dt;
132
133    TString hostname = gSystem->HostName();
134    Int_t pos;
135    if ((pos = hostname.Index(".")) != kNPOS)
136       hostname.Remove(pos);
137
138    if (!FSHasSpace(fs)) {
139       while (1) {
140          fstoggle = !fstoggle;
141          fs = fstoggle ? AliMDC::RawDBFS(1) : AliMDC::RawDBFS(0);
142          if (FSHasSpace(fs)) break;
143          Info("GetFileName", "sleeping 30 seconds before retrying...");
144          gSystem->Sleep(30000);   // sleep for 30 seconds
145          if (AliMDC::Instance() && AliMDC::Instance()->StopLoop())
146             return 0;
147       }
148    }
149
150    fname = fs + "/" + hostname + "_";
151    fname += dt.GetDate();
152    fname += "_";
153    fname += dt.GetTime();
154    fname += ".root";
155
156    fstoggle = !fstoggle;
157
158    return fname;
159 }
160
161 //______________________________________________________________________________
162 Bool_t AliRawDB::Create()
163 {
164    // Create a new raw DB.
165
166    const Int_t kMaxRetry = 200;
167    const Int_t kMaxSleep = 1;      // seconds
168    const Int_t kMaxSleepLong = 10; // seconds
169    Int_t retry = 0;
170
171 again:
172    if (AliMDC::Instance() && AliMDC::Instance()->StopLoop())
173       return kFALSE;
174
175    const char *fname = GetFileName();
176    if (!fname) {
177       Error("Create", "error getting raw DB file name");
178       return kFALSE;
179    }
180
181    retry++;
182
183    fRawDB = TFile::Open(fname, GetOpenOption(),
184                         Form("ALICE MDC%d raw DB", AliMDC::kMDC), fCompress,
185                         GetNetopt());
186    if (!fRawDB) {
187       if (retry < kMaxRetry) {
188          Warning("Create", "failure to open file, sleeping %d %s before retrying...",
189                  kMaxSleep, kMaxSleep==1 ? "second" : "seconds");
190          gSystem->Sleep(kMaxSleep*1000);
191          goto again;
192       }
193       Error("Create", "failure to open file %s after %d tries", fname, kMaxRetry);
194       return kFALSE;
195    }
196    if (retry > 1)
197       Warning("Create", "succeeded to open file after %d retries", retry);
198
199    if (fRawDB->IsZombie()) {
200       if (fRawDB->GetErrno() == ENOSPC ||
201           fRawDB->GetErrno() == 1018   ||   // SECOMERR
202           fRawDB->GetErrno() == 1027) {     // SESYSERR
203          fRawDB->ResetErrno();
204          delete fRawDB;
205          Warning("Create", "file is a zombie (no space), sleeping %d %s before retrying...",
206                  kMaxSleepLong, kMaxSleepLong==1 ? "second" : "seconds");
207          gSystem->Sleep(kMaxSleepLong*1000);   // sleep 10 seconds before retrying
208          goto again;
209       }
210       Error("Create", "file %s is zombie", fname);
211       fRawDB->ResetErrno();
212       delete fRawDB;
213       fRawDB = 0;
214       if (retry < kMaxRetry) {
215          Warning("Create", "file is a zombie, sleeping %d %s before retrying...",
216                  kMaxSleep, kMaxSleep==1 ? "second" : "seconds");
217          gSystem->Sleep(kMaxSleep*1000);
218          goto again;
219       }
220       Error("Create", "failure to open file %s after %d tries", fname, kMaxRetry);
221       return kFALSE;
222    }
223
224    // Create raw data TTree
225    MakeTree();
226
227    return kTRUE;
228 }
229
230 //______________________________________________________________________________
231 void AliRawDB::MakeTree()
232 {
233    // Create ROOT Tree object container.
234
235    fTree = new TTree("RAW", Form("ALICE MDC%d raw data tree", AliMDC::kMDC));
236    fTree->SetAutoSave(2000000000);  // autosave when 2 Gbyte written
237
238    Int_t bufsize = 256000;
239    // splitting 29.6 MB/s, no splitting 35.3 MB/s on P4 2GHz 15k SCSI
240    //Int_t split   = 1;
241    Int_t split   = 0;
242    fTree->Branch("rawevent", "AliRawEvent", &fEvent, bufsize, split);
243
244 #ifdef USE_HLT
245    // Create tree which will contain the HLT ESD information
246
247    fESDTree = new TTree("esdTree", Form("ALICE MDC%d HLT ESD tree", AliMDC::kMDC));
248    fESDTree->SetAutoSave(2000000000);  // autosave when 2 Gbyte written
249    split   = 99;
250    fESDTree->Branch("ESD", "AliESD", &fESD, bufsize, split);
251 #endif
252
253 }
254
255 //______________________________________________________________________________
256 void AliRawDB::Close()
257 {
258    // Close raw DB.
259
260    if (!fRawDB) return;
261
262    fRawDB->cd();
263
264    // Write the tree.
265    fTree->Write();
266 #ifdef USE_HLT
267    fESDTree->Write();
268 #endif
269
270    // Close DB, this also deletes the fTree
271    fRawDB->Close();
272
273    if (AliMDC::DeleteFiles()) {
274       gSystem->Unlink(fRawDB->GetName());
275       delete fRawDB;
276       fRawDB = 0;
277       return;
278    }
279
280    // Create semaphore to say this file is finished
281    Int_t tfd = ::creat(Form("%s.done", fRawDB->GetName()), 0644);
282    close(tfd);
283
284    delete fRawDB;
285    fRawDB = 0;
286 }
287
288 //______________________________________________________________________________
289 void AliRawDB::WriteStats(AliStats* stats)
290 {
291    // Write stats to raw DB, local run DB and global MySQL DB.
292
293    AliRawEventHeader &header = *GetEvent()->GetHeader();
294
295    // Write stats into RawDB
296    TDirectory *ds = gDirectory;
297    GetDB()->cd();
298    stats->SetEvents(GetEvents());
299    stats->SetLastId(header.GetRunNumber(), header.GetEventInRun());
300    stats->SetFileSize(GetBytesWritten());
301    stats->SetCompressionFactor(GetCompressionFactor());
302    stats->SetEndTime();
303    stats->Write("stats");
304    ds->cd();
305 }
306
307 //______________________________________________________________________________
308 Bool_t AliRawDB::NextFile()
309 {
310    // Close te current file and open a new one.
311    // Returns kFALSE in case opening failed.
312
313    Close();
314
315    if (!Create()) return kFALSE;
316    return kTRUE;
317 }
318
319 //______________________________________________________________________________
320 Float_t AliRawDB::GetCompressionFactor() const
321 {
322    // Return compression factor.
323
324    if (fTree->GetZipBytes() == 0.)
325       return 1.0;
326    else
327       return fTree->GetTotBytes()/fTree->GetZipBytes();
328 }