]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
New classes for shuttle (Laurent)
authorivana <ivana@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 20 Oct 2006 15:52:22 +0000 (15:52 +0000)
committerivana <ivana@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 20 Oct 2006 15:52:22 +0000 (15:52 +0000)
19 files changed:
MUON/AliMUON2DStoreValidator.cxx [new file with mode: 0644]
MUON/AliMUON2DStoreValidator.h [new file with mode: 0644]
MUON/AliMUONCheckItem.cxx [new file with mode: 0644]
MUON/AliMUONCheckItem.h [new file with mode: 0644]
MUON/AliMUONCheckItemIterator.cxx [new file with mode: 0644]
MUON/AliMUONCheckItemIterator.h [new file with mode: 0644]
MUON/AliMUONObjectPair.cxx [new file with mode: 0644]
MUON/AliMUONObjectPair.h [new file with mode: 0644]
MUON/AliMUONPedestalEventGenerator.cxx [new file with mode: 0644]
MUON/AliMUONPedestalEventGenerator.h [new file with mode: 0644]
MUON/AliMUONPedestalSubprocessor.cxx [new file with mode: 0644]
MUON/AliMUONPedestalSubprocessor.h [new file with mode: 0644]
MUON/AliMUONPreprocessor.cxx [new file with mode: 0644]
MUON/AliMUONPreprocessor.h [new file with mode: 0644]
MUON/AliMUONVSubprocessor.cxx [new file with mode: 0644]
MUON/AliMUONVSubprocessor.h [new file with mode: 0644]
MUON/MUONshuttleLinkDef.h [new file with mode: 0644]
MUON/TestMUONPreprocessor.C [new file with mode: 0644]
MUON/libMUONshuttle.pkg [new file with mode: 0644]

