]>
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 | |
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 | 38 | ClassImp(AliSurveyObj) |
75cab1ea | 39 | |
40 | ||
41 | const TString AliSurveyObj::fgkStorage = "alien://alice.cern.ch"; | |
42 | const TString AliSurveyObj::fgkBaseFolder = "/alice/data/Reference"; | |
43 | const TString AliSurveyObj::fgkValidDetectors = "ACORDE,BABYFRAME,BACKFRAME,\ | |
44 | EMCAL,FMD,HMPID,ITS,L3 MAGNET,MUON,MUON ABSORBERS,MUON DIPOLE,PHOS,PMD,\ | |
d2404e52 | 45 | SPACEFRAME,SUPERSTRUCTURE,T0,TOF,TPC,TRD,VZERO,ZDC,GRP"; |
75cab1ea | 46 | const TString AliSurveyObj::fgkGRPDetectors = "BABYFRAME,BACKFRAME,L3 MAGNET,\ |
47 | SPACEFRAME,MUON DIPOLE,MUON ABSORBERS,GRP"; | |
48 | const TString AliSurveyObj::fgkMUONDetectors = "MUON,SUPERSTRUCTURE"; | |
49 | ||
324b1730 | 50 | |
51 | //_____________________________________________________________________________ | |
52 | AliSurveyObj::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 | //_____________________________________________________________________________ | |
75 | AliSurveyObj::~AliSurveyObj() { | |
76 | //destructor | |
adfef030 | 77 | if (fDataPoints) { |
adfef030 | 78 | fDataPoints->Delete(); |
79 | fDataPoints = 0; | |
80 | } | |
324b1730 | 81 | } |
82 | ||
83 | ||
84 | //_____________________________________________________________________________ | |
85 | AliSurveyObj::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 | //_____________________________________________________________________________ |
112 | AliSurveyObj& 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 | //_____________________________________________________________________________ | |
140 | void 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 | //_____________________________________________________________________________ | |
148 | Bool_t AliSurveyObj::Connect(const char *gridUrl, const char *user) { | |
737100a1 | 149 | // Connects to the grid |
324b1730 | 150 | |
737100a1 | 151 | // If the same "Grid" is alreay active, skip connection |
adfef030 | 152 | if (!gGrid || gridUrl != gGrid->GridUrl() || |
153 | (( user != "" ) && ( user != gGrid->GetUser() )) ) { | |
154 | // connection to the Grid | |
155 | AliInfo("\nConnecting to the Grid..."); | |
156 | if (gGrid) { | |
157 | AliInfo(Form("gGrid = %x; GridUrl = %s; gGrid->GridUrl() = %s", | |
158 | gGrid, gridUrl, gGrid->GridUrl())); | |
159 | AliInfo(Form("User = %s; gGrid->GetUser() = %s", | |
160 | user, gGrid->GetUser())); | |
161 | } | |
162 | TGrid::Connect(gridUrl,user); | |
163 | } | |
324b1730 | 164 | |
adfef030 | 165 | if(!gGrid) { |
166 | AliError("Connection failed!"); | |
167 | return kFALSE; | |
168 | } | |
169 | return kTRUE; | |
324b1730 | 170 | } |
171 | ||
172 | ||
324b1730 | 173 | //_____________________________________________________________________________ |
174 | Bool_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 | 212 | Bool_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 | //_____________________________________________________________________________ | |
222 | Bool_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 | //_____________________________________________________________________________ | |
238 | TString 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 | //_____________________________________________________________________________ | |
262 | Bool_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 | //_____________________________________________________________________________ | |
271 | Bool_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 | 339 | TString 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 | //_____________________________________________________________________________ |
357 | Int_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 | //_____________________________________________________________________________ | |
375 | Int_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 | //_____________________________________________________________________________ | |
397 | Int_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 | //_____________________________________________________________________________ | |
419 | void 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 | //_____________________________________________________________________________ | |
452 | TGridResult * 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 | //_____________________________________________________________________________ | |
503 | Int_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 | //_____________________________________________________________________________ | |
541 | void AliSurveyObj::SetGridUser(TString username){ | |
542 | // Set the username used to connect to the GRID | |
543 | fGridUser = username; | |
544 | return; | |
324b1730 | 545 | } |
546 | ||
547 | ||
548 | //_____________________________________________________________________________ | |
549 | TString &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 | //_____________________________________________________________________________ | |
565 | Bool_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 | 872 | void 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 |