]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - SHUTTLE/AliShuttle.cxx
Warning fixed.
[u/mrichter/AliRoot.git] / SHUTTLE / AliShuttle.cxx
index 34ed3c4f9da5accf05dd3aa3b5de0e7fef0c418d..bdc3a7405b8d25b8d8928f9b7b21735e0a0063e3 100644 (file)
  * provided "as is" without express or implied warranty.                  *
  **************************************************************************/
 
-/*
-$Log$
-Revision 1.78  2007/12/19 11:50:41  acolla
-
-Raw data tag merged files is written in /alice/data/.../lhcPeriod_DET/runNb/raw if partition is made of DET only
-
-Revision 1.77  2007/12/19 11:16:16  acolla
-More meaningful log message added in GetFileSources
-
-Revision 1.76  2007/12/19 07:45:20  acolla
-bug fix in the name of the raw tag files (Raw instead of raw)
-
-Revision 1.75  2007/12/18 15:42:14  jgrosseo
-adding number of open runs to monitoring
-
-Revision 1.74  2007/12/17 03:23:32  jgrosseo
-several bugfixes
-added "empty preprocessor" as placeholder for Acorde in FDR
-
-Revision 1.73  2007/12/14 19:31:36  acolla
-Sending email to DCS experts is temporarily commented
-
-Revision 1.72  2007/12/13 15:44:28  acolla
-Run type added in mail sent to detector expert (eases understanding)
-
-Revision 1.71  2007/12/12 14:56:14  jgrosseo
-sending shuttle_ignore to ML also in case of 0 events
-
-Revision 1.70  2007/12/12 13:45:35  acolla
-Monalisa started in Collect() function. Alive message to monitor is sent at each Collect and every minute during preprocessor processing.
-
-Revision 1.69  2007/12/12 10:06:29  acolla
-in AliShuttle.cxx: SHUTTLE logbook is updated in case of invalid run times:
-
-time_start==0 && time_end==0
-
-logbook is NOT updated if time_start != 0 && time_end == 0, because it may mean that the run is still ongoing.
-
-Revision 1.68  2007/12/11 10:15:17  acolla
-Added marking SHUTTLE=DONE for invalid runs
-(invalid start time or end time) and runs with totalEvents < 1
-
-Revision 1.67  2007/12/07 19:14:36  acolla
-in AliShuttleTrigger:
-
-Added automatic collection of new runs on a regular time basis (settable from the configuration)
-
-in AliShuttleConfig: new members
-
-- triggerWait: time to wait for DIM trigger (s) before starting automatic collection of new runs
-- mode: run mode (test, prod) -> used to build log folder (logs or logs_PROD)
-
-in AliShuttle:
-
-- logs now stored in logs/#RUN/DET_#RUN.log
-
-Revision 1.66  2007/12/05 10:45:19  jgrosseo
-changed order of arguments to TMonaLisaWriter
-
-Revision 1.65  2007/11/26 16:58:37  acolla
-Monalisa configuration added: host and table name
-
-Revision 1.64  2007/11/13 16:15:47  acolla
-DCS map is stored in a file in the temp folder where the detector is processed.
-If the preprocessor fails, the temp folder is not removed. This will help the debugging of the problem.
-
-Revision 1.63  2007/11/02 10:53:16  acolla
-Protection added to AliShuttle::CopyFileLocally
-
-Revision 1.62  2007/10/31 18:23:13  acolla
-Furter developement on the Shuttle:
-
-- Shuttle now connects to the Grid as alidaq. The OCDB and Reference folders
-are now built from /alice/data, e.g.:
-/alice/data/2007/LHC07a/OCDB
-
-the year and LHC period are taken from the Shuttle.
-Raw metadata files are stored by GRP to:
-/alice/data/2007/LHC07a/<runNb>/Raw/RunMetadata.root
-
-- Shuttle sends a mail to DCS experts each time DP retrieval fails.
-
-Revision 1.61  2007/10/30 20:33:51  acolla
-Improved managing of temporary folders, which weren't correctly handled.
-Resolved bug introduced in StoreReferenceFile, which caused SPD preprocessor fail.
-
-Revision 1.60  2007/10/29 18:06:16  acolla
-
-New function StoreRunMetadataFile added to preprocessor and Shuttle interface
-This function can be used by GRP only. It stores raw data tags merged file to the
-raw data folder (e.g. /alice/data/2008/LHC08a/000099999/Raw).
-
-KNOWN ISSUES:
-
-1. Shuttle cannot write to /alice/data/ because it belongs to alidaq. Tag file is stored in /alice/simulation/... for the time being.
-2. Due to a bug in TAlien::Mkdir, the creation of a folder in recursive mode (-p option) does not work. The problem
-has been corrected in the root package on the Shuttle machine.
-
-Revision 1.59  2007/10/05 12:40:55  acolla
-
-Result error code added to AliDCSClient data members (it was "lost" with the new implementation of TMap* GetAliasValues and GetDPValues).
-
-Revision 1.58  2007/09/28 15:27:40  acolla
-
-AliDCSClient "multiSplit" option added in the DCS configuration
-in AliDCSMessage: variable MAX_BODY_SIZE set to 500000
-
-Revision 1.57  2007/09/27 16:53:13  acolla
-Detectors can have more than one AMANDA server. SHUTTLE queries the servers sequentially,
-merges the dcs aliases/DPs in one TMap and sends it to the preprocessor.
-
-Revision 1.56  2007/09/14 16:46:14  jgrosseo
-1) Connect and Close are called before and after each query, so one can
-keep the same AliDCSClient object.
-2) The splitting of a query is moved to GetDPValues/GetAliasValues.
-3) Splitting interval can be specified in constructor
-
-Revision 1.55  2007/08/06 12:26:40  acolla
-Function Bool_t GetHLTStatus added to preprocessor. It returns the status of HLT
-read from the run logbook.
-
-Revision 1.54  2007/07/12 09:51:25  jgrosseo
-removed duplicated log message in GetFile
-
-Revision 1.53  2007/07/12 09:26:28  jgrosseo
-updating hlt fxs base path
-
-Revision 1.52  2007/07/12 08:06:45  jgrosseo
-adding log messages in getfile... functions
-adding not implemented copy constructor in alishuttleconfigholder
-
-Revision 1.51  2007/07/03 17:24:52  acolla
-root moved to v5-16-00. TFileMerger->Cp moved to TFile::Cp.
-
-Revision 1.50  2007/07/02 17:19:32  acolla
-preprocessor is run in a temp directory that is removed when process is finished.
-
-Revision 1.49  2007/06/29 10:45:06  acolla
-Number of columns in MySql Shuttle logbook increased by one (HLT added)
-
-Revision 1.48  2007/06/21 13:06:19  acolla
-GetFileSources returns dummy list with 1 source if system=DCS (better than
-returning error as it was)
-
-Revision 1.47  2007/06/19 17:28:56  acolla
-HLT updated; missing map bug removed.
-
-Revision 1.46  2007/06/09 13:01:09  jgrosseo
-Switching to retrieval of several DCS DPs at a time (multiDPrequest)
-
-Revision 1.45  2007/05/30 06:35:20  jgrosseo
-Adding functionality to the Shuttle/TestShuttle:
-o) Function to retrieve list of sources from a given system (GetFileSources with id=0)
-o) Function to retrieve list of IDs for a given source      (GetFileIDs)
-These functions are needed for dealing with the tag files that are saved for the GRP preprocessor
-Example code has been added to the TestProcessor in TestShuttle
-
-Revision 1.44  2007/05/11 16:09:32  acolla
-Reference files for ITS, MUON and PHOS are now stored in OfflineDetName/OnlineDetName/run_...
-example: ITS/SPD/100_filename.root
-
-Revision 1.43  2007/05/10 09:59:51  acolla
-Various bug fixes in StoreRefFilesToGrid; Cleaning of reference storage before processing detector (CleanReferenceStorage)
-
-Revision 1.42  2007/05/03 08:01:39  jgrosseo
-typo in last commit :-(
-
-Revision 1.41  2007/05/03 08:00:48  jgrosseo
-fixing log message when pp want to skip dcs value retrieval
-
-Revision 1.40  2007/04/27 07:06:48  jgrosseo
-GetFileSources returns empty list in case of no files, but successful query
-No mails sent in testmode
-
-Revision 1.39  2007/04/17 12:43:57  acolla
-Correction in StoreOCDB; change of text in mail to detector expert
-
-Revision 1.38  2007/04/12 08:26:18  jgrosseo
-updated comment
-
-Revision 1.37  2007/04/10 16:53:14  jgrosseo
-redirecting sub detector stdout, stderr to sub detector log file
-
-Revision 1.35  2007/04/04 16:26:38  acolla
-1. Re-organization of function calls in TestPreprocessor to make it more meaningful.
-2. Added missing dependency in test preprocessors.
-3. in AliShuttle.cxx: processing time and memory consumption info on a single line.
-
-Revision 1.34  2007/04/04 10:33:36  jgrosseo
-1) 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.
-In case of an error with the Grid, the Shuttle will retry the storing later, the preprocessor does not need to be run again.
-
-2) 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.
-
-3) New function StoreReferenceFile to _directly_ store a file (without opening it) to the reference storage.
-
-4) The memory usage of the preprocessor is monitored. If it exceeds 2 GB it is terminated.
-
-5) 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.
-If you always need DCS data (like before), you do not need to implement it.
-
-6) The run type has been added to the monitoring page
-
-Revision 1.33  2007/04/03 13:56:01  acolla
-Grid Storage at the end of preprocessing. Added virtual method to disable DCS query according to the
-run type.
-
-Revision 1.32  2007/02/28 10:41:56  acolla
-Run type field added in SHUTTLE framework. Run type is read from "run type" logbook and retrieved by
-AliPreprocessor::GetRunType() function.
-Added some ldap definition files.
-
-Revision 1.30  2007/02/13 11:23:21  acolla
-Moved getters and setters of Shuttle's main OCDB/Reference, local
-OCDB/Reference, temp and log folders to AliShuttleInterface
-
-Revision 1.27  2007/01/30 17:52:42  jgrosseo
-adding monalisa monitoring
-
-Revision 1.26  2007/01/23 19:20:03  acolla
-Removed old ldif files, added TOF, MCH ldif files. Added some options in
-AliShuttleConfig::Print. Added in Ali Shuttle: SetShuttleTempDir and
-SetShuttleLogDir
-
-Revision 1.25  2007/01/15 19:13:52  acolla
-Moved some AliInfo to AliDebug in SendMail function
-
-Revision 1.21  2006/12/07 08:51:26  jgrosseo
-update (alberto):
-table, db names in ldap configuration
-added GRP preprocessor
-DCS data can also be retrieved by data point
-
-Revision 1.20  2006/11/16 16:16:48  jgrosseo
-introducing strict run ordering flag
-removed giving preprocessor name to preprocessor, they have to know their name themselves ;-)
-
-Revision 1.19  2006/11/06 14:23:04  jgrosseo
-major update (Alberto)
-o) reading of run parameters from the logbook
-o) online offline naming conversion
-o) standalone DCSclient package
-
-Revision 1.18  2006/10/20 15:22:59  jgrosseo
-o) Adding time out to the execution of the preprocessors: The Shuttle forks and the parent process monitors the child
-o) Merging Collect, CollectAll, CollectNew function
-o) Removing implementation of empty copy constructors (declaration still there!)
-
-Revision 1.17  2006/10/05 16:20:55  jgrosseo
-adapting to new CDB classes
-
-Revision 1.16  2006/10/05 15:46:26  jgrosseo
-applying to the new interface
-
-Revision 1.15  2006/10/02 16:38:39  jgrosseo
-update (alberto):
-fixed memory leaks
-storing of objects that failed to be stored to the grid before
-interfacing of shuttle status table in daq system
-
-Revision 1.14  2006/08/29 09:16:05  jgrosseo
-small update
-
-Revision 1.13  2006/08/15 10:50:00  jgrosseo
-effc++ corrections (alberto)
-
-Revision 1.12  2006/08/08 14:19:29  jgrosseo
-Update to shuttle classes (Alberto)
-
-- Possibility to set the full object's path in the Preprocessor's and
-Shuttle's  Store functions
-- Possibility to extend the object's run validity in the same classes
-("startValidity" and "validityInfinite" parameters)
-- Implementation of the StoreReferenceData function to store reference
-data in a dedicated CDB storage.
-
-Revision 1.11  2006/07/21 07:37:20  jgrosseo
-last run is stored after each run
-
-Revision 1.10  2006/07/20 09:54:40  jgrosseo
-introducing status management: The processing per subdetector is divided into several steps,
-after each step the status is stored on disk. If the system crashes in any of the steps the Shuttle
-can keep track of the number of failures and skips further processing after a certain threshold is
-exceeded. These thresholds can be configured in LDAP.
-
-Revision 1.9  2006/07/19 10:09:55  jgrosseo
-new configuration, accesst to DAQ FES (Alberto)
-
-Revision 1.8  2006/07/11 12:44:36  jgrosseo
-adding parameters for extended validity range of data produced by preprocessor
-
-Revision 1.7  2006/07/10 14:37:09  jgrosseo
-small fix + todo comment
-
-Revision 1.6  2006/07/10 13:01:41  jgrosseo
-enhanced storing of last sucessfully processed run (alberto)
-
-Revision 1.5  2006/07/04 14:59:57  jgrosseo
-revision of AliDCSValue: Removed wrapper classes, reduced storage size per value by factor 2
-
-Revision 1.4  2006/06/12 09:11:16  jgrosseo
-coding conventions (Alberto)
-
-Revision 1.3  2006/06/06 14:26:40  jgrosseo
-o) removed files that were moved to STEER
-o) shuttle updated to follow the new interface (Alberto)
-
-Revision 1.2  2006/03/07 07:52:34  hristov
-New version (B.Yordanov)
-
-Revision 1.6  2005/11/19 17:19:14  byordano
-RetrieveDATEEntries and RetrieveConditionsData added
-
-Revision 1.5  2005/11/19 11:09:27  byordano
-AliShuttle declaration added
-
-Revision 1.4  2005/11/17 17:47:34  byordano
-TList changed to TObjArray
-
-Revision 1.3  2005/11/17 14:43:23  byordano
-import to local CVS
-
-Revision 1.1.1.1  2005/10/28 07:33:58  hristov
-Initial import as subdirectory in AliRoot
-
-Revision 1.2  2005/09/13 08:41:15  byordano
-default startTime endTime added
-
-Revision 1.4  2005/08/30 09:13:02  byordano
-some docs added
-
-Revision 1.3  2005/08/29 21:15:47  byordano
-some docs added
-
-*/
+/* $Id$ */
 
 //
 // This class is the main manager for AliShuttle. 
