]> git.uio.no Git - u/mrichter/AliRoot.git/blame - STEER/AliSurveyObj.cxx
Setter method added
[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,\
d2404e52 45SPACEFRAME,SUPERSTRUCTURE,T0,TOF,TPC,TRD,VZERO,ZDC,GRP";
75cab1ea 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() ||
f12d42ce 153 (( strcmp(user,"") ) && ( strcmp(user,gGrid->GetUser()) )) ) {
adfef030 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;
2f29b48b 580 Bool_t check[kFieldCheck]; // used to check that mandatory column names are not missing
581 for (Int_t i = 0; i < kFieldCheck; ++i) check[i] = kFALSE;
68e43693 582 TString tmpname = "";
583 Float_t tmpx = 0.0, tmpy = 0.0, tmpz = 0.0;
2f29b48b 584 Float_t tmpprecX = -1., tmpprecY = -1., tmpprecZ = -1.;
68e43693 585 Char_t tmptype = '\0';
586 Bool_t tmptarg = kTRUE;
324b1730 587 AliSurveyPoint *dp = 0;
2f29b48b 588 TString *orderedValues[9] = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};
589 TString value[9];
324b1730 590
591 Int_t nrLines = lines->GetEntries();
592 Printf("Lines in file: %d\n", nrLines);
593
737100a1 594 // The main cycle, the buffer is parsed a line at a time
324b1730 595 TString currLine = "", nextLine = "";
596 for (Int_t i = 0; i < nrLines; ++i) {
737100a1 597
598 // Get the next line
324b1730 599 currLine = ((TObjString *)(lines->At(i)))->GetString().Data();
600 nextLine = ((i + 1) < nrLines ? ((TObjString *)(lines->At(i + 1)))->GetString().Data() : "");
601 currLine = Sanitize(currLine);
602 nextLine = Sanitize(nextLine);
737100a1 603 // Printf("\n%d: \"\"%s\"\"\"\n", i + 1, currLine.Data());
324b1730 604
737100a1 605 // Skip empty line
606 if (0 == currLine.Length()) Printf("Info: Empty line skipped\n\n");
607
608 // The line contains a keyword
609 else if (currLine.BeginsWith(">") && !nextLine.BeginsWith(">")) {
324b1730 610 currLine.Remove(TString::kLeading, '>');
611 currLine.Remove(TString::kTrailing, ':');
612 currLine.Remove(TString::kBoth, ' ');
613 nextLine.Remove(TString::kBoth, ' ');
2f29b48b 614 AliDebug(2, Form(" -> field line: \"%s\"\n", currLine.Data()));
615 AliDebug(2, Form(" -> value line: \"%s\"\n", nextLine.Data()));
324b1730 616
617 if (currLine.BeginsWith("Title", TString::kIgnoreCase)) {
618 // Report Title
619 fTitle = nextLine;
620 ++i;
621 } else if (currLine.BeginsWith("Date", TString::kIgnoreCase)) {
622 // Report(measurement) Date
623 fDate = nextLine;
624 ++i;
625 } else if (currLine.BeginsWith("Subdetector", TString::kIgnoreCase)) {
626 // Subdetector or structure
627 fDetector = nextLine;
628 ++i;
629 } else if (currLine.BeginsWith("Report URL", TString::kIgnoreCase)) {
630 // Report URL in EDMS
631 if (nextLine.BeginsWith("http://edms.cern.ch/document/", TString::kIgnoreCase) ||
632 nextLine.BeginsWith("https://edms.cern.ch/document/", TString::kIgnoreCase)) {
573b6a5a 633 fURL = nextLine;
324b1730 634 nextLine.Remove(TString::kTrailing, '/');
635 nextLine = nextLine(nextLine.Last('/') + 1, nextLine.Length() - nextLine.Last('/') + 1);
573b6a5a 636
68e43693 637 Int_t sscanftmp = 0;
638 if (1 != sscanf(nextLine.Data(), "%d", &sscanftmp)) {
573b6a5a 639 AliError("Survey text file sintax error! (incorrectly formated Report URL)");
324b1730 640 lines->Delete();
641 return kFALSE;
642 }
643 fReportNr = nextLine.Atoi();
573b6a5a 644 //Printf(" $$ %d $$\n", fReportNr);
324b1730 645 ++i;
737100a1 646 } else {
647 // URL incorrectly formated
324b1730 648 AliError("Survey text file sintax error! (incorrectly formated Report URL)");
649 return kFALSE;
650 }
651 } else if (currLine.BeginsWith("Version", TString::kIgnoreCase)) {
737100a1 652 // Report version
324b1730 653 if (!nextLine.IsDigit()) {
654 lines->Delete();
573b6a5a 655 AliError("Survey text file sintax error! (incorrectly formated Report Version)");
324b1730 656 return kFALSE;
657 }
658 fVersion = nextLine.Atoi();
659 ++i;
660 } else if (currLine.BeginsWith("General Observations", TString::kIgnoreCase)) {
737100a1 661 // Observations
324b1730 662 fObs = "";
737100a1 663 // Can be more than 1 line. Loop until another keyword is found
664 while (('>' != nextLine[0]) && (nextLine.Length() > 0) && (i < nrLines)) {
324b1730 665 fObs += (0 == fObs.Length()) ? nextLine : " / " + nextLine;
666 ++i;
667 nextLine = ((i + 1) < nrLines ? ((TObjString *)(lines->At(i + 1)))->GetString().Data() : "");
668 nextLine = Sanitize(nextLine);
669 }
324b1730 670 } else if (currLine.BeginsWith("Coordinate System", TString::kIgnoreCase)) {
737100a1 671 // Coordinate System
324b1730 672 fCoordSys = nextLine;
673 ++i;
674 } else if (currLine.BeginsWith("Units", TString::kIgnoreCase)) {
737100a1 675 // Measurement Unit
324b1730 676 fUnits = nextLine;
677 ++i;
678 } else if (currLine.BeginsWith("Nr Columns", TString::kIgnoreCase)) {
737100a1 679 // Number of columns in the "Data" section
324b1730 680 if (!nextLine.IsDigit()) {
681 lines->Delete();
573b6a5a 682 AliError("Survey text file sintax error! (incorrectly formated Number of Columns)");
324b1730 683 return kFALSE;
684 }
685 fNrColumns = nextLine.Atoi();
686 ++i;
687 } else if (currLine.BeginsWith("Column Names", TString::kIgnoreCase)) {
737100a1 688 // Column names separated by commas
324b1730 689 fColNames = nextLine;
690 colLine = nextLine.Tokenize(',');
691 if (colLine->GetEntries() != fNrColumns) {
573b6a5a 692 AliError("Survey text file sintax error! (Declared number of Columns doesn't match number of column names)");
324b1730 693 colLine->Delete();
694 lines->Delete();
695 return kFALSE;
696 }
697 ++i;
2f29b48b 698
699 // booleans to track if precision for 1 axis is defined in more than one column
700 Bool_t prX = kFALSE;
701 Bool_t prY = kFALSE;
702 Bool_t prZ = kFALSE;
703
704 for (Int_t j = 0; j < fNrColumns; ++j) {
705 TString cn = ((TObjString *)(colLine->At(j)))->GetString();
706 if (cn.BeginsWith("Point Name", TString::kIgnoreCase)) {
707 orderedValues[0] = &value[j];
708 check[0] = kTRUE;
709 } else if (cn.BeginsWith("X", TString::kIgnoreCase)) {
710 orderedValues[1] = &value[j];
711 check[1] = kTRUE;
712 } else if (cn.BeginsWith("Y", TString::kIgnoreCase)) {
713 orderedValues[2] = &value[j];
714 check[2] = kTRUE;
715 } else if (cn.BeginsWith("Z", TString::kIgnoreCase)) {
716 orderedValues[3] = &value[j];
717 check[3] = kTRUE;
718 } else if (cn.BeginsWith("Precision", TString::kIgnoreCase)) {
719 TString tmpCN = cn(0, cn.First('('));
720 Int_t precLength = TString("Precision").Length();
721 if (precLength == tmpCN.Length()) {
722 if(!orderedValues[6]){
723 orderedValues[6] = &value[j];
724 check[6] = kTRUE;
725 }else{
726 AliWarning("Global precision will not be used for X axis");
727 }
728 if(!orderedValues[7]){
729 orderedValues[7] = &value[j];
730 check[7] = kTRUE;
731 }else{
732 AliWarning("Global precision will not be used for Y axis");
733 }
734 if(!orderedValues[8]){
735 orderedValues[8] = &value[j];
736 check[8] = kTRUE;
737 }else{
738 AliWarning("Global precision will not be used for Z axis");
739 }
740 } else {
741 Bool_t orXYZ = kFALSE;
742 TString axis = cn(precLength, tmpCN.Length() - precLength);
743 if (axis.Contains('X', TString::kIgnoreCase)) {
744 if(!prX){
745 orderedValues[6] = &value[j];
746 check[6] = kTRUE;
747 orXYZ = kTRUE;
748 prX = kTRUE;
749 }else{
750 AliError("Precision for X axis was already set!");
751 return kFALSE;
752 }
753 }
754 if (axis.Contains('Y', TString::kIgnoreCase)) {
755 if(!prY){
756 orderedValues[7] = &value[j];
757 check[7] = kTRUE;
758 orXYZ = kTRUE;
759 prY = kTRUE;
760 }else{
761 AliError("Precision for Y axis was already set!");
762 return kFALSE;
763 }
764 }
765 if (axis.Contains('Z', TString::kIgnoreCase)) {
766 if(!prZ){
767 orderedValues[8] = &value[j];
768 check[8] = kTRUE;
769 orXYZ = kTRUE;
770 prZ = kTRUE;
771 }else{
772 AliError("Precision for Z axis was already set!");
773 return kFALSE;
774 }
775 }
776 if(!orXYZ)
777 {
778 AliError("Survey text file sintax error: precision column name does not refer to any axis!");
779 return kFALSE;
780 }
781 }
782 } else if (cn.BeginsWith("Point Type", TString::kIgnoreCase)) {
783 orderedValues[4] = &value[j];
784 check[4] = kTRUE;
785 } else if (cn.BeginsWith("Target Used", TString::kIgnoreCase)) {
786 orderedValues[5] = &value[j];
787 check[5] = kTRUE;
788 }
789 }
790
791 // Check if all the mandatory fields exist in the line with column names
792 if(!check[0]){
793 Printf("Missing mandatory column \"Point Name\"!");
794 return kFALSE;
795 }
796 if(!(check[1]&&check[2]&&check[3])){
797 Printf("Missing one or more mandatory columns for coordinates \"X\",\"Y\",\"Z\"");
798 return kFALSE;
799 }
800 if(!check[4]){
801 Printf("Missing mandatory column \"Point Type\"!");
802 return kFALSE;
803 }
804 if(!(check[6]&&check[7]&&check[8])){
805 Printf("Missing one or more mandatory columns for precision along \"X\",\"Y\",\"Z\" axes");
806 return kFALSE;
807 }
808
324b1730 809 } else if (currLine.BeginsWith("Data", TString::kIgnoreCase)) {
737100a1 810 // Data section!
573b6a5a 811 while ((nextLine.Length() > 0) && ('>' != nextLine[0])) {
573b6a5a 812
737100a1 813 // Printf("Data LINE: \"%s\": %d\n", nextLine.Data(), nextLine.Length());
814
815 // What is the separator used between fields?
816 // The allowed are: comma (','), tab ('\t'), and space (' ')
2f29b48b 817 if (fNrColumns == nextLine.CountChar(',') + 1) dataLine = nextLine.Tokenize(',');
818 else if (fNrColumns == nextLine.CountChar('\t') + 1) dataLine = nextLine.Tokenize('\t');
819 else if (fNrColumns == nextLine.CountChar(' ') + 1) dataLine = nextLine.Tokenize(' ');
820 else {
821 // Error (No separator was found!)
822 AliError("Survey text file syntax error! Error processing data line!");
823 lines->Delete();
824 return kFALSE;
825 }
826
324b1730 827 if (dataLine->GetEntries() != fNrColumns) {
737100a1 828 // The number of columns doesn't match the number specified in the header
2f29b48b 829 AliError("Survey text file sintax error! (Number of entries in line is different from number of Columns)");
324b1730 830 dataLine->Delete();
831 lines->Delete();
832 return kFALSE;
833 }
834
737100a1 835 // Process the data line using the column names as index
324b1730 836 for (Int_t j = 0; j < dataLine->GetEntries(); ++j) {
2f29b48b 837 value[j] = ((TObjString *)(dataLine->At(j)))->GetString();
324b1730 838 }
2f29b48b 839 tmpname = *orderedValues[0];
840 tmpx = orderedValues[1]->Atof();
841 tmpy = orderedValues[2]->Atof();
842 tmpz = orderedValues[3]->Atof();
843 tmpprecX = orderedValues[6]->Atof();
844 tmpprecY = orderedValues[7]->Atof();
845 tmpprecZ = orderedValues[8]->Atof();
846 tmptype = orderedValues[4]->Data()[0];
847 if(orderedValues[5]) tmptarg = (orderedValues[5]->Data()[0] == 'Y') ? kTRUE : kFALSE;
848
849 dp = new AliSurveyPoint(tmpname, tmpx, tmpy, tmpz, tmpprecX, tmpprecY, tmpprecZ, tmptype, tmptarg);
850 dp->PrintPoint();
851 AddPoint(dp);
324b1730 852
324b1730 853 dataLine->Delete();
854 dataLine = NULL;
855 ++i;
856 nextLine = ((i + 1) < nrLines ? ((TObjString *)(lines->At(i + 1)))->GetString().Data() : "");
857 nextLine = Sanitize(nextLine);
858 }
859 }
573b6a5a 860 } else {
861 AliError("Survey text file sintax error!");
324b1730 862 lines->Delete();
863 return kFALSE;
864 }
865 }
866 lines->Delete();
867 fIsValid = kTRUE;
868 return kTRUE;
869}
870
adfef030 871//_____________________________________________________________________________
737100a1 872void AliSurveyObj::Reset() {
873 // Resets the AliSurveyObj to a clean object.
874 // Used if the same object is filled more than once
875
adfef030 876 if (fDataPoints) {
adfef030 877 fDataPoints->Delete();
878 fDataPoints = 0;
879 }
880 fTitle = "";
881 fDate = "";
882 fDetector = "";
883 fURL = "http://edms.cern.ch/";
884 fReportNr = -1;
885 fVersion = -1;
886 fObs = "";
887 fCoordSys = "";
888 fUnits = "";
889 fNrColumns = -1;
890 fColNames = "";
891 fIsValid = kFALSE;
892 fDataPoints = new TObjArray(1);
893 fDataPoints->SetOwner(kTRUE);
894 return;
895}
896