]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliSurveyObj.cxx
1b9502e609e4f1c9fe298b693c8046c8afd5b008
[u/mrichter/AliRoot.git] / STEER / AliSurveyObj.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 /////////////////////////////////////////////////////////////////////
17 //                                                                 //
18 //  class AliSurveyObj                                             //
19 //  Retrieve and Convert survey data into ROOT Objects             //
20 //                                                                 //
21 /////////////////////////////////////////////////////////////////////
22
23 #include "AliSurveyObj.h"
24
25 //ROOT includes
26 #include "TROOT.h"
27 #include "Riostream.h"
28 #include "TObjArray.h"
29 #include "TGrid.h"
30 #include "TFile.h"
31 #include "TObjString.h"
32
33 //AliROOT includes
34 #include "AliLog.h"
35
36 //System includes
37 //#include <time.h> //for sleep(3); // not used anymore!?
38
39 ClassImp(AliSurveyObj)
40   
41 //_____________________________________________________________________________
42 AliSurveyObj::AliSurveyObj():
43   TObject(),
44   fTitle(""),
45   fDate(""),
46   fDetector(""),
47   fURL("http://edms.cern.ch/"),
48   fReportNr(-1),
49   fVersion(-1),
50   fObs(""),
51   fCoordSys(""),
52   fUnits(""),
53   fNrColumns(-1),
54   fColNames(""),
55   fIsValid(kFALSE),
56   fDataPoints(new TObjArray(1))
57 {
58   // constructor
59   fDataPoints->SetOwner(kTRUE);
60 }
61
62
63 //_____________________________________________________________________________
64 AliSurveyObj::~AliSurveyObj() {
65   //destructor
66   if (fDataPoints) {
67     for (Int_t i = 0; i < fDataPoints->GetEntries(); ++i) delete fDataPoints->At(i);
68     fDataPoints->Delete();
69     fDataPoints = 0;
70   }
71 }
72
73
74 //_____________________________________________________________________________
75 AliSurveyObj::AliSurveyObj(const AliSurveyObj& surveyObj):
76   TObject(),
77   fTitle(surveyObj.fTitle),
78   fDate(surveyObj.fDate),
79   fDetector(surveyObj.fDetector),
80   fURL(surveyObj.fURL),
81   fReportNr(surveyObj.fReportNr),
82   fVersion(surveyObj.fVersion),
83   fObs(surveyObj.fObs),
84   fCoordSys(surveyObj.fCoordSys),
85   fUnits(surveyObj.fUnits),
86   fNrColumns(surveyObj.fNrColumns),
87   fColNames(surveyObj.fColNames),
88   fIsValid(surveyObj.fIsValid),
89   fDataPoints(new TObjArray(1))
90 {
91   // copy constructor
92   TObject *curr = surveyObj.fDataPoints->First();
93   while (curr != 0) {
94     fDataPoints->Add(curr);
95     curr = surveyObj.fDataPoints->After(curr);
96   }
97 }
98
99 //_____________________________________________________________________________
100 AliSurveyObj& AliSurveyObj::operator=(const AliSurveyObj& surveyObj)
101 {
102   // assignment operator
103   if (this != &surveyObj) {
104     fTitle = surveyObj.fTitle;
105     fDate = surveyObj.fDate;
106     fDetector = surveyObj.fDetector;
107     fURL = surveyObj.fURL;
108     fReportNr = surveyObj.fReportNr;
109     fVersion = surveyObj.fVersion;
110     fObs = surveyObj.fObs;
111     fCoordSys = surveyObj.fCoordSys;
112     fUnits = surveyObj.fUnits;
113     fNrColumns = surveyObj.fNrColumns;
114     fColNames = surveyObj.fColNames;
115     fIsValid = surveyObj.fIsValid;
116     
117     TObject *curr = surveyObj.fDataPoints->First();
118     while (curr != 0) {
119       fDataPoints->Add(curr);
120       curr = surveyObj.fDataPoints->After(curr);
121     }
122   }
123   
124   return *this;
125 }
126
127
128 //_____________________________________________________________________________
129 void AliSurveyObj::AddPoint(AliSurveyPoint* point) {
130   fDataPoints->Add(point);
131   return;
132 }
133
134
135 //_____________________________________________________________________________
136 Bool_t AliSurveyObj::Connect(const char *gridUrl, const char *user) {
137
138   // if the same Grid is alreay active, skip connection
139   if (!gGrid || gridUrl != gGrid->GridUrl() ||
140       (( user != "" ) && ( user != gGrid->GetUser() )) ) {
141     // connection to the Grid
142     AliInfo("\nConnecting to the Grid...");
143     if (gGrid) {
144       AliInfo(Form("gGrid = %x; GridUrl = %s; gGrid->GridUrl() = %s", 
145                    gGrid, gridUrl, gGrid->GridUrl()));
146       AliInfo(Form("User = %s; gGrid->GetUser() = %s",
147                    user, gGrid->GetUser()));
148     }
149     TGrid::Connect(gridUrl,user);
150   }
151         
152   if(!gGrid) {
153     AliError("Connection failed!");
154     return kFALSE;
155   }
156   return kTRUE;
157 }
158
159
160 //_____________________________________________________________________________
161 Bool_t AliSurveyObj::OpenFile(TString openString) {
162   TString storage = "alien://alice.cern.ch";
163
164   Printf("TFile::Open string: \n -> \"%s\"\n", openString.Data());
165
166   if (openString.BeginsWith("alien://")) Connect(storage.Data(), "rsilva");
167
168   TFile *file = TFile::Open(openString.Data(), "READ");
169   if ( !file ) {
170     AliError(Form("Error opening file \"%s\"", openString.Data()));
171     return kFALSE;
172   }
173
174   Int_t size = file->GetSize();
175
176   char *buf = new Char_t[size];
177   memset(buf, '\0', size);
178
179   //--size;
180
181   file->Seek(0);  
182   if ( file->ReadBuffer(buf, size) ) {
183     AliError("Error reading file contents to buffer!");
184     return kFALSE;
185   }
186
187   // Printf("%d bytes read!\n", size);
188   Printf("%d bytes read!\n", file->GetBytesRead());
189   
190   // Printf("->\n%s\n<- ", buf);
191
192   // Printf("%d AQUI!\n", size);
193
194   ParseBuffer(buf);
195
196   file->Close();
197   delete[] buf;
198   return kTRUE;
199 }
200
201
202
203 //_____________________________________________________________________________
204 Bool_t AliSurveyObj::Fill(TString detector, Int_t year, Int_t reportNumber,
205                          Int_t reportVersion) {
206   TString baseFolder = "/alice/cern.ch/user/r/rsilva/";
207   TString validDetectors = "ACORDE,BABYFRAME,BACKFRAME,EMCAL,FMD,HMPID,ITS,L3 MAGNET,MUON,MUON ABSORBERS,MUON DIPOLE,PHOS,PMD,SPACEFRAME,SUPERSTRUCTURE,T0,TOF,TPC,TRD,V0,ZDC";
208   TString GRPDetectors = "BABYFRAME,BACKFRAME,L3 MAGNET,SPACEFRAME,MUON DIPOLE,MUON ABSORBERS";
209   TString MUONDetectors = "MUON,SUPERSTRUCTURE";
210
211   detector.ToUpper();
212   
213   // Check if <detector> is valid
214   TObjArray *dets = validDetectors.Tokenize(',');
215   if (!dets->FindObject(detector)) {
216     AliError(Form("Detector '%s' is not a valid detector/structure!", detector.Data()));
217     return kFALSE;
218   }
219   dets->Delete();
220   dets = 0;
221
222   dets = GRPDetectors.Tokenize(',');
223   if (dets->FindObject(detector)) detector = "GRP";
224   dets->Delete();
225   dets = 0;
226
227   dets = MUONDetectors.Tokenize(',');
228   if (dets->FindObject(detector)) detector = "MUON";
229   dets->Delete();
230   dets = 0;
231
232   // Check if <year>, <reportNumber> and <reportVersion> are valid
233   if ((year < 1950) || (reportNumber < 1) || (reportVersion < 1)) {
234     AliError("Invalid parameter values for AliSurveyObj::Fill. (Year, Report Number or Report Version)");
235     return kFALSE;
236   }
237
238   TString fullOpenString = "alien://" + baseFolder + detector + "/RawSurvey/";
239   fullOpenString += Form("%d/%d_v%d.txt?filetype=raw", year, reportNumber, reportVersion);
240   // !Still need to check it's a valid path before actually using it
241   
242   return OpenFile(fullOpenString);
243 }
244
245
246 //_____________________________________________________________________________
247 Bool_t AliSurveyObj::FillFromLocalFile(const Char_t* filename) {
248   TString fullOpenString = "file://" + TString(filename) + "?filetype=raw";
249
250   return OpenFile(fullOpenString);
251 }
252
253
254 //_____________________________________________________________________________
255 TString &AliSurveyObj::Sanitize(TString str) {
256   str.Remove(TString::kTrailing, '\r');
257   str.Remove(TString::kTrailing, '\n');
258   str.Remove(TString::kTrailing, '\r');
259   if (!str.IsAscii()) {
260     AliWarning("Warning: Non-ASCII characters!\n");
261     str = "";
262   }
263   return str.Remove(TString::kBoth, ' ');
264 }
265
266
267 //_____________________________________________________________________________
268 Bool_t AliSurveyObj::ParseBuffer(const Char_t* buf) {
269   if (fIsValid) Reset();
270
271   TString buffer = TString(buf);
272   TObjArray *lines = buffer.Tokenize('\n');
273   TObjArray *dataLine = NULL; // Used to Tokenize each point read
274   TObjArray *colLine = NULL; // Used to Tokenize the column names
275
276   const Int_t kFieldCheck = 10;
277   Bool_t check[kFieldCheck];
278   TString tmp_name = "";
279   Float_t tmp_x = 0.0, tmp_y = 0.0, tmp_z = 0.0;
280   Float_t tmp_precX = 0.0, tmp_precY = 0.0, tmp_precZ = 0.0;
281   Char_t tmp_type = '\0';
282   Bool_t tmp_targ = kTRUE;
283   AliSurveyPoint *dp = 0;
284   
285   for (Int_t i = 0; i < kFieldCheck; ++i) check[i] = kFALSE;
286
287   Int_t nrLines = lines->GetEntries();
288   Printf("Lines in file: %d\n", nrLines); 
289
290   TString currLine = "", nextLine = "";
291   for (Int_t i = 0; i < nrLines; ++i) {
292     currLine = ((TObjString *)(lines->At(i)))->GetString().Data();
293     nextLine = ((i + 1) < nrLines ? ((TObjString *)(lines->At(i + 1)))->GetString().Data() : "");
294     currLine = Sanitize(currLine);
295     nextLine = Sanitize(nextLine);
296     //Printf("\n%d: \"\"%s\"\"\"\n", i + 1, currLine.Data());
297     
298     if (0 == currLine.Length()) {
299       Printf("Info: Empty line skipped\n\n");
300     } else if (currLine.BeginsWith(">") && !nextLine.BeginsWith(">")) {
301       currLine.Remove(TString::kLeading, '>');
302       currLine.Remove(TString::kTrailing, ':');
303       currLine.Remove(TString::kBoth, ' ');
304       nextLine.Remove(TString::kBoth, ' ');
305       // Printf(" -> Field: \"%s\"\n", currLine.Data());
306       
307       if (currLine.BeginsWith("Title", TString::kIgnoreCase)) {
308         // Report Title
309         fTitle = nextLine;
310         ++i;
311       } else if (currLine.BeginsWith("Date", TString::kIgnoreCase)) {
312         // Report(measurement) Date
313         fDate = nextLine;
314         ++i;
315       } else if (currLine.BeginsWith("Subdetector", TString::kIgnoreCase)) {
316         // Subdetector or structure
317         fDetector = nextLine;
318         ++i;
319       } else if (currLine.BeginsWith("Report URL", TString::kIgnoreCase)) {
320         // Report URL in EDMS
321         if (nextLine.BeginsWith("http://edms.cern.ch/document/", TString::kIgnoreCase) ||
322             nextLine.BeginsWith("https://edms.cern.ch/document/", TString::kIgnoreCase)) {
323           fURL = nextLine;
324           nextLine.Remove(TString::kTrailing, '/');
325           nextLine = nextLine(nextLine.Last('/') + 1, nextLine.Length() - nextLine.Last('/') + 1);
326           
327           Printf("## %s ##\n", nextLine.Data());
328           Int_t sscanf_tmp = 0;
329           //if (!nextLine.IsDigit()) {
330           if (1 != sscanf(nextLine.Data(), "%d", &sscanf_tmp)) {
331             AliError("Survey text file sintax error! (incorrectly formated Report URL)");
332             lines->Delete();
333             return kFALSE;
334           }
335           fReportNr = nextLine.Atoi();
336           //Printf(" $$ %d $$\n", fReportNr);
337           ++i;
338         } else { // URL incorrectly formated
339           AliError("Survey text file sintax error! (incorrectly formated Report URL)");
340           return kFALSE;
341         }
342       } else if (currLine.BeginsWith("Version", TString::kIgnoreCase)) {
343         if (!nextLine.IsDigit()) {
344           lines->Delete();
345           AliError("Survey text file sintax error! (incorrectly formated Report Version)");
346           return kFALSE;
347         }
348         fVersion = nextLine.Atoi();
349         ++i;
350       } else if (currLine.BeginsWith("General Observations", TString::kIgnoreCase)) {
351         fObs = "";
352         while (('>' != nextLine[0]) && nextLine.Length() > 0) { 
353           fObs += (0 == fObs.Length()) ? nextLine : " / " + nextLine;
354           ++i;
355           nextLine = ((i + 1) < nrLines ? ((TObjString *)(lines->At(i + 1)))->GetString().Data() : "");
356           nextLine = Sanitize(nextLine);
357         }
358         // Printf("->%s<-\n", fObs.Data());
359       } else if (currLine.BeginsWith("Coordinate System", TString::kIgnoreCase)) {
360         fCoordSys = nextLine;
361         ++i;
362       } else if (currLine.BeginsWith("Units", TString::kIgnoreCase)) {
363         fUnits = nextLine;
364         ++i;
365       } else if (currLine.BeginsWith("Nr Columns", TString::kIgnoreCase)) {
366         if (!nextLine.IsDigit()) {
367           lines->Delete();
368           AliError("Survey text file sintax error! (incorrectly formated Number of Columns)");
369           return kFALSE;
370         }
371         fNrColumns = nextLine.Atoi();
372         ++i;
373       } else if (currLine.BeginsWith("Column Names", TString::kIgnoreCase)) {
374         fColNames = nextLine;
375         colLine = nextLine.Tokenize(',');
376         if (colLine->GetEntries() != fNrColumns) {
377           AliError("Survey text file sintax error! (Declared number of Columns doesn't match number of column names)");
378           colLine->Delete();
379           lines->Delete();
380           return kFALSE;
381         }
382         ++i;
383       } else if (currLine.BeginsWith("Data", TString::kIgnoreCase)) {
384         while ((nextLine.Length() > 0) && ('>' != nextLine[0])) {
385           Printf("Data LINE: \"%s\": %d\n", nextLine.Data(), nextLine.Length());
386           if (2 == nextLine.Length()) for(Int_t g = 0; g < 2; ++g) Printf("'%c'", nextLine[g]);
387
388           if (fNrColumns == nextLine.CountChar(',') + 1) dataLine = nextLine.Tokenize(',');
389           else if (fNrColumns == nextLine.CountChar('\t') + 1) dataLine = nextLine.Tokenize('\t');
390           else if (fNrColumns == nextLine.CountChar(' ') + 1) dataLine = nextLine.Tokenize(' ');
391           else {
392             //Error
393             AliError("Survey text file syntax error! Error processing data line!");
394             lines->Delete();
395             return kFALSE;
396           }
397
398           if (dataLine->GetEntries() != fNrColumns) {
399             AliError("Survey text file sintax error! (Number of entries in line is different from declared Number of Columns)");
400             dataLine->Delete();
401             lines->Delete();
402             return kFALSE;
403           }
404
405           for (Int_t t = 0; t < kFieldCheck; ++t) check[t] = 0;
406
407           for (Int_t j = 0; j < dataLine->GetEntries(); ++j) {
408             TString cn = ((TObjString *)(colLine->At(j)))->GetString();
409             TString value = ((TObjString *)(dataLine->At(j)))->GetString();
410             if (cn.BeginsWith("Point Name", TString::kIgnoreCase)) {
411               tmp_name = value;
412               check[0] = kTRUE;
413             } else if (cn.BeginsWith("X", TString::kIgnoreCase)) {
414               tmp_x = value.Atof();
415               check[1] = kTRUE;
416             } else if (cn.BeginsWith("Y", TString::kIgnoreCase)) {
417               tmp_y = value.Atof();
418               check[2] = kTRUE;
419             } else if (cn.BeginsWith("Z", TString::kIgnoreCase)) {
420               tmp_z = value.Atof();
421               check[3] = kTRUE;
422             } else if (cn.BeginsWith("Precision", TString::kIgnoreCase)) {
423               TString tmpCN = cn(0, cn.First('('));
424               Int_t precLength = TString("Precision").Length();
425               //Printf(" ====== %d ======= %d ====== \n", precLength, tmpCN.Length());
426               //Printf(" ====== %s ======= \n", tmpCN.Data());
427               if (precLength == tmpCN.Length()) {
428                 tmp_precX = tmp_precY = tmp_precZ = value.Atof();
429                 check[6] = kTRUE;
430               } else {
431                 TString axis = cn(precLength, tmpCN.Length() - precLength);
432                 if (axis.Contains('X', TString::kIgnoreCase)) {
433                   tmp_precX = value.Atof();
434                   check[7] = kTRUE;
435                 } else if (axis.Contains('Y', TString::kIgnoreCase)) {
436                   tmp_precY = value.Atof();
437                   check[8] = kTRUE;
438                 } else if (axis.Contains('Z', TString::kIgnoreCase)) {
439                   tmp_precZ = value.Atof();
440                   check[9] = kTRUE;
441                 } else {
442                   AliError("Survey text file sintax error! (Precision column name invalid)");
443                   dataLine->Delete();
444                   lines->Delete();
445                   return kFALSE;
446                 }
447               }
448             } else if (cn.BeginsWith("Point Type", TString::kIgnoreCase)) {
449               tmp_type = value.Data()[0];
450               check[4] = kTRUE;
451             } else if (cn.BeginsWith("Target Used", TString::kIgnoreCase)) {
452               tmp_targ = (value.Data()[0] == 'Y') ? kTRUE : kFALSE;
453               check[5] = kTRUE;
454             }
455
456             //Printf("--> %s\n", ((TObjString *)(dataLine->At(j)))->GetString().Data());
457           }
458           Bool_t res = kTRUE, precInd = kTRUE;
459
460           // Target
461           if (kFALSE == check[5]) {
462             tmp_targ = kTRUE;
463             check[5] = kTRUE;
464           }
465           
466           // Individual axis precisions
467           for (Int_t t = 7; t < 10; ++t) precInd &= check[t];
468           if ((kFALSE == check[6]) && (kTRUE == precInd)) check[6] = kTRUE;
469
470           for (Int_t t = 0; t < kFieldCheck - 3; ++t) {
471             //Printf("RES(%d): %d\n", t, check[t]);
472             res &= check[t];
473           }
474           if (kTRUE == res) {
475             dp = new AliSurveyPoint(tmp_name, tmp_x, tmp_y, tmp_z, tmp_precX, tmp_precY, tmp_precZ, tmp_type, tmp_targ);
476             dp->PrintPoint();
477             AddPoint(dp);
478           } else {
479             AliError("Parsing error processing data line!");
480             dataLine->Delete();
481             lines->Delete();
482             return kFALSE;
483           }
484           
485           dataLine->Delete();
486           dataLine = NULL;
487           ++i;
488           nextLine = ((i + 1) < nrLines ? ((TObjString *)(lines->At(i + 1)))->GetString().Data() : "");
489           nextLine = Sanitize(nextLine);
490         }
491       }
492     } else {
493       AliError("Survey text file sintax error!");
494       lines->Delete();
495       return kFALSE;
496     }
497   }
498   lines->Delete();
499   fIsValid = kTRUE;
500   return kTRUE;
501 }
502
503 //_____________________________________________________________________________
504 void AliSurveyObj::Reset()
505 {
506   if (fDataPoints) {
507     for (Int_t i = 0; i < fDataPoints->GetEntries(); ++i) delete fDataPoints->At(i);
508     fDataPoints->Delete();
509     fDataPoints = 0;
510   }
511   fTitle = "";
512   fDate = "";
513   fDetector = "";
514   fURL = "http://edms.cern.ch/";
515   fReportNr = -1;
516   fVersion = -1;
517   fObs = "";
518   fCoordSys = "";
519   fUnits = "";
520   fNrColumns = -1;
521   fColNames = "";
522   fIsValid = kFALSE;
523   fDataPoints = new TObjArray(1);
524   fDataPoints->SetOwner(kTRUE);
525   return;
526 }
527