/************************************************************************** * 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$ */ // Class AliMUONSt12QuadrantSegmentation // ------------------------------------- // Segmentation for MUON quadrants of stations 1 and 2 using // the mapping package // // Author: Ivana Hrivnacova, IPN Orsay #include #include #include #include #include "AliMpPad.h" #include "AliMpArea.h" #include "AliMpSectorReader.h" #include "AliMpSector.h" #include "AliMpVPadIterator.h" #include "AliMpSectorSegmentation.h" #include "AliMUONSt12QuadrantSegmentation.h" #include "AliRun.h" #include "AliMUON.h" #include "AliMUONChamber.h" #include "AliLog.h" #include "AliMpFiles.h" #include "AliMpNeighboursPadIterator.h" #include ClassImp(AliMUONSt12QuadrantSegmentation) const Float_t AliMUONSt12QuadrantSegmentation::fgkWireD = 0.21; const Float_t AliMUONSt12QuadrantSegmentation::fgkLengthUnit = 0.1; //______________________________________________________________________________ AliMUONSt12QuadrantSegmentation::AliMUONSt12QuadrantSegmentation( AliMpStationType stationType, AliMpPlaneType planeType) : AliMUONVGeometryDESegmentation(), fStationType(stationType), fPlaneType(planeType), fSector(0), fSectorSegmentation(0), fSectorIterator(0), fWireD(fgkWireD), fChamber(0), fId(0), fRmin(0.), fRmax(0.), fZ(0.), fIx(0), fIy(0), fX(0.), fY(0.), fZone(0), fXhit(0.), fYhit(0.), fIxt(0), fIyt(0), fIwt(0), fXt(0.), fYt(0.), fCorrA(0) { // Normal constructor ReadMappingData(); fCorrA = new TObjArray(3); fCorrA->AddAt(0,0); fCorrA->AddAt(0,1); fCorrA->AddAt(0,2); } //______________________________________________________________________________ AliMUONSt12QuadrantSegmentation::AliMUONSt12QuadrantSegmentation() : AliMUONVGeometryDESegmentation(), fStationType(kStation1), fPlaneType(kBendingPlane), fSector(0), fSectorSegmentation(0), fSectorIterator(0), fWireD(fgkWireD), fChamber(0), fId(0), fRmin(0.), fRmax(0.), fZ(0.), fIx(0), fIy(0), fX(0.), fY(0.), fZone(0), fXhit(0.), fYhit(0.), fIxt(0), fIyt(0), fIwt(0), fXt(0.), fYt(0.), fCorrA(0) { // Default Constructor } //______________________________________________________________________________ AliMUONSt12QuadrantSegmentation::AliMUONSt12QuadrantSegmentation(const AliMUONSt12QuadrantSegmentation& rhs) : AliMUONVGeometryDESegmentation(rhs) { // Copy constructor AliFatal("Copy constructor is not implemented."); } //______________________________________________________________________________ AliMUONSt12QuadrantSegmentation::~AliMUONSt12QuadrantSegmentation() { // Destructor delete fSector; delete fSectorSegmentation; delete fSectorIterator; } // // operators // //______________________________________________________________________________ AliMUONSt12QuadrantSegmentation& AliMUONSt12QuadrantSegmentation::operator=(const AliMUONSt12QuadrantSegmentation& rhs) { // Copy operator // check assignement to self if (this == &rhs) return *this; AliFatal("Assignment operator is not implemented."); return *this; } // // private methods // //______________________________________________________________________________ void AliMUONSt12QuadrantSegmentation::UpdateCurrentPadValues(const AliMpPad& pad) { // Updates current pad values. // --- fIx = pad.GetIndices().GetFirst(); fIy = pad.GetIndices().GetSecond(); fX = pad.Position().X() * fgkLengthUnit; fY = pad.Position().Y() * fgkLengthUnit; fZone = fSectorSegmentation->Zone(pad); } //______________________________________________________________________________ void AliMUONSt12QuadrantSegmentation::ReadMappingData() { // Reads mapping data // --- // set path to mapping data files if (!gSystem->Getenv("MINSTALL")) { TString dirPath = gSystem->Getenv("ALICE_ROOT"); dirPath += "/MUON/mapping"; AliMpFiles::Instance()->SetTopPath(dirPath); gSystem->Setenv("MINSTALL", dirPath.Data()); //cout << "AliMpFiles top path set to " << dirPath << endl; } AliMpSectorReader r(fStationType, fPlaneType); fSector = r.BuildSector(); fSectorSegmentation = new AliMpSectorSegmentation(fSector); } // // public methods // //______________________________________________________________________________ void AliMUONSt12QuadrantSegmentation::SetPadSize(Float_t /*p1*/, Float_t /*p2*/) { // Set pad size Dx*Dy // --- AliFatal("Not uniform pad size."); } //______________________________________________________________________________ void AliMUONSt12QuadrantSegmentation::SetDAnod(Float_t d) { // Set anod pitch // --- fWireD = d; } #include "AliMpMotifMap.h" //______________________________________________________________________________ Bool_t AliMUONSt12QuadrantSegmentation::HasPad(Float_t x, Float_t y, Float_t /*z*/) { // Returns true if a pad exists in the given position // fSector->GetMotifMap()->Print(); AliMpPad pad = fSectorSegmentation ->PadByPosition(TVector2(x/fgkLengthUnit, y/fgkLengthUnit), false); return pad.IsValid(); } //______________________________________________________________________________ Bool_t AliMUONSt12QuadrantSegmentation::HasPad(Int_t ix, Int_t iy) { // Returns true if a pad with given indices exists AliMpPad pad = fSectorSegmentation->PadByIndices(AliMpIntPair(ix,iy), false); return pad.IsValid(); } //______________________________________________________________________________ AliMUONGeometryDirection AliMUONSt12QuadrantSegmentation::GetDirection() { // Returns the direction with a constant pad size // (Direction or coordinate where the resolution is the best) switch ( fSector->GetDirection() ) { case kX: return kDirX; case kY: return kDirY; default: return kDirUndefined; } } //______________________________________________________________________________ const AliMpSectorSegmentation* AliMUONSt12QuadrantSegmentation::GetMpSegmentation() const { // Returns the mapping segmentation // (provides access to electronics info) return fSectorSegmentation; } //______________________________________________________________________________ Float_t AliMUONSt12QuadrantSegmentation::GetAnod(Float_t xhit) const { // Anod wire coordinate closest to xhit // Returns for a hit position xhit the position of the nearest anode wire // From AliMUONSegmentationV01. // --- Float_t wire= (xhit>0) ? Int_t(xhit/fWireD) + 0.5 : Int_t(xhit/fWireD) - 0.5; return fWireD*wire; } //______________________________________________________________________________ void AliMUONSt12QuadrantSegmentation::GetPadI(Float_t x, Float_t y, Float_t /*z*/, Int_t& ix, Int_t& iy) { // Returns pad coordinates (ix,iy) for given real coordinates (x,y) // --- GetPadI(x, y, ix, iy); } //______________________________________________________________________________ void AliMUONSt12QuadrantSegmentation::GetPadI(Float_t x, Float_t y, Int_t& ix, Int_t& iy) { // Returns pad coordinates (ix,iy) for given real coordinates (x,y) // If there is no pad, ix = 0, iy = 0 are returned. // --- AliMpPad pad = fSectorSegmentation ->PadByPosition(TVector2(x/fgkLengthUnit, y/fgkLengthUnit), true); ix = pad.GetIndices().GetFirst(); iy = pad.GetIndices().GetSecond(); } //______________________________________________________________________________ void AliMUONSt12QuadrantSegmentation::GetPadC(Int_t ix, Int_t iy, Float_t& x, Float_t& y, Float_t& z) { // Transform from pad to real coordinates // --- z = fZ; GetPadC(ix, iy, x , y); } //______________________________________________________________________________ void AliMUONSt12QuadrantSegmentation::GetPadC(Int_t ix, Int_t iy, Float_t& x, Float_t& y) { // Transform from pad to real coordinates // If there is no pad, x = 0., y = 0. are returned. // --- AliMpPad pad = fSectorSegmentation->PadByIndices(AliMpIntPair(ix,iy), true); x = pad.Position().X() * fgkLengthUnit; y = pad.Position().Y() * fgkLengthUnit; } //______________________________________________________________________________ void AliMUONSt12QuadrantSegmentation::Init(Int_t chamber) { // Initialize segmentation // --- // find Npx, Npy and save this info // reference to chamber AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON"); fChamber = &(pMUON->Chamber(chamber)); fRmin=fChamber->RInner(); fRmax=fChamber->ROuter(); fZ = 0; fId=chamber; } //______________________________________________________________________________ Float_t AliMUONSt12QuadrantSegmentation::Dpx() const { // Get pad size in x // --- AliFatal( "Not uniform pad size."); return 0.; } //______________________________________________________________________________ Float_t AliMUONSt12QuadrantSegmentation::Dpy() const { // Get pad size in y // --- AliFatal("Not uniform pad size."); return 0.; } //______________________________________________________________________________ Float_t AliMUONSt12QuadrantSegmentation::Dpx(Int_t isector) const { // Pad size in x by sector // --- return fSectorSegmentation->PadDimensions(isector).X()*2.*fgkLengthUnit; } //______________________________________________________________________________ Float_t AliMUONSt12QuadrantSegmentation::Dpy(Int_t isector) const { // Pad size in x, y by Sector // --- return fSectorSegmentation->PadDimensions(isector).Y()*2.*fgkLengthUnit; } //______________________________________________________________________________ Int_t AliMUONSt12QuadrantSegmentation::Npx() const { // Maximum number of Pads in x // hard coded for the time being // --- return fSectorSegmentation->MaxPadIndexX(); } //______________________________________________________________________________ Int_t AliMUONSt12QuadrantSegmentation::Npy() const { // Maximum number of Pads in y // hard coded for the time being // --- return fSectorSegmentation->MaxPadIndexY(); } //______________________________________________________________________________ void AliMUONSt12QuadrantSegmentation::SetPad(Int_t ix, Int_t iy) { // Set pad position. // Sets virtual pad coordinates, needed for evaluating pad response // outside the tracking program. // From AliMUONSegmentationV01. // --- GetPadC(ix, iy, fX, fY); fZone = Sector(ix, iy); } //______________________________________________________________________________ void AliMUONSt12QuadrantSegmentation::SetHit(Float_t xhit, Float_t yhit, Float_t /*zhit*/) { // Set hit position // Sets virtual hit position, needed for evaluating pad response // outside the tracking program // From AliMUONSegmentationV01. fXhit = xhit; fYhit = yhit; } //______________________________________________________________________________ void AliMUONSt12QuadrantSegmentation::FirstPad(Float_t xhit, Float_t yhit, Float_t /*zhit*/, Float_t dx, Float_t dy) { // Iterate over pads - initialiser // --- // Sets the current pad to that located in the hit position SetHit(GetAnod(xhit), yhit, 0.); // Enable iterating in one dimension if (dx == 0.) dx = 0.01; if (dy == 0.) dy = 0.01; // Delete previous iterator delete fSectorIterator; fSectorIterator = fSectorSegmentation ->CreateIterator(AliMpArea(TVector2(fXhit/fgkLengthUnit, fYhit/fgkLengthUnit), TVector2(dx/fgkLengthUnit, dy/fgkLengthUnit))); fSectorIterator->First(); if (! fSectorIterator->IsDone()) UpdateCurrentPadValues(fSectorIterator->CurrentItem()); } //______________________________________________________________________________ void AliMUONSt12QuadrantSegmentation::NextPad() { // Iterate over pads - stepper // --- fSectorIterator->Next(); if (! fSectorIterator->IsDone()) UpdateCurrentPadValues(fSectorIterator->CurrentItem()); } //______________________________________________________________________________ Int_t AliMUONSt12QuadrantSegmentation::MorePads() { // Iterate over pads - condition // --- if (fSectorIterator->IsDone()) return 0; else return 1; } //______________________________________________________________________________ Float_t AliMUONSt12QuadrantSegmentation::Distance2AndOffset(Int_t iX, Int_t iY, Float_t x, Float_t y, Int_t* /*dummy*/) { // Returns the square of the distance between 1 pad // labelled by its channel numbers and a coordinate // --- AliMpPad pad = fSectorSegmentation->PadByIndices(AliMpIntPair(iX, iY)); if (!pad.IsValid()) AliFatal("Cannot locate pad."); return (pad.Position()*fgkLengthUnit - TVector2(x, y)).Mod2(); } //______________________________________________________________________________ void AliMUONSt12QuadrantSegmentation::GetNParallelAndOffset(Int_t /*iX*/, Int_t /*iY*/, Int_t* /*Nparallel*/, Int_t* /*Offset*/) { // Number of pads read in parallel and offset to add to x // (specific to LYON, but mandatory for display) // --- AliFatal( "Not yet implemented."); } //______________________________________________________________________________ void AliMUONSt12QuadrantSegmentation::Neighbours(Int_t iX, Int_t iY, Int_t* Nlist, Int_t Xlist[10], Int_t Ylist[10]) { // Get next neighbours // --- AliMpPad pad = fSectorSegmentation->PadByIndices(AliMpIntPair(iX,iY)); Int_t &i = *Nlist; i=0; AliMpNeighboursPadIterator iter = AliMpNeighboursPadIterator(fSectorSegmentation, pad, kFALSE); for( iter.First(); !iter.IsDone() && i<10; iter.Next()) { Xlist[i] = iter.CurrentItem().GetIndices().GetFirst(); Ylist[i] = iter.CurrentItem().GetIndices().GetSecond(); i++; } } //______________________________________________________________________________ Int_t AliMUONSt12QuadrantSegmentation::Ix() { // Current pad cursor during disintegration // x, y-coordinate // --- return fSectorIterator->CurrentItem().GetIndices().GetFirst(); } //______________________________________________________________________________ Int_t AliMUONSt12QuadrantSegmentation::Iy() { // Current pad cursor during disintegration // x, y-coordinate // --- return fSectorIterator->CurrentItem().GetIndices().GetSecond(); } //______________________________________________________________________________ Int_t AliMUONSt12QuadrantSegmentation::ISector() { // Current sector // --- return fZone; } //______________________________________________________________________________ Int_t AliMUONSt12QuadrantSegmentation::Sector(Int_t ix, Int_t iy) { // Calculate sector from pad coordinates // --- return fSectorSegmentation ->Zone(fSectorSegmentation->PadByIndices(AliMpIntPair(ix, iy))); } //______________________________________________________________________________ Int_t AliMUONSt12QuadrantSegmentation::Sector(Float_t x, Float_t y) { // Calculate sector from pad coordinates // --- return fSectorSegmentation ->Zone(fSectorSegmentation ->PadByPosition(TVector2(x/fgkLengthUnit, y/fgkLengthUnit))); } //______________________________________________________________________________ void AliMUONSt12QuadrantSegmentation::IntegrationLimits(Float_t& x1, Float_t& x2, Float_t& y1, Float_t& y2) { // Current integration limits // --- x1 = fXhit - fX - Dpx(fZone)/2.; x2 = x1 + Dpx(fZone); y1 = fYhit - fY - Dpy(fZone)/2.; y2 = y1 + Dpy(fZone); } //______________________________________________________________________________ Int_t AliMUONSt12QuadrantSegmentation::SigGenCond(Float_t x, Float_t y, Float_t /*z*/) { // Signal Generation Condition during Stepping // 0: don't generate signal // 1: generate signal // Comments: // // Crossing of pad boundary and mid plane between neighbouring wires is checked. // To correctly simulate the dependence of the spatial resolution on the angle // of incidence signal must be generated for constant steps on // the projection of the trajectory along the anode wire. // // Signal will be generated if particle crosses pad boundary or // boundary between two wires. // // From AliMUONSegmentationV01 // --- Int_t ixt, iyt; GetPadI(x, y, ixt, iyt); Int_t iwt=(x>0) ? Int_t(x/fWireD)+1 : Int_t(x/fWireD)-1; if ((ixt != fIxt) || (iyt !=fIyt) || (iwt != fIwt)) { return 1; } else { return 0; } } //______________________________________________________________________________ void AliMUONSt12QuadrantSegmentation::SigGenInit(Float_t x, Float_t y, Float_t /*z*/) { // Initialise signal generation at coord (x,y,z) // Initialises pad and wire position during stepping. // From AliMUONSegmentationV01 // --- fXt = x; fYt = y; GetPadI(x, y, fIxt, fIyt); fIwt = (x>0) ? Int_t(x/fWireD)+1 : Int_t(x/fWireD)-1 ; } //______________________________________________________________________________ void AliMUONSt12QuadrantSegmentation::GiveTestPoints(Int_t& n, Float_t* x, Float_t* y) const { // Test points for auto calibration // Returns test point on the pad plane. // Used during determination of the segmoid correction of the COG-method // From AliMUONSegmentationV01 // --- n=1; x[0] = (fRmax+fRmin)/2/TMath::Sqrt(2.); y[0] = x[0]; } //______________________________________________________________________________ void AliMUONSt12QuadrantSegmentation::Draw(const char * /*opt*/) { // Draw the segmentation zones. // (Called from AliMUON::BuildGeometry) // --- AliWarning("Not yet implemented."); } //______________________________________________________________________________ void AliMUONSt12QuadrantSegmentation::SetCorrFunc(Int_t isec, TF1* func) { // Set the correction function. // From AliMUONSegmentationV01 // --- fCorrA->AddAt(func, isec); } //______________________________________________________________________________ TF1* AliMUONSt12QuadrantSegmentation::CorrFunc(Int_t isec) const { // Get the correction Function. // From AliMUONSegmentationV01 // --- return (TF1*) fCorrA->At(isec); } //______________________________________________________________________________ void AliMUONSt12QuadrantSegmentation::Streamer(TBuffer &R__b) { // Stream an object of class AliMUONSt12QuadrantSegmentation. if (R__b.IsReading()) { AliMUONSt12QuadrantSegmentation::Class()->ReadBuffer(R__b, this); ReadMappingData(); } else { AliMUONSt12QuadrantSegmentation::Class()->WriteBuffer(R__b, this); } }