@@ -391,6 +57,7 @@ some docs added
 #include <TFile.h>
 #include <TGrid.h>
 #include <TGridResult.h>
+#include <TMap.h>
 
 #include <TMonaLisaWriter.h>
 
@@ -399,6 +66,8 @@ some docs added
 #include <sys/types.h>
 #include <sys/wait.h>
 
+#include <signal.h>
+
 ClassImp(AliShuttle)
 
 //______________________________________________________________________________________________
@@ -409,6 +78,8 @@ fTimeout(timeout), fRetries(retries),
 fPreprocessorMap(),
 fLogbookEntry(0),
 fCurrentDetector(),
+fFirstProcessing(0),
+fFXSError(-1),
 fStatusEntry(0),
 fMonitoringMutex(0),
 fLastActionTime(0),
@@ -584,6 +255,8 @@ Bool_t AliShuttle::StoreOCDB()
        // Then calls StoreRefFilesToGrid to store reference files. 
        //
        
+       UpdateShuttleStatus(AliShuttleStatus::kStoreStarted);
+                               
        if (fTestMode & kErrorGrid)
        {
                Log("SHUTTLE", "StoreOCDB - In TESTMODE - Simulating error while storing in the Grid");
@@ -592,10 +265,10 @@ Bool_t AliShuttle::StoreOCDB()
        }
        
        Log("SHUTTLE","StoreOCDB - Storing OCDB data ...");
-       Bool_t resultCDB = StoreOCDB(fgkMainCDB);
+       Int_t resultCDB = StoreOCDB(fgkMainCDB);
 
        Log("SHUTTLE","StoreOCDB - Storing reference data ...");
-       Bool_t resultRef = StoreOCDB(fgkMainRefStorage);
+       Int_t resultRef = StoreOCDB(fgkMainRefStorage);
        
        Log("SHUTTLE","StoreOCDB - Storing reference files ...");
        Bool_t resultRefFiles = CopyFilesToGrid("reference");
@@ -607,19 +280,56 @@ Bool_t AliShuttle::StoreOCDB()
                resultMetadata = CopyFilesToGrid("metadata");
        }
        
-       return resultCDB && resultRef && resultRefFiles && resultMetadata;
+       Int_t storeResult = 0;
+       
+       if (resultCDB < 0 || resultRef < 0 || resultRefFiles == kFALSE || resultMetadata == kFALSE)
+               storeResult = -1;
+       else if (resultCDB > 0 || resultRef > 0)
+               storeResult = 1;
+               
+       if (storeResult < 0)
+       {
+               Log("SHUTTLE", 
+                       Form("\t\t\t****** run %d - %s: STORAGE ERROR ******",
+                               GetCurrentRun(), fCurrentDetector.Data()));
+               UpdateShuttleStatus(AliShuttleStatus::kStoreError);
+       } 
+       else if (storeResult > 0)
+       {
+               Log("SHUTTLE", 
+                       Form("\t\t\t****** run %d - %s: STORAGE DELAYED ******",
+                               GetCurrentRun(), fCurrentDetector.Data()));
+               UpdateShuttleStatus(AliShuttleStatus::kStoreDelayed);
+       }
+       else if (storeResult == 0) 
+       {
+               Log("SHUTTLE", 
+                       Form("\t\t\t****** run %d - %s: DONE ******",
+                               GetCurrentRun(), fCurrentDetector.Data()));
+               UpdateShuttleStatus(AliShuttleStatus::kDone);
+               UpdateShuttleLogbook(fCurrentDetector, "DONE");
+       }
+
+       return (storeResult == 0);
 }
 
 //______________________________________________________________________________________________
