]> git.uio.no Git - u/mrichter/AliRoot.git/blame - SHUTTLE/AliShuttle.cxx
Adding proton histograms and v0 selections
[u/mrichter/AliRoot.git] / SHUTTLE / AliShuttle.cxx
CommitLineData
73abe331 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$Log$
8884d71e 18Revision 1.76 2007/12/19 07:45:20 acolla
19bug fix in the name of the raw tag files (Raw instead of raw)
20
955d2abc 21Revision 1.75 2007/12/18 15:42:14 jgrosseo
22adding number of open runs to monitoring
23
fbc112e3 24Revision 1.74 2007/12/17 03:23:32 jgrosseo
25several bugfixes
26added "empty preprocessor" as placeholder for Acorde in FDR
27
4508ab8b 28Revision 1.73 2007/12/14 19:31:36 acolla
29Sending email to DCS experts is temporarily commented
30
b5f1c82e 31Revision 1.72 2007/12/13 15:44:28 acolla
32Run type added in mail sent to detector expert (eases understanding)
33
6a1146c4 34Revision 1.71 2007/12/12 14:56:14 jgrosseo
35sending shuttle_ignore to ML also in case of 0 events
36
97e3c167 37Revision 1.70 2007/12/12 13:45:35 acolla
38Monalisa started in Collect() function. Alive message to monitor is sent at each Collect and every minute during preprocessor processing.
39
ee6f7523 40Revision 1.69 2007/12/12 10:06:29 acolla
41in AliShuttle.cxx: SHUTTLE logbook is updated in case of invalid run times:
42
43time_start==0 && time_end==0
44
45logbook is NOT updated if time_start != 0 && time_end == 0, because it may mean that the run is still ongoing.
46
1abfbb60 47Revision 1.68 2007/12/11 10:15:17 acolla
48Added marking SHUTTLE=DONE for invalid runs
49(invalid start time or end time) and runs with totalEvents < 1
50
b0e53b15 51Revision 1.67 2007/12/07 19:14:36 acolla
52in AliShuttleTrigger:
53
54Added automatic collection of new runs on a regular time basis (settable from the configuration)
55
56in AliShuttleConfig: new members
57
58- triggerWait: time to wait for DIM trigger (s) before starting automatic collection of new runs
59- mode: run mode (test, prod) -> used to build log folder (logs or logs_PROD)
60
61in AliShuttle:
62
63- logs now stored in logs/#RUN/DET_#RUN.log
64
7d4cf768 65Revision 1.66 2007/12/05 10:45:19 jgrosseo
66changed order of arguments to TMonaLisaWriter
67
468df1ce 68Revision 1.65 2007/11/26 16:58:37 acolla
69Monalisa configuration added: host and table name
70
b832ec02 71Revision 1.64 2007/11/13 16:15:47 acolla
72DCS map is stored in a file in the temp folder where the detector is processed.
73If the preprocessor fails, the temp folder is not removed. This will help the debugging of the problem.
74
b1d18693 75Revision 1.63 2007/11/02 10:53:16 acolla
76Protection added to AliShuttle::CopyFileLocally
77
7d43a416 78Revision 1.62 2007/10/31 18:23:13 acolla
79Furter developement on the Shuttle:
80
81- Shuttle now connects to the Grid as alidaq. The OCDB and Reference folders
82are now built from /alice/data, e.g.:
83/alice/data/2007/LHC07a/OCDB
84
85the year and LHC period are taken from the Shuttle.
86Raw metadata files are stored by GRP to:
87/alice/data/2007/LHC07a/<runNb>/Raw/RunMetadata.root
88
89- Shuttle sends a mail to DCS experts each time DP retrieval fails.
90
675f64cd 91Revision 1.61 2007/10/30 20:33:51 acolla
92Improved managing of temporary folders, which weren't correctly handled.
93Resolved bug introduced in StoreReferenceFile, which caused SPD preprocessor fail.
94
d524ade6 95Revision 1.60 2007/10/29 18:06:16 acolla
96
97New function StoreRunMetadataFile added to preprocessor and Shuttle interface
98This function can be used by GRP only. It stores raw data tags merged file to the
99raw data folder (e.g. /alice/data/2008/LHC08a/000099999/Raw).
100
101KNOWN ISSUES:
102
1031. Shuttle cannot write to /alice/data/ because it belongs to alidaq. Tag file is stored in /alice/simulation/... for the time being.
1042. Due to a bug in TAlien::Mkdir, the creation of a folder in recursive mode (-p option) does not work. The problem
105has been corrected in the root package on the Shuttle machine.
106
c88ad5db 107Revision 1.59 2007/10/05 12:40:55 acolla
108
109Result error code added to AliDCSClient data members (it was "lost" with the new implementation of TMap* GetAliasValues and GetDPValues).
110
1790d4b7 111Revision 1.58 2007/09/28 15:27:40 acolla
112
113AliDCSClient "multiSplit" option added in the DCS configuration
114in AliDCSMessage: variable MAX_BODY_SIZE set to 500000
115
542b6cc8 116Revision 1.57 2007/09/27 16:53:13 acolla
117Detectors can have more than one AMANDA server. SHUTTLE queries the servers sequentially,
118merges the dcs aliases/DPs in one TMap and sends it to the preprocessor.
119
1d172743 120Revision 1.56 2007/09/14 16:46:14 jgrosseo
1211) Connect and Close are called before and after each query, so one can
122keep the same AliDCSClient object.
1232) The splitting of a query is moved to GetDPValues/GetAliasValues.
1243) Splitting interval can be specified in constructor
125
b41b252a 126Revision 1.55 2007/08/06 12:26:40 acolla
127Function Bool_t GetHLTStatus added to preprocessor. It returns the status of HLT
128read from the run logbook.
129
4859271b 130Revision 1.54 2007/07/12 09:51:25 jgrosseo
131removed duplicated log message in GetFile
132
4f0749a8 133Revision 1.53 2007/07/12 09:26:28 jgrosseo
134updating hlt fxs base path
135
42fde080 136Revision 1.52 2007/07/12 08:06:45 jgrosseo
137adding log messages in getfile... functions
138adding not implemented copy constructor in alishuttleconfigholder
139
1bcd28db 140Revision 1.51 2007/07/03 17:24:52 acolla
141root moved to v5-16-00. TFileMerger->Cp moved to TFile::Cp.
142
a986b218 143Revision 1.50 2007/07/02 17:19:32 acolla
144preprocessor is run in a temp directory that is removed when process is finished.
145
5bac2bde 146Revision 1.49 2007/06/29 10:45:06 acolla
147Number of columns in MySql Shuttle logbook increased by one (HLT added)
148
db99d43e 149Revision 1.48 2007/06/21 13:06:19 acolla
150GetFileSources returns dummy list with 1 source if system=DCS (better than
151returning error as it was)
152
6297b37d 153Revision 1.47 2007/06/19 17:28:56 acolla
154HLT updated; missing map bug removed.
155
dc25836b 156Revision 1.46 2007/06/09 13:01:09 jgrosseo
157Switching to retrieval of several DCS DPs at a time (multiDPrequest)
158
a038aa70 159Revision 1.45 2007/05/30 06:35:20 jgrosseo
160Adding functionality to the Shuttle/TestShuttle:
161o) Function to retrieve list of sources from a given system (GetFileSources with id=0)
162o) Function to retrieve list of IDs for a given source (GetFileIDs)
163These functions are needed for dealing with the tag files that are saved for the GRP preprocessor
164Example code has been added to the TestProcessor in TestShuttle
165
4a33bdd9 166Revision 1.44 2007/05/11 16:09:32 acolla
167Reference files for ITS, MUON and PHOS are now stored in OfflineDetName/OnlineDetName/run_...
168example: ITS/SPD/100_filename.root
169
2d9019b4 170Revision 1.43 2007/05/10 09:59:51 acolla
171Various bug fixes in StoreRefFilesToGrid; Cleaning of reference storage before processing detector (CleanReferenceStorage)
172
546242fb 173Revision 1.42 2007/05/03 08:01:39 jgrosseo
174typo in last commit :-(
175
8b739301 176Revision 1.41 2007/05/03 08:00:48 jgrosseo
177fixing log message when pp want to skip dcs value retrieval
178
651fdaab 179Revision 1.40 2007/04/27 07:06:48 jgrosseo
180GetFileSources returns empty list in case of no files, but successful query
181No mails sent in testmode
182
86aa42c3 183Revision 1.39 2007/04/17 12:43:57 acolla
184Correction in StoreOCDB; change of text in mail to detector expert
185
26758fce 186Revision 1.38 2007/04/12 08:26:18 jgrosseo
187updated comment
188
3c2a21c8 189Revision 1.37 2007/04/10 16:53:14 jgrosseo
190redirecting sub detector stdout, stderr to sub detector log file
191
3d8bc902 192Revision 1.35 2007/04/04 16:26:38 acolla
1931. Re-organization of function calls in TestPreprocessor to make it more meaningful.
1942. Added missing dependency in test preprocessors.
1953. in AliShuttle.cxx: processing time and memory consumption info on a single line.
196
886d60e6 197Revision 1.34 2007/04/04 10:33:36 jgrosseo
1981) Storing of files to the Grid is now done _after_ your preprocessors succeeded. This is transparent, which means that you can still use the same functions (Store, StoreReferenceData) to store files to the Grid. However, the Shuttle first stores them locally and transfers them after the preprocessor finished. The return code of these two functions has changed from UInt_t to Bool_t which gives you the success of the storing.
199In case of an error with the Grid, the Shuttle will retry the storing later, the preprocessor does not need to be run again.
200
2012) The meaning of the return code of the preprocessor has changed. 0 is now success and any other value means failure. This value is stored in the log and you can use it to keep details about the error condition.
202
2033) New function StoreReferenceFile to _directly_ store a file (without opening it) to the reference storage.
204
2054) The memory usage of the preprocessor is monitored. If it exceeds 2 GB it is terminated.
206
2075) New function AliPreprocessor::ProcessDCS(). If you do not need to have DCS data in all cases, you can skip the processing by implemting this function and returning kFALSE under certain conditions. E.g. if there is a certain run type.
208If you always need DCS data (like before), you do not need to implement it.
209
2106) The run type has been added to the monitoring page
211
9827400b 212Revision 1.33 2007/04/03 13:56:01 acolla
213Grid Storage at the end of preprocessing. Added virtual method to disable DCS query according to the
214run type.
215
3301427a 216Revision 1.32 2007/02/28 10:41:56 acolla
217Run type field added in SHUTTLE framework. Run type is read from "run type" logbook and retrieved by
218AliPreprocessor::GetRunType() function.
219Added some ldap definition files.
220
d386d623 221Revision 1.30 2007/02/13 11:23:21 acolla
222Moved getters and setters of Shuttle's main OCDB/Reference, local
223OCDB/Reference, temp and log folders to AliShuttleInterface
224
9d733021 225Revision 1.27 2007/01/30 17:52:42 jgrosseo
226adding monalisa monitoring
227
e7f62f16 228Revision 1.26 2007/01/23 19:20:03 acolla
229Removed old ldif files, added TOF, MCH ldif files. Added some options in
230AliShuttleConfig::Print. Added in Ali Shuttle: SetShuttleTempDir and
231SetShuttleLogDir
232
36c99a6a 233Revision 1.25 2007/01/15 19:13:52 acolla
234Moved some AliInfo to AliDebug in SendMail function
235
fc5a4708 236Revision 1.21 2006/12/07 08:51:26 jgrosseo
237update (alberto):
238table, db names in ldap configuration
239added GRP preprocessor
240DCS data can also be retrieved by data point
241
2c15234c 242Revision 1.20 2006/11/16 16:16:48 jgrosseo
243introducing strict run ordering flag
244removed giving preprocessor name to preprocessor, they have to know their name themselves ;-)
245
be48e3ea 246Revision 1.19 2006/11/06 14:23:04 jgrosseo
247major update (Alberto)
248o) reading of run parameters from the logbook
249o) online offline naming conversion
250o) standalone DCSclient package
251
eba76848 252Revision 1.18 2006/10/20 15:22:59 jgrosseo
253o) Adding time out to the execution of the preprocessors: The Shuttle forks and the parent process monitors the child
254o) Merging Collect, CollectAll, CollectNew function
255o) Removing implementation of empty copy constructors (declaration still there!)
256
cb343cfd 257Revision 1.17 2006/10/05 16:20:55 jgrosseo
258adapting to new CDB classes
259
6ec0e06c 260Revision 1.16 2006/10/05 15:46:26 jgrosseo
261applying to the new interface
262
481441a2 263Revision 1.15 2006/10/02 16:38:39 jgrosseo
264update (alberto):
265fixed memory leaks
266storing of objects that failed to be stored to the grid before
267interfacing of shuttle status table in daq system
268
2bb7b766 269Revision 1.14 2006/08/29 09:16:05 jgrosseo
270small update
271
85a80aa9 272Revision 1.13 2006/08/15 10:50:00 jgrosseo
273effc++ corrections (alberto)
274
4f0ab988 275Revision 1.12 2006/08/08 14:19:29 jgrosseo
276Update to shuttle classes (Alberto)
277
278- Possibility to set the full object's path in the Preprocessor's and
279Shuttle's Store functions
280- Possibility to extend the object's run validity in the same classes
281("startValidity" and "validityInfinite" parameters)
282- Implementation of the StoreReferenceData function to store reference
283data in a dedicated CDB storage.
284
84090f85 285Revision 1.11 2006/07/21 07:37:20 jgrosseo
286last run is stored after each run
287
7bfb2090 288Revision 1.10 2006/07/20 09:54:40 jgrosseo
289introducing status management: The processing per subdetector is divided into several steps,
290after each step the status is stored on disk. If the system crashes in any of the steps the Shuttle
291can keep track of the number of failures and skips further processing after a certain threshold is
292exceeded. These thresholds can be configured in LDAP.
293
5164a766 294Revision 1.9 2006/07/19 10:09:55 jgrosseo
295new configuration, accesst to DAQ FES (Alberto)
296
57f50b3c 297Revision 1.8 2006/07/11 12:44:36 jgrosseo
298adding parameters for extended validity range of data produced by preprocessor
299
17111222 300Revision 1.7 2006/07/10 14:37:09 jgrosseo
301small fix + todo comment
302
e090413b 303Revision 1.6 2006/07/10 13:01:41 jgrosseo
304enhanced storing of last sucessfully processed run (alberto)
305
a7160fe9 306Revision 1.5 2006/07/04 14:59:57 jgrosseo
307revision of AliDCSValue: Removed wrapper classes, reduced storage size per value by factor 2
308
45a493ce 309Revision 1.4 2006/06/12 09:11:16 jgrosseo
310coding conventions (Alberto)
311
58bc3020 312Revision 1.3 2006/06/06 14:26:40 jgrosseo
313o) removed files that were moved to STEER
314o) shuttle updated to follow the new interface (Alberto)
315
b948db8d 316Revision 1.2 2006/03/07 07:52:34 hristov
317New version (B.Yordanov)
318
d477ad88 319Revision 1.6 2005/11/19 17:19:14 byordano
320RetrieveDATEEntries and RetrieveConditionsData added
321
322Revision 1.5 2005/11/19 11:09:27 byordano
323AliShuttle declaration added
324
325Revision 1.4 2005/11/17 17:47:34 byordano
326TList changed to TObjArray
327
328Revision 1.3 2005/11/17 14:43:23 byordano
329import to local CVS
330
331Revision 1.1.1.1 2005/10/28 07:33:58 hristov
332Initial import as subdirectory in AliRoot
333
73abe331 334Revision 1.2 2005/09/13 08:41:15 byordano
335default startTime endTime added
336
337Revision 1.4 2005/08/30 09:13:02 byordano
338some docs added
339
340Revision 1.3 2005/08/29 21:15:47 byordano
341some docs added
342
343*/
344
345//
346// This class is the main manager for AliShuttle.
347// It organizes the data retrieval from DCS and call the
b948db8d 348// interface methods of AliPreprocessor.
73abe331 349// For every detector in AliShuttleConfgi (see AliShuttleConfig),
350// data for its set of aliases is retrieved. If there is registered
b948db8d 351// AliPreprocessor for this detector then it will be used
352// accroding to the schema (see AliPreprocessor).
353// If there isn't registered AliPreprocessor than the retrieved
73abe331 354// data is stored automatically to the undelying AliCDBStorage.
355// For detSpec is used the alias name.
356//
357
358#include "AliShuttle.h"
359
360#include "AliCDBManager.h"
361#include "AliCDBStorage.h"
362#include "AliCDBId.h"
84090f85 363#include "AliCDBRunRange.h"
364#include "AliCDBPath.h"
5164a766 365#include "AliCDBEntry.h"
73abe331 366#include "AliShuttleConfig.h"
eba76848 367#include "DCSClient/AliDCSClient.h"
73abe331 368#include "AliLog.h"
b948db8d 369#include "AliPreprocessor.h"
5164a766 370#include "AliShuttleStatus.h"
2bb7b766 371#include "AliShuttleLogbookEntry.h"
73abe331 372
57f50b3c 373#include <TSystem.h>
58bc3020 374#include <TObject.h>
b948db8d 375#include <TString.h>
57f50b3c 376#include <TTimeStamp.h>
73abe331 377#include <TObjString.h>
57f50b3c 378#include <TSQLServer.h>
379#include <TSQLResult.h>
380#include <TSQLRow.h>
cb343cfd 381#include <TMutex.h>
9827400b 382#include <TSystemDirectory.h>
383#include <TSystemFile.h>
a986b218 384#include <TFile.h>
9827400b 385#include <TGrid.h>
386#include <TGridResult.h>
73abe331 387
e7f62f16 388#include <TMonaLisaWriter.h>
389
5164a766 390#include <fstream>
391
cb343cfd 392#include <sys/types.h>
393#include <sys/wait.h>
394
73abe331 395ClassImp(AliShuttle)
396
b948db8d 397//______________________________________________________________________________________________
398AliShuttle::AliShuttle(const AliShuttleConfig* config,
399 UInt_t timeout, Int_t retries):
4f0ab988 400fConfig(config),
401fTimeout(timeout), fRetries(retries),
402fPreprocessorMap(),
2bb7b766 403fLogbookEntry(0),
eba76848 404fCurrentDetector(),
85a80aa9 405fStatusEntry(0),
cb343cfd 406fMonitoringMutex(0),
eba76848 407fLastActionTime(0),
e7f62f16 408fLastAction(),
9827400b 409fMonaLisa(0),
410fTestMode(kNone),
ffa29e93 411fReadTestMode(kFALSE),
412fOutputRedirected(kFALSE)
73abe331 413{
414 //
415 // config: AliShuttleConfig used
73abe331 416 // timeout: timeout used for AliDCSClient connection
417 // retries: the number of retries in case of connection error.
418 //
419
57f50b3c 420 if (!fConfig->IsValid()) AliFatal("********** !!!!! Invalid configuration !!!!! **********");
be48e3ea 421 for(int iSys=0;iSys<4;iSys++) {
57f50b3c 422 fServer[iSys]=0;
be48e3ea 423 if (iSys < 3)
2c15234c 424 fFXSlist[iSys].SetOwner(kTRUE);
57f50b3c 425 }
2bb7b766 426 fPreprocessorMap.SetOwner(kTRUE);
be48e3ea 427
428 for (UInt_t iDet=0; iDet<NDetectors(); iDet++)
429 fFirstUnprocessed[iDet] = kFALSE;
430
cb343cfd 431 fMonitoringMutex = new TMutex();
58bc3020 432}
433
b948db8d 434//______________________________________________________________________________________________
57f50b3c 435AliShuttle::~AliShuttle()
58bc3020 436{
9827400b 437 //
438 // destructor
439 //
58bc3020 440
b948db8d 441 fPreprocessorMap.DeleteAll();
be48e3ea 442 for(int iSys=0;iSys<4;iSys++)
57f50b3c 443 if(fServer[iSys]) {
444 fServer[iSys]->Close();
445 delete fServer[iSys];
eba76848 446 fServer[iSys] = 0;
57f50b3c 447 }
2bb7b766 448
449 if (fStatusEntry){
450 delete fStatusEntry;
451 fStatusEntry = 0;
452 }
cb343cfd 453
454 if (fMonitoringMutex)
455 {
456 delete fMonitoringMutex;
457 fMonitoringMutex = 0;
458 }
73abe331 459}
460
b948db8d 461//______________________________________________________________________________________________
57f50b3c 462void AliShuttle::RegisterPreprocessor(AliPreprocessor* preprocessor)
58bc3020 463{
73abe331 464 //
b948db8d 465 // Registers new AliPreprocessor.
73abe331 466 // It uses GetName() for indentificator of the pre processor.
467 // The pre processor is registered it there isn't any other
468 // with the same identificator (GetName()).
469 //
470
eba76848 471 const char* detName = preprocessor->GetName();
472 if(GetDetPos(detName) < 0)
473 AliFatal(Form("********** !!!!! Invalid detector name: %s !!!!! **********", detName));
474
475 if (fPreprocessorMap.GetValue(detName)) {
476 AliWarning(Form("AliPreprocessor %s is already registered!", detName));
73abe331 477 return;
478 }
479
eba76848 480 fPreprocessorMap.Add(new TObjString(detName), preprocessor);
73abe331 481}
b948db8d 482//______________________________________________________________________________________________
3301427a 483Bool_t AliShuttle::Store(const AliCDBPath& path, TObject* object,
84090f85 484 AliCDBMetaData* metaData, Int_t validityStart, Bool_t validityInfinite)
73abe331 485{
9827400b 486 // Stores a CDB object in the storage for offline reconstruction. Objects that are not needed for
487 // offline reconstruction, but should be stored anyway (e.g. for debugging) should NOT be stored
488 // using this function. Use StoreReferenceData instead!
489 // It calls StoreLocally function which temporarily stores the data locally; when the preprocessor
490 // finishes the data are transferred to the main storage (Grid).
b948db8d 491
3301427a 492 return StoreLocally(fgkLocalCDB, path, object, metaData, validityStart, validityInfinite);
84090f85 493}
494
495//______________________________________________________________________________________________
3301427a 496Bool_t AliShuttle::StoreReferenceData(const AliCDBPath& path, TObject* object, AliCDBMetaData* metaData)
84090f85 497{
9827400b 498 // Stores a CDB object in the storage for reference data. This objects will not be available during
499 // offline reconstrunction. Use this function for reference data only!
500 // It calls StoreLocally function which temporarily stores the data locally; when the preprocessor
501 // finishes the data are transferred to the main storage (Grid).
85a80aa9 502
3301427a 503 return StoreLocally(fgkLocalRefStorage, path, object, metaData);
85a80aa9 504}
505
506//______________________________________________________________________________________________
3301427a 507Bool_t AliShuttle::StoreLocally(const TString& localUri,
85a80aa9 508 const AliCDBPath& path, TObject* object, AliCDBMetaData* metaData,
509 Int_t validityStart, Bool_t validityInfinite)
510{
9827400b 511 // Store object temporarily in local storage. Parameters are passed by Store and StoreReferenceData functions.
512 // when the preprocessor finishes the data are transferred to the main storage (Grid).
513 // The parameters are:
514 // 1) Uri of the backup storage (Local)
515 // 2) the object's path.
516 // 3) the object to be stored
517 // 4) the metaData to be associated with the object
518 // 5) the validity start run number w.r.t. the current run,
519 // if the data is valid only for this run leave the default 0
520 // 6) specifies if the calibration data is valid for infinity (this means until updated),
521 // typical for calibration runs, the default is kFALSE
522 //
523 // returns 0 if fail, 1 otherwise
84090f85 524
9827400b 525 if (fTestMode & kErrorStorage)
526 {
527 Log(fCurrentDetector, "StoreLocally - In TESTMODE - Simulating error while storing locally");
528 return kFALSE;
529 }
530
3301427a 531 const char* cdbType = (localUri == fgkLocalCDB) ? "CDB" : "Reference";
2bb7b766 532
85a80aa9 533 Int_t firstRun = GetCurrentRun() - validityStart;
84090f85 534 if(firstRun < 0) {
9827400b 535 AliWarning("First valid run happens to be less than 0! Setting it to 0.");
84090f85 536 firstRun=0;
537 }
538
539 Int_t lastRun = -1;
540 if(validityInfinite) {
541 lastRun = AliCDBRunRange::Infinity();
542 } else {
543 lastRun = GetCurrentRun();
544 }
545
3301427a 546 // Version is set to current run, it will be used later to transfer data to Grid
547 AliCDBId id(path, firstRun, lastRun, GetCurrentRun(), -1);
2bb7b766 548
549 if(! dynamic_cast<TObjString*> (metaData->GetProperty("RunUsed(TObjString)"))){
550 TObjString runUsed = Form("%d", GetCurrentRun());
9e080f92 551 metaData->SetProperty("RunUsed(TObjString)", runUsed.Clone());
2bb7b766 552 }
84090f85 553
3301427a 554 Bool_t result = kFALSE;
84090f85 555
3301427a 556 if (!(AliCDBManager::Instance()->GetStorage(localUri))) {
557 Log("SHUTTLE", Form("StoreLocally - Cannot activate local %s storage", cdbType));
84090f85 558 } else {
3301427a 559 result = AliCDBManager::Instance()->GetStorage(localUri)
84090f85 560 ->Put(object, id, metaData);
561 }
562
563 if(!result) {
564
9827400b 565 Log(fCurrentDetector, Form("StoreLocally - Can't store object <%s>!", id.ToString().Data()));
3301427a 566 }
2bb7b766 567
3301427a 568 return result;
569}
84090f85 570
3301427a 571//______________________________________________________________________________________________
572Bool_t AliShuttle::StoreOCDB()
573{
9827400b 574 //
575 // Called when preprocessor ends successfully or when previous storage attempt failed (kStoreError status)
576 // Calls underlying StoreOCDB(const char*) function twice, for OCDB and Reference storage.
577 // Then calls StoreRefFilesToGrid to store reference files.
578 //
579
580 if (fTestMode & kErrorGrid)
581 {
582 Log("SHUTTLE", "StoreOCDB - In TESTMODE - Simulating error while storing in the Grid");
583 Log(fCurrentDetector, "StoreOCDB - In TESTMODE - Simulating error while storing in the Grid");
584 return kFALSE;
585 }
586
c88ad5db 587 Log("SHUTTLE","StoreOCDB - Storing OCDB data ...");
86aa42c3 588 Bool_t resultCDB = StoreOCDB(fgkMainCDB);
589
c88ad5db 590 Log("SHUTTLE","StoreOCDB - Storing reference data ...");
3301427a 591 Bool_t resultRef = StoreOCDB(fgkMainRefStorage);
9827400b 592
c88ad5db 593 Log("SHUTTLE","StoreOCDB - Storing reference files ...");
594 Bool_t resultRefFiles = CopyFilesToGrid("reference");
595
596 Bool_t resultMetadata = kTRUE;
597 if(fCurrentDetector == "GRP")
598 {
599 Log("StoreOCDB - SHUTTLE","Storing Run Metadata file ...");
600 resultMetadata = CopyFilesToGrid("metadata");
601 }
9827400b 602
c88ad5db 603 return resultCDB && resultRef && resultRefFiles && resultMetadata;
3301427a 604}
605
606//______________________________________________________________________________________________
607Bool_t AliShuttle::StoreOCDB(const TString& gridURI)
608{
609 //
610 // Called by StoreOCDB(), performs actual storage to the main OCDB and reference storages (Grid)
611 //
612
613 TObjArray* gridIds=0;
614
615 Bool_t result = kTRUE;
616
617 const char* type = 0;
618 TString localURI;
619 if(gridURI == fgkMainCDB) {
620 type = "OCDB";
621 localURI = fgkLocalCDB;
622 } else if(gridURI == fgkMainRefStorage) {
623 type = "reference";
624 localURI = fgkLocalRefStorage;
625 } else {
626 AliError(Form("Invalid storage URI: %s", gridURI.Data()));
627 return kFALSE;
628 }
629
630 AliCDBManager* man = AliCDBManager::Instance();
631
632 AliCDBStorage *gridSto = man->GetStorage(gridURI);
633 if(!gridSto) {
634 Log("SHUTTLE",
635 Form("StoreOCDB - cannot activate main %s storage", type));
636 return kFALSE;
637 }
638
639 gridIds = gridSto->GetQueryCDBList();
640
641 // get objects previously stored in local CDB
642 AliCDBStorage *localSto = man->GetStorage(localURI);
643 if(!localSto) {
644 Log("SHUTTLE",
645 Form("StoreOCDB - cannot activate local %s storage", type));
646 return kFALSE;
647 }
648 AliCDBPath aPath(GetOfflineDetName(fCurrentDetector.Data()),"*","*");
649 // Local objects were stored with current run as Grid version!
650 TList* localEntries = localSto->GetAll(aPath.GetPath(), GetCurrentRun(), GetCurrentRun());
651 localEntries->SetOwner(1);
652
653 // loop on local stored objects
654 TIter localIter(localEntries);
655 AliCDBEntry *aLocEntry = 0;
656 while((aLocEntry = dynamic_cast<AliCDBEntry*> (localIter.Next()))){
657 aLocEntry->SetOwner(1);
658 AliCDBId aLocId = aLocEntry->GetId();
659 aLocEntry->SetVersion(-1);
660 aLocEntry->SetSubVersion(-1);
661
662 // If local object is valid up to infinity we store it only if it is
663 // the first unprocessed run!
664 if (aLocId.GetLastRun() == AliCDBRunRange::Infinity() &&
665 !fFirstUnprocessed[GetDetPos(fCurrentDetector)])
666 {
667 Log("SHUTTLE", Form("StoreOCDB - %s: object %s has validity infinite but "
668 "there are previous unprocessed runs!",
669 fCurrentDetector.Data(), aLocId.GetPath().Data()));
4508ab8b 670 result = kFALSE;
3301427a 671 continue;
672 }
673
674 // loop on Grid valid Id's
675 Bool_t store = kTRUE;
676 TIter gridIter(gridIds);
677 AliCDBId* aGridId = 0;
678 while((aGridId = dynamic_cast<AliCDBId*> (gridIter.Next()))){
679 if(aGridId->GetPath() != aLocId.GetPath()) continue;
680 // skip all objects valid up to infinity
681 if(aGridId->GetLastRun() == AliCDBRunRange::Infinity()) continue;
682 // if we get here, it means there's already some more recent object stored on Grid!
683 store = kFALSE;
684 break;
685 }
686
687 // If we get here, the file can be stored!
688 Bool_t storeOk = gridSto->Put(aLocEntry);
689 if(!store || storeOk){
690
691 if (!store)
692 {
693 Log(fCurrentDetector.Data(),
694 Form("StoreOCDB - A more recent object already exists in %s storage: <%s>",
695 type, aGridId->ToString().Data()));
696 } else {
697 Log("SHUTTLE",
698 Form("StoreOCDB - Object <%s> successfully put into %s storage",
699 aLocId.ToString().Data(), type));
2d9019b4 700 Log(fCurrentDetector.Data(),
701 Form("StoreOCDB - Object <%s> successfully put into %s storage",
702 aLocId.ToString().Data(), type));
3301427a 703 }
84090f85 704
3301427a 705 // removing local filename...
706 TString filename;
707 localSto->IdToFilename(aLocId, filename);
c88ad5db 708 Log("SHUTTLE", Form("StoreOCDB - Removing local file %s", filename.Data()));
3301427a 709 RemoveFile(filename.Data());
710 continue;
711 } else {
712 Log("SHUTTLE",
713 Form("StoreOCDB - Grid %s storage of object <%s> failed",
714 type, aLocId.ToString().Data()));
2d9019b4 715 Log(fCurrentDetector.Data(),
716 Form("StoreOCDB - Grid %s storage of object <%s> failed",
717 type, aLocId.ToString().Data()));
3301427a 718 result = kFALSE;
b948db8d 719 }
720 }
3301427a 721 localEntries->Clear();
2bb7b766 722
b948db8d 723 return result;
3301427a 724}
725
546242fb 726//______________________________________________________________________________________________
727Bool_t AliShuttle::CleanReferenceStorage(const char* detector)
728{
2d9019b4 729 // clears the directory used to store reference files of a given subdetector
546242fb 730
731 AliCDBManager* man = AliCDBManager::Instance();
732 AliCDBStorage* sto = man->GetStorage(fgkLocalRefStorage);
2d9019b4 733 TString localBaseFolder = sto->GetBaseFolder();
734
735 TString targetDir = GetRefFilePrefix(localBaseFolder.Data(), detector);
736
d524ade6 737 Log("SHUTTLE", Form("CleanReferenceStorage - Cleaning %s", targetDir.Data()));
2d9019b4 738
739 TString begin;
740 begin.Form("%d_", GetCurrentRun());
741
742 TSystemDirectory* baseDir = new TSystemDirectory("/", targetDir);
743 if (!baseDir)
744 return kTRUE;
745
746 TList* dirList = baseDir->GetListOfFiles();
747 delete baseDir;
748
749 if (!dirList) return kTRUE;
750
751 if (dirList->GetEntries() < 3)
752 {
753 delete dirList;
754 return kTRUE;
755 }
756
757 Int_t nDirs = 0, nDel = 0;
758 TIter dirIter(dirList);
759 TSystemFile* entry = 0;
546242fb 760
2d9019b4 761 Bool_t success = kTRUE;
546242fb 762
2d9019b4 763 while ((entry = dynamic_cast<TSystemFile*> (dirIter.Next())))
764 {
765 if (entry->IsDirectory())
766 continue;
767
768 TString fileName(entry->GetName());
769 if (!fileName.BeginsWith(begin))
770 continue;
771
772 nDirs++;
773
774 // delete file
775 Int_t result = gSystem->Unlink(fileName.Data());
776
777 if (result)
778 {
d524ade6 779 Log("SHUTTLE", Form("CleanReferenceStorage - Could not delete file %s!", fileName.Data()));
2d9019b4 780 success = kFALSE;
781 } else {
782 nDel++;
783 }
784 }
785
786 if(nDirs > 0)
787 Log("SHUTTLE", Form("CleanReferenceStorage - %d (over %d) reference files in folder %s were deleted.",
788 nDel, nDirs, targetDir.Data()));
789
790
791 delete dirList;
792 return success;
793
794
795
796
797
546242fb 798
799 Int_t result = gSystem->GetPathInfo(targetDir, 0, (Long64_t*) 0, 0, 0);
800 if (result == 0)
801 {
802 // delete directory
d524ade6 803 result = gSystem->Exec(Form("rm -rf %s", targetDir.Data()));
546242fb 804 if (result != 0)
805 {
d524ade6 806 Log("SHUTTLE", Form("CleanReferenceStorage - Could not clean directory %s", targetDir.Data()));
546242fb 807 return kFALSE;
808 }
809 }
810
811 result = gSystem->mkdir(targetDir, kTRUE);
812 if (result != 0)
813 {
c88ad5db 814 Log("SHUTTLE", Form("CleanReferenceStorage - Error creating base directory %s", targetDir.Data()));
546242fb 815 return kFALSE;
816 }
817
818 return kTRUE;
819}
820
9827400b 821//______________________________________________________________________________________________
822Bool_t AliShuttle::StoreReferenceFile(const char* detector, const char* localFile, const char* gridFileName)
823{
824 //
3c2a21c8 825 // Stores reference file directly (without opening it). This function stores the file locally.
9827400b 826 //
3c2a21c8 827 // The file is stored under the following location:
828 // <base folder of local reference storage>/<DET>/<RUN#>_<gridFileName>
829 // where <gridFileName> is the second parameter given to the function
830 //
9827400b 831
832 if (fTestMode & kErrorStorage)
833 {
834 Log(fCurrentDetector, "StoreReferenceFile - In TESTMODE - Simulating error while storing locally");
835 return kFALSE;
836 }
837
838 AliCDBManager* man = AliCDBManager::Instance();
839 AliCDBStorage* sto = man->GetStorage(fgkLocalRefStorage);
840
841 TString localBaseFolder = sto->GetBaseFolder();
842
d524ade6 843 TString target = GetRefFilePrefix(localBaseFolder.Data(), detector);
844 target.Append(Form("/%d_%s", GetCurrentRun(), gridFileName));
9827400b 845
d524ade6 846 return CopyFileLocally(localFile, target);
c88ad5db 847}
848
849//______________________________________________________________________________________________
850Bool_t AliShuttle::StoreRunMetadataFile(const char* localFile, const char* gridFileName)
851{
852 //
853 // Stores Run metadata file to the Grid, in the run folder
854 //
855 // Only GRP can call this function.
856
857 if (fTestMode & kErrorStorage)
858 {
859 Log(fCurrentDetector, "StoreRunMetaDataFile - In TESTMODE - Simulating error while storing locally");
860 return kFALSE;
861 }
862
863 AliCDBManager* man = AliCDBManager::Instance();
864 AliCDBStorage* sto = man->GetStorage(fgkLocalRefStorage);
865
866 TString localBaseFolder = sto->GetBaseFolder();
867
868 // Build Run level folder
955d2abc 869 // folder = /alice/data/year/lhcPeriod/runNb/raw
c88ad5db 870
c88ad5db 871
675f64cd 872 TString lhcPeriod = GetLHCPeriod();
c88ad5db 873 if (lhcPeriod.Length() == 0)
874 {
875 Log("SHUTTLE","StoreRunMetaDataFile - LHCPeriod not found in logbook!");
876 return 0;
877 }
8884d71e 878
955d2abc 879 TString target = Form("%s/GRP/RunMetadata/alice/data/%d/%s/%09d/raw/%s",
675f64cd 880 localBaseFolder.Data(), GetCurrentYear(),
d524ade6 881 lhcPeriod.Data(), GetCurrentRun(), gridFileName);
c88ad5db 882
d524ade6 883 return CopyFileLocally(localFile, target);
c88ad5db 884}
885
886//______________________________________________________________________________________________
d524ade6 887Bool_t AliShuttle::CopyFileLocally(const char* localFile, const TString& target)
c88ad5db 888{
889 //
890 // Stores file locally. Called by StoreReferenceFile and StoreRunMetadataFile
d524ade6 891 // Files are temporarily stored in the local reference storage. When the preprocessor
892 // finishes, the Shuttle calls CopyFilesToGrid to transfer the files to AliEn
893 // (in reference or run level folders)
c88ad5db 894 //
895
d524ade6 896 TString targetDir(target(0, target.Last('/')));
897
898 //try to open base dir folder, if it does not exist
2d9019b4 899 void* dir = gSystem->OpenDirectory(targetDir.Data());
900 if (dir == NULL) {
901 if (gSystem->mkdir(targetDir.Data(), kTRUE)) {
c88ad5db 902 Log("SHUTTLE", Form("StoreFileLocally - Can't open directory <%s>", targetDir.Data()));
2d9019b4 903 return kFALSE;
904 }
905
906 } else {
907 gSystem->FreeDirectory(dir);
908 }
9827400b 909
7d43a416 910 Int_t result = 0;
911
912 result = gSystem->GetPathInfo(localFile, 0, (Long64_t*) 0, 0, 0);
9827400b 913 if (result)
914 {
c88ad5db 915 Log("SHUTTLE", Form("StoreFileLocally - %s does not exist", localFile));
546242fb 916 return kFALSE;
9827400b 917 }
546242fb 918
7d43a416 919 result = gSystem->GetPathInfo(target, 0, (Long64_t*) 0, 0, 0);
920 if (!result)
921 {
922 Log("SHUTTLE", Form("StoreFileLocally - target file %s already exist, removing...", target.Data()));
923 if (gSystem->Unlink(target.Data()))
924 {
925 Log("SHUTTLE", Form("StoreFileLocally - Could not remove existing target file %s!", target.Data()));
926 return kFALSE;
927 }
928 }
929
9827400b 930 result = gSystem->CopyFile(localFile, target);
931
932 if (result == 0)
933 {
c88ad5db 934 Log("SHUTTLE", Form("StoreFileLocally - File %s stored locally to %s", localFile, target.Data()));
9827400b 935 return kTRUE;
936 }
937 else
938 {
d524ade6 939 Log("SHUTTLE", Form("StoreFileLocally - Could not store file %s to %s! Error code = %d",
546242fb 940 localFile, target.Data(), result));
9827400b 941 return kFALSE;
942 }
c88ad5db 943
944
945
9827400b 946}
947
948//______________________________________________________________________________________________
c88ad5db 949Bool_t AliShuttle::CopyFilesToGrid(const char* type)
9827400b 950{
951 //
c88ad5db 952 // Transfers local files to the Grid. Local files can be reference files
953 // or run metadata file (from GRP only).
9827400b 954 //
c88ad5db 955 // According to the type (ref, metadata) the files are stored under the following location:
956 // ref --> <base folder of reference storage>/<DET>/<RUN#>_<gridFileName>
957 // metadata --> <run data folder>/<MetadataFileName>
86aa42c3 958 //
c88ad5db 959
9827400b 960 AliCDBManager* man = AliCDBManager::Instance();
961 AliCDBStorage* sto = man->GetStorage(fgkLocalRefStorage);
962 if (!sto)
963 return kFALSE;
964 TString localBaseFolder = sto->GetBaseFolder();
9827400b 965
c88ad5db 966 TString dir;
967 TString alienDir;
9827400b 968 TString begin;
9827400b 969
c88ad5db 970 if (strcmp(type, "reference") == 0)
971 {
972 dir = GetRefFilePrefix(localBaseFolder.Data(), fCurrentDetector.Data());
973 AliCDBStorage* gridSto = man->GetStorage(fgkMainRefStorage);
974 if (!gridSto)
975 return kFALSE;
976 TString gridBaseFolder = gridSto->GetBaseFolder();
977 alienDir = GetRefFilePrefix(gridBaseFolder.Data(), fCurrentDetector.Data());
978 begin = Form("%d_", GetCurrentRun());
979 }
980 else if (strcmp(type, "metadata") == 0)
981 {
c88ad5db 982
675f64cd 983 TString lhcPeriod = GetLHCPeriod();
c88ad5db 984
985 if (lhcPeriod.Length() == 0)
986 {
987 Log("SHUTTLE","CopyFilesToGrid - LHCPeriod not found in logbook!");
988 return 0;
989 }
990
955d2abc 991 dir = Form("%s/GRP/RunMetadata/alice/data/%d/%s/%09d/raw",
675f64cd 992 localBaseFolder.Data(), GetCurrentYear(),
c88ad5db 993 lhcPeriod.Data(), GetCurrentRun());
675f64cd 994 alienDir = dir(dir.Index("/alice/data/"), dir.Length());
995
c88ad5db 996 begin = "";
997 }
998 else
999 {
1000 Log("SHUTTLE", "CopyFilesToGrid - Unexpected: type label must be reference or metadata!");
1001 return kFALSE;
1002 }
1003
9827400b 1004 TSystemDirectory* baseDir = new TSystemDirectory("/", dir);
3d8bc902 1005 if (!baseDir)
1006 return kTRUE;
1007
2d9019b4 1008 TList* dirList = baseDir->GetListOfFiles();
1009 delete baseDir;
1010
1011 if (!dirList) return kTRUE;
1012
1013 if (dirList->GetEntries() < 3)
3d8bc902 1014 {
2d9019b4 1015 delete dirList;
9827400b 1016 return kTRUE;
3d8bc902 1017 }
2d9019b4 1018
546242fb 1019 if (!gGrid)
1020 {
c88ad5db 1021 Log("SHUTTLE", "CopyFilesToGrid - Connection to Grid failed: Cannot continue!");
2d9019b4 1022 delete dirList;
546242fb 1023 return kFALSE;
1024 }
1025
2d9019b4 1026 Int_t nDirs = 0, nTransfer = 0;
1027 TIter dirIter(dirList);
1028 TSystemFile* entry = 0;
1029
9827400b 1030 Bool_t success = kTRUE;
3d8bc902 1031 Bool_t first = kTRUE;
9827400b 1032
2d9019b4 1033 while ((entry = dynamic_cast<TSystemFile*> (dirIter.Next())))
1034 {
9827400b 1035 if (entry->IsDirectory())
1036 continue;
1037
1038 TString fileName(entry->GetName());
1039 if (!fileName.BeginsWith(begin))
1040 continue;
1041
2d9019b4 1042 nDirs++;
1043
3d8bc902 1044 if (first)
1045 {
1046 first = kFALSE;
c88ad5db 1047 // check that folder exists, otherwise create it
3d8bc902 1048 TGridResult* result = gGrid->Ls(alienDir.Data(), "a");
1049
1050 if (!result)
2d9019b4 1051 {
1052 delete dirList;
3d8bc902 1053 return kFALSE;
2d9019b4 1054 }
3d8bc902 1055
546242fb 1056 if (!result->GetFileName(1)) // TODO: It looks like element 0 is always 0!!
3d8bc902 1057 {
675f64cd 1058 // TODO It does not work currently! Bug in TAliEn::Mkdir
1059 // TODO Manually fixed in local root v5-16-00
c88ad5db 1060 if (!gGrid->Mkdir(alienDir.Data(),"-p",0))
3d8bc902 1061 {
c88ad5db 1062 Log("SHUTTLE", Form("CopyFilesToGrid - Cannot create directory %s",
3d8bc902 1063 alienDir.Data()));
2d9019b4 1064 delete dirList;
3d8bc902 1065 return kFALSE;
546242fb 1066 } else {
c88ad5db 1067 Log("SHUTTLE",Form("CopyFilesToGrid - Folder %s created", alienDir.Data()));
3d8bc902 1068 }
1069
546242fb 1070 } else {
c88ad5db 1071 Log("SHUTTLE",Form("CopyFilesToGrid - Folder %s found", alienDir.Data()));
3d8bc902 1072 }
1073 }
1074
9827400b 1075 TString fullLocalPath;
1076 fullLocalPath.Form("%s/%s", dir.Data(), fileName.Data());
1077
1078 TString fullGridPath;
1079 fullGridPath.Form("alien://%s/%s", alienDir.Data(), fileName.Data());
1080
a986b218 1081 Bool_t result = TFile::Cp(fullLocalPath, fullGridPath);
9827400b 1082
1083 if (result)
1084 {
c88ad5db 1085 Log("SHUTTLE", Form("CopyFilesToGrid - Copying local file %s to %s succeeded!",
1086 fullLocalPath.Data(), fullGridPath.Data()));
9827400b 1087 RemoveFile(fullLocalPath);
2d9019b4 1088 nTransfer++;
9827400b 1089 }
1090 else
1091 {
c88ad5db 1092 Log("SHUTTLE", Form("CopyFilesToGrid - Copying local file %s to %s FAILED!",
1093 fullLocalPath.Data(), fullGridPath.Data()));
9827400b 1094 success = kFALSE;
1095 }
1096 }
2d9019b4 1097
c88ad5db 1098 Log("SHUTTLE", Form("CopyFilesToGrid - %d (over %d) files in folder %s copied to Grid.",
1099 nTransfer, nDirs, dir.Data()));
2d9019b4 1100
1101
1102 delete dirList;
9827400b 1103 return success;
1104}
1105
2d9019b4 1106//______________________________________________________________________________________________
1107const char* AliShuttle::GetRefFilePrefix(const char* base, const char* detector)
1108{
1109 //
1110 // Get folder name of reference files
1111 //
1112
1113 TString offDetStr(GetOfflineDetName(detector));
1114 TString dir;
1115 if (offDetStr == "ITS" || offDetStr == "MUON" || offDetStr == "PHOS")
1116 {
1117 dir.Form("%s/%s/%s", base, offDetStr.Data(), detector);
1118 } else {
1119 dir.Form("%s/%s", base, offDetStr.Data());
1120 }
1121
1122 return dir.Data();
1123
1124
1125}
c88ad5db 1126
3301427a 1127//______________________________________________________________________________________________
1128void AliShuttle::CleanLocalStorage(const TString& uri)
1129{
9827400b 1130 //
1131 // Called in case the preprocessor is declared failed. Remove remaining objects from the local storages.
1132 //
3301427a 1133
1134 const char* type = 0;
1135 if(uri == fgkLocalCDB) {
1136 type = "OCDB";
1137 } else if(uri == fgkLocalRefStorage) {
546242fb 1138 type = "Reference";
3301427a 1139 } else {
1140 AliError(Form("Invalid storage URI: %s", uri.Data()));
1141 return;
1142 }
1143
1144 AliCDBManager* man = AliCDBManager::Instance();
b948db8d 1145
3301427a 1146 // open local storage
1147 AliCDBStorage *localSto = man->GetStorage(uri);
1148 if(!localSto) {
1149 Log("SHUTTLE",
1150 Form("CleanLocalStorage - cannot activate local %s storage", type));
1151 return;
1152 }
1153
1154 TString filename(Form("%s/%s/*/Run*_v%d_s*.root",
546242fb 1155 localSto->GetBaseFolder().Data(), GetOfflineDetName(fCurrentDetector.Data()), GetCurrentRun()));
3301427a 1156
c88ad5db 1157 AliDebug(2, Form("filename = %s", filename.Data()));
3301427a 1158
c88ad5db 1159 Log("SHUTTLE", Form("Removing remaining local files for run %d and detector %s ...",
3301427a 1160 GetCurrentRun(), fCurrentDetector.Data()));
1161
1162 RemoveFile(filename.Data());
1163
1164}
1165
1166//______________________________________________________________________________________________
1167void AliShuttle::RemoveFile(const char* filename)
1168{
9827400b 1169 //
1170 // removes local file
1171 //
3301427a 1172
1173 TString command(Form("rm -f %s", filename));
1174
1175 Int_t result = gSystem->Exec(command.Data());
1176 if(result != 0)
1177 {
1178 Log("SHUTTLE", Form("RemoveFile - %s: Cannot remove file %s!",
1179 fCurrentDetector.Data(), filename));
1180 }
73abe331 1181}
1182
b948db8d 1183//______________________________________________________________________________________________
5164a766 1184AliShuttleStatus* AliShuttle::ReadShuttleStatus()
1185{
9827400b 1186 //
1187 // Reads the AliShuttleStatus from the CDB
1188 //
5164a766 1189
2bb7b766 1190 if (fStatusEntry){
1191 delete fStatusEntry;
1192 fStatusEntry = 0;
1193 }
5164a766 1194
10a5a932 1195 fStatusEntry = AliCDBManager::Instance()->GetStorage(GetLocalCDB())
2bb7b766 1196 ->Get(Form("/SHUTTLE/STATUS/%s", fCurrentDetector.Data()), GetCurrentRun());
5164a766 1197
2bb7b766 1198 if (!fStatusEntry) return 0;
1199 fStatusEntry->SetOwner(1);
5164a766 1200
2bb7b766 1201 AliShuttleStatus* status = dynamic_cast<AliShuttleStatus*> (fStatusEntry->GetObject());
1202 if (!status) {
1203 AliError("Invalid object stored to CDB!");
1204 return 0;
1205 }
5164a766 1206
2bb7b766 1207 return status;
5164a766 1208}
1209
1210//______________________________________________________________________________________________
7bfb2090 1211Bool_t AliShuttle::WriteShuttleStatus(AliShuttleStatus* status)
5164a766 1212{
9827400b 1213 //
1214 // writes the status for one subdetector
1215 //
2bb7b766 1216
1217 if (fStatusEntry){
1218 delete fStatusEntry;
1219 fStatusEntry = 0;
1220 }
5164a766 1221
2bb7b766 1222 Int_t run = GetCurrentRun();
5164a766 1223
2bb7b766 1224 AliCDBId id(AliCDBPath("SHUTTLE", "STATUS", fCurrentDetector), run, run);
5164a766 1225
2bb7b766 1226 fStatusEntry = new AliCDBEntry(status, id, new AliCDBMetaData);
1227 fStatusEntry->SetOwner(1);
5164a766 1228
2bb7b766 1229 UInt_t result = AliCDBManager::Instance()->GetStorage(fgkLocalCDB)->Put(fStatusEntry);
7bfb2090 1230
2bb7b766 1231 if (!result) {
3301427a 1232 Log("SHUTTLE", Form("WriteShuttleStatus - Failed for %s, run %d",
1233 fCurrentDetector.Data(), run));
2bb7b766 1234 return kFALSE;
1235 }
e7f62f16 1236
1237 SendMLInfo();
7bfb2090 1238
2bb7b766 1239 return kTRUE;
5164a766 1240}
1241
1242//______________________________________________________________________________________________
1243void AliShuttle::UpdateShuttleStatus(AliShuttleStatus::Status newStatus, Bool_t increaseCount)
1244{
9827400b 1245 //
1246 // changes the AliShuttleStatus for the given detector and run to the given status
1247 //
5164a766 1248
2bb7b766 1249 if (!fStatusEntry){
1250 AliError("UNEXPECTED: fStatusEntry empty");
1251 return;
1252 }
5164a766 1253
2bb7b766 1254 AliShuttleStatus* status = dynamic_cast<AliShuttleStatus*> (fStatusEntry->GetObject());
5164a766 1255
2bb7b766 1256 if (!status){
c88ad5db 1257 Log("SHUTTLE", "UpdateShuttleStatus - UNEXPECTED: status could not be read from current CDB entry");
2bb7b766 1258 return;
1259 }
5164a766 1260
2c15234c 1261 TString actionStr = Form("UpdateShuttleStatus - %s: Changing state from %s to %s",
eba76848 1262 fCurrentDetector.Data(),
36c99a6a 1263 status->GetStatusName(),
eba76848 1264 status->GetStatusName(newStatus));
cb343cfd 1265 Log("SHUTTLE", actionStr);
1266 SetLastAction(actionStr);
5164a766 1267
2bb7b766 1268 status->SetStatus(newStatus);
1269 if (increaseCount) status->IncreaseCount();
5164a766 1270
2bb7b766 1271 AliCDBManager::Instance()->GetStorage(fgkLocalCDB)->Put(fStatusEntry);
e7f62f16 1272
1273 SendMLInfo();
5164a766 1274}
e7f62f16 1275
1276//______________________________________________________________________________________________
1277void AliShuttle::SendMLInfo()
1278{
1279 //
1280 // sends ML information about the current status of the current detector being processed
1281 //
1282
1283 AliShuttleStatus* status = dynamic_cast<AliShuttleStatus*> (fStatusEntry->GetObject());
1284
1285 if (!status){
3301427a 1286 Log("SHUTTLE", "SendMLInfo - UNEXPECTED: status could not be read from current CDB entry");
e7f62f16 1287 return;
1288 }
1289
1290 TMonaLisaText mlStatus(Form("%s_status", fCurrentDetector.Data()), status->GetStatusName());
1291 TMonaLisaValue mlRetryCount(Form("%s_count", fCurrentDetector.Data()), status->GetCount());
1292
1293 TList mlList;
1294 mlList.Add(&mlStatus);
1295 mlList.Add(&mlRetryCount);
1296
ee6f7523 1297 TString mlID;
1298 mlID.Form("%d", GetCurrentRun());
1299 fMonaLisa->SendParameters(&mlList, mlID);
e7f62f16 1300}
1301
5164a766 1302//______________________________________________________________________________________________
1303Bool_t AliShuttle::ContinueProcessing()
1304{
9827400b 1305 // this function reads the AliShuttleStatus information from CDB and
1306 // checks if the processing should be continued
1307 // if yes it returns kTRUE and updates the AliShuttleStatus with nextStatus
2bb7b766 1308
57c1a579 1309 if (!fConfig->HostProcessDetector(fCurrentDetector)) return kFALSE;
1310
1311 AliPreprocessor* aPreprocessor =
1312 dynamic_cast<AliPreprocessor*> (fPreprocessorMap.GetValue(fCurrentDetector));
1313 if (!aPreprocessor)
1314 {
c88ad5db 1315 Log("SHUTTLE", Form("ContinueProcessing - %s: no preprocessor registered", fCurrentDetector.Data()));
57c1a579 1316 return kFALSE;
1317 }
1318
2bb7b766 1319 AliShuttleLogbookEntry::Status entryStatus =
eba76848 1320 fLogbookEntry->GetDetectorStatus(fCurrentDetector);
2bb7b766 1321
1322 if(entryStatus != AliShuttleLogbookEntry::kUnprocessed) {
c88ad5db 1323 Log("SHUTTLE", Form("ContinueProcessing - %s is %s",
2bb7b766 1324 fCurrentDetector.Data(),
1325 fLogbookEntry->GetDetectorStatusName(entryStatus)));
1326 return kFALSE;
1327 }
1328
1329 // if we get here, according to Shuttle logbook subdetector is in UNPROCESSED state
be48e3ea 1330
1331 // check if current run is first unprocessed run for current detector
1332 if (fConfig->StrictRunOrder(fCurrentDetector) &&
1333 !fFirstUnprocessed[GetDetPos(fCurrentDetector)])
1334 {
86aa42c3 1335 if (fTestMode == kNone)
1336 {
c88ad5db 1337 Log("SHUTTLE", Form("ContinueProcessing - %s requires strict run ordering"
1338 " but this is not the first unprocessed run!"));
86aa42c3 1339 return kFALSE;
1340 }
1341 else
1342 {
c88ad5db 1343 Log("SHUTTLE", Form("ContinueProcessing - In TESTMODE - "
1344 "Although %s requires strict run ordering "
1345 "and this is not the first unprocessed run, "
1346 "the SHUTTLE continues"));
86aa42c3 1347 }
be48e3ea 1348 }
1349
2bb7b766 1350 AliShuttleStatus* status = ReadShuttleStatus();
1351 if (!status) {
1352 // first time
1353 Log("SHUTTLE", Form("ContinueProcessing - %s: Processing first time",
1354 fCurrentDetector.Data()));
1355 status = new AliShuttleStatus(AliShuttleStatus::kStarted);
1356 return WriteShuttleStatus(status);
1357 }
1358
1359 // The following two cases shouldn't happen if Shuttle Logbook was correctly updated.
1360 // If it happens it may mean Logbook updating failed... let's do it now!
1361 if (status->GetStatus() == AliShuttleStatus::kDone ||
1362 status->GetStatus() == AliShuttleStatus::kFailed){
1363 Log("SHUTTLE", Form("ContinueProcessing - %s is already %s. Updating Shuttle Logbook",
1364 fCurrentDetector.Data(),
1365 status->GetStatusName(status->GetStatus())));
1366 UpdateShuttleLogbook(fCurrentDetector.Data(),
1367 status->GetStatusName(status->GetStatus()));
1368 return kFALSE;
1369 }
1370
3301427a 1371 if (status->GetStatus() == AliShuttleStatus::kStoreError) {
2bb7b766 1372 Log("SHUTTLE",
c88ad5db 1373 Form("ContinueProcessing - %s: Grid storage of one or more "
1374 "objects failed. Trying again now",
2bb7b766 1375 fCurrentDetector.Data()));
9827400b 1376 UpdateShuttleStatus(AliShuttleStatus::kStoreStarted);
1377 if (StoreOCDB()){
c88ad5db 1378 Log("SHUTTLE", Form("ContinueProcessing - %s: all objects "
1379 "successfully stored into main storage",
3301427a 1380 fCurrentDetector.Data()));
2bb7b766 1381 } else {
1382 Log("SHUTTLE",
1383 Form("ContinueProcessing - %s: Grid storage failed again",
1384 fCurrentDetector.Data()));
9827400b 1385 UpdateShuttleStatus(AliShuttleStatus::kStoreError);
2bb7b766 1386 }
1387 return kFALSE;
1388 }
1389
1390 // if we get here, there is a restart
57c1a579 1391 Bool_t cont = kFALSE;
2bb7b766 1392
1393 // abort conditions
cb343cfd 1394 if (status->GetCount() >= fConfig->GetMaxRetries()) {
57c1a579 1395 Log("SHUTTLE", Form("ContinueProcessing - %s failed %d times in status %s - "
1396 "Updating Shuttle Logbook", fCurrentDetector.Data(),
2bb7b766 1397 status->GetCount(), status->GetStatusName()));
1398 UpdateShuttleLogbook(fCurrentDetector.Data(), "FAILED");
e7f62f16 1399 UpdateShuttleStatus(AliShuttleStatus::kFailed);
3301427a 1400
1401 // there may still be objects in local OCDB and reference storage
1402 // and FXS databases may be not updated: do it now!
9827400b 1403
1404 // TODO Currently disabled, we want to keep files in case of failure!
1405 // CleanLocalStorage(fgkLocalCDB);
1406 // CleanLocalStorage(fgkLocalRefStorage);
1407 // UpdateTableFailCase();
1408
1409 // Send mail to detector expert!
c88ad5db 1410 Log("SHUTTLE", Form("ContinueProcessing - Sending mail to %s expert...",
1411 fCurrentDetector.Data()));
9827400b 1412 if (!SendMail())
1413 Log("SHUTTLE", Form("ContinueProcessing - Could not send mail to %s expert",
1414 fCurrentDetector.Data()));
3301427a 1415
57c1a579 1416 } else {
1417 Log("SHUTTLE", Form("ContinueProcessing - %s: restarting. "
1418 "Aborted before with %s. Retry number %d.", fCurrentDetector.Data(),
1419 status->GetStatusName(), status->GetCount()));
9827400b 1420 Bool_t increaseCount = kTRUE;
c88ad5db 1421 if (status->GetStatus() == AliShuttleStatus::kDCSError ||
1422 status->GetStatus() == AliShuttleStatus::kDCSStarted)
1423 increaseCount = kFALSE;
675f64cd 1424
9827400b 1425 UpdateShuttleStatus(AliShuttleStatus::kStarted, increaseCount);
57c1a579 1426 cont = kTRUE;
2bb7b766 1427 }
1428
57c1a579 1429 return cont;
5164a766 1430}
1431
1432//______________________________________________________________________________________________
2bb7b766 1433Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry)
58bc3020 1434{
73abe331 1435 //
b948db8d 1436 // Makes data retrieval for all detectors in the configuration.
2bb7b766 1437 // entry: Shuttle logbook entry, contains run paramenters and status of detectors
1438 // (Unprocessed, Inactive, Failed or Done).
d477ad88 1439 // Returns kFALSE in case of error occured and kTRUE otherwise
73abe331 1440 //
1441
9827400b 1442 if (!entry) return kFALSE;
2bb7b766 1443
1444 fLogbookEntry = entry;
1445
c88ad5db 1446 Log("SHUTTLE", Form("\t\t\t^*^*^*^*^*^*^*^*^*^*^*^* run %d: START ^*^*^*^*^*^*^*^*^*^*^*^*",
9827400b 1447 GetCurrentRun()));
2bb7b766 1448
e7f62f16 1449 // Send the information to ML
1450 TMonaLisaText mlStatus("SHUTTLE_status", "Processing");
9827400b 1451 TMonaLisaText mlRunType("SHUTTLE_runtype", Form("%s (%s)", entry->GetRunType(), entry->GetRunParameter("log")));
e7f62f16 1452
1453 TList mlList;
1454 mlList.Add(&mlStatus);
9827400b 1455 mlList.Add(&mlRunType);
e7f62f16 1456
ee6f7523 1457 TString mlID;
1458 mlID.Form("%d", GetCurrentRun());
1459 fMonaLisa->SendParameters(&mlList, mlID);
3301427a 1460
9827400b 1461 if (fLogbookEntry->IsDone())
1462 {
1463 Log("SHUTTLE","Process - Shuttle is already DONE. Updating logbook");
1464 UpdateShuttleLogbook("shuttle_done");
1465 fLogbookEntry = 0;
1466 return kTRUE;
1467 }
1468
1469 // read test mode if flag is set
1470 if (fReadTestMode)
1471 {
3d8bc902 1472 fTestMode = kNone;
9827400b 1473 TString logEntry(entry->GetRunParameter("log"));
1474 //printf("log entry = %s\n", logEntry.Data());
1475 TString searchStr("Testmode: ");
1476 Int_t pos = logEntry.Index(searchStr.Data());
1477 //printf("%d\n", pos);
1478 if (pos >= 0)
1479 {
1480 TSubString subStr = logEntry(pos + searchStr.Length(), logEntry.Length());
1481 //printf("%s\n", subStr.String().Data());
1482 TString newStr(subStr.Data());
1483 TObjArray* token = newStr.Tokenize(' ');
1484 if (token)
1485 {
1486 //token->Print();
1487 TObjString* tmpStr = dynamic_cast<TObjString*> (token->First());
1488 if (tmpStr)
1489 {
1490 Int_t testMode = tmpStr->String().Atoi();
1491 if (testMode > 0)
1492 {
c88ad5db 1493 Log("SHUTTLE", Form("Process - Enabling test mode %d", testMode));
9827400b 1494 SetTestMode((TestMode) testMode);
1495 }
1496 }
1497 delete token;
1498 }
1499 }
1500 }
c88ad5db 1501
eba76848 1502 fLogbookEntry->Print("all");
57f50b3c 1503
1504 // Initialization
d477ad88 1505 Bool_t hasError = kFALSE;
5164a766 1506
675f64cd 1507 // Set the CDB and Reference folders according to the year and LHC period
1508 TString lhcPeriod(GetLHCPeriod());
1509 if (lhcPeriod.Length() == 0)
1510 {
7d4cf768 1511 Log("SHUTTLE","Process - LHCPeriod not found in logbook!");
1512 return 0;
675f64cd 1513 }
1514
1515 if (fgkMainCDB.Length() == 0)
1516 fgkMainCDB = Form("alien://folder=/alice/data/%d/%s/OCDB?user=alidaq?cacheFold=/tmp/OCDBCache",
1517 GetCurrentYear(), lhcPeriod.Data());
1518
1519 if (fgkMainRefStorage.Length() == 0)
1520 fgkMainRefStorage = Form("alien://folder=/alice/data/%d/%s/Reference?user=alidaq?cacheFold=/tmp/OCDBCache",
1521 GetCurrentYear(), lhcPeriod.Data());
1522
57f50b3c 1523 // Loop on detectors in the configuration
b948db8d 1524 TIter iter(fConfig->GetDetectors());
2bb7b766 1525 TObjString* aDetector = 0;
b948db8d 1526
4508ab8b 1527 Bool_t first = kTRUE;
1528
be48e3ea 1529 while ((aDetector = (TObjString*) iter.Next()))
1530 {
7bfb2090 1531 fCurrentDetector = aDetector->String();
5164a766 1532
9e080f92 1533 if (ContinueProcessing() == kFALSE) continue;
4508ab8b 1534
1535 if (first)
1536 {
1537 // only read QueryCDB when needed and only once
1538 AliCDBStorage *mainCDBSto = AliCDBManager::Instance()->GetStorage(fgkMainCDB);
1539 if(mainCDBSto) mainCDBSto->QueryCDB(GetCurrentRun());
1540 AliCDBStorage *mainRefSto = AliCDBManager::Instance()->GetStorage(fgkMainRefStorage);
1541 if(mainRefSto) mainRefSto->QueryCDB(GetCurrentRun());
1542 first = kFALSE;
1543 }
9e080f92 1544
c88ad5db 1545 Log("SHUTTLE", Form("\t\t\t****** run %d - %s: START ******",
2bb7b766 1546 GetCurrentRun(), aDetector->GetName()));
1547
9d733021 1548 for(Int_t iSys=0;iSys<3;iSys++) fFXSCalled[iSys]=kFALSE;
1549
c88ad5db 1550 Log(fCurrentDetector.Data(), "Process - Starting processing");
85a80aa9 1551
be48e3ea 1552 Int_t pid = fork();
1553
1554 if (pid < 0)
1555 {
c88ad5db 1556 Log("SHUTTLE", "Process - ERROR: Forking failed");
be48e3ea 1557 }
1558 else if (pid > 0)
1559 {
1560 // parent
c88ad5db 1561 Log("SHUTTLE", Form("Process - In parent process of %d - %s: Starting monitoring",
be48e3ea 1562 GetCurrentRun(), aDetector->GetName()));
1563
1564 Long_t begin = time(0);
1565
1566 int status; // to be used with waitpid, on purpose an int (not Int_t)!
1567 while (waitpid(pid, &status, WNOHANG) == 0)
1568 {
1569 Long_t expiredTime = time(0) - begin;
1570
1571 if (expiredTime > fConfig->GetPPTimeOut())
1572 {
9827400b 1573 TString tmp;
c88ad5db 1574 tmp.Form("Process - Process of %s time out. "
1575 "Run time: %d seconds. Killing...",
1576 fCurrentDetector.Data(), expiredTime);
9827400b 1577 Log("SHUTTLE", tmp);
1578 Log(fCurrentDetector, tmp);
be48e3ea 1579
1580 kill(pid, 9);
1581
3301427a 1582 UpdateShuttleStatus(AliShuttleStatus::kPPTimeOut);
be48e3ea 1583 hasError = kTRUE;
1584
1585 gSystem->Sleep(1000);
1586 }
1587 else
1588 {
be48e3ea 1589 gSystem->Sleep(1000);
9827400b 1590
1591 TString checkStr;
1592 checkStr.Form("ps -o vsize --pid %d | tail -n 1", pid);
1593 FILE* pipe = gSystem->OpenPipe(checkStr, "r");
1594 if (!pipe)
1595 {
c88ad5db 1596 Log("SHUTTLE", Form("Process - Error: "
1597 "Could not open pipe to %s", checkStr.Data()));
9827400b 1598 continue;
1599 }
1600
1601 char buffer[100];
1602 if (!fgets(buffer, 100, pipe))
1603 {
c88ad5db 1604 Log("SHUTTLE", "Process - Error: ps did not return anything");
9827400b 1605 gSystem->ClosePipe(pipe);
1606 continue;
1607 }
1608 gSystem->ClosePipe(pipe);
1609
1610 //Log("SHUTTLE", Form("ps returned %s", buffer));
1611
1612 Int_t mem = 0;
1613 if ((sscanf(buffer, "%d\n", &mem) != 1) || !mem)
1614 {
c88ad5db 1615 Log("SHUTTLE", "Process - Error: Could not parse output of ps");
9827400b 1616 continue;
1617 }
1618
1619 if (expiredTime % 60 == 0)
ee6f7523 1620 {
c88ad5db 1621 Log("SHUTTLE", Form("Process - %s: Checking process. "
1622 "Run time: %d seconds - Memory consumption: %d KB",
1623 fCurrentDetector.Data(), expiredTime, mem));
ee6f7523 1624 SendAlive();
1625 }
9827400b 1626
1627 if (mem > fConfig->GetPPMaxMem())
1628 {
1629 TString tmp;
c88ad5db 1630 tmp.Form("Process - Process exceeds maximum allowed memory "
1631 "(%d KB > %d KB). Killing...",
9827400b 1632 mem, fConfig->GetPPMaxMem());
1633 Log("SHUTTLE", tmp);
1634 Log(fCurrentDetector, tmp);
1635
1636 kill(pid, 9);
1637
1638 UpdateShuttleStatus(AliShuttleStatus::kPPOutOfMemory);
1639 hasError = kTRUE;
1640
1641 gSystem->Sleep(1000);
1642 }
be48e3ea 1643 }
1644 }
1645
c88ad5db 1646 Log("SHUTTLE", Form("Process - In parent process of %d - %s: Client has terminated.",
be48e3ea 1647 GetCurrentRun(), aDetector->GetName()));
1648
1649 if (WIFEXITED(status))
1650 {
1651 Int_t returnCode = WEXITSTATUS(status);
1652
c88ad5db 1653 Log("SHUTTLE", Form("Process - %s: the return code is %d", fCurrentDetector.Data(),
3301427a 1654 returnCode));
be48e3ea 1655
9827400b 1656 if (returnCode == 0) hasError = kTRUE;
be48e3ea 1657 }
1658 }
1659 else if (pid == 0)
1660 {
1661 // client
c88ad5db 1662 Log("SHUTTLE", Form("Process - In client process of %d - %s", GetCurrentRun(),
1663 aDetector->GetName()));
be48e3ea 1664
c88ad5db 1665 Log("SHUTTLE", Form("Process - Redirecting output to %s log",fCurrentDetector.Data()));
ffa29e93 1666
546242fb 1667 if ((freopen(GetLogFileName(fCurrentDetector), "a", stdout)) == 0)
ffa29e93 1668 {
c88ad5db 1669 Log("SHUTTLE", "Process - Could not freopen stdout");
ffa29e93 1670 }
1671 else
1672 {
1673 fOutputRedirected = kTRUE;
1674 if ((dup2(fileno(stdout), fileno(stderr))) < 0)
c88ad5db 1675 Log("SHUTTLE", "Process - Could not redirect stderr");
ffa29e93 1676
1677 }
1678
5bac2bde 1679 TString wd = gSystem->WorkingDirectory();
675f64cd 1680 TString tmpDir = Form("%s/%s_%d_process", GetShuttleTempDir(),
1681 fCurrentDetector.Data(), GetCurrentRun());
5bac2bde 1682
d524ade6 1683 Int_t result = gSystem->GetPathInfo(tmpDir.Data(), 0, (Long64_t*) 0, 0, 0);
1684 if (!result) // temp dir already exists!
1685 {
1686 Log(fCurrentDetector.Data(),
1687 Form("Process - %s dir already exists! Removing...", tmpDir.Data()));
1688 gSystem->Exec(Form("rm -rf %s",tmpDir.Data()));
675f64cd 1689 }
1690
1691 if (gSystem->mkdir(tmpDir.Data(), 1))
1692 {
1693 Log(fCurrentDetector.Data(), "Process - could not make temp directory!!");
1694 gSystem->Exit(1);
d524ade6 1695 }
1696
1697 if (!gSystem->ChangeDirectory(tmpDir.Data()))
1698 {
1699 Log(fCurrentDetector.Data(), "Process - could not change directory!!");
1700 gSystem->Exit(1);
1701 }
5bac2bde 1702
9827400b 1703 Bool_t success = ProcessCurrentDetector();
5bac2bde 1704
1705 gSystem->ChangeDirectory(wd.Data());
b1d18693 1706
9827400b 1707 if (success) // Preprocessor finished successfully!
1708 {
b1d18693 1709 // remove temporary folder
fbc112e3 1710 // temporary commented (JF)
1711 //gSystem->Exec(Form("rm -rf %s",tmpDir.Data()));
b1d18693 1712
3301427a 1713 // Update time_processed field in FXS DB
1714 if (UpdateTable() == kFALSE)
5bac2bde 1715 Log("SHUTTLE", Form("Process - %s: Could not update FXS databases!",
1716 fCurrentDetector.Data()));
3301427a 1717
1718 // Transfer the data from local storage to main storage (Grid)
1719 UpdateShuttleStatus(AliShuttleStatus::kStoreStarted);
1720 if (StoreOCDB() == kFALSE)
1721 {
c88ad5db 1722 Log("SHUTTLE",
1723 Form("\t\t\t****** run %d - %s: STORAGE ERROR ******",
3301427a 1724 GetCurrentRun(), aDetector->GetName()));
1725 UpdateShuttleStatus(AliShuttleStatus::kStoreError);
9827400b 1726 success = kFALSE;
3301427a 1727 } else {
c88ad5db 1728 Log("SHUTTLE",
1729 Form("\t\t\t****** run %d - %s: DONE ******",
3301427a 1730 GetCurrentRun(), aDetector->GetName()));
1731 UpdateShuttleStatus(AliShuttleStatus::kDone);
9827400b 1732 UpdateShuttleLogbook(fCurrentDetector, "DONE");
3301427a 1733 }
c88ad5db 1734 } else
1735 {
1736 Log("SHUTTLE",
1737 Form("\t\t\t****** run %d - %s: PP ERROR ******",
1738 GetCurrentRun(), aDetector->GetName()));
be48e3ea 1739 }
1740
4b95672b 1741 for (UInt_t iSys=0; iSys<3; iSys++)
1742 {
1743 if (fFXSCalled[iSys]) fFXSlist[iSys].Clear();
1744 }
1745
c88ad5db 1746 Log("SHUTTLE", Form("Process - Client process of %d - %s is exiting now with %d.",
9827400b 1747 GetCurrentRun(), aDetector->GetName(), success));
be48e3ea 1748
1749 // the client exits here
9827400b 1750 gSystem->Exit(success);
be48e3ea 1751
1752 AliError("We should never get here!!!");
1753 }
7bfb2090 1754 }
5164a766 1755
c88ad5db 1756 Log("SHUTTLE", Form("\t\t\t^*^*^*^*^*^*^*^*^*^*^*^* run %d: FINISH ^*^*^*^*^*^*^*^*^*^*^*^*",
2bb7b766 1757 GetCurrentRun()));
1758
1759 //check if shuttle is done for this run, if so update logbook
1760 TObjArray checkEntryArray;
1761 checkEntryArray.SetOwner(1);
9e080f92 1762 TString whereClause = Form("where run=%d", GetCurrentRun());
b0e53b15 1763 if (!QueryShuttleLogbook(whereClause.Data(), checkEntryArray) ||
1764 checkEntryArray.GetEntries() == 0) {
9e080f92 1765 Log("SHUTTLE", Form("Process - Warning: Cannot check status of run %d on Shuttle logbook!",
1766 GetCurrentRun()));
1767 return hasError == kFALSE;
1768 }
b948db8d 1769
9e080f92 1770 AliShuttleLogbookEntry* checkEntry = dynamic_cast<AliShuttleLogbookEntry*>
1771 (checkEntryArray.At(0));
2bb7b766 1772
9e080f92 1773 if (checkEntry)
1774 {
1775 if (checkEntry->IsDone())
be48e3ea 1776 {
9e080f92 1777 Log("SHUTTLE","Process - Shuttle is DONE. Updating logbook");
1778 UpdateShuttleLogbook("shuttle_done");
1779 }
1780 else
1781 {
1782 for (UInt_t iDet=0; iDet<NDetectors(); iDet++)
be48e3ea 1783 {
9e080f92 1784 if (checkEntry->GetDetectorStatus(iDet) == AliShuttleLogbookEntry::kUnprocessed)
be48e3ea 1785 {
9e080f92 1786 AliDebug(2, Form("Run %d: setting %s as \"not first time unprocessed\"",
1787 checkEntry->GetRun(), GetDetName(iDet)));
1788 fFirstUnprocessed[iDet] = kFALSE;
be48e3ea 1789 }
1790 }
2bb7b766 1791 }
1792 }
1793
1794 fLogbookEntry = 0;
85a80aa9 1795
a7160fe9 1796 return hasError == kFALSE;
73abe331 1797}
1798
b948db8d 1799//______________________________________________________________________________________________
9827400b 1800Bool_t AliShuttle::ProcessCurrentDetector()
73abe331 1801{
1802 //
2bb7b766 1803 // Makes data retrieval just for a specific detector (fCurrentDetector).
73abe331 1804 // Threre should be a configuration for this detector.
73abe331 1805
1d172743 1806 Log("SHUTTLE", Form("ProcessCurrentDetector - Retrieving values for %s, run %d",
1807 fCurrentDetector.Data(), GetCurrentRun()));
73abe331 1808
d524ade6 1809 TString wd = gSystem->WorkingDirectory();
1810
2d9019b4 1811 if (!CleanReferenceStorage(fCurrentDetector.Data()))
546242fb 1812 return kFALSE;
d524ade6 1813
1814 gSystem->ChangeDirectory(wd.Data());
1815
1d172743 1816 TMap* dcsMap = new TMap();
3301427a 1817
1818 // call preprocessor
1819 AliPreprocessor* aPreprocessor =
1820 dynamic_cast<AliPreprocessor*> (fPreprocessorMap.GetValue(fCurrentDetector));
1821
1822 aPreprocessor->Initialize(GetCurrentRun(), GetCurrentStartTime(), GetCurrentEndTime());
1823
1824 Bool_t processDCS = aPreprocessor->ProcessDCS();
d477ad88 1825
651fdaab 1826 if (!processDCS)
1827 {
1d172743 1828 Log(fCurrentDetector, "ProcessCurrentDetector -"
1829 " The preprocessor requested to skip the retrieval of DCS values");
651fdaab 1830 }
8b739301 1831 else if (fTestMode & kSkipDCS)
2c15234c 1832 {
1d172743 1833 Log(fCurrentDetector, "ProcessCurrentDetector - In TESTMODE: Skipping DCS processing");
9827400b 1834 }
1835 else if (fTestMode & kErrorDCS)
1836 {
1d172743 1837 Log(fCurrentDetector, "ProcessCurrentDetector - In TESTMODE: Simulating DCS error");
3d8bc902 1838 UpdateShuttleStatus(AliShuttleStatus::kDCSStarted);
9827400b 1839 UpdateShuttleStatus(AliShuttleStatus::kDCSError);
1d172743 1840 delete dcsMap;
9827400b 1841 return kFALSE;
2c15234c 1842 } else {
3301427a 1843
1844 UpdateShuttleStatus(AliShuttleStatus::kDCSStarted);
1845
1d172743 1846 // Query DCS archive
1847 Int_t nServers = fConfig->GetNServers(fCurrentDetector);
a038aa70 1848
1d172743 1849 for (int iServ=0; iServ<nServers; iServ++)
2c15234c 1850 {
1d172743 1851
1852 TString host(fConfig->GetDCSHost(fCurrentDetector, iServ));
1853 Int_t port = fConfig->GetDCSPort(fCurrentDetector, iServ);
542b6cc8 1854 Int_t multiSplit = fConfig->GetMultiSplit(fCurrentDetector, iServ);
1855
1790d4b7 1856 Log(fCurrentDetector, Form("ProcessCurrentDetector -"
1857 " Querying DCS Amanda server %s:%d (%d of %d)",
1858 host.Data(), port, iServ+1, nServers));
1d172743 1859
1860 TMap* aliasMap = 0;
1861 TMap* dpMap = 0;
1862
1863 if (fConfig->GetDCSAliases(fCurrentDetector, iServ)->GetEntries() > 0)
2c15234c 1864 {
1d172743 1865 aliasMap = GetValueSet(host, port,
542b6cc8 1866 fConfig->GetDCSAliases(fCurrentDetector, iServ),
1867 kAlias, multiSplit);
1d172743 1868 if (!aliasMap)
1869 {
1870 Log(fCurrentDetector,
1871 Form("ProcessCurrentDetector -"
675f64cd 1872 " Error retrieving DCS aliases from server %s."
1873 " Sending mail to DCS experts!", host.Data()));
1d172743 1874 UpdateShuttleStatus(AliShuttleStatus::kDCSError);
675f64cd 1875
b5f1c82e 1876 //if (!SendMailToDCS())
1877 // Log("SHUTTLE", Form("ProcessCurrentDetector - Could not send mail to DCS experts!"));
675f64cd 1878
a038aa70 1879 delete dcsMap;
1d172743 1880 return kFALSE;
1881 }
2c15234c 1882 }
a038aa70 1883
1d172743 1884 if (fConfig->GetDCSDataPoints(fCurrentDetector, iServ)->GetEntries() > 0)
a038aa70 1885 {
1d172743 1886 dpMap = GetValueSet(host, port,
542b6cc8 1887 fConfig->GetDCSDataPoints(fCurrentDetector, iServ),
1888 kDP, multiSplit);
1d172743 1889 if (!dpMap)
1890 {
1891 Log(fCurrentDetector,
1892 Form("ProcessCurrentDetector -"
675f64cd 1893 " Error retrieving DCS data points from server %s."
1894 " Sending mail to DCS experts!", host.Data()));
1d172743 1895 UpdateShuttleStatus(AliShuttleStatus::kDCSError);
675f64cd 1896
b5f1c82e 1897 //if (!SendMailToDCS())
1898 // Log("SHUTTLE", Form("ProcessCurrentDetector - Could not send mail to DCS experts!"));
675f64cd 1899
1d172743 1900 if (aliasMap) delete aliasMap;
1901 delete dcsMap;
1902 return kFALSE;
1903 }
a038aa70 1904 }
1d172743 1905
1906 // merge aliasMap and dpMap into dcsMap
1907 if(aliasMap) {
1908 TIter iter(aliasMap);
a038aa70 1909 TObjString* key = 0;
1910 while ((key = (TObjString*) iter.Next()))
1d172743 1911 dcsMap->Add(key, aliasMap->GetValue(key->String()));
1912
1913 aliasMap->SetOwner(kFALSE);
1914 delete aliasMap;
1915 }
1916
1917 if(dpMap) {
1918 TIter iter(dpMap);
1919 TObjString* key = 0;
1920 while ((key = (TObjString*) iter.Next()))
1921 dcsMap->Add(key, dpMap->GetValue(key->String()));
1922
1923 dpMap->SetOwner(kFALSE);
1924 delete dpMap;
a038aa70 1925 }
73abe331 1926 }
1927 }
dc25836b 1928
b1d18693 1929 // save map into file, to help debugging in case of preprocessor error
fbc112e3 1930 TFile* f = TFile::Open("DCSMap.root","recreate");
b1d18693 1931 f->cd();
1932 dcsMap->Write("DCSMap", TObject::kSingleKey);
1933 f->Close();
fbc112e3 1934 delete f;
b1d18693 1935
2bb7b766 1936 // DCS Archive DB processing successful. Call Preprocessor!
85a80aa9 1937 UpdateShuttleStatus(AliShuttleStatus::kPPStarted);
a7160fe9 1938
a038aa70 1939 UInt_t returnValue = aPreprocessor->Process(dcsMap);
b948db8d 1940
3301427a 1941 if (returnValue > 0) // Preprocessor error!
1942 {
c88ad5db 1943 Log(fCurrentDetector, Form("ProcessCurrentDetector - "
1944 "Preprocessor failed. Process returned %d.", returnValue));
cb343cfd 1945 UpdateShuttleStatus(AliShuttleStatus::kPPError);
a038aa70 1946 dcsMap->DeleteAll();
1947 delete dcsMap;
9827400b 1948 return kFALSE;
1949 }
1950
1951 // preprocessor ok!
1952 UpdateShuttleStatus(AliShuttleStatus::kPPDone);
1953 Log(fCurrentDetector, Form("ProcessCurrentDetector - %s preprocessor returned success",
1954 fCurrentDetector.Data()));
b948db8d 1955
a038aa70 1956 dcsMap->DeleteAll();
1957 delete dcsMap;
b948db8d 1958
9827400b 1959 return kTRUE;
2bb7b766 1960}
1961
fbc112e3 1962//______________________________________________________________________________________________
1963void AliShuttle::CountOpenRuns()
1964{
1965 // Query DAQ's Shuttle logbook and sends the number of open runs to ML
1966
1967 // check connection, in case connect
1968 if (!Connect(3))
1969 return;
1970
1971 TString sqlQuery;
1972 sqlQuery = Form("select count(*) from %s where shuttle_done=0", fConfig->GetShuttlelbTable());
1973
1974 TSQLResult* aResult = fServer[3]->Query(sqlQuery);
1975 if (!aResult) {
1976 AliError(Form("Can't execute query <%s>!", sqlQuery.Data()));
1977 return;
1978 }
1979
1980 AliDebug(2,Form("Query = %s", sqlQuery.Data()));
1981
1982 if (aResult->GetRowCount() == 0) {
1983 AliError(Form("No result for query %s received", sqlQuery.Data()));
1984 return;
1985 }
1986
1987 if (aResult->GetFieldCount() != 1) {
1988 AliError(Form("Invalid field count for query %s received", sqlQuery.Data()));
1989 return;
1990 }
1991
1992 TSQLRow* aRow = aResult->Next();
1993 if (!aRow) {
1994 AliError(Form("Could not receive result of query %s", sqlQuery.Data()));
1995 return;
1996 }
1997
1998 TString result(aRow->GetField(0), aRow->GetFieldLength(0));
1999 Int_t count = result.Atoi();
2000
2001 Log("SHUTTLE", Form("%d unprocessed runs", count));
2002
2003 delete aRow;
2004 delete aResult;
2005
2006 TMonaLisaValue mlStatus("SHUTTLE_openruns", count);
2007
2008 TList mlList;
2009 mlList.Add(&mlStatus);
2010
2011 fMonaLisa->SendParameters(&mlList, "__PROCESSINGINFO__");
2012}
2013
2bb7b766 2014//______________________________________________________________________________________________
2015Bool_t AliShuttle::QueryShuttleLogbook(const char* whereClause,
2016 TObjArray& entries)
2017{
9827400b 2018 // Query DAQ's Shuttle logbook and fills detector status object.
2019 // Call QueryRunParameters to query DAQ logbook for run parameters.
2020 //
2bb7b766 2021
fc5a4708 2022 entries.SetOwner(1);
2023
2bb7b766 2024 // check connection, in case connect
fbc112e3 2025 if (!Connect(3)) return kFALSE;
2bb7b766 2026
2027 TString sqlQuery;
441b0e9c 2028 sqlQuery = Form("select * from %s %s order by run", fConfig->GetShuttlelbTable(), whereClause);
2bb7b766 2029
be48e3ea 2030 TSQLResult* aResult = fServer[3]->Query(sqlQuery);
2bb7b766 2031 if (!aResult) {
2032 AliError(Form("Can't execute query <%s>!", sqlQuery.Data()));
2033 return kFALSE;
2034 }
2035
fc5a4708 2036 AliDebug(2,Form("Query = %s", sqlQuery.Data()));
2037
2bb7b766 2038 if(aResult->GetRowCount() == 0) {
c88ad5db 2039 Log("SHUTTLE", "No entries in Shuttle Logbook match request");
9827400b 2040 delete aResult;
2041 return kTRUE;
2bb7b766 2042 }
2043
2044 // TODO Check field count!
db99d43e 2045 const UInt_t nCols = 23;
2bb7b766 2046 if (aResult->GetFieldCount() != (Int_t) nCols) {
c88ad5db 2047 Log("SHUTTLE", "Invalid SQL result field number!");
2bb7b766 2048 delete aResult;
2049 return kFALSE;
2050 }
2051
2bb7b766 2052 TSQLRow* aRow;
2053 while ((aRow = aResult->Next())) {
2054 TString runString(aRow->GetField(0), aRow->GetFieldLength(0));
2055 Int_t run = runString.Atoi();
2056
eba76848 2057 AliShuttleLogbookEntry *entry = QueryRunParameters(run);
2058 if (!entry)
2059 continue;
2bb7b766 2060
2061 // loop on detectors
eba76848 2062 for(UInt_t ii = 0; ii < nCols; ii++)
2063 entry->SetDetectorStatus(aResult->GetFieldName(ii), aRow->GetField(ii));
2bb7b766 2064
eba76848 2065 entries.AddLast(entry);
2bb7b766 2066 delete aRow;
2067 }
2068
2bb7b766 2069 delete aResult;
2070 return kTRUE;
2071}
2072
2073//______________________________________________________________________________________________
eba76848 2074AliShuttleLogbookEntry* AliShuttle::QueryRunParameters(Int_t run)
2bb7b766 2075{
eba76848 2076 //
2077 // Retrieve run parameters written in the DAQ logbook and sets them into AliShuttleLogbookEntry object
2078 //
2bb7b766 2079
2080 // check connection, in case connect
be48e3ea 2081 if (!Connect(3))
eba76848 2082 return 0;
2bb7b766 2083
2084 TString sqlQuery;
2c15234c 2085 sqlQuery.Form("select * from %s where run=%d", fConfig->GetDAQlbTable(), run);
2bb7b766 2086
be48e3ea 2087 TSQLResult* aResult = fServer[3]->Query(sqlQuery);
2bb7b766 2088 if (!aResult) {
c88ad5db 2089 Log("SHUTTLE", Form("Can't execute query <%s>!", sqlQuery.Data()));
eba76848 2090 return 0;
2bb7b766 2091 }
2092
eba76848 2093 if (aResult->GetRowCount() == 0) {
2bb7b766 2094 Log("SHUTTLE", Form("QueryRunParameters - No entry in DAQ Logbook for run %d. Skipping", run));
2095 delete aResult;
eba76848 2096 return 0;
2bb7b766 2097 }
2098
eba76848 2099 if (aResult->GetRowCount() > 1) {
c88ad5db 2100 Log("SHUTTLE", Form("QueryRunParameters - UNEXPECTED: "
2101 "more than one entry in DAQ Logbook for run %d!", run));
2bb7b766 2102 delete aResult;
eba76848 2103 return 0;
2bb7b766 2104 }
2105
eba76848 2106 TSQLRow* aRow = aResult->Next();
2107 if (!aRow)
2108 {
c88ad5db 2109 Log("SHUTTLE", Form("QueryRunParameters - Could not retrieve row for run %d. Skipping", run));
eba76848 2110 delete aResult;
2111 return 0;
2112 }
2bb7b766 2113
eba76848 2114 AliShuttleLogbookEntry* entry = new AliShuttleLogbookEntry(run);
2bb7b766 2115
eba76848 2116 for (Int_t ii = 0; ii < aResult->GetFieldCount(); ii++)
2117 entry->SetRunParameter(aResult->GetFieldName(ii), aRow->GetField(ii));
2bb7b766 2118
eba76848 2119 UInt_t startTime = entry->GetStartTime();
2120 UInt_t endTime = entry->GetEndTime();
2121
1abfbb60 2122// if (!startTime || !endTime || startTime > endTime)
2123// {
2124// Log("SHUTTLE",
2125// Form("QueryRunParameters - Invalid parameters for Run %d: startTime = %d, endTime = %d. Skipping!",
2126// run, startTime, endTime));
2127//
2128// Log("SHUTTLE", Form("Marking SHUTTLE done for run %d", run));
2129// fLogbookEntry = entry;
2130// if (!UpdateShuttleLogbook("shuttle_done"))
2131// {
2132// AliError(Form("Could not update logbook for run %d !", run));
2133// }
2134// fLogbookEntry = 0;
2135//
2136// delete entry;
2137// delete aRow;
2138// delete aResult;
2139// return 0;
2140// }
2141
2142 if (!startTime)
b0e53b15 2143 {
2144 Log("SHUTTLE",
1abfbb60 2145 Form("QueryRunParameters - Invalid parameters for Run %d: "
2146 "startTime = %d, endTime = %d. Skipping!",
2147 run, startTime, endTime));
b0e53b15 2148
2149 Log("SHUTTLE", Form("Marking SHUTTLE done for run %d", run));
2150 fLogbookEntry = entry;
ee6f7523 2151 if (!UpdateShuttleLogbook("shuttle_ignored"))
b0e53b15 2152 {
2153 AliError(Form("Could not update logbook for run %d !", run));
2154 }
2155 fLogbookEntry = 0;
2156
2157 delete entry;
2158 delete aRow;
2159 delete aResult;
2160 return 0;
2161 }
2162
1abfbb60 2163 if (startTime && !endTime)
2164 {
2165 // TODO Here we don't mark SHUTTLE done, because this may mean
2166 //the run is still ongoing!!
2167 Log("SHUTTLE",
2168 Form("QueryRunParameters - Invalid parameters for Run %d: "
2169 "startTime = %d, endTime = %d. Skipping (Shuttle won't be marked as DONE)!",
2170 run, startTime, endTime));
2171
2172 //Log("SHUTTLE", Form("Marking SHUTTLE done for run %d", run));
2173 //fLogbookEntry = entry;
2174 //if (!UpdateShuttleLogbook("shuttle_done"))
2175 //{
2176 // AliError(Form("Could not update logbook for run %d !", run));
2177 //}
2178 //fLogbookEntry = 0;
2179
2180 delete entry;
2181 delete aRow;
2182 delete aResult;
2183 return 0;
2184 }
2185
2186 if (startTime && endTime && (startTime > endTime))
2187 {
2188 Log("SHUTTLE",
2189 Form("QueryRunParameters - Invalid parameters for Run %d: "
2190 "startTime = %d, endTime = %d. Skipping!",
2191 run, startTime, endTime));
2192
2193 Log("SHUTTLE", Form("Marking SHUTTLE done for run %d", run));
2194 fLogbookEntry = entry;
ee6f7523 2195 if (!UpdateShuttleLogbook("shuttle_ignored"))
1abfbb60 2196 {
2197 AliError(Form("Could not update logbook for run %d !", run));
2198 }
2199 fLogbookEntry = 0;
2200
2201 delete entry;
2202 delete aRow;
2203 delete aResult;
2204 return 0;
2205 }
2206
b0e53b15 2207 TString totEventsStr = entry->GetRunParameter("totalEvents");
2208 Int_t totEvents = totEventsStr.Atoi();
2209 if (totEvents < 1)
2210 {
eba76848 2211 Log("SHUTTLE",
b0e53b15 2212 Form("QueryRunParameters - Run %d has 0 events - Skipping!", run));
2213
2214 Log("SHUTTLE", Form("Marking SHUTTLE done for run %d", run));
2215 fLogbookEntry = entry;
97e3c167 2216 if (!UpdateShuttleLogbook("shuttle_ignored"))
b0e53b15 2217 {
2218 AliError(Form("Could not update logbook for run %d !", run));
2219 }
2220 fLogbookEntry = 0;
2221
eba76848 2222 delete entry;
2bb7b766 2223 delete aRow;
eba76848 2224 delete aResult;
2225 return 0;
2bb7b766 2226 }
2227
eba76848 2228 delete aRow;
2bb7b766 2229 delete aResult;
eba76848 2230
2231 return entry;
2bb7b766 2232}
2233
a038aa70 2234//______________________________________________________________________________________________
2235TMap* AliShuttle::GetValueSet(const char* host, Int_t port, const TSeqCollection* entries,
542b6cc8 2236 DCSType type, Int_t multiSplit)
a038aa70 2237{
2238 // Retrieve all "entry" data points from the DCS server
2239 // host, port: TSocket connection parameters
2240 // entries: list of name of the alias or data point
2241 // type: kAlias or kDP
2242 // returns TMap of values, 0 when failure
542b6cc8 2243
2244 AliDCSClient client(host, port, fTimeout, fRetries, multiSplit);
b41b252a 2245
a038aa70 2246 TMap* result = 0;
b41b252a 2247 if (type == kAlias)
a038aa70 2248 {
b41b252a 2249 result = client.GetAliasValues(entries, GetCurrentStartTime(),
2250 GetCurrentEndTime());
2251 }
2252 else if (type == kDP)
2253 {
2254 result = client.GetDPValues(entries, GetCurrentStartTime(),
2255 GetCurrentEndTime());
2256 }
a038aa70 2257
b41b252a 2258 if (result == 0)
2259 {
2260 Log(fCurrentDetector.Data(), Form("GetValueSet - Can't get entries! Reason: %s",
1790d4b7 2261 client.GetErrorString(client.GetResultErrorCode())));
2262 if (client.GetResultErrorCode() == AliDCSClient::fgkServerError)
2263 Log(fCurrentDetector.Data(), Form("GetValueSet - Server error code: %s",
2264 client.GetServerError().Data()));
a038aa70 2265
b41b252a 2266 return 0;
a038aa70 2267 }
b41b252a 2268
a038aa70 2269 return result;
2270}
b41b252a 2271
b948db8d 2272//______________________________________________________________________________________________
57f50b3c 2273const char* AliShuttle::GetFile(Int_t system, const char* detector,
2274 const char* id, const char* source)
b948db8d 2275{
9827400b 2276 // Get calibration file from file exchange servers
2277 // First queris the FXS database for the file name, using the run, detector, id and source info
2278 // then calls RetrieveFile(filename) for actual copy to local disk
2279 // run: current run being processed (given by Logbook entry fLogbookEntry)
2280 // detector: the Preprocessor name
2281 // id: provided as a parameter by the Preprocessor
2282 // source: provided by the Preprocessor through GetFileSources function
2283
2284 // check if test mode should simulate a FXS error
2285 if (fTestMode & kErrorFXSFiles)
2286 {
2287 Log(detector, Form("GetFile - In TESTMODE - Simulating error while connecting to %s FXS", GetSystemName(system)));
2288 return 0;
2289 }
2290
57f50b3c 2291 // check connection, in case connect
9d733021 2292 if (!Connect(system))
eba76848 2293 {
9d733021 2294 Log(detector, Form("GetFile - Couldn't connect to %s FXS database", GetSystemName(system)));
57f50b3c 2295 return 0;
2296 }
2297
2298 // Query preparation
9d733021 2299 TString sourceName(source);
d386d623 2300 Int_t nFields = 3;
2301 TString sqlQueryStart = Form("select filePath,size,fileChecksum from %s where",
2302 fConfig->GetFXSdbTable(system));
2303 TString whereClause = Form("run=%d and detector=\"%s\" and fileId=\"%s\"",
2304 GetCurrentRun(), detector, id);
2305
9d733021 2306 if (system == kDAQ)
2307 {
d386d623 2308 whereClause += Form(" and DAQsource=\"%s\"", source);
57f50b3c 2309 }
9d733021 2310 else if (system == kDCS)
eba76848 2311 {
9d733021 2312 sourceName="none";
57f50b3c 2313 }
9d733021 2314 else if (system == kHLT)
9e080f92 2315 {
d386d623 2316 whereClause += Form(" and DDLnumbers=\"%s\"", source);
9d733021 2317 nFields = 3;
9e080f92 2318 }
2319
9e080f92 2320 TString sqlQuery = Form("%s %s", sqlQueryStart.Data(), whereClause.Data());
2321
2322 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
2323
2324 // Query execution
2325 TSQLResult* aResult = 0;
9d733021 2326 aResult = dynamic_cast<TSQLResult*> (fServer[system]->Query(sqlQuery));
9e080f92 2327 if (!aResult) {
9d733021 2328 Log(detector, Form("GetFileName - Can't execute SQL query to %s database for: id = %s, source = %s",
2329 GetSystemName(system), id, sourceName.Data()));
9e080f92 2330 return 0;
2331 }
2332
2333 if(aResult->GetRowCount() == 0)
2334 {
2335 Log(detector,
9d733021 2336 Form("GetFileName - No entry in %s FXS db for: id = %s, source = %s",
2337 GetSystemName(system), id, sourceName.Data()));
9e080f92 2338 delete aResult;
2339 return 0;
2340 }
2bb7b766 2341
9e080f92 2342 if (aResult->GetRowCount() > 1) {
2343 Log(detector,
9d733021 2344 Form("GetFileName - More than one entry in %s FXS db for: id = %s, source = %s",
2345 GetSystemName(system), id, sourceName.Data()));
9e080f92 2346 delete aResult;
2347 return 0;
2348 }
2349
9d733021 2350 if (aResult->GetFieldCount() != nFields) {
9e080f92 2351 Log(detector,
9d733021 2352 Form("GetFileName - Wrong field count in %s FXS db for: id = %s, source = %s",
2353 GetSystemName(system), id, sourceName.Data()));
9e080f92 2354 delete aResult;
2355 return 0;
2356 }
2357
2358 TSQLRow* aRow = dynamic_cast<TSQLRow*> (aResult->Next());
2359
2360 if (!aRow){
9d733021 2361 Log(detector, Form("GetFileName - Empty set result in %s FXS db from query: id = %s, source = %s",
2362 GetSystemName(system), id, sourceName.Data()));
9e080f92 2363 delete aResult;
2364 return 0;
2365 }
2366
2367 TString filePath(aRow->GetField(0), aRow->GetFieldLength(0));
2368 TString fileSize(aRow->GetField(1), aRow->GetFieldLength(1));
d386d623 2369 TString fileChecksum(aRow->GetField(2), aRow->GetFieldLength(2));
9e080f92 2370
2371 delete aResult;
2372 delete aRow;
2373
d386d623 2374 AliDebug(2, Form("filePath = %s; size = %s, fileChecksum = %s",
2375 filePath.Data(), fileSize.Data(), fileChecksum.Data()));
9e080f92 2376
9e080f92 2377 // retrieved file is renamed to make it unique
675f64cd 2378 TString localFileName = Form("%s/%s_%d_process/%s_%s_%d_%s_%s.shuttle",
2379 GetShuttleTempDir(), detector, GetCurrentRun(),
d524ade6 2380 GetSystemName(system), detector, GetCurrentRun(),
2381 id, sourceName.Data());
9d733021 2382
9e080f92 2383
9d733021 2384 // file retrieval from FXS
4b95672b 2385 UInt_t nRetries = 0;
2386 UInt_t maxRetries = 3;
2387 Bool_t result = kFALSE;
2388
2389 // copy!! if successful TSystem::Exec returns 0
2390 while(nRetries++ < maxRetries) {
2391 AliDebug(2, Form("Trying to copy file. Retry # %d", nRetries));
2392 result = RetrieveFile(system, filePath.Data(), localFileName.Data());
2393 if(!result)
2394 {
2395 Log(detector, Form("GetFileName - Copy of file %s from %s FXS failed",
9d733021 2396 filePath.Data(), GetSystemName(system)));
4b95672b 2397 continue;
4f0749a8 2398 }
9e080f92 2399
d386d623 2400 if (fileChecksum.Length()>0)
4b95672b 2401 {
2402 // compare md5sum of local file with the one stored in the FXS DB
d524ade6 2403 Int_t md5Comp = gSystem->Exec(Form("md5sum %s |grep %s 2>&1 > /dev/null",
2404 localFileName.Data(), fileChecksum.Data()));
9e080f92 2405
4b95672b 2406 if (md5Comp != 0)
2407 {
2408 Log(detector, Form("GetFileName - md5sum of file %s does not match with local copy!",
2409 filePath.Data()));
2410 result = kFALSE;
2411 continue;
2412 }
d386d623 2413 } else {
2414 Log(fCurrentDetector, Form("GetFile - md5sum of file %s not set in %s database, skipping comparison",
2415 filePath.Data(), GetSystemName(system)));
9d733021 2416 }
4b95672b 2417 if (result) break;
9e080f92 2418 }
2419
4b95672b 2420 if(!result) return 0;
2421
9d733021 2422 fFXSCalled[system]=kTRUE;
2423 TObjString *fileParams = new TObjString(Form("%s#!?!#%s", id, sourceName.Data()));
2424 fFXSlist[system].Add(fileParams);
9e080f92 2425
675f64cd 2426 static TString staticLocalFileName;
2427 staticLocalFileName.Form("%s", localFileName.Data());
2428
c88ad5db 2429 Log(fCurrentDetector, Form("GetFile - Retrieved file with id %s and "
2430 "source %s from %s to %s", id, source,
d524ade6 2431 GetSystemName(system), localFileName.Data()));
675f64cd 2432
d524ade6 2433 return staticLocalFileName.Data();
2bb7b766 2434}
2435
2436//______________________________________________________________________________________________
9d733021 2437Bool_t AliShuttle::RetrieveFile(UInt_t system, const char* fxsFileName, const char* localFileName)
9e080f92 2438{
9827400b 2439 //
2440 // Copies file from FXS to local Shuttle machine
2441 //
2bb7b766 2442
9e080f92 2443 // check temp directory: trying to cd to temp; if it does not exist, create it
d524ade6 2444 AliDebug(2, Form("Copy file %s from %s FXS into %s",
2445 GetSystemName(system), fxsFileName, localFileName));
2446
2447 TString tmpDir(localFileName);
2448
2449 tmpDir = tmpDir(0,tmpDir.Last('/'));
9e080f92 2450
d524ade6 2451 Int_t noDir = gSystem->GetPathInfo(tmpDir.Data(), 0, (Long64_t*) 0, 0, 0);
2452 if (noDir) // temp dir does not exists!
2453 {
2454 if (gSystem->mkdir(tmpDir.Data(), 1))
2455 {
2456 Log(fCurrentDetector.Data(), "RetrieveFile - could not make temp directory!!");
9e080f92 2457 return kFALSE;
2458 }
9e080f92 2459 }
2460
9d733021 2461 TString baseFXSFolder;
2462 if (system == kDAQ)
2463 {
2464 baseFXSFolder = "FES/";
2465 }
2466 else if (system == kDCS)
2467 {
2468 baseFXSFolder = "";
2469 }
2470 else if (system == kHLT)
2471 {
42fde080 2472 baseFXSFolder = "/opt/FXS/";
9d733021 2473 }
2474
2475
d524ade6 2476 TString command = Form("scp -oPort=%d -2 %s@%s:%s%s %s",
9d733021 2477 fConfig->GetFXSPort(system),
2478 fConfig->GetFXSUser(system),
2479 fConfig->GetFXSHost(system),
2480 baseFXSFolder.Data(),
2481 fxsFileName,
9e080f92 2482 localFileName);
2483
2484 AliDebug(2, Form("%s",command.Data()));
2485
4b95672b 2486 Bool_t result = (gSystem->Exec(command.Data()) == 0);
9e080f92 2487
4b95672b 2488 return result;
9e080f92 2489}
2490
2491//______________________________________________________________________________________________
9d733021 2492TList* AliShuttle::GetFileSources(Int_t system, const char* detector, const char* id)
2493{
9827400b 2494 //
2495 // Get sources producing the condition file Id from file exchange servers
4a33bdd9 2496 // if id is NULL all sources are returned (distinct)
9827400b 2497 //
1bcd28db 2498
8884d71e 2499 if (id)
2500 {
2501 Log(detector, Form("GetFileSources - Querying %s FXS for files with id %s produced by %s", GetSystemName(system), id, detector));
2502 } else {
2503 Log(detector, Form("GetFileSources - Querying %s FXS for files produced by %s", GetSystemName(system), detector));
2504 }
9827400b 2505
2506 // check if test mode should simulate a FXS error
2507 if (fTestMode & kErrorFXSSources)
2508 {
2509 Log(detector, Form("GetFileSources - In TESTMODE - Simulating error while connecting to %s FXS", GetSystemName(system)));
2510 return 0;
2511 }
2512
9d733021 2513 if (system == kDCS)
2514 {
c88ad5db 2515 Log(detector, "GetFileSources - WARNING: DCS system has only one source of data!");
6297b37d 2516 TList *list = new TList();
2517 list->SetOwner(1);
2518 list->Add(new TObjString(" "));
2519 return list;
9d733021 2520 }
9e080f92 2521
2522 // check connection, in case connect
9d733021 2523 if (!Connect(system))
2524 {
4a33bdd9 2525 Log(detector, Form("GetFileSources - Couldn't connect to %s FXS database", GetSystemName(system)));
9d733021 2526 return NULL;
9e080f92 2527 }
2528
9d733021 2529 TString sourceName = 0;
2530 if (system == kDAQ)
2531 {
2532 sourceName = "DAQsource";
2533 } else if (system == kHLT)
2534 {
2535 sourceName = "DDLnumbers";
2536 }
2537
4a33bdd9 2538 TString sqlQueryStart = Form("select distinct %s from %s where", sourceName.Data(), fConfig->GetFXSdbTable(system));
2539 TString whereClause = Form("run=%d and detector=\"%s\"",
2540 GetCurrentRun(), detector);
2541 if (id)
2542 whereClause += Form(" and fileId=\"%s\"", id);
9e080f92 2543 TString sqlQuery = Form("%s %s", sqlQueryStart.Data(), whereClause.Data());
2544
2545 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
2546
2547 // Query execution
2548 TSQLResult* aResult;
9d733021 2549 aResult = fServer[system]->Query(sqlQuery);
9e080f92 2550 if (!aResult) {
9d733021 2551 Log(detector, Form("GetFileSources - Can't execute SQL query to %s database for id: %s",
2552 GetSystemName(system), id));
9e080f92 2553 return 0;
2554 }
2555
86aa42c3 2556 TList *list = new TList();
2557 list->SetOwner(1);
2558
9d733021 2559 if (aResult->GetRowCount() == 0)
2560 {
9e080f92 2561 Log(detector,
9d733021 2562 Form("GetFileSources - No entry in %s FXS table for id: %s", GetSystemName(system), id));
9e080f92 2563 delete aResult;
86aa42c3 2564 return list;
9e080f92 2565 }
2566
1bcd28db 2567 Log(detector, Form("GetFileSources - Found %d sources", aResult->GetRowCount()));
9e080f92 2568
1bcd28db 2569 TSQLRow* aRow;
9d733021 2570 while ((aRow = aResult->Next()))
2571 {
9e080f92 2572
9d733021 2573 TString source(aRow->GetField(0), aRow->GetFieldLength(0));
2574 AliDebug(2, Form("%s = %s", sourceName.Data(), source.Data()));
2575 list->Add(new TObjString(source));
9e080f92 2576 delete aRow;
2577 }
9d733021 2578
9e080f92 2579 delete aResult;
2580
2581 return list;
2bb7b766 2582}
2583
4a33bdd9 2584//______________________________________________________________________________________________
2585TList* AliShuttle::GetFileIDs(Int_t system, const char* detector, const char* source)
2586{
2587 //
2588 // Get all ids of condition files produced by a given source from file exchange servers
2589 //
2590
1bcd28db 2591 Log(detector, Form("GetFileIDs - Retrieving ids with source %s with %s", source, GetSystemName(system)));
2592
4a33bdd9 2593 // check if test mode should simulate a FXS error
2594 if (fTestMode & kErrorFXSSources)
2595 {
2596 Log(detector, Form("GetFileIDs - In TESTMODE - Simulating error while connecting to %s FXS", GetSystemName(system)));
2597 return 0;
2598 }
2599
2600 // check connection, in case connect
2601 if (!Connect(system))
2602 {
2603 Log(detector, Form("GetFileIDs - Couldn't connect to %s FXS database", GetSystemName(system)));
2604 return NULL;
2605 }
2606
2607 TString sourceName = 0;
2608 if (system == kDAQ)
2609 {
2610 sourceName = "DAQsource";
2611 } else if (system == kHLT)
2612 {
2613 sourceName = "DDLnumbers";
2614 }
2615
2616 TString sqlQueryStart = Form("select fileId from %s where", fConfig->GetFXSdbTable(system));
2617 TString whereClause = Form("run=%d and detector=\"%s\"",
2618 GetCurrentRun(), detector);
2619 if (sourceName.Length() > 0 && source)
2620 whereClause += Form(" and %s=\"%s\"", sourceName.Data(), source);
2621 TString sqlQuery = Form("%s %s", sqlQueryStart.Data(), whereClause.Data());
2622
2623 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
2624
2625 // Query execution
2626 TSQLResult* aResult;
2627 aResult = fServer[system]->Query(sqlQuery);
2628 if (!aResult) {
2629 Log(detector, Form("GetFileIDs - Can't execute SQL query to %s database for source: %s",
2630 GetSystemName(system), source));
2631 return 0;
2632 }
2633
2634 TList *list = new TList();
2635 list->SetOwner(1);
2636
2637 if (aResult->GetRowCount() == 0)
2638 {
2639 Log(detector,
2640 Form("GetFileIDs - No entry in %s FXS table for source: %s", GetSystemName(system), source));
2641 delete aResult;
2642 return list;
2643 }
2644
1bcd28db 2645 Log(detector, Form("GetFileIDs - Found %d ids", aResult->GetRowCount()));
2646
4a33bdd9 2647 TSQLRow* aRow;
2648
2649 while ((aRow = aResult->Next()))
2650 {
2651
2652 TString id(aRow->GetField(0), aRow->GetFieldLength(0));
2653 AliDebug(2, Form("fileId = %s", id.Data()));
2654 list->Add(new TObjString(id));
2655 delete aRow;
2656 }
2657
2658 delete aResult;
2659
2660 return list;
2661}
2662
2bb7b766 2663//______________________________________________________________________________________________
9d733021 2664Bool_t AliShuttle::Connect(Int_t system)
2bb7b766 2665{
9827400b 2666 // Connect to MySQL Server of the system's FXS MySQL databases
2667 // DAQ Logbook, Shuttle Logbook and DAQ FXS db are on the same host
2668 //
57f50b3c 2669
9d733021 2670 // check connection: if already connected return
2671 if(fServer[system] && fServer[system]->IsConnected()) return kTRUE;
57f50b3c 2672
9d733021 2673 TString dbHost, dbUser, dbPass, dbName;
57f50b3c 2674
9d733021 2675 if (system < 3) // FXS db servers
2676 {
2677 dbHost = Form("mysql://%s:%d", fConfig->GetFXSdbHost(system), fConfig->GetFXSdbPort(system));
2678 dbUser = fConfig->GetFXSdbUser(system);
2679 dbPass = fConfig->GetFXSdbPass(system);
2680 dbName = fConfig->GetFXSdbName(system);
2681 } else { // Run & Shuttle logbook servers
2682 // TODO Will the Shuttle logbook server be the same as the Run logbook server ???
2683 dbHost = Form("mysql://%s:%d", fConfig->GetDAQlbHost(), fConfig->GetDAQlbPort());
2684 dbUser = fConfig->GetDAQlbUser();
2685 dbPass = fConfig->GetDAQlbPass();
2686 dbName = fConfig->GetDAQlbDB();
2687 }
57f50b3c 2688
9d733021 2689 fServer[system] = TSQLServer::Connect(dbHost.Data(), dbUser.Data(), dbPass.Data());
2690 if (!fServer[system] || !fServer[system]->IsConnected()) {
2691 if(system < 3)
2692 {
2693 AliError(Form("Can't establish connection to FXS database for %s",
2694 AliShuttleInterface::GetSystemName(system)));
2695 } else {
2696 AliError("Can't establish connection to Run logbook.");
57f50b3c 2697 }
9d733021 2698 if(fServer[system]) delete fServer[system];
2699 return kFALSE;
2bb7b766 2700 }
57f50b3c 2701
9d733021 2702 // Get tables
2703 TSQLResult* aResult=0;
2704 switch(system){
2705 case kDAQ:
2706 aResult = fServer[kDAQ]->GetTables(dbName.Data());
2707 break;
2708 case kDCS:
2709 aResult = fServer[kDCS]->GetTables(dbName.Data());
2710 break;
2711 case kHLT:
2712 aResult = fServer[kHLT]->GetTables(dbName.Data());
2713 break;
2714 default:
2715 aResult = fServer[3]->GetTables(dbName.Data());
2716 break;
2717 }
2718
2719 delete aResult;
2bb7b766 2720 return kTRUE;
2721}
57f50b3c 2722
9e080f92 2723//______________________________________________________________________________________________
9d733021 2724Bool_t AliShuttle::UpdateTable()
9e080f92 2725{
9827400b 2726 //
2727 // Update FXS table filling time_processed field in all rows corresponding to current run and detector
2728 //
9e080f92 2729
9d733021 2730 Bool_t result = kTRUE;
9e080f92 2731
9d733021 2732 for (UInt_t system=0; system<3; system++)
2733 {
2734 if(!fFXSCalled[system]) continue;
9e080f92 2735
9d733021 2736 // check connection, in case connect
2737 if (!Connect(system))
2738 {
2739 Log(fCurrentDetector, Form("UpdateTable - Couldn't connect to %s FXS database", GetSystemName(system)));
2740 result = kFALSE;
2741 continue;
9e080f92 2742 }
9e080f92 2743
9d733021 2744 TTimeStamp now; // now
2745
2746 // Loop on FXS list entries
2747 TIter iter(&fFXSlist[system]);
2748 TObjString *aFXSentry=0;
2749 while ((aFXSentry = dynamic_cast<TObjString*> (iter.Next())))
2750 {
2751 TString aFXSentrystr = aFXSentry->String();
2752 TObjArray *aFXSarray = aFXSentrystr.Tokenize("#!?!#");
2753 if (!aFXSarray || aFXSarray->GetEntries() != 2 )
2754 {
2755 Log(fCurrentDetector, Form("UpdateTable - error updating %s FXS entry. Check string: <%s>",
2756 GetSystemName(system), aFXSentrystr.Data()));
2757 if(aFXSarray) delete aFXSarray;
2758 result = kFALSE;
2759 continue;
2760 }
2761 const char* fileId = ((TObjString*) aFXSarray->At(0))->GetName();
2762 const char* source = ((TObjString*) aFXSarray->At(1))->GetName();
2763
2764 TString whereClause;
2765 if (system == kDAQ)
2766 {
2767 whereClause = Form("where run=%d and detector=\"%s\" and fileId=\"%s\" and DAQsource=\"%s\";",
2768 GetCurrentRun(), fCurrentDetector.Data(), fileId, source);
2769 }
2770 else if (system == kDCS)
2771 {
2772 whereClause = Form("where run=%d and detector=\"%s\" and fileId=\"%s\";",
2773 GetCurrentRun(), fCurrentDetector.Data(), fileId);
2774 }
2775 else if (system == kHLT)
2776 {
2777 whereClause = Form("where run=%d and detector=\"%s\" and fileId=\"%s\" and DDLnumbers=\"%s\";",
2778 GetCurrentRun(), fCurrentDetector.Data(), fileId, source);
2779 }
2780
2781 delete aFXSarray;
9e080f92 2782
9d733021 2783 TString sqlQuery = Form("update %s set time_processed=%d %s", fConfig->GetFXSdbTable(system),
2784 now.GetSec(), whereClause.Data());
9e080f92 2785
9d733021 2786 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
9e080f92 2787
9d733021 2788 // Query execution
2789 TSQLResult* aResult;
2790 aResult = dynamic_cast<TSQLResult*> (fServer[system]->Query(sqlQuery));
2791 if (!aResult)
2792 {
2793 Log(fCurrentDetector, Form("UpdateTable - %s db: can't execute SQL query <%s>",
2794 GetSystemName(system), sqlQuery.Data()));
2795 result = kFALSE;
2796 continue;
2797 }
2798 delete aResult;
9e080f92 2799 }
9e080f92 2800 }
2801
9d733021 2802 return result;
9e080f92 2803}
57f50b3c 2804
3301427a 2805//______________________________________________________________________________________________
2806Bool_t AliShuttle::UpdateTableFailCase()
2807{
9827400b 2808 // Update FXS table filling time_processed field in all rows corresponding to current run and detector
2809 // this is called in case the preprocessor is declared failed for the current run, because
2810 // the fields are updated only in case of success
3301427a 2811
2812 Bool_t result = kTRUE;
2813
2814 for (UInt_t system=0; system<3; system++)
2815 {
2816 // check connection, in case connect
2817 if (!Connect(system))
2818 {
2819 Log(fCurrentDetector, Form("UpdateTableFailCase - Couldn't connect to %s FXS database",
2820 GetSystemName(system)));
2821 result = kFALSE;
2822 continue;
2823 }
2824
2825 TTimeStamp now; // now
2826
2827 // Loop on FXS list entries
2828
2829 TString whereClause = Form("where run=%d and detector=\"%s\";",
2830 GetCurrentRun(), fCurrentDetector.Data());
2831
2832
2833 TString sqlQuery = Form("update %s set time_processed=%d %s", fConfig->GetFXSdbTable(system),
2834 now.GetSec(), whereClause.Data());
2835
2836 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
2837
2838 // Query execution
2839 TSQLResult* aResult;
2840 aResult = dynamic_cast<TSQLResult*> (fServer[system]->Query(sqlQuery));
2841 if (!aResult)
2842 {
2843 Log(fCurrentDetector, Form("UpdateTableFailCase - %s db: can't execute SQL query <%s>",
2844 GetSystemName(system), sqlQuery.Data()));
2845 result = kFALSE;
2846 continue;
2847 }
2848 delete aResult;
2849 }
2850
2851 return result;
2852}
2853
2bb7b766 2854//______________________________________________________________________________________________
2855Bool_t AliShuttle::UpdateShuttleLogbook(const char* detector, const char* status)
2856{
e7f62f16 2857 //
2858 // Update Shuttle logbook filling detector or shuttle_done column
2859 // ex. of usage: UpdateShuttleLogbook("PHOS", "DONE") or UpdateShuttleLogbook("shuttle_done")
2860 //
57f50b3c 2861
2bb7b766 2862 // check connection, in case connect
be48e3ea 2863 if(!Connect(3)){
2bb7b766 2864 Log("SHUTTLE", "UpdateShuttleLogbook - Couldn't connect to DAQ Logbook.");
2865 return kFALSE;
57f50b3c 2866 }
2867
2bb7b766 2868 TString detName(detector);
2869 TString setClause;
ee6f7523 2870 if (detName == "shuttle_done" || detName == "shuttle_ignored")
e7f62f16 2871 {
2bb7b766 2872 setClause = "set shuttle_done=1";
e7f62f16 2873
ee6f7523 2874 if (detName == "shuttle_done")
b0e53b15 2875 {
2876 // Send the information to ML
2877 TMonaLisaText mlStatus("SHUTTLE_status", "Done");
e7f62f16 2878
b0e53b15 2879 TList mlList;
2880 mlList.Add(&mlStatus);
2881
ee6f7523 2882 TString mlID;
2883 mlID.Form("%d", GetCurrentRun());
2884 fMonaLisa->SendParameters(&mlList, mlID);
b0e53b15 2885 }
2bb7b766 2886 } else {
2bb7b766 2887 TString statusStr(status);
2888 if(statusStr.Contains("done", TString::kIgnoreCase) ||
2889 statusStr.Contains("failed", TString::kIgnoreCase)){
eba76848 2890 setClause = Form("set %s=\"%s\"", detector, status);
2bb7b766 2891 } else {
2892 Log("SHUTTLE",
2893 Form("UpdateShuttleLogbook - Invalid status <%s> for detector %s",
2894 status, detector));
2895 return kFALSE;
2896 }
2897 }
57f50b3c 2898
2bb7b766 2899 TString whereClause = Form("where run=%d", GetCurrentRun());
2900
441b0e9c 2901 TString sqlQuery = Form("update %s %s %s",
2902 fConfig->GetShuttlelbTable(), setClause.Data(), whereClause.Data());
57f50b3c 2903
2bb7b766 2904 AliDebug(2, Form("SQL query: \n%s",sqlQuery.Data()));
2905
2906 // Query execution
2907 TSQLResult* aResult;
be48e3ea 2908 aResult = dynamic_cast<TSQLResult*> (fServer[3]->Query(sqlQuery));
2bb7b766 2909 if (!aResult) {
2910 Log("SHUTTLE", Form("UpdateShuttleLogbook - Can't execute query <%s>", sqlQuery.Data()));
2911 return kFALSE;
57f50b3c 2912 }
2bb7b766 2913 delete aResult;
57f50b3c 2914
2915 return kTRUE;
2916}
2917
2918//______________________________________________________________________________________________
2bb7b766 2919Int_t AliShuttle::GetCurrentRun() const
2920{
9827400b 2921 //
2922 // Get current run from logbook entry
2923 //
57f50b3c 2924
2bb7b766 2925 return fLogbookEntry ? fLogbookEntry->GetRun() : -1;
57f50b3c 2926}
2927
2928//______________________________________________________________________________________________
2bb7b766 2929UInt_t AliShuttle::GetCurrentStartTime() const
2930{
9827400b 2931 //
2932 // get current start time
2933 //
57f50b3c 2934
2bb7b766 2935 return fLogbookEntry ? fLogbookEntry->GetStartTime() : 0;
57f50b3c 2936}
2937
2938//______________________________________________________________________________________________
2bb7b766 2939UInt_t AliShuttle::GetCurrentEndTime() const
2940{
9827400b 2941 //
2942 // get current end time from logbook entry
2943 //
57f50b3c 2944
2bb7b766 2945 return fLogbookEntry ? fLogbookEntry->GetEndTime() : 0;
57f50b3c 2946}
2947
675f64cd 2948//______________________________________________________________________________________________
2949UInt_t AliShuttle::GetCurrentYear() const
2950{
2951 //
2952 // Get current year from logbook entry
2953 //
2954
2955 if (!fLogbookEntry) return 0;
2956
2957 TTimeStamp startTime(GetCurrentStartTime());
2958 TString year = Form("%d",startTime.GetDate());
2959 year = year(0,4);
2960
2961 return year.Atoi();
2962}
2963
2964//______________________________________________________________________________________________
2965const char* AliShuttle::GetLHCPeriod() const
2966{
2967 //
2968 // Get current LHC period from logbook entry
2969 //
2970
2971 if (!fLogbookEntry) return 0;
2972
2973 return fLogbookEntry->GetRunParameter("LHCperiod");
2974}
2975
b948db8d 2976//______________________________________________________________________________________________
2977void AliShuttle::Log(const char* detector, const char* message)
2978{
9827400b 2979 //
2980 // Fill log string with a message
2981 //
b948db8d 2982
7d4cf768 2983 TString logRunDir = GetShuttleLogDir();
2984 if (GetCurrentRun() >=0)
2985 logRunDir += Form("/%d", GetCurrentRun());
2986
2987 void* dir = gSystem->OpenDirectory(logRunDir.Data());
84090f85 2988 if (dir == NULL) {
7d4cf768 2989 if (gSystem->mkdir(logRunDir.Data(), kTRUE)) {
36c99a6a 2990 AliError(Form("Can't open directory <%s>", GetShuttleLogDir()));
84090f85 2991 return;
2992 }
b948db8d 2993
84090f85 2994 } else {
2995 gSystem->FreeDirectory(dir);
2996 }
b948db8d 2997
cb343cfd 2998 TString toLog = Form("%s (%d): %s - ", TTimeStamp(time(0)).AsString("s"), getpid(), detector);
e7f62f16 2999 if (GetCurrentRun() >= 0)
3000 toLog += Form("run %d - ", GetCurrentRun());
2bb7b766 3001 toLog += Form("%s", message);
3002
84090f85 3003 AliInfo(toLog.Data());
ffa29e93 3004
3005 // if we redirect the log output already to the file, leave here
3006 if (fOutputRedirected && strcmp(detector, "SHUTTLE") != 0)
3007 return;
b948db8d 3008
ffa29e93 3009 TString fileName = GetLogFileName(detector);
e7f62f16 3010
84090f85 3011 gSystem->ExpandPathName(fileName);
3012
3013 ofstream logFile;
3014 logFile.open(fileName, ofstream::out | ofstream::app);
3015
3016 if (!logFile.is_open()) {
3017 AliError(Form("Could not open file %s", fileName.Data()));
3018 return;
3019 }
7bfb2090 3020
84090f85 3021 logFile << toLog.Data() << "\n";
b948db8d 3022
84090f85 3023 logFile.close();
b948db8d 3024}
2bb7b766 3025
ffa29e93 3026//______________________________________________________________________________________________
3027TString AliShuttle::GetLogFileName(const char* detector) const
3028{
3029 //
3030 // returns the name of the log file for a given sub detector
3031 //
3032
3033 TString fileName;
3034
3035 if (GetCurrentRun() >= 0)
7d4cf768 3036 {
3037 fileName.Form("%s/%d/%s_%d.log", GetShuttleLogDir(), GetCurrentRun(),
3038 detector, GetCurrentRun());
3039 } else {
ffa29e93 3040 fileName.Form("%s/%s.log", GetShuttleLogDir(), detector);
7d4cf768 3041 }
ffa29e93 3042
3043 return fileName;
3044}
3045
ee6f7523 3046//______________________________________________________________________________________________
3047void AliShuttle::SendAlive()
3048{
3049 // sends alive message to ML
3050
3051 TMonaLisaText mlStatus("SHUTTLE_status", "Alive");
3052
3053 TList mlList;
3054 mlList.Add(&mlStatus);
3055
3056 fMonaLisa->SendParameters(&mlList, "__PROCESSINGINFO__");
3057}
3058
2bb7b766 3059//______________________________________________________________________________________________
3060Bool_t AliShuttle::Collect(Int_t run)
3061{
9827400b 3062 //
3063 // Collects conditions data for all UNPROCESSED run written to DAQ LogBook in case of run = -1 (default)
3064 // If a dedicated run is given this run is processed
3065 //
3066 // In operational mode, this is the Shuttle function triggered by the EOR signal.
3067 //
2bb7b766 3068
eba76848 3069 if (run == -1)
3070 Log("SHUTTLE","Collect - Shuttle called. Collecting conditions data for unprocessed runs");
3071 else
3072 Log("SHUTTLE", Form("Collect - Shuttle called. Collecting conditions data for run %d", run));
cb343cfd 3073
3074 SetLastAction("Starting");
2bb7b766 3075
ee6f7523 3076 // create ML instance
3077 if (!fMonaLisa)
3078 fMonaLisa = new TMonaLisaWriter(fConfig->GetMonitorHost(), fConfig->GetMonitorTable());
3079
ee6f7523 3080 SendAlive();
fbc112e3 3081 CountOpenRuns();
ee6f7523 3082
2bb7b766 3083 TString whereClause("where shuttle_done=0");
eba76848 3084 if (run != -1)
3085 whereClause += Form(" and run=%d", run);
2bb7b766 3086
3087 TObjArray shuttleLogbookEntries;
be48e3ea 3088 if (!QueryShuttleLogbook(whereClause, shuttleLogbookEntries))
3089 {
cb343cfd 3090 Log("SHUTTLE", "Collect - Can't retrieve entries from Shuttle logbook");
2bb7b766 3091 return kFALSE;
3092 }
3093
9e080f92 3094 if (shuttleLogbookEntries.GetEntries() == 0)
3095 {
3096 if (run == -1)
3097 Log("SHUTTLE","Collect - Found no UNPROCESSED runs in Shuttle logbook");
3098 else
3099 Log("SHUTTLE", Form("Collect - Run %d is already DONE "
3100 "or it does not exist in Shuttle logbook", run));
3101 return kTRUE;
3102 }
3103
be48e3ea 3104 for (UInt_t iDet=0; iDet<NDetectors(); iDet++)
3105 fFirstUnprocessed[iDet] = kTRUE;
3106
fc5a4708 3107 if (run != -1)
be48e3ea 3108 {
3109 // query Shuttle logbook for earlier runs, check if some detectors are unprocessed,
3110 // flag them into fFirstUnprocessed array
3111 TString whereClause(Form("where shuttle_done=0 and run < %d", run));
3112 TObjArray tmpLogbookEntries;
3113 if (!QueryShuttleLogbook(whereClause, tmpLogbookEntries))
3114 {
3115 Log("SHUTTLE", "Collect - Can't retrieve entries from Shuttle logbook");
3116 return kFALSE;
3117 }
3118
3119 TIter iter(&tmpLogbookEntries);
3120 AliShuttleLogbookEntry* anEntry = 0;
3121 while ((anEntry = dynamic_cast<AliShuttleLogbookEntry*> (iter.Next())))
3122 {
3123 for (UInt_t iDet=0; iDet<NDetectors(); iDet++)
3124 {
3125 if (anEntry->GetDetectorStatus(iDet) == AliShuttleLogbookEntry::kUnprocessed)
3126 {
3127 AliDebug(2, Form("Run %d: setting %s as \"not first time unprocessed\"",
3128 anEntry->GetRun(), GetDetName(iDet)));
3129 fFirstUnprocessed[iDet] = kFALSE;
3130 }
3131 }
3132
3133 }
3134
3135 }
3136
3137 if (!RetrieveConditionsData(shuttleLogbookEntries))
3138 {
cb343cfd 3139 Log("SHUTTLE", "Collect - Process of at least one run failed");
2bb7b766 3140 return kFALSE;
3141 }
3142
36c99a6a 3143 Log("SHUTTLE", "Collect - Requested run(s) successfully processed");
eba76848 3144 return kTRUE;
2bb7b766 3145}
3146
2bb7b766 3147//______________________________________________________________________________________________
3148Bool_t AliShuttle::RetrieveConditionsData(const TObjArray& dateEntries)
3149{
9827400b 3150 //
3151 // Retrieve conditions data for all runs that aren't processed yet
3152 //
2bb7b766 3153
3154 Bool_t hasError = kFALSE;
3155
3156 TIter iter(&dateEntries);
3157 AliShuttleLogbookEntry* anEntry;
3158
3159 while ((anEntry = (AliShuttleLogbookEntry*) iter.Next())){
3160 if (!Process(anEntry)){
3161 hasError = kTRUE;
3162 }
4b95672b 3163
3164 // clean SHUTTLE temp directory
d524ade6 3165 //TString filename = Form("%s/*.shuttle", GetShuttleTempDir());
3166 //RemoveFile(filename.Data());
2bb7b766 3167 }
3168
3169 return hasError == kFALSE;
3170}
cb343cfd 3171
3172//______________________________________________________________________________________________
3173ULong_t AliShuttle::GetTimeOfLastAction() const
3174{
9827400b 3175 //
3176 // Gets time of last action
3177 //
3178
cb343cfd 3179 ULong_t tmp;
36c99a6a 3180
cb343cfd 3181 fMonitoringMutex->Lock();
be48e3ea 3182
cb343cfd 3183 tmp = fLastActionTime;
36c99a6a 3184
cb343cfd 3185 fMonitoringMutex->UnLock();
36c99a6a 3186
cb343cfd 3187 return tmp;
3188}
3189
3190//______________________________________________________________________________________________
3191const TString AliShuttle::GetLastAction() const
3192{
9827400b 3193 //
cb343cfd 3194 // returns a string description of the last action
9827400b 3195 //
cb343cfd 3196
3197 TString tmp;
36c99a6a 3198
cb343cfd 3199 fMonitoringMutex->Lock();
3200
3201 tmp = fLastAction;
3202
3203 fMonitoringMutex->UnLock();
3204
36c99a6a 3205 return tmp;
cb343cfd 3206}
3207
3208//______________________________________________________________________________________________
3209void AliShuttle::SetLastAction(const char* action)
3210{
9827400b 3211 //
cb343cfd 3212 // updates the monitoring variables
9827400b 3213 //
36c99a6a 3214
cb343cfd 3215 fMonitoringMutex->Lock();
36c99a6a 3216
cb343cfd 3217 fLastAction = action;
3218 fLastActionTime = time(0);
3219
3220 fMonitoringMutex->UnLock();
3221}
eba76848 3222
3223//______________________________________________________________________________________________
3224const char* AliShuttle::GetRunParameter(const char* param)
3225{
9827400b 3226 //
3227 // returns run parameter read from DAQ logbook
3228 //
eba76848 3229
3230 if(!fLogbookEntry) {
3231 AliError("No logbook entry!");
3232 return 0;
3233 }
3234
3235 return fLogbookEntry->GetRunParameter(param);
3236}
57c1a579 3237
d386d623 3238//______________________________________________________________________________________________
9827400b 3239AliCDBEntry* AliShuttle::GetFromOCDB(const char* detector, const AliCDBPath& path)
d386d623 3240{
9827400b 3241 //
3242 // returns object from OCDB valid for current run
3243 //
d386d623 3244
9827400b 3245 if (fTestMode & kErrorOCDB)
3246 {
3247 Log(detector, "GetFromOCDB - In TESTMODE - Simulating error with OCDB");
3248 return 0;
3249 }
3250
d386d623 3251 AliCDBStorage *sto = AliCDBManager::Instance()->GetStorage(fgkMainCDB);
3252 if (!sto)
3253 {
9827400b 3254 Log(detector, "GetFromOCDB - Cannot activate main OCDB for query!");
d386d623 3255 return 0;
3256 }
3257
3258 return dynamic_cast<AliCDBEntry*> (sto->Get(path, GetCurrentRun()));
3259}
3260
57c1a579 3261//______________________________________________________________________________________________
3262Bool_t AliShuttle::SendMail()
3263{
9827400b 3264 //
3265 // sends a mail to the subdetector expert in case of preprocessor error
3266 //
3267
3268 if (fTestMode != kNone)
3269 return kTRUE;
57c1a579 3270
57c1a579 3271 TString to="";
3272 TIter iterExperts(fConfig->GetResponsibles(fCurrentDetector));
3273 TObjString *anExpert=0;
3274 while ((anExpert = (TObjString*) iterExperts.Next()))
3275 {
3276 to += Form("%s,", anExpert->GetName());
3277 }
4508ab8b 3278 if (to.Length() > 0)
3279 to.Remove(to.Length()-1);
909732f7 3280 AliDebug(2, Form("to: %s",to.Data()));
57c1a579 3281
86aa42c3 3282 if (to.IsNull()) {
c88ad5db 3283 Log("SHUTTLE", "List of detector responsibles not yet set!");
36c99a6a 3284 return kFALSE;
3285 }
3286
fbc112e3 3287 void* dir = gSystem->OpenDirectory(GetShuttleLogDir());
3288 if (dir == NULL)
3289 {
3290 if (gSystem->mkdir(GetShuttleLogDir(), kTRUE))
3291 {
3292 Log("SHUTTLE", Form("SendMail - Can't open directory <%s>", GetShuttleLogDir()));
3293 return kFALSE;
3294 }
3295
3296 } else {
3297 gSystem->FreeDirectory(dir);
3298 }
3299
4508ab8b 3300 TString bodyFileName;
3301 bodyFileName.Form("%s/mail.body", GetShuttleLogDir());
3302 gSystem->ExpandPathName(bodyFileName);
3303
3304 ofstream mailBody;
3305 mailBody.open(bodyFileName, ofstream::out);
3306
3307 if (!mailBody.is_open())
3308 {
3309 Log("SHUTTLE", Form("Could not open mail body file %s", bodyFileName.Data()));
3310 return kFALSE;
3311 }
3312
57c1a579 3313 TString cc="alberto.colla@cern.ch";
3314
6a1146c4 3315 TString subject = Form("%s Shuttle preprocessor FAILED in run %d (run type = %s)!",
3316 fCurrentDetector.Data(), GetCurrentRun(), GetRunType());
909732f7 3317 AliDebug(2, Form("subject: %s", subject.Data()));
57c1a579 3318
3319 TString body = Form("Dear %s expert(s), \n\n", fCurrentDetector.Data());
3320 body += Form("SHUTTLE just detected that your preprocessor "
6a1146c4 3321 "failed processing run %d (run type = %s)!!\n\n",
3322 GetCurrentRun(), GetRunType());
7d4cf768 3323 body += Form("Please check %s status on the SHUTTLE monitoring page: \n\n",
3324 fCurrentDetector.Data());
b0e53b15 3325 if (fConfig->GetRunMode() == AliShuttleConfig::kTest)
3326 {
3327 body += Form("\thttp://pcalimonitor.cern.ch:8889/shuttle.jsp?time=168 \n\n");
3328 } else {
4508ab8b 3329 body += Form("\thttp://pcalimonitor.cern.ch/shuttle.jsp?instance=PROD&time=168 \n\n");
b0e53b15 3330 }
3331
7d4cf768 3332
3333 TString logFolder = "logs";
3334 if (fConfig->GetRunMode() == AliShuttleConfig::kProd)
3335 logFolder += "_PROD";
3336
3337
546242fb 3338 body += Form("Find the %s log for the current run on \n\n"
7d4cf768 3339 "\thttp://pcalishuttle01.cern.ch:8880/%s/%d/%s_%d.log \n\n",
3340 fCurrentDetector.Data(), logFolder.Data(), GetCurrentRun(),
3341 fCurrentDetector.Data(), GetCurrentRun());
3342 body += Form("The last 10 lines of %s log file are following:\n\n", fCurrentDetector.Data());
57c1a579 3343
909732f7 3344 AliDebug(2, Form("Body begin: %s", body.Data()));
57c1a579 3345
3346 mailBody << body.Data();
3347 mailBody.close();
3348 mailBody.open(bodyFileName, ofstream::out | ofstream::app);
3349
7d4cf768 3350 TString logFileName = Form("%s/%d/%s_%d.log", GetShuttleLogDir(),
3351 GetCurrentRun(), fCurrentDetector.Data(), GetCurrentRun());
57c1a579 3352 TString tailCommand = Form("tail -n 10 %s >> %s", logFileName.Data(), bodyFileName.Data());
3353 if (gSystem->Exec(tailCommand.Data()))
3354 {
3355 mailBody << Form("%s log file not found ...\n\n", fCurrentDetector.Data());
3356 }
3357
3358 TString endBody = Form("------------------------------------------------------\n\n");
675f64cd 3359 endBody += Form("In case of problems please contact the SHUTTLE core team.\n\n");
3360 endBody += "Please do not answer this message directly, it is automatically generated.\n\n";
3361 endBody += "Greetings,\n\n \t\t\tthe SHUTTLE\n";
3362
3363 AliDebug(2, Form("Body end: %s", endBody.Data()));
3364
3365 mailBody << endBody.Data();
3366
3367 mailBody.close();
3368
3369 // send mail!
3370 TString mailCommand = Form("mail -s \"%s\" -c %s %s < %s",
3371 subject.Data(),
3372 cc.Data(),
3373 to.Data(),
3374 bodyFileName.Data());
3375 AliDebug(2, Form("mail command: %s", mailCommand.Data()));
3376
3377 Bool_t result = gSystem->Exec(mailCommand.Data());
3378
3379 return result == 0;
3380}
3381
3382//______________________________________________________________________________________________
3383Bool_t AliShuttle::SendMailToDCS()
3384{
3385 //
3386 // sends a mail to the DCS experts in case of DCS error
3387 //
3388
3389 if (fTestMode != kNone)
3390 return kTRUE;
3391
3392 void* dir = gSystem->OpenDirectory(GetShuttleLogDir());
3393 if (dir == NULL)
3394 {
3395 if (gSystem->mkdir(GetShuttleLogDir(), kTRUE))
3396 {
3397 Log("SHUTTLE", Form("SendMailToDCS - Can't open directory <%s>", GetShuttleLogDir()));
3398 return kFALSE;
3399 }
3400
3401 } else {
3402 gSystem->FreeDirectory(dir);
3403 }
3404
3405 TString bodyFileName;
3406 bodyFileName.Form("%s/mail.body", GetShuttleLogDir());
3407 gSystem->ExpandPathName(bodyFileName);
3408
3409 ofstream mailBody;
3410 mailBody.open(bodyFileName, ofstream::out);
3411
3412 if (!mailBody.is_open())
3413 {
3414 Log("SHUTTLE", Form("SendMailToDCS - Could not open mail body file %s", bodyFileName.Data()));
3415 return kFALSE;
3416 }
3417
3418 TString to="Vladimir.Fekete@cern.ch, Svetozar.Kapusta@cern.ch";
3419 //TString to="alberto.colla@cern.ch";
3420 AliDebug(2, Form("to: %s",to.Data()));
3421
3422 if (to.IsNull()) {
3423 Log("SHUTTLE", "List of detector responsibles not yet set!");
3424 return kFALSE;
3425 }
3426
3427 TString cc="alberto.colla@cern.ch";
3428
3429 TString subject = Form("Retrieval of data points for %s FAILED in run %d !",
3430 fCurrentDetector.Data(), GetCurrentRun());
3431 AliDebug(2, Form("subject: %s", subject.Data()));
3432
3433 TString body = Form("Dear DCS experts, \n\n");
3434 body += Form("SHUTTLE couldn\'t retrieve the data points for detector %s "
3435 "in run %d!!\n\n", fCurrentDetector.Data(), GetCurrentRun());
7d4cf768 3436 body += Form("Please check %s status on the SHUTTLE monitoring page: \n\n",
3437 fCurrentDetector.Data());
b0e53b15 3438 if (fConfig->GetRunMode() == AliShuttleConfig::kTest)
3439 {
3440 body += Form("\thttp://pcalimonitor.cern.ch:8889/shuttle.jsp?time=168 \n\n");
3441 } else {
3442 body += Form("\thttp://pcalimonitor.cern.ch/shuttle.jsp?instance=PROD?time=168 \n\n");
3443 }
7d4cf768 3444
3445 TString logFolder = "logs";
3446 if (fConfig->GetRunMode() == AliShuttleConfig::kProd)
3447 logFolder += "_PROD";
3448
3449
675f64cd 3450 body += Form("Find the %s log for the current run on \n\n"
7d4cf768 3451 "\thttp://pcalishuttle01.cern.ch:8880/%s/%d/%s_%d.log \n\n",
3452 fCurrentDetector.Data(), logFolder.Data(), GetCurrentRun(),
3453 fCurrentDetector.Data(), GetCurrentRun());
3454 body += Form("The last 10 lines of %s log file are following:\n\n", fCurrentDetector.Data());
675f64cd 3455
3456 AliDebug(2, Form("Body begin: %s", body.Data()));
3457
3458 mailBody << body.Data();
3459 mailBody.close();
3460 mailBody.open(bodyFileName, ofstream::out | ofstream::app);
3461
7d4cf768 3462 TString logFileName = Form("%s/%d/%s_%d.log", GetShuttleLogDir(), GetCurrentRun(),
3463 fCurrentDetector.Data(), GetCurrentRun());
675f64cd 3464 TString tailCommand = Form("tail -n 10 %s >> %s", logFileName.Data(), bodyFileName.Data());
3465 if (gSystem->Exec(tailCommand.Data()))
3466 {
3467 mailBody << Form("%s log file not found ...\n\n", fCurrentDetector.Data());
3468 }
3469
3470 TString endBody = Form("------------------------------------------------------\n\n");
36c99a6a 3471 endBody += Form("In case of problems please contact the SHUTTLE core team.\n\n");
3472 endBody += "Please do not answer this message directly, it is automatically generated.\n\n";
546242fb 3473 endBody += "Greetings,\n\n \t\t\tthe SHUTTLE\n";
57c1a579 3474
909732f7 3475 AliDebug(2, Form("Body end: %s", endBody.Data()));
57c1a579 3476
3477 mailBody << endBody.Data();
3478
3479 mailBody.close();
3480
3481 // send mail!
3482 TString mailCommand = Form("mail -s \"%s\" -c %s %s < %s",
3483 subject.Data(),
3484 cc.Data(),
3485 to.Data(),
3486 bodyFileName.Data());
909732f7 3487 AliDebug(2, Form("mail command: %s", mailCommand.Data()));
57c1a579 3488
3489 Bool_t result = gSystem->Exec(mailCommand.Data());
3490
3491 return result == 0;
3492}
d386d623 3493
441b0e9c 3494//______________________________________________________________________________________________
9827400b 3495const char* AliShuttle::GetRunType()
441b0e9c 3496{
9827400b 3497 //
3498 // returns run type read from "run type" logbook
3499 //
441b0e9c 3500
3501 if(!fLogbookEntry) {
3502 AliError("No logbook entry!");
3503 return 0;
3504 }
3505
9827400b 3506 return fLogbookEntry->GetRunType();
441b0e9c 3507}
3508
4859271b 3509//______________________________________________________________________________________________
3510Bool_t AliShuttle::GetHLTStatus()
3511{
3512 // Return HLT status (ON=1 OFF=0)
3513 // Converts the HLT status from the status string read in the run logbook (not just a bool)
3514
3515 if(!fLogbookEntry) {
3516 AliError("No logbook entry!");
3517 return 0;
3518 }
3519
3520 // TODO implement when HLTStatus is inserted in run logbook
3521 //TString hltStatus = fLogbookEntry->GetRunParameter("HLTStatus");
3522 //if(hltStatus == "OFF") {return kFALSE};
3523
3524 return kTRUE;
3525}
3526
d386d623 3527//______________________________________________________________________________________________
3528void AliShuttle::SetShuttleTempDir(const char* tmpDir)
3529{
9827400b 3530 //
3531 // sets Shuttle temp directory
3532 //
d386d623 3533
3534 fgkShuttleTempDir = gSystem->ExpandPathName(tmpDir);
3535}
3536
3537//______________________________________________________________________________________________
3538void AliShuttle::SetShuttleLogDir(const char* logDir)
3539{
9827400b 3540 //
3541 // sets Shuttle log directory
3542 //
d386d623 3543
3544 fgkShuttleLogDir = gSystem->ExpandPathName(logDir);
3545}