diff --git a/MUON/AliMUON2DStoreValidator.cxx b/MUON/AliMUON2DStoreValidator.cxx
new file mode 100644 (file)
index 0000000..e082b61
--- /dev/null
@@ -0,0 +1,328 @@
+/**************************************************************************
+* 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.                  *
+**************************************************************************/
+
+// $Id$
+
+#include "AliMUON2DStoreValidator.h"
+
+#include "AliLog.h"
+#include "AliMUONCalibParam1I.h"
+#include "AliMpIntPair.h"
+#include "AliMpManuList.h"
+#include "AliMUONV2DStore.h"
+#include "TList.h"
+#include "TObjArray.h"
+#include "AliMUONCheckItem.h"
+#include "AliMUONCheckItemIterator.h"
+#include "AliMpDEManager.h"
+#include "TObjString.h"
+#include "AliMUONConstants.h"
+#include "Riostream.h"
+
+/// \class AliMUON2DStoreValidator
+///
+/// Determine which channels, manus, DEs, stations are missing
+/// from a 2DStore. This is mainly to be used during (shuttle) preprocessing
+/// to insure that what we'll put in the CDB is as complete as possible,
+/// and to detect possible problem.
+///
+/// We made an effort to present the result of the validation in the most
+/// concise way (i.e. if all channels of a DE are missing, we do not list 
+/// them, we just write "DE dead" ;-) )
+/// 
+/// The list of missing things is kept in a structure of objects defined as :
+/// 
+/// fMissing = TObjArray[0..N tracking chambers]
+/// fMissing[iChamber] = AliMUONCheckItem which contains n AliMUONCheckItem, 
+/// where n is the number of DE for that chamber
+/// fMissing[iChamber]->GetItem(de) = AliMUONCheckItem which contains m
+/// AliMUONCheckItem where m is the number of Manu for that DE
+/// fMissing[iChamber]->GetItem(de)->GetItem(manu) = AliMUONCheckItem which 
+/// contains k TObjString = Form("%d",manuChannel)
+///
+/// \author Laurent Aphecetche
+
+/// \cond CLASSIMP
+ClassImp(AliMUON2DStoreValidator)
+/// \endcond
+
+//_____________________________________________________________________________
+AliMUON2DStoreValidator::AliMUON2DStoreValidator() 
+: TObject(),
+  fManuList(0x0),
+  fChambers(0x0)
+{
+    /// ctor
+}
+
+//_____________________________________________________________________________
+AliMUON2DStoreValidator::~AliMUON2DStoreValidator()
+{
+  /// dtor
+  delete fManuList;
+  delete fChambers;
+}
+
+//_____________________________________________________________________________
+AliMUONCheckItem* 
+AliMUON2DStoreValidator::GetChamber(Int_t chamberID)
+{
+  /// Return (and create if not present) the given chamber
+  /// chamberID in 0..NCh()
+  
+  if ( chamberID < 0 || chamberID >= AliMUONConstants::NCh() )
+  {
+    AliFatal(Form("Invalid chamber number %d",chamberID));
+    return 0x0;
+  }
+  
+  if (!fChambers) 
+  {
+    fChambers = new TObjArray(AliMUONConstants::NCh());
+  }
+    
+  AliMUONCheckItem* chamber = 
+    static_cast<AliMUONCheckItem*>(fChambers->At(chamberID));
+  
+  if (!chamber)
+  {
+    chamber = new AliMUONCheckItem(chamberID,
+                                   AliMpDEManager::GetNofDEInChamber(chamberID),
+                                   "Chamber");
+    fChambers->AddAt(chamber,chamberID);
+  }
+  return chamber;
+}
+
+//_____________________________________________________________________________
+AliMUONCheckItem* 
+AliMUON2DStoreValidator::GetDE(Int_t detElemId)
+{
+  /// Return (and create if not present) a given detection element
+  
+  Int_t chamberID = AliMpDEManager::GetChamberId(detElemId);
+  AliMUONCheckItem* chamber = GetChamber(chamberID);  
+  AliMUONCheckItem* de = 
+    static_cast<AliMUONCheckItem*>(chamber->GetItem(detElemId));
+  if (!de)
+  {
+    AliDebug(3,Form("Did not find DE %4d into chamber %d, will create it",
+                    detElemId,chamberID));
+    de = new AliMUONCheckItem(detElemId,
+                              AliMpManuList::NumberOfManus(detElemId),
+                              "Detection Element");
+    Bool_t ok = chamber->AddItem(detElemId,de);
+    if (!ok)
+    {
+      AliError(Form("Could not add DE %4d into chamber %2d",detElemId,chamberID));
+    }
+  }
+  return de;
+}
+
+//_____________________________________________________________________________
+AliMUONCheckItem* 
+AliMUON2DStoreValidator::GetManu(Int_t detElemId, Int_t manuId)
+{
+  /// Return (and create) a given manu
+  
+  AliMUONCheckItem* de = GetDE(detElemId);
+  AliMUONCheckItem* manu = static_cast<AliMUONCheckItem*>(de->GetItem(manuId));
+  if (!manu)
+  {
+    manu = new AliMUONCheckItem(manuId,AliMpManuList::NumberOfChannels(detElemId,manuId),"Manu");
+    Bool_t ok = de->AddItem(manuId,manu);
+    if (!ok)
+    {
+      AliError(Form("Could not add manu %4d into DE %4d",manuId,detElemId));
+    }
+    
+  }
+  return manu;
+}
+
+//_____________________________________________________________________________
+void
+AliMUON2DStoreValidator::AddMissingChannel(Int_t detElemId, 
+                                           Int_t manuId, Int_t manuChannel)
+{
+  /// Add one missing channel to the list of missing things
+  
+  AliDebug(3,Form("DE %4d Manu %4d Channel %2d is missing",
+                  detElemId,manuId,manuChannel));
+
+  AliMUONCheckItem* manu = GetManu(detElemId,manuId);
+  Bool_t ok = manu->AddItem(manuChannel,new TObjString(Form("%2d",manuChannel)));
+  if (!ok)
+  {
+    AliError(Form("Could not add channel %2d to manuId %4d in DE %4d",
+                    manuChannel,manuId,detElemId));
+  }
+}
+
+//_____________________________________________________________________________
+void
+AliMUON2DStoreValidator::AddMissingManu(Int_t detElemId, Int_t manuId)
+{
+  /// Add one missing manu to the list of missing things
+  
+  AliDebug(3,Form("DE %4d Manu %4d is completely missing",
+                  detElemId,manuId));
+
+  Int_t n(AliMpManuList::NumberOfChannels(detElemId,manuId));
+
+  for ( Int_t i = 0; i < n; ++i )
+  {
+    AddMissingChannel(detElemId,manuId,i);
+  }
+}
+
+//_____________________________________________________________________________
+void
+AliMUON2DStoreValidator::ReportManu(AliMUONCheckItem& manu)
+{  
+  /// Report list of missing channels from this manu
+  
+  TObjString* channel(0x0);
+  AliMUONCheckItemIterator it(manu);
+  
+  it.First();
+  
+  while ( ( channel = static_cast<TObjString*>(it.Next()) ) )
+  {
+    cout << Form("\t\t\tChannel %s is missing",channel->GetString().Data()) << endl;
+  }
+  
+}
+
+//_____________________________________________________________________________
+void
+AliMUON2DStoreValidator::ReportDE(AliMUONCheckItem& de)
+{  
+  /// Report list of missing manus from this de
+  AliMUONCheckItem* manu(0x0);
+  AliMUONCheckItemIterator it(de);
+  
+  cout << Form("\tDE %4d",de.GetID()) << endl;
+  
+  it.First();
+  
+  while ( ( manu = static_cast<AliMUONCheckItem*>(it.Next()) ) )
+  {
+    if ( manu->IsDead() )
+    {
+      cout << Form("\t\tManu %4d is missing",manu->GetID()) << endl;
+    }
+    else
+    {
+      ReportManu(*manu);
+    }
+  }
+}
+
+//_____________________________________________________________________________
+void
+AliMUON2DStoreValidator::ReportChamber(AliMUONCheckItem& chamber)
+{  
+  /// Report list of missing de from this chamber
+  
+  AliMUONCheckItem* de(0x0);
+  AliMUONCheckItemIterator it(chamber);
+  
+  it.First();
+  
+  while ( ( de = static_cast<AliMUONCheckItem*>(it.Next()) ) )
+  {
+    if ( de->IsDead() )
+    {
+      cout << Form("\tDE %4d is missing",de->GetID()) << endl;
+    }
+    else
+    {
+      ReportDE(*de);
+    }
+  }
+}
+
+//_____________________________________________________________________________
+void
+AliMUON2DStoreValidator::Report(const TObjArray& chambers)
+{
+  /// Reports what is missing, trying to be as concise as possible.
+  
+  for ( Int_t iChamber = 0; iChamber <= chambers.GetLast(); ++iChamber )
+  {
+    AliMUONCheckItem* chamber = static_cast<AliMUONCheckItem*>(chambers.At(iChamber));
+    if ( chamber )
+    {
+      if ( chamber->IsDead() )
+      {
+        cout << Form("Chamber %2d is missing",iChamber) << endl;
+      }
+      else
+      {
+        ReportChamber(*chamber);
+      }
+    }
+  }
+}
+
+//_____________________________________________________________________________
+TObjArray* 
+AliMUON2DStoreValidator::Validate(const AliMUONV2DStore& store,
+                                  Float_t invalidFloatValue)
+{
+  /// Validate the store. 
+  /// The invalidFloatValue is used to decide if a store content value
+  /// is valid or not.
+  
+  delete fChambers;
+  fChambers = 0x0;
+  
+  if (!fManuList) fManuList = AliMpManuList::ManuList();
+
+  // Now checks if some full manus are missing
+  TIter next(fManuList);
+  AliMpIntPair* p;
+
+  while ( ( p = (AliMpIntPair*)next() ) )
+  {
+    Int_t detElemId = p->GetFirst();
+    Int_t manuId = p->GetSecond();
+    AliMUONVCalibParam* test = 
+      static_cast<AliMUONVCalibParam*>(store.Get(detElemId,manuId));
+    if (!test)
+    {
+      // completely missing manu
+      AddMissingManu(detElemId,manuId);
+    }
+    else
+    {
+      // manu is there, check all its channels
+      for ( Int_t manuChannel = 0 ; manuChannel < test->Size(); ++manuChannel )
+      {
+        if ( AliMpManuList::DoesChannelExist(detElemId,manuId,manuChannel) &&
+             ( test->ValueAsFloat(manuChannel,0) == invalidFloatValue ||
+               test->ValueAsFloat(manuChannel,1) == invalidFloatValue ) )             
+        {
+          AddMissingChannel(detElemId,manuId,manuChannel);
+        }
+      }
+    }
+  }
+  return fChambers;
+}
+
+
diff --git a/MUON/AliMUON2DStoreValidator.h b/MUON/AliMUON2DStoreValidator.h
new file mode 100644 (file)
index 0000000..f0b9e39
--- /dev/null
@@ -0,0 +1,60 @@
+#ifndef ALIMUON2DSTOREVALIDATOR_H
+#define ALIMUON2DSTOREVALIDATOR_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+* See cxx source for full Copyright notice                               */
+
+// $Id$
+
+/// \ingroup shuttle
+/// \class AliMUON2DStoreValidator
+/// \brief Determine which channels, manus, DEs, stations are missing
+/// from a 2DStore.
+/// 
+/// \author Laurent Aphecetche
+
+#ifndef ROOT_TObject
+#  include "TObject.h"
+#endif
+
+class AliMUONV2DStore;
+class TList;
+class TObjArray;
+class AliMUONCheckItem;
+
+class AliMUON2DStoreValidator : public TObject
+{
+public:
+  AliMUON2DStoreValidator();
+  virtual ~AliMUON2DStoreValidator();
+  
+  TObjArray* Validate(const AliMUONV2DStore& store, Float_t invalidFloatValue);
+  void Report() const { Report(*fChambers); }
+
+  static void Report(const TObjArray& chambers);
+
+private:
+    
+  AliMUON2DStoreValidator(const AliMUON2DStoreValidator&);
+  AliMUON2DStoreValidator& operator=(const AliMUON2DStoreValidator&);
+
+  void AddMissingChannel(Int_t detElemId, Int_t manuId, Int_t manuChannel);
+
+  void AddMissingManu(Int_t detElemId, Int_t manuId);
+
+  AliMUONCheckItem* GetChamber(Int_t chamberID);
+  AliMUONCheckItem* GetDE(Int_t detElemId);
+  AliMUONCheckItem* GetManu(Int_t detElemId, Int_t manuId);
+  
+  static void ReportChamber(AliMUONCheckItem& chamber);
+  static void ReportDE(AliMUONCheckItem& de);
+  static void ReportManu(AliMUONCheckItem& manu);
+  
+private:
+  TList* fManuList; //! List of (DE,manuID) pairs.
+  TObjArray* fChambers; //! Array of AliMUONCheckItem.
+  
+  ClassDef(AliMUON2DStoreValidator,1) // Validator of 2DStore
+};
+
+#endif
diff --git a/MUON/AliMUONCheckItem.cxx b/MUON/AliMUONCheckItem.cxx
new file mode 100644 (file)
index 0000000..730bf4a
--- /dev/null
@@ -0,0 +1,173 @@
+/**************************************************************************
+* 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.                  *
+**************************************************************************/
+
+// $Id$
+
+#include "AliMUONCheckItem.h"
+
+#include "AliLog.h"
+#include "AliMpExMap.h"
+#include "Riostream.h"
+#include "AliMUONCheckItemIterator.h"
+
+/// \class AliMUONCheckItem
+///
+/// A structure used to gather information at different levels (ch,manu,de,chamber)
+///
+/// Used by AliMUON2DStoreValidator to present results in a concise way
+///
+/// 
+/// \author Laurent Aphecetche
+
+/// \cond CLASSIMP
+ClassImp(AliMUONCheckItem)
+/// \endcond
+
+//_____________________________________________________________________________
+AliMUONCheckItem::AliMUONCheckItem(Int_t id, Int_t maxNumber, const char* name) : 
+TNamed(name,name),
+fID(id),
+fDead(-1),
+fMaximum(maxNumber),
+fMissing(new AliMpExMap(kTRUE))
+{
+  /// ctor. id is the number of that item, maxNumber is the maximum number
+  /// of sub-item it can contains, and name is a label, e.g. de, chamber, manu.
+  /// Note that name="manu" has a special influence on the IsDead() method.
+  
+  fMissing->SetSize(fMaximum);
+  AliDebug(1,Form("ID %d maxNumber %d name %s",id,maxNumber,name));
+}
+
+//_____________________________________________________________________________
+AliMUONCheckItem::~AliMUONCheckItem()
+{
+  /// dtor
+  delete fMissing;
+}
+
+//_____________________________________________________________________________
+Bool_t AliMUONCheckItem::AddItem(Int_t id, TObject* item)
+{
+  /// Add an item, if possible.
+  
+  if ( IsFull() ) 
+  {
+    AliError("I'm already full!");
+    return kFALSE;
+  }
+  
+  TObject* test = GetItem(id);
+  if (test) 
+  {
+    AliError(Form("id %d is already there !",id));
+    return kFALSE;
+  }
+  else
+  {
+    fMissing->Add(id,item);
+    fDead=-1;
+  }  
+  return kTRUE;
+}
+
+//_____________________________________________________________________________
+void
+AliMUONCheckItem::ComputeDead() const
+{
+  /// Decide whether this item is completely dead, which is determined by
+  /// the fact that all its sub-items are dead, or for name="manu", by
+  /// the fact that all channels are missing, i.e. IsFull()==kTRUE
+  
+  TString name(GetName());
+  name.ToLower();
+
+  if ( name.Contains("manu") )
+  {
+    if ( IsFull() ) 
+    {
+      fDead=1;
+    }
+    else
+    {
+      fDead=0;
+    }
+  }
+  else
+  {
+    AliMUONCheckItemIterator it(*this);
+    AliMUONCheckItem* item;
+    it.First();
+    Int_t ndead(0);
+    fDead=0;
+    while ( ( item = dynamic_cast<AliMUONCheckItem*>(it.Next()) ) )
+    {
+      if ( item->IsDead() ) ++ndead;
+    }
+    if ( ndead == fMaximum ) fDead = 1;
+  }
+}
+
+//_____________________________________________________________________________
+TObject* 
+AliMUONCheckItem::GetItem(Int_t id) const
+{
+  /// Return item of a given id
+  return fMissing->GetValue(id);
+}
+
+//_____________________________________________________________________________
+Bool_t 
+AliMUONCheckItem::IsDead() const
+{
+  /// Return (and compute it first if not done already) dead status
+  if ( fDead == -1 )
+  {
+    ComputeDead();
+  }
+  return (fDead==1);
+}
+
+//_____________________________________________________________________________
+Bool_t 
+AliMUONCheckItem::IsFull() const
+{
+  /// Whether we have as many sub-items as possible
+  return (fMissing->GetSize() == fMaximum);
+}
+  
+//_____________________________________________________________________________
+void
+AliMUONCheckItem::Print(Option_t* opt) const
+{
+  /// output to screen
+  cout << Form("<AliMUONCheckItem> %s ID %d has %d items over %d max. Dead %d",
+               GetName(),fID,fMissing->GetSize(),fMaximum,IsDead()) << endl;  
+  TString sopt(opt);
+  sopt.ToLower();
+  if (sopt.Contains("all") )
+  {
+    TObject* object(0x0);
+  
+    AliMUONCheckItemIterator it(*this);
+  
+    it.First();
+  
+    while ( ( object = it.Next() ) )
+    {
+      object->Print(opt);
+    }
+  }
+}
diff --git a/MUON/AliMUONCheckItem.h b/MUON/AliMUONCheckItem.h
new file mode 100644 (file)
index 0000000..49e5e85
--- /dev/null
@@ -0,0 +1,56 @@
+#ifndef ALIMUONCHECKITEM_H
+#define ALIMUONCHECKITEM_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+* See cxx source for full Copyright notice                               */
+
+// $Id$
+
+/// \ingroup shuttle
+/// \class AliMUONCheckItem
+/// \brief A structure used to gather information at different levels (ch,manu,de,chamber)
+/// 
+/// \author Laurent Aphecetche
+
+#ifndef ROOT_TNamed
+#  include "TNamed.h"
+#endif
+
+class AliMpExMap;
+class TExMapIter;
+class AliMUONCheckItemIterator;
+
+class AliMUONCheckItem : public TNamed
+{
+  friend class AliMUONCheckItemIterator;
+
+public:
+
+  AliMUONCheckItem(Int_t id, Int_t maxNumber, const char* name);
+  virtual ~AliMUONCheckItem();
+  
+  Int_t GetID() const { return fID; }
+  
+  TObject* GetItem(Int_t id) const;
+  Bool_t AddItem(Int_t id, TObject* item);
+  
+  Bool_t IsFull() const;
+  Bool_t IsDead() const;
+  
+  void Print(Option_t* opt="") const;
+  
+private:
+  AliMUONCheckItem(const AliMUONCheckItem&);
+  AliMUONCheckItem& operator=(const AliMUONCheckItem&);
+  void ComputeDead() const;
+  
+private:
+  Int_t fID; //!< identifier of this item
+  mutable Int_t fDead; //!< whether this object is completely dead
+  Int_t fMaximum; //!< maximum number of sub-items possible within this item
+  AliMpExMap* fMissing; //!< pointers to the sub-items
+  
+  ClassDef(AliMUONCheckItem,1) // A composite object
+};
+
+#endif
diff --git a/MUON/AliMUONCheckItemIterator.cxx b/MUON/AliMUONCheckItemIterator.cxx
new file mode 100644 (file)
index 0000000..54a5d56
--- /dev/null
@@ -0,0 +1,81 @@
+/**************************************************************************
+* 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.                  *
+**************************************************************************/
+
+// $Id$
+
+#include "AliMUONCheckItemIterator.h"
+#include "TExMap.h"
+#include "AliMpExMap.h"
+#include "AliMUONCheckItem.h"
+
+/// \class AliMUONCheckItemIterator
+///
+/// Iterator on AliMUONCheckItem objects
+/// 
+///
+/// \author Laurent Aphecetche
+
+/// \cond CLASSIMP
+ClassImp(AliMUONCheckItemIterator)
+/// \endcond
+
+//_____________________________________________________________________________
+AliMUONCheckItemIterator::AliMUONCheckItemIterator() : TObject(), fIter(0x0)
+{
+  /// default ctor
+}
+
+//_____________________________________________________________________________
+AliMUONCheckItemIterator::AliMUONCheckItemIterator(const AliMUONCheckItem& item)
+: TObject(),
+fIter(0x0)
+{
+  /// ctor
+  AliMpExMap* m = item.fMissing;
+  fIter = new TExMapIter(m->GetIterator());
+}
+
+//_____________________________________________________________________________
+AliMUONCheckItemIterator::~AliMUONCheckItemIterator()
+{
+  /// dtor
+  delete fIter;
+}
+
+//_____________________________________________________________________________
+void
+AliMUONCheckItemIterator::First()
+{
+  /// Rewind the iterator
+  if ( fIter) fIter->Reset();
+}
+
+//_____________________________________________________________________________
+TObject*
+AliMUONCheckItemIterator::Next()
+{
+  /// Advance one object. Return 0 if ended.
+  if (!fIter) return 0x0;
+  Long_t key, value;
+  Bool_t ok = fIter->Next(key,value);
+  if (ok)
+  {
+    return reinterpret_cast<TObject*>(value);
+  }
+  else
+  {
+    return 0x0;
+  }
+}
diff --git a/MUON/AliMUONCheckItemIterator.h b/MUON/AliMUONCheckItemIterator.h
new file mode 100644 (file)
index 0000000..05a3308
--- /dev/null
@@ -0,0 +1,42 @@
+#ifndef ALIMUONCHECKITEMITERATOR_H
+#define ALIMUONCHECKITEMITERATOR_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+* See cxx source for full Copyright notice                               */
+
+// $Id$
+
+/// \ingroup shuttle
+/// \class AliMUONCheckItemIterator
+/// \brief Iterator on CheckItem
+/// 
+/// \author Laurent Aphecetche
+
+#ifndef ROOT_TObject
+#  include "TObject.h"
+#endif
+
+class AliMUONCheckItem;
+class TExMapIter;
+
+class AliMUONCheckItemIterator : public TObject
+{
+public:
+  AliMUONCheckItemIterator();
+  AliMUONCheckItemIterator(const AliMUONCheckItem& object);
+  virtual ~AliMUONCheckItemIterator();
+
+  void First();
+  TObject* Next();
+  
+private:
+  AliMUONCheckItemIterator(const AliMUONCheckItemIterator&);
+  AliMUONCheckItemIterator& operator=(const AliMUONCheckItemIterator&);
+  
+private:
+  TExMapIter* fIter; //!< the actual iterator doing the job
+  
+  ClassDef(AliMUONCheckItemIterator,1) // Iterator for AliMUONCheckItem objects
+};
+
+#endif
diff --git a/MUON/AliMUONObjectPair.cxx b/MUON/AliMUONObjectPair.cxx
new file mode 100644 (file)
index 0000000..b55cd1c
--- /dev/null
@@ -0,0 +1,117 @@
+/**************************************************************************
+* 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.                  *
+**************************************************************************/
+
+// $Id$
+
+#include "AliMUONObjectPair.h"
+
+/// \class AliMUONObjectPair
+///
+/// The equivalent of a std::pair<TObject*,TObject*> ;-)
+///
+/// What else can be said ? That if we'd been using STL, that class
+/// would not be there, thus saving some octets ? No comment.
+/// 
+/// Well, in fact, there *is* a difference wrt to std::pair : here
+/// we decide on the ownership of the first and/or second object...
+///
+/// \author Laurent Aphecetche
+
+/// \cond CLASSIMP
+ClassImp(AliMUONObjectPair)
+/// \endcond
+
+//_____________________________________________________________________________
+AliMUONObjectPair::AliMUONObjectPair() 
+: TObject(),
+fFirst(0x0),
+fSecond(0x0),
+fIsOwnerOfFirst(kTRUE),
+fIsOwnerOfSecond(kTRUE)
+{
+  /// ctor
+}
+
+//_____________________________________________________________________________
+AliMUONObjectPair::AliMUONObjectPair(TObject* first, 
+                  TObject* second,
+                  Bool_t isOwnerOfFirst,
+                  Bool_t isOwnerOfSecond)
+: TObject(),
+fFirst(first),
+fSecond(second),
+fIsOwnerOfFirst(isOwnerOfFirst),
+fIsOwnerOfSecond(isOwnerOfSecond)
+{
+  /// ctor
+}
+
+//_____________________________________________________________________________
+AliMUONObjectPair::AliMUONObjectPair(const AliMUONObjectPair& other)
+: TObject(other),
+fFirst(0x0),
+fSecond(0x0),
+fIsOwnerOfFirst(kTRUE),
+fIsOwnerOfSecond(kTRUE)
+{
+  /// copy ctor
+  other.Copy(*this);
+}
+
+//_____________________________________________________________________________
+AliMUONObjectPair& 
+AliMUONObjectPair::operator=(const AliMUONObjectPair& other)
+{
+  /// assignement operator
+  AliMUONObjectPair pair(other);
+  pair.Copy(*this);
+  return *this;
+}
+
+//_____________________________________________________________________________
+AliMUONObjectPair::~AliMUONObjectPair()
+{
+  /// dtor
+  if ( fIsOwnerOfFirst ) delete fFirst;
+  if ( fIsOwnerOfSecond ) delete fSecond;
+}
+
+//_____________________________________________________________________________
+void
+AliMUONObjectPair::Copy(TObject& other) const
+{
+  /// Copy this to other (used by copy ctor and operator=)
+  
+  TObject::Copy(other);
+  AliMUONObjectPair& pair = (AliMUONObjectPair&)(other);
+  pair.fIsOwnerOfFirst = fIsOwnerOfFirst;
+  pair.fIsOwnerOfSecond = fIsOwnerOfSecond;
+  if ( fIsOwnerOfFirst ) 
+  {
+    pair.fFirst = fFirst->Clone();
+  }
+  else
+  {
+    pair.fFirst = fFirst;
+  }
+  if ( fIsOwnerOfSecond )
+  {
+    pair.fSecond = fSecond->Clone();
+  }
+  else
+  {
+    pair.fSecond = fSecond;
+  }
+}
diff --git a/MUON/AliMUONObjectPair.h b/MUON/AliMUONObjectPair.h
new file mode 100644 (file)
index 0000000..9025e7a
--- /dev/null
@@ -0,0 +1,50 @@
+#ifndef ALIMUONOBJECTPAIR_H
+#define ALIMUONOBJECTPAIR_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+* See cxx source for full Copyright notice                               */
+
+// $Id$
+
+/// \ingroup base
+/// \class AliMUONObjectPair
+/// \brief The equivalent of a std::pair<TObject*,TObject*> ;-)
+/// 
+// Author Laurent Aphecetche
+
+#ifndef ROOT_TObject
+#  include "TObject.h"
+#endif
+
+class AliMUONObjectPair : public TObject
+{
+public:
+  AliMUONObjectPair();
+  AliMUONObjectPair(TObject* first, 
+                    TObject* second,
+                    Bool_t isOwnerOfFirst=kTRUE,
+                    Bool_t isOwnerOfSecond=kFALSE);
+  AliMUONObjectPair(const AliMUONObjectPair& other);
+  AliMUONObjectPair& operator=(const AliMUONObjectPair& other);
+  
+  virtual ~AliMUONObjectPair();
+
+  TObject* First() const { return fFirst; }
+  TObject* Second() const { return fSecond; }
+
+  TObject* Key() const { return fFirst; }
+  TObject* Value() const { return fSecond; }
+
+  virtual void Copy(TObject& other) const;
+  
+private:
+
+  TObject* fFirst; ///< first element of the pair
+  TObject* fSecond; ///< second element of the pair
+  Bool_t fIsOwnerOfFirst; ///< whether we own the first element
+  Bool_t fIsOwnerOfSecond; ///<whether we own the second element
+  
+  ClassDef(AliMUONObjectPair,1) // A pair of TObject*
+};
+
+#endif
diff --git a/MUON/AliMUONPedestalEventGenerator.cxx b/MUON/AliMUONPedestalEventGenerator.cxx
new file mode 100644 (file)
index 0000000..cadf6c8
--- /dev/null
@@ -0,0 +1,491 @@
+/**************************************************************************
+* 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.                  *
+**************************************************************************/
+
+// $Id$
+
+#include "AliMUONPedestalEventGenerator.h"
+
+#include "AliDAQ.h"
+#include "AliHeader.h"
+#include "AliLog.h"
+#include "AliMUONCalibrationData.h"
+#include "AliMUONData.h"
+#include "AliMUONDigit.h"
+#include "AliMUONRawWriter.h"
+#include "AliMUONVCalibParam.h"
+#include "AliMpIntPair.h"
+#include "AliMpManuList.h"
+#include "AliRunLoader.h"
+
+#include "TClonesArray.h"
+#include "TRandom.h"
+#include "TStopwatch.h"
+#include "TSystem.h"
+#include "TMath.h"
+
+///
+/// \class AliMUONPedestalEventGenerator
+///
+/// Generate simulated pedestal events for MUON TRK, to be able to e.g. test
+/// online calibration routines.
+///
+/// The pedestals themselves are taken from the CDB. What we get from the CDB
+/// is, per channel, the mean and the sigma of the pedestal. We then use
+/// those informations to randomly get the pedestals for each channel, for
+/// each event (picking in a gaus(mean,sigma)).
+///
+/// Output can be just digits, or digits + raw (ddl), or digits + raw (ddl)
+/// + raw (date files, one per LDC), depending of ctor and MakeDDL() method.
+///
+/// \author L. Aphecetche
+///
+
+/// \cond CLASSIMP
+ClassImp(AliMUONPedestalEventGenerator)
+/// \endcond
+
+Int_t AliMUONPedestalEventGenerator::fgCounter(0);
+
+//_____________________________________________________________________________
+AliMUONPedestalEventGenerator::AliMUONPedestalEventGenerator(Int_t runNumber,
+                                                             Int_t nevents,
+                                                             const char* filename)
+: TTask("AliMUONPedestalEventGenerator","Generate fake pedestal events"), 
+fManuList(AliMpManuList::ManuList()),
+fCalibrationData(new AliMUONCalibrationData(runNumber)),
+fDateFileName(filename),
+fGAliceFileName("galice.root"),
+fMakeDDL(kTRUE)
+{
+  /// Will generate pedestals according to (mean,sigma)s found in CDB
+  /// for run runNumber.
+  /// Will generate nevents events
+  /// If filename is != "", it will be the basename of the output LDC files
+  ///
+  if (!gSystem->IsAbsoluteFileName(fGAliceFileName)) 
+  {
+    char* absFileName = gSystem->ConcatFileName(gSystem->WorkingDirectory(),
+                                                fGAliceFileName);
+    fGAliceFileName = absFileName;
+    delete[] absFileName;
+  }
+  
+  AliRunLoader* runLoader = LoadRun("recreate");
+  
+  runLoader->SetNumberOfEventsPerFile(nevents);
+  
+  if (!runLoader)
+  {
+    AliError("Could not create RunLoader");
+    return;
+  }
+  
+  AliConfig::Instance()
+    ->CreateDetectorFolders(runLoader->GetEventFolder(), 
+                            "MUON", "MUON");
+  
+  AliLoader* loader = new AliLoader("MUON",runLoader->GetEventFolder());
+  
+       runLoader->AddLoader(loader);
+  
+  // Initialize event headers.
+  runLoader->MakeTree("E");
+  for ( Int_t iEvent = 0; iEvent < nevents; ++iEvent )
+  {
+    runLoader->SetEventNumber(iEvent);
+    runLoader->GetHeader()->Reset(runNumber,iEvent);
+    runLoader->TreeE()->Fill();
+  }
+  runLoader->WriteHeader("OVERWRITE");
+  runLoader->CdGAFile();
+  runLoader->Write(0, TObject::kOverwrite);  
+
+  assert(runLoader->GetNumberOfEvents()==nevents);
+  assert(runLoader->GetHeader()->GetRun()==runNumber);
+  
+  delete runLoader;
+}
+
+
+//_____________________________________________________________________________
+AliMUONPedestalEventGenerator::~AliMUONPedestalEventGenerator()
+{
+  /// dtor
+  delete fManuList;
+  delete fCalibrationData;
+  AliInfo(Form("make a digit counter %d",fgCounter));
+}
+
+//_____________________________________________________________________________
+Bool_t 
+AliMUONPedestalEventGenerator::ConvertRawFilesToDate()
+{
+  /// convert raw data DDL files to DATE files with the program "dateStream".
+  /// we make one file per LDC
+  
+  const Int_t kIDet = AliDAQ::DetectorID("MUONTRK");
+  
+  const Int_t kNLDCs = TMath::CeilNint(AliDAQ::NumberOfLdcs(kIDet));
+  
+  char* path = gSystem->Which(gSystem->Getenv("PATH"), "dateStream");
+  if (!path) 
+  {
+    AliError("the program dateStream was not found");
+    return kFALSE;
+  }
+  
+  delete[] path;
+  
+  AliRunLoader* runLoader = LoadRun("read");
+  if (!runLoader) return kFALSE;
+  
+  AliInfo(Form("converting raw data DDL files to DATE files %s", fDateFileName.Data()));
+  FILE** pipe = new FILE*[kNLDCs];
+  
+  for ( Int_t iFile = 0; iFile < kNLDCs; ++iFile)
+  {
+    char command[256];
+    // Note the option -s. It is used in order to avoid
+    // the generation of SOR/EOR events.
+    sprintf(command, "dateStream -s -D -o %s.LDC%d -# %d -C", 
+            fDateFileName.Data(), iFile, runLoader->GetNumberOfEvents());
+    pipe[iFile] = gSystem->OpenPipe(command, "w");
+  }
+  
+  for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); ++iEvent) 
+  {
+    Float_t ldc = 0;
+    Int_t prevLDC = -1;
+
+    for (Int_t iDDL = 0; iDDL < AliDAQ::NumberOfDdls(kIDet); ++iDDL) 
+    {        
+      Int_t ddlID = AliDAQ::DdlID(kIDet,iDDL);
+      Int_t ldcID = Int_t(ldc + 0.0001);
+      ldc += AliDAQ::NumberOfLdcs(kIDet) / AliDAQ::NumberOfDdls(kIDet);
+      
+      char rawFileName[256];
+      sprintf(rawFileName, "raw%d/%s", 
+              iEvent, AliDAQ::DdlFileName(kIDet,iDDL));
+      
+      // check existence and size of raw data file
+      FILE* file = fopen(rawFileName, "rb");
+      if (!file) continue;
+      fseek(file, 0, SEEK_END);
+      unsigned long size = ftell(file);
+      fclose(file);
+      if (!size) continue;
+      
+      if (ldcID != prevLDC) {
+        fprintf(pipe[ldcID], " LDC Id %d\n", ldcID);
+        prevLDC = ldcID;
+      }
+      fprintf(pipe[ldcID], "  Equipment Id %d Payload %s\n", ddlID, rawFileName);
+    }
+  }
+  
+  Int_t result(0);
+  
+  for ( Int_t iFile = 0; iFile < kNLDCs; ++iFile)
+  {
+    result += gSystem->ClosePipe(pipe[iFile]);
+  }
+  
+  delete [] pipe;
+  delete runLoader;
+  return (result == 0);
+}
+
+//_____________________________________________________________________________
+void
+AliMUONPedestalEventGenerator::Exec(Option_t*)
+{  
+  /// Main steering method
+  
+  TStopwatch timer;
+  timer.Start(kTRUE);
+  
+  TStopwatch writeTimer;
+  writeTimer.Start(kTRUE); writeTimer.Stop();
+  TStopwatch fillTimer;
+  fillTimer.Start(kTRUE); fillTimer.Stop();
+  TStopwatch resetTimer;
+  resetTimer.Start(kTRUE); resetTimer.Stop();
+  TStopwatch getEventTimer;
+  getEventTimer.Start(kTRUE); getEventTimer.Stop();
+  TStopwatch branchTimer;
+  branchTimer.Start(kTRUE); branchTimer.Stop();
+  TStopwatch generateDigitsTimer;
+  generateDigitsTimer.Start(kTRUE); generateDigitsTimer.Stop();
+  TStopwatch digits2RawTimer;
+  digits2RawTimer.Start(kTRUE); digits2RawTimer.Stop();
+  TStopwatch convertRawFilesToDateTimer;
+  convertRawFilesToDateTimer.Start(kTRUE); convertRawFilesToDateTimer.Stop();
+  TStopwatch getTimer;
+
+  getTimer.Start(kTRUE); 
+  AliMUONData* data = GetDataAccess("update");
+  AliRunLoader* runLoader = data->GetLoader()->GetRunLoader();  
+  getTimer.Stop();
+  
+  for ( Int_t i = 0; i < runLoader->GetNumberOfEvents(); ++i )
+  {
+    getEventTimer.Start(kFALSE);
+    runLoader->GetEvent(i);
+    getEventTimer.Stop();
+    
+    branchTimer.Start(kFALSE);
+    if ( data->TreeD() == 0x0 )
+    {
+      AliDebug(1,"Calling MakeDigitsContainer");
+      data->GetLoader()->MakeDigitsContainer();
+    }
+    data->MakeBranch("D,GLT");
+    data->SetTreeAddress("D,GLT");
+    branchTimer.Stop();
+    
+    generateDigitsTimer.Start(kFALSE);
+    GenerateDigits(data);
+    generateDigitsTimer.Stop();
+    
+    fillTimer.Start(kTRUE);
+    // Fill the output treeD
+    data->Fill("D,GLT");
+    fillTimer.Stop();
+    
+    // Write to the output tree(D).
+    // Please note that as GlobalTrigger, LocalTrigger and Digits are in the same
+    // tree (=TreeD) in different branches, this WriteDigits in fact writes all of 
+    // the 3 branches.
+    
+    writeTimer.Start(kFALSE);
+    data->GetLoader()->WriteDigits("OVERWRITE");
+    writeTimer.Stop();
+    
+    // Finally, we clean up after ourselves.
+    resetTimer.Start(kTRUE);
+    data->ResetDigits();
+    data->ResetTrigger();
+    data->GetLoader()->UnloadDigits();
+    resetTimer.Stop();
+  }
+  
+  TStopwatch endTimer;
+  endTimer.Start(kTRUE);
+  runLoader->WriteRunLoader("OVERWRITE");
+  delete data;
+  delete runLoader;
+  endTimer.Stop();
+  
+  if ( fMakeDDL ) 
+  {
+    // Now convert the digits.root file(s) to DDL files
+    digits2RawTimer.Start(kFALSE);
+    Digits2Raw();
+    digits2RawTimer.Stop();
+  }
+  
+  // Finally, if instructed to do so, convert DDL files to DATE file(s)
+  if ( fMakeDDL && fDateFileName.Length() > 0 ) 
+  {
+    convertRawFilesToDateTimer.Start(kFALSE);
+    AliDebug(1,"Converting to DATE file(s)");
+    
+    Bool_t dateOutput = ConvertRawFilesToDate();
+    convertRawFilesToDateTimer.Stop();
+    if (!dateOutput) 
+    {
+      AliError("DATE output failed. Aborting.");
+      return;
+    }    
+  }
+  
+  AliInfo(Form("Execution time Exec : R:%.2fs C:%.2fs",
+               timer.RealTime(),timer.CpuTime()));
+
+  AliInfo(Form("  Execution time branch : R:%.2fs C:%.2fs",
+               branchTimer.RealTime(),branchTimer.CpuTime()));
+  AliInfo(Form("  Execution time getEvent : R:%.2fs C:%.2fs",
+               getEventTimer.RealTime(),getEventTimer.CpuTime()));
+  AliInfo(Form("  Execution time fill digits : R:%.2fs C:%.2fs",
+               fillTimer.RealTime(),fillTimer.CpuTime()));
+  AliInfo(Form("  Execution time write digits : R:%.2fs C:%.2fs",
+               writeTimer.RealTime(),writeTimer.CpuTime()));
+  AliInfo(Form("  Execution time reset digits : R:%.2fs C:%.2fs",
+               resetTimer.RealTime(),resetTimer.CpuTime()));
+  AliInfo(Form("  Execution time for GenerateDigits : R:%.2fs C:%.2fs",
+               generateDigitsTimer.RealTime(),generateDigitsTimer.CpuTime()));
+  AliInfo(Form("  Execution time for Digits2Raw : R:%.2fs C:%.2fs",
+               digits2RawTimer.RealTime(),digits2RawTimer.CpuTime()));
+  AliInfo(Form("  Execution time for ConvertRawFilesToDate : R:%.2fs C:%.2fs",
+               convertRawFilesToDateTimer.RealTime(),convertRawFilesToDateTimer.CpuTime()));
+  AliInfo(Form("  Execution time for get : R:%.2fs C:%.2fs",
+               getTimer.RealTime(),getTimer.CpuTime()));
+  AliInfo(Form("  Execution time for end : R:%.2fs C:%.2fs",
+               endTimer.RealTime(),endTimer.CpuTime()));
+}
+
+//_____________________________________________________________________________
+void
+AliMUONPedestalEventGenerator::Digits2Raw()
+{
+  /// Converts digits (from MUON.Digits.root file) to Raw DDL ascii files.
+  
+  AliMUONData* data = GetDataAccess("read");
+  AliRunLoader* runLoader = data->GetLoader()->GetRunLoader();
+  AliDebug(1,Form("runLoader=%p",runLoader));
+  
+  AliMUONRawWriter rawWriter(data);
+  
+  // Generate RAW data from the digits
+  // Be carefull to create&change to the correct directory first...
+
+  TString baseDir = gSystem->WorkingDirectory();
+
+  for ( Int_t i = 0; i < runLoader->GetNumberOfEvents(); ++i )
+  {
+    runLoader->GetEvent(i);
+    
+    AliDebug(1,Form("processing event %d", i));
+    
+    char dirName[256];
+    sprintf(dirName, "raw%d", i);
+    gSystem->MakeDirectory(dirName);
+    if (!gSystem->ChangeDirectory(dirName)) 
+    {
+      AliError(Form("couldn't change to directory %s", dirName));
+      return;
+    }
+
+    rawWriter.Digits2Raw();
+    
+    gSystem->ChangeDirectory(baseDir);
+  }
+  
+  delete data;
+  delete runLoader;
+  
+  AliDebug(1,Form("DDL files written successfully"));    
+}
+
+//_____________________________________________________________________________
+void
+AliMUONPedestalEventGenerator::GenerateDigits(AliMUONData* data)
+{  
+  /// Generate digits (where ADC is set to pedestal value) for all MUON TRK
+  /// and for 1 event.
+  
+  TIter next(fManuList);
+  AliMpIntPair* p;
+  Int_t ngenerated(0);
+  
+  while ( ( p = static_cast<AliMpIntPair*>(next())) )
+  {
+    Int_t detElemId = p->GetFirst();
+
+    Int_t chamber = detElemId/100-1;
+        
+    TClonesArray* pdigits = data->Digits(chamber);
+    if (!pdigits)
+    {
+      AliError(Form("No digits for chamber %d",1));
+      continue;
+    }
+    TClonesArray& digits = *pdigits;
+    
+    Int_t manuId = p->GetSecond();
+    
+    AliMUONVCalibParam* pedestals = fCalibrationData->Pedestals(detElemId,manuId);
+    if (!pedestals)
+    {
+      AliError(Form("Could not find pedestals for (DE,MANU)=(%d,%d)",detElemId,
+                    manuId));
+      return;
+    }
+    for ( Int_t manuChannel = 0; manuChannel < pedestals->Size(); ++manuChannel )
+    {
+      Float_t mean = pedestals->ValueAsFloat(manuChannel,0);
+      if (mean == AliMUONVCalibParam::InvalidFloatValue())
+      {
+        // This is a poor's man way of knowing if that channel really exists.
+        // Better and safer way (but much slower too) would be to check pad existence
+        // using AliMpVSegmentation::PadByLocation(AliMpIntPair(manuId,manuChannel))
+        continue;
+      }
+      else
+      {
+        Float_t sigma = pedestals->ValueAsFloat(manuChannel,1);
+        AliMUONDigit d;
+        Float_t ped = gRandom->Gaus(mean,sigma);
+       Int_t pedADC = TMath::FloorNint(ped);
+        d.SetElectronics(manuId, manuChannel);
+        d.SetADC(pedADC);
+        d.SetSignal(ped);
+        d.SetDetElemId(detElemId); 
+        // we do not set the remaining parts of the digit, as in principle
+        // this is all we need : manuId, manuChannel and ADC, as far as
+        // real data is concerned.
+        new (digits[digits.GetLast()+1]) AliMUONDigit(d);
+        ++fgCounter;
+        ++ngenerated;
+      }
+    }
+  }
+  AliDebug(1,Form("ngenerated=%d",ngenerated));
+}
+
+//_____________________________________________________________________________
+AliMUONData*
+AliMUONPedestalEventGenerator::GetDataAccess(const char* mode)
+{
+  /// Get the pointer to AliMUONData object
+  AliRunLoader* runLoader = LoadRun(mode);
+  if (!runLoader)
+  {
+    AliError("Could not get RunLoader");
+    return 0x0;
+  }
+  AliLoader* loader = static_cast<AliLoader*>(runLoader->GetLoader("MUONLoader"));
+  if (!loader)
+  {
+    AliError("Could not get MuonLoader");
+    return 0x0;
+  }
+  
+  return new AliMUONData(loader,"MUON","MUONData");
+}
+
+//_____________________________________________________________________________
+AliRunLoader*
+AliMUONPedestalEventGenerator::LoadRun(const char* mode)
+{
+  /// Get access to AliRunLoader object
+  while (AliRunLoader::GetRunLoader()) 
+  {
+    AliDebug(1,Form("Deleting AliRunLoader %p",AliRunLoader::GetRunLoader()));
+    delete AliRunLoader::GetRunLoader();
+  }
+  
+  AliRunLoader* runLoader = 
+    AliRunLoader::Open(fGAliceFileName,AliConfig::GetDefaultEventFolderName(), 
+                       mode);
+  
+  AliDebug(1,Form("AliRunLoader(%s)=%p",mode,runLoader));
+           
+  if (!runLoader) 
+  {
+    AliError("No run loader found in file galice.root");
+  }
+  return runLoader;
+}
diff --git a/MUON/AliMUONPedestalEventGenerator.h b/MUON/AliMUONPedestalEventGenerator.h
new file mode 100644 (file)
index 0000000..3998ce2
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef ALIMUONPEDESTALEVENTGENERATOR_H
+#define ALIMUONPEDESTALEVENTGENERATOR_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+* See cxx source for full Copyright notice                               */
+
+// $Id$
+
+/// \ingroup shuttle
+/// \class AliMUONPedestalEventGenerator
+/// \brief Generate pedestal events (only for tracker).
+/// 
+/// \author Laurent Aphecetche
+
+#ifndef ROOT_TTask
+#  include "TTask.h"
+#endif
+#ifndef ROOT_TString
+#  include "TString.h"
+#endif
+
+class AliMUONCalibrationData;
+class AliMUONData;
+class TList;
+class AliRunLoader;
+
+class AliMUONPedestalEventGenerator : public TTask
+{
+public:
+  AliMUONPedestalEventGenerator(Int_t runNumber, Int_t nevents, const char* dateFileName);
+  virtual ~AliMUONPedestalEventGenerator();
+  
+  void Exec(Option_t* option);
+  
+  void MakeDDL(Bool_t value) { fMakeDDL = value; }
+  
+private:
+  AliMUONPedestalEventGenerator(const AliMUONPedestalEventGenerator&);
+  AliMUONPedestalEventGenerator& operator=(const AliMUONPedestalEventGenerator&);
+  Bool_t ConvertRawFilesToDate();
+  void GenerateDigits(AliMUONData* data);
+  AliMUONData* GetDataAccess(const char* mode);
+  AliRunLoader* LoadRun(const char* mode);
+  void Digits2Raw();
+  
+private:
+  TList* fManuList; //! list of (de,manu) pairs
+  AliMUONCalibrationData* fCalibrationData; //! access to pedestal CDB
+  TString fDateFileName; //! basefilename of the DATE output file
+  TString fGAliceFileName; //! absolute path to galice.root file
+  Bool_t fMakeDDL; //! whether to generate DDL ascii files or not
+  static Int_t fgCounter; //! 
+  
+  ClassDef(AliMUONPedestalEventGenerator,1) // Random generator of pedestal events for MUON TRK
+};
+
+#endif
diff --git a/MUON/AliMUONPedestalSubprocessor.cxx b/MUON/AliMUONPedestalSubprocessor.cxx
new file mode 100644 (file)
index 0000000..c1fdebe
--- /dev/null
@@ -0,0 +1,195 @@
+/**************************************************************************
+* 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.                  *
+**************************************************************************/
+
+// $Id$
+
+#include "AliMUONPedestalSubprocessor.h"
+
+#include "AliCDBMetaData.h"
+#include "AliLog.h"
+#include "AliMUON2DMap.h"
+#include "AliMUON2DStoreValidator.h"
+#include "AliMUONCalibParam2F.h"
+#include "Riostream.h"
+#include "TObjString.h"
+#include "TSystem.h"
+#include <sstream>
+#include "AliMUONVDataIterator.h"
+#include "AliMUONConstants.h"
+#include "AliMUONObjectPair.h"
+#include "AliMpBusPatch.h"
+#include "AliMUONPreprocessor.h"
+
+///
+/// \class AliMUONPedestalSubprocessor
+///
+/// Implementation of AliMUONVSubprocessor class to deal with MUON TRK pedestals.
+///
+/// Pedestals are read in from an ascii file, with the format :               \n
+///---------------------------------------------------------------------------\n
+/// BUS_PATCH MANU_ADDR CHANNEL      MEAN       SIGMA                         \n
+///---------------------------------------------------------------------------\n
+///
+/// \author L. Aphecetche
+///
+
+/// \cond CLASSIMP
+ClassImp(AliMUONPedestalSubprocessor)
+/// \endcond
+
+//_____________________________________________________________________________
+AliMUONPedestalSubprocessor::AliMUONPedestalSubprocessor(AliMUONPreprocessor* master)
+: AliMUONVSubprocessor(master,
+                       "Pedestals",
+                       "Upload MUON Tracker pedestals to OCDB"),
+fPedestals(0x0)
+{
+  // default ctor
+}
+
+//_____________________________________________________________________________
+AliMUONPedestalSubprocessor::~AliMUONPedestalSubprocessor()
+{
+  // dtor
+  delete fPedestals;
+}
+
+//_____________________________________________________________________________
+void 
+AliMUONPedestalSubprocessor::Initialize(Int_t run, UInt_t startTime, UInt_t endTime)
+{
+  /// When starting a new run, reads in the pedestals ASCII files.
+  
+  const Int_t kSystem = AliMUONPreprocessor::kDAQ;
+  const char* kId = "PEDESTALS";
+  
+  delete fPedestals;
+  fPedestals = new AliMUON2DMap(kTRUE);
+  
+  AliInfo(Form("Reading pedestal files for Run %d startTime %ld endTime %ld",
+               run,startTime,endTime));
+  
+  TList* sources = Master()->GetFileSources(kSystem,kId);
+  TIter next(sources);
+  TObjString* o(0x0);
+  while ( ( o = static_cast<TObjString*>(next()) ) )
+  {
+    TString fileName(Master()->GetFile(kSystem,kId,o->GetName()));
+    Bool_t ok = ReadFile(fileName.Data());
+    if (!ok)
+    {
+      AliError(Form("Could not read file %s",fileName.Data()));
+    }
+  }
+  delete sources;
+}
+
+//_____________________________________________________________________________
+UInt_t 
+AliMUONPedestalSubprocessor::Process(TMap* /*dcsAliasMap*/)
+{
+  // Store the pedestals into the CDB
+  
+  if (!fPedestals) return 0;
+  
+  AliInfo("Validating pedestals");
+  AliMUON2DStoreValidator validator;
+  TObjArray* missing =
+    validator.Validate(*fPedestals,AliMUONCalibParam2F::InvalidFloatValue());  
+  
+  if (missing)  
+  {
+    validator.Report(*missing);
+//    AliError("Will not write into CDB as some pieces are missing...");
+//    return 0;
+  }
+  
+  AliInfo("Storing pedestals");
+  
+  AliCDBMetaData metaData;
+       metaData.SetBeamPeriod(0);
+       metaData.SetResponsible("MUON TRK");
+       metaData.SetComment("Computed by AliMUONPedestalSubprocessor $Id$");
+  
+       UInt_t result = Master()->Store("Calib", "Pedestals", fPedestals, &metaData, 0, 0);
+  
+  return result;  
+}
+
+//_____________________________________________________________________________
+Bool_t
+AliMUONPedestalSubprocessor::ReadFile(const char* filename)
+{
+  // Read the pedestals from an ASCII file.
+  // Format of that file is one line per channel :
+  //---------------------------------------------------------------------------
+  // BUS_PATCH MANU_ADDR CHANNEL      MEAN       SIGMA
+  //---------------------------------------------------------------------------
+  //
+  // Return kFALSE if reading was not successfull.
+  //
+  
+  AliInfo(Form("Reading %s",filename));
+  
+  std::ifstream in(gSystem->ExpandPathName(filename));
+  if (!in.good()) return kFALSE;
+  
+  char line[80];
+  Int_t busPatchID, manuID, manuChannel;
+  Float_t pedMean, pedSigma;
+  AliMpBusPatch busPatch;
+  busPatch.ReadBusPatchFile();
+  static const Int_t kNchannels(64);
+  static Bool_t replace(kFALSE);
+  
+  while ( in.getline(line,80) )
+  {
+    if ( line[0] == '/' && line[1] == '/' ) continue;
+    std::istringstream sin(line);
+    sin >> busPatchID >> manuID >> manuChannel >> pedMean >> pedSigma;
+    Int_t detElemID = busPatch.GetDEfromBus(busPatchID);
+    AliDebug(3,Form("BUSPATCH %3d DETELEMID %4d MANU %3d CH %3d MEAN %7.2f SIGMA %7.2f",
+             busPatchID,detElemID,manuID,manuChannel,pedMean,pedSigma));
+    
+    AliMUONVCalibParam* ped = 
+      static_cast<AliMUONVCalibParam*>(fPedestals->Get(detElemID,manuID));
+    
+    if (!ped) 
+    {
+      ped = new AliMUONCalibParam2F(kNchannels,AliMUONCalibParam2F::InvalidFloatValue());  
+      fPedestals->Set(detElemID,manuID,ped,replace);
+    }
+    ped->SetValueAsFloat(manuChannel,0,pedMean);
+    ped->SetValueAsFloat(manuChannel,1,pedSigma);
+  }
+  in.close();
+  return kTRUE;
+}
+
+
+//_____________________________________________________________________________
+void
+AliMUONPedestalSubprocessor::Print(Option_t* opt) const
+{
+  /// ouput to screen
+  AliMUONVDataIterator* it = fPedestals->Iterator();
+  AliMUONObjectPair* p;
+
+  while ( ( p = static_cast<AliMUONObjectPair*>(it->Next() ) ) )
+  {
+    AliMUONVCalibParam* value = static_cast<AliMUONVCalibParam*>(p->Value());
+    value->Print(opt);
+  }
+}
diff --git a/MUON/AliMUONPedestalSubprocessor.h b/MUON/AliMUONPedestalSubprocessor.h
new file mode 100644 (file)
index 0000000..d87466f
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef ALIMUONPEDESTALSUBPROCESSOR_H
+#define ALIMUONPEDESTALSUBPROCESSOR_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+* See cxx source for full Copyright notice                               */
+
+// $Id$
+
+/// \ingroup shuttle
+/// \class AliMUONPedestalSubprocessor
+/// \brief Implementation of AliMUONVSubprocessor for MUON TRK pedestals
+/// 
+/// \author Laurent Aphecetche
+
+#ifndef ALIMUONVSUBPROCESSOR_H
+#  include "AliMUONVSubprocessor.h"
+#endif
+
+class AliMUONV2DStore;
+class TObjArray;
+
+class AliMUONPedestalSubprocessor : public AliMUONVSubprocessor
+{
+public:
+  AliMUONPedestalSubprocessor(AliMUONPreprocessor* master);
+  virtual ~AliMUONPedestalSubprocessor();
+  
+  void Initialize(Int_t run, UInt_t startTime, UInt_t endTime);
+  UInt_t Process(TMap* dcsAliasMap);
+  void Print(Option_t* opt="") const;
+  
+private:
+  AliMUONPedestalSubprocessor(const AliMUONPedestalSubprocessor&);
+  AliMUONPedestalSubprocessor& operator=(const AliMUONPedestalSubprocessor&);
+  
+  Bool_t ReadFile(const char* filename);
+  void ReportMissing(const TObjArray& chambers);
+  
+private:
+  AliMUONV2DStore* fPedestals; //! Pedestals for the MUON TRK
+  
+  ClassDef(AliMUONPedestalSubprocessor,1) // A shuttle preprocessor for MUON TRK pedetals
+};
+
+#endif
diff --git a/MUON/AliMUONPreprocessor.cxx b/MUON/AliMUONPreprocessor.cxx
new file mode 100644 (file)
index 0000000..b969f15
--- /dev/null
@@ -0,0 +1,112 @@
+/**************************************************************************
+* 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.                  *
+**************************************************************************/
+
+// $Id$
+
+#include "AliMUONPreprocessor.h"
+#include "TObjArray.h"
+#include "AliMUONPedestalSubprocessor.h"
+#include "Riostream.h"
+
+/// \class AliMUONPreprocessor
+///
+/// Shuttle preprocessor for MUON subsystems (TRK and TRG)
+/// 
+/// It's simply a manager class that deals with a list of sub-tasks 
+/// (of type AliMUONVSubprocessor).
+///
+/// \author Laurent Aphecetche
+
+/// \cond CLASSIMP
+ClassImp(AliMUONPreprocessor)
+/// \endcond
+
+//_____________________________________________________________________________
+AliMUONPreprocessor::AliMUONPreprocessor(const char* detector, 
+                                         AliShuttleInterface* shuttle) 
+: AliPreprocessor(detector,shuttle), fSubprocessors(new TObjArray[kLast])
+{
+  /// ctor. Builds the list of subtasks
+  ///
+  /// \todo FIXME: should test detector wrt to tracker or trigger to 
+  /// instantiate the correct list of subtasks, which should be : 
+  /// Tracker : 
+  /// pedestals
+  /// gains
+  /// deadchannels
+  /// gms
+  ///
+  /// Trigger : 
+  /// masks
+  /// lut
+  ///
+  fSubprocessors->AddAt(new AliMUONPedestalSubprocessor(this),kPedestal);
+}
+
+//_____________________________________________________________________________
+AliMUONPreprocessor::~AliMUONPreprocessor()
+{
+  /// dtor
+  delete fSubprocessors;
+}
+
+//_____________________________________________________________________________
+void
+AliMUONPreprocessor::Initialize(Int_t run, UInt_t startTime, UInt_t endTime)
+{
+  /// loop over subtasks and initialize them
+  for ( Int_t i = 0; i <= fSubprocessors->GetLast(); ++i )
+  {
+    Subprocessor(i)->Initialize(run,startTime,endTime);
+  }
+}
+
+//_____________________________________________________________________________
+UInt_t
+AliMUONPreprocessor::Process(TMap* dcsAliasMap)
+{
+  /// loop over subtasks to make them work
+  UInt_t rv(0);
+  
+  for ( Int_t i = 0; i <= fSubprocessors->GetLast(); ++i )
+  {
+    rv += Subprocessor(i)->Process(dcsAliasMap);
+  }
+  return rv;
+}
+
+//_____________________________________________________________________________
+void
+AliMUONPreprocessor::Print(Option_t* opt) const
+{
+  /// output to screen
+  cout << "<AliMUONPreprocessor> subprocessors :" << endl;
+  for ( Int_t i=0; i <= fSubprocessors->GetLast(); ++i )
+  {
+    Subprocessor(i)->Print(opt);
+  }
+}
+
+//_____________________________________________________________________________
+AliMUONVSubprocessor*
+AliMUONPreprocessor::Subprocessor(Int_t i) const
+{
+  /// return i-th subprocessor
+  if ( i >= 0 && i <= fSubprocessors->GetLast() )
+  {
+    return static_cast<AliMUONVSubprocessor*>(fSubprocessors->At(i));
+  }
+  return 0x0;
+}
diff --git a/MUON/AliMUONPreprocessor.h b/MUON/AliMUONPreprocessor.h
new file mode 100644 (file)
index 0000000..deeb3c9
--- /dev/null
@@ -0,0 +1,62 @@
+#ifndef ALIMUONPREPROCESSOR_H
+#define ALIMUONPREPROCESSOR_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+* See cxx source for full Copyright notice                               */
+
+// $Id$
+
+/// \ingroup shuttle
+/// \class AliMUONPreprocessor
+/// \brief Shuttle preprocessor for MUON subsystems (TRK and TRG)
+/// 
+/// \author Laurent Aphecetche
+
+#ifndef ALI_PREPROCESSOR_H
+#  include "AliPreprocessor.h"
+#endif
+
+class AliMUONVSubprocessor;
+class TObjArray;
+
+class AliMUONPreprocessor : public AliPreprocessor
+{
+public:
+  AliMUONPreprocessor(const char* detector, AliShuttleInterface* shuttle);
+  virtual ~AliMUONPreprocessor();
+  
+  virtual void Initialize(Int_t run, UInt_t startTime, UInt_t endTime);
+  virtual UInt_t Process(TMap* dcsAliasMap);
+  virtual void Print(Option_t* opt="") const;
+  
+  TList* GetFileSources(Int_t system, const char* id) 
+  { return AliPreprocessor::GetFileSources(system,id); }
+
+  UInt_t Store(const char* pathLevel2, const char* pathLevel3, TObject* object,
+               AliCDBMetaData* metaData, 
+               Int_t validityStart = 0, Bool_t validityInfinite = kFALSE)
+  {
+    return AliPreprocessor::Store(pathLevel2,pathLevel3,object,metaData,
+                                  validityStart,validityInfinite);
+  }
+  
+  const char* GetFile(Int_t system, const char* id, const char* source)
+  {
+    return AliPreprocessor::GetFile(system,id,source);
+  }  
+  
+private:
+  enum ESubprocessors { kPedestal=0, kLast };
+  
+  AliMUONPreprocessor(const AliMUONPreprocessor& rhs);
+  AliMUONPreprocessor& operator=(const AliMUONPreprocessor& rhs);
+  
+  AliMUONVSubprocessor* Subprocessor(Int_t i) const;
+  
+private:
+  TObjArray* fSubprocessors; ///!< sub processors to execute
+  
+  ClassDef(AliMUONPreprocessor,1) // MUON Shuttle preprocessor
+};
+
+#endif
diff --git a/MUON/AliMUONVSubprocessor.cxx b/MUON/AliMUONVSubprocessor.cxx
new file mode 100644 (file)
index 0000000..0866ff6
--- /dev/null
@@ -0,0 +1,57 @@
+/**************************************************************************
+* 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.                  *
+**************************************************************************/
+
+// $Id$
+
+#include "AliMUONVSubprocessor.h"
+
+/// \class AliMUONVSubprocessor
+///
+/// Base class for a shuttle sub-task for MUON (either TRK or TRG)
+///
+/// It allows to organize more cleanly the various calibration tasks
+/// to be performed within the MUON shuttle's preprocessors
+///
+/// \author Laurent Aphecetche
+///
+
+/// \cond CLASSIMP
+ClassImp(AliMUONVSubprocessor)
+/// \endcond
+
+//_____________________________________________________________________________
+AliMUONVSubprocessor::AliMUONVSubprocessor(AliMUONPreprocessor* master,
+                                           const char* name,
+                                           const char* title)
+: TNamed(name,title), fMaster(master)
+{
+  /// ctor
+}
+
+//_____________________________________________________________________________
+AliMUONVSubprocessor::~AliMUONVSubprocessor()
+{
+  /// dtor
+}
+
+//_____________________________________________________________________________
+void
+AliMUONVSubprocessor::Initialize(Int_t /*run*/, 
+                                 UInt_t /*startTime*/, 
+                                 UInt_t /*endTime*/)
+{
+  /// optional
+}
+
diff --git a/MUON/AliMUONVSubprocessor.h b/MUON/AliMUONVSubprocessor.h
new file mode 100644 (file)
index 0000000..0078833
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef ALIMUONVSUBPROCESSOR_H
+#define ALIMUONVSUBPROCESSOR_H
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+* See cxx source for full Copyright notice                               */
+
+// $Id$
+
+/// \ingroup shuttle
+/// \class AliMUONVSubprocessor
+/// \brief Base class for a shuttle sub-task for MUON (either TRK or TRG)
+/// 
+/// \author Laurent Aphecetche
+
+#ifndef ROOT_TNamed
+#  include "TNamed.h"
+#endif
+
+class TMap;
+class AliMUONPreprocessor;
+
+class AliMUONVSubprocessor : public TNamed
+{
+public:
+  AliMUONVSubprocessor(AliMUONPreprocessor* master,
+                       const char* name="", const char* title="");
+  virtual ~AliMUONVSubprocessor();
+  
+  virtual void Initialize(Int_t run, UInt_t startTime, UInt_t endTime);
+  virtual UInt_t Process(TMap* dcsAliasMap) = 0;
+  
+protected:
+  AliMUONPreprocessor* Master() const { return fMaster; }
+  
+  AliMUONVSubprocessor();
+  AliMUONVSubprocessor(const AliMUONVSubprocessor&);
+  AliMUONVSubprocessor& operator=(const AliMUONVSubprocessor&);
+  
+private:
+  AliMUONPreprocessor* fMaster; ///< Pointer to our master
+  
+  ClassDef(AliMUONVSubprocessor,1) // Base class of MUON shuttle sub(pre)processors
+};
+
+#endif
diff --git a/MUON/MUONshuttleLinkDef.h b/MUON/MUONshuttleLinkDef.h
new file mode 100644 (file)
index 0000000..d1586cb
--- /dev/null
@@ -0,0 +1,11 @@
+#ifdef __CINT__
+
+#pragma link C++ class AliMUON2DStoreValidator+;
+#pragma link C++ class AliMUONPreprocessor+;
+#pragma link C++ class AliMUONVSubprocessor+;
+#pragma link C++ class AliMUONPedestalSubprocessor+;
+#pragma link C++ class AliMUONPedestalEventGenerator+;
+#pragma link C++ class AliMUONCheckItem+;
+#pragma link C++ class AliMUONCheckItemIterator+;
+
+#endif
diff --git a/MUON/TestMUONPreprocessor.C b/MUON/TestMUONPreprocessor.C
new file mode 100644 (file)
index 0000000..cb76ef2
--- /dev/null
@@ -0,0 +1,131 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+
+/* $Id$ */
+
+#if !defined(__CINT__) || defined(__MAKECINT__)
+
+// This macro runs the test preprocessor
+// It uses AliTestShuttle to simulate a full Shuttle process
+
+// The input data is created in the functions
+//   CreateDCSAliasMap() creates input that would in the same way come from DCS
+//   ReadDCSAliasMap() reads from a file
+//   CreateInputFilesMap() creates a list of local files, that can be accessed by the shuttle
+//
+// According to SHUTTLE/TestShuttle/TestPreprocessor.C
+// By Laurent Aphecetche, SUBATECH Nantes
+
+#include "AliCDBManager.h"
+#include "AliShuttleInterface.h"
+#include "AliCDBId.h"
+#include "AliTestShuttle.h"
+#include "TMap.h"
+#include "Riostream.h"
+#include "TSystem.h"
+#include "AliMpExMap.h"
+#include "TMap.h"
+#include "TString.h"
+#include "TObjArray.h"
+#include "AliMpHelper.h"
+#include "AliDCSValue.h"
+#include "TObjString.h"
+#include "TRandom.h"
+#include "AliMUONPreprocessor.h"
+#include "AliCDBEntry.h"
+#endif
+
+void TestMUONPreprocessor()
+{
+  // load library
+  gSystem->Load("../SHUTTLE/TestShuttle/libTestShuttle.so");
+  
+  // initialize location of CDB
+  AliCDBManager::Instance()->SetDefaultStorage("local://$ALICE_ROOT/SHUTTLE/TestShuttle/TestCDB");
+
+  // create AliTestShuttle instance
+  // The parameters are run, startTime, endTime
+  AliTestShuttle* shuttle = new AliTestShuttle(800, 0, 1);
+
+  // TODO(1)
+  //
+  // The shuttle can read DCS data, if the preprocessor should be tested to process DCS data,
+  // some fake data has to be created.
+  //
+  // The "fake" input data can be taken using either (a) or (b):
+  // (a) data from a file: Use ReadDCSAliasMap()
+  //     the format of the file is explained in ReadDCSAliasMap()
+  //     To use it uncomment the following line:
+  //
+// TMap* dcsAliasMap = ReadDCSAliasMap();
+  //
+  // (b) generated in this macro: Use CreateDCSAliasMap() and its documentation
+  //     To use it uncomment the following line:
+  //
+// TMap* dcsAliasMap = CreateDCSAliasMap();
+
+  // now give the alias map to the shuttle
+  // shuttle->SetDCSInput(dcsAliasMap);
+
+  // TODO(2)
+  //
+  // The shuttle can also process files that originate from DCS, DAQ and HLT.
+  // To test it, we provide some local files and locations where these would be found when
+  // the online machinery would be there.
+  // In real life this functions would be produces by the sub-detectors
+  // calibration programs in DCS, DAQ or HLT. These files can then be retrieved using the Shuttle.
+  //
+  // Files are added with the function AliTestShuttle::AddInputFile. The syntax is:
+  // AddInputFile(<system>, <detector>, <id>, <source>, <local-file>)
+  // In this example we add a file originating from the GDC with the id PEDESTALS
+  // Three files originating from different LDCs but with the same id are also added
+//  shuttle->AddInputFile(AliTestShuttle::kDAQ, "DET", "PEDESTALS", "GDC", "file1.root");
+//  shuttle->AddInputFile(AliTestShuttle::kDAQ, "DET", "DRIFTVELOCITY", "LDC0", "file2a.root");
+//  shuttle->AddInputFile(AliTestShuttle::kDAQ, "DET", "DRIFTVELOCITY", "LDC1", "file2b.root");
+//  shuttle->AddInputFile(AliTestShuttle::kDAQ, "DET", "DRIFTVELOCITY", "LDC2", "file2b.root");
+
+  shuttle->AddInputFile(AliTestShuttle::kDAQ,"MUON","PEDESTALS","LDC0","$ALICE_ROOT/MUON/data/LDC0.ped");
+  shuttle->AddInputFile(AliTestShuttle::kDAQ,"MUON","PEDESTALS","LDC1","$ALICE_ROOT/MUON/data/LDC1.ped");
+  shuttle->AddInputFile(AliTestShuttle::kDAQ,"MUON","PEDESTALS","LDC2","$ALICE_ROOT/MUON/data/LDC2.ped");
+  shuttle->AddInputFile(AliTestShuttle::kDAQ,"MUON","PEDESTALS","LDC3","$ALICE_ROOT/MUON/data/LDC3.ped");
+  
+  // TODO(3)
+  // Create the preprocessor that should be tested, it registers itself automatically to the shuttle
+//  AliPreprocessor* pp = new AliTestPreprocessor("DET", shuttle);
+  new AliMUONPreprocessor("MUON",shuttle);
+
+  shuttle->Print();
+  
+  // Test the preprocessor
+  shuttle->Process();
+
+  // TODO(4)
+  // In the preprocessor AliShuttleInterface::Store should be called to put the final
+  // data to the CDB. To check if all went fine have a look at the files produced in
+  // $ALICE_ROOT/SHUTTLE/TestShuttle/TestCDB/<detector>/SHUTTLE/Data
+  //
+  // Check the file which should have been created
+//  AliCDBEntry* entry = AliCDBManager::Instance()->Get("DET/SHUTTLE/Data", 7);
+//  if (!entry)
+//  {
+//    printf("The file is not there. Something went wrong.\n");
+//    return;
+//  }
+//
+//  AliTestDataDCS* output = dynamic_cast<AliTestDataDCS*> (entry->GetObject());
+//  // If everything went fine, draw the result
+//  if (output)
+//    output->Draw();
+}
diff --git a/MUON/libMUONshuttle.pkg b/MUON/libMUONshuttle.pkg
new file mode 100644 (file)
index 0000000..ecbfd24
--- /dev/null
@@ -0,0 +1,18 @@
+# $Id$
+
+SRCS:= \
+AliMUONPreprocessor.cxx \
+AliMUONVSubprocessor.cxx \
+AliMUONPedestalSubprocessor.cxx \
+AliMUON2DStoreValidator.cxx \
+AliMUONPedestalEventGenerator.cxx \
+AliMUONCheckItem.cxx \
+AliMUONCheckItemIterator.cxx
+
+HDRS:= $(SRCS:.cxx=.h)
+
+DHDR:= MUONshuttleLinkDef.h
+
+EINCLUDE := MUON/mapping
+
+