/** CbmMuchSector.cxx *@author M.Ryzhinskiy *@since 15.03.07 *@version 1.0 ** ** This class describes the digitization scheme for a sector of the MuCh. ** The sector is a rectangle of size fLx and fLy. The following ** types are implemented: ** 1 = GEMs ** 2 = CPCs **/ #include using std::cout; using std::endl; #include "TMath.h" #include "CbmMuchSector.h" #include "CbmMuchSectorDigiPar.h" // ----- Default constructor ------------------------------------------- CbmMuchSector::CbmMuchSector() { fDetectorId = 0; fX0 = fY0 = fRotation = fLx = fLy = fDx = fDy = 0.; fSinRot = TMath::Sin(fRotation); fCosRot = TMath::Cos(fRotation); fNChannels = 0; fSigmaX = fSigmaY = fSigmaXY = 0.; cout << "-W- CbmMuchSector: Do not use this constructor! " << endl; } // ------------------------------------------------------------------------- // ----- Enhanced constructor (by z0 and d) ------------------------------------------ CbmMuchSector::CbmMuchSector(TString tempName, Int_t detId, Int_t iType, Double_t x0, Double_t y0, Double_t z0, Double_t rotation, Double_t lx, Double_t ly, Double_t d, Double_t dx, Double_t dy, Int_t iChannels) { fName = tempName.Data(); fDetectorId = detId; fType = iType; fX0 = x0; fY0 = y0; fZ0 = z0; // z position of the station fRotation = rotation; fSinRot = TMath::Sin(fRotation); fCosRot = TMath::Cos(fRotation); fLx = lx; fLy = ly; fD = d; // thickness of the station fDx = dx; fDy = dy; if ( fType == 1 || fType == 2) { // GEMs or CPCs // Define number of channels fNChannels = iChannels; // calculate errors fSigmaX = fDx / TMath::Sqrt(12); fSigmaY = fDy / TMath::Sqrt(12); fSigmaXY = 0.; } else { cout << "-E- CbmMuchSector: Illegal sector type " << fType << endl; Fatal("", "Illegal sector type"); } // Transform errors to global c.s. Double_t vX = fCosRot * fCosRot * fSigmaX * fSigmaX - 2. * fCosRot * fSinRot * fSigmaXY + fSinRot * fSinRot * fSigmaY * fSigmaY; Double_t vY = fSinRot * fSinRot * fSigmaX * fSigmaX + 2. * fCosRot * fSinRot * fSigmaXY + fCosRot * fCosRot * fSigmaY * fSigmaY; Double_t vXY = fCosRot * fSinRot * fSigmaX * fSigmaX + ( fCosRot*fCosRot - fSinRot*fSinRot ) * fSigmaXY - fCosRot * fSinRot * fSigmaY * fSigmaY; fSigmaX = TMath::Sqrt(vX); fSigmaY = TMath::Sqrt(vY); fSigmaXY = vXY; } // ------------------------------------------------------------------------- // ----- Standard constructor ------------------------------------------ CbmMuchSector::CbmMuchSector(Int_t detId, Int_t iType, Double_t x0, Double_t y0, Double_t rotation, Double_t lx, Double_t ly, Double_t dx, Double_t dy, Int_t iChannels) { fDetectorId = detId; fType = iType; fX0 = x0; fY0 = y0; fRotation = rotation; fSinRot = TMath::Sin(fRotation); fCosRot = TMath::Cos(fRotation); fLx = lx; fLy = ly; fDx = dx; fDy = dy; if ( fType == 1 || fType == 2) { // GEMs or CPCs // Define number of channels fNChannels = iChannels; // calculate errors fSigmaX = fDx / TMath::Sqrt(12); fSigmaY = fDy / TMath::Sqrt(12); fSigmaXY = 0.; } else { cout << "-E- CbmMuchSector: Illegal sector type " << fType << endl; Fatal("", "Illegal sector type"); } // Transform errors to global c.s. Double_t vX = fCosRot * fCosRot * fSigmaX * fSigmaX - 2. * fCosRot * fSinRot * fSigmaXY + fSinRot * fSinRot * fSigmaY * fSigmaY; Double_t vY = fSinRot * fSinRot * fSigmaX * fSigmaX + 2. * fCosRot * fSinRot * fSigmaXY + fCosRot * fCosRot * fSigmaY * fSigmaY; Double_t vXY = fCosRot * fSinRot * fSigmaX * fSigmaX + ( fCosRot*fCosRot - fSinRot*fSinRot ) * fSigmaXY - fCosRot * fSinRot * fSigmaY * fSigmaY; fSigmaX = TMath::Sqrt(vX); fSigmaY = TMath::Sqrt(vY); fSigmaXY = vXY; } // ------------------------------------------------------------------------- // ----- Destructor ---------------------------------------------------- CbmMuchSector::~CbmMuchSector() { }; // ------------------------------------------------------------------------- // ----- Public method GetChannel -------------------------------------- Int_t CbmMuchSector::GetChannel(Double_t x, Double_t y) { // Calculate internal coordinates. Return -1 if outside the sector. Double_t xint = 0; Double_t yint = 0; if ( ! IntCoord(x, y, xint, yint) ) return -1; Int_t iChan = 0; Int_t nCol = Int_t( (fLx+1e-7) / fDx); Int_t iCol = Int_t(xint / fDx); Int_t iRow = Int_t(yint / fDy); iChan = iRow * nCol + iCol; if (iChan < 0 || iChan > fNChannels-1) { cout << "-E- CbmMuchSector::GetChannel: " << "Channel number " << iChan << " exceeds limit " << fNChannels << endl; cout << GetStationNr() << " " << GetSectorNr() << endl; cout << x << " " << y << endl; Fatal("GetChannel", "illegal channel number"); } return iChan; } // ------------------------------------------------------------------------- // ----- Public method Inside ------------------------------------------ Bool_t CbmMuchSector::Inside(Double_t x, Double_t y) { Double_t xint, yint; return IntCoord(x, y, xint, yint); } // ------------------------------------------------------------------------- // ----- Public method ActivateChannels -------------------------------- Bool_t CbmMuchSector::ActivateChannels(Int_t ipt, Double_t x, Double_t y) { Int_t iPad = GetChannel(x, y); if (iPad < 0) return kFALSE; fActive.insert(iPad); fTrueHits[iPad] = ipt; return kTRUE; } // ------------------------------------------------------------------------- // ----- Public method PointIndex -------------------------------------- Int_t CbmMuchSector::GetPointIndex(Int_t iPad) { if (fTrueHits.find(iPad) == fTrueHits.end()) return -1; return fTrueHits[iPad]; } // ------------------------------------------------------------------------- // ----- Public method Reset ------------------------------------------- void CbmMuchSector::Reset() { fActive.clear(); fTrueHits.clear(); } // ------------------------------------------------------------------------- // ----- Public method Print ------------------------------------------- void CbmMuchSector::Print() { cout << " Sector Nr. "; cout.width(3); cout << GetSectorNr() << ", Type "; cout.width(1); cout << fType << ", centre ("; cout.width(6); cout << fX0 << ", "; cout.width(6); cout << fY0 << ") cm, rotation " ; cout.width(6); cout << fRotation*180./TMath::Pi() << " deg., lx = "; cout.width(3); cout << fLx << " cm, ly = "; cout.width(3); cout << fLy << " cm, channels: " << GetNChannels() << endl; } // ------------------------------------------------------------------------- // ----- Private method IntCoord --------------------------------------- Bool_t CbmMuchSector::IntCoord(Double_t x, Double_t y, Double_t& xint, Double_t& yint) const { // Translation into sector centre system x = x - fX0; y = y - fY0; // Rotation around the sector centre xint = x * fCosRot + y * fSinRot; yint = y * fCosRot - x * fSinRot; // Translation into sector corner system xint = xint + fLx/2.; yint = yint + fLy/2.; // Check whether point is inside the sector if ( ! IsInside(xint, yint) ) { // xint = yint = 0.; return kFALSE; } return kTRUE; } // ------------------------------------------------------------------------- // ----- Private method IsInside --------------------------------------- Bool_t CbmMuchSector::IsInside(Double_t xint, Double_t yint) const { if ( xint < 0. ) return kFALSE; if ( xint > fLx ) return kFALSE; if ( yint < 0. ) return kFALSE; if ( yint > fLy ) return kFALSE; return kTRUE; } // ------------------------------------------------------------------------- ClassImp(CbmMuchSector)