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