]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - SHUTTLE/AliShuttle.cxx
Method for touching a file on the grid after processing a run in case of shuttle...
[u/mrichter/AliRoot.git] / SHUTTLE / AliShuttle.cxx
index b822f6895e0463b2f736e67963a09f47ac573f22..a40805b6565753c55a7d57f2325ae6ec7536cd42 100644 (file)
  * provided "as is" without express or implied warranty.                  *
  **************************************************************************/
 
-/*
-$Log$
-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. 
@@ -365,6 +57,7 @@ some docs added
 #include <TFile.h>
 #include <TGrid.h>
 #include <TGridResult.h>
+#include <TMap.h>
 
 #include <TMonaLisaWriter.h>
 
@@ -373,6 +66,8 @@ some docs added
 #include <sys/types.h>
 #include <sys/wait.h>
 
+#include <signal.h>
+
 ClassImp(AliShuttle)
 
 //______________________________________________________________________________________________
@@ -383,6 +78,8 @@ fTimeout(timeout), fRetries(retries),
 fPreprocessorMap(),
 fLogbookEntry(0),
 fCurrentDetector(),
+fFirstProcessing(0),
+fFXSError(-1),
 fStatusEntry(0),
 fMonitoringMutex(0),
 fLastActionTime(0),
@@ -558,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");
@@ -566,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");
@@ -581,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;
@@ -605,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();
@@ -614,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();
@@ -624,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!
@@ -648,6 +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()));
+                       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;
                }
 
@@ -700,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;
 }
 
 //______________________________________________________________________________________________
@@ -846,7 +596,7 @@ Bool_t AliShuttle::StoreRunMetadataFile(const char* localFile, const char* gridF
        TString localBaseFolder = sto->GetBaseFolder();
        
        // Build Run level folder
-       // folder = /alice/data/year/lhcPeriod/runNb/Raw
+       // folder = /alice/data/year/lhcPeriod/runNb/raw
        
                
        TString lhcPeriod = GetLHCPeriod();     
@@ -856,7 +606,17 @@ Bool_t AliShuttle::StoreRunMetadataFile(const char* localFile, const char* gridF
                return 0;
        }
        
-       TString target = Form("%s/GRP/RunMetadata/alice/data/%d/%s/%09d/Raw/%s", 
+       // TODO partitions with one detector only write data into LHCperiod_DET
+       TString partition = GetRunParameter("detector");
+       
+       if (partition.Length() > 0 && partition != "ALICE")
+       {
+               lhcPeriod.Append(Form("_%s", partition.Data()));
+               Log(fCurrentDetector, Form("Run data tags merged file will be written in %s", 
+                               lhcPeriod.Data()));
+       }
+               
+       TString target = Form("%s/GRP/RunMetadata/alice/data/%d/%s/%09d/raw/%s", 
                                localBaseFolder.Data(), GetCurrentYear(), 
                                lhcPeriod.Data(), GetCurrentRun(), gridFileName);
                                        
@@ -879,7 +639,7 @@ Bool_t AliShuttle::CopyFileLocally(const char* localFile, const TString& target)
        void* dir = gSystem->OpenDirectory(targetDir.Data());
        if (dir == NULL) {
                if (gSystem->mkdir(targetDir.Data(), kTRUE)) {
-                       Log("SHUTTLE", Form("StoreFileLocally - Can't open directory <%s>", targetDir.Data()));
+                       Log("SHUTTLE", Form("CopyFileLocally - Can't open directory <%s>", targetDir.Data()));
                        return kFALSE;
                }
 
@@ -892,17 +652,17 @@ Bool_t AliShuttle::CopyFileLocally(const char* localFile, const TString& target)
        result = gSystem->GetPathInfo(localFile, 0, (Long64_t*) 0, 0, 0);
        if (result)
        {
-               Log("SHUTTLE", Form("StoreFileLocally - %s does not exist", localFile));
+               Log("SHUTTLE", Form("CopyFileLocally - %s does not exist", localFile));
                return kFALSE;
        }
 
        result = gSystem->GetPathInfo(target, 0, (Long64_t*) 0, 0, 0);
        if (!result)
        {
-               Log("SHUTTLE", Form("StoreFileLocally - target file %s already exist, removing...", target.Data()));
+               Log("SHUTTLE", Form("CopyFileLocally - target file %s already exist, removing...", target.Data()));
                if (gSystem->Unlink(target.Data()))
                {
-                       Log("SHUTTLE", Form("StoreFileLocally - Could not remove existing target file %s!", target.Data()));
+                       Log("SHUTTLE", Form("CopyFileLocally - Could not remove existing target file %s!", target.Data()));
                        return kFALSE;
                }
        }       
@@ -911,12 +671,12 @@ Bool_t AliShuttle::CopyFileLocally(const char* localFile, const TString& target)
 
        if (result == 0)
        {
-               Log("SHUTTLE", Form("StoreFileLocally - File %s stored locally to %s", localFile, target.Data()));
+               Log("SHUTTLE", Form("CopyFileLocally - File %s stored locally to %s", localFile, target.Data()));
                return kTRUE;
        }
        else
        {
-               Log("SHUTTLE", Form("StoreFileLocally - Could not store file %s to %s! Error code = %d", 
+               Log("SHUTTLE", Form("CopyFileLocally - Could not store file %s to %s! Error code = %d", 
                                localFile, target.Data(), result));
                return kFALSE;
        }       
@@ -968,7 +728,15 @@ Bool_t AliShuttle::CopyFilesToGrid(const char* type)
                        return 0;
                }
                
-               dir = Form("%s/GRP/RunMetadata/alice/data/%d/%s/%09d/Raw", 
+               // TODO partitions with one detector only write data into LHCperiod_DET
+               TString partition = GetRunParameter("detector");
+       
+               if (partition.Length() > 0 && partition != "ALICE")
+               {
+                       lhcPeriod.Append(Form("_%s", partition.Data()));
+               }
+               
+               dir = Form("%s/GRP/RunMetadata/alice/data/%d/%s/%09d/raw", 
                                localBaseFolder.Data(), GetCurrentYear(), 
                                lhcPeriod.Data(), GetCurrentRun());
                alienDir = dir(dir.Index("/alice/data/"), dir.Length());
@@ -1286,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));
@@ -1299,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)));
@@ -1327,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;
        }
 
@@ -1388,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. "
@@ -1399,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);
@@ -1427,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);
@@ -1500,20 +1280,28 @@ Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry)
                fgkMainRefStorage = Form("alien://folder=/alice/data/%d/%s/Reference?user=alidaq?cacheFold=/tmp/OCDBCache", 
                                        GetCurrentYear(), lhcPeriod.Data());
        
-       AliCDBStorage *mainCDBSto = AliCDBManager::Instance()->GetStorage(fgkMainCDB);
-       if(mainCDBSto) mainCDBSto->QueryCDB(GetCurrentRun());
-       AliCDBStorage *mainRefSto = AliCDBManager::Instance()->GetStorage(fgkMainRefStorage);
-       if(mainRefSto) mainRefSto->QueryCDB(GetCurrentRun());
-
        // Loop on detectors in the configuration
        TIter iter(fConfig->GetDetectors());
        TObjString* aDetector = 0;
 
+       Bool_t first = kTRUE;
+
        while ((aDetector = (TObjString*) iter.Next()))
        {
                fCurrentDetector = aDetector->String();
 
-               if (ContinueProcessing() == kFALSE) continue;
+               if (ContinueProcessing() == kFALSE) 
+                       continue;
+               
+               if (first)
+               {
+                 // only read QueryCDB when needed and only once
+                 AliCDBStorage *mainCDBSto = AliCDBManager::Instance()->GetStorage(fgkMainCDB);
+                 if(mainCDBSto) mainCDBSto->QueryCDB(GetCurrentRun());
+                 AliCDBStorage *mainRefSto = AliCDBManager::Instance()->GetStorage(fgkMainRefStorage);
+                 if(mainRefSto) mainRefSto->QueryCDB(GetCurrentRun());
+                 first = kFALSE;
+               }
 
                Log("SHUTTLE", Form("\t\t\t****** run %d - %s: START  ******",
                                                GetCurrentRun(), aDetector->GetName()));
@@ -1673,14 +1461,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
-                               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)
@@ -1688,22 +1482,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 ******",
@@ -1760,6 +1542,10 @@ Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry)
                                        fFirstUnprocessed[iDet] = kFALSE;
                                }
                        }
+                       TMonaLisaText  mlStatusPending("SHUTTLE_status", "Pending");
+                       mlList.Clear();
+                       mlList.Add(&mlStatusPending);
+                       fMonaLisa->SendParameters(&mlList, mlID);
                }
        }
 
@@ -1769,7 +1555,7 @@ Bool_t AliShuttle::Process(AliShuttleLogbookEntry* entry)
 }
 
 //______________________________________________________________________________________________
-Bool_t AliShuttle::ProcessCurrentDetector()
+Int_t AliShuttle::ProcessCurrentDetector()
 {
        //
         // Makes data retrieval just for a specific detector (fCurrentDetector).
@@ -1781,16 +1567,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();
@@ -1810,7 +1606,7 @@ Bool_t AliShuttle::ProcessCurrentDetector()
                UpdateShuttleStatus(AliShuttleStatus::kDCSStarted);
                UpdateShuttleStatus(AliShuttleStatus::kDCSError);
                delete dcsMap;
-               return kFALSE;
+               return 0;
        } else {
 
                UpdateShuttleStatus(AliShuttleStatus::kDCSStarted);
@@ -1845,11 +1641,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;
                                }
                        }
                        
@@ -1866,12 +1663,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;
                                }                               
                        }
                        
@@ -1908,7 +1706,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!
        {
@@ -1917,7 +1725,7 @@ Bool_t AliShuttle::ProcessCurrentDetector()
                UpdateShuttleStatus(AliShuttleStatus::kPPError);
                dcsMap->DeleteAll();
                delete dcsMap;
-               return kFALSE;
+               return 0;
        }
        
        // preprocessor ok!
@@ -1928,7 +1736,59 @@ Bool_t AliShuttle::ProcessCurrentDetector()
        dcsMap->DeleteAll();
        delete dcsMap;
 
-       return kTRUE;
+       return 1;
+}
+
+//______________________________________________________________________________________________
+void AliShuttle::CountOpenRuns()
+{
+       // Query DAQ's Shuttle logbook and sends the number of open runs to ML
+       
+       // check connection, in case connect
+       if (!Connect(3)) 
+               return;
+
+       TString sqlQuery;
+       sqlQuery = Form("select count(*) from %s where shuttle_done=0", fConfig->GetShuttlelbTable());
+       
+       TSQLResult* aResult = fServer[3]->Query(sqlQuery);
+       if (!aResult) {
+               AliError(Form("Can't execute query <%s>!", sqlQuery.Data()));
+               return;
+       }
+
+       AliDebug(2,Form("Query = %s", sqlQuery.Data()));
+       
+       if (aResult->GetRowCount() == 0) {
+               AliError(Form("No result for query %s received", sqlQuery.Data()));
+               return;
+       }
+
+       if (aResult->GetFieldCount() != 1) {
+               AliError(Form("Invalid field count for query %s received", sqlQuery.Data()));
+               return;
+       }
+
+       TSQLRow* aRow = aResult->Next();
+       if (!aRow) {
+               AliError(Form("Could not receive result of query %s", sqlQuery.Data()));
+               return;
+       }
+       
+       TString result(aRow->GetField(0), aRow->GetFieldLength(0));
+       Int_t count = result.Atoi();
+       
+       Log("SHUTTLE", Form("%d unprocessed runs", count));
+       
+       delete aRow;
+       delete aResult;
+
+       TMonaLisaValue mlStatus("SHUTTLE_openruns", count);
+
+       TList mlList;
+       mlList.Add(&mlStatus);
+
+       fMonaLisa->SendParameters(&mlList, "__PROCESSINGINFO__");
 }
 
 //______________________________________________________________________________________________
@@ -1942,7 +1802,7 @@ Bool_t AliShuttle::QueryShuttleLogbook(const char* whereClause,
        entries.SetOwner(1);
 
        // check connection, in case connect
-       if(!Connect(3)) return kFALSE;
+       if (!Connect(3)) return kFALSE;
 
        TString sqlQuery;
        sqlQuery = Form("select * from %s %s order by run", fConfig->GetShuttlelbTable(), whereClause);
@@ -2036,119 +1896,36 @@ 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;
-       }
        
-       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));              
-               
-               //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 && 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_ignored"))
-               {
-                       AliError(Form("Could not update logbook for run %d !", run));
-               }
-               fLogbookEntry = 0;
-                               
-               delete entry;
-               delete aRow;
-               delete aResult;
-               return 0;
-       }
-                       
        TString totEventsStr = entry->GetRunParameter("totalEvents");  
        Int_t totEvents = totEventsStr.Atoi();
-       if (totEvents < 1) 
-       {
-               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;
-       }
+       
+       if (startTime != 0 && endTime != 0 && endTime > startTime && totEvents > 0)
+               return entry;   
 
-       delete aRow;
-       delete aResult;
+       Log("SHUTTLE",
+               Form("QueryRunParameters - Invalid parameters for Run %d: "
+                       "startTime = %d, endTime = %d. Skipping (Shuttle won't be marked as DONE)!",
+                       run, startTime, endTime));              
 
-       return entry;
+       if (totEvents < 1) 
+               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_done"))
+       //{
+       //      AliError(Form("Could not update logbook for run %d !", run));
+       //}
+       //fLogbookEntry = 0;
+                       
+       delete entry;
+       return 0;
 }
 
 //______________________________________________________________________________________________
@@ -2212,6 +1989,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;
        }
 
@@ -2234,7 +2012,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());
@@ -2245,15 +2022,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;
@@ -2261,8 +2039,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;
        }
@@ -2271,6 +2050,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;
        }
@@ -2278,8 +2058,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;
        }
@@ -2307,25 +2088,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;
@@ -2337,7 +2138,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()));
@@ -2378,26 +2183,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);
 
@@ -2416,7 +2206,12 @@ TList* AliShuttle::GetFileSources(Int_t system, const char* detector, const char
        // if id is NULL all sources are returned (distinct)
        //
 
-       Log(detector, Form("GetFileSources - Retrieving sources with id %s from %s", id, GetSystemName(system)));
+       if (id)
+       {
+               Log(detector, Form("GetFileSources - Querying %s FXS for files with id %s produced by %s", GetSystemName(system), id, detector));
+       } else {
+               Log(detector, Form("GetFileSources - Querying %s FXS for files produced by %s", GetSystemName(system), detector));
+       }
        
        // check if test mode should simulate a FXS error
        if (fTestMode & kErrorFXSSources)
@@ -2438,6 +2233,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;
        }
 
@@ -2465,6 +2261,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;
        }
 
@@ -2788,15 +2585,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);
@@ -2992,8 +2795,8 @@ Bool_t AliShuttle::Collect(Int_t run)
        if (!fMonaLisa)
                fMonaLisa = new TMonaLisaWriter(fConfig->GetMonitorHost(), fConfig->GetMonitorTable());
                
-
        SendAlive();
+       CountOpenRuns();
 
        TString whereClause("where shuttle_done=0");
        if (run != -1)
@@ -3052,10 +2855,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;
 }
 
@@ -3174,7 +2979,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
@@ -3182,6 +2987,14 @@ Bool_t AliShuttle::SendMail()
        
        if (fTestMode != kNone)
                return kTRUE;
+               
+       if (!fConfig->SendMail()) 
+               return kTRUE;
+
+       if (target == kDCSEMail || target == kFXSEMail) {
+               if (!fFirstProcessing)
+               return kTRUE;
+       }
 
        void* dir = gSystem->OpenDirectory(GetShuttleLogDir());
        if (dir == NULL)
@@ -3196,125 +3009,46 @@ 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;
-       }
-
+       // det experts in to
        TString to="";
-       TIter iterExperts(fConfig->GetResponsibles(fCurrentDetector));
+       TIter *iterExperts;
+       if (target == kDCSEMail) {
+               iterExperts = new TIter(fConfig->GetAdmins(AliShuttleConfig::kAmanda));
+       }
+       else if (target == kFXSEMail) {
+               iterExperts = new TIter(fConfig->GetAdmins(system));
+       }
+       else {
+               iterExperts = new TIter(fConfig->GetResponsibles(fCurrentDetector));
+       }
        TObjString *anExpert=0;
-       while ((anExpert = (TObjString*) iterExperts.Next()))
+       while ((anExpert = (TObjString*) iterExperts->Next()))
        {
                to += Form("%s,", anExpert->GetName());
        }
-       to.Remove(to.Length()-1);
+       delete iterExperts;
+       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!");
+               Log("SHUTTLE", Form("List of %d responsibles not set!", (Int_t) target));
                return kFALSE;
        }
 
-       TString cc="alberto.colla@cern.ch";
-
-       TString subject = Form("%s Shuttle preprocessor FAILED in run %d !",
-                               fCurrentDetector.Data(), GetCurrentRun());
-       AliDebug(2, Form("subject: %s", subject.Data()));
-
-       TString body = Form("Dear %s expert(s), \n\n", fCurrentDetector.Data());
-       body += Form("SHUTTLE just detected that your preprocessor "
-                       "failed processing run %d!!\n\n", GetCurrentRun());
-       body += Form("Please check %s status on the SHUTTLE monitoring page: \n\n", 
-                               fCurrentDetector.Data());
-       if (fConfig->GetRunMode() == AliShuttleConfig::kTest)
+       // SHUTTLE responsibles in cc
+       TString cc="";
+       TIter iterAdmins(fConfig->GetAdmins(AliShuttleConfig::kGlobal));
+       TObjString *anAdmin=0;
+       while ((anAdmin = (TObjString*) iterAdmins.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");
-       }
-       
-       
-       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);
-
-       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());
-       }
-
-       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)
-       {
-               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);
@@ -3324,37 +3058,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 cc="alberto.colla@cern.ch";
+       TString subject;
+       TString body;
 
-       TString subject = Form("Retrieval of data points for %s FAILED in run %d !",
+       if (target == kDCSEMail){
+               subject = Form("Retrieval of data points for %s FAILED in run %d !",
                                fCurrentDetector.Data(), GetCurrentRun());
-       AliDebug(2, Form("subject: %s", subject.Data()));
+               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("FXS communication for %s FAILED in run %d !",
+                               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 Shuttle preprocessor FAILED in run %d (run type = %s)!",
+                                      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";
@@ -3372,8 +3126,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()))
        {
@@ -3423,20 +3177,28 @@ 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};
-
-       return kTRUE;
+       // 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;
+       }
 }
-
 //______________________________________________________________________________________________
 void AliShuttle::SetShuttleTempDir(const char* tmpDir)
 {
@@ -3456,3 +3218,49 @@ 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 command;
+       command.Form("touch /alice/data/%d/%s/SHUTTLE_DONE/shuttle_done_%i", GetCurrentYear(), GetLHCPeriod(),GetCurrentRun());
+       TGridResult *resultTouch = dynamic_cast<TGridResult*>(gGrid->Command(command));
+       if (resultTouch){
+               TMap *mapTouch = dynamic_cast<TMap*>(resultTouch->At(0));
+               if (mapTouch){
+                       TObjString *valueTouch = dynamic_cast<TObjString*>(mapTouch->GetValue("__result__"));
+                       if (valueTouch){
+                               if (valueTouch->GetString()=="1"){
+                               return kTRUE;
+                               }       
+                               else {
+                                       Log("SHUTTLE",Form("No value for __result__ key set in the map for touching command"));
+                               }
+                       }
+                       else {
+                               Log("SHUTTLE",Form("No value set in the map for touching command"));
+                       }
+               }
+               else {
+                       Log("SHUTTLE",Form("No map for touching command"));
+               }
+       }
+
+       else {
+               Log("SHUTTLE",Form("No result for touching command"));
+       }
+       Log("SHUTTLE",Form("Could not touch file for run %i",GetCurrentRun()));
+       return kFALSE;
+}
+
+