**************************************************************************/
// $Id$
+
+//-----------------------------------------------------------------------------
/// \class AliMUONPadStatusMapMaker
///
-/// Convert a pad status container into a pad status *map* container
+/// Convert a pad statuses into pad status maps.
///
/// A pad status is one 32-bits word describing whether this pad pedestal, gains
/// hv is correct or not.
/// If a pad is at a physical boundary, is will for sure have some bits at 1
/// (i.e. a non-existing neighbour is considered = bad).
///
-// author Laurent Aphecetche
+///
+/// add something about the reject list/probabilities here... (LA)
+///
+/// \author Laurent Aphecetche
+//-----------------------------------------------------------------------------
#include "AliMUONPadStatusMapMaker.h"
+#include "AliCodeTimer.h"
#include "AliLog.h"
+#include "AliMpDDLStore.h"
+#include "AliMpDetElement.h"
+#include "AliMpManuIterator.h"
#include "AliMUON2DMap.h"
-#include "AliMUONCalibParam1I.h"
-#include "AliMUONObjectPair.h"
-#include "AliMUONV2DStore.h"
+#include "AliMUONCalibParamNF.h"
+#include "AliMUONCalibParamNI.h"
+#include "AliMUONCalibrationData.h"
+#include "AliMUONPadStatusMaker.h"
+#include "AliMUONRejectList.h"
#include "AliMUONVCalibParam.h"
-#include "AliMUONVDataIterator.h"
-#include "AliMpArea.h"
+#include "AliMUONVStore.h"
#include "AliMpConstants.h"
-#include "AliMpDEManager.h"
-#include "AliMpManuList.h"
-#include "AliMpPad.h"
-#include "AliMpSegmentation.h"
-#include "AliMpStationType.h"
-#include "AliMpVPadIterator.h"
-#include "AliMpVSegmentation.h"
#include <Riostream.h>
-#include <TMath.h>
-#include <TObjArray.h>
-#include <TStopwatch.h>
#include <TList.h>
-#include <map>
-#include <utility>
+#include "TRandom.h"
+#include <cassert>
+/// \cond CLASSIMP
ClassImp(AliMUONPadStatusMapMaker)
+/// \endcond
Int_t AliMUONPadStatusMapMaker::fgkSelfDead = 1;
-namespace
-{
- Bool_t IsZero(Double_t x)
- {
- return TMath::Abs(x) < AliMpConstants::LengthTolerance();
- }
-}
-
//_____________________________________________________________________________
-AliMUONPadStatusMapMaker::AliMUONPadStatusMapMaker()
+AliMUONPadStatusMapMaker::AliMUONPadStatusMapMaker(const AliMUONPadStatusMaker& padStatusMaker,
+ Int_t mask,
+ Bool_t deferredInitialization)
: TObject(),
-fStatus(0x0),
-fMask(0),
-fSegmentation(0x0),
-fTimerComputeStatusMap(0x0)
+fkStatusMaker(padStatusMaker),
+fMask(mask),
+fStatusMap(new AliMUON2DMap(true)),
+fRejectProbabilities(new AliMUON2DMap(true)),
+fRejectList(0x0),
+fComputeOnDemand(deferredInitialization)
{
/// ctor
-}
-
-//_____________________________________________________________________________
-AliMUONPadStatusMapMaker::~AliMUONPadStatusMapMaker()
-{
- /// dtor
- delete fTimerComputeStatusMap;
-}
-
-//_____________________________________________________________________________
-Int_t
-AliMUONPadStatusMapMaker::ComputeStatusMap(const TObjArray& neighbours,
- Int_t detElemId) const
-{
- /// Given a list of neighbours of one pad (which includes the pad itself)
- /// compute the status map (aka deadmap) for that pad.
-
- fTimerComputeStatusMap->Start(kFALSE);
+ if (!deferredInitialization)
+ {
+ AliCodeTimerAuto("Computing complete status map at once",0);
+ AliMUONVStore* neighboursStore = padStatusMaker.NeighboursStore();
+ AliMUONVCalibParam* param;
+ TIter next(neighboursStore->CreateIterator());
+ while ( ( param = static_cast<AliMUONVCalibParam*>(next()) ) )
+ {
+ Int_t detElemId = param->ID0();
+ Int_t manuId = param->ID1();
+ ComputeStatusMap(detElemId,manuId);
+ }
+ }
- Int_t statusMap(0);
+ /// Whatever the deferred flag is, we *have* to compute the reject
+ /// probabilities here and now, for *all* channels.
- //Compute the statusmap related to the status of neighbouring
- //pads. An invalid pad means "outside of edges".
- Int_t i(0);
- TIter next(&neighbours);
- AliMpPad* p;
+ AliMUONRejectList* rl = padStatusMaker.CalibrationData().RejectList();
- while ( ( p = static_cast<AliMpPad*>(next()) ) )
+ if (rl)
{
- Int_t status = 0;
- if ( !p->IsValid() )
+ AliMpManuIterator it;
+ Int_t detElemId;
+ Int_t manuId;
+
+ while ( it.Next(detElemId,manuId) )
{
- status = -1;
+ AliMpDetElement* de = AliMpDDLStore::Instance()->GetDetElement(detElemId);
+ Int_t busPatchId = AliMpDDLStore::Instance()->GetBusPatchId(detElemId,manuId);
+
+ AliMUONVCalibParam* param = new AliMUONCalibParamNF(1,AliMpConstants::ManuNofChannels(),detElemId,manuId,0);
+
+ Int_t n(0);
+
+ for ( Int_t i = 0; i < AliMpConstants::ManuNofChannels(); ++i )
+ {
+ Float_t proba(0.0);
+
+ if ( de->IsConnectedChannel(manuId,i) )
+ {
+ proba = TMath::Max(rl->DetectionElementProbability(detElemId),rl->BusPatchProbability(busPatchId));
+
+ proba = TMath::Max(proba,rl->ManuProbability(detElemId,manuId));
+
+ proba = TMath::Max(proba,rl->ChannelProbability(detElemId,manuId,i));
+
+ if ( proba > 0 )
+ {
+ ++n;
+ param->SetValueAsFloat(i,0,proba);
+ }
+ }
+ }
+
+ if ( n > 0 )
+ {
+ fRejectProbabilities->Add(param);
+ }
+ else
+ {
+ // no need to add empty stuff...
+ delete param;
+ }
}
- else
+
+ if ( rl->IsBinary())
{
- status = GetPadStatus(detElemId,*p);
+ fRejectList = fRejectProbabilities;
+ fRejectProbabilities = 0x0;
+ AliDebug(1,"RejectList = RejectProbabilities");
+ StdoutToAliDebug(1,fRejectList->Print("","MEAN"));
}
- if ( ( fMask==0 && status !=0 ) || ( (status & fMask) != 0 ) )
+ else
{
- statusMap |= (1<<i);
+ AliWarning("Will run with non trivial survival probabilities for channels, manus, etc... Better check this is a simulation and not real data !");
+ fRejectList = new AliMUON2DMap(true);
}
- ++i;
}
-
- fTimerComputeStatusMap->Stop();
- return statusMap;
-}
-
-//_____________________________________________________________________________
-Int_t
-AliMUONPadStatusMapMaker::GetPadStatus(Int_t detElemId,
- const AliMpPad& pad) const
-{
- /// Get the pad status
- Int_t manuId = pad.GetLocation().GetFirst();
- Int_t manuChannel = pad.GetLocation().GetSecond();
- AliMUONVCalibParam* param = static_cast<AliMUONVCalibParam*>(fStatus->Get(detElemId,manuId));
- return param->ValueAsInt(manuChannel);
+ else
+ {
+ fRejectList = fRejectProbabilities;
+ fRejectProbabilities = 0x0;
+ AliInfo("No RejectList found, so no RejectList will be used.");
+ }
}
//_____________________________________________________________________________
-Bool_t
-AliMUONPadStatusMapMaker::IsValid(const AliMpPad& pad,
- const TVector2& shift) const
+AliMUONPadStatusMapMaker::~AliMUONPadStatusMapMaker()
{
- /// Whether pad.Position()+shift is within the detector
- TVector2 testPos = pad.Position() - pad.Dimensions() + shift;
- AliMpPad p = fSegmentation->PadByPosition(testPos,kFALSE);
- return p.IsValid();
+ /// dtor
+ delete fStatusMap;
+ delete fRejectProbabilities;
+ delete fRejectList;
}
//_____________________________________________________________________________
-AliMUONV2DStore*
-AliMUONPadStatusMapMaker::MakeEmptyPadStatusMap()
+AliMUONVCalibParam*
+AliMUONPadStatusMapMaker::ComputeStatusMap(Int_t detElemId, Int_t manuId) const
{
- AliMUONV2DStore* padStatusMap = new AliMUON2DMap(kTRUE);
+ /// Compute the status map for a given manu, and add it to our internal
+ /// fStatusMap internal storage
- TList* list = AliMpManuList::ManuList();
+ AliCodeTimerAuto("(Int_t,Int_t)",0)
+
+ AliMUONVCalibParam* param = new AliMUONCalibParamNI(1,AliMpConstants::ManuNofChannels(),
+ detElemId,manuId,-1);
+
+ Bool_t ok = fStatusMap->Add(param);
+ if (!ok)
+ {
+ AliFatal(Form("Could not add manu %d of de %d",manuId,detElemId));
+ }
+
+ AliMUONVCalibParam* neighbours = fkStatusMaker.Neighbours(detElemId,manuId);
- AliMpIntPair* pair;
+ AliMUONVCalibParam* statusParam = fkStatusMaker.PadStatus(detElemId,manuId);
- TIter next(list);
+ Int_t n = neighbours->Dimension();
- while ( ( pair = static_cast<AliMpIntPair*>(next()) ) )
+ for ( Int_t manuChannel = 0; manuChannel < param->Size(); ++manuChannel )
{
- Int_t detElemId = pair->GetFirst();
- Int_t manuId = pair->GetSecond();
- padStatusMap->Set(detElemId,manuId,new AliMUONCalibParam1I(64,0),kFALSE);
+ Int_t statusMap(0);
+
+ Int_t x = neighbours->ValueAsIntFast(manuChannel,0);
+ if ( x < 0 )
+ {
+ // channel is not a valid one (i.e. (manuId,manuChannel) is not an existing pad)
+ statusMap = -1;//fgkSelfDead;
+ continue;
+ }
+
+ for ( Int_t i = 0; i < n; ++i )
+ {
+ // Compute the statusmap related to the status of neighbouring
+ // pads. An invalid pad means "outside of edges".
+
+ Int_t y = neighbours->ValueAsIntFast(manuChannel,i);
+ Int_t m,c;
+ neighbours->UnpackValue(y,m,c);
+ if ( c < 0 ) continue;
+ Int_t status = 0;
+ if ( !m )
+ {
+ status = -1;
+ }
+ else
+ {
+ status = statusParam->ValueAsIntFast(c); //fkStatusMaker.PadStatus(detElemId,m,c);
+ }
+ if ( ( fMask==0 && status !=0 ) || ( (status & fMask) != 0 ) )
+ {
+ statusMap |= (1<<i);
+ }
+ }
+ param->SetValueAsIntFast(manuChannel,0,statusMap);
}
-
- delete list;
-
- return padStatusMap;
+ return param;
}
//_____________________________________________________________________________
-AliMUONV2DStore*
-AliMUONPadStatusMapMaker::MakePadStatusMap(const AliMUONV2DStore& status,
- Int_t mask)
+void
+AliMUONPadStatusMapMaker::RefreshRejectProbabilities()
{
- /// Given the status store for all pads, compute a status map store
- /// for all pads.
- /// @param mask is the status mask to be tested to tell if a pad is ok or not
-
- fStatus = &status;
- fMask = mask;
+ /// From the (fixed) fRejectProbabilities, compute
+ /// a fRejectList that will be valid for one event
+ /// If fRejectProbabilities=0x0 it means we're dealing with
+ /// trivial probabilities (0 or 1) and those are assumed to be already
+ /// in fRejectList then.
- AliMpExMap chamberTimers(kTRUE);
- fTimerComputeStatusMap = new TStopwatch;
- fTimerComputeStatusMap->Start(kTRUE);
- fTimerComputeStatusMap->Stop();
+ if ( !fRejectProbabilities ) return;
- TStopwatch timer;
+ AliCodeTimerAuto("",0);
- timer.Start(kTRUE);
+ fRejectList->Clear();
- AliMUONV2DStore* statusMap = status.CloneEmpty();
+ TIter next(fRejectProbabilities->CreateIterator());
+ AliMUONVCalibParam* paramProba;
+ AliMUONVCalibParam* paramReject;
- AliMUONVDataIterator* it = status.Iterator();
- AliMUONObjectPair* pair;
-
- while ( ( pair = static_cast<AliMUONObjectPair*>(it->Next()) ) )
+ while ( ( paramProba = static_cast<AliMUONVCalibParam*>(next()) ) )
{
- AliMpIntPair* ip = static_cast<AliMpIntPair*>(pair->First());
-
- Int_t detElemId = ip->GetFirst();
+ paramReject = new AliMUONCalibParamNF(1,paramProba->Size(),paramProba->ID0(),paramProba->ID1(),0.0);
- Int_t manuId = ip->GetSecond();
- Int_t chamber = AliMpDEManager::GetChamberId(detElemId);
+ Int_t n(0);
- TStopwatch* chTimer = static_cast<TStopwatch*>(chamberTimers.GetValue(chamber));
- if (!chTimer)
+ for ( Int_t i = 0; i < paramProba->Size(); ++i )
{
- chTimer = new TStopwatch;
- chTimer->Start(kTRUE);
- chTimer->Stop();
- chamberTimers.Add(chamber,chTimer);
- }
-
- chTimer->Start(kFALSE);
-
- const AliMpVSegmentation* seg =
- AliMpSegmentation::Instance()->GetMpSegmentationByElectronics(detElemId,manuId);
- fSegmentation = seg;
-
- AliMUONVCalibParam* statusEntry = static_cast<AliMUONVCalibParam*>(pair->Second());
-
- AliMUONVCalibParam* statusMapEntry = static_cast<AliMUONVCalibParam*>
- (statusMap->Get(detElemId,manuId));
-
- if (!statusMapEntry)
- {
- statusMapEntry = new AliMUONCalibParam1I(64,0);
- statusMap->Set(detElemId,manuId,statusMapEntry,false);
- }
-
- for ( Int_t manuChannel = 0; manuChannel < statusEntry->Size(); ++manuChannel )
- {
- // Loop over channels and for each channel loop on its immediate neighbours
- // to produce a statusMap word for this channel.
-
- AliMpPad pad = seg->PadByLocation(AliMpIntPair(manuId,manuChannel),kFALSE);
+ Float_t proba = paramProba->ValueAsFloat(i);
+ Float_t x(proba);
- Int_t statusMapValue(0);
-
- if ( pad.IsValid() )
+ if ( proba > 0.0 && proba < 1.0 )
{
- TObjArray neighbours;
- neighbours.SetOwner(kTRUE);
- fSegmentation->GetNeighbours(pad,neighbours,true,true);
- statusMapValue = ComputeStatusMap(neighbours,detElemId);
+ x = gRandom->Rndm();
+ proba = ( x < proba ) ? 1.0 : 0.0;
}
- else
+
+ if (proba>0.0)
{
- statusMapValue = fgkSelfDead;
+ ++n;
+ paramReject->SetValueAsFloat(i,0,proba);
}
- statusMapEntry->SetValueAsInt(manuChannel,0,statusMapValue);
}
- chTimer->Stop();
+ if (n) fRejectList->Add(paramReject);
}
+}
+
+//_____________________________________________________________________________
+Int_t
+AliMUONPadStatusMapMaker::StatusMap(Int_t detElemId, Int_t manuId,
+ Int_t manuChannel) const
+
+{
+ /// Get the pad status map
- delete it;
+ AliMUONVCalibParam* param = static_cast<AliMUONVCalibParam*>(fStatusMap->FindObject(detElemId,manuId));
+ if (!param)
+ {
+ if ( fComputeOnDemand )
+ {
+ // not yet computed, so do it now
+ param = ComputeStatusMap(detElemId,manuId);
+ }
+ else
+ {
+ // we're locked. probably a bad manuId ?
+ return fgkSelfDead;
+ }
+ }
- TExMapIter cit = chamberTimers.GetIterator();
+ Int_t statusMap = param->ValueAsInt(manuChannel);
- Long_t key, value;
+ AliMUONVCalibParam* r = static_cast<AliMUONVCalibParam*>(fRejectList->FindObject(detElemId,manuId));
- while ( cit.Next(key,value) )
+ if (r)
{
- TStopwatch* t = reinterpret_cast<TStopwatch*>(value);
- cout << Form("Chamber %2ld CPU time/manu %5.0f ms ",key,t->CpuTime()*1e3/t->Counter());
- t->Print();
- }
+ Float_t v= r->ValueAsFloat(manuChannel);
+
+ assert (v==0.0 || v==1.0 );
- cout << "ComputeStatusMap timer : ";
- fTimerComputeStatusMap->Print();
- cout<< endl;
-
- cout << "MakePadStatusMap total timer : ";
- timer.Print();
- cout << endl;
+ if ( v > 0 )
+ {
+ statusMap |= fgkSelfDead;
+ }
+ }
return statusMap;
+
}
-