-Bool_t AliShuttle::StoreOCDB(const TString& gridURI)
+Int_t AliShuttle::StoreOCDB(const TString& gridURI)
 {
        //
        // Called by StoreOCDB(), performs actual storage to the main OCDB and reference storages (Grid)
        //
+       // Return code:
+       //   -2 initialization error
+       //   -1 storage error
+       //   0  success
+       //   1  storage delayed (e.g. previous unprocessed runs)
+       //
 
        TObjArray* gridIds=0;
 
        Bool_t result = kTRUE;
+       Bool_t delayed = kFALSE;
 
        const char* type = 0;
        TString localURI;
@@ -631,7 +341,7 @@ Bool_t AliShuttle::StoreOCDB(const TString& gridURI)
                localURI = fgkLocalRefStorage;
        } else {
                AliError(Form("Invalid storage URI: %s", gridURI.Data()));
-               return kFALSE;
+               return -2;
        }
 
        AliCDBManager* man = AliCDBManager::Instance();
@@ -640,7 +350,7 @@ Bool_t AliShuttle::StoreOCDB(const TString& gridURI)
        if(!gridSto) {
                Log("SHUTTLE",
                        Form("StoreOCDB - cannot activate main %s storage", type));
-               return kFALSE;
+               return -2;
        }
 
        gridIds = gridSto->GetQueryCDBList();
@@ -650,7 +360,7 @@ Bool_t AliShuttle::StoreOCDB(const TString& gridURI)
        if(!localSto) {
                Log("SHUTTLE",
                        Form("StoreOCDB - cannot activate local %s storage", type));
-               return kFALSE;
+               return -2;
        }
        AliCDBPath aPath(GetOfflineDetName(fCurrentDetector.Data()),"*","*");
        // Local objects were stored with current run as Grid version!
@@ -674,7 +384,10 @@ Bool_t AliShuttle::StoreOCDB(const TString& gridURI)
                        Log("SHUTTLE", Form("StoreOCDB - %s: object %s has validity infinite but "
                                                "there are previous unprocessed runs!",
                                                fCurrentDetector.Data(), aLocId.GetPath().Data()));
-                       result = kFALSE;
+                       Log(fCurrentDetector.Data(), Form("StoreOCDB - %s: object %s has validity infinite but "
+                                               "there are previous unprocessed runs!",
+                                               fCurrentDetector.Data(), aLocId.GetPath().Data()));
+                       delayed = kTRUE;
                        continue;
                }
 
@@ -727,7 +440,17 @@ Bool_t AliShuttle::StoreOCDB(const TString& gridURI)
        }
        localEntries->Clear();
 
-       return result;
+       Int_t returnCode = 0;
+       
+       if (result == kFALSE)
+               returnCode = -1;
+       else if (delayed != kFALSE)
+               returnCode =  1;
+
+       Log("SHUTTLE", Form("StoreOCDB - Returning with %d (result = %d, delayed = %d)", returnCode, result, delayed));
+       Log(fCurrentDetector.Data(), Form("StoreOCDB - Returning with %d (result = %d, delayed = %d)", returnCode, result, delayed));
+       
+       return returnCode;
 }
 
 //______________________________________________________________________________________________
@@ -893,8 +616,8 @@ Bool_t AliShuttle::StoreRunMetadataFile(const char* localFile, const char* gridF
                                lhcPeriod.Data()));
        }
                
-       TString target = Form("%s/GRP/RunMetadata/alice/data/%d/%s/%09d/raw/%s", 
-                               localBaseFolder.Data(), GetCurrentYear(), 
+       TString target = Form("%s/GRP/RunMetadata%s%d/%s/%09d/raw/%s", 
+                               localBaseFolder.Data(), fConfig->GetAlienPath(), GetCurrentYear(), 
                                lhcPeriod.Data(), GetCurrentRun(), gridFileName);
                                        
        return CopyFileLocally(localFile, target);
@@ -1013,10 +736,10 @@ Bool_t AliShuttle::CopyFilesToGrid(const char* type)
                        lhcPeriod.Append(Form("_%s", partition.Data()));
                }
                
-               dir = Form("%s/GRP/RunMetadata/alice/data/%d/%s/%09d/raw", 
-                               localBaseFolder.Data(), GetCurrentYear(), 
+               dir = Form("%s/GRP/RunMetadata%s%d/%s/%09d/raw", 
+                               localBaseFolder.Data(), fConfig->GetAlienPath(), GetCurrentYear(), 
                                lhcPeriod.Data(), GetCurrentRun());
-               alienDir = dir(dir.Index("/alice/data/"), dir.Length());
+               alienDir = dir(dir.Index(fConfig->GetAlienPath()), dir.Length());
                
                begin = "";
        }
@@ -1331,7 +1054,8 @@ Bool_t AliShuttle::ContinueProcessing()
        // checks if the processing should be continued
        // if yes it returns kTRUE and updates the AliShuttleStatus with nextStatus
 
-       if (!fConfig->HostProcessDetector(fCurrentDetector)) return kFALSE;
+       if (!fConfig->HostProcessDetector(fCurrentDetector))
+               return kFALSE;
 
        AliPreprocessor* aPreprocessor =
                dynamic_cast<AliPreprocessor*> (fPreprocessorMap.GetValue(fCurrentDetector));
@@ -1344,7 +1068,7 @@ Bool_t AliShuttle::ContinueProcessing()
        AliShuttleLogbookEntry::Status entryStatus =
                fLogbookEntry->GetDetectorStatus(fCurrentDetector);
 
-       if(entryStatus != AliShuttleLogbookEntry::kUnprocessed) {
+       if (entryStatus != AliShuttleLogbookEntry::kUnprocessed) {
                Log("SHUTTLE", Form("ContinueProcessing - %s is %s",
                                fCurrentDetector.Data(),
                                fLogbookEntry->GetDetectorStatusName(entryStatus)));
@@ -1372,43 +1096,44 @@ Bool_t AliShuttle::ContinueProcessing()
                }
        }
 
+       // Is the subdetector processed first time for this run?
+       fFirstProcessing = kFALSE;
+
        AliShuttleStatus* status = ReadShuttleStatus();
        if (!status) {
                // first time
                Log("SHUTTLE", Form("ContinueProcessing - %s: Processing first time",
                                fCurrentDetector.Data()));
                status = new AliShuttleStatus(AliShuttleStatus::kStarted);
+               fFirstProcessing = kTRUE;
                return WriteShuttleStatus(status);
        }
 
-       // The following two cases shouldn't happen if Shuttle Logbook was correctly updated.
+       // The following case shouldn't happen if Shuttle Logbook was correctly updated.
        // If it happens it may mean Logbook updating failed... let's do it now!
        if (status->GetStatus() == AliShuttleStatus::kDone ||
-           status->GetStatus() == AliShuttleStatus::kFailed){
+           status->GetStatus() == AliShuttleStatus::kFailed ||
+           status->GetStatus() == AliShuttleStatus::kSkipped) {
                Log("SHUTTLE", Form("ContinueProcessing - %s is already %s. Updating Shuttle Logbook",
                                        fCurrentDetector.Data(),
                                        status->GetStatusName(status->GetStatus())));
-               UpdateShuttleLogbook(fCurrentDetector.Data(),
-                                       status->GetStatusName(status->GetStatus()));
+               
+               if (status->GetStatus() == AliShuttleStatus::kSkipped)
+               {
+                       UpdateShuttleLogbook(fCurrentDetector.Data(), "DONE");
+               }
+               else
+                       UpdateShuttleLogbook(fCurrentDetector.Data(), status->GetStatusName(status->GetStatus()));
+                       
                return kFALSE;
        }
 
-       if (status->GetStatus() == AliShuttleStatus::kStoreError) {
+       if (status->GetStatus() == AliShuttleStatus::kStoreStarted || status->GetStatus() == AliShuttleStatus::kStoreDelayed ||status->GetStatus() == AliShuttleStatus::kStoreError) {
                Log("SHUTTLE",
                        Form("ContinueProcessing - %s: Grid storage of one or more "
                                "objects failed. Trying again now",
                                fCurrentDetector.Data()));
-               UpdateShuttleStatus(AliShuttleStatus::kStoreStarted);
-               if (StoreOCDB()){
-                       Log("SHUTTLE", Form("ContinueProcessing - %s: all objects "
-                               "successfully stored into main storage",
-                               fCurrentDetector.Data()));
-               } else {
-                       Log("SHUTTLE",
-                               Form("ContinueProcessing - %s: Grid storage failed again",
-                                       fCurrentDetector.Data()));
-                       UpdateShuttleStatus(AliShuttleStatus::kStoreError);
-               }
+               StoreOCDB();
                return kFALSE;
        }
 
@@ -1433,10 +1158,10 @@ Bool_t AliShuttle::ContinueProcessing()
                
                // Send mail to detector expert!
                Log("SHUTTLE", Form("ContinueProcessing - Sending mail to %s expert...", 
-                                       fCurrentDetector.Data()));
-               if (!SendMail())
+                                   fCurrentDetector.Data()));
+               if (!SendMail(kPPEMail))
                        Log("SHUTTLE", Form("ContinueProcessing - Could not send mail to %s expert",
-                                       fCurrentDetector.Data()));
+                                           fCurrentDetector.Data()));
 
        } else {
                Log("SHUTTLE", Form("ContinueProcessing - %s: restarting. "
@@ -1444,7 +1169,8 @@ Bool_t AliShuttle::ContinueProcessing()
                                status->GetStatusName(), status->GetCount()));
                Bool_t increaseCount = kTRUE;
                if (status->GetStatus() == AliShuttleStatus::kDCSError || 
-                       status->GetStatus() == AliShuttleStatus::kDCSStarted)
+                   status->GetStatus() == AliShuttleStatus::kDCSStarted ||
+                   status->GetStatus() == AliShuttleStatus::kFXSError)
                                increaseCount = kFALSE;
                                
                UpdateShuttleStatus(AliShuttleStatus::kStarted, increaseCount);
