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