/// \author Diego Stocco (Torino)
#include "AliMUONTriggerChamberEff.h"
-#include "AliMUONDigit.h"
+#include "AliMUONVDigit.h"
#include "AliMUONConstants.h"
-#include "AliMUONGlobalTrigger.h"
-#include "AliMUONGeometryTransformer.h"
-#include "AliMUONSegmentation.h"
-#include "AliMUON.h"
-#include "AliMUONData.h"
#include "AliMUONTriggerTrack.h"
+#include "AliMUONDigitMaker.h"
+#include "AliMUONLocalTrigger.h"
+#include "AliMUONGeometryTransformer.h"
+
+#include "AliMUONTrack.h"
+#include "AliMUONTrackParam.h"
+#include "AliMUONTrackExtrap.h"
+
+#include "AliMUONDigitStoreV1.h"
+#include "AliMUONVDigitStore.h"
+#include "AliMUONVTriggerStore.h"
+#include "AliMUONVTriggerTrackStore.h"
+#include "AliMUONVTrackStore.h"
#include "AliMpVSegmentation.h"
#include "AliMpSegmentation.h"
#include "AliMpPad.h"
#include "AliMpDEIterator.h"
#include "AliMpPlaneType.h"
+#include "AliMpDEManager.h"
-#include "AliRunLoader.h"
-#include "AliRun.h"
+#include "AliLog.h"
#include <Riostream.h>
#include <TFile.h>
#include <TH1F.h>
#include <TMath.h>
+#include <TSeqCollection.h>
+#include <TTree.h>
+#include <TROOT.h>
+
+
/// \cond CLASSIMP
ClassImp(AliMUONTriggerChamberEff)
/// \endcond
+
//_____________________________________________________________________________
-AliMUONTriggerChamberEff::AliMUONTriggerChamberEff(const char* galiceFile,
- Int_t firstEvent, Int_t lastEvent)
+AliMUONTriggerChamberEff::AliMUONTriggerChamberEff()
: TObject(),
- fFirstEvent(firstEvent),
- fLastEvent(lastEvent),
- fFirstRun(-1),
- fLastRun(-1),
- fRunLoader(0x0),
- fData(0x0),
+ fTransformer(0x0),
+ fDigitMaker(0x0),
fReproduceTrigResponse(kFALSE),
fPrintInfo(kFALSE),
- fMUON(0x0),
+ fWriteOnESD(kFALSE),
fDebugLevel(0),
- fGaliceDir(0x0)
+ fkMaxDistance(99999.)
{
/// Standard constructor
- SetGaliceFile(galiceFile);
ResetArrays();
}
+
//_____________________________________________________________________________
-AliMUONTriggerChamberEff::AliMUONTriggerChamberEff(Int_t firstRun, Int_t lastRun,
- const char* galiceRunDir,
- Int_t firstEvent, Int_t lastEvent)
+AliMUONTriggerChamberEff::AliMUONTriggerChamberEff(const AliMUONGeometryTransformer* transformer,
+ const AliMUONDigitMaker* digitMaker,
+ Bool_t writeOnESD)
: TObject(),
- fFirstEvent(firstEvent),
- fLastEvent(lastEvent),
- fFirstRun(firstRun),
- fLastRun(lastRun),
- fRunLoader(0x0),
- fData(0x0),
+ fTransformer(transformer),
+ fDigitMaker(digitMaker),
fReproduceTrigResponse(kFALSE),
fPrintInfo(kFALSE),
- fMUON(0x0),
+ fWriteOnESD(writeOnESD),
fDebugLevel(0),
- fGaliceDir(galiceRunDir)
+ fkMaxDistance(99999.)
{
+/// Standard constructor
ResetArrays();
- delete gAlice;
}
+
//_____________________________________________________________________________
AliMUONTriggerChamberEff::~AliMUONTriggerChamberEff()
{
/// Destructor
- fRunLoader->UnloadAll();
- delete fRunLoader;
- delete fData;
+ Bool_t writeOnESD=fWriteOnESD;
+ fWriteOnESD=kFALSE;
+ if(writeOnESD) SaveInESDFile();
}
+
//_____________________________________________________________________________
-void AliMUONTriggerChamberEff::SetGaliceFile(const char *galiceFile)
+AliMUONTriggerChamberEff::AliMUONTriggerChamberEff(const AliMUONTriggerChamberEff& other)
+ :TObject(other),
+ fTransformer(0x0),
+ fDigitMaker(0x0),
+ fReproduceTrigResponse(other.fReproduceTrigResponse),
+ fPrintInfo(other.fPrintInfo),
+ fWriteOnESD(other.fWriteOnESD),
+ fDebugLevel(other.fDebugLevel),
+ fkMaxDistance(other.fkMaxDistance)
{
- //
- /// Opens the galice.root and loads tracks and digits.
- //
-
- fRunLoader = AliRunLoader::Open(galiceFile,"MUONFolder","READ");
- if (!fRunLoader)
- {
- AliError(Form("Error opening %s file \n",galiceFile));
- }
- else
- {
- fRunLoader->LoadgAlice();
- gAlice = fRunLoader->GetAliRun();
- fMUON = (AliMUON*)gAlice->GetModule("MUON");
-
- if(fLastEvent<=0 || fLastEvent>fRunLoader->GetNumberOfEvents())fLastEvent = fRunLoader->GetNumberOfEvents()-1;
- if(fFirstEvent<0)fFirstEvent=0;
-
-
- AliLoader* loader = fRunLoader->GetLoader("MUONLoader");
- if ( loader )
- {
- fData = new AliMUONData(loader,"MUON","MUON");
- loader->LoadTracks("READ");
- loader->LoadDigits("READ");
- }
- else
- {
- AliError(Form("Could get MUONLoader"));
+ for(Int_t ch=0; ch<fgkNchambers; ch++){
+ for(Int_t cath=0; cath<fgkNcathodes; cath++){
+ fTrigger34[ch][cath] = other.fTrigger34[ch][cath];
+ fTrigger44[cath] = other.fTrigger44[cath];
+ for(Int_t slat=0; slat<fgkNslats; slat++){
+ fInefficientSlat[ch][cath][slat] = other.fInefficientSlat[ch][cath][slat];
+ fHitPerSlat[ch][cath][slat] = other.fHitPerSlat[ch][cath][slat];
+ }
+ for(Int_t board=0; board<fgkNboards; board++){
+ fInefficientBoard[ch][cath][board] = other.fInefficientBoard[ch][cath][board];
+ fHitPerBoard[ch][cath][board] = other.fHitPerBoard[ch][cath][board];
+ }
}
}
}
+
//_____________________________________________________________________________
-void AliMUONTriggerChamberEff::CleanGalice()
+AliMUONTriggerChamberEff& AliMUONTriggerChamberEff::operator=(const AliMUONTriggerChamberEff& other)
{
- //
- /// Unload all loaded data
- //
-
- fRunLoader->UnloadAll();
- delete fRunLoader;
- fRunLoader = 0;
+ /// Asignment operator
+ // check assignement to self
+ if (this == &other)
+ return *this;
+
+ // base class assignement
+ TObject::operator=(other);
+
+ fTransformer = 0x0;
+ fDigitMaker = 0x0;
+ fReproduceTrigResponse = other.fReproduceTrigResponse;
+ fPrintInfo = other.fPrintInfo;
+ fWriteOnESD = other.fWriteOnESD;
+ fDebugLevel = other.fDebugLevel;
+ //fkMaxDistance = other.fkMaxDistance;
+ return *this;
}
+
//_____________________________________________________________________________
void AliMUONTriggerChamberEff::ResetArrays()
{
fInefficientSlat[ch][cath][slat] = 0;
fHitPerSlat[ch][cath][slat] = 0;
}
+ for(Int_t board=0; board<fgkNboards; board++){
+ fInefficientBoard[ch][cath][board] = 0;
+ fHitPerBoard[ch][cath][board] = 0;
+ }
}
}
}
+//______________________________________________________________________________
+Bool_t
+AliMUONTriggerChamberEff::TriggerDigits(const AliMUONVTriggerStore& triggerStore,
+ AliMUONVDigitStore& digitStore) const
+{
+ //
+ /// make (S)Digit for trigger
+ //
+ digitStore.Clear();
+
+ AliMUONLocalTrigger* locTrg;
+ TIter next(triggerStore.CreateLocalIterator());
+
+ while ( ( locTrg = static_cast<AliMUONLocalTrigger*>(next()) ) )
+ {
+ if (locTrg->IsNull()) continue;
+
+ TArrayS xyPattern[2];
+ locTrg->GetXPattern(xyPattern[0]);
+ locTrg->GetYPattern(xyPattern[1]);
+
+ Int_t nBoard = locTrg->LoCircuit();
+ fDigitMaker->TriggerDigits(nBoard, xyPattern, digitStore);
+ }
+ return kTRUE;
+}
+
+
//_____________________________________________________________________________
-void AliMUONTriggerChamberEff::InfoDigit()
+void AliMUONTriggerChamberEff::InfoDigit(AliMUONVDigitStore& digitStore)
{
//
/// Prints information on digits (for debugging)
//
-
- AliMUONDigit * mDigit=0x0;
- Int_t firstTrigCh = AliMUONConstants::NTrackingCh();
- // Addressing
- Int_t nchambers = AliMUONConstants::NCh();
- fData->SetTreeAddress("D,GLT");
+ TIter next(digitStore.CreateIterator());
+ AliMUONVDigit* mDigit=0x0;
- fData->GetDigits();
- // Loop on chambers
- for(Int_t ichamber=firstTrigCh; ichamber<nchambers; ichamber++) {
- TClonesArray* digits = fData->Digits(ichamber);
- digits->Sort();
- Int_t ndigits = (Int_t)digits->GetEntriesFast();
- for(Int_t idigit=0; idigit<ndigits; idigit++) {
- mDigit = (AliMUONDigit*)digits->At(idigit);
- mDigit->Print();
- } // end digit loop
- } // end chamber loop
- fData->ResetDigits();
+ while ( ( mDigit = static_cast<AliMUONVDigit*>(next()) ) )
+ {
+ mDigit->Print();
+ } // end digit loop
+ printf("\n");
}
//_____________________________________________________________________________
-Bool_t AliMUONTriggerChamberEff::PadMatchTrack(Float_t xPad, Float_t yPad, Float_t dpx, Float_t dpy,
- Float_t xTrackAtPad, Float_t yTrackAtPad, Int_t chamber)
+Int_t AliMUONTriggerChamberEff::MatchingPad(AliMUONVDigitStore& digitStore, Int_t &detElemId,
+ Float_t coor[2], Bool_t isMatch[fgkNcathodes],
+ Int_t nboard[fgkNcathodes][4],
+ Float_t zRealMatch[fgkNchambers], Float_t y11)
{
//
- /// Decides if the digit belongs to the trigger track.
+ /// Check slat and board number of digit matching track
//
- Float_t numOfHalfWidth = 5.;
- Bool_t match = kFALSE;
- Float_t maxDistX = dpx;
- if(fReproduceTrigResponse && chamber>=2) maxDistX = 3.*dpx;// Non-bending plane: check the +- 1 strip between stations
- if(!fReproduceTrigResponse)maxDistX = numOfHalfWidth*dpx;
- Float_t maxDistY = dpy;
- if(fReproduceTrigResponse && chamber%2) maxDistY = 3*dpy;// bending plane: check the +- 1 strip between planes in the same station
- if(!fReproduceTrigResponse) maxDistY = numOfHalfWidth*dpy;
- Float_t deltaX = TMath::Abs(xPad-xTrackAtPad);
- Float_t deltaY = TMath::Abs(yPad-yTrackAtPad);
- if(deltaX<=maxDistX && deltaY<=maxDistY)match = kTRUE;
- return match;
-}
+ enum {kBending, kNonBending};
+
+ Float_t minMatchDist[fgkNcathodes];
+ Int_t padsInCheckArea[fgkNcathodes];
+
+ for(Int_t cath=0; cath<fgkNcathodes; cath++){
+ isMatch[cath] = kFALSE;
+ minMatchDist[cath] = fkMaxDistance/10.;
+ padsInCheckArea[cath] = 0;
+ }
+ Int_t iChamber = AliMpDEManager::GetChamberId(detElemId);
+ Int_t ch = iChamber-10;
+ Float_t oldDeltaZ = AliMUONConstants::DefaultChamberZ(iChamber) - AliMUONConstants::DefaultChamberZ(10);
+ Float_t y = coor[1];
+ Int_t iSlat = detElemId%100;
+ Int_t trigDigitBendPlane = -1;
+ Int_t foundDetElemId = detElemId;
+ Float_t foundZmatch=999.;
+ Float_t yCoorAtPadZ=999.;
+
+ TIter next(digitStore.CreateIterator());
+ AliMUONVDigit* mDigit;
+ Int_t idigit=0;
+
+ while ( ( mDigit = static_cast<AliMUONVDigit*>(next()) ) )
+ {
+ idigit++;
+ Int_t currDetElemId = mDigit->DetElemId();
+ Int_t currCh = AliMpDEManager::GetChamberId(currDetElemId);
+ if(currCh!=iChamber) continue;
+ Int_t currSlat = currDetElemId%100;
+ Int_t slatDiff = TMath::Abs(currSlat-iSlat);
+ if(slatDiff>1 && slatDiff<17) continue; // Check neighbour slats
+ Int_t cathode = mDigit->Cathode();
+ Int_t ix = mDigit->PadX();
+ Int_t iy = mDigit->PadY();
+ Float_t xpad, ypad, zpad;
+ const AliMpVSegmentation* seg = AliMpSegmentation::Instance()
+ ->GetMpSegmentation(currDetElemId,AliMp::GetCathodType(cathode));
+
+ AliMpPad pad = seg->PadByIndices(AliMpIntPair(ix,iy),kTRUE);
+ Float_t xlocal1 = pad.Position().X();
+ Float_t ylocal1 = pad.Position().Y();
+ Float_t dpx = pad.Dimensions().X();
+ Float_t dpy = pad.Dimensions().Y();
+ fTransformer->Local2Global(currDetElemId, xlocal1, ylocal1, 0, xpad, ypad, zpad);
+ if(fDebugLevel>2)printf("DetElemId = %i\tCathode = %i\t(x,y) Pad = (%i,%i) = (%.2f,%.2f)\tDim = (%.2f,%.2f)\tTrack = (%.2f,%.2f)\n",currDetElemId,cathode,ix,iy,xpad,ypad,dpx,dpy,coor[0],coor[1]);
+ // searching track intersection with chambers (second approximation)
+ if(ch%2==1){
+ //if(iChamber%2==1){
+ Float_t deltaZ = zpad - zRealMatch[0];
+ y = (coor[1]-y11)*deltaZ/oldDeltaZ + y11;
+ if(fDebugLevel>=3 && TMath::Abs(y-coor[1])>0.1)printf("oldDeltaZ = %7.2f newDeltaZ = %7.2f\toldY = %7.2f new y = %7.2f\n",oldDeltaZ,deltaZ,coor[1],y);
+ }
+ Float_t matchDist = PadMatchTrack(xpad, ypad, dpx, dpy, coor[0], y, ch);
+ if(matchDist<fkMaxDistance/2.) padsInCheckArea[cathode]++;
+ if(matchDist>minMatchDist[cathode])continue;
+ isMatch[cathode] = kTRUE;
+ minMatchDist[cathode] = matchDist;
+ foundDetElemId = currDetElemId;
+ foundZmatch=zpad;
+ yCoorAtPadZ=y;
+ if(cathode==kBending) trigDigitBendPlane = idigit;
+ for (Int_t loc=0; loc<pad.GetNofLocations(); loc++){
+ AliMpIntPair location = pad.GetLocation(loc);
+ nboard[cathode][loc] = location.GetFirst();
+ }
+ for(Int_t loc=pad.GetNofLocations(); loc<4; loc++){
+ nboard[cathode][loc]=-1;
+ }
+ }
+ for(Int_t cath=0; cath<fgkNcathodes; cath++){
+ if(padsInCheckArea[cath]>2) {
+ if(fDebugLevel>=1) printf("padsInCheckArea[%i] = %i\n",cath,padsInCheckArea[cath]);
+ return -500;
+ }
+ }
+
+ if(isMatch[kBending] || isMatch[kNonBending]){
+ detElemId = foundDetElemId;
+ zRealMatch[ch] = foundZmatch;
+ coor[1] = yCoorAtPadZ;
+ if(fDebugLevel>2){
+ Int_t whichCathode=kBending;
+ if(!isMatch[kBending])whichCathode=kNonBending;
+ }
+ }
+ return trigDigitBendPlane;
+}
//_____________________________________________________________________________
-Bool_t AliMUONTriggerChamberEff::IsDiffLocalBoard(Int_t currDetElemId, Int_t iy, Int_t detElemIdP1, Int_t iyDigitP1) const
+Float_t AliMUONTriggerChamberEff::PadMatchTrack(Float_t xPad, Float_t yPad,
+ Float_t dpx, Float_t dpy,
+ Float_t xTrackAtPad, Float_t yTrackAtPad,
+ Int_t chamber)
{
//
- /// Determins if the digits belong to the same local board.
- /// Used only if one wants to reproduce the trigger algorithm result.
- /// (fReproduceTrigResponse = kTRUE).
+ /// Decides if the digit belongs to the trigger track.
//
- Bool_t isDiff = kTRUE;
- if(detElemIdP1<0 || iyDigitP1<0)return kFALSE;
- Int_t currSlat = currDetElemId%100;
- Int_t slatP1 = detElemIdP1%100;
- Int_t currLoc = iy/16;
- Int_t locP1 = iyDigitP1/16;
- if(currSlat==slatP1 && currLoc==locP1)isDiff = kFALSE;
- return isDiff;
+ Float_t maxDist = 2.;//3. // cm
+ Float_t maxDistCheckArea = 6.; // cm
+
+ Float_t matchDist = fkMaxDistance;
+
+ Float_t deltaX = TMath::Abs(xPad-xTrackAtPad)-dpx;
+ Float_t deltaY = TMath::Abs(yPad-yTrackAtPad)-dpy;
+ Float_t maxDistX = maxDist;
+ Float_t maxDistY = maxDist;
+
+ if(fReproduceTrigResponse){
+ maxDistX = dpx;
+ maxDistY = dpy;
+ deltaX = TMath::Abs(xPad-xTrackAtPad);
+ deltaY = TMath::Abs(yPad-yTrackAtPad);
+ if(dpx<dpy && chamber>=2) maxDistX = 3.*dpx;// Non-bending plane: check the +- 1 strip between stations
+ if(dpy<dpx && chamber%2) maxDistY = 3.*dpy;// bending plane: check the +- 1 strip between planes in the same station
+ }
+
+ if(deltaX<=maxDistX && deltaY<=maxDistY) matchDist = TMath::Max(deltaX, deltaY);
+ else if(deltaX<=maxDistCheckArea && deltaY<=maxDistCheckArea) matchDist = fkMaxDistance/5.;
+ return matchDist;
}
//_____________________________________________________________________________
void AliMUONTriggerChamberEff::CalculateEfficiency(Int_t trigger44, Int_t trigger34,
- Float_t &efficiency, Float_t &error, Bool_t failuresAsInput)
+ Float_t &efficiency, Float_t &error,
+ Bool_t failuresAsInput)
{
//
/// Returns the efficiency.
//_____________________________________________________________________________
-Int_t AliMUONTriggerChamberEff::DetElemIdFromPos(Float_t x, Float_t y, Int_t chamber, Int_t cathode)
+Int_t AliMUONTriggerChamberEff::DetElemIdFromPos(Float_t x, Float_t y,
+ Int_t chamber, Int_t cathode)
{
//
/// Given the (x,y) position in the chamber,
Int_t resultingDetElemId = -1;
AliMpDEIterator it;
- const AliMUONGeometryTransformer *kGeomTransformer = fMUON->GetGeometryTransformer();
- AliMUONSegmentation *segmentation = fMUON->GetSegmentation();
+ Float_t minDist = 999.;
for ( it.First(chamber-1); ! it.IsDone(); it.Next() ){
Int_t detElemId = it.CurrentDEId();
+ Int_t ich = detElemId/100-10;
+ Float_t tolerance=0.2*((Float_t)ich);
+ Float_t currDist=9999.;
+
+ const AliMpVSegmentation* seg =
+ AliMpSegmentation::Instance()
+ ->GetMpSegmentation(detElemId,AliMp::GetCathodType(cathode));
+ if (!seg) continue;
+
+ Float_t deltax = seg->Dimensions().X();
+ Float_t deltay = seg->Dimensions().Y();
+ Float_t xlocal1 = -deltax;
+ Float_t ylocal1 = -deltay;
+ Float_t xlocal2 = +deltax;
+ Float_t ylocal2 = +deltay;
+ Float_t xg01, yg01, zg1, xg02, yg02, zg2;
+ fTransformer->Local2Global(detElemId, xlocal1, ylocal1, 0, xg01, yg01, zg1);
+ fTransformer->Local2Global(detElemId, xlocal2, ylocal2, 0, xg02, yg02, zg2);
+
+ Float_t xg1 = xg01, xg2 = xg02, yg1 = yg01, yg2 = yg02;
+
+ if(xg01>xg02){
+ xg1 = xg02;
+ xg2 = xg01;
+ }
+ if(yg01>yg02){
+ yg1 = yg02;
+ yg2 = yg01;
+ }
- if ( segmentation->HasDE(detElemId) ){
- const AliMpVSegmentation* seg =
- AliMpSegmentation::Instance()
- ->GetMpSegmentation(detElemId,AliMp::GetCathodType(cathode));
- if (seg){
- Float_t deltax = seg->Dimensions().X();
- Float_t deltay = seg->Dimensions().Y();
- Float_t xlocal1 = -deltax;
- Float_t ylocal1 = -deltay;
- Float_t xlocal2 = +deltax;
- Float_t ylocal2 = +deltay;
- Float_t xg01, yg01, zg1, xg02, yg02, zg2;
- kGeomTransformer->Local2Global(detElemId, xlocal1, ylocal1, 0, xg01, yg01, zg1);
- kGeomTransformer->Local2Global(detElemId, xlocal2, ylocal2, 0, xg02, yg02, zg2);
-
- Float_t xg1 = xg01, xg2 = xg02, yg1 = yg01, yg2 = yg02;
-
- if(xg01>xg02){
- xg1 = xg02;
- xg2 = xg01;
- }
- if(yg01>yg02){
- yg1 = yg02;
- yg2 = yg01;
- }
-
- if(x>=xg1 && x<=xg2 && y>=yg1 && y<=yg2){
- resultingDetElemId = detElemId;
- break;
- }
+ if(x>=xg1-tolerance && x<=xg2+tolerance && y>=yg1-tolerance && y<=yg2+tolerance){ // takes into account errors in extrapolation
+ if(y<yg1) currDist = yg1-y;
+ else if(y>yg2) currDist = y-yg2;
+ if(currDist<minDist) {
+ resultingDetElemId = detElemId;
+ minDist=currDist;
+ continue;
}
+ resultingDetElemId = detElemId;
+ break;
}
- }
+ } // loop on detElemId
return resultingDetElemId;
}
//_____________________________________________________________________________
-void AliMUONTriggerChamberEff::LocalBoardFromPos(Float_t x, Float_t y, Int_t detElemId, Int_t cathode, Int_t localBoard[4])
+void AliMUONTriggerChamberEff::LocalBoardFromPos(Float_t x, Float_t y,
+ Int_t detElemId, Int_t cathode,
+ Int_t localBoard[4])
{
//
/// Given the (x,y) position in the chamber,
for(Int_t loc=0; loc<4; loc++){
localBoard[loc]=-1;
}
- const AliMUONGeometryTransformer *kGeomTransformer = fMUON->GetGeometryTransformer();
Float_t xl, yl, zl;
- kGeomTransformer->Global2Local(detElemId, x, y, 0, xl, yl, zl);
+ fTransformer->Global2Local(detElemId, x, y, 0, xl, yl, zl);
TVector2 pos(xl,yl);
const AliMpVSegmentation* seg =
AliMpSegmentation::Instance()
//_____________________________________________________________________________
-void AliMUONTriggerChamberEff::PrintTrigger(AliMUONGlobalTrigger *globalTrig)
-{
- //
- /// Print trigger response.
- //
-
- printf("===================================================\n");
- printf(" Global Trigger output\t \tLow pt\tHigh pt\n");
-
- printf(" number of Single:\t \t");
- printf("%i\t",globalTrig->SingleLpt());
- printf("%i\t",globalTrig->SingleHpt());
- printf("\n");
-
- printf(" number of UnlikeSign pair:\t");
- printf("%i\t",globalTrig->PairUnlikeLpt());
- printf("%i\t",globalTrig->PairUnlikeHpt());
- printf("\n");
-
- printf(" number of LikeSign pair:\t");
- printf("%i\t",globalTrig->PairLikeLpt());
- printf("%i\t",globalTrig->PairLikeHpt());
- printf("\n");
- printf("===================================================\n");
- printf("\n");
-}
-
-void AliMUONTriggerChamberEff::PerformTriggerChamberEff(const char* outputDir)
+void AliMUONTriggerChamberEff::EventChamberEff(const AliMUONVTriggerStore& triggerStore,
+ const AliMUONVTriggerTrackStore& trigTrackStore,
+ const AliMUONVTrackStore& trackStore)
{
//
/// Main method.
/// Files with calculated efficiency are placed in the user defined outputDir.
//
+ if(!fTransformer || ! fDigitMaker) {
+ AliError(Form("AliMUONGeometryTransformer or AliMUONDigitMaker not properly initialized!!"));
+ return;
+ }
+
enum {kBending, kNonBending};
- Int_t evtBeforePrint = 1000;
Float_t rad2deg = 180./TMath::Pi();
- Int_t chOrder[] = {0,2,1,3};
- Int_t station[] = {0,0,1,1};
+ Int_t chOrder[fgkNchambers] = {0,2,1,3};
Float_t zRealMatch[fgkNchambers] = {0.0};
Float_t correctFactor[fgkNcathodes] = {1.};
Bool_t match[fgkNchambers][fgkNcathodes] = {{kFALSE}};
+ Bool_t matchPad[fgkNcathodes]={kFALSE};
- TClonesArray *recTrigTracksArray = 0x0;
- AliMUONTriggerTrack *recTrigTrack = 0x0;
- AliMUONDigit * mDigit = 0x0;
Float_t zMeanChamber[fgkNchambers];
for(Int_t ch=0; ch<fgkNchambers; ch++){
zMeanChamber[ch] = AliMUONConstants::DefaultChamberZ(10+ch);
}
- TClonesArray * globalTrigger = 0x0;
- AliMUONGlobalTrigger * gloTrg = 0x0;
-
- Int_t partNumOfTrig[fgkNchambers][fgkNcathodes] = {{0}};
- Int_t totNumOfTrig[fgkNchambers][fgkNcathodes] = {{0}};
- Int_t atLeast1MuPerEv[fgkNchambers][fgkNcathodes] = {{0}};
Int_t digitPerTrack[fgkNcathodes] = {0};
- Float_t trackIntersectCh[2][fgkNchambers]={{0.0}};
+ Float_t trackIntersectCh[fgkNchambers][2]={{0.0}};
- Int_t slatInPlane1[2][fgkNcathodes];
- Int_t iyDigitInPlane1[2][fgkNcathodes];
+ Int_t triggeredDigits[2][fgkNchambers] = {{-1}};
- const Int_t kMaxNumOfTracks = 10;
- Int_t trigScheme[kMaxNumOfTracks][fgkNchambers][fgkNcathodes]={{{0}}};
- Int_t triggeredDigits[kMaxNumOfTracks][fgkNchambers][fgkNcathodes] = {{{-1}}};
- Int_t slatThatTriggered[kMaxNumOfTracks][fgkNchambers][fgkNcathodes]={{{-1}}};
- Int_t boardThatTriggered[kMaxNumOfTracks][fgkNchambers][fgkNcathodes][4]={{{{-1}}}};
- Int_t nboard[4]={-1};
+ Int_t trigScheme[fgkNchambers][fgkNcathodes]={{0}};
+ Int_t slatThatTriggered[fgkNchambers][fgkNcathodes]={{-1}};
+ Int_t boardThatTriggered[fgkNchambers][fgkNcathodes][4]={{{-1}}};
+ Int_t nboard[fgkNcathodes][4]={{-1}};
Int_t ineffBoard[4]={-1};
- const Int_t kMaxNumOfDigits = 20;
- Int_t detElOfDigitsInData[kMaxNumOfDigits][fgkNchambers][fgkNcathodes] = {{{-1}}};
+ AliMUONDigitStoreV1 digitStore;
+ TriggerDigits(triggerStore,digitStore);
- char filename[150];
- FileStat_t fs;
-
- if(fFirstRun<0)fFirstRun=fLastRun=-1;
-
- for(Int_t iRun = fFirstRun; iRun <= fLastRun; iRun++){// Loop over runs
- // open run loader and load gAlice
- if(fFirstRun>=0){
- cout<<"\n\nRun = "<<iRun<<endl;
- sprintf(filename, "%s/run%i/galice.root", fGaliceDir.Data(), iRun);
- if(gSystem->GetPathInfo(filename,fs)){
- cout<<"Warning: "<<filename<<" not found. Skip to next one"<<endl;
- continue;
+ for(Int_t ch=0; ch<fgkNchambers; ch++){
+ for(Int_t itrack=0; itrack<2; itrack++){
+ triggeredDigits[itrack][ch]=-1;
}
- cout<<"Opening file "<<filename<<endl;
- SetGaliceFile(filename);
}
- for (Int_t ievent=fFirstEvent; ievent<=fLastEvent; ievent++) { // event loop
- Bool_t isClearEvent = kTRUE;
+ AliMUONTriggerTrack *recTrigTrack = 0x0;
+ TIter next(trigTrackStore.CreateIterator());
+
+ while ( ( recTrigTrack = static_cast<AliMUONTriggerTrack*>(next()) ) )
+ {
+ for(Int_t cath=0; cath<fgkNcathodes; cath++){
+ digitPerTrack[cath]=0;
+ }
for(Int_t ch=0; ch<fgkNchambers; ch++){
for(Int_t cath=0; cath<fgkNcathodes; cath++){
- partNumOfTrig[ch][cath]=0;
match[ch][cath]=kFALSE;
- for(Int_t itrack=0; itrack<kMaxNumOfTracks; itrack++){
- triggeredDigits[itrack][ch][cath]=-1;
- slatThatTriggered[itrack][ch][cath]=-1;
- for(Int_t loc=0; loc<4; loc++){
- boardThatTriggered[itrack][ch][cath][loc]=-1;
- }
- }
- for(Int_t idig=0; idig<kMaxNumOfDigits; idig++){
- detElOfDigitsInData[idig][ch][cath]=-1;
+ slatThatTriggered[ch][cath]=-1;
+ for(Int_t loc=0; loc<4; loc++){
+ boardThatTriggered[ch][cath][loc]=-1;
}
}
}
- fRunLoader->GetEvent(ievent);
- if (ievent%evtBeforePrint==0) printf("\t Event = %d\n",ievent);
+ Bool_t isClearEvent = kTRUE;
+ Bool_t doubleCountTrack = kFALSE;
- fData->SetTreeAddress("RL");
- fData->GetRecTriggerTracks();
- recTrigTracksArray = fData->RecTriggerTracks();
- Int_t nRecTrigTracks = (Int_t) recTrigTracksArray->GetEntriesFast();
+ if(!IsCleanTrack(recTrigTrack, trackStore)) {
+ if(fDebugLevel>=1) printf("\tTrack %p (%f, %f) don't match tracker track: rejected!\n",recTrigTrack,recTrigTrack->GetX11(),recTrigTrack->GetY11());
+ continue;
+ }
- fData->SetTreeAddress("D,GLT");
- fData->GetDigits();
+ Float_t x11 = recTrigTrack->GetX11();// x position (info from non-bending plane)
+ Float_t y11 = recTrigTrack->GetY11();// y position (info from bending plane)
+ Float_t thetaX = recTrigTrack->GetThetax();
+ Float_t thetaY = recTrigTrack->GetThetay();
- const AliMUONGeometryTransformer* kGeomTransformer = fMUON->GetGeometryTransformer();
+ if(fDebugLevel>=3) printf("\tTrack = %p\npos from track: (x,y) = (%f, %f), (thetaX, thetaY) = (%f, %f)\n",recTrigTrack,x11,y11,thetaX*rad2deg,thetaY*rad2deg);
- for (Int_t iRecTrigTrack=0; iRecTrigTrack<nRecTrigTracks; iRecTrigTrack++) {
+ for(Int_t ch=0; ch<fgkNchambers; ch++) {
+ zRealMatch[ch] = zMeanChamber[ch];
for(Int_t cath=0; cath<fgkNcathodes; cath++){
- digitPerTrack[cath]=0;
- for(Int_t sta=0; sta<2; sta++){
- slatInPlane1[sta][cath] = -9999;
- iyDigitInPlane1[sta][cath] = -9999;
- }
+ trigScheme[ch][cath] = 0;
}
+ }
- Bool_t doubleCountTrack = kFALSE;
-
- // reading info from tracks
- recTrigTrack = (AliMUONTriggerTrack *)recTrigTracksArray->At(iRecTrigTrack);
- Float_t x11 = recTrigTrack->GetX11();// x position (info from non-bending plane)
- Float_t y11 = recTrigTrack->GetY11();// y position (info from bending plane)
- Float_t thetaX = recTrigTrack->GetThetax();
- Float_t thetaY = recTrigTrack->GetThetay();
+ for(Int_t ch=0; ch<fgkNchambers; ch++) { // chamber loop
+ Int_t currCh = chOrder[ch];
+ if(fDebugLevel>=2)
+ printf("zMeanChamber[%i] = %.2f\tzRealMatch[0] = %.2f\n",currCh,zMeanChamber[currCh],zRealMatch[0]);
- if(fDebugLevel>=3)printf("\tEvent = %i, Track = %i\npos from track: (x,y) = (%f, %f), (thetaX, thetaY) = (%f, %f)\n",ievent,iRecTrigTrack,x11,y11,thetaX*rad2deg,thetaY*rad2deg);
+ for(Int_t cath=0; cath<fgkNcathodes; cath++){
+ correctFactor[cath]=1.;
+ }
+ // calculate corrections to trigger track theta
+ if(ch>=1)correctFactor[kNonBending] = zMeanChamber[0]/zRealMatch[0];// corrects x position
+ if(ch>=2)correctFactor[kBending] = (zMeanChamber[2] - zMeanChamber[0]) / (zRealMatch[2] - zRealMatch[0]);// corrects y position
+
+ // searching track intersection with chambers (first approximation)
+ Float_t deltaZ = zMeanChamber[currCh] - zMeanChamber[0];
+ trackIntersectCh[currCh][0] = zMeanChamber[currCh] * TMath::Tan(thetaX) * correctFactor[kNonBending];// x position (info from non-bending plane)
+ trackIntersectCh[currCh][1] = y11 + deltaZ * TMath::Tan(thetaY) * correctFactor[kBending];// y position (info from bending plane)
+ Int_t detElemIdFromTrack = DetElemIdFromPos(trackIntersectCh[currCh][0], trackIntersectCh[currCh][1], 11+currCh, 0);
+ if(detElemIdFromTrack<0) {
+ if(fDebugLevel>1) printf("Warning: trigger track outside trigger chamber\n");
+ continue;
+ }
+
+ triggeredDigits[1][currCh] = MatchingPad(digitStore, detElemIdFromTrack, trackIntersectCh[currCh], matchPad, nboard, zRealMatch, y11);
+
+ // if MatchingPad = -500 => too many digits matching pad =>
+ // => Event not clear => Reject track
+ if(triggeredDigits[1][currCh]<-100){
+ isClearEvent = kFALSE;
+ if(fDebugLevel>=1) printf("Warning: track = %p (%i) matches many pads. Rejected!\n",recTrigTrack, detElemIdFromTrack);
+ break;
+ }
- for(Int_t ch=0; ch<fgkNchambers; ch++) {
- zRealMatch[ch] = zMeanChamber[ch];
+ // deciding if digit matches track
+ Bool_t isDiffLocBoard = kFALSE;
+ if(fReproduceTrigResponse && ch>2){
for(Int_t cath=0; cath<fgkNcathodes; cath++){
- trigScheme[iRecTrigTrack][ch][cath] = 0;
+ if(boardThatTriggered[currCh][cath][0]>=0){
+ if(boardThatTriggered[currCh][cath][0]!=boardThatTriggered[currCh-1][cath][0]) isDiffLocBoard = kTRUE;
+ }
}
}
- for(Int_t ch=0; ch<fgkNchambers; ch++) { // chamber loop
- Int_t currCh = chOrder[ch];
- Int_t ichamber = 10+currCh;
- Int_t currStation = station[currCh];
- TClonesArray* digits = fData->Digits(ichamber);
- digits->Sort();
- Int_t ndigits = (Int_t)digits->GetEntriesFast();
- if(fDebugLevel>=2){
- if(fDebugLevel<3)printf("\tEvent = %i, Track = %i\n", ievent, iRecTrigTrack);
- printf("DigitNum: %i digits detected\n",ndigits);
- }
+ if(isDiffLocBoard && fDebugLevel>=1)printf("\tDifferent local board\n");
- for(Int_t cath=0; cath<fgkNcathodes; cath++){
- correctFactor[cath]=1.;
+ for(Int_t cath=0; cath<fgkNcathodes; cath++){
+ match[currCh][cath] = (matchPad[cath] && !isDiffLocBoard);
+ if(!match[currCh][cath]) continue;
+ digitPerTrack[cath]++;
+ trigScheme[currCh][cath]++;
+ slatThatTriggered[currCh][cath] = detElemIdFromTrack;
+ for(Int_t loc=0; loc<4; loc++){
+ boardThatTriggered[currCh][cath][loc] = nboard[cath][loc];
}
- // calculate corrections to trigger track theta
- if(ch>=1)correctFactor[kNonBending] = zMeanChamber[0]/zRealMatch[0];// corrects x position
- if(ch>=2)correctFactor[kBending] = (zMeanChamber[2] - zMeanChamber[0]) / (zRealMatch[2] - zRealMatch[0]);// corrects y position
-
- // searching track intersection with chambers (first approximation)
- Float_t deltaZ = zMeanChamber[currCh] - zMeanChamber[0];
- trackIntersectCh[0][currCh] = zMeanChamber[currCh] * TMath::Tan(thetaX) * correctFactor[kNonBending];// x position (info from non-bending plane)
- trackIntersectCh[1][currCh] = y11 + deltaZ * TMath::Tan(thetaY) * correctFactor[kBending];// y position (info from bending plane)
-
- for(Int_t idigit=0; idigit<ndigits; idigit++) { // digit loop
- mDigit = (AliMUONDigit*)digits->At(idigit);
- for(Int_t loc=0; loc<4; loc++){
- nboard[loc]=-1;
- }
-
- // searching loaded digit global position and dimension
- Int_t detElemId = mDigit->DetElemId();
- Int_t cathode = mDigit->Cathode();
- Int_t ix = mDigit->PadX();
- Int_t iy = mDigit->PadY();
- Float_t xpad, ypad, zpad;
- if(detElOfDigitsInData[idigit][ch][cathode]==-1)detElOfDigitsInData[idigit][ch][cathode] = detElemId;
-
- if(fDebugLevel>=2)printf("cathode = %i\n",cathode);
- const AliMpVSegmentation* seg = AliMpSegmentation::Instance()
- ->GetMpSegmentation(detElemId,AliMp::GetCathodType(cathode));
-
- AliMpPad pad = seg->PadByIndices(AliMpIntPair(ix,iy),kTRUE);
- for (Int_t loc=0; loc<pad.GetNofLocations(); loc++){
- AliMpIntPair location = pad.GetLocation(loc);
- nboard[loc] = location.GetFirst();
- }
-
- // get the pad position and dimensions
- Float_t xlocal1 = pad.Position().X();
- Float_t ylocal1 = pad.Position().Y();
- Float_t dpx = pad.Dimensions().X();
- Float_t dpy = pad.Dimensions().Y();
-
- kGeomTransformer->Local2Global(detElemId, xlocal1, ylocal1, 0, xpad, ypad, zpad);
-
- if(fDebugLevel>=3)printf("ch = %i\t cath = %i\tpad = (%4.1f, %4.1f, %4.1f)\tsize = (%3.1f, %3.1f)\n",currCh,cathode,xpad,ypad,zpad,dpx,dpy);
-
- // searching track intersection with chambers (second approximation)
- if(ch>=2){
- deltaZ = zpad - zRealMatch[0];
- trackIntersectCh[1][currCh] = y11 + deltaZ * TMath::Tan(thetaY) * correctFactor[kBending];// y position (info from bending plane)
- }
-
- // deciding if digit matches track
- Bool_t isDiffLocBoard = kFALSE;
- if(fReproduceTrigResponse)isDiffLocBoard = IsDiffLocalBoard(detElemId, iy, slatInPlane1[currStation][cathode], iyDigitInPlane1[currStation][cathode]);
- Bool_t matchPad = PadMatchTrack(xpad, ypad, dpx, dpy, trackIntersectCh[0][currCh], trackIntersectCh[1][currCh], currCh);
-
- if(matchPad && ch<2){
- slatInPlane1[currStation][cathode] = detElemId;
- iyDigitInPlane1[currStation][cathode] = iy;
- if(fDebugLevel>=3)printf("slatInPlane1[%i][%i] = %i\tiyDigitInPlane1[%i][%i] = %i\n",currStation,cathode,slatInPlane1[currStation][cathode],currStation,cathode,iyDigitInPlane1[currStation][cathode]);
- }
-
- if(isDiffLocBoard && fDebugLevel>=1)printf("\tDifferent local board\n");
-
- match[currCh][cathode] = (matchPad && !isDiffLocBoard);
+ }
+ } // end chamber loop
- if(match[currCh][cathode]){
- digitPerTrack[cathode]++;
- trigScheme[iRecTrigTrack][currCh][cathode]++;
- triggeredDigits[iRecTrigTrack][currCh][cathode] = idigit;
- slatThatTriggered[iRecTrigTrack][currCh][cathode] = detElemId;
- for(Int_t loc=0; loc<4; loc++){
- boardThatTriggered[iRecTrigTrack][currCh][cathode][loc] = nboard[loc];
- }
- if(digitPerTrack[cathode]>4 && !fReproduceTrigResponse)isClearEvent = kFALSE;
- }
+ for(Int_t cath=0; cath<fgkNcathodes; cath++){
+ if(digitPerTrack[cath]<3)isClearEvent = kFALSE;
+ if(fDebugLevel>=1 && !isClearEvent)printf("Warning: found %i digits for trigger track cathode %i.\nRejecting event\n", digitPerTrack[cath],cath);
+ }
- // in case of match, store real z position of the chamber
- if(matchPad)zRealMatch[currCh] = zpad;
+ if(!isClearEvent && !fReproduceTrigResponse) continue;
- } // end digit loop
- } // end chamber loop
+ Int_t commonDigits = 0;
+ for(Int_t ch=0; ch<fgkNchambers; ch++){
+ if(triggeredDigits[1][ch]==triggeredDigits[0][ch]) commonDigits++; // Compare with previous track
+ triggeredDigits[0][ch] = triggeredDigits[1][ch]; // Store this track parameters for comparison with next one
+ }
+ if(commonDigits>=2){
+ doubleCountTrack=kTRUE;
+ }
+ if(!doubleCountTrack || fReproduceTrigResponse){
for(Int_t cath=0; cath<fgkNcathodes; cath++){
- if(digitPerTrack[cath]<3 && !fReproduceTrigResponse)isClearEvent = kFALSE;
- }
-
- if(!isClearEvent && !fReproduceTrigResponse){
- fData->ResetDigits();
- continue;
- }
-
- Int_t commonDigits = 0;
- Int_t doubleTrack = -1;
- for(Int_t itrack=0; itrack<iRecTrigTrack; itrack++){
+ Int_t is44 = 1;
+ Bool_t goodForSlatEff = kTRUE;
+ Bool_t goodForBoardEff = kTRUE;
+ Int_t ineffSlat = -1;
+ Int_t ineffDetElId = -1;
+ Int_t firstSlat = slatThatTriggered[0][cath]%100;
+ if(firstSlat<0) firstSlat=slatThatTriggered[1][cath]%100;
+ Int_t firstBoard = boardThatTriggered[0][kBending][0];
+ if(firstBoard<0) firstBoard=boardThatTriggered[1][kBending][0];
for(Int_t ch=0; ch<fgkNchambers; ch++){
- if(triggeredDigits[itrack][ch][kBending]==triggeredDigits[iRecTrigTrack][ch][kBending])commonDigits++;
- }
- if(commonDigits>=2){
- doubleCountTrack=kTRUE;
- doubleTrack = itrack;
- break;
- }
- }
-
- for(Int_t cath=0; cath<fgkNcathodes; cath++){
- if(!doubleCountTrack || fReproduceTrigResponse){
- Int_t is44 = 1;
- Bool_t goodForSlatEff=kTRUE;
- Bool_t goodForBoardEff=kTRUE;
- Int_t firstSlat=slatThatTriggered[iRecTrigTrack][0][cath]%100;
- if(firstSlat<0)firstSlat=slatThatTriggered[iRecTrigTrack][1][cath]%100;
- Int_t firstBoard=boardThatTriggered[iRecTrigTrack][0][0][0];
- if(firstBoard<0)firstBoard=boardThatTriggered[iRecTrigTrack][1][0][0];
- for(Int_t ch=0; ch<fgkNchambers; ch++){
- is44 *= trigScheme[iRecTrigTrack][ch][cath];
- Int_t currSlat=slatThatTriggered[iRecTrigTrack][ch][cath]%100;
- if(currSlat<0)continue;
- if(currSlat!=firstSlat)goodForSlatEff=kFALSE;
- Bool_t atLeastOneLoc=kFALSE;
- for(Int_t loc=0; loc<4; loc++){
- Int_t currBoard = boardThatTriggered[iRecTrigTrack][ch][cath][loc];
- if(currBoard==firstBoard){
- atLeastOneLoc=kTRUE;
- break;
- }
- }
- if(!atLeastOneLoc)goodForBoardEff=kFALSE;
+ Bool_t isCurrChIneff = kFALSE;
+ is44 *= trigScheme[ch][cath];
+ Int_t currSlat = slatThatTriggered[ch][cath]%100;
+ if(currSlat<0){
+ ineffDetElId = DetElemIdFromPos(trackIntersectCh[ch][0], trackIntersectCh[ch][1], 11+ch, cath);
+ currSlat = ineffDetElId%100;
+ ineffSlat = currSlat;
+ isCurrChIneff = kTRUE;
}
- if(fDebugLevel==1)printf("\tEvent = %i, Track = %i\n", ievent, iRecTrigTrack);
- if(is44==1){
- fTrigger44[cath]++;
- if(fDebugLevel>=1)printf("Trigger44[%i] = %i\n",cath,fTrigger44[cath]);
- if(goodForSlatEff){
- for(Int_t ch=0; ch<fgkNchambers; ch++){
- for(Int_t slat=0; slat<fgkNslats; slat++){
- Int_t corrDetEl = (ch+11)*100 + slat;
- if(corrDetEl==slatThatTriggered[iRecTrigTrack][ch][cath]){
- fHitPerSlat[ch][cath][slat]++;
- if(fDebugLevel>=1)printf("Slat that triggered = %i\n",corrDetEl);
- if(goodForBoardEff && firstBoard>0){
- fHitPerBoard[ch][cath][firstBoard-1]++;
- if(fDebugLevel>=1)printf("Board that triggered = %i\n",firstBoard);
- }
- else if(fDebugLevel>=1)printf("Event = %i, Track = %i: Particle crossed different boards: rejected!\n",ievent,iRecTrigTrack);
- }
- }
- }
+ if(currSlat!=firstSlat)goodForSlatEff=kFALSE;
+ Bool_t atLeastOneLoc=kFALSE;
+ if(isCurrChIneff) LocalBoardFromPos(trackIntersectCh[ch][0], trackIntersectCh[ch][1], ineffDetElId, cath, ineffBoard);
+ for(Int_t loc=0; loc<4; loc++){
+ Int_t currBoard = boardThatTriggered[ch][cath][loc];
+ if(isCurrChIneff) currBoard = ineffBoard[loc];
+ if(currBoard==firstBoard){
+ atLeastOneLoc=kTRUE;
+ break;
}
- else printf("Event = %i, Track = %i: Particle crossed different slats: rejected!\n",ievent,iRecTrigTrack);
}
- if(digitPerTrack[cath]==3){
+ if(!atLeastOneLoc)goodForBoardEff=kFALSE;
+ } // end chamber loop
+
+ // Trigger 4/4
+ if(is44==1){
+ fTrigger44[cath]++;
+ if(fDebugLevel>=1)printf("Trigger44[%i] = %i\n",cath,fTrigger44[cath]);
+ if(goodForSlatEff){
for(Int_t ch=0; ch<fgkNchambers; ch++){
- if(match[ch][cath])partNumOfTrig[ch][cath]++;
- if(trigScheme[iRecTrigTrack][ch][cath]==0){
- fTrigger34[ch][cath]++;
- if(fDebugLevel>=1)printf("Trigger34[%i][%i] = %i\n",ch,cath,fTrigger34[ch][cath]);
- if(!goodForSlatEff){
- printf("Event %i, Track = %i: Particle crossed different slats: rejected!\n",ievent,iRecTrigTrack);
- continue;
- }
- Int_t ineffSlat = DetElemIdFromPos(trackIntersectCh[0][ch], trackIntersectCh[1][ch], 11+ch, cath);
- if(fDebugLevel>=1)printf("Slat non efficient = %i\n",ineffSlat);
- if(ineffSlat>0){
- Int_t slatInCh = ineffSlat%100;
- fInefficientSlat[ch][cath][slatInCh]++;
- for(Int_t idig=0; idig<kMaxNumOfDigits; idig++){
- if(ineffSlat==detElOfDigitsInData[idig][ch][cath])cout<<"Warning: "<<ineffSlat<<" is not inefficient!!!"<<endl;
- }
- LocalBoardFromPos(trackIntersectCh[0][ch], trackIntersectCh[1][ch], ineffSlat, cath, ineffBoard);
- Int_t boardNonEff=-1;
- for(Int_t loc=0; loc<4; loc++){
- if(ineffBoard[loc]==firstBoard){
- boardNonEff=ineffBoard[loc];
- break;
- }
- }
- if(fDebugLevel>=1)printf("Board non efficient = %i\n",boardNonEff);
- if(boardNonEff>0)fInefficientBoard[ch][cath][boardNonEff-1]++;
- else if(fDebugLevel>=1){
- printf("Inefficient board should be %i.\tBoards found:\n", firstBoard);
- for(Int_t loc=0; loc<4; loc++){
- printf("%i\t",ineffBoard[loc]);
- }
- printf("\n");
- }
-
- }
+ fHitPerSlat[ch][cath][firstSlat]++;
+ if(fDebugLevel>=1)printf("Slat that triggered = %i\n",slatThatTriggered[ch][cath]);
+ if(goodForBoardEff && firstBoard>0){
+ fHitPerBoard[ch][cath][firstBoard-1]++;
+ if(fDebugLevel>=1)printf("Board that triggered = %i\n",firstBoard);
}
+ else if(fDebugLevel>=1) printf("Track = %p: Particle crossed different boards: rejected!\n",recTrigTrack);
}
}
+ else if(fDebugLevel>=1) printf("Track = %p: Particle crossed different slats: rejected!\n",recTrigTrack);
+ //cout<<"fTrigger44["<<cath<<"] = "<<fTrigger44[cath]<<"\tfHitPerSlat["<<0<<"]["<<cath<<"]["<<firstSlat<<"] = "<<fHitPerSlat[0][cath][firstSlat]<<"\tfHitPerBoard["<<0<<"]["<<cath<<"]["<<firstBoard-1<<"] = "<<fHitPerBoard[0][cath][firstBoard-1]<<endl; //REMEMBER TO CUT
}
- else if(doubleCountTrack){
- if(fDebugLevel<=1)printf("\n\tEvent = %i, Track = %i: ", ievent,iRecTrigTrack);
- printf("Double Count Track: %i similar to %i. Track rejected!\n",iRecTrigTrack, doubleTrack);
+
+ // Trigger 3/4
+ if(ineffDetElId>0){
+ Int_t ineffCh = ineffDetElId/100-11;
+ fTrigger34[ineffCh][cath]++;
+ if(fDebugLevel>=1) printf("Trigger34[%i][%i] = %i\n",ineffCh,cath,fTrigger34[ineffCh][cath]);
+ if(goodForSlatEff){
+ if(fDebugLevel>=1) printf("Slat non efficient = %i\n",ineffDetElId);
+ fInefficientSlat[ineffCh][cath][ineffSlat]++;
+
+ if(goodForBoardEff && firstBoard>0){
+ if(fDebugLevel>=1) printf("Board non efficient = %i\n",firstBoard);
+ fInefficientBoard[ineffCh][cath][firstBoard-1]++;
+ }
+ else if(fDebugLevel>=1) printf("Track = %p: Particle crossed different boards: rejected!\n",recTrigTrack);
+ }
+ else if(fDebugLevel>=1) printf("Track = %p: Particle crossed different slats: rejected!\n",recTrigTrack);
+ //cout<<"fTrigger34["<<ineffCh<<"]["<<cath<<"] = "<<fTrigger34[ineffCh][cath]<<"\tfInefficientSlat["<<ineffCh<<"]["<<cath<<"]["<<ineffSlat<<"] = "<<fInefficientSlat[ineffCh][cath][ineffSlat]<<"\tfInefficientBoard["<<ineffCh<<"]["<<cath<<"]["<<firstBoard-1<<"] = "<<fInefficientBoard[ineffCh][cath][firstBoard-1]<<endl; //REMEMBER TO CUT
}
- }
- }// end trigger tracks loop
- if(nRecTrigTracks<=0){
- fData->ResetDigits();
- continue;
- }
- for(Int_t ch=0; ch<fgkNchambers; ch++){
- for(Int_t cath=0; cath<fgkNcathodes; cath++){
- totNumOfTrig[ch][cath] += partNumOfTrig[ch][cath];
- if(partNumOfTrig[ch][cath]>0)atLeast1MuPerEv[ch][cath]++;
- }
+ } // end loop on cathodes
}
-
- if(fPrintInfo){
- //Global trigger
- globalTrigger = fData->GlobalTrigger();
- Int_t nglobals = (Int_t) globalTrigger->GetEntriesFast(); // should be 1
-
- for (Int_t iglobal=0; iglobal<nglobals; iglobal++) { // Global Trigger
- gloTrg = (AliMUONGlobalTrigger*)globalTrigger->At(iglobal);
- }
- PrintTrigger(gloTrg);
- InfoDigit();
- cout<<"\n"<<endl;
+ else if(doubleCountTrack){
+ if(fDebugLevel>=1)
+ printf("\n\tTrack = %p: \nDouble Count Track: Track rejected!\n",recTrigTrack);
}
+ } // end trigger tracks loop
- fData->ResetDigits();
- }// end event loop
- if(fFirstRun>=0)CleanGalice();
- } //end loop over run
-
- // Write output data
- WriteEfficiencyMap(outputDir);
-
- WriteOutput(outputDir, totNumOfTrig, atLeast1MuPerEv);
+ if(fPrintInfo) InfoDigit(digitStore);
}
//_____________________________________________________________________________
-void AliMUONTriggerChamberEff::WriteOutput(const char* outputDir, Int_t totNumOfTrig[4][2], Int_t atLeast1MuPerEv[4][2])
+void AliMUONTriggerChamberEff::WriteEfficiencyMap(const char* outputDir)
{
//
/// Writes information on calculated efficiency.
/// It writes: triggerChamberEff.root file containing efficiency histograms.
- ///
- /// In addition a text file triggerChamberEff.out is created,
- /// with further informations on efficiencies.
//
- char *cathodeName[fgkNcathodes]={"Bending plane", "Non-Bending plane"};
char *cathCode[fgkNcathodes] = {"bendPlane", "nonBendPlane"};
char outFileName[100];
- sprintf(outFileName, "%s/triggerChamberEff.out",outputDir);
- FILE *outfile = fopen(outFileName, "w");
- for(Int_t cath=0; cath<fgkNcathodes; cath++){
- fprintf(outfile,"%s:\n",cathodeName[cath]);
- for(Int_t ch=0; ch<fgkNchambers; ch++){
- fprintf(outfile,"Total number of muon triggers chamber 1%i = %i\n",ch+1,totNumOfTrig[ch][cath]);
- }
- fprintf(outfile,"\n");
- }
- fprintf(outfile,"\n");
- for(Int_t cath=0; cath<fgkNcathodes; cath++){
- fprintf(outfile,"%s:\n",cathodeName[cath]);
- for(Int_t ch=0; ch<fgkNchambers; ch++){
- fprintf(outfile,"At least 1 muon triggered chamber 1%i = %i\n",ch+1, atLeast1MuPerEv[ch][cath]);
- }
- fprintf(outfile,"\n");
- }
- fprintf(outfile,"\n\n");
- for(Int_t cath=0; cath<fgkNcathodes; cath++){
- fprintf(outfile,"%s:\n",cathodeName[cath]);
- fprintf(outfile,"Number of triggers where all chambers counted = %i\n",fTrigger44[cath]);
- fprintf(outfile,"\n");
- }
- fprintf(outfile,"\n");
- for(Int_t cath=0; cath<fgkNcathodes; cath++){
- fprintf(outfile,"%s:\n",cathodeName[cath]);
- for(Int_t ch=0; ch<fgkNchambers; ch++){
- fprintf(outfile,"Number of triggers where chamber 1%i did not count = %i\n",ch+1,fTrigger34[ch][cath]);
- }
- fprintf(outfile,"\n");
- }
-
- fprintf(outfile,"\n");
- for(Int_t cath=0; cath<fgkNcathodes; cath++){
- fprintf(outfile,"%s:\n",cathodeName[cath]);
- for(Int_t ch=0; ch<fgkNchambers; ch++){
- Int_t sumIneff = 0, sumHits = 0;
- fprintf(outfile,"\n Chamber %1i\n", ch+1);
- for(Int_t slat=0; slat<fgkNslats; slat++){
- fprintf(outfile,"Number of triggers where slat %2i - did not count = %5i - was hit (hit%sCh%iSlat%i) = %5i\n",slat,fInefficientSlat[ch][cath][slat],cathCode[cath],11+ch,slat,fHitPerSlat[ch][cath][slat]);
- sumIneff += fInefficientSlat[ch][cath][slat];
- sumHits += fHitPerSlat[ch][cath][slat];
- }
- fprintf(outfile,"Number of triggers where chamber %1i - did not count = %5i - was hit (hit%sCh%i) = %5i\n",ch+1,sumIneff,cathCode[cath],11+ch,sumHits);
- }
- fprintf(outfile,"\n");
- }
- fclose(outfile);
- sprintf(outFileName, "%s/triggerChamberEff.root",outputDir);
+ sprintf(outFileName, "%s/MUON.TriggerEfficiencyMap.root",outputDir);
TFile *outputHistoFile = new TFile(outFileName,"RECREATE");
TDirectory *dir = gDirectory;
TH1F *histo[fgkNcathodes][fgkNchambers+1];
TH1F *histoBoard[fgkNcathodes][fgkNchambers];
- char histoName[30];
+ // ADDED for check
+ enum {allChEff, chNonEff, numOfHistoTypes};
+ char *histoTypeName[numOfHistoTypes] = {"CountInCh", "NonCountInCh"};
+ char *histoTypeTitle[numOfHistoTypes] = {"counted", "non counted"};
+ TH1F *histoCheckSlat[fgkNcathodes][fgkNchambers][numOfHistoTypes];
+ TH1F *histoCheckBoard[fgkNcathodes][fgkNchambers][numOfHistoTypes];
+ // end ADDED for check
+
+ char histoName[40];
char histoTitle[90];
for(Int_t cath=0; cath<fgkNcathodes; cath++){
histoBoard[cath][ch]->SetXTitle("boards");
histoBoard[cath][ch]->SetYTitle(yAxisTitle);
histoBoard[cath][ch]->GetXaxis()->SetNdivisions(fgkNboards);
+
+ // ADDED for check
+ for(Int_t hType=0; hType<numOfHistoTypes; hType++){
+ sprintf(histoName, "%sSlat%s%i", cathCode[cath], histoTypeName[hType], 11+ch);
+ sprintf(histoTitle, "Chamber %i: slat %s %s", 11+ch, histoTypeTitle[hType], cathCode[cath]);
+ histoCheckSlat[cath][ch][hType] = new TH1F(histoName, histoTitle, fgkNslats, 0-0.5, fgkNslats-0.5);
+ histoCheckSlat[cath][ch][hType]->SetXTitle("slat");
+ histoCheckSlat[cath][ch][hType]->SetYTitle(yAxisTitle);
+ histoCheckSlat[cath][ch][hType]->GetXaxis()->SetNdivisions(fgkNslats);
+
+ sprintf(histoName, "%sBoard%s%i", cathCode[cath], histoTypeName[hType], 11+ch);
+ sprintf(histoTitle, "Chamber %i: board %s %s", 11+ch, histoTypeTitle[hType], cathCode[cath]);
+ histoCheckBoard[cath][ch][hType] = new TH1F(histoName, histoTitle, fgkNboards, 1-0.5, fgkNboards+1.-0.5);
+ histoCheckBoard[cath][ch][hType]->SetXTitle("boards");
+ histoCheckBoard[cath][ch][hType]->SetYTitle(yAxisTitle);
+ histoCheckBoard[cath][ch][hType]->GetXaxis()->SetNdivisions(fgkNboards);
+ }
+ // end ADDED for check
}
}
}
Float_t efficiency, efficiencyError;
+ Int_t bin;
for(Int_t cath=0; cath<fgkNcathodes; cath++){
for(Int_t ch=0; ch<fgkNchambers; ch++){
for(Int_t slat=0; slat<fgkNslats; slat++){
CalculateEfficiency(fHitPerSlat[ch][cath][slat], fHitPerSlat[ch][cath][slat]+fInefficientSlat[ch][cath][slat], efficiency, efficiencyError, kFALSE);
- histo[cath][ch]->SetBinContent(slat+1, efficiency);
- histo[cath][ch]->SetBinError(slat+1, efficiencyError);
+ bin = histo[cath][ch]->FindBin(slat);
+ histo[cath][ch]->SetBinContent(bin, efficiency);
+ histo[cath][ch]->SetBinError(bin, efficiencyError);
+
+ // ADDED for check
+ histoCheckSlat[cath][ch][allChEff]->SetBinContent(bin, fHitPerSlat[ch][cath][slat]);
+ histoCheckSlat[cath][ch][chNonEff]->SetBinContent(bin, fInefficientSlat[ch][cath][slat]);
}
CalculateEfficiency(fTrigger44[cath], fTrigger34[ch][cath]+fTrigger44[cath], efficiency, efficiencyError, kFALSE);
- histo[cath][kChamberEff]->SetBinContent(ch+1, efficiency);
- histo[cath][kChamberEff]->SetBinError(ch+1, efficiencyError);
+ bin = histo[cath][ch]->FindBin(11+ch);
+ histo[cath][kChamberEff]->SetBinContent(bin, efficiency);
+ histo[cath][kChamberEff]->SetBinError(bin, efficiencyError);
for(Int_t board=0; board<fgkNboards; board++){
CalculateEfficiency(fHitPerBoard[ch][cath][board], fHitPerBoard[ch][cath][board]+fInefficientBoard[ch][cath][board], efficiency, efficiencyError, kFALSE);
- histoBoard[cath][ch]->SetBinContent(board+1, efficiency);
- histoBoard[cath][ch]->SetBinError(board+1, efficiencyError);
+ bin = histoBoard[cath][ch]->FindBin(board+1);
+ histoBoard[cath][ch]->SetBinContent(bin, efficiency);
+ histoBoard[cath][ch]->SetBinError(bin, efficiencyError);
+
+ // ADDED for check
+ histoCheckBoard[cath][ch][allChEff]->SetBinContent(bin, fHitPerBoard[ch][cath][board]);
+ histoCheckBoard[cath][ch][chNonEff]->SetBinContent(bin, fInefficientBoard[ch][cath][board]);
}
}
}
//_____________________________________________________________________________
-void AliMUONTriggerChamberEff::WriteEfficiencyMap(const char* outputDir)
+void AliMUONTriggerChamberEff::WriteEfficiencyMapTxt(const char* outputDir)
{
//
/// Writes the calculated efficiency in the text file efficiencyCells.dat
}// loop on chambers
}
+
+//_____________________________________________________________________________
+Bool_t AliMUONTriggerChamberEff::IsCleanTrack(AliMUONTriggerTrack *triggerTrack,
+ const AliMUONVTrackStore& trackStore)
+{
+ //
+ /// Try to match track from tracking system with trigger track
+ //
+ const Double_t kDistSigma[3]={1,1,0.02}; // sigma of distributions (trigger-track) X,Y,slopeY
+ const Double_t kMaxChi2MatchTrigger = 16.0;
+
+ AliMUONTrackParam trackParam;
+
+ Double_t distTriggerTrack[3];
+ Double_t xTrack, yTrack, ySlopeTrack, chi2;
+
+ AliMUONTrack* track;
+ TIter next(trackStore.CreateIterator());
+
+ while ( ( track = static_cast<AliMUONTrack*>(next()) ) )
+ {
+ trackParam = *((AliMUONTrackParam*) (track->GetTrackParamAtHit()->Last()));
+ AliMUONTrackExtrap::ExtrapToZ(&trackParam, AliMUONConstants::DefaultChamberZ(10)); // extrap to 1st trigger chamber
+
+ xTrack = trackParam.GetNonBendingCoor();
+ yTrack = trackParam.GetBendingCoor();
+ ySlopeTrack = trackParam.GetBendingSlope();
+
+ distTriggerTrack[0] = (triggerTrack->GetX11()-xTrack)/kDistSigma[0];
+ distTriggerTrack[1] = (triggerTrack->GetY11()-yTrack)/kDistSigma[1];
+ distTriggerTrack[2] = (TMath::Tan(triggerTrack->GetThetay())-ySlopeTrack)/kDistSigma[2];
+ chi2 = 0.;
+ for (Int_t iVar = 0; iVar < 3; iVar++) chi2 += distTriggerTrack[iVar]*distTriggerTrack[iVar];
+ chi2 /= 3.; // Normalized Chi2: 3 degrees of freedom (X,Y,slopeY)
+ if (chi2 < kMaxChi2MatchTrigger) return kTRUE;
+ }
+
+ return kFALSE;
+}
+
+
+//_____________________________________________________________________________
+void AliMUONTriggerChamberEff::SaveInESDFile()
+{
+ //
+ /// Store AliMUONTriggerChamberEff in esd file
+ //
+ TDirectory *dir = gDirectory;
+ TFile *logFile = 0x0;
+ TSeqCollection *list = gROOT->GetListOfFiles();
+ Int_t n = list->GetEntries();
+ for(Int_t i=0; i<n; i++) {
+ logFile = (TFile*)list->At(i);
+ if (strstr(logFile->GetName(), "AliESDs.root")) break;
+ }
+ if(logFile){
+ TTree *esdTree = (TTree*)logFile->Get("esdTree");
+ if(esdTree){
+ if(!esdTree->GetUserInfo()->FindObject("AliMUONTriggerChamberEff")){
+ AliInfo(Form("Adding AliMUONTrigChamberEff in %s",logFile->GetName()));
+ esdTree->GetUserInfo()->Add(this->Clone());
+ esdTree->Write("",TObject::kOverwrite);
+ }
+ }
+ }
+ dir->cd();
+}