@@ -1472,8 +1198,17 @@ Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry)
                                        GetCurrentRun()));
 
        // Send the information to ML
+       CountOpenRuns();
+       
        TMonaLisaText  mlStatus("SHUTTLE_status", "Processing");
-       TMonaLisaText  mlRunType("SHUTTLE_runtype", Form("%s (%s)", entry->GetRunType(), entry->GetRunParameter("log")));
+       TString runType(entry->GetRunType());
+       if (strlen(entry->GetRunParameter("log")) > 0){
+
+               runType += "(";
+               runType += entry->GetRunParameter("log");
+               runType += ")";
+       }
+       TMonaLisaText  mlRunType("SHUTTLE_runtype", runType);
 
        TList mlList;
        mlList.Add(&mlStatus);
@@ -1537,13 +1272,12 @@ Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry)
                return 0; 
        }       
        
-       if (fgkMainCDB.Length() == 0)
-               fgkMainCDB = Form("alien://folder=/alice/data/%d/%s/OCDB?user=alidaq?cacheFold=/tmp/OCDBCache", 
-                                       GetCurrentYear(), lhcPeriod.Data());
+       // build cdb paths (repeat each time, LHCperiod might have changed)
+       fgkMainCDB.Form("alien://folder=%s%d/%s/OCDB?user=alidaq?cacheFold=/tmp/OCDBCache", 
+                                       fConfig->GetAlienPath(), GetCurrentYear(), lhcPeriod.Data());
        
-       if (fgkMainRefStorage.Length() == 0)
-               fgkMainRefStorage = Form("alien://folder=/alice/data/%d/%s/Reference?user=alidaq?cacheFold=/tmp/OCDBCache", 
-                                       GetCurrentYear(), lhcPeriod.Data());
+       fgkMainRefStorage.Form("alien://folder=%s%d/%s/Reference?user=alidaq?cacheFold=/tmp/OCDBCache", 
+                                       fConfig->GetAlienPath(), GetCurrentYear(), lhcPeriod.Data());
        
        // Loop on detectors in the configuration
        TIter iter(fConfig->GetDetectors());
@@ -1555,7 +1289,8 @@ Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry)
        {
                fCurrentDetector = aDetector->String();
 
-               if (ContinueProcessing() == kFALSE) continue;
+               if (ContinueProcessing() == kFALSE) 
+                       continue;
                
                if (first)
                {
@@ -1604,7 +1339,7 @@ Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry)
 
                                        kill(pid, 9);
 
-                                       UpdateShuttleStatus(AliShuttleStatus::kPPTimeOut);
+                                       UpdateShuttleStatus(AliShuttleStatus::kPPTimeOut);
                                        hasError = kTRUE;
 
                                        gSystem->Sleep(1000);
@@ -1683,8 +1418,8 @@ Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry)
                }
                else if (pid == 0)
                {
-                       // client
-                       Log("SHUTTLE", Form("Process - In client process of %d - %s", GetCurrentRun(),
+                       // child
+                       Log("SHUTTLE", Form("Process - In child process of %d - %s", GetCurrentRun(),
                                aDetector->GetName()));
 
                        Log("SHUTTLE", Form("Process - Redirecting output to %s log",fCurrentDetector.Data()));
@@ -1725,15 +1460,20 @@ Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry)
                                gSystem->Exit(1);                       
                        }
                        
-                       Bool_t success = ProcessCurrentDetector();
-                       
+                       Int_t success = ProcessCurrentDetector();
+
                        gSystem->ChangeDirectory(wd.Data());
                                                
-                       if (success) // Preprocessor finished successfully!
+                       if (success == 1) // Preprocessor finished successfully!
                        { 
-                               // remove temporary folder
-                                // temporary commented (JF)
-                               //gSystem->Exec(Form("rm -rf %s",tmpDir.Data()));
+                               // remove temporary folder or DCS map
+                               if (!fConfig->KeepTempFolder())
+                               {
+                                       gSystem->Exec(Form("rm -rf %s",tmpDir.Data()));
+                               } else if (!fConfig->KeepDCSMap())
+                               {
+                                       gSystem->Exec(Form("rm -f %s/DCSMap.root",tmpDir.Data()));
+                               }
                                
                                // Update time_processed field in FXS DB
                                if (UpdateTable() == kFALSE)
@@ -1741,22 +1481,10 @@ Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry)
                                                        fCurrentDetector.Data()));
 
                                // Transfer the data from local storage to main storage (Grid)
-                               UpdateShuttleStatus(AliShuttleStatus::kStoreStarted);
                                if (StoreOCDB() == kFALSE)
-                               {
-                                       Log("SHUTTLE", 
-                                               Form("\t\t\t****** run %d - %s: STORAGE ERROR ******",
-                                                       GetCurrentRun(), aDetector->GetName()));
-                                       UpdateShuttleStatus(AliShuttleStatus::kStoreError);
                                        success = kFALSE;
-                               } else {
-                                       Log("SHUTTLE", 
-                                               Form("\t\t\t****** run %d - %s: DONE ******",
-                                                       GetCurrentRun(), aDetector->GetName()));
-                                       UpdateShuttleStatus(AliShuttleStatus::kDone);
-                                       UpdateShuttleLogbook(fCurrentDetector, "DONE");
-                               }
-                       } else 
+                       } 
+                       else if (success == 0)
                        {
                                Log("SHUTTLE", 
                                        Form("\t\t\t****** run %d - %s: PP ERROR ******",
@@ -1813,6 +1541,10 @@ Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry)
                                        fFirstUnprocessed[iDet] = kFALSE;
                                }
                        }
+                       TMonaLisaText  mlStatusPending("SHUTTLE_status", "Pending");
+                       mlList.Clear();
+                       mlList.Add(&mlStatusPending);
+                       fMonaLisa->SendParameters(&mlList, mlID);
                }
        }
 
@@ -1822,7 +1554,7 @@ Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry)
 }
 
 //______________________________________________________________________________________________
-Bool_t AliShuttle::ProcessCurrentDetector()
+Int_t AliShuttle::ProcessCurrentDetector()
 {
        //
         // Makes data retrieval just for a specific detector (fCurrentDetector).
@@ -1834,16 +1566,26 @@ Bool_t AliShuttle::ProcessCurrentDetector()
        TString wd = gSystem->WorkingDirectory();
        
        if (!CleanReferenceStorage(fCurrentDetector.Data()))
-               return kFALSE;
+               return 0;
        
        gSystem->ChangeDirectory(wd.Data());
        
-       TMap* dcsMap = new TMap();
-
        // call preprocessor
        AliPreprocessor* aPreprocessor =
                dynamic_cast<AliPreprocessor*> (fPreprocessorMap.GetValue(fCurrentDetector));
 
+       // check if the preprocessor wants to process this run type
+       if (aPreprocessor->ProcessRunType() == kFALSE)
+       {
+               UpdateShuttleStatus(AliShuttleStatus::kSkipped);
+               UpdateShuttleLogbook(fCurrentDetector, "DONE");
+               Log(fCurrentDetector, Form("ProcessCurrentDetector - %s preprocessor is not interested in this run type", fCurrentDetector.Data()));
+       
+               return 2;
+       }
+       
+       TMap* dcsMap = new TMap();
+       
        aPreprocessor->Initialize(GetCurrentRun(), GetCurrentStartTime(), GetCurrentEndTime());
 
        Bool_t processDCS = aPreprocessor->ProcessDCS();
@@ -1863,7 +1605,7 @@ Bool_t AliShuttle::ProcessCurrentDetector()
                UpdateShuttleStatus(AliShuttleStatus::kDCSStarted);
                UpdateShuttleStatus(AliShuttleStatus::kDCSError);
                delete dcsMap;
-               return kFALSE;
+               return 0;
        } else {
 
                UpdateShuttleStatus(AliShuttleStatus::kDCSStarted);
@@ -1884,7 +1626,7 @@ Bool_t AliShuttle::ProcessCurrentDetector()
                        
                        TMap* aliasMap = 0;
                        TMap* dpMap = 0;
-       
+
                        if (fConfig->GetDCSAliases(fCurrentDetector, iServ)->GetEntries() > 0)
                        {
                                aliasMap = GetValueSet(host, port, 
@@ -1898,11 +1640,12 @@ Bool_t AliShuttle::ProcessCurrentDetector()
                                                        " Sending mail to DCS experts!", host.Data()));
                                        UpdateShuttleStatus(AliShuttleStatus::kDCSError);
                                        
-                                       //if (!SendMailToDCS())
-                                       //      Log("SHUTTLE", Form("ProcessCurrentDetector - Could not send mail to DCS experts!"));
+                                       if (!SendMail(kDCSEMail))
+                                               Log("SHUTTLE", Form("ProcessCurrentDetector - "
+                                                                   "Could not send mail to DCS experts!"));
 
                                        delete dcsMap;
-                                       return kFALSE;
+                                       return 0;
                                }
                        }
                        
