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