1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 Revision 1.14 2006/08/29 09:16:05 jgrosseo
21 Revision 1.13 2006/08/15 10:50:00 jgrosseo
22 effc++ corrections (alberto)
24 Revision 1.12 2006/08/08 14:19:29 jgrosseo
25 Update to shuttle classes (Alberto)
27 - Possibility to set the full object's path in the Preprocessor's and
28 Shuttle's Store functions
29 - Possibility to extend the object's run validity in the same classes
30 ("startValidity" and "validityInfinite" parameters)
31 - Implementation of the StoreReferenceData function to store reference
32 data in a dedicated CDB storage.
34 Revision 1.11 2006/07/21 07:37:20 jgrosseo
35 last run is stored after each run
37 Revision 1.10 2006/07/20 09:54:40 jgrosseo
38 introducing status management: The processing per subdetector is divided into several steps,
39 after each step the status is stored on disk. If the system crashes in any of the steps the Shuttle
40 can keep track of the number of failures and skips further processing after a certain threshold is
41 exceeded. These thresholds can be configured in LDAP.
43 Revision 1.9 2006/07/19 10:09:55 jgrosseo
44 new configuration, accesst to DAQ FES (Alberto)
46 Revision 1.8 2006/07/11 12:44:36 jgrosseo
47 adding parameters for extended validity range of data produced by preprocessor
49 Revision 1.7 2006/07/10 14:37:09 jgrosseo
50 small fix + todo comment
52 Revision 1.6 2006/07/10 13:01:41 jgrosseo
53 enhanced storing of last sucessfully processed run (alberto)
55 Revision 1.5 2006/07/04 14:59:57 jgrosseo
56 revision of AliDCSValue: Removed wrapper classes, reduced storage size per value by factor 2
58 Revision 1.4 2006/06/12 09:11:16 jgrosseo
59 coding conventions (Alberto)
61 Revision 1.3 2006/06/06 14:26:40 jgrosseo
62 o) removed files that were moved to STEER
63 o) shuttle updated to follow the new interface (Alberto)
65 Revision 1.2 2006/03/07 07:52:34 hristov
66 New version (B.Yordanov)
68 Revision 1.6 2005/11/19 17:19:14 byordano
69 RetrieveDATEEntries and RetrieveConditionsData added
71 Revision 1.5 2005/11/19 11:09:27 byordano
72 AliShuttle declaration added
74 Revision 1.4 2005/11/17 17:47:34 byordano
75 TList changed to TObjArray
77 Revision 1.3 2005/11/17 14:43:23 byordano
80 Revision 1.1.1.1 2005/10/28 07:33:58 hristov
81 Initial import as subdirectory in AliRoot
83 Revision 1.2 2005/09/13 08:41:15 byordano
84 default startTime endTime added
86 Revision 1.4 2005/08/30 09:13:02 byordano
89 Revision 1.3 2005/08/29 21:15:47 byordano
95 // This class is the main manager for AliShuttle.
96 // It organizes the data retrieval from DCS and call the
97 // interface methods of AliPreprocessor.
98 // For every detector in AliShuttleConfgi (see AliShuttleConfig),
99 // data for its set of aliases is retrieved. If there is registered
100 // AliPreprocessor for this detector then it will be used
101 // accroding to the schema (see AliPreprocessor).
102 // If there isn't registered AliPreprocessor than the retrieved
103 // data is stored automatically to the undelying AliCDBStorage.
104 // For detSpec is used the alias name.
107 #include "AliShuttle.h"
109 #include "AliCDBManager.h"
110 #include "AliCDBStorage.h"
111 #include "AliCDBId.h"
112 #include "AliCDBRunRange.h"
113 #include "AliCDBPath.h"
114 #include "AliCDBEntry.h"
115 #include "AliShuttleConfig.h"
116 #include "AliDCSClient.h"
118 #include "AliPreprocessor.h"
119 #include "AliShuttleStatus.h"
120 #include "AliShuttleLogbookEntry.h"
125 #include <TTimeStamp.h>
126 #include <TObjString.h>
127 #include <TSQLServer.h>
128 #include <TSQLResult.h>
135 TString AliShuttle::fgkMainCDB("alien://folder=ShuttleCDB");
136 TString AliShuttle::fgkLocalCDB("local://LocalShuttleCDB");
137 TString AliShuttle::fgkMainRefStorage("alien://folder=ShuttleReference");
138 TString AliShuttle::fgkLocalRefStorage("local://LocalReferenceStorage");
140 Bool_t AliShuttle::fgkProcessDCS(kTRUE);
143 const char* AliShuttle::fgkShuttleTempDir = gSystem->ExpandPathName("$ALICE_ROOT/SHUTTLE/temp");
144 const char* AliShuttle::fgkShuttleLogDir = gSystem->ExpandPathName("$ALICE_ROOT/SHUTTLE/log");
146 const char* AliShuttle::fgkDetectorName[AliShuttle::kNDetectors] = {"SPD", "SDD", "SSD", "TPC", "TRD", "TOF",
147 "PHOS", "CPV", "RICH", "EMCAL", "MUON_TRK", "MUON_TRG", "FMD", "ZDC", "PMD", "START", "VZERO"};
149 const char* AliShuttle::fgkDetectorCode[AliShuttle::kNDetectors] = {"SPD", "SDD", "SSD", "TPC", "TRD", "TOF",
150 "PHS", "CPV", "HMP", "EMC", "MCH", "MTR", "FMD", "ZDC", "PMD", "T00", "V00"};
152 //______________________________________________________________________________________________
153 AliShuttle::AliShuttle(const AliShuttleConfig* config,
154 UInt_t timeout, Int_t retries):
156 fTimeout(timeout), fRetries(retries),
159 fCurrentDetector(""),
164 // config: AliShuttleConfig used
165 // timeout: timeout used for AliDCSClient connection
166 // retries: the number of retries in case of connection error.
169 if (!fConfig->IsValid()) AliFatal("********** !!!!! Invalid configuration !!!!! **********");
170 for(int iSys=0;iSys<3;iSys++) {
172 fFESlist[iSys].SetOwner(kTRUE);
174 fPreprocessorMap.SetOwner(kTRUE);
177 //______________________________________________________________________
178 AliShuttle::AliShuttle(const AliShuttle& /*other*/):
179 AliShuttleInterface(),
181 fTimeout(0), fRetries(0),
184 fCurrentDetector(""),
188 // copy constructor (not implemented)
192 //______________________________________________________________________
193 AliShuttle &AliShuttle::operator=(const AliShuttle& /*other*/)
195 // assignment operator (not implemented)
200 //______________________________________________________________________________________________
201 AliShuttle::~AliShuttle()
205 fPreprocessorMap.DeleteAll();
206 for(int iSys=0;iSys<3;iSys++)
208 fServer[iSys]->Close();
209 delete fServer[iSys];
218 //______________________________________________________________________________________________
219 void AliShuttle::RegisterPreprocessor(AliPreprocessor* preprocessor)
222 // Registers new AliPreprocessor.
223 // It uses GetName() for indentificator of the pre processor.
224 // The pre processor is registered it there isn't any other
225 // with the same identificator (GetName()).
228 if (fPreprocessorMap.GetValue(preprocessor->GetName())) {
229 AliWarning(Form("AliPreprocessor %s is already registered!",
230 preprocessor->GetName()));
234 fPreprocessorMap.Add(new TObjString(preprocessor->GetName()), preprocessor);
236 //______________________________________________________________________________________________
237 UInt_t AliShuttle::Store(const AliCDBPath& path, TObject* object,
238 AliCDBMetaData* metaData, Int_t validityStart, Bool_t validityInfinite)
240 // Stores a CDB object in the storage for offline reconstruction. Objects that are not needed for
241 // offline reconstruction, but should be stored anyway (e.g. for debugging) should NOT be stored
242 // using this function. Use StoreReferenceData instead!
243 // It calls WriteToCDB function which perform actual storage
245 return WriteToCDB(fgkMainCDB, fgkLocalCDB, path, object,
246 metaData, validityStart, validityInfinite);
250 //______________________________________________________________________________________________
251 UInt_t AliShuttle::StoreReferenceData(const AliCDBPath& path, TObject* object,
252 AliCDBMetaData* metaData, Int_t validityStart, Bool_t validityInfinite)
254 // Stores a CDB object in the storage for reference data. This objects will not be available during
255 // offline reconstrunction. Use this function for reference data only!
256 // It calls WriteToCDB function which perform actual storage
258 return WriteToCDB(fgkMainRefStorage, fgkLocalRefStorage, path, object,
259 metaData, validityStart, validityInfinite);
263 //______________________________________________________________________________________________
264 UInt_t AliShuttle::WriteToCDB(const char* mainUri, const char* localUri,
265 const AliCDBPath& path, TObject* object, AliCDBMetaData* metaData,
266 Int_t validityStart, Bool_t validityInfinite)
268 // write object into the CDB. Parameters are passed by Store and StoreReferenceData functions.
269 // The parameters are:
270 // 1) Uri of the main storage (Grid)
271 // 2) Uri of the backup storage (Local)
272 // 3) the object's path.
273 // 4) the object to be stored
274 // 5) the metaData to be associated with the object
275 // 6) the validity start run number w.r.t. the current run,
276 // if the data is valid only for this run leave the default 0
277 // 7) specifies if the calibration data is valid for infinity (this means until updated),
278 // typical for calibration runs, the default is kFALSE
281 // 1 if stored in main (Grid) storage
282 // 2 if stored in backup (Local) storage
284 const char* cdbType = (mainUri == fgkMainCDB) ? "CDB" : "Reference";
286 Int_t firstRun = GetCurrentRun() - validityStart;
288 AliError("First valid run happens to be less than 0! Setting it to 0.");
293 if(validityInfinite) {
294 lastRun = AliCDBRunRange::Infinity();
296 lastRun = GetCurrentRun();
299 AliCDBId id(path, firstRun, lastRun, -1, -1);
301 if(! dynamic_cast<TObjString*> (metaData->GetProperty("RunUsed(TObjString)"))){
302 TObjString runUsed = Form("%d", GetCurrentRun());
303 metaData->SetProperty("RunUsed(TObjString)",&runUsed);
308 if (!(AliCDBManager::Instance()->GetStorage(mainUri))) {
309 AliError(Form("WriteToCDB - Cannot activate main %s storage", cdbType));
311 result = (UInt_t) AliCDBManager::Instance()->GetStorage(mainUri)
312 ->Put(object, id, metaData);
317 Log(fCurrentDetector,
318 Form("WriteToCDB - Problem with main %s storage. Putting <%s> into backup storage",
319 cdbType, path.GetPath().Data()));
321 // Set Grid version to current run number, to ease retrieval later
322 id.SetVersion(GetCurrentRun());
324 result = AliCDBManager::Instance()->GetStorage(localUri)
325 ->Put(object, id, metaData);
331 Log(fCurrentDetector, "WriteToCDB - Can't store data!");
339 //______________________________________________________________________________________________
340 AliShuttleStatus* AliShuttle::ReadShuttleStatus()
342 // Reads the AliShuttleStatus from the CDB
349 fStatusEntry = AliCDBManager::Instance()->GetStorage(AliShuttle::GetLocalCDB())
350 ->Get(Form("/SHUTTLE/STATUS/%s", fCurrentDetector.Data()), GetCurrentRun());
352 if (!fStatusEntry) return 0;
353 fStatusEntry->SetOwner(1);
355 AliShuttleStatus* status = dynamic_cast<AliShuttleStatus*> (fStatusEntry->GetObject());
357 AliError("Invalid object stored to CDB!");
364 //______________________________________________________________________________________________
365 Bool_t AliShuttle::WriteShuttleStatus(AliShuttleStatus* status)
367 // writes the status for one subdetector
374 Int_t run = GetCurrentRun();
376 AliCDBId id(AliCDBPath("SHUTTLE", "STATUS", fCurrentDetector), run, run);
378 fStatusEntry = new AliCDBEntry(status, id, new AliCDBMetaData);
379 fStatusEntry->SetOwner(1);
381 UInt_t result = AliCDBManager::Instance()->GetStorage(fgkLocalCDB)->Put(fStatusEntry);
384 AliError(Form("WriteShuttleStatus for %s, run %d failed", fCurrentDetector.Data(), run));
391 //______________________________________________________________________________________________
392 void AliShuttle::UpdateShuttleStatus(AliShuttleStatus::Status newStatus, Bool_t increaseCount)
394 // changes the AliShuttleStatus for the given detector and run to the given status
397 AliError("UNEXPECTED: fStatusEntry empty");
401 AliShuttleStatus* status = dynamic_cast<AliShuttleStatus*> (fStatusEntry->GetObject());
404 AliError("UNEXPECTED: status could not be read from current CDB entry");
408 Log("SHUTTLE", Form("UpdateShuttleStatus - %s: Changing state from %s to %s", fCurrentDetector.Data(),
409 status->GetStatusName(), status->GetStatusName(newStatus)));
411 status->SetStatus(newStatus);
412 if (increaseCount) status->IncreaseCount();
414 AliCDBManager::Instance()->GetStorage(fgkLocalCDB)->Put(fStatusEntry);
416 //______________________________________________________________________________________________
417 Bool_t AliShuttle::ContinueProcessing()
419 // this function reads the AliShuttleStatus information from CDB and
420 // checks if the processing should be continued
421 // if yes it returns kTRUE and updates the AliShuttleStatus with nextStatus
423 if(!GetDetCode(fCurrentDetector)) {
424 Log("SHUTTLE", Form("ContinueProcessing - %s: unknown detector",
425 fCurrentDetector.Data()));
429 AliShuttleLogbookEntry::Status entryStatus =
430 fLogbookEntry->GetDetectorStatus(GetDetCode(fCurrentDetector));
432 if(entryStatus != AliShuttleLogbookEntry::kUnprocessed) {
433 Log("SHUTTLE", Form("ContinueProcessing - %s is already %s",
434 fCurrentDetector.Data(),
435 fLogbookEntry->GetDetectorStatusName(entryStatus)));
439 // if we get here, according to Shuttle logbook subdetector is in UNPROCESSED state
440 AliShuttleStatus* status = ReadShuttleStatus();
443 Log("SHUTTLE", Form("ContinueProcessing - %s: Processing first time",
444 fCurrentDetector.Data()));
445 status = new AliShuttleStatus(AliShuttleStatus::kStarted);
446 return WriteShuttleStatus(status);
449 // The following two cases shouldn't happen if Shuttle Logbook was correctly updated.
450 // If it happens it may mean Logbook updating failed... let's do it now!
451 if (status->GetStatus() == AliShuttleStatus::kDone ||
452 status->GetStatus() == AliShuttleStatus::kFailed){
453 Log("SHUTTLE", Form("ContinueProcessing - %s is already %s. Updating Shuttle Logbook",
454 fCurrentDetector.Data(),
455 status->GetStatusName(status->GetStatus())));
456 UpdateShuttleLogbook(fCurrentDetector.Data(),
457 status->GetStatusName(status->GetStatus()));
461 if (status->GetStatus() == AliShuttleStatus::kStoreFailed) {
463 Form("ContinueProcessing - %s: Grid storage of one or more objects failed. Trying again now",
464 fCurrentDetector.Data()));
465 if(TryToStoreAgain()){
466 Log(fCurrentDetector.Data(), "ContinueProcessing - All objects successfully stored into OCDB");
467 UpdateShuttleStatus(AliShuttleStatus::kDone);
468 UpdateShuttleLogbook(fCurrentDetector.Data(), "DONE");
471 Form("ContinueProcessing - %s: Grid storage failed again",
472 fCurrentDetector.Data()));
477 // if we get here, there is a restart
480 // TODO we should add two counters, one for PP and one for DCS!
481 if ((status->GetStatus() == AliShuttleStatus::kPPStarted ||
482 status->GetStatus() == AliShuttleStatus::kPPError) &&
483 (status->GetCount() >= fConfig->GetMaxPPRetries() ||
484 status->GetCount() >= fConfig->GetMaxRetries())) {
486 Form("ContinueProcessing - %s failed %d times in status %s - Updating Shuttle Logbook",
487 fCurrentDetector.Data(),
488 status->GetCount(), status->GetStatusName()));
489 UpdateShuttleLogbook(fCurrentDetector.Data(), "FAILED");
493 Log("SHUTTLE", Form("ContinueProcessing - %s: restarting. Got stuck before in %s. Retry number %d.",
494 fCurrentDetector.Data(),
495 status->GetStatusName(), status->GetCount()));
497 UpdateShuttleStatus(AliShuttleStatus::kStarted);
502 //______________________________________________________________________________________________
503 Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry)
506 // Makes data retrieval for all detectors in the configuration.
507 // entry: Shuttle logbook entry, contains run paramenters and status of detectors
508 // (Unprocessed, Inactive, Failed or Done).
509 // Returns kFALSE in case of error occured and kTRUE otherwise
512 if(!entry) return kFALSE;
514 fLogbookEntry = entry;
516 if(fLogbookEntry->IsDone()){
517 Log("SHUTTLE","Process - Shuttle is already DONE. Updating logbook");
518 UpdateShuttleLogbook("shuttle_done");
524 AliInfo(Form("\n\n \t\t\t^*^*^*^*^*^*^*^*^*^*^*^* run %d: START ^*^*^*^*^*^*^*^*^*^*^*^* \n",
527 fLogbookEntry->Print("");
530 Bool_t hasError = kFALSE;
531 for(Int_t iSys=0;iSys<3;iSys++) fFESCalled[iSys]=kFALSE;
533 AliCDBStorage *mainCDBSto = AliCDBManager::Instance()->GetStorage(fgkMainCDB);
534 if(mainCDBSto) mainCDBSto->QueryCDB(GetCurrentRun());
535 AliCDBStorage *mainRefSto = AliCDBManager::Instance()->GetStorage(fgkMainRefStorage);
536 if(mainRefSto) mainRefSto->QueryCDB(GetCurrentRun());
538 // Loop on detectors in the configuration
539 TIter iter(fConfig->GetDetectors());
540 TObjString* aDetector = 0;
542 while ((aDetector = (TObjString*) iter.Next())) {
543 fCurrentDetector = aDetector->String();
545 if (!fConfig->HostProcessDetector(fCurrentDetector)) continue;
547 AliPreprocessor* aPreprocessor =
548 dynamic_cast<AliPreprocessor*> (fPreprocessorMap.GetValue(fCurrentDetector));
550 Log("SHUTTLE",Form("Process - %s: no preprocessor registered. Skipping"));
554 if (ContinueProcessing() == kFALSE) continue;
556 AliInfo(Form("\n\n \t\t\t****** run %d - %s: START ******",
557 GetCurrentRun(), aDetector->GetName()));
559 UInt_t result = ProcessCurrentDetector();
563 AliInfo(Form("\n \t\t\t****** run %d - %s: PREPROCESSOR ERROR ****** \n\n",
564 GetCurrentRun(), aDetector->GetName()));
569 AliInfo(Form("\n \t\t\t****** run %d - %s: STORAGE ERROR ****** \n\n",
570 GetCurrentRun(), aDetector->GetName()));
572 AliInfo(Form("\n \t\t\t****** run %d - %s: DONE ****** \n\n",
573 GetCurrentRun(), aDetector->GetName()));
576 // Process successful: Update time_processed field in FES logbooks!
577 if(fFESCalled[kDAQ]) {
578 hasError = (UpdateDAQTable() == kFALSE);
579 fFESlist[kDAQ].Clear();
581 //if(fFESCalled[kDCS]) {
582 // hasError = UpdateDCSTable(aDetector->GetName());
583 // fFESlist[kDCS].Clear();
585 //if(fFESCalled[kHLT]) {
586 // hasError = UpdateHLTTable(aDetector->GetName());
587 // fFESlist[kHLT].Clear();
592 AliInfo(Form("\n\n \t\t\t^*^*^*^*^*^*^*^*^*^*^*^* run %d: FINISH ^*^*^*^*^*^*^*^*^*^*^*^* \n",
595 //check if shuttle is done for this run, if so update logbook
596 TObjArray checkEntryArray;
597 checkEntryArray.SetOwner(1);
598 TString whereClause = Form("where run=%d",GetCurrentRun());
599 if(QueryShuttleLogbook(whereClause.Data(), checkEntryArray)) {
601 AliShuttleLogbookEntry* checkEntry = dynamic_cast<AliShuttleLogbookEntry*>
602 (checkEntryArray.At(0));
604 if(checkEntry && checkEntry->IsDone()){
605 Log("SHUTTLE","Process - Shuttle is DONE. Updating logbook");
606 UpdateShuttleLogbook("shuttle_done");
612 return hasError == kFALSE;
615 //______________________________________________________________________________________________
616 UInt_t AliShuttle::ProcessCurrentDetector()
619 // Makes data retrieval just for a specific detector (fCurrentDetector).
620 // Threre should be a configuration for this detector.
622 AliInfo(Form("Retrieving values for %s, run %d", fCurrentDetector.Data(), GetCurrentRun()));
624 UpdateShuttleStatus(AliShuttleStatus::kDCSStarted);
626 TString host(fConfig->GetDCSHost(fCurrentDetector));
627 Int_t port = fConfig->GetDCSPort(fCurrentDetector);
629 TIter iter(fConfig->GetDCSAliases(fCurrentDetector));
632 aliasMap.SetOwner(1);
634 Bool_t aDCSError = kFALSE;
637 while ((anAlias = (TObjString*) iter.Next())) {
638 TObjArray *valueSet = new TObjArray();
639 valueSet->SetOwner(1);
640 // TODO Test only... I've added a flag that allows to
641 // exclude DCS archive DB query
643 AliInfo("Querying DCS archive DB data...");
644 aDCSError = (GetValueSet(host, port, anAlias->String(), valueSet) == 0);
646 AliInfo(Form("Skipping DCS processing. Port = %d",port));
650 aliasMap.Add(anAlias->Clone(), valueSet);
652 Log(fCurrentDetector, Form("ProcessCurrentDetector - Error while retrieving alias %s",
653 anAlias->GetName()));
654 UpdateShuttleStatus(AliShuttleStatus::kDCSError, kTRUE);
655 aliasMap.DeleteAll();
660 // DCS Archive DB processing successful. Call Preprocessor!
661 UpdateShuttleStatus(AliShuttleStatus::kPPStarted);
663 AliPreprocessor* aPreprocessor =
664 dynamic_cast<AliPreprocessor*> (fPreprocessorMap.GetValue(fCurrentDetector));
666 aPreprocessor->Initialize(GetCurrentRun(), GetCurrentStartTime(), GetCurrentEndTime());
668 UInt_t aPPResult = aPreprocessor->Process(&aliasMap);
670 UInt_t returnValue = 0;
671 if (aPPResult == 0) { // Preprocessor error
672 UpdateShuttleStatus(AliShuttleStatus::kPPError, kTRUE);
674 } else if (fGridError == kFALSE) { // process and Grid storage ok!
675 UpdateShuttleStatus(AliShuttleStatus::kDone);
676 UpdateShuttleLogbook(fCurrentDetector, "DONE");
677 Log(fCurrentDetector.Data(),
678 "ProcessCurrentDetector - Preprocessor and Grid storage ended successfully");
680 } else { // Grid storage error (process ok, but object put in local storage)
681 UpdateShuttleStatus(AliShuttleStatus::kStoreFailed);
685 aliasMap.DeleteAll();
690 //______________________________________________________________________________________________
691 Bool_t AliShuttle::QueryShuttleLogbook(const char* whereClause,
694 // Query DAQ's Shuttle logbook and fills detector status object.
695 // Call QueryRunParameters to query DAQ logbook for run parameters.
697 // check connection, in case connect
698 if(!Connect(kDAQ)) return kFALSE;
701 sqlQuery = Form("select * from logbook_shuttle %s order by run", whereClause);
703 TSQLResult* aResult = fServer[kDAQ]->Query(sqlQuery);
705 AliError(Form("Can't execute query <%s>!", sqlQuery.Data()));
709 if(aResult->GetRowCount() == 0) {
710 if(sqlQuery.Contains("where shuttle_done=0")){
711 Log("SHUTTLE", "QueryShuttleLogbook - All runs in Shuttle Logbook are already DONE");
715 AliError("No entries in Shuttle Logbook match request");
721 // TODO Check field count!
722 const UInt_t nCols = 24;
723 if (aResult->GetFieldCount() != (Int_t) nCols) {
724 AliError("Invalid SQL result field number!");
732 while ((aRow = aResult->Next())) {
733 TString runString(aRow->GetField(0), aRow->GetFieldLength(0));
734 Int_t run = runString.Atoi();
736 UInt_t startTime, endTime;
737 if(!QueryRunParameters(run, startTime, endTime)) continue;
739 const UInt_t nDet = AliShuttle::kNDetectors;
740 AliShuttleLogbookEntry::Status detStatus[nDet];
743 for(UInt_t ii = 0; ii < nCols; ii++){
744 TString detCode(aResult->GetFieldName(ii));
745 Int_t detPos = AliShuttle::GetDetPos(detCode.Data());
746 if(detPos < 0) continue;
747 TString statusString(aRow->GetField(ii), aRow->GetFieldLength(ii));
748 if(statusString == "UNPROCESSED"){
749 detStatus[detPos] = AliShuttleLogbookEntry::kUnprocessed;
750 } else if (statusString == "INACTIVE") {
751 detStatus[detPos] = AliShuttleLogbookEntry::kInactive;
752 } else if (statusString == "FAILED") {
753 detStatus[detPos] = AliShuttleLogbookEntry::kFailed;
754 } else if (statusString == "DONE") {
755 detStatus[detPos] = AliShuttleLogbookEntry::kDone;
759 entries.AddLast(new AliShuttleLogbookEntry(run, startTime, endTime, detStatus));
763 if(sqlQuery.Contains("where shuttle_done=0"))
764 Log("SHUTTLE", Form("QueryShuttleLogbook - Found %d unprocessed runs in Shuttle Logbook",
765 entries.GetEntriesFast()));
770 //______________________________________________________________________________________________
771 Bool_t AliShuttle::QueryRunParameters(Int_t& run, UInt_t& startTime, UInt_t& endTime)
773 // Retrieve start time and end time for run in the DAQ logbook
775 // check connection, in case connect
776 if(!Connect(kDAQ)) return kFALSE;
779 sqlQuery = Form("select time_start, time_end from logbook where run=%d", run);
781 TSQLResult* aResult = fServer[kDAQ]->Query(sqlQuery);
783 AliError(Form("Can't execute query <%s>!", sqlQuery.Data()));
787 if(aResult->GetRowCount() == 0) {
788 Log("SHUTTLE", Form("QueryRunParameters - No entry in DAQ Logbook for run %d. Skipping", run));
793 if(aResult->GetRowCount() > 1) {
794 AliError(Form("More than one entry in DAQ Logbook for run %d. Skipping", run));
800 while ((aRow = aResult->Next())) {
802 TString startTimeString(aRow->GetField(0),
803 aRow->GetFieldLength(0));
804 startTime = startTimeString.Atoi();
805 TString endTimeString(aRow->GetField(1),
806 aRow->GetFieldLength(1));
807 endTime = endTimeString.Atoi();
809 if (!startTime || !endTime || startTime > endTime) {
811 Form("QueryRunParameters - Invalid parameters for Run %d: startTime = %d, endTime = %d",
812 run, startTime, endTime));
825 //______________________________________________________________________________________________
826 Bool_t AliShuttle::TryToStoreAgain()
828 // Called in case the detector failed to store the object in Grid OCDB
829 // It tries to store the object again, if it does not find more recent and overlapping objects
830 // Calls underlying TryToStoreAgain(const char*) function twice, for OCDB and Reference storage.
832 AliInfo("Trying to store OCDB data again...");
833 Bool_t resultCDB = TryToStoreAgain(fgkMainCDB);
835 AliInfo("Trying to store reference data again...");
836 Bool_t resultRef = TryToStoreAgain(fgkMainRefStorage);
838 return resultCDB && resultRef;
841 //______________________________________________________________________________________________
842 Bool_t AliShuttle::TryToStoreAgain(TString& gridURI)
844 // Called by TryToStoreAgain(), performs actual storage retry
848 Bool_t result = kTRUE;
850 const char* type = 0;
852 if(gridURI == fgkMainCDB) {
854 backupURI = fgkLocalCDB;
855 } else if(gridURI == fgkMainRefStorage) {
857 backupURI = fgkLocalRefStorage;
859 AliError(Form("Invalid storage URI: %s", gridURI.Data()));
863 AliCDBManager* man = AliCDBManager::Instance();
865 AliCDBStorage *gridSto = man->GetStorage(gridURI);
867 Log(fCurrentDetector.Data(),
868 Form("TryToStoreAgain - cannot activate main %s storage", type));
872 gridIds = gridSto->GetQueryCDBList();
874 // get objects previously stored in local CDB
875 AliCDBStorage *backupSto = man->GetStorage(backupURI);
876 AliCDBPath aPath(fCurrentDetector,"*","*");
877 // Local objects were stored with current run as Grid version!
878 TList* localEntries = backupSto->GetAll(aPath.GetPath(), GetCurrentRun(), GetCurrentRun());
879 localEntries->SetOwner(1);
881 // loop on local stored objects
882 TIter localIter(localEntries);
883 AliCDBEntry *aLocEntry = 0;
884 while((aLocEntry = dynamic_cast<AliCDBEntry*> (localIter.Next()))){
885 aLocEntry->SetOwner(1);
886 AliCDBId aLocId = aLocEntry->GetId();
887 aLocEntry->SetVersion(-1);
888 aLocEntry->SetSubVersion(-1);
890 // loop on Grid valid Id's
891 Bool_t store = kTRUE;
892 TIter gridIter(gridIds);
893 AliCDBId* aGridId = 0;
894 while((aGridId = dynamic_cast<AliCDBId*> (gridIter.Next()))){
895 // If local object is valid up to infinity we store it anyway
896 // TODO This does not work! It may hide more recent objects...
897 if(aLocId.GetLastRun() == AliCDBRunRange::Infinity()) {
898 // TODO Check that it won't hide more recent files! how????
901 if(aGridId->GetPath() != aLocId.GetPath()) continue;
902 // skip all objects valid up to infinity
903 if(aGridId->GetLastRun() == AliCDBRunRange::Infinity()) continue;
904 // if we get here, it means there's already some more recent object stored on Grid!
910 Log(fCurrentDetector.Data(),
911 Form("TryToStoreAgain - A more recent object already exists in %s storage: <%s>",
912 type, aGridId->ToString().Data()));
913 // removing local filename...
914 // TODO maybe it's better not to remove it, it was not copied to the Grid!
916 backupSto->IdToFilename(aLocId, filename);
917 AliInfo(Form("Removing local file %s", filename.Data()));
918 gSystem->Exec(Form("rm %s",filename.Data()));
922 // If we get here, the file can be stored!
923 Bool_t storeOk = gridSto->Put(aLocEntry);
925 Log(fCurrentDetector.Data(),
926 Form("TryToStoreAgain - Object <%s> successfully put into %s storage",
927 aLocId.ToString().Data(), type));
929 // removing local filename...
931 backupSto->IdToFilename(aLocId, filename);
932 AliInfo(Form("Removing local file %s", filename.Data()));
933 gSystem->Exec(Form("rm %s", filename.Data()));
936 Log(fCurrentDetector.Data(),
937 Form("TryToStoreAgain - Grid %s storage of object <%s> failed again",
938 type, aLocId.ToString().Data()));
942 localEntries->Clear();
947 //______________________________________________________________________________________________
948 Bool_t AliShuttle::GetValueSet(const char* host, Int_t port, const char* alias,
951 // Retrieve all "alias" data points from the DCS server
952 // host, port: TSocket connection parameters
953 // alias: name of the alias
954 // valueSet: array of retrieved AliDCSValue's
956 AliDCSClient client(host, port, fTimeout, fRetries);
957 if (!client.IsConnected()) {
961 Int_t result = client.GetAliasValues(alias,
962 GetCurrentStartTime(), GetCurrentEndTime(), valueSet);
965 Log(fCurrentDetector.Data(), Form("GetValueSet - Can't get '%s'! Reason: %s",
966 alias, AliDCSClient::GetErrorString(result)));
968 if (result == AliDCSClient::fgkServerError) {
969 Log(fCurrentDetector.Data(), Form("GetValueSet - Server error: %s",
970 client.GetServerError().Data()));
979 //______________________________________________________________________________________________
980 const char* AliShuttle::GetFile(Int_t system, const char* detector,
981 const char* id, const char* source)
983 // Get calibration file from file exchange servers
984 // calls specific getter according to system index (kDAQ, kDCS, kHLT)
988 return GetDAQFileName(detector, id, source);
991 return GetDCSFileName(detector, id, source);
994 return GetHLTFileName(detector, id, source);
997 AliError(Form("No valid system index: %d",system));
1003 //______________________________________________________________________________________________
1004 TList* AliShuttle::GetFileSources(Int_t system, const char* detector, const char* id)
1006 // Get sources producing the condition file Id from file exchange servers
1007 // calls specific getter according to system index (kDAQ, kDCS, kHLT)
1011 return GetDAQFileSources(detector, id);
1014 return GetDCSFileSources(detector, id);
1017 return GetHLTFileSources(detector, id);
1020 AliError(Form("No valid system index: %d",system));
1026 //______________________________________________________________________________________________
1027 Bool_t AliShuttle::Connect(Int_t system)
1029 // Connect to MySQL Server of the system's FES logbook
1030 // DAQ Logbook, Shuttle Logbook and DAQ FES Logbook are on the same host
1032 // check connection: if already connected return
1033 if(fServer[system] && fServer[system]->IsConnected()) return kTRUE;
1035 TString aFESlbHost= Form("mysql://%s", fConfig->GetFESlbHost(system));
1037 fServer[system] = TSQLServer::Connect(aFESlbHost,
1038 fConfig->GetFESlbUser(system),
1039 fConfig->GetFESlbPass(system));
1040 if (!fServer[system] || !fServer[system]->IsConnected()) {
1041 AliError(Form("Can't establish connection to FES logbook for %s",fkSystemNames[system]));
1042 if(fServer[system]) delete fServer[system];
1047 // TODO in the configuration should the table name be there too?
1048 TSQLResult* aResult=0;
1051 aResult = fServer[kDAQ]->GetTables("REFSYSLOG");
1054 //aResult = fServer[kDCS]->GetTables("REFSYSLOG");
1057 //aResult = fServer[kHLT]->GetTables("REFSYSLOG");
1067 //______________________________________________________________________________________________
1068 const char* AliShuttle::GetDAQFileName(const char* detector, const char* id, const char* source)
1070 // Retrieves a file from the DAQ FES.
1071 // First queris the DAQ logbook_fs for the DAQ file name, using the run, detector, id and source info
1072 // then calls RetrieveDAQFile(DAQfilename) for actual copy to local disk
1073 // run: current run being processed (given by Logbook entry fLogbookEntry)
1074 // detector: comes from the Preprocessor name (must be converted into detector code with GetDetCode)
1075 // id: provided as a parameter by the Preprocessor
1076 // source: provided by the Preprocessor through GetFileSources function
1078 // check connection, in case connect
1080 Log(detector, "GetDAQFileName - Couldn't connect to DAQ Logbook");
1084 // Query preparation
1085 TString sqlQueryStart = "select filePath from logbook_fs where";
1086 TString whereClause = Form("run=%d and detector=\"%s\" and fileId=\"%s\" and DAQsource=\"%s\"",
1087 GetCurrentRun(), GetDetCode(detector), id, source);
1088 TString sqlQuery = Form("%s %s", sqlQueryStart.Data(), whereClause.Data());
1090 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
1093 TSQLResult* aResult = 0;
1094 aResult = dynamic_cast<TSQLResult*> (fServer[kDAQ]->Query(sqlQuery));
1096 Log(detector, Form("GetDAQFileName - Can't execute SQL query for: id = %s, source = %s",
1101 if (aResult->GetRowCount() == 0) {
1103 Form("GetDAQFileName - No entry in FES table for: id = %s, source = %s",
1109 if (aResult->GetRowCount() >1) {
1111 Form("GetDAQFileName - More than one entry in FES table for: id = %s, source = %s",
1117 TSQLRow* aRow = dynamic_cast<TSQLRow*> (aResult->Next());
1120 Log(detector, Form("GetDAQFileName - Empty set result from query: id = %s, source = %s",
1126 TString filePath(aRow->GetField(0), aRow->GetFieldLength(0));
1131 AliDebug(2, Form("filePath = %s",filePath.Data()));
1133 // retrieved file is renamed to make it unique
1134 TString localFileName = Form("%s_%d_%s_%s.shuttle",
1135 detector, GetCurrentRun(), id, source);
1137 // file retrieval from DAQ FES
1138 Bool_t result = RetrieveDAQFile(filePath.Data(), localFileName.Data());
1140 Log(detector, Form("GetDAQFileName - Copy of file %s from DAQ FES failed", filePath.Data()));
1143 AliInfo(Form("File %s copied from DAQ FES into %s/%s",
1144 filePath.Data(), fgkShuttleTempDir, localFileName.Data()));
1148 fFESCalled[kDAQ]=kTRUE;
1149 TObjString *fileParams = new TObjString(Form("%s_!?!_%s", id, source));
1150 fFESlist[kDAQ].Add(fileParams);
1152 return localFileName.Data();
1156 //______________________________________________________________________________________________
1157 Bool_t AliShuttle::RetrieveDAQFile(const char* daqFileName, const char* localFileName)
1160 // check temp directory: trying to cd to temp; if it does not exist, create it
1161 AliDebug(2, Form("Copy file %s from DAQ FES into folder %s and rename it as %s",
1162 daqFileName,fgkShuttleTempDir, localFileName));
1164 void* dir = gSystem->OpenDirectory(fgkShuttleTempDir);
1166 if (gSystem->mkdir(fgkShuttleTempDir, kTRUE)) {
1167 AliError(Form("Can't open directory <%s>", fgkShuttleTempDir));
1172 gSystem->FreeDirectory(dir);
1175 TString baseDAQFESFolder = "DAQ";
1176 TString command = Form("scp %s@%s:%s/%s %s/%s",
1177 fConfig->GetFESUser(kDAQ),
1178 fConfig->GetFESHost(kDAQ),
1179 baseDAQFESFolder.Data(),
1184 AliDebug(2, Form("%s",command.Data()));
1186 UInt_t nRetries = 0;
1187 UInt_t maxRetries = 3;
1189 // copy!! if successful TSystem::Exec returns 0
1190 while(nRetries++ < maxRetries) {
1191 AliDebug(2, Form("Trying to copy file. Retry # %d", nRetries));
1192 if(gSystem->Exec(command.Data()) == 0) return kTRUE;
1199 //______________________________________________________________________________________________
1200 TList* AliShuttle::GetDAQFileSources(const char* detector, const char* id)
1202 // Retrieves a file from the DCS FES.
1204 // check connection, in case connect
1206 Log(detector, "GetDAQFileSources - Couldn't connect to DAQ Logbook");
1210 // Query preparation
1211 TString sqlQueryStart = "select DAQsource from logbook_fs where";
1212 TString whereClause = Form("run=%d and detector=\"%s\" and fileId=\"%s\"",
1213 GetCurrentRun(), GetDetCode(detector), id);
1214 TString sqlQuery = Form("%s %s", sqlQueryStart.Data(), whereClause.Data());
1216 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
1219 TSQLResult* aResult;
1220 aResult = fServer[kDAQ]->Query(sqlQuery);
1222 Log(detector, Form("GetDAQFileSources - Can't execute SQL query for id: %s", id));
1226 if (aResult->GetRowCount() == 0) {
1228 Form("GetDAQFileSources - No entry in FES table for id: %s", id));
1234 TList *list = new TList();
1237 while((aRow = aResult->Next())){
1239 TString daqSource(aRow->GetField(0), aRow->GetFieldLength(0));
1240 AliDebug(2, Form("daqSource = %s", daqSource.Data()));
1241 list->Add(new TObjString(daqSource));
1250 //______________________________________________________________________________________________
1251 const char* AliShuttle::GetDCSFileName(const char* /*detector*/, const char* /*id*/, const char* /*source*/){
1252 // Retrieves a file from the DCS FES.
1254 return "You're in DCS";
1258 //______________________________________________________________________________________________
1259 TList* AliShuttle::GetDCSFileSources(const char* /*detector*/, const char* /*id*/){
1260 // Retrieves a file from the DCS FES.
1266 //______________________________________________________________________________________________
1267 const char* AliShuttle::GetHLTFileName(const char* /*detector*/, const char* /*id*/, const char* /*source*/){
1268 // Retrieves a file from the HLT FES.
1270 return "You're in HLT";
1274 //______________________________________________________________________________________________
1275 TList* AliShuttle::GetHLTFileSources(const char* /*detector*/, const char* /*id*/){
1276 // Retrieves a file from the HLT FES.
1282 //______________________________________________________________________________________________
1283 Bool_t AliShuttle::UpdateDAQTable()
1285 // Update DAQ table filling time_processed field in all rows corresponding to current run and detector
1287 // check connection, in case connect
1289 Log(fCurrentDetector, "UpdateDAQTable - Couldn't connect to DAQ Logbook");
1293 TTimeStamp now; // now
1295 // Loop on FES list entries
1296 TIter iter(&fFESlist[kDAQ]);
1297 TObjString *aFESentry=0;
1298 while((aFESentry = dynamic_cast<TObjString*> (iter.Next()))){
1299 TString aFESentrystr = aFESentry->String();
1300 TObjArray *aFESarray = aFESentrystr.Tokenize("_!?!_");
1301 if(!aFESarray || aFESarray->GetEntries() != 2 ) {
1302 Log(fCurrentDetector, Form("UpdateDAQTable - error updating FES entry. Check string: <%s>",
1303 aFESentrystr.Data()));
1304 if(aFESarray) delete aFESarray;
1307 const char* fileId = ((TObjString*) aFESarray->At(0))->GetName();
1308 const char* daqSource = ((TObjString*) aFESarray->At(1))->GetName();
1309 TString whereClause = Form("where run=%d and detector=\"%s\" and fileId=\"%s\" and DAQsource=\"%s\";",
1310 GetCurrentRun(), GetDetCode(fCurrentDetector), fileId, daqSource);
1314 TString sqlQuery = Form("update logbook_fs set time_processed=%d %s", now.GetSec(), whereClause.Data());
1316 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
1319 TSQLResult* aResult;
1320 aResult = dynamic_cast<TSQLResult*> (fServer[kDAQ]->Query(sqlQuery));
1322 Log(fCurrentDetector, Form("UpdateDAQTable - Can't execute SQL query <%s>", sqlQuery.Data()));
1332 //______________________________________________________________________________________________
1333 Bool_t AliShuttle::UpdateShuttleLogbook(const char* detector, const char* status)
1335 // Update Shuttle logbook filling detector or shuttle_done column
1336 // ex. of usage: UpdateShuttleLogbook("PHOS", "DONE") or UpdateShuttleLogbook("shuttle_done")
1338 // check connection, in case connect
1340 Log("SHUTTLE", "UpdateShuttleLogbook - Couldn't connect to DAQ Logbook.");
1344 TString detName(detector);
1346 if(detName == "shuttle_done") {
1347 setClause = "set shuttle_done=1";
1349 TString detCode = GetDetCode(detector);
1350 if(detCode.IsNull()) {
1351 Log("SHUTTLE", Form("UpdateShuttleLogbook - Unknown detector %s", detector));
1354 TString statusStr(status);
1355 if(statusStr.Contains("done", TString::kIgnoreCase) ||
1356 statusStr.Contains("failed", TString::kIgnoreCase)){
1357 setClause = Form("set %s=\"%s\"", detCode.Data(), status);
1360 Form("UpdateShuttleLogbook - Invalid status <%s> for detector %s",
1366 TString whereClause = Form("where run=%d", GetCurrentRun());
1368 TString sqlQuery = Form("update logbook_shuttle %s %s",
1369 setClause.Data(), whereClause.Data());
1371 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
1374 TSQLResult* aResult;
1375 aResult = dynamic_cast<TSQLResult*> (fServer[kDAQ]->Query(sqlQuery));
1377 Log("SHUTTLE", Form("UpdateShuttleLogbook - Can't execute query <%s>", sqlQuery.Data()));
1385 //______________________________________________________________________________________________
1386 Int_t AliShuttle::GetCurrentRun() const
1388 // Get current run from logbook entry
1390 return fLogbookEntry ? fLogbookEntry->GetRun() : -1;
1393 //______________________________________________________________________________________________
1394 UInt_t AliShuttle::GetCurrentStartTime() const
1396 // get current start time
1398 return fLogbookEntry ? fLogbookEntry->GetStartTime() : 0;
1401 //______________________________________________________________________________________________
1402 UInt_t AliShuttle::GetCurrentEndTime() const
1404 // get current end time from logbook entry
1406 return fLogbookEntry ? fLogbookEntry->GetEndTime() : 0;
1409 //______________________________________________________________________________________________
1410 const char* AliShuttle::GetDetCode(const char* detector){
1411 // Return detector code
1413 for(UInt_t iDet=0; iDet < kNDetectors; iDet++){
1414 if(!strcmp(fgkDetectorName[iDet], detector)) return fgkDetectorCode[iDet];
1417 AliErrorClass(Form("Unknown detector: %s",detector));
1421 //______________________________________________________________________________________________
1422 const char* AliShuttle::GetDetCode(UInt_t detPos){
1423 // Return detector code
1425 if( detPos >= kNDetectors) {
1426 AliErrorClass(Form("Invalid parameter: %d", detPos));
1429 return fgkDetectorCode[detPos];
1432 //______________________________________________________________________________________________
1433 const Int_t AliShuttle::GetDetPos(const char* detCode){
1434 // Return detector position in the detector code array
1436 for(UInt_t iDet=0; iDet < kNDetectors; iDet++){
1437 if(!strcmp(fgkDetectorCode[iDet], detCode)) return iDet;
1442 //______________________________________________________________________________________________
1443 void AliShuttle::Log(const char* detector, const char* message)
1445 // Fill log string with a message
1447 void* dir = gSystem->OpenDirectory(fgkShuttleLogDir);
1449 if (gSystem->mkdir(fgkShuttleLogDir, kTRUE)) {
1450 AliError(Form("Can't open directory <%s>", fgkShuttleTempDir));
1455 gSystem->FreeDirectory(dir);
1458 TString toLog = Form("%s: %s - ", TTimeStamp(time(0)).AsString("s"), detector);
1459 if(GetCurrentRun()>=0 ) toLog += Form("run %d - ", GetCurrentRun());
1460 toLog += Form("%s", message);
1462 AliInfo(toLog.Data());
1465 fileName.Form("%s/%s.log", fgkShuttleLogDir, detector);
1466 gSystem->ExpandPathName(fileName);
1469 logFile.open(fileName, ofstream::out | ofstream::app);
1471 if (!logFile.is_open()) {
1472 AliError(Form("Could not open file %s", fileName.Data()));
1476 logFile << toLog.Data() << "\n";
1482 //______________________________________________________________________________________________
1483 Bool_t AliShuttle::Collect(Int_t run)
1486 // Collects conditions data for the given run.
1489 AliInfo(Form("Collecting conditions data for run %d", run));
1491 TString whereClause("where run=");
1494 TObjArray dateEntries;
1495 if (!QueryShuttleLogbook(whereClause, dateEntries)) {
1496 AliError("Can't retrieve entries from Shuttle logbook!");
1500 if (!dateEntries.GetEntriesFast()) {
1501 AliError(Form("Retrieval of parameters for run %d failed!", run));
1505 if (dateEntries.GetEntriesFast() > 1) {
1506 AliError(Form("There is more than one entry for run <%d> in Shuttle logbook!", run));
1510 if (!RetrieveConditionsData(dateEntries)) {
1511 AliError("An error occured during conditions data retrieval!");
1518 //______________________________________________________________________________________________
1519 Bool_t AliShuttle::CollectNew()
1522 // Collects conditions data for all UNPROCESSED run written to DAQ LogBook.
1523 // In operational mode, this is the Shuttle function triggered by the EOR signal.
1526 Log("SHUTTLE","CollectNew - Shuttle called. Collecting conditions data for unprocessed runs");
1528 TString whereClause("where shuttle_done=0");
1530 TObjArray shuttleLogbookEntries;
1531 if (!QueryShuttleLogbook(whereClause, shuttleLogbookEntries)) {
1532 Log("SHUTTLE", "CollectNew - Can't retrieve entries from Shuttle logbook");
1536 if (!RetrieveConditionsData(shuttleLogbookEntries)) {
1537 Log("SHUTTLE", "CollectNew - Process of at least one run failed");
1544 //______________________________________________________________________________________________
1545 Bool_t AliShuttle::CollectAll()
1548 // Collects conditions data for all runs (even if they're already done!) written in Shuttle LogBook.
1551 AliInfo("Collecting conditions data for all runs ...");
1553 TObjArray dateEntries;
1554 if (!QueryShuttleLogbook("", dateEntries)) {
1555 AliError("Can't retrieve entries from Shuttle logbook");
1559 if (!RetrieveConditionsData(dateEntries)) {
1560 AliError("An error occured during conditions data retrieval!");
1568 //______________________________________________________________________________________________
1569 Bool_t AliShuttle::RetrieveConditionsData(const TObjArray& dateEntries)
1571 // Retrieve conditions data for all runs that aren't processed yet
1573 Bool_t hasError = kFALSE;
1575 TIter iter(&dateEntries);
1576 AliShuttleLogbookEntry* anEntry;
1578 while ((anEntry = (AliShuttleLogbookEntry*) iter.Next())){
1579 if (!Process(anEntry)){
1584 return hasError == kFALSE;