@@ -1919,12 +1662,13 @@ Bool_t AliShuttle::ProcessCurrentDetector()
                                                        " Sending mail to DCS experts!", host.Data()));
                                        UpdateShuttleStatus(AliShuttleStatus::kDCSError);
                                        
-                                       //if (!SendMailToDCS())
-                                       //      Log("SHUTTLE", Form("ProcessCurrentDetector - Could not send mail to DCS experts!"));
+                                       if (!SendMail(kDCSEMail))
+                                               Log("SHUTTLE", Form("ProcessCurrentDetector - "
+                                                                   "Could not send mail to DCS experts!"));
                                        
                                        if (aliasMap) delete aliasMap;
                                        delete dcsMap;
-                                       return kFALSE;
+                                       return 0;
                                }                               
                        }
                        
@@ -1961,7 +1705,17 @@ Bool_t AliShuttle::ProcessCurrentDetector()
        // DCS Archive DB processing successful. Call Preprocessor!
        UpdateShuttleStatus(AliShuttleStatus::kPPStarted);
 
+       fFXSError = -1; // this variable is kTRUE after ::Process if an FXS error occured
+       
        UInt_t returnValue = aPreprocessor->Process(dcsMap);
+       
+       if (fFXSError!=-1) {
+               UpdateShuttleStatus(AliShuttleStatus::kFXSError);
+               SendMail(kFXSEMail, fFXSError);
+               dcsMap->DeleteAll();
+               delete dcsMap;
+               return 0;
+       }
 
        if (returnValue > 0) // Preprocessor error!
        {
@@ -1970,7 +1724,7 @@ Bool_t AliShuttle::ProcessCurrentDetector()
                UpdateShuttleStatus(AliShuttleStatus::kPPError);
                dcsMap->DeleteAll();
                delete dcsMap;
-               return kFALSE;
+               return 0;
        }
        
        // preprocessor ok!
@@ -1981,7 +1735,7 @@ Bool_t AliShuttle::ProcessCurrentDetector()
        dcsMap->DeleteAll();
        delete dcsMap;
 
-       return kTRUE;
+       return 1;
 }
 
 //______________________________________________________________________________________________
@@ -2141,119 +1895,44 @@ AliShuttleLogbookEntry* AliShuttle::QueryRunParameters(Int_t run)
        for (Int_t ii = 0; ii < aResult->GetFieldCount(); ii++)
                entry->SetRunParameter(aResult->GetFieldName(ii), aRow->GetField(ii));
 
+       delete aRow;
+       delete aResult;
+       
        UInt_t startTime = entry->GetStartTime();
        UInt_t endTime = entry->GetEndTime();
-
-//     if (!startTime || !endTime || startTime > endTime) 
-//     {
-//             Log("SHUTTLE",
-//                     Form("QueryRunParameters - Invalid parameters for Run %d: startTime = %d, endTime = %d. Skipping!",
-//                             run, startTime, endTime));              
-//             
-//             Log("SHUTTLE", Form("Marking SHUTTLE done for run %d", run));
-//             fLogbookEntry = entry;  
-//             if (!UpdateShuttleLogbook("shuttle_done"))
-//             {
-//                     AliError(Form("Could not update logbook for run %d !", run));
-//             }
-//             fLogbookEntry = 0;
-//                             
-//             delete entry;
-//             delete aRow;
-//             delete aResult;
-//             return 0;
-//     }
-
-       if (!startTime) 
-       {
-               Log("SHUTTLE",
-                       Form("QueryRunParameters - Invalid parameters for Run %d: " 
-                               "startTime = %d, endTime = %d. Skipping!",
-                                       run, startTime, endTime));              
-               
-               Log("SHUTTLE", Form("Marking SHUTTLE done for run %d", run));
-               fLogbookEntry = entry;  
-               if (!UpdateShuttleLogbook("shuttle_ignored"))
-               {
-                       AliError(Form("Could not update logbook for run %d !", run));
-               }
-               fLogbookEntry = 0;
-                               
-               delete entry;
-               delete aRow;
-               delete aResult;
-               return 0;
-       }
+       Bool_t ecsSuccess = entry->GetECSSuccess();
        
-       if (startTime && !endTime) 
-       {
-               // TODO Here we don't mark SHUTTLE done, because this may mean 
-               //the run is still ongoing!!            
-               Log("SHUTTLE",
-                       Form("QueryRunParameters - Invalid parameters for Run %d: "
-                            "startTime = %d, endTime = %d. Skipping (Shuttle won't be marked as DONE)!",
-                                       run, startTime, endTime));              
+       TString totEventsStr = entry->GetRunParameter("totalEvents");  
+       Int_t totEvents = totEventsStr.Atoi();
+       
+       if (startTime != 0 && endTime != 0 && endTime > startTime && totEvents > 0 && ecsSuccess)
+               return entry;
                
-               //Log("SHUTTLE", Form("Marking SHUTTLE done for run %d", run));
-               //fLogbookEntry = entry;        
-               //if (!UpdateShuttleLogbook("shuttle_done"))
-               //{
-               //      AliError(Form("Could not update logbook for run %d !", run));
-               //}
-               //fLogbookEntry = 0;
-                               
-               delete entry;
-               delete aRow;
-               delete aResult;
-               return 0;
+       if (ecsSuccess == kFALSE)
+       {
+               Log("SHUTTLE", Form("Skipped run %d due to ECS failure, Reason: %s", run, entry->GetRunParameter("eor_reason")));
        }
-                       
-       if (startTime && endTime && (startTime > endTime)) 
+       else if (totEvents < 1) 
        {
-               Log("SHUTTLE",
-                       Form("QueryRunParameters - Invalid parameters for Run %d: "
-                               "startTime = %d, endTime = %d. Skipping!",
-                                       run, startTime, endTime));              
-               
-               Log("SHUTTLE", Form("Marking SHUTTLE done for run %d", run));
-               fLogbookEntry = entry;  
-               if (!UpdateShuttleLogbook("shuttle_ignored"))
-               {
-                       AliError(Form("Could not update logbook for run %d !", run));
-               }
-               fLogbookEntry = 0;
-                               
-               delete entry;
-               delete aRow;
-               delete aResult;
-               return 0;
+               Log("SHUTTLE", Form("QueryRunParameters - Run %d has 0 events - Skipping!", run));
        }
-                       
-       TString totEventsStr = entry->GetRunParameter("totalEvents");  
-       Int_t totEvents = totEventsStr.Atoi();
-       if (totEvents < 1) 
+       else
        {
-               Log("SHUTTLE",
-                       Form("QueryRunParameters - Run %d has 0 events - Skipping!", run));             
-               
-               Log("SHUTTLE", Form("Marking SHUTTLE done for run %d", run));           
-               fLogbookEntry = entry;  
-               if (!UpdateShuttleLogbook("shuttle_ignored"))
-               {
-                       AliError(Form("Could not update logbook for run %d !", run));
-               }
-               fLogbookEntry = 0;
-                               
-               delete entry;
-               delete aRow;
-               delete aResult;
-               return 0;
+               Log("SHUTTLE", Form("QueryRunParameters - Invalid parameters for Run %d: "
+                       "startTime = %d, endTime = %d. Skipping (Shuttle won't be marked as DONE)!",
+                       run, startTime, endTime));
        }
 
-       delete aRow;
-       delete aResult;
-
-       return entry;
+       //Log("SHUTTLE", Form("Marking SHUTTLE done for run %d", run));
+       //fLogbookEntry = entry;        
+       //if (!UpdateShuttleLogbook("shuttle_done"))
+       //{
+       //      AliError(Form("Could not update logbook for run %d !", run));
+       //}
+       //fLogbookEntry = 0;
+                       
+       delete entry;
+       return 0;
 }
 
 //______________________________________________________________________________________________
