]>
Commit | Line | Data |
---|---|---|
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 | |
324b1730 | 26 | #include "TObjArray.h" |
27 | #include "TGrid.h" | |
75cab1ea | 28 | #include "TGridResult.h" |
324b1730 | 29 | #include "TFile.h" |
30 | #include "TObjString.h" | |
31 | ||
32 | //AliROOT includes | |
33 | #include "AliLog.h" | |
68e43693 | 34 | #include "AliSurveyPoint.h" |
324b1730 | 35 | |
324b1730 | 36 | ClassImp(AliSurveyObj) |
75cab1ea | 37 | |
38 | ||
39 | const TString AliSurveyObj::fgkStorage = "alien://alice.cern.ch"; | |
40 | const TString AliSurveyObj::fgkBaseFolder = "/alice/data/Reference"; | |
41 | const TString AliSurveyObj::fgkValidDetectors = "ACORDE,BABYFRAME,BACKFRAME,\ | |
42 | EMCAL,FMD,HMPID,ITS,L3 MAGNET,MUON,MUON ABSORBERS,MUON DIPOLE,PHOS,PMD,\ | |
d2404e52 | 43 | SPACEFRAME,SUPERSTRUCTURE,T0,TOF,TPC,TRD,VZERO,ZDC,GRP"; |
75cab1ea | 44 | const TString AliSurveyObj::fgkGRPDetectors = "BABYFRAME,BACKFRAME,L3 MAGNET,\ |
45 | SPACEFRAME,MUON DIPOLE,MUON ABSORBERS,GRP"; | |
46 | const TString AliSurveyObj::fgkMUONDetectors = "MUON,SUPERSTRUCTURE"; | |
47 | ||
324b1730 | 48 | |
49 | //_____________________________________________________________________________ | |
50 | AliSurveyObj::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), | |
737100a1 | 64 | fGridUser(""), |
324b1730 | 65 | fDataPoints(new TObjArray(1)) |
66 | { | |
67 | // constructor | |
68 | fDataPoints->SetOwner(kTRUE); | |
69 | } | |
70 | ||
71 | ||
72 | //_____________________________________________________________________________ | |
73 | AliSurveyObj::~AliSurveyObj() { | |
74 | //destructor | |
adfef030 | 75 | if (fDataPoints) { |
adfef030 | 76 | fDataPoints->Delete(); |
77 | fDataPoints = 0; | |
78 | } | |
324b1730 | 79 | } |
80 | ||
81 | ||
82 | //_____________________________________________________________________________ | |
83 | AliSurveyObj::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), | |
737100a1 | 97 | fGridUser(surveyObj.fGridUser), |
324b1730 | 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 | ||
75cab1ea | 108 | |
324b1730 | 109 | //_____________________________________________________________________________ |
110 | AliSurveyObj& 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; | |
737100a1 | 126 | fGridUser = surveyObj.fGridUser; |
324b1730 | 127 | TObject *curr = surveyObj.fDataPoints->First(); |
128 | while (curr != 0) { | |
129 | fDataPoints->Add(curr); | |
130 | curr = surveyObj.fDataPoints->After(curr); | |
131 | } | |
132 | } | |
324b1730 | 133 | return *this; |
134 | } | |
135 | ||
136 | ||
137 | //_____________________________________________________________________________ | |
138 | void AliSurveyObj::AddPoint(AliSurveyPoint* point) { | |
737100a1 | 139 | // Adds a point to the TObjArray which containst the list of points |
324b1730 | 140 | fDataPoints->Add(point); |
141 | return; | |
142 | } | |
143 | ||
144 | ||
145 | //_____________________________________________________________________________ | |
146 | Bool_t AliSurveyObj::Connect(const char *gridUrl, const char *user) { | |
737100a1 | 147 | // Connects to the grid |
324b1730 | 148 | |
737100a1 | 149 | // If the same "Grid" is alreay active, skip connection |
adfef030 | 150 | if (!gGrid || gridUrl != gGrid->GridUrl() || |
f12d42ce | 151 | (( strcmp(user,"") ) && ( strcmp(user,gGrid->GetUser()) )) ) { |
adfef030 | 152 | // connection to the Grid |
153 | AliInfo("\nConnecting to the Grid..."); | |
154 | if (gGrid) { | |
65b25288 | 155 | AliInfo(Form("gGrid = %p; GridUrl = %s; gGrid->GridUrl() = %s", |
adfef030 | 156 | gGrid, gridUrl, gGrid->GridUrl())); |
157 | AliInfo(Form("User = %s; gGrid->GetUser() = %s", | |
158 | user, gGrid->GetUser())); | |
159 | } | |
160 | TGrid::Connect(gridUrl,user); | |
161 | } | |
324b1730 | 162 | |
adfef030 | 163 | if(!gGrid) { |
164 | AliError("Connection failed!"); | |
165 | return kFALSE; | |
166 | } | |
167 | return kTRUE; | |
324b1730 | 168 | } |
169 | ||
170 | ||
324b1730 | 171 | //_____________________________________________________________________________ |
172 | Bool_t AliSurveyObj::OpenFile(TString openString) { | |
737100a1 | 173 | // Opens the file and reads it to a buffer |
324b1730 | 174 | |
a3ba938d | 175 | AliInfo(Form("Opening file \"%s\"\n for survey data", openString.Data())); |
324b1730 | 176 | |
737100a1 | 177 | if (openString.BeginsWith("alien://")) |
75cab1ea | 178 | if (!Connect(fgkStorage.Data(), fGridUser.Data())) { |
737100a1 | 179 | AliError(Form("Error connecting to GRID")); |
180 | return kFALSE; | |
181 | } | |
324b1730 | 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 | ||
737100a1 | 191 | char *buf = new Char_t[size + 1]; |
192 | memset(buf, '\0', size + 1); | |
324b1730 | 193 | |
194 | file->Seek(0); | |
195 | if ( file->ReadBuffer(buf, size) ) { | |
196 | AliError("Error reading file contents to buffer!"); | |
197 | return kFALSE; | |
198 | } | |
73bbf779 | 199 | AliInfo(Form("%lld bytes read!\n", file->GetBytesRead())); |
324b1730 | 200 | |
f6b15a09 | 201 | Bool_t goodParsing = ParseBuffer(buf); |
324b1730 | 202 | |
203 | file->Close(); | |
204 | delete[] buf; | |
f6b15a09 | 205 | return goodParsing; |
324b1730 | 206 | } |
207 | ||
208 | ||
324b1730 | 209 | //_____________________________________________________________________________ |
75cab1ea | 210 | Bool_t AliSurveyObj::FillFromLocalFile(const Char_t* filename) { |
211 | // Fills the object from a file in a local filesystem | |
737100a1 | 212 | |
75cab1ea | 213 | TString fullOpenString = "file://" + TString(filename) + "?filetype=raw"; |
214 | ||
215 | return OpenFile(fullOpenString); | |
216 | } | |
217 | ||
218 | ||
219 | //_____________________________________________________________________________ | |
220 | Bool_t AliSurveyObj::IsValidDetector(TString detector) const { | |
221 | // Checks if the detector name is valid | |
324b1730 | 222 | |
adfef030 | 223 | detector.ToUpper(); |
75cab1ea | 224 | |
225 | TObjArray *dets = fgkValidDetectors.Tokenize(','); | |
226 | TObject *found = dets->FindObject(detector); | |
adfef030 | 227 | dets->Delete(); |
228 | dets = 0; | |
229 | ||
75cab1ea | 230 | if (!found) return kFALSE; |
231 | else return kTRUE; | |
232 | } | |
233 | ||
234 | ||
235 | //_____________________________________________________________________________ | |
236 | TString AliSurveyObj::RealFolderName(TString detector) const { | |
237 | // Returns the actual folder name for a given detector | |
737100a1 | 238 | // Some "detectors" don't have a folder of their own |
75cab1ea | 239 | |
240 | detector.ToUpper(); | |
241 | TString folderName = detector; | |
242 | ||
243 | TObjArray *dets = fgkGRPDetectors.Tokenize(','); | |
244 | if (dets->FindObject(detector)) folderName = "GRP"; | |
adfef030 | 245 | dets->Delete(); |
246 | dets = 0; | |
247 | ||
75cab1ea | 248 | dets = fgkMUONDetectors.Tokenize(','); |
249 | if (dets->FindObject(detector)) folderName = "MUON"; | |
250 | dets->Delete(); | |
251 | ||
252 | ||
253 | ||
adfef030 | 254 | dets = 0; |
255 | ||
75cab1ea | 256 | return folderName; |
257 | } | |
258 | ||
259 | //_____________________________________________________________________________ | |
260 | Bool_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 | //_____________________________________________________________________________ | |
269 | Bool_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 | ||
737100a1 | 285 | // Check if <year>, <reportNumber> and <reportVersion> are valid (roughly) |
75cab1ea | 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)); | |
adfef030 | 307 | return kFALSE; |
308 | } | |
324b1730 | 309 | |
75cab1ea | 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 | /* | |
737100a1 | 327 | // Finally composes the full string |
75cab1ea | 328 | TString fullOpenString = "alien://" + fgkBaseFolder + "/" + detectorFolder + "/RawSurvey/"; |
adfef030 | 329 | fullOpenString += Form("%d/%d_v%d.txt?filetype=raw", year, reportNumber, reportVersion); |
75cab1ea | 330 | */ |
737100a1 | 331 | |
324b1730 | 332 | return OpenFile(fullOpenString); |
333 | } | |
334 | ||
335 | ||
336 | //_____________________________________________________________________________ | |
75cab1ea | 337 | TString 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 | } | |
737100a1 | 351 | |
75cab1ea | 352 | ///alice/cern.ch/user/r/rsilva/TRD/RawSurvey/2007/.816582_v2.txt/v1.0 |
324b1730 | 353 | |
75cab1ea | 354 | //_____________________________________________________________________________ |
355 | Int_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 | //_____________________________________________________________________________ | |
373 | Int_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 | //_____________________________________________________________________________ | |
395 | Int_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 | //_____________________________________________________________________________ | |
417 | void AliSurveyObj::ListValidDetectors() { | |
a3ba938d | 418 | // List the valid detector names |
a3ba938d | 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; | |
a3ba938d | 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; | |
a3ba938d | 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; | |
75cab1ea | 442 | } |
443 | ||
444 | ||
445 | //_____________________________________________________________________________ | |
446 | TGridResult * 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 | ||
a3ba938d | 481 | AliInfo(Form("\nLooking for: %s \n", lsArg.Data())); |
75cab1ea | 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 | //_____________________________________________________________________________ | |
496 | Int_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) { | |
a7307087 | 513 | Printf("%d reports found:", numberEntries); |
75cab1ea | 514 | for (int i = 0; i < res->GetEntries(); ++i) { |
515 | fn = res->GetFileNamePath(i); | |
a7307087 | 516 | Printf("Detector:%s\tYear:%d\tEDMS Report Number:%d\tVersion:%d", |
75cab1ea | 517 | FileNamePathToDetector(fn).Data(), |
518 | FileNamePathToReportYear(fn), | |
519 | FileNamePathToReportNumber(fn), | |
a7307087 | 520 | FileNamePathToReportVersion(fn)); |
75cab1ea | 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 | //_____________________________________________________________________________ | |
533 | void AliSurveyObj::SetGridUser(TString username){ | |
534 | // Set the username used to connect to the GRID | |
535 | fGridUser = username; | |
536 | return; | |
324b1730 | 537 | } |
538 | ||
539 | ||
540 | //_____________________________________________________________________________ | |
541 | TString &AliSurveyObj::Sanitize(TString str) { | |
737100a1 | 542 | // Cleans up a line of new line and carriage return characters. |
543 | // (Specially usefull for files created in Windows.) | |
544 | ||
324b1730 | 545 | str.Remove(TString::kTrailing, '\r'); |
546 | str.Remove(TString::kTrailing, '\n'); | |
573b6a5a | 547 | str.Remove(TString::kTrailing, '\r'); |
a3ba938d | 548 | |
573b6a5a | 549 | if (!str.IsAscii()) { |
550 | AliWarning("Warning: Non-ASCII characters!\n"); | |
551 | str = ""; | |
552 | } | |
324b1730 | 553 | return str.Remove(TString::kBoth, ' '); |
554 | } | |
555 | ||
556 | ||
557 | //_____________________________________________________________________________ | |
558 | Bool_t AliSurveyObj::ParseBuffer(const Char_t* buf) { | |
737100a1 | 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 | |
adfef030 | 563 | if (fIsValid) Reset(); |
564 | ||
737100a1 | 565 | // Copy the buffer to a TString to use Tokenize |
324b1730 | 566 | TString buffer = TString(buf); |
a3ba938d | 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 | ||
737100a1 | 587 | TObjArray *dataLine = NULL; // Used to Tokenize each point/line read |
324b1730 | 588 | TObjArray *colLine = NULL; // Used to Tokenize the column names |
589 | ||
737100a1 | 590 | // Some local variables declarations and initializations |
324b1730 | 591 | const Int_t kFieldCheck = 10; |
2f29b48b | 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; | |
68e43693 | 594 | TString tmpname = ""; |
595 | Float_t tmpx = 0.0, tmpy = 0.0, tmpz = 0.0; | |
2f29b48b | 596 | Float_t tmpprecX = -1., tmpprecY = -1., tmpprecZ = -1.; |
68e43693 | 597 | Char_t tmptype = '\0'; |
598 | Bool_t tmptarg = kTRUE; | |
324b1730 | 599 | AliSurveyPoint *dp = 0; |
2f29b48b | 600 | TString *orderedValues[9] = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}; |
601 | TString value[9]; | |
324b1730 | 602 | |
603 | Int_t nrLines = lines->GetEntries(); | |
604 | Printf("Lines in file: %d\n", nrLines); | |
605 | ||
737100a1 | 606 | // The main cycle, the buffer is parsed a line at a time |
324b1730 | 607 | TString currLine = "", nextLine = ""; |
608 | for (Int_t i = 0; i < nrLines; ++i) { | |
737100a1 | 609 | |
610 | // Get the next line | |
324b1730 | 611 | currLine = ((TObjString *)(lines->At(i)))->GetString().Data(); |
612 | nextLine = ((i + 1) < nrLines ? ((TObjString *)(lines->At(i + 1)))->GetString().Data() : ""); | |
a3ba938d | 613 | // Printf("%d: \"%s\"", i, currLine.Data()); |
614 | // Printf("%d: \"%s\"\n", i+1, nextLine.Data()); | |
324b1730 | 615 | |
737100a1 | 616 | // The line contains a keyword |
a3ba938d | 617 | if (currLine.BeginsWith(">") && !nextLine.BeginsWith(">")) { |
324b1730 | 618 | currLine.Remove(TString::kLeading, '>'); |
619 | currLine.Remove(TString::kTrailing, ':'); | |
620 | currLine.Remove(TString::kBoth, ' '); | |
621 | nextLine.Remove(TString::kBoth, ' '); | |
2f29b48b | 622 | AliDebug(2, Form(" -> field line: \"%s\"\n", currLine.Data())); |
623 | AliDebug(2, Form(" -> value line: \"%s\"\n", nextLine.Data())); | |
324b1730 | 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)) { | |
573b6a5a | 641 | fURL = nextLine; |
324b1730 | 642 | nextLine.Remove(TString::kTrailing, '/'); |
643 | nextLine = nextLine(nextLine.Last('/') + 1, nextLine.Length() - nextLine.Last('/') + 1); | |
573b6a5a | 644 | |
f6b15a09 | 645 | if (!nextLine.IsDigit()) { |
a3ba938d | 646 | AliError("Survey text file sintax error! (incorrectly formatted Report URL)"); |
f6b15a09 | 647 | AliError(Form("Wrong report number string: \"%s\"",nextLine.Data())); |
324b1730 | 648 | lines->Delete(); |
a3ba938d | 649 | delete lines; lines = NULL; |
324b1730 | 650 | return kFALSE; |
651 | } | |
652 | fReportNr = nextLine.Atoi(); | |
573b6a5a | 653 | //Printf(" $$ %d $$\n", fReportNr); |
324b1730 | 654 | ++i; |
737100a1 | 655 | } else { |
a3ba938d | 656 | // URL incorrectly formatted |
657 | AliError("Survey text file sintax error! (incorrectly formatted Report URL)"); | |
324b1730 | 658 | return kFALSE; |
659 | } | |
660 | } else if (currLine.BeginsWith("Version", TString::kIgnoreCase)) { | |
737100a1 | 661 | // Report version |
324b1730 | 662 | if (!nextLine.IsDigit()) { |
663 | lines->Delete(); | |
a3ba938d | 664 | delete lines; lines = NULL; |
665 | AliError("Survey text file sintax error! (incorrectly formatted Report Version)"); | |
324b1730 | 666 | return kFALSE; |
667 | } | |
668 | fVersion = nextLine.Atoi(); | |
669 | ++i; | |
670 | } else if (currLine.BeginsWith("General Observations", TString::kIgnoreCase)) { | |
737100a1 | 671 | // Observations |
324b1730 | 672 | fObs = ""; |
737100a1 | 673 | // Can be more than 1 line. Loop until another keyword is found |
674 | while (('>' != nextLine[0]) && (nextLine.Length() > 0) && (i < nrLines)) { | |
324b1730 | 675 | fObs += (0 == fObs.Length()) ? nextLine : " / " + nextLine; |
676 | ++i; | |
677 | nextLine = ((i + 1) < nrLines ? ((TObjString *)(lines->At(i + 1)))->GetString().Data() : ""); | |
324b1730 | 678 | } |
324b1730 | 679 | } else if (currLine.BeginsWith("Coordinate System", TString::kIgnoreCase)) { |
737100a1 | 680 | // Coordinate System |
324b1730 | 681 | fCoordSys = nextLine; |
682 | ++i; | |
683 | } else if (currLine.BeginsWith("Units", TString::kIgnoreCase)) { | |
737100a1 | 684 | // Measurement Unit |
324b1730 | 685 | fUnits = nextLine; |
686 | ++i; | |
687 | } else if (currLine.BeginsWith("Nr Columns", TString::kIgnoreCase)) { | |
737100a1 | 688 | // Number of columns in the "Data" section |
324b1730 | 689 | if (!nextLine.IsDigit()) { |
690 | lines->Delete(); | |
a3ba938d | 691 | delete lines; lines = NULL; |
692 | AliError("Survey text file sintax error! (incorrectly formatted Number of Columns)"); | |
324b1730 | 693 | return kFALSE; |
694 | } | |
695 | fNrColumns = nextLine.Atoi(); | |
696 | ++i; | |
697 | } else if (currLine.BeginsWith("Column Names", TString::kIgnoreCase)) { | |
737100a1 | 698 | // Column names separated by commas |
324b1730 | 699 | fColNames = nextLine; |
700 | colLine = nextLine.Tokenize(','); | |
701 | if (colLine->GetEntries() != fNrColumns) { | |
573b6a5a | 702 | AliError("Survey text file sintax error! (Declared number of Columns doesn't match number of column names)"); |
324b1730 | 703 | colLine->Delete(); |
704 | lines->Delete(); | |
a3ba938d | 705 | delete lines; lines = NULL; |
324b1730 | 706 | return kFALSE; |
707 | } | |
708 | ++i; | |
2f29b48b | 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]){ | |
a3ba938d | 804 | AliError("Missing mandatory column \"Point Name\"!"); |
2f29b48b | 805 | return kFALSE; |
806 | } | |
807 | if(!(check[1]&&check[2]&&check[3])){ | |
a3ba938d | 808 | AliError("Missing one or more mandatory columns for coordinates \"X\",\"Y\",\"Z\""); |
2f29b48b | 809 | return kFALSE; |
810 | } | |
811 | if(!check[4]){ | |
a3ba938d | 812 | AliError("Missing mandatory column \"Point Type\"!"); |
2f29b48b | 813 | return kFALSE; |
814 | } | |
815 | if(!(check[6]&&check[7]&&check[8])){ | |
a3ba938d | 816 | AliError("Missing one or more mandatory columns for precision along \"X\",\"Y\",\"Z\" axes"); |
2f29b48b | 817 | return kFALSE; |
818 | } | |
819 | ||
324b1730 | 820 | } else if (currLine.BeginsWith("Data", TString::kIgnoreCase)) { |
737100a1 | 821 | // Data section! |
573b6a5a | 822 | while ((nextLine.Length() > 0) && ('>' != nextLine[0])) { |
573b6a5a | 823 | |
737100a1 | 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 (' ') | |
2f29b48b | 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(); | |
a3ba938d | 835 | delete lines; lines = NULL; |
2f29b48b | 836 | return kFALSE; |
837 | } | |
838 | ||
324b1730 | 839 | if (dataLine->GetEntries() != fNrColumns) { |
737100a1 | 840 | // The number of columns doesn't match the number specified in the header |
2f29b48b | 841 | AliError("Survey text file sintax error! (Number of entries in line is different from number of Columns)"); |
324b1730 | 842 | dataLine->Delete(); |
843 | lines->Delete(); | |
a3ba938d | 844 | delete lines; lines = NULL; |
324b1730 | 845 | return kFALSE; |
846 | } | |
847 | ||
737100a1 | 848 | // Process the data line using the column names as index |
324b1730 | 849 | for (Int_t j = 0; j < dataLine->GetEntries(); ++j) { |
2f29b48b | 850 | value[j] = ((TObjString *)(dataLine->At(j)))->GetString(); |
324b1730 | 851 | } |
2f29b48b | 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); | |
a3ba938d | 863 | if(AliLog::GetDebugLevel("","AliSurveyObj")>1) dp->PrintPoint(); |
2f29b48b | 864 | AddPoint(dp); |
324b1730 | 865 | |
324b1730 | 866 | dataLine->Delete(); |
867 | dataLine = NULL; | |
868 | ++i; | |
869 | nextLine = ((i + 1) < nrLines ? ((TObjString *)(lines->At(i + 1)))->GetString().Data() : ""); | |
324b1730 | 870 | } |
871 | } | |
573b6a5a | 872 | } else { |
873 | AliError("Survey text file sintax error!"); | |
324b1730 | 874 | lines->Delete(); |
a3ba938d | 875 | delete lines; lines = NULL; |
324b1730 | 876 | return kFALSE; |
877 | } | |
878 | } | |
879 | lines->Delete(); | |
a3ba938d | 880 | delete lines; lines = NULL; |
324b1730 | 881 | fIsValid = kTRUE; |
882 | return kTRUE; | |
883 | } | |
884 | ||
adfef030 | 885 | //_____________________________________________________________________________ |
737100a1 | 886 | void AliSurveyObj::Reset() { |
887 | // Resets the AliSurveyObj to a clean object. | |
888 | // Used if the same object is filled more than once | |
889 | ||
adfef030 | 890 | if (fDataPoints) { |
adfef030 | 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 |