First version of the occupancy DA, which should have been committed with a previous...
authorlaphecet <laphecet@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 29 Jun 2009 09:06:16 +0000 (09:06 +0000)
committerlaphecet <laphecet@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 29 Jun 2009 09:06:16 +0000 (09:06 +0000)
MUON/MUONTRKOCCda.cxx [new file with mode: 0644]

diff --git a/MUON/MUONTRKOCCda.cxx b/MUON/MUONTRKOCCda.cxx
new file mode 100644 (file)
index 0000000..46f7354
--- /dev/null
@@ -0,0 +1,287 @@
+/*
+ MCH DA for online occupancy
+ Contact: Laurent Aphecetche <laurent.aphecetche@subatech.in2p3.fr>, Jean-Luc Charvet <jean-luc.charvet@cea.fr>, Alberto Baldisseri <alberto.baldisseri@cea.fr>
+ Link: 
+ Run Type: PHYSICS STANDALONE
+ DA Type: MON
+ Number of events needed: all (or at least as much as possible...)
+ Input Files:
+ Output Files: mch.occupancy, to be exported to the DAQ FXS
+ Trigger types used: PHYSICS_EVENT
+*/
+
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * 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.                  *
+ **************************************************************************/
+
+///
+/// MUON TRACKER DA to compute the hit count at manu level.
+///
+/// In the end, this DA produces an ASCII file containing
+/// the hit count of all the manus (that were seen in the data flow)
+/// of the MUON Tracker (and the number of seen events, so we can
+/// later on compute the occupancy)
+///
+/// $Id$
+
+#include "AliMUON2DMap.h"
+#include "AliMUONCalibParamNI.h"
+#include "AliMUONRawStreamTrackerHP.h"
+#include "AliMpConstants.h"
+#include "AliRawEventHeaderBase.h"
+#include "AliRawReader.h"
+#include "Riostream.h"
+#include "TPluginManager.h"
+#include "TROOT.h"
+#include "TString.h"
+#include "TTimeStamp.h"
+#include "TStopwatch.h"
+#include "daqDA.h"
+#include "event.h"
+
+#ifdef ALI_AMORE
+#include <AmoreDA.h>
+#endif
+
+const char* OUTPUT_FILE = "mch.occupancy";
+const char* DAVERSION = "MUONTRKOCCda v1.0";
+
+//______________________________________________________________________________
+void Add(AliMUONVStore& destStore, const AliMUONVStore& srcStore)
+{
+  /// Add all elements from srcStore to destStore
+  /// Each element of srcStore is supposed to be an AliMUONCalibParamNI,
+  /// with ID0=busPatchId and ID1=manuId
+  
+  TIter next(srcStore.CreateIterator());
+  AliMUONVCalibParam* source;
+  
+  while ( ( source = static_cast<AliMUONVCalibParam*>(next()) ) )
+  {
+    AliMUONCalibParamNI* dest = static_cast<AliMUONCalibParamNI*>(destStore.FindObject(source->ID0(),source->ID1()));
+    if (!dest)
+    {
+      dest = static_cast<AliMUONCalibParamNI*>(source->Clone());
+      destStore.Add(dest);
+    }
+    else
+    {
+      for ( Int_t i = 0; i < source->Size(); ++i ) 
+      {
+        for ( Int_t j = 0; j  < source->Dimension(); ++j ) 
+        {
+          dest->SetValueAsInt(i,j,dest->ValueAsInt(i,j)+source->ValueAsInt(i,j));
+        }
+      }
+    }
+  }
+}
+
+//______________________________________________________________________________
+void GenerateOutputFile(const AliMUONVStore& store, ostream& out, 
+                        Int_t runNumber, Int_t nevents)
+{
+  /// Write the channel hit count (grouped by manu) in the output file.
+  
+  TIter next(store.CreateIterator());
+  AliMUONVCalibParam* manu;
+  
+  out << "//===========================================================================" << endl;
+  out << "//  Hit counter file calculated by " << __FILE__ << endl;
+  out << "//===========================================================================" << endl;
+  out << "//" << endl;
+  out << "//       * Run Number          : " << runNumber << endl;
+  out << "//       * File Creation Date  : " << TTimeStamp().AsString("l") << endl;
+  out << "//---------------------------------------------------------------------------" << endl;
+  out << "//  BP   MANU  SUM_N  NEVENTS" << endl;
+  out << "//---------------------------------------------------------------------------" << endl;
+  
+  while ( ( manu = static_cast<AliMUONVCalibParam*>(next()) ) )
+  {
+    Int_t sum(0);
+//    Int_t nevents(0);
+    
+    for ( Int_t i = 0; i < manu->Size(); ++i ) 
+    {
+      sum += manu->ValueAsInt(i);
+      //      nevents = TMath::Max(nevents,manu->ValueAsInt(i,1));
+      // nevents = TMath::Max(nevents,manu->ValueAsInt(i,1));
+    }
+    
+    out << Form("%5d %5d %10d %10d",manu->ID0(),manu->ID1(),sum,nevents) << endl;
+  }
+}
+  
+//______________________________________________________________________________
+int main(int argc, char **argv) 
+{
+  /// Main method.
+  ///
+  /// We loop over all physics events.
+  /// For each event we store the channels that were hit for that event.
+  /// If the event is good, we then increment the list of channels hit for
+  /// the whole run.
+  /// We delete the store for a single event and move to next event.
+  ///
+  /// In the end we output an ASCII file with the necessary information 
+  /// to compute the occupancy later on, i.e. the number of times channels
+  /// were seen per manu, and the number of events.
+  ///
+  
+  TStopwatch timers;
+  timers.Start(kTRUE); 
+  
+  ios::sync_with_stdio();
+
+  cout << "Running " << DAVERSION << endl;
+  
+  if ( argc < 2 ) 
+  {
+    cout << "Wrong number of arguments" << endl;
+    cout << "Usage : " << argv[0] << " datasource1 [datasource2] ..." << endl;
+    return -1;
+  }
+  
+  // needed for streamer application
+  gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo",
+                                        "*",
+                                        "TStreamerInfo",
+                                        "RIO",
+                                        "TStreamerInfo()");
+  
+  Int_t numberOfEvents(0);
+  Int_t numberOfPhysicsEvent(0);
+  Int_t numberOfBadEvents(0);
+  Int_t numberOfUsedEvents(0);
+  
+  AliMUON2DMap oneEventData(kTRUE);
+  AliMUON2DMap accumulatedData(kTRUE);
+  
+  UInt_t runNumber(0);
+
+  for ( Int_t i = 1; i < argc; ++i ) 
+  {    
+    AliRawReader* rawReader = AliRawReader::Create(argv[i]);
+
+    while ( rawReader->NextEvent() ) 
+    {
+      /* check shutdown condition */
+      if (daqDA_checkShutdown()) break;
+    
+      ++numberOfEvents;
+     
+      if ( rawReader->GetType() == AliRawEventHeaderBase::kEndOfRun )
+      {
+        printf("EOR event detected\n");
+        break;
+      }
+    
+      if ( rawReader->GetType() != AliRawEventHeaderBase::kPhysicsEvent ) continue;
+    
+      ++numberOfPhysicsEvent;
+      
+      if ( rawReader->GetRunNumber() != runNumber )
+      {
+        if ( runNumber != 0 ) 
+        {
+          cout << "Uh oh. That's bad... Changing of run number ???" << endl;
+          return -9999;
+        }
+        runNumber = rawReader->GetRunNumber();
+      }
+      
+      AliMUONRawStreamTrackerHP stream(rawReader);
+      
+      stream.DisableWarnings();
+      stream.EnabbleErrorLogger();
+      
+      oneEventData.Clear();
+      
+      Int_t buspatchId;
+      UShort_t  manuId;
+      UChar_t manuChannel;
+      UShort_t adc;
+      
+      stream.First();
+      
+      while ( stream.Next(buspatchId,manuId,manuChannel,adc,kTRUE) )
+      {    
+        AliMUONVCalibParam* one = static_cast<AliMUONVCalibParam*>(oneEventData.FindObject(buspatchId,manuId));
+        
+        if (!one)
+        {
+          one = new AliMUONCalibParamNI(1,AliMpConstants::ManuNofChannels(),buspatchId,manuId);
+          oneEventData.Add(one);
+        }
+        
+        one->SetValueAsInt(manuChannel,0,one->ValueAsInt(manuChannel,0)+1);
+      }
+      
+      Bool_t badEvent = stream.HasPaddingError() || stream.HasGlitchError();
+      
+      if ( !badEvent )
+      {
+        ++numberOfUsedEvents;
+        Add(accumulatedData,oneEventData);
+      }
+      else
+      {
+        ++numberOfBadEvents;
+      }
+    }
+    
+    delete rawReader;
+  }
+  
+  
+  cout << Form("%12d events processed : %12d physics %d used ones %d bad ones",
+               numberOfEvents,numberOfPhysicsEvent,numberOfUsedEvents,numberOfBadEvents) << endl;
+    
+  ofstream fout(OUTPUT_FILE);
+  
+  GenerateOutputFile(accumulatedData,fout,runNumber,numberOfUsedEvents);
+  
+  fout.close();
+  
+#ifdef ALI_AMORE
+  
+  // Send occupancy store (as a big string) to the AMORE DB
+  
+  amore::da::AmoreDA amoreDA(amore::da::AmoreDA::kSender);
+  
+  ostringstream str;
+  
+  GenerateOutputFile(accumulatedData,str,runNumber,numberOfUsedEvents);
+  
+  str.close();
+  
+  TObjString occupancyAsString(str.str().c_str());
+  
+  Int_t status = amoreDA.Send("Occupancy",&occupanyAsString);
+  if ( status )
+  {
+    cerr << "ERROR : Failed to write occupancies in the AMORE database : " << status << endl;
+  } 
+
+#endif
+  
+  /* store the result file on FXS */  
+  if (daqDA_FES_storeFile(OUTPUT_FILE,"OCCUPANCY")) return -9;
+
+  timers.Stop();
+  printf("\nExecution time : R:%7.2fs C:%7.2fs\n", timers.RealTime(), timers.CpuTime());
+
+  return 0;
+}