@@ -2317,6 +1996,7 @@ const char* AliShuttle::GetFile(Int_t system, const char* detector,
        if (!Connect(system))
        {
                Log(detector, Form("GetFile - Couldn't connect to %s FXS database", GetSystemName(system)));
+               fFXSError = system;
                return 0;
        }
 
@@ -2339,7 +2019,6 @@ const char* AliShuttle::GetFile(Int_t system, const char* detector,
        else if (system == kHLT)
        {
                whereClause += Form(" and DDLnumbers=\"%s\"", source);
-               nFields = 3;
        }
 
        TString sqlQuery = Form("%s %s", sqlQueryStart.Data(), whereClause.Data());
@@ -2350,15 +2029,16 @@ const char* AliShuttle::GetFile(Int_t system, const char* detector,
        TSQLResult* aResult = 0;
        aResult = dynamic_cast<TSQLResult*> (fServer[system]->Query(sqlQuery));
        if (!aResult) {
-               Log(detector, Form("GetFileName - Can't execute SQL query to %s database for: id = %s, source = %s",
+               Log(detector, Form("GetFile - Can't execute SQL query to %s database for: id = %s, source = %s",
                                GetSystemName(system), id, sourceName.Data()));
+               fFXSError = system;
                return 0;
        }
 
-       if(aResult->GetRowCount() == 0)
+       if (aResult->GetRowCount() == 0)
        {
                Log(detector,
-                       Form("GetFileName - No entry in %s FXS db for: id = %s, source = %s",
+                       Form("GetFile - No entry in %s FXS db for: id = %s, source = %s",
                                GetSystemName(system), id, sourceName.Data()));
                delete aResult;
                return 0;
@@ -2366,8 +2046,9 @@ const char* AliShuttle::GetFile(Int_t system, const char* detector,
 
        if (aResult->GetRowCount() > 1) {
                Log(detector,
-                       Form("GetFileName - More than one entry in %s FXS db for: id = %s, source = %s",
+                       Form("GetFile - More than one entry in %s FXS db for: id = %s, source = %s",
                                GetSystemName(system), id, sourceName.Data()));
+               fFXSError = system;
                delete aResult;
                return 0;
        }
@@ -2376,6 +2057,7 @@ const char* AliShuttle::GetFile(Int_t system, const char* detector,
                Log(detector,
                        Form("GetFileName - Wrong field count in %s FXS db for: id = %s, source = %s",
                                GetSystemName(system), id, sourceName.Data()));
+               fFXSError = system;
                delete aResult;
                return 0;
        }
@@ -2383,8 +2065,9 @@ const char* AliShuttle::GetFile(Int_t system, const char* detector,
        TSQLRow* aRow = dynamic_cast<TSQLRow*> (aResult->Next());
 
        if (!aRow){
-               Log(detector, Form("GetFileName - Empty set result in %s FXS db from query: id = %s, source = %s",
+               Log(detector, Form("GetFile - Empty set result in %s FXS db from query: id = %s, source = %s",
                                GetSystemName(system), id, sourceName.Data()));
+               fFXSError = system;
                delete aResult;
                return 0;
        }
@@ -2412,25 +2095,45 @@ const char* AliShuttle::GetFile(Int_t system, const char* detector,
        Bool_t result = kFALSE;
 
        // copy!! if successful TSystem::Exec returns 0
-       while(nRetries++ < maxRetries) {
+       while (nRetries++ < maxRetries) {
                AliDebug(2, Form("Trying to copy file. Retry # %d", nRetries));
                result = RetrieveFile(system, filePath.Data(), localFileName.Data());
-               if(!result)
+               if (!result)
                {
-                       Log(detector, Form("GetFileName - Copy of file %s from %s FXS failed",
+                       Log(detector, Form("GetFile - Copy of file %s from %s FXS failed",
                                        filePath.Data(), GetSystemName(system)));
                        continue;
                } 
 
+                if (fileSize.Length()>0)
+                {
+                        // compare filesize of local file with the one stored in the FXS DB
+                       Long_t size = -1;
+                       Int_t sizeComp = gSystem->GetPathInfo(localFileName.Data(), 0, &size, 0, 0);
+
+                       if (sizeComp != 0 || size != fileSize.Atoi())
+                       {
+                               Log(detector, Form("GetFile - size of file %s does not match with local copy!",
+                                                       filePath.Data()));
+                               result = kFALSE;
+                               continue;
+                       }
+
+               } else {
+                       Log(fCurrentDetector, Form("GetFile - size of file %s not set in %s database, skipping comparison",
+                                               filePath.Data(), GetSystemName(system)));
+                }
+
                if (fileChecksum.Length()>0)
                {
                        // compare md5sum of local file with the one stored in the FXS DB
-                       Int_t md5Comp = gSystem->Exec(Form("md5sum %s |grep %s 2>&1 > /dev/null",
+                       if(fileChecksum.Contains(' ')) fileChecksum.Resize(fileChecksum.First(' '));
+                       Int_t md5Comp = gSystem->Exec(Form("md5sum %s |grep %s > /dev/null 2> /dev/null",
                                                localFileName.Data(), fileChecksum.Data()));
 
                        if (md5Comp != 0)
                        {
-                               Log(detector, Form("GetFileName - md5sum of file %s does not match with local copy!",
+                               Log(detector, Form("GetFile - md5sum of file %s does not match with local copy!",
                                                        filePath.Data()));
                                result = kFALSE;
                                continue;
@@ -2442,7 +2145,11 @@ const char* AliShuttle::GetFile(Int_t system, const char* detector,
                if (result) break;
        }
 
-       if(!result) return 0;
+       if (!result) 
+       {
+               fFXSError = system;
+               return 0;
+       }
 
        fFXSCalled[system]=kTRUE;
        TObjString *fileParams = new TObjString(Form("%s#!?!#%s", id, sourceName.Data()));
@@ -2483,26 +2190,11 @@ Bool_t AliShuttle::RetrieveFile(UInt_t system, const char* fxsFileName, const ch
                }
        }
 
-       TString baseFXSFolder;
-       if (system == kDAQ)
-       {
-               baseFXSFolder = "FES/";
-       }
-       else if (system == kDCS)
-       {
-               baseFXSFolder = "";
-       }
-       else if (system == kHLT)
-       {
-               baseFXSFolder = "/opt/FXS/";
-       }
-
-
-       TString command = Form("scp -oPort=%d -2 %s@%s:%s%s %s",
+       TString command = Form("scp -oPort=%d -2 %s@%s:%s/%s %s",
                fConfig->GetFXSPort(system),
                fConfig->GetFXSUser(system),
                fConfig->GetFXSHost(system),
-               baseFXSFolder.Data(),
+               fConfig->GetFXSBaseFolder(system),
                fxsFileName,
                localFileName);
 
@@ -2548,6 +2240,7 @@ TList* AliShuttle::GetFileSources(Int_t system, const char* detector, const char
        if (!Connect(system))
        {
                Log(detector, Form("GetFileSources - Couldn't connect to %s FXS database", GetSystemName(system)));
+               fFXSError = system;
                return NULL;
        }
 
@@ -2575,6 +2268,7 @@ TList* AliShuttle::GetFileSources(Int_t system, const char* detector, const char
        if (!aResult) {
                Log(detector, Form("GetFileSources - Can't execute SQL query to %s database for id: %s",
                                GetSystemName(system), id));
+               fFXSError = system;
                return 0;
        }
 
@@ -2898,15 +2592,21 @@ Bool_t AliShuttle::UpdateShuttleLogbook(const char* detector, const char* status
 
                if (detName == "shuttle_done")
                {
-                       // Send the information to ML
-                       TMonaLisaText  mlStatus("SHUTTLE_status", "Done");
+                       if (TouchFile()==kTRUE){
+                               //Send the information to ML
+                               TMonaLisaText  mlStatus("SHUTTLE_status", "Done");
 
-                       TList mlList;
-                       mlList.Add(&mlStatus);
-               
-                       TString mlID;
-                       mlID.Form("%d", GetCurrentRun());
-                       fMonaLisa->SendParameters(&mlList, mlID);
+                               TList mlList;
+                               mlList.Add(&mlStatus);
+                               
+                               TString mlID;
+                               mlID.Form("%d", GetCurrentRun());
+                               fMonaLisa->SendParameters(&mlList, mlID);
+                       }
+                       else{
+                               return kFALSE;
+                       }
+                                       
                }
        } else {
                TString statusStr(status);
@@ -3020,7 +2720,7 @@ void AliShuttle::Log(const char* detector, const char* message)
                gSystem->FreeDirectory(dir);
        }
 
-       TString toLog = Form("%s (%d): %s - ", TTimeStamp(time(0)).AsString("s"), getpid(), detector);
+       TString toLog = Form("%s UTC (%d): %s - ", TTimeStamp(time(0)).AsString("s"), getpid(), detector);
        if (GetCurrentRun() >= 0) 
                toLog += Form("run %d - ", GetCurrentRun());
        toLog += Form("%s", message);
@@ -3133,9 +2833,9 @@ Bool_t AliShuttle::Collect(Int_t run)
        {
                // query Shuttle logbook for earlier runs, check if some detectors are unprocessed,
                // flag them into fFirstUnprocessed array
-               TString whereClause(Form("where shuttle_done=0 and run < %d", run));
+               TString whereClauseBis(Form("where shuttle_done=0 and run < %d", run));
                TObjArray tmpLogbookEntries;
-               if (!QueryShuttleLogbook(whereClause, tmpLogbookEntries))
+               if (!QueryShuttleLogbook(whereClauseBis, tmpLogbookEntries))
                {
                        Log("SHUTTLE", "Collect - Can't retrieve entries from Shuttle logbook");
                        return kFALSE;
@@ -3162,10 +2862,12 @@ Bool_t AliShuttle::Collect(Int_t run)
        if (!RetrieveConditionsData(shuttleLogbookEntries))
        {
                Log("SHUTTLE", "Collect - Process of at least one run failed");
+               CountOpenRuns();
                return kFALSE;
        }
 
        Log("SHUTTLE", "Collect - Requested run(s) successfully processed");
+       CountOpenRuns();
        return kTRUE;
 }
 
@@ -3284,7 +2986,7 @@ AliCDBEntry* AliShuttle::GetFromOCDB(const char* detector, const AliCDBPath& pat
 }
 
 //______________________________________________________________________________________________
-Bool_t AliShuttle::SendMail()
+Bool_t AliShuttle::SendMail(EMailTarget target, Int_t system)
 {
        //
        // sends a mail to the subdetector expert in case of preprocessor error
@@ -3292,23 +2994,19 @@ Bool_t AliShuttle::SendMail()
        
        if (fTestMode != kNone)
                return kTRUE;
+               
+       if (!fConfig->SendMail()) 
+               return kTRUE;
 
-       TString to="";
-       TIter iterExperts(fConfig->GetResponsibles(fCurrentDetector));
-       TObjString *anExpert=0;
-       while ((anExpert = (TObjString*) iterExperts.Next()))
-       {
-               to += Form("%s,", anExpert->GetName());
-       }
-       if (to.Length() > 0)
-         to.Remove(to.Length()-1);
-       AliDebug(2, Form("to: %s",to.Data()));
-
-       if (to.IsNull()) {
-               Log("SHUTTLE", "List of detector responsibles not yet set!");
-               return kFALSE;
+       if (target == kDCSEMail || target == kFXSEMail) {
+               if (!fFirstProcessing)
+               return kTRUE;
        }
 
+       Int_t runMode = (Int_t)fConfig->GetRunMode();
+       TString tmpStr;
+       if (runMode == 0) tmpStr = " Nightly Test:";
+       else tmpStr = " Data Taking:"; 
        void* dir = gSystem->OpenDirectory(GetShuttleLogDir());
        if (dir == NULL)
        {
@@ -3322,111 +3020,55 @@ Bool_t AliShuttle::SendMail()
                gSystem->FreeDirectory(dir);
        }
 
-       TString bodyFileName;
-       bodyFileName.Form("%s/mail.body", GetShuttleLogDir());
-       gSystem->ExpandPathName(bodyFileName);
-
-       ofstream mailBody;
-       mailBody.open(bodyFileName, ofstream::out);
-
-       if (!mailBody.is_open())
-       {
-               Log("SHUTTLE", Form("Could not open mail body file %s", bodyFileName.Data()));
-               return kFALSE;
-       }
-
-       TString cc="alberto.colla@cern.ch";
-
-       TString subject = Form("%s Shuttle preprocessor FAILED in run %d (run type = %s)!",
-                               fCurrentDetector.Data(), GetCurrentRun(), GetRunType());
-       AliDebug(2, Form("subject: %s", subject.Data()));
+       // det experts in to
+       TString to="";
+       TIter *iterExperts = 0;
+       if (target == kDCSEMail) {
+               iterExperts = new TIter(fConfig->GetAdmins(AliShuttleConfig::kAmanda));
+       }
+       else if (target == kFXSEMail) {
+               iterExperts = new TIter(fConfig->GetAdmins(system));
+       }
+       if (iterExperts) {
+               TObjString *anExpert=0;
+               while ((anExpert = (TObjString*) iterExperts->Next()))
+               {
+                       to += Form("%s,", anExpert->GetName());
+               }
+               delete iterExperts;
+       }
 
-       TString body = Form("Dear %s expert(s), \n\n", fCurrentDetector.Data());
-       body += Form("SHUTTLE just detected that your preprocessor "
-                       "failed processing run %d (run type = %s)!!\n\n", 
-                                       GetCurrentRun(), GetRunType());
-       body += Form("Please check %s status on the SHUTTLE monitoring page: \n\n", 
-                               fCurrentDetector.Data());
-       if (fConfig->GetRunMode() == AliShuttleConfig::kTest)
+       // add subdetector experts      
+       iterExperts = new TIter(fConfig->GetResponsibles(fCurrentDetector));
+       TObjString *anExpert=0;
+       while ((anExpert = (TObjString*) iterExperts->Next()))
        {
-               body += Form("\thttp://pcalimonitor.cern.ch:8889/shuttle.jsp?time=168 \n\n");
-       } else {
-               body += Form("\thttp://pcalimonitor.cern.ch/shuttle.jsp?instance=PROD&time=168 \n\n");
+               to += Form("%s,", anExpert->GetName());
        }
+       delete iterExperts;
        
-       
-       TString logFolder = "logs";
-       if (fConfig->GetRunMode() == AliShuttleConfig::kProd) 
-               logFolder += "_PROD";
-       
-       
-       body += Form("Find the %s log for the current run on \n\n"
-               "\thttp://pcalishuttle01.cern.ch:8880/%s/%d/%s_%d.log \n\n", 
-               fCurrentDetector.Data(), logFolder.Data(), GetCurrentRun(), 
-                               fCurrentDetector.Data(), GetCurrentRun());
-       body += Form("The last 10 lines of %s log file are following:\n\n", fCurrentDetector.Data());
-
-       AliDebug(2, Form("Body begin: %s", body.Data()));
-
-       mailBody << body.Data();
-       mailBody.close();
-       mailBody.open(bodyFileName, ofstream::out | ofstream::app);
+       if (to.Length() > 0)
+         to.Remove(to.Length()-1);
+       AliDebug(2, Form("to: %s",to.Data()));
 
-       TString logFileName = Form("%s/%d/%s_%d.log", GetShuttleLogDir(), 
-               GetCurrentRun(), fCurrentDetector.Data(), GetCurrentRun());
-       TString tailCommand = Form("tail -n 10 %s >> %s", logFileName.Data(), bodyFileName.Data());
-       if (gSystem->Exec(tailCommand.Data()))
-       {
-               mailBody << Form("%s log file not found ...\n\n", fCurrentDetector.Data());
+       if (to.IsNull()) {
+               Log("SHUTTLE", Form("List of %d responsibles not set!", (Int_t) target));
+               return kFALSE;
        }
 
-       TString endBody = Form("------------------------------------------------------\n\n");
-       endBody += Form("In case of problems please contact the SHUTTLE core team.\n\n");
-       endBody += "Please do not answer this message directly, it is automatically generated.\n\n";
-       endBody += "Greetings,\n\n \t\t\tthe SHUTTLE\n";
-
-       AliDebug(2, Form("Body end: %s", endBody.Data()));
-
-       mailBody << endBody.Data();
-
-       mailBody.close();
-
-       // send mail!
-       TString mailCommand = Form("mail -s \"%s\" -c %s %s < %s",
-                                               subject.Data(),
-                                               cc.Data(),
-                                               to.Data(),
-                                               bodyFileName.Data());
-       AliDebug(2, Form("mail command: %s", mailCommand.Data()));
-
-       Bool_t result = gSystem->Exec(mailCommand.Data());
-
-       return result == 0;
-}
-
-//______________________________________________________________________________________________
-Bool_t AliShuttle::SendMailToDCS()
-{
-       //
-       // sends a mail to the DCS experts in case of DCS error
-       //
-       
-       if (fTestMode != kNone)
-               return kTRUE;
-
-       void* dir = gSystem->OpenDirectory(GetShuttleLogDir());
-       if (dir == NULL)
+       // SHUTTLE responsibles in cc
+       TString cc="";
+       TIter iterAdmins(fConfig->GetAdmins(AliShuttleConfig::kGlobal));
+       TObjString *anAdmin=0;
+       while ((anAdmin = (TObjString*) iterAdmins.Next()))
        {
-               if (gSystem->mkdir(GetShuttleLogDir(), kTRUE))
-               {
-                       Log("SHUTTLE", Form("SendMailToDCS - Can't open directory <%s>", GetShuttleLogDir()));
-                       return kFALSE;
-               }
-
-       } else {
-               gSystem->FreeDirectory(dir);
+               cc += Form("%s,", anAdmin->GetName());
        }
+       if (cc.Length() > 0)
+         cc.Remove(cc.Length()-1);
+       AliDebug(2, Form("cc: %s",to.Data()));
 
+       // mail body 
        TString bodyFileName;
        bodyFileName.Form("%s/mail.body", GetShuttleLogDir());
        gSystem->ExpandPathName(bodyFileName);
@@ -3436,37 +3078,57 @@ Bool_t AliShuttle::SendMailToDCS()
 
        if (!mailBody.is_open())
        {
-               Log("SHUTTLE", Form("SendMailToDCS - Could not open mail body file %s", bodyFileName.Data()));
+               Log("SHUTTLE", Form("Could not open mail body file %s", bodyFileName.Data()));
                return kFALSE;
        }
 
-       TString to="Vladimir.Fekete@cern.ch, Svetozar.Kapusta@cern.ch";
-       //TString to="alberto.colla@cern.ch";
-       AliDebug(2, Form("to: %s",to.Data()));
 
-       if (to.IsNull()) {
-               Log("SHUTTLE", "List of detector responsibles not yet set!");
-               return kFALSE;
-       }
+       TString subject;
+       TString body;
 
-       TString cc="alberto.colla@cern.ch";
-
-       TString subject = Form("Retrieval of data points for %s FAILED in run %d !",
-                               fCurrentDetector.Data(), GetCurrentRun());
-       AliDebug(2, Form("subject: %s", subject.Data()));
+       if (target == kDCSEMail){
+               subject = Form("%s Retrieval of data points for %s FAILED in run %d !",
+                               tmpStr.Data(), fCurrentDetector.Data(), GetCurrentRun());
+               AliDebug(2, Form("subject: %s", subject.Data()));
+               
+               body = Form("Dear DCS experts, \n\n");
+               body += Form("SHUTTLE couldn\'t retrieve the data points for detector %s "
+                            "in run %d!!\n\n", fCurrentDetector.Data(), GetCurrentRun());
+       }
+       else if (target == kFXSEMail){
+               subject = Form("%s FXS communication for %s FAILED in run %d !",
+                               tmpStr.Data(), fCurrentDetector.Data(), GetCurrentRun());
+               AliDebug(2, Form("subject: %s", subject.Data()));
+               TString sys;
+               if (system == kDAQ) sys="DAQ";
+               else if (system == kDCS) sys="DCS";
+               else if (system == kHLT) sys="HLT";
+               else return kFALSE;
+               body = Form("Dear  %s FXS experts, \n\n",sys.Data());
+               body += Form("SHUTTLE couldn\'t retrieve data from the FXS for detector %s "
+                            "in run %d!!\n\n", fCurrentDetector.Data(), GetCurrentRun());
+       }
+       else {
+               subject = Form("%s %s Shuttle preprocessor FAILED in run %d (run type = %s)!",
+                                      tmpStr.Data(), fCurrentDetector.Data(), GetCurrentRun(), GetRunType());
+               AliDebug(2, Form("subject: %s", subject.Data()));
+       
+               body = Form("Dear %s expert(s), \n\n", fCurrentDetector.Data());
+               body += Form("SHUTTLE just detected that your preprocessor "
+                            "failed processing run %d (run type = %s)!!\n\n", 
+                            GetCurrentRun(), GetRunType());
+       }
 
-       TString body = Form("Dear DCS experts, \n\n");
-       body += Form("SHUTTLE couldn\'t retrieve the data points for detector %s "
-                       "in run %d!!\n\n", fCurrentDetector.Data(), GetCurrentRun());
        body += Form("Please check %s status on the SHUTTLE monitoring page: \n\n", 
                                fCurrentDetector.Data());
        if (fConfig->GetRunMode() == AliShuttleConfig::kTest)
        {
                body += Form("\thttp://pcalimonitor.cern.ch:8889/shuttle.jsp?time=168 \n\n");
        } else {
-               body += Form("\thttp://pcalimonitor.cern.ch/shuttle.jsp?instance=PROD?time=168 \n\n");
+               body += Form("\thttp://pcalimonitor.cern.ch/shuttle.jsp?instance=PROD&time=168 \n\n");
        }
-
+       
+       
        TString logFolder = "logs";
        if (fConfig->GetRunMode() == AliShuttleConfig::kProd) 
                logFolder += "_PROD";
@@ -3484,8 +3146,8 @@ Bool_t AliShuttle::SendMailToDCS()
        mailBody.close();
        mailBody.open(bodyFileName, ofstream::out | ofstream::app);
 
-       TString logFileName = Form("%s/%d/%s_%d.log", GetShuttleLogDir(), GetCurrentRun(),
-               fCurrentDetector.Data(), GetCurrentRun());
+       TString logFileName = Form("%s/%d/%s_%d.log", GetShuttleLogDir(), 
+               GetCurrentRun(), fCurrentDetector.Data(), GetCurrentRun());
        TString tailCommand = Form("tail -n 10 %s >> %s", logFileName.Data(), bodyFileName.Data());
        if (gSystem->Exec(tailCommand.Data()))
        {
@@ -3535,18 +3197,74 @@ const char* AliShuttle::GetRunType()
 Bool_t AliShuttle::GetHLTStatus()
 {
        // Return HLT status (ON=1 OFF=0)
-       // Converts the HLT status from the status string read in the run logbook (not just a bool)
+       // Converts the HLT status from the mode string read in the run logbook (not just a bool)
 
        if(!fLogbookEntry) {
                AliError("No logbook entry!");
                return 0;
        }
 
-       // TODO implement when HLTStatus is inserted in run logbook
-       //TString hltStatus = fLogbookEntry->GetRunParameter("HLTStatus");
-       //if(hltStatus == "OFF") {return kFALSE};
+       // TODO implement when HLTMode is inserted in run logbook
+       TString hltMode = fLogbookEntry->GetRunParameter("HLTMode");
+       TSubString firstChar = hltMode(0,1);
+       AliDebug(2,Form("First char = %s ",firstChar.Data())); 
+       if (firstChar == "A") {
+               return kFALSE;
+       }
+       else if ((firstChar == "B") || (firstChar == "C") || (firstChar == "D") || (firstChar == "E")) {
+               return kTRUE;
+       }
+       else {
+               Log("SHUTTLE","Unexpected HLT mode! Returning 0....");
+               return kFALSE;
+       }
+}
+
+//______________________________________________________________________________________________
+const char* AliShuttle::GetTriggerConfiguration()
+{
+       // Receives the trigger configuration from the DAQ logbook for the current run
+       
+       // check connection, if needed reconnect
+       if (!Connect(3)) 
+               return 0;
 
-       return kTRUE;
+       TString sqlQuery;
+       sqlQuery.Form("SELECT configFile FROM logbook_trigger_config WHERE run = %d", GetCurrentRun());
+       TSQLResult* result = fServer[3]->Query(sqlQuery);
+       if (!result)
+       {
+               Log("SHUTTLE", Form("ERROR: Can't execute query <%s>!", sqlQuery.Data()));
+               return 0;
+       }
+       
+       if (result->GetRowCount() == 0)
+       {
+               Log("SHUTTLE", "ERROR: Trigger configuration not found in logbook_trigger_config");
+               delete result;
+               return 0;
+       }
+       
+       TSQLRow* row = result->Next();
+       if (!row)
+       {
+               Log("SHUTTLE", "ERROR: Could not receive logbook_trigger_config data");
+               delete result;
+               return 0;
+       }
+
+       // static, so that pointer remains valid when it is returned to the calling class       
+       static TString triggerConfig(row->GetField(0));
+       
+       delete row;
+       row = 0;
+       
+       delete result;
+       result = 0;
+       
+       Log("SHUTTLE", Form("Found trigger configuration: %s", triggerConfig.Data()));
+       
+       return triggerConfig;
 }
 
 //______________________________________________________________________________________________
@@ -3568,3 +3286,75 @@ void AliShuttle::SetShuttleLogDir(const char* logDir)
 
        fgkShuttleLogDir = gSystem->ExpandPathName(logDir);
 }
+//______________________________________________________________________________________________
+Bool_t AliShuttle::TouchFile()
+{
+       //
+       // touching a file on the grid if run has been DONE
+       //
+       
+       if (!gGrid)
+       {
+               Log("SHUTTLE",Form("No TGrid connection estabilished!"));
+               Log("SHUTTLE",Form("Could not touch file for run %i",GetCurrentRun()));
+               return kFALSE;
+       }
+
+       TString dir;
+       dir.Form("%s%d/%s/SHUTTLE_DONE", fConfig->GetAlienPath(), GetCurrentYear(), GetLHCPeriod());
+       // checking whether directory for touch command exists
+       TString commandLs;
+       commandLs.Form("ls %s",dir.Data());
+       TGridResult *resultLs = dynamic_cast<TGridResult*>(gGrid->Command(commandLs));
+       if (!resultLs){
+               Log("SHUTTLE",Form("No result for %s command, returning without touching",commandLs.Data()));
+               return kFALSE;
+       }
+       TMap *mapLs = dynamic_cast<TMap*>(resultLs->At(0));
+       if (!mapLs){
+               Log("SHUTTLE",Form("No map for %s command, returning without touching",commandLs.Data()));
+               return kFALSE;
+       }
+       TObjString *valueLsPath = dynamic_cast<TObjString*>(mapLs->GetValue("path"));
+       if (!valueLsPath || (TString)(valueLsPath->GetString()).CompareTo(dir)!=1){ 
+               Log("SHUTTLE",Form("No directory %s found, creating it",dir.Data()));
+
+               // creating the directory
+
+               Bool_t boolMkdir = gGrid->Mkdir(dir.Data());
+               if (!boolMkdir) {
+                       Log("SHUTTLE",Form("Impossible to create dir %s in alien catalogue for run %i!",dir.Data(),GetCurrentRun()));
+                       return kFALSE;
+               }
+               Log("SHUTTLE",Form("Directory %s successfully created in alien catalogue for run %i",dir.Data(),GetCurrentRun()));
+       }
+       else {
+               Log("SHUTTLE",Form("Directory %s correctly found for run %i",dir.Data(),GetCurrentRun()));
+       }
+
+       TString command;
+       command.Form("touch %s/%i", dir.Data(), GetCurrentRun());
+       Log("SHUTTLE", Form("Creating entry in file catalog: %s", command.Data()));
+       TGridResult *resultTouch = dynamic_cast<TGridResult*>(gGrid->Command(command));
+       if (!resultTouch){
+               Log("SHUTTLE",Form("No result for touching command, returning without touching for run %i",GetCurrentRun()));
+               return kFALSE;
+       }
+       TMap *mapTouch = dynamic_cast<TMap*>(resultTouch->At(0));
+       if (!mapTouch){
+               Log("SHUTTLE",Form("No map for touching command, returning without touching for run %i",GetCurrentRun()));
+               return kFALSE;
+       }
+       TObjString *valueTouch = dynamic_cast<TObjString*>(mapTouch->GetValue("__result__"));
+       if (!valueTouch){
+               Log("SHUTTLE",Form("No value for \"__result__\" key set in the map for touching command, returning without touching for run %i",GetCurrentRun()));
+               return kFALSE;
+       }
+       if (valueTouch->GetString()!="1"){
+               Log("SHUTTLE",Form("Failing the touching command, returning without touching for run %i",GetCurrentRun()));
+               return kFALSE;
+       }
+       return kTRUE;
+}
+
+