-
Eoin Clerkin authored
Decision to not use doxygen for licence headers. Removes doxygen formatting and file tag.
Eoin Clerkin authoredDecision to not use doxygen for licence headers. Removes doxygen formatting and file tag.
CbmTrdParModDigi.cxx 31.33 KiB
/* Copyright (C) 2018-2020 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
SPDX-License-Identifier: GPL-3.0-only
Authors: Florian Uhlig [committer] */
#include "CbmTrdParModDigi.h"
#include "CbmTrdAddress.h" // for CbmTrdAddress
#include "CbmTrdPoint.h" // for CbmTrdPoint
#include <Logger.h> // for LOG, Severity, Severity::debug2
#include <TGeoManager.h> // for TGeoManager, gGeoManager
#include <TString.h> // for TString
#include <TVector3.h> // for TVector3
#include <iomanip> // for setprecision, __iom_t5
#include <math.h> // for fabs
#include <stdio.h> // for printf
#include <string.h> // for strcmp
//___________________________________________________________________
CbmTrdParModDigi::CbmTrdParModDigi()
: CbmTrdParMod("CbmTrdParModDigi", "TRD read-out definition")
, fNofSectors(1)
, fOrientation(0)
, fAnodeWireOffset(0.375)
, fAnodeWireSpacing(0.25)
, fAnodeWireToPadPlaneDistance(0.35)
, fX(0.)
, fY(0.)
, fZ(0.)
, fSizeX(0)
, fSizeY(0)
, fSizeZ(0)
, fSectorX()
, fSectorY()
, fSectorZ()
, fSectorBeginX()
, fSectorBeginY()
, fSectorEndX()
, fSectorEndY()
, fSectorSizeX()
, fSectorSizeY()
, fPadSizeX()
, fPadSizeY()
{
}
//___________________________________________________________________
CbmTrdParModDigi::CbmTrdParModDigi(Double_t x, Double_t y, Double_t z, Double_t sizex, Double_t sizey, Double_t sizez,
Int_t nofSectors, Int_t orientation, const TArrayD& sectorSizeX,
const TArrayD& sectorSizeY, const TArrayD& padSizeX, const TArrayD& padSizeY)
: CbmTrdParMod("CbmTrdParModDigi", "TRD read-out definition")
, fNofSectors(nofSectors)
, fOrientation(orientation)
, fAnodeWireOffset(0.375)
, fAnodeWireSpacing(0.25)
, fAnodeWireToPadPlaneDistance(0.35)
, fX(x)
, fY(y)
, fZ(z)
, fSizeX(sizex)
, fSizeY(sizey)
, fSizeZ(sizez)
, fSectorX(nofSectors)
, fSectorY(nofSectors)
, fSectorZ(nofSectors)
, fSectorBeginX(nofSectors)
, fSectorBeginY(nofSectors)
, fSectorEndX(nofSectors)
, fSectorEndY(nofSectors)
, fSectorSizeX(sectorSizeX)
, fSectorSizeY(sectorSizeY)
, fPadSizeX(padSizeX)
, fPadSizeY(padSizeY)
{
/**
Calculate the coordinates of the begin and the end of each sector
as well as the coordinates of the center of the sector
In the moment it is assumed that there are sectors which have either
in x- or y-direction the size of the chamber.
*/
if (nofSectors > 1) {
Double_t beginx, beginy, endx, endy;
Double_t summed_sectsize;
if (sectorSizeX.GetAt(0) == 2 * sizex) { //substructure only in y-direction
beginx = 0;
endx = 2 * sizex;
summed_sectsize = 0;
for (Int_t i = 0; i < fNofSectors; i++) {
if (0 == i) {
beginy = 0.;
endy = sectorSizeY.GetAt(i);
summed_sectsize += sectorSizeY.GetAt(i);
}
else {
beginy = summed_sectsize;
endy = summed_sectsize += sectorSizeY.GetAt(i);
}
fSectorBeginX.AddAt(beginx, i);
fSectorBeginY.AddAt(beginy, i);
fSectorEndX.AddAt(endx, i);
fSectorEndY.AddAt(endy, i);
fSectorX.AddAt(beginx + (sectorSizeX.GetAt(i) / 2.), i);
fSectorY.AddAt(beginy + (sectorSizeY.GetAt(i) / 2.), i);
fSectorZ.AddAt(fZ, i);
}
}
else {
LOG(warn) << GetName()
<< "::CbmTrdParModDigi - detect different information on "
"module size x : geometry="
<< std::setprecision(5) << 2 * sizex << " CbmTrdPads.h=" << sectorSizeX.GetAt(0);
beginy = 0;
endy = 2 * sizey;
summed_sectsize = 0;
for (Int_t i = 0; i < fNofSectors; i++) {
if (0 == i) {
beginx = 0.;
endx = sectorSizeX.GetAt(i);
summed_sectsize += sectorSizeX.GetAt(i);
}
else {
beginx = summed_sectsize;
endx = summed_sectsize += sectorSizeX.GetAt(i);
}
fSectorBeginX.AddAt(beginx, i);
fSectorBeginY.AddAt(beginy, i);
fSectorEndX.AddAt(endx, i);
fSectorEndY.AddAt(endy, i);
fSectorX.AddAt(beginx + (sectorSizeX.GetAt(i) / 2.), i);
fSectorY.AddAt(beginy + (sectorSizeY.GetAt(i) / 2.), i);
fSectorZ.AddAt(fZ, i);
}
}
}
else {
fSectorBeginX.AddAt(0., 0);
fSectorBeginY.AddAt(0., 0);
fSectorEndX.AddAt(sectorSizeX.GetAt(0), 0);
fSectorEndY.AddAt(sectorSizeY.GetAt(0), 0);
fSectorX.AddAt(x, 0);
fSectorY.AddAt(y, 0);
fSectorZ.AddAt(z, 0);
}
}
//___________________________________________________________________________
void CbmTrdParModDigi::Print(Option_t* opt) const
{
/**
Dump formated parameters for this module
*/
printf(" CbmTrdParModDigi @ %5d ly[%d] idLy[%3d] rotation[%3ddeg] rows[%2d] "
"cols[%3d]\n",
fModuleId, CbmTrdAddress::GetLayerId(fModuleId), CbmTrdAddress::GetModuleId(fModuleId), fOrientation * 90,
GetNofRows(), GetNofColumns());
if (strcmp(opt, "all") != 0) return;
printf(" center [%7.2f %7.2f %7.2f]\n"
" size [%7.2f %7.2f %7.2f]\n"
" anode pitch[%5.3f] d2PP[%5.3f] off[%5.3f]\n"
" pads ",
fX, fY, fZ, fSizeX, fSizeY, fSizeZ, fAnodeWireSpacing, fAnodeWireToPadPlaneDistance, fAnodeWireOffset);
for (Int_t isec(0); isec < fNofSectors; isec++)
printf(" [c(%3d) r(%2d)]x[w(%4.2f) h(%5.2f)] area[%5.2fx%5.2f] limits "
"x[%5.2f %5.2f] y[%5.2f %5.2f]\n ",
GetNofColumnsInSector(isec), GetNofRowsInSector(isec), fPadSizeX.At(isec), fPadSizeY.At(isec),
fSectorSizeX[isec], fSectorSizeY[isec], fSectorBeginX[isec], fSectorEndX[isec], fSectorBeginY[isec],
fSectorEndY[isec]);
printf("\n");
}
//___________________________________________________________________________
void CbmTrdParModDigi::ProjectPositionToNextAnodeWire(Double_t* local_point) const
{
/**
Move the local point along y to the next anode wire position.
20131009 - DE - checked OK
*/
if (/*fAnodeWireOffset > 0.0 && */ fAnodeWireSpacing > 0.0) { // wires must be defined defined
// check, if the input is within the allowed range
if (fabs(local_point[1]) - fSizeY > 1.e-3)
LOG(error) << "CbmTrdParModDigi::ProjectPositionToNextAnodeWire - local "
"point must be within gas volume, y="
<< std::setprecision(5) << local_point[1] << " module size " << fSizeY;
Double_t ypos = local_point[1];
LOG(debug2) << "local y before projection: " << std::setprecision(5) << local_point[1] << " cm";
// make sure, local_point[1] is not negative (due to module center coordinate)
// therefore transform to local corner first and then back at the end of operation
local_point[1] += fSizeY; // transform to module corner coordinates
local_point[1] = Int_t(((local_point[1] - fAnodeWireOffset) / fAnodeWireSpacing) + 0.5) * fAnodeWireSpacing
+ fAnodeWireOffset; // find closest anode wire
if (local_point[1] > 2 * fSizeY - fAnodeWireOffset)
local_point[1] = 2 * fSizeY - fAnodeWireOffset; // move inwards to the last anode wire
local_point[1] -= fSizeY; // transform back to module center coordinates
LOG(debug2) << "local y after projection: " << std::setprecision(5) << local_point[1] << " cm";
// check, if we have left the anode wire grid
if (fabs(local_point[1]) > fSizeY - fAnodeWireOffset)
LOG(error) << "CbmTrdParModDigi::ProjectPositionToNextAnodeWire - local "
"point projected outside anode wire plane, from "
<< std::setprecision(5) << ypos << " to " << std::setprecision(5) << local_point[1]
<< " - last anode wire at " << std::setprecision(5) << fSizeY - fAnodeWireOffset;
}
else {
LOG(error) << "CbmTrdParModDigi::ProjectPositionToNextAnodeWire: "
"fAnodeWireOffset and fAnodeWireSpacing not set. "
"ProjectPositionToNextAnodeWire can not be used.";
}
}
//___________________________________________________________________________
Int_t CbmTrdParModDigi::GetSector(const Double_t* local_point) const
{
/**
Calculate the position in the chamber
with the origin of the local coordinate system
in the lower left corner of the chamber (looking upstream)
x goes to the left, looking in beam direction, y goes upward
*/
Double_t posx, posy;
TransformToLocalCorner(local_point, posx, posy);
for (Int_t i = 0; i < fNofSectors; i++) {
if (posx >= fSectorBeginX[i] && posx <= fSectorEndX[i] && posy >= fSectorBeginY[i] && posy <= fSectorEndY[i]) {
return i;
}
}
LOG(error) << "CbmTrdParModDigi::GetSector: Could not find local point [" << local_point[0] << " " << local_point[1]
<< "] in any of the sectors";
Print("all");
return -1; // This should be never reached
}
//___________________________________________________________________________
Int_t CbmTrdParModDigi::GetSector(Int_t npady, Int_t& rowId) const
{
/**
Calculate the pad coordinates in this sector from pad coordinates in the module e.g. in which sector is pad (20/28)
*/
if ((npady < 0) || (npady > GetNofRows() - 1)) {
LOG(error) << "CbmTrdParModDigi::GetSector - there is no such row number: " << npady;
return -1;
}
Int_t secRows = 0; // number of rows in sector
Int_t nofRows = 0; // number of rows in total
if (fSectorSizeY.At(0) < fSizeY) { // if there are sectors in y direction
for (Int_t iSector = 0; iSector < fNofSectors; iSector++) { // for each sector
secRows = (Int_t)(fSectorSizeY.At(iSector) / fPadSizeY.At(iSector) + 0.5); // need to round for correct result
if (npady < nofRows + secRows) { // if we are in the sector containing the pad
// note nypad = 12 is not in sector 0, with rowIds 0..11
rowId = npady - nofRows;
LOG(debug2) << "npady : " << npady << " <= " << nofRows + secRows << " rowId " << rowId << " nRows(sec-1) "
<< nofRows << " sec " << iSector;
if ((rowId < 0) || (rowId > GetNofRowsInSector(iSector) - 1))
LOG(fatal) << "CbmTrdParModDigi::GetModuleRow rowId " << rowId << " of "
<< GetNofRowsInSector(iSector) - 1
//<< " in moduleAddress " << fModuleAddress
<< " is out of bounds!";
return iSector; // return sector
}
nofRows += secRows; // sum up new total number of rows
}
}
LOG(error) << "CbmTrdParModDigi::GetSector: Could not find pad in any of the sectors";
return -1; // This should be never reached
}
//___________________________________________________________________________
Int_t CbmTrdParModDigi::GetNofColumns() const
{
/**
* Get total number of pad columns in module
*/
Int_t nofColumns = 0;
if (fSectorSizeX.At(0) < fSizeX) {
for (Int_t i = 0; i < fNofSectors; i++) {
nofColumns += (Int_t)(fSectorSizeX.At(i) / fPadSizeX.At(i) + 0.5); // need to round for correct result
}
}
else {
nofColumns = (Int_t)(fSectorSizeX.At(0) / fPadSizeX.At(0) + 0.5); // need to round for correct result
}
return nofColumns;
}
//___________________________________________________________________________
Int_t CbmTrdParModDigi::GetNofRows() const
{
/**
* Get total number of pad rows in module
*/
Int_t nofRows = 0;
if (fSectorSizeY.At(0) < fSizeY) {
for (Int_t i = 0; i < fNofSectors; i++) {
nofRows += (Int_t)(fSectorSizeY.At(i) / fPadSizeY.At(i) + 0.5); // need to round for correct result
}
}
else {
nofRows = (Int_t)(fSectorSizeY.At(0) / fPadSizeY.At(0) + 0.5); // need to round for correct result
}
return nofRows;
}
//___________________________________________________________________________
Int_t CbmTrdParModDigi::GetNofColumnsInSector(Int_t i) const
{
return (Int_t)(fSectorSizeX.At(i) / fPadSizeX.At(i) + 0.5); // need to round for correct result
}
//___________________________________________________________________________
Int_t CbmTrdParModDigi::GetNofRowsInSector(Int_t i) const
{
return (Int_t)(fSectorSizeY.At(i) / fPadSizeY.At(i) + 0.5); // need to round for correct result
}
//___________________________________________________________________________
Int_t CbmTrdParModDigi::GetModuleRow(Int_t& sectorId, Int_t& rowId) const
{
// check limits
if ((sectorId < 0) || (sectorId > GetNofSectors() - 1))
LOG(fatal) << "CbmTrdParModDigi::GetModuleRow sectorId " << sectorId << " of "
<< GetNofSectors() - 1
//<< " in moduleAddress " << fModuleAddress
<< " is out of bounds!";
// check limits
if ((rowId < 0) || (rowId > GetNofRowsInSector(sectorId) - 1))
LOG(fatal) << "CbmTrdParModDigi::GetModuleRow rowId " << rowId << " of "
<< GetNofRowsInSector(sectorId) - 1
//<< " in moduleAddress " << fModuleAddress
<< " is out of bounds!";
Int_t moduleRowId = rowId;
// calculate row number within module
for (Int_t iSector = 0; iSector < sectorId; iSector++) {
moduleRowId += (Int_t)(fSectorSizeY.At(iSector) / fPadSizeY.At(iSector) + 0.5);
// LOG(info) << "adding sector " << iSector << " of " << sectorId;
}
// if (sectorId == 0)
// // do nothing
// if (sectorId >= 1)
// moduleRowId += (Int_t)(fSectorSizeY.At(0) / fPadSizeY.At(0) + 0.5);
// if (sectorId >= 2)
// moduleRowId += (Int_t)(fSectorSizeY.At(1) / fPadSizeY.At(1) + 0.5);
return moduleRowId;
}
//___________________________________________________________________________
Int_t CbmTrdParModDigi::GetSectorRow(Int_t growId, Int_t& rowId) const
{
// check limits
if ((growId < 0) || (growId >= GetNofRows()))
LOG(fatal) << "CbmTrdParModDigi::GetSectorRow rowId " << growId << " of "
<< GetNofRows()
//<< " in moduleAddress " << fModuleAddress
<< " is out of bounds!";
rowId = growId;
// calculate row number within sector
Int_t iSector(0);
for (; iSector < 3; iSector++) {
Int_t nr(GetNofRowsInSector(iSector));
if (rowId - nr + 1 > 0) rowId -= nr;
else
break;
}
return iSector;
}
//___________________________________________________________________________
Bool_t CbmTrdParModDigi::GetPadInfo(const Double_t* local_point, Int_t& sectorId, Int_t& columnId, Int_t& rowId) const
{
// check, if the input is within the allowed range
if (fabs(local_point[0]) > fSizeX) {
LOG(error) << "CbmTrdParModDigi::GetPadInfo - local point x must be within "
"gas volume, x="
<< std::setprecision(8) << local_point[0] << " fSizeX=" << std::setprecision(8) << fSizeX;
return kFALSE;
}
if (fabs(local_point[1]) > fSizeY) {
LOG(error) << "CbmTrdParModDigi::GetPadInfo - local point y must be within "
"gas volume, y="
<< std::setprecision(8) << local_point[1] << " fSizeY=" << std::setprecision(8) << fSizeY;
return kFALSE;
}
Double_t posX, posY;
TransformToLocalSector(local_point, posX, posY);
// calculate in which sector the point is
sectorId = GetSector(local_point);
columnId = (Int_t)(posX / fPadSizeX.At(sectorId));
rowId = (Int_t)(posY / fPadSizeY.At(sectorId));
return kTRUE;
}
//___________________________________________________________________________
void CbmTrdParModDigi::GetPadInfo(const CbmTrdPoint* trdPoint, Int_t& sectorId, Int_t& columnId, Int_t& rowId) const
{
/**
Calculate point in the middle of the detector. This is
for safety reasons, because the point at exit is slightly
outside of the active volume. If one does not use a point
in the detector one will get a wrong volume from the
geomanager. Navigate to the correct volume to get all
necessary information about this volume
*/
Double_t x_mean = 0.5 * (trdPoint->GetXIn() + trdPoint->GetXOut());
Double_t y_mean = 0.5 * (trdPoint->GetYIn() + trdPoint->GetYOut());
Double_t z_mean = 0.5 * (trdPoint->GetZIn() + trdPoint->GetZOut());
gGeoManager->FindNode(x_mean, y_mean, z_mean);
TString curNode = gGeoManager->GetPath();
if (!curNode.Contains("gas")) {
// if the point is not in the gas volume print warning
LOG(warn) << "This point is not in the trd gas";
/*
LOG(warn) << "x: " << std::setprecision(7) << trdPoint->GetXIn() << ", " << trdPoint->GetXOut();
LOG(warn) << "y: " << std::setprecision(7) << trdPoint->GetYIn() << ", " << trdPoint->GetYOut();
LOG(warn) << "z: " << std::setprecision(7) << trdPoint->GetZIn() << ", " << trdPoint->GetZOut();
*/
sectorId = -1;
return;
}
// Get the local point in local MC coordinates from
// the geomanager. This coordinate system is rotated
// if the chamber is rotated. This is corrected in
// GetModuleInformation to have a
// the same local coordinate system in all the chambers
const Double_t* global_point = gGeoManager->GetCurrentPoint();
Double_t local_point[3];
gGeoManager->MasterToLocal(global_point, local_point);
// 20131009 - DE - debuging output to check module orientation 0,1,2,3 with box generator
if (fair::Logger::Logging(fair::Severity::debug2)) {
// print module orientation
LOG(debug2) << "module orientation: " << std::setprecision(5) << fOrientation;
// print global coordinate
LOG(debug2) << "global x: " << std::setprecision(5) << global_point[0] << " y: " << std::setprecision(5)
<< global_point[1] << " z: " << std::setprecision(5) << global_point[2];
// print local coordinate - relative to module center
LOG(debug2) << "local x: " << std::setprecision(5) << local_point[0] << " y: " << std::setprecision(5)
<< local_point[1] << " z: " << std::setprecision(5) << local_point[2];
// test projection to next anode wire
Double_t proj_point[3];
proj_point[0] = local_point[0];
proj_point[1] = local_point[1];
proj_point[2] = local_point[2];
ProjectPositionToNextAnodeWire(proj_point);
// print local coordinate - relative to module center
LOG(debug2) << "proj x: " << std::setprecision(5) << proj_point[0] << " y: " << std::setprecision(5)
<< proj_point[1] << " z: " << std::setprecision(5) << proj_point[2];
Double_t corner_point[3];
corner_point[2] = local_point[2];
TransformToLocalCorner(local_point, corner_point[0], corner_point[1]);
// print local coordinate - relative to module corner
LOG(debug2) << "corner x: " << std::setprecision(5) << corner_point[0] << " y: " << std::setprecision(5)
<< corner_point[1] << " z: " << std::setprecision(5) << corner_point[2];
LOG(debug2) << "pos x: " << std::setprecision(5) << fX << " y: " << std::setprecision(5) << fY
<< " z: " << std::setprecision(5) << fZ << " ori: " << std::setprecision(5) << fOrientation;
LOG(debug2) << "size/2 x: " << std::setprecision(5) << fSizeX << " y: " << std::setprecision(5) << fSizeY
<< " z: " << std::setprecision(5) << fSizeZ;
Double_t sector_point[3];
sector_point[2] = local_point[2];
TransformToLocalSector(local_point, sector_point[0], sector_point[1]);
// print local coordinate - relative to module sector
LOG(debug2) << "sector x: " << std::setprecision(5) << sector_point[0] << " y: " << std::setprecision(5)
<< sector_point[1] << " z: " << std::setprecision(5) << sector_point[2];
// calculate in which sector the point is
sectorId = GetSector(local_point);
LOG(debug2) << "sectornr: " << std::setprecision(5) << sectorId;
LOG(debug2) << "ncol : " << std::setprecision(5) << GetNofColumns();
LOG(debug2) << "nrow : " << std::setprecision(5) << GetNofRows();
// print local coordinate - relative to module sector
LOG(debug2) << "sec2 x: " << std::setprecision(5) << fSectorBeginX.GetAt(2) << " y: " << std::setprecision(5)
<< fSectorBeginY.GetAt(2);
LOG(debug2) << "sec1 x: " << std::setprecision(5) << fSectorBeginX.GetAt(1) << " y: " << std::setprecision(5)
<< fSectorBeginY.GetAt(1);
LOG(debug2) << "sec0 x: " << std::setprecision(5) << fSectorBeginX.GetAt(0) << " y: " << std::setprecision(5)
<< fSectorBeginY.GetAt(0);
// get pad information
Int_t s, c, r;
GetPadInfo(local_point, s, c, r);
LOG(debug2) << "pad sec: " << s << " col: " << c << " row: " << r;
} // debug2
// Int_t moduleAddress = CbmTrdAddress::GetModuleAddress(trdPoint->GetDetectorID());
GetModuleInformation(
/*moduleAddress, */ local_point, sectorId, columnId, rowId);
}
//___________________________________________________________________________
void CbmTrdParModDigi::TransformToLocalCorner(const Double_t* local_point, Double_t& posX, Double_t& posY) const
{
/**
Transformation from local coordinate system
with origin in the middle of the module
into a system with the origin in the lower left corner (looking upstream).
Since for both coordinate systems the orientation is the same
this is only a shift by the half size of the module in x- and y-direction
20131009 - DE - checked OK for module orientations 0,1,2,3
*/
posX = local_point[0] + fSizeX;
posY = local_point[1] + fSizeY;
}
//___________________________________________________________________________
void CbmTrdParModDigi::TransformToLocalSector(const Double_t* local_point, Double_t& posX, Double_t& posY) const
{
/**
Transformation of the module coordinate system
with origin in the middle of the module
into a system with the origin in the lower left corner (looking upstream)
of the sector the point is in.
First, transform in a system with origin in the lower left corner.
20131009 - DE - checked OK for module orientations 0,1,2,3
*/
TransformToLocalCorner(local_point, posX, posY);
Int_t sector = GetSector(local_point);
posX -= fSectorBeginX.GetAt(sector);
posY -= fSectorBeginY.GetAt(sector);
}
//___________________________________________________________________________
void CbmTrdParModDigi::TransformToLocalPad(const Double_t* local_point, Double_t& posX, Double_t& posY) const
{
/**
Transformation of the local module coordinate system
with origin in the middle of the module
into a system with the origin in the local pad center
of the pad below the point.
First, transform in a system with origin in the lower left sector.
*/
Double_t sector_point[2];
TransformToLocalSector(local_point, sector_point[0], sector_point[1]);
// TransformToLocalCorner(local_point, posX, posY);
Int_t sectorId = GetSector(local_point);
Double_t padx =
(Int_t(sector_point[0] / fPadSizeX.At(sectorId)) + 0.5) * fPadSizeX.At(sectorId); // x position of pad center
Double_t pady =
(Int_t(sector_point[1] / fPadSizeY.At(sectorId)) + 0.5) * fPadSizeY.At(sectorId); // y position of pad center
posX = sector_point[0] - padx;
posY = sector_point[1] - pady;
/*
// print debug info
LOG(info) << "sector x: " << std::setprecision(5) << sector_point[0]
<< " y: " << std::setprecision(5) << sector_point[1];
LOG(info) << "pad x: " << std::setprecision(5) << padx
<< " y: " << std::setprecision(5) << pady;
LOG(info) << "diff x: " << std::setprecision(5) << posX
<< " y: " << std::setprecision(5) << posY;
LOG(info) << "npad x: " << std::setprecision(5) << padx / fPadSizeX.At(sectorId)
<< " y: " << std::setprecision(5) << pady / fPadSizeY.At(sectorId);
*/
}
//___________________________________________________________________________
void CbmTrdParModDigi::TransformHitError(TVector3& hitErr) const
{
Double_t x, y; // ,z;
x = hitErr.X();
y = hitErr.Y();
// z = hitErr.Z();
//LOG(info) << "ori : " << fOrientation;
if ((fOrientation == 1) || (fOrientation == 3)) { // for orientations 1 or 3
hitErr.SetX(y); // swap errors
hitErr.SetY(x); // swap errors
// LOG(info) << " swapped x and y error";
// LOG(info) << "ori : " << fOrientation << " swapped x and y error";
}
}
//___________________________________________________________________________
void CbmTrdParModDigi::GetModuleInformation(
//Int_t moduleAddress,
const Double_t* local_point, Int_t& sectorId, Int_t& columnId, Int_t& rowId) const
{
// safety check. Up to now always correct, so could be removed.
// if (fModuleAddress != moduleAddress) {
// LOG(error) << "CbmTrdParModDigi::GetModuleInformation: This is wrong!";
// }
Double_t posX, posY;
TransformToLocalSector(local_point, posX, posY);
// calculate in which sector the point is
sectorId = GetSector(local_point);
columnId = (Int_t)(posX / fPadSizeX.At(sectorId));
rowId = (Int_t)(posY / fPadSizeY.At(sectorId));
}
//___________________________________________________________________________
void CbmTrdParModDigi::GetPadPosition(const Int_t sector, const Int_t col, const Int_t row, TVector3& padPos,
TVector3& padPosErr) const
{
/**
* Get address of a pad, return position relative to module center
*/
Double_t posX = 0;
Double_t posY = 0;
Double_t posZ = 0;
Double_t padsizex = fPadSizeX.At(sector);
Double_t padsizey = fPadSizeY.At(sector);
// calculate position in sector coordinate system
// with the origin in the lower left corner (looking upstream)
posX = (((Double_t) col + 0.5) * padsizex);
posY = (((Double_t) row + 0.5) * padsizey);
// calculate position in module coordinate system
// with the origin in the lower left corner (looking upstream)
posX += fSectorBeginX.GetAt(sector);
posY += fSectorBeginY.GetAt(sector);
// calculate position in the module coordinate system
// with origin in the middle of the module
posX -= fSizeX;
posY -= fSizeY;
posZ = 0;
// check limits
if (fabs(posX) > fSizeX) LOG(fatal) << "CbmTrdParModDigi::GetPadPosition posX=" << posX << " is out of bounds!";
// check limits
if (fabs(posY) > fSizeY) LOG(fatal) << "CbmTrdParModDigi::GetPadPosition posY=" << posY << " is out of bounds!";
padPos.SetXYZ(posX, posY, posZ);
padPosErr.SetXYZ(padsizex / 2., padsizey / 2., 0.);
}
//___________________________________________________________________________
void CbmTrdParModDigi::GetPadPosition(const Int_t padAddress, TVector3& padPos, TVector3& padPosErr) const
{
/**
* Get address of a pad, return position relative to module center
*/
// Double_t posX = 0;
// Double_t posY = 0;
// Double_t posZ = 0;
Int_t sectorId = CbmTrdAddress::GetSectorId(padAddress);
Int_t rowId = CbmTrdAddress::GetRowId(padAddress);
Int_t columnId = CbmTrdAddress::GetColumnId(padAddress);
return GetPadPosition(sectorId, rowId, columnId, padPos, padPosErr);
}
//___________________________________________________________________________
void CbmTrdParModDigi::GetPadPosition(const Int_t padAddress, bool isCbmTrdDigiAddress, TVector3& padPos,
TVector3& padPosErr) const
{
/**
* Get address of a pad, based on the channel address stored in the CbmTrdDigi
*/
if (!isCbmTrdDigiAddress)
LOG(error) << "Trying to get a CbmTrd PadPosition from DigiAddress format "
"function without digiAddress format";
Int_t row = GetPadRow(padAddress);
Int_t col = GetPadColumn(padAddress);
Int_t srow(-1);
Int_t sector = GetSectorRow(row, srow);
return GetPadPosition(sector, col, srow, padPos, padPosErr);
}
//___________________________________________________________________________
void CbmTrdParModDigi::GetPosition(
// Int_t moduleAddress,
Int_t sectorId, Int_t columnId, Int_t rowId, TVector3& padPos, TVector3& padSize) const
{
/**
Calculate position in global coordinates
from digi information (sectorId, columnId, rowId).
Returns two TVector3. One with the position
and one with the padsize of the fired pad
*/
// if (fModuleAddress != moduleAddress) {
// LOG(error) << "CbmTrdParModDigi::GetPosition This is wrong!";
// }
// check limits
if ((sectorId < 0) || (sectorId > GetNofSectors() - 1))
LOG(fatal) << "CbmTrdParModDigi::GetPosition sectorId " << sectorId << " of "
<< GetNofSectors() - 1 //<< " in moduleAddress " << moduleAddress
<< " is out of bounds!";
// check limits
if ((columnId < 0) || (columnId > GetNofColumnsInSector(sectorId) - 1))
LOG(fatal) << "CbmTrdParModDigi::GetPosition columnId " << columnId << " of "
<< GetNofColumnsInSector(sectorId) - 1
//<< " in moduleAddress " << moduleAddress
<< " is out of bounds!";
// check limits
if ((rowId < 0) || (rowId > GetNofRowsInSector(sectorId) - 1))
LOG(fatal) << "CbmTrdParModDigi::GetPosition rowId " << rowId << " of "
<< GetNofRowsInSector(sectorId) - 1
//<< " in moduleAddress " << moduleAddress
<< " is out of bounds!";
Double_t local_point[3];
Double_t padsizex = fPadSizeX.At(sectorId);
Double_t padsizey = fPadSizeY.At(sectorId);
// calculate position in sector coordinate system
// with the origin in the lower left corner (looking upstream)
local_point[0] = (((Double_t) columnId + 0.5) * padsizex);
local_point[1] = (((Double_t) rowId + 0.5) * padsizey);
// calculate position in module coordinate system
// with the origin in the lower left corner (looking upstream)
local_point[0] += fSectorBeginX.GetAt(sectorId);
local_point[1] += fSectorBeginY.GetAt(sectorId);
// local_point[i] must be >= 0 at this point
// check limits
if ((local_point[0] < 0) || (local_point[0] > 2 * fSizeX))
LOG(fatal) << "CbmTrdParModDigi::GetPosition local_point[0]="
<< local_point[0]
//<< " in moduleAddress " << moduleAddress
<< " is out of bounds!";
// check limits
if ((local_point[1] < 0) || (local_point[1] > 2 * fSizeY))
LOG(fatal) << "CbmTrdParModDigi::GetPosition local_point[1]="
<< local_point[1]
//<< " in moduleAddress " << moduleAddress
<< " is out of bounds!";
// calculate position in the module coordinate system
// with origin in the middle of the module
local_point[0] -= fSizeX;
local_point[1] -= fSizeY;
local_point[2] = fSizeZ;
// navigate to the correct module. (fX,fY,fZ)
gGeoManager->FindNode(fX, fY, fZ);
// get the local point in local MC coordinates from
// the geomanager. This coordinate system is rotated,
// if the chamber is rotated. This is corrected in
// GetModuleInformation to have the same
// local coordinate system in all the chambers
Double_t global_point[3]; // global_point[3];
gGeoManager->LocalToMaster(local_point, global_point);
// calculate the position in the global coordinate system
// with the origin in target
Double_t posX = global_point[0];
Double_t posY = global_point[1];
Double_t posZ = global_point[2];
padPos.SetXYZ(posX, posY, posZ);
padSize.SetXYZ(padsizex, padsizey, 0.);
}
//___________________________________________________________________________
Int_t CbmTrdParModDigi::GetPadColumn(const Int_t channelNumber) const
{
// calculate the pad column based on
// the channeNumber as defined in the
// CbmTrdDigi
Int_t ncols = GetNofColumns();
Int_t col = channelNumber % ncols;
return col;
}
//___________________________________________________________________________
Int_t CbmTrdParModDigi::GetPadRow(const Int_t channelNumber) const
{
// calculate the pad row based on
// the channeNumber as defined in the
// CbmTrdDigi
Int_t ncols = GetNofColumns();
Int_t row = channelNumber / ncols;
return row;
}
ClassImp(CbmTrdParModDigi)