Introduction of the online monitoring code into the alimdc package. Fixed some memory...
[u/mrichter/AliRoot.git] / RAW / AliRawDB.cxx
CommitLineData
a197a4ce 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 "AliMDC.h"
36
a109e73e 37#ifdef USE_HLT
38#include "AliESD.h"
39#endif
40
a197a4ce 41#include "AliRawDB.h"
42
43
44ClassImp(AliRawDB)
45
46
47//______________________________________________________________________________
a109e73e 48AliRawDB::AliRawDB(AliRawEvent *event,
49#ifdef USE_HLT
50 AliESD *esd,
51#endif
52 Double_t maxsize, Int_t compress,
a197a4ce 53 Bool_t create)
54{
55 // Create a new raw DB containing at most maxsize bytes.
56
57 fEvent = event;
a109e73e 58 fESD = esd;
a197a4ce 59 fMaxSize = maxsize;
60 fCompress = compress;
61
62 // Consistency check with DATE header file
63#ifdef ALI_DATE
64 if (fEvent->GetHeader()->HeaderSize() != EVENT_HEAD_BASE_SIZE) {
65 Error("AliRawDB", "inconsistency between DATE and AliRawEvent headers");
66 MakeZombie();
67 return;
68 }
69#endif
70
71 if (create) {
72 if (!Create())
73 MakeZombie();
74 }
75}
76
77//______________________________________________________________________________
78AliRawDB::AliRawDB(const AliRawDB& rawDB): TObject(rawDB)
79{
80// copy constructor
81
82 Fatal("AliRawDB", "copy constructor not implemented");
83}
84
85//______________________________________________________________________________
86AliRawDB& AliRawDB::operator = (const AliRawDB& /*rawDB*/)
87{
88// assignment operator
89
90 Fatal("operator =", "assignment operator not implemented");
91 return *this;
92}
93
94//______________________________________________________________________________
95Bool_t AliRawDB::FSHasSpace(const char *fs) const
96{
97 // Check for at least fMaxSize bytes of free space on the file system.
98 // If the space is not available return kFALSE, kTRUE otherwise.
99
100 Long_t id, bsize, blocks, bfree;
101
102 if (gSystem->GetFsInfo(fs, &id, &bsize, &blocks, &bfree) == 1) {
103 Error("FSHasSpace", "could not stat file system %s", fs);
104 return kFALSE;
105 }
106
107 // Leave 5 percent of diskspace free
108 Double_t avail = Double_t(bfree) * 0.95;
109 if (avail*bsize > fMaxSize)
110 return kTRUE;
111
112 Warning("FSHasSpace", "no space on file system %s", fs);
113 return kFALSE;
114}
115
116//______________________________________________________________________________
117const char *AliRawDB::GetFileName() const
118{
119 // Return filename based on hostname and date and time. This will make
120 // each file unique. Also makes sure (via FSHasSpace()) that there is
121 // enough space on the file system to store the file. Returns 0 in
122 // case of error or interrupt signal.
123
124 static TString fname;
125 static Bool_t fstoggle = kFALSE;
126
127 TString fs = fstoggle ? AliMDC::RawDBFS(1) : AliMDC::RawDBFS(0);
128 TDatime dt;
129
130 TString hostname = gSystem->HostName();
131 Int_t pos;
132 if ((pos = hostname.Index(".")) != kNPOS)
133 hostname.Remove(pos);
134
135 if (!FSHasSpace(fs)) {
136 while (1) {
137 fstoggle = !fstoggle;
138 fs = fstoggle ? AliMDC::RawDBFS(1) : AliMDC::RawDBFS(0);
139 if (FSHasSpace(fs)) break;
140 Info("GetFileName", "sleeping 30 seconds before retrying...");
141 gSystem->Sleep(30000); // sleep for 30 seconds
142 if (AliMDC::Instance() && AliMDC::Instance()->StopLoop())
143 return 0;
144 }
145 }
146
147 fname = fs + "/" + hostname + "_";
148 fname += dt.GetDate();
149 fname += "_";
150 fname += dt.GetTime();
151 fname += ".root";
152
153 fstoggle = !fstoggle;
154
155 return fname;
156}
157
158//______________________________________________________________________________
159Bool_t AliRawDB::Create()
160{
161 // Create a new raw DB.
162
163 const Int_t kMaxRetry = 200;
164 const Int_t kMaxSleep = 1; // seconds
165 const Int_t kMaxSleepLong = 10; // seconds
166 Int_t retry = 0;
167
168again:
169 if (AliMDC::Instance() && AliMDC::Instance()->StopLoop())
170 return kFALSE;
171
172 const char *fname = GetFileName();
173 if (!fname) {
174 Error("Create", "error getting raw DB file name");
175 return kFALSE;
176 }
177
178 retry++;
179
180 fRawDB = TFile::Open(fname, GetOpenOption(),
181 Form("ALICE MDC%d raw DB", AliMDC::kMDC), fCompress,
182 GetNetopt());
183 if (!fRawDB) {
184 if (retry < kMaxRetry) {
185 Warning("Create", "failure to open file, sleeping %d %s before retrying...",
186 kMaxSleep, kMaxSleep==1 ? "second" : "seconds");
187 gSystem->Sleep(kMaxSleep*1000);
188 goto again;
189 }
190 Error("Create", "failure to open file %s after %d tries", fname, kMaxRetry);
191 return kFALSE;
192 }
193 if (retry > 1)
194 Warning("Create", "succeeded to open file after %d retries", retry);
195
196 if (fRawDB->IsZombie()) {
197 if (fRawDB->GetErrno() == ENOSPC ||
198 fRawDB->GetErrno() == 1018 || // SECOMERR
199 fRawDB->GetErrno() == 1027) { // SESYSERR
200 fRawDB->ResetErrno();
201 delete fRawDB;
202 Warning("Create", "file is a zombie (no space), sleeping %d %s before retrying...",
203 kMaxSleepLong, kMaxSleepLong==1 ? "second" : "seconds");
204 gSystem->Sleep(kMaxSleepLong*1000); // sleep 10 seconds before retrying
205 goto again;
206 }
207 Error("Create", "file %s is zombie", fname);
208 fRawDB->ResetErrno();
209 delete fRawDB;
210 fRawDB = 0;
211 if (retry < kMaxRetry) {
212 Warning("Create", "file is a zombie, sleeping %d %s before retrying...",
213 kMaxSleep, kMaxSleep==1 ? "second" : "seconds");
214 gSystem->Sleep(kMaxSleep*1000);
215 goto again;
216 }
217 Error("Create", "failure to open file %s after %d tries", fname, kMaxRetry);
218 return kFALSE;
219 }
220
221 // Create raw data TTree
222 MakeTree();
223
224 return kTRUE;
225}
226
227//______________________________________________________________________________
228void AliRawDB::MakeTree()
229{
230 // Create ROOT Tree object container.
231
232 fTree = new TTree("RAW", Form("ALICE MDC%d raw data tree", AliMDC::kMDC));
233 fTree->SetAutoSave(2000000000); // autosave when 2 Gbyte written
234
235 Int_t bufsize = 256000;
236 // splitting 29.6 MB/s, no splitting 35.3 MB/s on P4 2GHz 15k SCSI
237 //Int_t split = 1;
238 Int_t split = 0;
239 fTree->Branch("rawevent", "AliRawEvent", &fEvent, bufsize, split);
a109e73e 240
241#ifdef USE_HLT
242 // Create tree which will contain the HLT ESD information
243
244 fESDTree = new TTree("esdTree", Form("ALICE MDC%d HLT ESD tree", AliMDC::kMDC));
245 fESDTree->SetAutoSave(2000000000); // autosave when 2 Gbyte written
246 split = 99;
247 fESDTree->Branch("ESD", "AliESD", &fESD, bufsize, split);
248#endif
249
a197a4ce 250}
251
252//______________________________________________________________________________
253void AliRawDB::Close()
254{
255 // Close raw DB.
256
257 if (!fRawDB) return;
258
259 fRawDB->cd();
260
261 // Write the tree.
262 fTree->Write();
a109e73e 263 fESDTree->Write();
a197a4ce 264
265 // Close DB, this also deletes the fTree
266 fRawDB->Close();
267
268 if (AliMDC::DeleteFiles()) {
269 gSystem->Unlink(fRawDB->GetName());
270 delete fRawDB;
271 fRawDB = 0;
272 return;
273 }
274
275 // Create semaphore to say this file is finished
276 Int_t tfd = ::creat(Form("%s.done", fRawDB->GetName()), 0644);
277 close(tfd);
278
279 delete fRawDB;
280 fRawDB = 0;
281}
282
283//______________________________________________________________________________
284Bool_t AliRawDB::NextFile()
285{
286 // Close te current file and open a new one.
287 // Returns kFALSE in case opening failed.
288
289 Close();
290
291 if (!Create()) return kFALSE;
292 return kTRUE;
293}
294
295//______________________________________________________________________________
296Float_t AliRawDB::GetCompressionFactor() const
297{
298 // Return compression factor.
299
300 if (fTree->GetZipBytes() == 0.)
301 return 1.0;
302 else
303 return fTree->GetTotBytes()/fTree->GetZipBytes();
304}