]> git.uio.no Git - u/mrichter/AliRoot.git/blame_incremental - STEER/AliSurveyObj.cxx
AliTriggerConfiguration: fix for DTRUE and 5 bcmasks
[u/mrichter/AliRoot.git] / STEER / AliSurveyObj.cxx
... / ...
CommitLineData
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 "TObjArray.h"
27#include "TGrid.h"
28#include "TGridResult.h"
29#include "TFile.h"
30#include "TObjString.h"
31
32//AliROOT includes
33#include "AliLog.h"
34#include "AliSurveyPoint.h"
35
36ClassImp(AliSurveyObj)
37
38
39const TString AliSurveyObj::fgkStorage = "alien://alice.cern.ch";
40const TString AliSurveyObj::fgkBaseFolder = "/alice/data/Reference";
41const TString AliSurveyObj::fgkValidDetectors = "ACORDE,BABYFRAME,BACKFRAME,\
42EMCAL,FMD,HMPID,ITS,L3 MAGNET,MUON,MUON ABSORBERS,MUON DIPOLE,PHOS,PMD,\
43SPACEFRAME,SUPERSTRUCTURE,T0,TOF,TPC,TRD,VZERO,ZDC,GRP";
44const TString AliSurveyObj::fgkGRPDetectors = "BABYFRAME,BACKFRAME,L3 MAGNET,\
45SPACEFRAME,MUON DIPOLE,MUON ABSORBERS,GRP";
46const TString AliSurveyObj::fgkMUONDetectors = "MUON,SUPERSTRUCTURE";
47
48
49//_____________________________________________________________________________
50AliSurveyObj::AliSurveyObj():
51 TObject(),
52 fTitle(""),
53 fDate(""),
54 fDetector(""),
55 fURL("http://edms.cern.ch/"),
56 fReportNr(-1),
57 fVersion(-1),
58 fObs(""),
59 fCoordSys(""),
60 fUnits(""),
61 fNrColumns(-1),
62 fColNames(""),
63 fIsValid(kFALSE),
64 fGridUser(""),
65 fDataPoints(new TObjArray(1))
66{
67 // constructor
68 fDataPoints->SetOwner(kTRUE);
69}
70
71
72//_____________________________________________________________________________
73AliSurveyObj::~AliSurveyObj() {
74 //destructor
75 if (fDataPoints) {
76 fDataPoints->Delete();
77 fDataPoints = 0;
78 }
79}
80
81
82//_____________________________________________________________________________
83AliSurveyObj::AliSurveyObj(const AliSurveyObj& surveyObj):
84 TObject(),
85 fTitle(surveyObj.fTitle),
86 fDate(surveyObj.fDate),
87 fDetector(surveyObj.fDetector),
88 fURL(surveyObj.fURL),
89 fReportNr(surveyObj.fReportNr),
90 fVersion(surveyObj.fVersion),
91 fObs(surveyObj.fObs),
92 fCoordSys(surveyObj.fCoordSys),
93 fUnits(surveyObj.fUnits),
94 fNrColumns(surveyObj.fNrColumns),
95 fColNames(surveyObj.fColNames),
96 fIsValid(surveyObj.fIsValid),
97 fGridUser(surveyObj.fGridUser),
98 fDataPoints(new TObjArray(1))
99{
100 // copy constructor
101 TObject *curr = surveyObj.fDataPoints->First();
102 while (curr != 0) {
103 fDataPoints->Add(curr);
104 curr = surveyObj.fDataPoints->After(curr);
105 }
106}
107
108
109//_____________________________________________________________________________
110AliSurveyObj& AliSurveyObj::operator=(const AliSurveyObj& surveyObj)
111{
112 // assignment operator
113 if (this != &surveyObj) {
114 fTitle = surveyObj.fTitle;
115 fDate = surveyObj.fDate;
116 fDetector = surveyObj.fDetector;
117 fURL = surveyObj.fURL;
118 fReportNr = surveyObj.fReportNr;
119 fVersion = surveyObj.fVersion;
120 fObs = surveyObj.fObs;
121 fCoordSys = surveyObj.fCoordSys;
122 fUnits = surveyObj.fUnits;
123 fNrColumns = surveyObj.fNrColumns;
124 fColNames = surveyObj.fColNames;
125 fIsValid = surveyObj.fIsValid;
126 fGridUser = surveyObj.fGridUser;
127 TObject *curr = surveyObj.fDataPoints->First();
128 while (curr != 0) {
129 fDataPoints->Add(curr);
130 curr = surveyObj.fDataPoints->After(curr);
131 }
132 }
133 return *this;
134}
135
136
137//_____________________________________________________________________________
138void AliSurveyObj::AddPoint(AliSurveyPoint* point) {
139 // Adds a point to the TObjArray which containst the list of points
140 fDataPoints->Add(point);
141 return;
142}
143
144
145//_____________________________________________________________________________
146Bool_t AliSurveyObj::Connect(const char *gridUrl, const char *user) {
147 // Connects to the grid
148
149 // If the same "Grid" is alreay active, skip connection
150 if (!gGrid || gridUrl != gGrid->GridUrl() ||
151 (( strcmp(user,"") ) && ( strcmp(user,gGrid->GetUser()) )) ) {
152 // connection to the Grid
153 AliInfo("\nConnecting to the Grid...");
154 if (gGrid) {
155 AliInfo(Form("gGrid = %p; GridUrl = %s; gGrid->GridUrl() = %s",
156 gGrid, gridUrl, gGrid->GridUrl()));
157 AliInfo(Form("User = %s; gGrid->GetUser() = %s",
158 user, gGrid->GetUser()));
159 }
160 TGrid::Connect(gridUrl,user);
161 }
162
163 if(!gGrid) {
164 AliError("Connection failed!");
165 return kFALSE;
166 }
167 return kTRUE;
168}
169
170
171//_____________________________________________________________________________
172Bool_t AliSurveyObj::OpenFile(TString openString) {
173 // Opens the file and reads it to a buffer
174
175 AliInfo(Form("Opening file \"%s\"\n for survey data", openString.Data()));
176
177 if (openString.BeginsWith("alien://"))
178 if (!Connect(fgkStorage.Data(), fGridUser.Data())) {
179 AliError(Form("Error connecting to GRID"));
180 return kFALSE;
181 }
182
183 TFile *file = TFile::Open(openString.Data(), "READ");
184 if ( !file ) {
185 AliError(Form("Error opening file \"%s\"", openString.Data()));
186 return kFALSE;
187 }
188
189 Int_t size = file->GetSize();
190
191 char *buf = new Char_t[size + 1];
192 memset(buf, '\0', size + 1);
193
194 file->Seek(0);
195 if ( file->ReadBuffer(buf, size) ) {
196 AliError("Error reading file contents to buffer!");
197 return kFALSE;
198 }
199 AliInfo(Form("%l bytes read!\n", file->GetBytesRead()));
200
201 ParseBuffer(buf);
202
203 file->Close();
204 delete[] buf;
205 return kTRUE;
206}
207
208
209//_____________________________________________________________________________
210Bool_t AliSurveyObj::FillFromLocalFile(const Char_t* filename) {
211 // Fills the object from a file in a local filesystem
212
213 TString fullOpenString = "file://" + TString(filename) + "?filetype=raw";
214
215 return OpenFile(fullOpenString);
216}
217
218
219//_____________________________________________________________________________
220Bool_t AliSurveyObj::IsValidDetector(TString detector) const {
221 // Checks if the detector name is valid
222
223 detector.ToUpper();
224
225 TObjArray *dets = fgkValidDetectors.Tokenize(',');
226 TObject *found = dets->FindObject(detector);
227 dets->Delete();
228 dets = 0;
229
230 if (!found) return kFALSE;
231 else return kTRUE;
232}
233
234
235//_____________________________________________________________________________
236TString AliSurveyObj::RealFolderName(TString detector) const {
237 // Returns the actual folder name for a given detector
238 // Some "detectors" don't have a folder of their own
239
240 detector.ToUpper();
241 TString folderName = detector;
242
243 TObjArray *dets = fgkGRPDetectors.Tokenize(',');
244 if (dets->FindObject(detector)) folderName = "GRP";
245 dets->Delete();
246 dets = 0;
247
248 dets = fgkMUONDetectors.Tokenize(',');
249 if (dets->FindObject(detector)) folderName = "MUON";
250 dets->Delete();
251
252
253
254 dets = 0;
255
256 return folderName;
257}
258
259//_____________________________________________________________________________
260Bool_t AliSurveyObj::Fill(TString detector, Int_t reportNumber,
261 TString username) {
262 // Fills the object from a file in the default storage location in AliEn.
263 // The highest version available is selected.
264
265 return Fill(detector, reportNumber, -1, username);
266}
267
268//_____________________________________________________________________________
269Bool_t AliSurveyObj::Fill(TString detector, Int_t reportNumber,
270 Int_t reportVersion, TString username) {
271 // Fills the object from a file in the default storage location in AliEn.
272 // A specific version is selected.
273
274 detector.ToUpper();
275
276 // Check if <detector> is valid
277 if (!IsValidDetector(detector)) {
278 AliWarning(Form("Detector '%s' is not a valid detector/structure!", detector.Data()));
279 return kFALSE;
280 }
281
282 // Some "detectors" don't have a folder of their own
283 // TString detectorFolder = RealFolderName(detector);
284
285 // Check if <year>, <reportNumber> and <reportVersion> are valid (roughly)
286 if ((reportNumber < 1) || (reportVersion < -1) || (0 == reportVersion)) {
287 AliError("Invalid parameter values for AliSurveyObj::Fill. (Report Number or Report Version)");
288 return kFALSE;
289 }
290
291 // Check if the fGridUser is set, or specified
292 if (username.Length() > 0) SetGridUser(username);
293 else if (0 == fGridUser.Length()) {
294 AliError("GRID username not specified and not previously set!");
295 return kFALSE;
296 }
297
298 // Query AliEn for the available reports
299 TGridResult *res = QueryReports(detector, -1, reportNumber, reportVersion);
300 if (!res) AliError(Form("Error querying AliEn for detector '%s', \
301 report number '%d' and report version '%d'.",
302 detector.Data(), reportNumber, reportVersion));
303 Int_t numberEntries = res->GetEntries();
304 if (0 == numberEntries) {
305 AliError(Form("No report found for detector '%s', report number '%d' and report version '%d'",
306 detector.Data(), reportNumber, reportVersion));
307 return kFALSE;
308 }
309
310 TString fileNamePath = "";
311 if (1 == numberEntries) fileNamePath = res->GetFileNamePath(0);
312 else if (numberEntries > 1) {
313 TString higherVerFNP = res->GetFileNamePath(0);
314 Int_t lastYear = FileNamePathToReportYear(higherVerFNP);
315 for (Int_t i = 1; i < numberEntries; ++i) {
316 TString currFNP = res->GetFileNamePath(i);
317 if (FileNamePathToReportVersion(currFNP) >
318 FileNamePathToReportVersion(higherVerFNP)) higherVerFNP = currFNP;
319 if (lastYear != FileNamePathToReportYear(currFNP))
320 AliWarning("Inconsistency detected, year differs for reports with the same report number! Please inform the responsible and check the report against the one in DCDB.");
321 }
322 fileNamePath = higherVerFNP;
323 }
324
325 TString fullOpenString = "alien://" + fileNamePath + "?filetype=raw";
326 /*
327 // Finally composes the full string
328 TString fullOpenString = "alien://" + fgkBaseFolder + "/" + detectorFolder + "/RawSurvey/";
329 fullOpenString += Form("%d/%d_v%d.txt?filetype=raw", year, reportNumber, reportVersion);
330 */
331
332 return OpenFile(fullOpenString);
333}
334
335
336//_____________________________________________________________________________
337TString AliSurveyObj::FileNamePathToDetector(TString filename) const {
338 // Get the report number from the complete path in the format:
339 // /alice/data/Reference/HMPID/RawSurvey/2006/781282_v1.txt
340
341 TString ret = "";
342
343 if (filename.Length() > fgkBaseFolder.Length()) {
344 ret = filename.Remove(0, fgkBaseFolder.Length());
345 ret.Remove(TString::kLeading, '/');
346 ret = ret(0, ret.First('/'));
347 if (!IsValidDetector(ret)) ret = "";
348 }
349 return ret;
350}
351
352///alice/cern.ch/user/r/rsilva/TRD/RawSurvey/2007/.816582_v2.txt/v1.0
353
354//_____________________________________________________________________________
355Int_t AliSurveyObj::FileNamePathToReportYear(TString filename) const {
356 // Get the report year from the complete path in the format:
357 // /alice/data/Reference/HMPID/RawSurvey/2006/781282_v1.txt
358
359 TString ret = "";
360
361 if (filename.Length() > fgkBaseFolder.Length()) {
362 ret = filename.Remove(0, fgkBaseFolder.Length());
363 ret.Remove(TString::kLeading, '/');
364 Int_t beg = ret.First('/') + TString("RawSurvey/").Length() + 1;
365 ret = ret(beg, ret.Last('/') - beg);
366 return ret.Atoi();
367 }
368 return -1;
369}
370
371
372//_____________________________________________________________________________
373Int_t AliSurveyObj::FileNamePathToReportNumber(TString filename) const {
374 // Get the report number from the complete path in the format:
375 // /alice/data/Reference/HMPID/RawSurvey/2006/781282_v1.txt
376
377 TString ret = "";
378
379 if (filename.Length() > fgkBaseFolder.Length()) {
380 ret = filename.Remove(0, fgkBaseFolder.Length());
381 ret.Remove(TString::kLeading, '/');
382 if ((ret.CountChar('/') > 3) || (ret.CountChar('.') > 1)) {
383 AliWarning("Error getting the Report Number from the filename path!");
384 return -1;
385 }
386 ret = ret(ret.Last('/') + 1 , ret.Last('_') - ret.Last('/') - 1);
387 return ret.Atoi();
388 }
389 AliWarning("Error getting the Report Number from the filename path!");
390 return -1;
391}
392
393
394//_____________________________________________________________________________
395Int_t AliSurveyObj::FileNamePathToReportVersion(TString filename) const {
396 // Get the report version from the complete path in the format:
397 // /alice/data/Reference/HMPID/RawSurvey/2006/781282_v1.txt
398
399 TString ret = "";
400
401 if (filename.Length() > fgkBaseFolder.Length()) {
402 ret = filename.Remove(0, fgkBaseFolder.Length());
403 ret.Remove(TString::kLeading, '/');
404 if ((ret.CountChar('/') > 3) || (ret.CountChar('.') > 1)) {
405 AliWarning("Error getting the Report Version from the filename path!");
406 return -1;
407 }
408 ret = ret(ret.Last('_') + 1 + 1 , ret.Last('.') - ret.Last('_') - 1 - 1);
409 return ret.Atoi();
410 }
411 AliWarning("Error getting the Report Version from the filename path!");
412 return -1;
413}
414
415
416//_____________________________________________________________________________
417void AliSurveyObj::ListValidDetectors() {
418 // List the valid detector names
419 Printf("Listing all valid detectors:\n");
420 TObjArray *dets = fgkValidDetectors.Tokenize(',');
421 for (int i = 0; i < dets->GetEntries(); ++i)
422 Printf("%s", ((TObjString *) dets->At(i))->GetString().Data());
423 dets->Delete();
424 dets = 0;
425 Printf("Some reports are stored in more general folders.\n"
426 "These reports can be opened using either name, the original or the\n"
427 "folder name. Example: 'SPACEFRAME' or 'GRP' are both valid when\n"
428 "opening a report for the Spaceframe.\n\n"
429 "Detectors stored in 'MUON' folder:");
430 dets = fgkMUONDetectors.Tokenize(',');
431 for (int i = 0; i < dets->GetEntries(); ++i)
432 Printf("%s", ((TObjString *) dets->At(i))->GetString().Data());
433 dets->Delete();
434 dets = 0;
435 Printf("Detectors stored in 'GRP' folder:");
436 dets = fgkGRPDetectors.Tokenize(',');
437 for (int i = 0; i < dets->GetEntries(); ++i)
438 Printf("%s", ((TObjString *) dets->At(i))->GetString().Data());
439 dets->Delete();
440 dets = 0;
441 return;
442}
443
444
445//_____________________________________________________________________________
446TGridResult * AliSurveyObj::QueryReports(TString detector, Int_t year,
447 Int_t reportNumber,
448 Int_t reportVersion) {
449 // Queries AliEn for existing reports matching the specified conditions
450 TString lsArg = fgkBaseFolder;
451
452 TString detectorFolder = "";
453 if (detector.Length() > 0) {
454 detector.ToUpper();
455 // Check if <detector> is valid
456 if (!IsValidDetector(detector)) {
457 AliError(Form("Detector '%s' is not a valid detector/structure!",
458 detector.Data()));
459 return 0;
460 }
461 // Some "detectors" don't have a folder of their own
462 detectorFolder = "/" + RealFolderName(detector);
463 } else detectorFolder = "/*";
464
465 lsArg += detectorFolder + "/RawSurvey";
466
467 TString yearFolder = "";
468 if (year > 1950) yearFolder.Form("/%d", year);
469 else yearFolder = "/*";
470
471 TString reportFolder = "";
472 if (reportNumber > 0) reportFolder.Form("/%d", reportNumber);
473 else reportFolder = "/*";
474
475 TString versionFolder = "";
476 if (reportVersion > 0) versionFolder.Form("_v%d", reportVersion);
477 else versionFolder = "_v*";
478
479 lsArg += yearFolder + reportFolder + versionFolder + ".txt";
480
481 AliInfo(Form("\nLooking for: %s \n", lsArg.Data()));
482
483 // Check if fGridUser is set and Connect to AliEn
484 if (0 == fGridUser.Length()) {
485 AliError("To use this method it's necessary to call SetGridUser(...) in advance.");
486 return 0;
487 } else if (!Connect(fgkStorage.Data(), fGridUser.Data())) {
488 AliError(Form("Error connecting to GRID"));
489 return 0;
490 }
491 return gGrid->Ls(lsArg);
492}
493
494
495//_____________________________________________________________________________
496Int_t AliSurveyObj::ListReports(TString detector, Int_t year,
497 Int_t reportNumber,
498 Int_t reportVersion) {
499 // Lists all available reports matching the specified conditions
500 // Returns the number of reports found
501
502 TGridResult *res = QueryReports(detector, year, reportNumber, reportVersion);
503
504 if (0 == res) {
505 AliError("Query failed.");
506 return 0;
507 }
508
509 TString fn = "";
510 Int_t numberEntries = res->GetEntries();
511
512 if (numberEntries > 0) {
513 Printf(Form("%d reports found:", numberEntries));
514 for (int i = 0; i < res->GetEntries(); ++i) {
515 fn = res->GetFileNamePath(i);
516 Printf(Form("Detector:%s\tYear:%d\tEDMS Report Number:%d\tVersion:%d",
517 FileNamePathToDetector(fn).Data(),
518 FileNamePathToReportYear(fn),
519 FileNamePathToReportNumber(fn),
520 FileNamePathToReportVersion(fn)));
521 }
522 delete res;
523 return numberEntries;
524 } else {
525 AliInfo("No results found for the requested query.");
526 delete res;
527 return 0;
528 }
529}
530
531
532//_____________________________________________________________________________
533void AliSurveyObj::SetGridUser(TString username){
534 // Set the username used to connect to the GRID
535 fGridUser = username;
536 return;
537}
538
539
540//_____________________________________________________________________________
541TString &AliSurveyObj::Sanitize(TString str) {
542 // Cleans up a line of new line and carriage return characters.
543 // (Specially usefull for files created in Windows.)
544
545 str.Remove(TString::kTrailing, '\r');
546 str.Remove(TString::kTrailing, '\n');
547 str.Remove(TString::kTrailing, '\r');
548
549 if (!str.IsAscii()) {
550 AliWarning("Warning: Non-ASCII characters!\n");
551 str = "";
552 }
553 return str.Remove(TString::kBoth, ' ');
554}
555
556
557//_____________________________________________________________________________
558Bool_t AliSurveyObj::ParseBuffer(const Char_t* buf) {
559 // Parses a character buffer assuming the format defined with the TS/SU
560 // http://aliceinfo/Offline/Activities/Alignment/SurveyInformation.html
561
562 // If the object is already filled clean it up
563 if (fIsValid) Reset();
564
565 // Copy the buffer to a TString to use Tokenize
566 TString buffer = TString(buf);
567 TObjArray *linesRaw = buffer.Tokenize('\n');
568 // replace the array of lines with an array of sanitized lines
569 // in the process we remove empty lines, particularly disturbing
570 // in case of dos fileformat
571 TString oneLine = "";
572 TObjString* oneLineObj = 0;
573 TObjArray *lines = new TObjArray();
574 for(Int_t i=0; i<linesRaw->GetEntries(); i++)
575 {
576 oneLine = ((TObjString *)(linesRaw->At(i)))->GetString().Data();
577 oneLine = Sanitize(oneLine);
578 if (oneLine.Length() == 0) continue;
579 oneLineObj = new TObjString(oneLine);
580 lines->Add(oneLineObj);
581 }
582
583 linesRaw->Delete();
584 delete linesRaw;
585 linesRaw = NULL;
586
587 TObjArray *dataLine = NULL; // Used to Tokenize each point/line read
588 TObjArray *colLine = NULL; // Used to Tokenize the column names
589
590 // Some local variables declarations and initializations
591 const Int_t kFieldCheck = 10;
592 Bool_t check[kFieldCheck]; // used to check that mandatory column names are not missing
593 for (Int_t i = 0; i < kFieldCheck; ++i) check[i] = kFALSE;
594 TString tmpname = "";
595 Float_t tmpx = 0.0, tmpy = 0.0, tmpz = 0.0;
596 Float_t tmpprecX = -1., tmpprecY = -1., tmpprecZ = -1.;
597 Char_t tmptype = '\0';
598 Bool_t tmptarg = kTRUE;
599 AliSurveyPoint *dp = 0;
600 TString *orderedValues[9] = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};
601 TString value[9];
602
603 Int_t nrLines = lines->GetEntries();
604 Printf("Lines in file: %d\n", nrLines);
605
606 // The main cycle, the buffer is parsed a line at a time
607 TString currLine = "", nextLine = "";
608 for (Int_t i = 0; i < nrLines; ++i) {
609
610 // Get the next line
611 currLine = ((TObjString *)(lines->At(i)))->GetString().Data();
612 nextLine = ((i + 1) < nrLines ? ((TObjString *)(lines->At(i + 1)))->GetString().Data() : "");
613 // Printf("%d: \"%s\"", i, currLine.Data());
614 // Printf("%d: \"%s\"\n", i+1, nextLine.Data());
615
616 // The line contains a keyword
617 if (currLine.BeginsWith(">") && !nextLine.BeginsWith(">")) {
618 currLine.Remove(TString::kLeading, '>');
619 currLine.Remove(TString::kTrailing, ':');
620 currLine.Remove(TString::kBoth, ' ');
621 nextLine.Remove(TString::kBoth, ' ');
622 AliDebug(2, Form(" -> field line: \"%s\"\n", currLine.Data()));
623 AliDebug(2, Form(" -> value line: \"%s\"\n", nextLine.Data()));
624
625 if (currLine.BeginsWith("Title", TString::kIgnoreCase)) {
626 // Report Title
627 fTitle = nextLine;
628 ++i;
629 } else if (currLine.BeginsWith("Date", TString::kIgnoreCase)) {
630 // Report(measurement) Date
631 fDate = nextLine;
632 ++i;
633 } else if (currLine.BeginsWith("Subdetector", TString::kIgnoreCase)) {
634 // Subdetector or structure
635 fDetector = nextLine;
636 ++i;
637 } else if (currLine.BeginsWith("Report URL", TString::kIgnoreCase)) {
638 // Report URL in EDMS
639 if (nextLine.BeginsWith("http://edms.cern.ch/document/", TString::kIgnoreCase) ||
640 nextLine.BeginsWith("https://edms.cern.ch/document/", TString::kIgnoreCase)) {
641 fURL = nextLine;
642 nextLine.Remove(TString::kTrailing, '/');
643 nextLine = nextLine(nextLine.Last('/') + 1, nextLine.Length() - nextLine.Last('/') + 1);
644
645 Int_t sscanftmp = 0;
646 if (1 != sscanf(nextLine.Data(), "%d", &sscanftmp)) {
647 AliError("Survey text file sintax error! (incorrectly formatted Report URL)");
648 lines->Delete();
649 delete lines; lines = NULL;
650 return kFALSE;
651 }
652 fReportNr = nextLine.Atoi();
653 //Printf(" $$ %d $$\n", fReportNr);
654 ++i;
655 } else {
656 // URL incorrectly formatted
657 AliError("Survey text file sintax error! (incorrectly formatted Report URL)");
658 return kFALSE;
659 }
660 } else if (currLine.BeginsWith("Version", TString::kIgnoreCase)) {
661 // Report version
662 if (!nextLine.IsDigit()) {
663 lines->Delete();
664 delete lines; lines = NULL;
665 AliError("Survey text file sintax error! (incorrectly formatted Report Version)");
666 return kFALSE;
667 }
668 fVersion = nextLine.Atoi();
669 ++i;
670 } else if (currLine.BeginsWith("General Observations", TString::kIgnoreCase)) {
671 // Observations
672 fObs = "";
673 // Can be more than 1 line. Loop until another keyword is found
674 while (('>' != nextLine[0]) && (nextLine.Length() > 0) && (i < nrLines)) {
675 fObs += (0 == fObs.Length()) ? nextLine : " / " + nextLine;
676 ++i;
677 nextLine = ((i + 1) < nrLines ? ((TObjString *)(lines->At(i + 1)))->GetString().Data() : "");
678 }
679 } else if (currLine.BeginsWith("Coordinate System", TString::kIgnoreCase)) {
680 // Coordinate System
681 fCoordSys = nextLine;
682 ++i;
683 } else if (currLine.BeginsWith("Units", TString::kIgnoreCase)) {
684 // Measurement Unit
685 fUnits = nextLine;
686 ++i;
687 } else if (currLine.BeginsWith("Nr Columns", TString::kIgnoreCase)) {
688 // Number of columns in the "Data" section
689 if (!nextLine.IsDigit()) {
690 lines->Delete();
691 delete lines; lines = NULL;
692 AliError("Survey text file sintax error! (incorrectly formatted Number of Columns)");
693 return kFALSE;
694 }
695 fNrColumns = nextLine.Atoi();
696 ++i;
697 } else if (currLine.BeginsWith("Column Names", TString::kIgnoreCase)) {
698 // Column names separated by commas
699 fColNames = nextLine;
700 colLine = nextLine.Tokenize(',');
701 if (colLine->GetEntries() != fNrColumns) {
702 AliError("Survey text file sintax error! (Declared number of Columns doesn't match number of column names)");
703 colLine->Delete();
704 lines->Delete();
705 delete lines; lines = NULL;
706 return kFALSE;
707 }
708 ++i;
709
710 // booleans to track if precision for 1 axis is defined in more than one column
711 Bool_t prX = kFALSE;
712 Bool_t prY = kFALSE;
713 Bool_t prZ = kFALSE;
714
715 for (Int_t j = 0; j < fNrColumns; ++j) {
716 TString cn = ((TObjString *)(colLine->At(j)))->GetString();
717 if (cn.BeginsWith("Point Name", TString::kIgnoreCase)) {
718 orderedValues[0] = &value[j];
719 check[0] = kTRUE;
720 } else if (cn.BeginsWith("X", TString::kIgnoreCase)) {
721 orderedValues[1] = &value[j];
722 check[1] = kTRUE;
723 } else if (cn.BeginsWith("Y", TString::kIgnoreCase)) {
724 orderedValues[2] = &value[j];
725 check[2] = kTRUE;
726 } else if (cn.BeginsWith("Z", TString::kIgnoreCase)) {
727 orderedValues[3] = &value[j];
728 check[3] = kTRUE;
729 } else if (cn.BeginsWith("Precision", TString::kIgnoreCase)) {
730 TString tmpCN = cn(0, cn.First('('));
731 Int_t precLength = TString("Precision").Length();
732 if (precLength == tmpCN.Length()) {
733 if(!orderedValues[6]){
734 orderedValues[6] = &value[j];
735 check[6] = kTRUE;
736 }else{
737 AliWarning("Global precision will not be used for X axis");
738 }
739 if(!orderedValues[7]){
740 orderedValues[7] = &value[j];
741 check[7] = kTRUE;
742 }else{
743 AliWarning("Global precision will not be used for Y axis");
744 }
745 if(!orderedValues[8]){
746 orderedValues[8] = &value[j];
747 check[8] = kTRUE;
748 }else{
749 AliWarning("Global precision will not be used for Z axis");
750 }
751 } else {
752 Bool_t orXYZ = kFALSE;
753 TString axis = cn(precLength, tmpCN.Length() - precLength);
754 if (axis.Contains('X', TString::kIgnoreCase)) {
755 if(!prX){
756 orderedValues[6] = &value[j];
757 check[6] = kTRUE;
758 orXYZ = kTRUE;
759 prX = kTRUE;
760 }else{
761 AliError("Precision for X axis was already set!");
762 return kFALSE;
763 }
764 }
765 if (axis.Contains('Y', TString::kIgnoreCase)) {
766 if(!prY){
767 orderedValues[7] = &value[j];
768 check[7] = kTRUE;
769 orXYZ = kTRUE;
770 prY = kTRUE;
771 }else{
772 AliError("Precision for Y axis was already set!");
773 return kFALSE;
774 }
775 }
776 if (axis.Contains('Z', TString::kIgnoreCase)) {
777 if(!prZ){
778 orderedValues[8] = &value[j];
779 check[8] = kTRUE;
780 orXYZ = kTRUE;
781 prZ = kTRUE;
782 }else{
783 AliError("Precision for Z axis was already set!");
784 return kFALSE;
785 }
786 }
787 if(!orXYZ)
788 {
789 AliError("Survey text file sintax error: precision column name does not refer to any axis!");
790 return kFALSE;
791 }
792 }
793 } else if (cn.BeginsWith("Point Type", TString::kIgnoreCase)) {
794 orderedValues[4] = &value[j];
795 check[4] = kTRUE;
796 } else if (cn.BeginsWith("Target Used", TString::kIgnoreCase)) {
797 orderedValues[5] = &value[j];
798 check[5] = kTRUE;
799 }
800 }
801
802 // Check if all the mandatory fields exist in the line with column names
803 if(!check[0]){
804 AliError("Missing mandatory column \"Point Name\"!");
805 return kFALSE;
806 }
807 if(!(check[1]&&check[2]&&check[3])){
808 AliError("Missing one or more mandatory columns for coordinates \"X\",\"Y\",\"Z\"");
809 return kFALSE;
810 }
811 if(!check[4]){
812 AliError("Missing mandatory column \"Point Type\"!");
813 return kFALSE;
814 }
815 if(!(check[6]&&check[7]&&check[8])){
816 AliError("Missing one or more mandatory columns for precision along \"X\",\"Y\",\"Z\" axes");
817 return kFALSE;
818 }
819
820 } else if (currLine.BeginsWith("Data", TString::kIgnoreCase)) {
821 // Data section!
822 while ((nextLine.Length() > 0) && ('>' != nextLine[0])) {
823
824 // Printf("Data LINE: \"%s\": %d\n", nextLine.Data(), nextLine.Length());
825
826 // What is the separator used between fields?
827 // The allowed are: comma (','), tab ('\t'), and space (' ')
828 if (fNrColumns == nextLine.CountChar(',') + 1) dataLine = nextLine.Tokenize(',');
829 else if (fNrColumns == nextLine.CountChar('\t') + 1) dataLine = nextLine.Tokenize('\t');
830 else if (fNrColumns == nextLine.CountChar(' ') + 1) dataLine = nextLine.Tokenize(' ');
831 else {
832 // Error (No separator was found!)
833 AliError("Survey text file syntax error! Error processing data line!");
834 lines->Delete();
835 delete lines; lines = NULL;
836 return kFALSE;
837 }
838
839 if (dataLine->GetEntries() != fNrColumns) {
840 // The number of columns doesn't match the number specified in the header
841 AliError("Survey text file sintax error! (Number of entries in line is different from number of Columns)");
842 dataLine->Delete();
843 lines->Delete();
844 delete lines; lines = NULL;
845 return kFALSE;
846 }
847
848 // Process the data line using the column names as index
849 for (Int_t j = 0; j < dataLine->GetEntries(); ++j) {
850 value[j] = ((TObjString *)(dataLine->At(j)))->GetString();
851 }
852 tmpname = *orderedValues[0];
853 tmpx = orderedValues[1]->Atof();
854 tmpy = orderedValues[2]->Atof();
855 tmpz = orderedValues[3]->Atof();
856 tmpprecX = orderedValues[6]->Atof();
857 tmpprecY = orderedValues[7]->Atof();
858 tmpprecZ = orderedValues[8]->Atof();
859 tmptype = orderedValues[4]->Data()[0];
860 if(orderedValues[5]) tmptarg = (orderedValues[5]->Data()[0] == 'Y') ? kTRUE : kFALSE;
861
862 dp = new AliSurveyPoint(tmpname, tmpx, tmpy, tmpz, tmpprecX, tmpprecY, tmpprecZ, tmptype, tmptarg);
863 if(AliLog::GetDebugLevel("","AliSurveyObj")>1) dp->PrintPoint();
864 AddPoint(dp);
865
866 dataLine->Delete();
867 dataLine = NULL;
868 ++i;
869 nextLine = ((i + 1) < nrLines ? ((TObjString *)(lines->At(i + 1)))->GetString().Data() : "");
870 }
871 }
872 } else {
873 AliError("Survey text file sintax error!");
874 lines->Delete();
875 delete lines; lines = NULL;
876 return kFALSE;
877 }
878 }
879 lines->Delete();
880 delete lines; lines = NULL;
881 fIsValid = kTRUE;
882 return kTRUE;
883}
884
885//_____________________________________________________________________________
886void AliSurveyObj::Reset() {
887 // Resets the AliSurveyObj to a clean object.
888 // Used if the same object is filled more than once
889
890 if (fDataPoints) {
891 fDataPoints->Delete();
892 fDataPoints = 0;
893 }
894 fTitle = "";
895 fDate = "";
896 fDetector = "";
897 fURL = "http://edms.cern.ch/";
898 fReportNr = -1;
899 fVersion = -1;
900 fObs = "";
901 fCoordSys = "";
902 fUnits = "";
903 fNrColumns = -1;
904 fColNames = "";
905 fIsValid = kFALSE;
906 fDataPoints = new TObjArray(1);
907 fDataPoints->SetOwner(kTRUE);
908 return;
909}
910