From: ivana Date: Fri, 20 Oct 2006 15:52:22 +0000 (+0000) Subject: New classes for shuttle (Laurent) X-Git-Url: http://git.uio.no/git/?a=commitdiff_plain;h=ea199e3323227b3b3b8ef38f428c172b1e0eb413;hp=4465b13c11cf8805c1db1abd0d0fda893f24ab14;p=u%2Fmrichter%2FAliRoot.git New classes for shuttle (Laurent) --- diff --git a/MUON/AliMUON2DStoreValidator.cxx b/MUON/AliMUON2DStoreValidator.cxx new file mode 100644 index 00000000000..e082b611916 --- /dev/null +++ b/MUON/AliMUON2DStoreValidator.cxx @@ -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(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(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(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(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(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(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(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(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 index 00000000000..f0b9e39f14c --- /dev/null +++ b/MUON/AliMUON2DStoreValidator.h @@ -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 index 00000000000..730bf4ae8a3 --- /dev/null +++ b/MUON/AliMUONCheckItem.cxx @@ -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(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(" %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 index 00000000000..49e5e85bcae --- /dev/null +++ b/MUON/AliMUONCheckItem.h @@ -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 index 00000000000..54a5d56fb50 --- /dev/null +++ b/MUON/AliMUONCheckItemIterator.cxx @@ -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(value); + } + else + { + return 0x0; + } +} diff --git a/MUON/AliMUONCheckItemIterator.h b/MUON/AliMUONCheckItemIterator.h new file mode 100644 index 00000000000..05a330807ab --- /dev/null +++ b/MUON/AliMUONCheckItemIterator.h @@ -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 index 00000000000..b55cd1c10a2 --- /dev/null +++ b/MUON/AliMUONObjectPair.cxx @@ -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 ;-) +/// +/// 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 index 00000000000..9025e7a8220 --- /dev/null +++ b/MUON/AliMUONObjectPair.h @@ -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 ;-) +/// +// 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; ///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(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(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 index 00000000000..3998ce2e218 --- /dev/null +++ b/MUON/AliMUONPedestalEventGenerator.h @@ -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 index 00000000000..c1fdebe6f3b --- /dev/null +++ b/MUON/AliMUONPedestalSubprocessor.cxx @@ -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 +#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(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(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(it->Next() ) ) ) + { + AliMUONVCalibParam* value = static_cast(p->Value()); + value->Print(opt); + } +} diff --git a/MUON/AliMUONPedestalSubprocessor.h b/MUON/AliMUONPedestalSubprocessor.h new file mode 100644 index 00000000000..d87466fb7a4 --- /dev/null +++ b/MUON/AliMUONPedestalSubprocessor.h @@ -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 index 00000000000..b969f155941 --- /dev/null +++ b/MUON/AliMUONPreprocessor.cxx @@ -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 << " 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(fSubprocessors->At(i)); + } + return 0x0; +} diff --git a/MUON/AliMUONPreprocessor.h b/MUON/AliMUONPreprocessor.h new file mode 100644 index 00000000000..deeb3c9de48 --- /dev/null +++ b/MUON/AliMUONPreprocessor.h @@ -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 index 00000000000..0866ff61876 --- /dev/null +++ b/MUON/AliMUONVSubprocessor.cxx @@ -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 index 00000000000..0078833373d --- /dev/null +++ b/MUON/AliMUONVSubprocessor.h @@ -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 index 00000000000..d1586cbe37c --- /dev/null +++ b/MUON/MUONshuttleLinkDef.h @@ -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 index 00000000000..cb76ef200b9 --- /dev/null +++ b/MUON/TestMUONPreprocessor.C @@ -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(, , , , ) + // 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//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 (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 index 00000000000..ecbfd242708 --- /dev/null +++ b/MUON/libMUONshuttle.pkg @@ -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 + +