Select Git revision
DeviceImage.cxx
CbmMuchModuleGemRectangular.cxx 9.79 KiB
/* Copyright (C) 2012-2020 Petersburg Nuclear Physics Institute named by B.P.Konstantinov of National Research Centre "Kurchatov Institute", Gatchina
SPDX-License-Identifier: GPL-3.0-only
Authors: Mikhail Ryzhinskiy, Evgeny Kryshen [committer] */
/** CbmMuchModuleGemRectangular.cxx
*@author M.Ryzhinskiy <m.ryzhinskiy@gsi.de>
*@version 1.0
*@since 11.02.08
**
** This class holds the transport geometry parameters
** of one side of MuCh module.
**/
#include "CbmMuchModuleGemRectangular.h"
#include "CbmMuchPadRectangular.h" // for CbmMuchPadRectangular
#include "CbmMuchSectorRectangular.h" // for CbmMuchSectorRectangular
#include <TMathBase.h> // for Abs
#include <algorithm> // for find
#include <limits> // for numeric_limits
#include <vector> // for vector, vector<>::iterator
using std::vector;
// ----- Default constructor -------------------------------------------
CbmMuchModuleGemRectangular::CbmMuchModuleGemRectangular()
: CbmMuchModuleGem()
, fUseModuleDesign(kFALSE)
, fGridNx(0)
, fGridNy(0)
, fGridDx(0.)
, fGridDy(0.)
, fGrid()
{
fDetectorType = 1;
}
// -------------------------------------------------------------------------
// ----- Standard constructor ------------------------------------------
CbmMuchModuleGemRectangular::CbmMuchModuleGemRectangular(Int_t iStation, Int_t iLayer, Bool_t iSide, Int_t iModule,
TVector3 position, TVector3 size, Double_t cutRadius)
: CbmMuchModuleGem(iStation, iLayer, iSide, iModule, position, size, cutRadius)
, fUseModuleDesign(kFALSE)
, fGridNx(0)
, fGridNy(0)
, fGridDx(0.)
, fGridDy(0.)
, fGrid()
{
fDetectorType = 1;
}
// -------------------------------------------------------------------------
// ----- Public method GetSector ---------------------------------------
CbmMuchSectorRectangular* CbmMuchModuleGemRectangular::GetSector(Int_t ix, Int_t iy)
{
if (ix < 0 || ix >= fGridNx) return nullptr;
if (iy < 0 || iy >= fGridNy) return nullptr;
Long64_t iSector = fGrid[ix][iy];
if (iSector == -1) return nullptr;
return (CbmMuchSectorRectangular*) fSectors[iSector];
}
// -------------------------------------------------------------------------
// ----- Public method GetSector ---------------------------------------
CbmMuchSectorRectangular* CbmMuchModuleGemRectangular::GetSector(Double_t x, Double_t y){
return GetSector(GetGridIndexX(x), GetGridIndexY(y));
}
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
Int_t CbmMuchModuleGemRectangular::GetGridIndexX(Double_t x)
{
Double_t mx0 = fPosition[0];
Double_t mlx = fSize[0];
Double_t msx = mx0 > 0 ? +1 : -1;
Double_t mx1 = mx0 - msx * mlx / 2;
return Int_t((x - mx1) / msx / fGridDx);
}
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
Int_t CbmMuchModuleGemRectangular::GetGridIndexY(Double_t y)
{
Double_t my0 = fPosition[1];
Double_t mly = fSize[1];
Double_t msy = my0 > 0 ? +1 : -1;
Double_t my1 = my0 - msy * mly / 2;
return Int_t((y - my1) / msy / fGridDy);
}
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
CbmMuchPadRectangular* CbmMuchModuleGemRectangular::GetPad(Double_t x, Double_t y)
{
CbmMuchSectorRectangular* sector = GetSector(x, y);
if (!sector) return nullptr;
return sector->GetPad(x, y);
}
// -------------------------------------------------------------------------
// ----- Public method InitGrid -----------------------------------------
Bool_t CbmMuchModuleGemRectangular::InitGrid(Bool_t useModuleDesign)
{
Int_t nSectors = GetNSectors();
if (!nSectors) return kFALSE;
fUseModuleDesign = useModuleDesign;
Double_t mx0 = fPosition[0];
Double_t my0 = fPosition[1];
Double_t mlx = fSize[0];
Double_t mly = fSize[1];
Double_t msx = mx0 > 0 ? +1 : -1;
Double_t msy = my0 > 0 ? +1 : -1;
Double_t mx1 = mx0 - msx * mlx / 2;
Double_t my1 = my0 - msy * mly / 2;
// Determine grid dimensions
fGridDx = std::numeric_limits<Double_t>::max();
fGridDy = std::numeric_limits<Double_t>::max();
for (Int_t iSector = 0; iSector < nSectors; iSector++) {
CbmMuchSectorRectangular* s = (CbmMuchSectorRectangular*) fSectors[iSector];
if (s->IsIncomplete()) continue;
Double_t dx = s->GetSize()[0];
Double_t dy = s->GetSize()[1];
if (dx < fGridDx) fGridDx = dx;
if (dy < fGridDy) fGridDy = dy;
}
Int_t nCell = fUseModuleDesign ? 1 : 2; // Number of additional columns/rows in the grid
fGridNx = Int_t((mlx + 1e-5) / fGridDx) + nCell;
fGridNy = Int_t((mly + 1e-5) / fGridDy) + nCell;
// Fill grid fGrid.resize(fGridNx);
for (Int_t ix = 0; ix < fGridNx; ix++) {
fGrid[ix].resize(fGridNy);
for (Int_t iy = 0; iy < fGridNy; iy++) {
Double_t x = mx1 + msx * fGridDx * (ix + 1e-3);
Double_t y = my1 + msy * fGridDy * (iy + 1e-3);
fGrid[ix][iy] = -1;
for (int iSector = 0; iSector < nSectors; iSector++) {
CbmMuchSectorRectangular* sec = (CbmMuchSectorRectangular*) fSectors[iSector];
if (sec->Inside(x, y)) {
fGrid[ix][iy] = sec->GetSectorIndex();
break;
}
}
}
}
return kTRUE;
}
// -------------------------------------------------------------------------
// ------ Public method InitNeighbours ------------------------------------
void CbmMuchModuleGemRectangular::InitNeighbourSectors()
{
vector<CbmMuchSectorRectangular*> neighbours;
vector<CbmMuchSectorRectangular*>::iterator it;
for (Int_t iSector = 0; iSector < GetNSectors(); iSector++) {
CbmMuchSectorRectangular* sector = (CbmMuchSectorRectangular*) fSectors[iSector];
Double_t x1 = sector->GetX1() - 1e-3;
Double_t x2 = sector->GetX2() + 1e-3;
Double_t y1 = sector->GetY1() - 1e-3;
Double_t y2 = sector->GetY2() + 1e-3;
Double_t ix1 = GetGridIndexX(x1);
Double_t ix2 = GetGridIndexX(x2);
Double_t iy1 = GetGridIndexY(y1);
Double_t iy2 = GetGridIndexY(y2);
Double_t ixmin = (ix1 < ix2) ? ix1 : ix2;
Double_t ixmax = (ix1 < ix2) ? ix2 : ix1;
Double_t iymin = (iy1 < iy2) ? iy1 : iy2;
Double_t iymax = (iy1 < iy2) ? iy2 : iy1;
if (ixmin < 0) ixmin = 0;
if (ixmax >= fGridNx) ixmax = fGridNx - 1;
if (iymin < 0) iymin = 0;
if (iymax >= fGridNy) iymax = fGridNy - 1;
for (Int_t ix = ixmin; ix <= ixmax; ix++) {
for (Int_t iy = iymin; iy <= iymax; iy++) {
Int_t iSec = fGrid[ix][iy];
if (iSec < 0) continue;
if (iSec == iSector) continue;
CbmMuchSectorRectangular* sec = (CbmMuchSectorRectangular*) fSectors[iSec];
it = find(neighbours.begin(), neighbours.end(), sec);
if (it == neighbours.end()) neighbours.push_back(sec);
}
}
sector->SetNeighbours(neighbours);
neighbours.clear();
}
}
// -------------------------------------------------------------------------
// ------ Public method InitNeighbourPads ----------------------------------
void CbmMuchModuleGemRectangular::InitNeighbourPads()
{
vector<CbmMuchPad*>::iterator it;
vector<CbmMuchPad*> neighbours;
// Loop over all sectors within the module
for (Int_t iSector = 0; iSector < GetNSectors(); iSector++) {
CbmMuchSectorRectangular* sector = (CbmMuchSectorRectangular*) fSectors[iSector];
if (!sector) continue; Double_t mindx = sector->GetPadDx();
Double_t mindy = sector->GetPadDy();
vector<CbmMuchSectorRectangular*> neighbourSectors = sector->GetNeighbours();
for (UInt_t iSec = 0; iSec < neighbourSectors.size(); iSec++) {
CbmMuchSectorRectangular* sec = neighbourSectors[iSec];
Double_t dx = sec->GetPadDx();
Double_t dy = sec->GetPadDy();
if (dx < mindx) mindx = dx;
if (dy < mindy) mindy = dy;
}
for (Int_t iChannel = 0; iChannel < sector->GetNChannels(); iChannel++) {
CbmMuchPadRectangular* pad = (CbmMuchPadRectangular*) sector->GetPadByChannelIndex(iChannel);
Double_t x1 = pad->GetX1();
Double_t x2 = pad->GetX2();
Double_t y1 = pad->GetY1();
Double_t y2 = pad->GetY2();
for (Double_t x = x1 - mindx / 2; x < x2 + mindx / 2 + 1e-3; x += mindx) {
for (Double_t y = y1 - mindy / 2; y < y2 + mindy / 2 + 1e-3; y += mindy) {
CbmMuchPad* p = GetPad(x, y);
if (!p) continue;
if (p == pad) continue;
it = find(neighbours.begin(), neighbours.end(), p);
if (it == neighbours.end()) neighbours.push_back(p);
}
}
pad->SetNeighbours(neighbours);
neighbours.clear();
}
}
}
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
Bool_t CbmMuchModuleGemRectangular::InitModule()
{
Bool_t useModuleDesign = TMath::Abs(fPosition[0]) > 1e-5 || TMath::Abs(fPosition[1]) > 1e-5;
if (!InitGrid(useModuleDesign)) return kFALSE;
InitNeighbourSectors();
for (Int_t iSector = 0; iSector < GetNSectors(); iSector++) {
CbmMuchSectorRectangular* sector = (CbmMuchSectorRectangular*) fSectors[iSector];
if (!sector) continue;
sector->AddPads();
}
InitNeighbourPads();
return kTRUE;
}
// -------------------------------------------------------------------------
ClassImp(CbmMuchModuleGemRectangular)