Skip to content
Snippets Groups Projects
Select Git revision
  • f9e0943e376629bbafd30654960ba472592f25f3
  • master default protected
  • nightly_master
  • online_much_readconf_cleanup protected
  • online_mvd_readconf_cleanup protected
  • jul25_patches
  • cleanup_rich_v25a
  • jul24_patches
  • nov23_patches
  • DC_2404
  • nighly_master
  • DC_Jan24
  • DC_Nov23
  • DC_Oct23
  • feb23_patches
  • L1Algo-dev9
  • dec21_patches protected
  • apr21_patches protected
  • dev_2025_43
  • dev_2025_42
  • dev_2025_41
  • dev_2025_40
  • dev_2025_39
  • dev_2025_38
  • dev_2025_37
  • dev_2025_36
  • dev_2025_35
  • dev_2025_34
  • dev_2025_33
  • dev_2025_32
  • dev_2025_31
  • dev_2025_30
  • RC_jul25
  • dev_2025_29
  • dev_2025_28
  • dev_2025_27
  • dev_2025_26
  • dev_2025_25
38 results

DeviceImage.cxx

Blame
  • 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)