]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
Adding macro to perform sanity checks on the global HLT trigger decision objects.
authoraszostak <aszostak@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 13 Sep 2010 13:33:25 +0000 (13:33 +0000)
committeraszostak <aszostak@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 13 Sep 2010 13:33:25 +0000 (13:33 +0000)
HLT/trigger/macros/SanityCheckGlobalTriggerDecisions.C [new file with mode: 0644]

diff --git a/HLT/trigger/macros/SanityCheckGlobalTriggerDecisions.C b/HLT/trigger/macros/SanityCheckGlobalTriggerDecisions.C
new file mode 100644 (file)
index 0000000..71075f7
--- /dev/null
@@ -0,0 +1,306 @@
+/**************************************************************************
+ * This file is property of and copyright by the ALICE HLT Project        *
+ * All rights reserved.                                                   *
+ *                                                                        *
+ * Primary Authors:                                                       *
+ *   Artur Szostak <artursz@iafrica.com>                                  *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+// $Id: $
+
+/**
+ * \ingroup macros
+ * \file SanityCheckGlobalTriggerDecisions.C
+ * \brief Macro for performing sanity checks on the HLT global trigger decisions.
+ *
+ * Basic sanity checks are performed by the SanityCheckGlobalTriggerDecisions macro
+ * on the HLT global trigger counters. These checks include:
+ *  - The counters must be increasing with increasing event ID.
+ *  - The total events counter must be the largest and the number of events read
+ *    by the raw reader must be less than or equal to the total events counter.
+ *
+ * The simplest way to run this macro with defaults is to run the following
+ * command from a terminal shell:
+ * \code
+ *   > aliroot -b -q $ALICE_ROOT/HLT/trigger/macros/SanityCheckGlobalTriggerDecisions.C
+ * \endcode
+ * This will expect data in DDL directory format in the current directory.
+ *
+ * \author Artur Szostak <artursz@iafrica.com>
+ */
+
+#if !defined(__CINT__) || defined(__MAKECINT__)
+#include "AliHLTGlobalTriggerDecision.h"
+#include "TSystem.h"
+#include "TString.h"
+#include "TFile.h"
+#include "TCollection.h"
+#include "TMap.h"
+#include "TObjArray.h"
+#include "TObjString.h"
+#include "TArrayI.h"
+#include "TArrayL64.h"
+#include "Riostream.h"
+#endif
+
+#include "DumpGlobalTrigger.C"
+
+
+/**
+ * Checks to see if a file contains global HLT trigger decision objects.
+ * \param filename  The name of the ROOT file to check.
+ * \returns true if the file contains AliHLTGlobalTriggerDecision objects and
+ *    false otherwise.
+ */
+bool FileContainsDecisions(const char* filename)
+{
+       TFile* file = new TFile(filename, "READ");
+       if (file == NULL)
+       {
+               cerr << "ERROR: Could not create a TFile object to open '"
+                       << filename << "'." << endl;
+               return false;
+       }
+       TIter next(file->GetListOfKeys());
+       TObject* key = NULL;
+       bool result = false;
+       while ((key = next()) != NULL)
+       {
+               TObject* obj = file->Get(key->GetName());
+               if (obj == NULL) continue;
+               if (TString(obj->ClassName()) == "AliHLTGlobalTriggerDecision")
+               {
+                       result = true;
+                       break;
+               }
+       }
+       delete file;
+       return result;
+}
+
+/**
+ * Routine to print the counters in a HLT global trigger decision object.
+ * \param key  The key object storing the key name of the object in the ROOT file.
+ * \param decision  The HLT global decision object to print.
+ */
+void PrintCounters(const TObject* key, const AliHLTGlobalTriggerDecision* decision)
+{
+       if (key == NULL) return;
+       if (decision == NULL) return;
+       cout << key->GetName() << " (Global component ID = " << decision->GetUniqueID() << "):";
+       const TArrayL64& counters = decision->Counters();
+       for (Int_t i = 0; i < counters.GetSize(); ++i)
+       {
+               cout << " " << counters[i];
+       }
+       if (counters.GetSize() <= 0) cout << "(none)";
+       cout << endl;
+}
+
+/**
+ * Performs sanity checks on the global HLT trigger counters found in the raw data.
+ *
+ * \param dataSource  This is the path to the raw data or the ROOT/DATE file
+ *     contining the raw data. (default is the current directory).
+ *     One can also specify the output ROOT file as generated by the
+ *     DumpGlobalTrigger.C macro directly.
+ * \param firstEvent  The event number of the first event to process. (default = 0)
+ *     This parameter is ignored if dataSource points to a file containing
+ *     AliHLTGlobalTriggerDecision objects.
+ * \param lastEvent  The event number of the last event to process. If this is
+ *     less than firstEvent then it is set to maximum events available
+ *     automatically. (default = -1)
+ *     This parameter is ignored if dataSource points to a file containing
+ *     AliHLTGlobalTriggerDecision objects.
+ * \param debug  Specifies if full debug messages should be printed when running
+ *     the DumpGlobalTrigger.C macro.
+ * \returns true if the data passed all validity checks and false if there was a problem.
+ */
+bool SanityCheckGlobalTriggerDecisions(
+               const char* dataSource = "./",
+               Int_t firstEvent = 0,
+               Int_t lastEvent = -1,
+               bool debug = false
+       )
+{
+       const char* outputFile = "globalTriggerDecisions.root";
+       if ((! TString(dataSource).EndsWith(".root")) ||
+           (TString(dataSource).EndsWith(".root") && ! FileContainsDecisions(dataSource))
+          )
+       {
+               if (gSystem->Exec(Form("test -f %s", outputFile)) == 0)
+               {
+                       cerr << "ERROR: File " << outputFile
+                               << " already exists. It must be moved or removed."
+                               << " This script will not overwrite it."
+                               << endl;
+                       return false;
+               }
+               DumpGlobalTrigger(dataSource, firstEvent, lastEvent, outputFile, debug);
+       }
+       else
+       {
+               outputFile = dataSource;
+       }
+
+       TMap map;
+       map.SetOwnerKeyValue(kTRUE, kTRUE);
+       TObjArray eventIds;
+       eventIds.SetOwner(kFALSE);
+       TArrayI objIds;
+
+       TFile* file = new TFile(outputFile, "READ");
+       if (file == NULL)
+       {
+               cerr << "ERROR: Could not create a TFile object to open '"
+                       << outputFile << "'." << endl;
+               return false;
+       }
+       TIter next(file->GetListOfKeys());
+       TObject* key = NULL;
+       while ((key = next()) != NULL)
+       {
+               TObject* obj = file->Get(key->GetName());
+               if (obj == NULL)
+               {
+                       cerr << "Warning: Could not fetch object '" << key->GetName() << "'." << endl;
+                       continue;
+               }
+               TObjString* id = new TObjString(key->GetName());
+               map.Add(id, obj->Clone());
+               eventIds.Add(id);
+               bool addID = true;
+               for (Int_t i = 0; i < objIds.GetSize(); ++i)
+               {
+                       if (objIds[i] == Int_t(obj->GetUniqueID()))
+                       {
+                               addID = false;
+                               break;
+                       }
+               }
+               if (addID)
+               {
+                       objIds.Set(objIds.GetSize()+1);
+                       objIds[objIds.GetSize()-1] = Int_t(obj->GetUniqueID());
+               }
+       }
+       delete file;
+
+       eventIds.Sort();  // Must sort the events in order of increasing event ID.
+       ULong64_t totalCounters = 0;
+       bool result = true;
+
+       for (Int_t n = 0; n < objIds.GetSize(); ++n)
+       {
+               UInt_t objId = UInt_t(objIds[n]);
+               TObject* oldKey = NULL;
+               AliHLTGlobalTriggerDecision* oldDecision = NULL;
+               TIter nextEvent(&eventIds);
+               AliHLTGlobalTriggerDecision* decision = NULL;
+               while ((key = nextEvent()) != NULL)
+               {
+                       TPair* pair = (TPair*) map.FindObject(key->GetName());
+                       if (pair == NULL)
+                       {
+                               cerr << "Warning: Could not find trigger decision '" << key->GetName() << "' in the map." << endl;
+                               continue;
+                       }
+                       decision = (AliHLTGlobalTriggerDecision*) pair->Value();
+                       if (decision == NULL)
+                       {
+                               cerr << "Warning: The trigger decision object for '" << key->GetName() << "' was NULL in the map." << endl;
+                               continue;
+                       }
+                       if (decision->GetUniqueID() != objId) continue;  // Filter on the current ID we are handling.
+
+                       bool printCounters = false;
+                       const TArrayL64& counters = decision->Counters();
+
+                       // Check that all current counters are larger than the old ones.
+                       if (oldDecision != NULL)
+                       {
+                               const TArrayL64& oldCounters = oldDecision->Counters();
+                               if (counters.GetSize() == oldCounters.GetSize())
+                               {
+                                       for (Int_t i = 0; i < counters.GetSize(); ++i)
+                                       {
+                                               if (oldCounters[i] > counters[i])
+                                               {
+                                                       cerr << "ERROR: Previous counter value " << oldCounters[i]
+                                                               << " from object " << oldKey->GetName()
+                                                               << " is larger than the new one " << counters[i]
+                                                               << " from " << key->GetName()
+                                                               << "." << endl;
+                                                       printCounters = true;
+                                                       result = false;
+                                               }
+                                       }
+                               }
+                               else
+                               {
+                                       cerr << "ERROR: Number of previous counters from object " << oldKey->GetName()
+                                               << " do not match the current counters from " << key->GetName()
+                                               << "." << endl;
+                                       printCounters = true;
+                                       result = false;
+                               }
+                       }
+
+                       // Check that all counters are larger than the total counter at the end.
+                       if (counters.GetSize() > 0)
+                       {
+                               for (Int_t i = 0; i < counters.GetSize()-1; ++i)
+                               {
+                                       if (counters[i] > counters[counters.GetSize()-1])
+                                       {
+                                               cerr << "ERROR: Counter " << i
+                                                       << " with value " << counters[i]
+                                                       << " from object " << oldKey->GetName()
+                                                       << " is larger than the last counter " << counters[counters.GetSize()-1]
+                                                       << "." << endl;
+                                               printCounters = true;
+                                               result = false;
+                                       }
+                               }
+                       }
+
+                       if (debug && ! printCounters) PrintCounters(key, decision);
+                       if (printCounters)
+                       {                               
+                               cout << "Previous counters: "; PrintCounters(oldKey, oldDecision);
+                               cout << " Current counters: "; PrintCounters(key, decision);
+                               cout << endl;
+                       }
+                       oldDecision = decision;
+                       oldKey = key;
+               }
+               if (oldDecision != NULL)
+               {
+                       if (oldDecision->Counters().GetSize() > 0)
+                       {
+                               // oldDecision will contain the last counter, which we use to get
+                               // the total number of events seen by the global trigger component.
+                               const TArrayL64& oldCounters = oldDecision->Counters();
+                               totalCounters += oldCounters[oldCounters.GetSize()-1];
+                       }
+               }
+       }
+       
+       if (ULong64_t(eventIds.GetEntries()) > totalCounters)
+       {
+               cerr << "ERROR: The total number of events counters added up to " << totalCounters
+                       << ", but the total number of events seen on file is " << eventIds.GetEntries()
+                       << ". This is inconsistent." << endl;
+               result = false;
+       }
+       return result;
+}
+