34#include "TRestDetectorReadoutPlane.h"
67 if (TMath::Abs(
fNormal.Mag2() - 1.0) > 1E-6) {
69 RESTError <<
"TRestDetectorReadoutPlane::SetNormal : normal vector cannot be zero." << RESTendl;
81 RESTError <<
"TRestDetectorReadoutPlane::SetHeight : height cannot be negative." << RESTendl;
98 cout <<
"REST ERROR (GetReadoutModuleByID) : Module ID : " << modID <<
" was not found" << endl;
118 Double_t x = numeric_limits<Double_t>::quiet_NaN();
124 if (sX > 2 * sY)
return x;
147 Double_t deltaX = abs(x2 - x1);
148 Double_t deltaY = abs(y2 - y1);
150 Int_t rotation = (Int_t)(std::round(rModule->
GetRotation() *
units(
"degrees")));
151 if (rotation % 90 == 0) {
152 if (rotation / 90 % 2 == 0)
185 Double_t y = numeric_limits<Double_t>::quiet_NaN();
191 if (sY > 2 * sX)
return y;
217 Double_t deltaX = abs(x2 - x1);
218 Double_t deltaY = abs(y2 - y1);
220 Int_t rotation = (Int_t)std::round(rModule->
GetRotation() *
units(
"degrees"));
221 if (rotation % 90 == 0) {
222 if (rotation / 90 % 2 == 0)
262 const TVector3 diff = position -
fPosition;
274 TVector3 pos = TVector3(0, 0, z);
303 TVector3 posNew = TVector3(position.X() -
fPosition.X(), position.Y() -
fPosition.Y(), position.Z());
307 if (distance > 0 && distance <
fHeight) {
327 if (distance >= 0 && distance <=
fHeight) {
328 const TVector2 positionInPlane = GetPositionInPlane(position);
331 if (module.IsInside(positionInPlane)) {
332 return module.GetModuleID();
345 if (DetailLevel >= 0) {
346 RESTMetadata <<
"-- Readout plane : " <<
GetID() << RESTendl;
347 RESTMetadata <<
"----------------------------------------------------------------" << RESTendl;
348 RESTMetadata <<
"-- Position : X = " <<
fPosition.X() <<
" mm, "
350 RESTMetadata <<
"-- Normal vector : X = " <<
fNormal.X() <<
" mm, "
351 <<
" Y : " <<
fNormal.Y() <<
" mm, Z : " <<
fNormal.Z() <<
" mm" << RESTendl;
352 RESTMetadata <<
"-- X-axis vector : X = " <<
fAxisX.X() <<
" mm, "
353 <<
" Y : " <<
fAxisX.Y() <<
" mm, Z : " <<
fAxisX.Z() <<
" mm" << RESTendl;
354 RESTMetadata <<
"-- Y-axis vector : Y = " <<
fAxisY.X() <<
" mm, Y : " <<
fAxisY.Y()
355 <<
" mm, Z : " <<
fAxisY.Z() <<
" mm" << RESTendl;
358 <<
" mm" << RESTendl;
359 RESTMetadata <<
"-- Height : " <<
fHeight <<
" mm" << RESTendl;
363 RESTMetadata <<
"----------------------------------------------------------------" << RESTendl;
384 double xmin, xmax, ymin, ymax;
388 TH2Poly* readoutHistogram =
new TH2Poly(
"ReadoutHistogram",
"ReadoutHistogram", xmin, xmax, ymin, ymax);
395 for (
int ch = 0; ch < nChannels; ch++) {
399 for (
int px = 0; px < nPixels; px++) {
400 for (
int v = 0; v < 4; v++) {
405 readoutHistogram->AddBin(4, x, y);
410 readoutHistogram->SetStats(
false);
412 return readoutHistogram;
422 xmin = std::numeric_limits<Double_t>::max(), xmax = std::numeric_limits<Double_t>::min(),
423 ymin = std::numeric_limits<Double_t>::max(), ymax = std::numeric_limits<Double_t>::min();
428 for (
int v = 0; v < 4; v++) {
432 if (x[v] < xmin) xmin = x[v];
433 if (y[v] < ymin) ymin = y[v];
434 if (x[v] > xmax) xmax = x[v];
435 if (y[v] > ymax) ymax = y[v];
440void TRestDetectorReadoutPlane::UpdateAxes() {
441 const TVector3 zUnit = {0, 0, 1};
445 constexpr double tolerance = 1E-6;
448 if ((
fNormal - zUnit).Mag2() < tolerance) {
450 }
else if ((
fNormal + zUnit).Mag2() < tolerance) {
456 TVector3 rotationAxis = zUnit.Cross(
fNormal);
459 double rotationAngle = acos(zUnit.Dot(
fNormal) / (zUnit.Mag() *
fNormal.Mag()));
462 fAxisX.Rotate(rotationAngle, rotationAxis);
463 fAxisY.Rotate(rotationAngle, rotationAxis);
471 if (TMath::Abs(
fNormal.Mag2() - 1.0) > tolerance || TMath::Abs(
fAxisX.Mag2() - 1.0) > tolerance ||
472 TMath::Abs(
fAxisY.Mag2() - 1.0) > tolerance) {
473 RESTError <<
"TRestDetectorReadoutPlane::UpdateAxes() : "
474 <<
"The normal vector, the X-axis vector and the Y-axis vector must be unitary."
480 RESTError <<
"TRestDetectorReadoutPlane::UpdateAxes() : "
481 <<
"The normal vector, the X-axis vector and the Y-axis vector must be orthogonal."
488 <<
"TRestDetectorReadoutPlane::UpdateAxes() : "
489 <<
"The normal vector is not the cross product between the X-axis vector and the Y-axis vector."
495void TRestDetectorReadoutPlane::SetRotation(Double_t radians) {
497 fRotation = TVector2::Phi_0_2pi(radians);
501TVector2 TRestDetectorReadoutPlane::GetPositionInPlane(
const TVector3& point)
const {
508TVector3 TRestDetectorReadoutPlane::GetPositionInWorld(
const TVector2& point, Double_t height)
const {
512Double_t TRestDetectorReadoutPlane::GetDistanceToPlane(
const TVector3& point)
const {
516void TRestDetectorReadoutPlane::SetAxisX(
const TVector3& axis) {
517 const TVector3 axisInPlane = (axis - axis.Dot(
fNormal) *
fNormal).Unit();
518 if (axisInPlane.Mag2() < 1E-6) {
519 RESTError <<
"TRestDetectorReadoutPlane::SetAxisX() : "
520 <<
"The X-axis vector must not be parallel to the normal vector." << RESTendl;
525 const Double_t angle =
fAxisX.Angle(axisInPlane);
531 const double distance = GetDistanceToPlane(point);
532 if (distance < 0 || distance >
fHeight) {
536 const TVector2 pointInPlane = GetPositionInPlane(point);
546 cout <<
"Adding module" << endl;
551 if (lastModule.GetName().empty()) {
552 lastModule.SetName(fName);
554 if (lastModule.GetType().empty()) {
555 lastModule.SetType(fType);
558 for (
size_t channelIndex = 0; channelIndex < lastModule.GetNumberOfChannels(); channelIndex++) {
560 if (channel->
GetName().empty()) {
561 channel->
SetName(lastModule.GetName());
563 if (channel->
GetType().empty()) {
564 channel->
SetType(lastModule.GetType());
std::string GetType() const
Returns the channel type.
void SetName(const std::string &name)
Sets the channel name.
Int_t GetNumberOfPixels()
Returns the total number of pixels inside the readout channel.
void SetType(const std::string &type)
Sets the channel type.
std::string GetName() const
Returns the channel name.
TRestDetectorReadoutPixel * GetPixel(int n)
Returns a pointer to the pixel n by index.
TVector2 GetPixelCenter(Int_t channel, Int_t pixel)
Returns the center pixel position for a given channel and pixel indexes.
TRestDetectorReadoutChannel * GetChannel(size_t n)
Returns a pointer to a readout channel by index.
Double_t GetRotation() const
Returns the module rotation in degrees.
TVector2 GetPixelVertex(Int_t channel, Int_t pixel, Int_t vertex)
Returns any of the pixel vertex position for a given channel and pixel indexes.
TVector2 GetVertex(int n) const
Returns the coordinates of the specified vertex index n. The physical coordinates relative to the rea...
size_t GetNumberOfChannels() const
Returns the total number of channels defined inside the module.
TVector2 GetCenter() const
Returns the center TVector2 position of the pixel.
TVector2 GetSize()
Returns a TVector2 with the pixel size.
Bool_t isDaqIDInside(Int_t daqId)
This method determines if the daqId given is associated to any of the readout readout channels in any...
Int_t GetNumberOfChannels()
Returns the total number of channels in the readout plane.
Int_t isZInsideDriftVolume(Double_t z)
This method determines if a given position in z is inside the drift volume drifting distance for this...
TRestDetectorReadoutModule * GetModuleByID(Int_t modID)
Returns a pointer to a module using its internal module id.
void SetNormal(const TVector3 &normal)
It updates the value of the normal vector and recalculates the corresponding X and Y axis.
TH2Poly * GetReadoutHistogram()
Creates and returns a TH2Poly object with the readout pixel description.
Double_t fRotation
Rotation (in radians) of the readout plane around the normal vector.
Int_t GetModuleIDFromPosition(const TVector3 &position) const
This method returns the module id where pos is found. The z-coordinate must be found in between the c...
Double_t fChargeCollection
The fraction of charge/energy this readout plane collects from a hit position.
void Print(Int_t DetailLevel=0)
Prints information with details of the readout plane and modules defined inside the readout plane.
TRestDetectorReadoutPlane()
Default TRestDetectorReadoutPlane constructor.
bool IsInside(const TVector3 &point) const
Check if the point is inside any module of the readout plane.
size_t GetNumberOfModules() const
Returns the total number of modules in the readout plane.
void Draw()
Draws the readout plane using GetReadoutHistogram.
Double_t GetX(Int_t modID, Int_t chID)
Returns the X coordinate of a given channel in a given module using their internal module and channel...
Double_t GetDistanceTo(const TVector3 &pos) const
Returns the perpendicular distance to the readout plane from a given position pos.
Int_t FindChannel(Int_t module, const TVector2 &position)
Finds the readout channel index for a given module stored in a given module index stored in the reado...
Double_t fHeight
A length in mm that confers a 3rd dimension to the readout plane and defines a volume.
void GetBoundaries(double &xmin, double &xmax, double &ymin, double &ymax)
Finds the xy boundaries of the readout plane delimited by the modules.
Double_t GetY(Int_t modID, Int_t chID)
Returns the Y coordinate of a given channel in a given module using their internal module and channel...
virtual ~TRestDetectorReadoutPlane()
Default TRestDetectorReadoutPlane destructor.
TVector3 fPosition
The position of the readout plane that defines the origin (0,0) in plane coordinates.
TVector3 GetCathodePosition() const
Returns a TVector3 with the cathode position.
void SetHeight(Double_t d)
Used to define the height of the readout volume with sign crosscheck.
TVector3 fAxisX
A vector contained in the plane that defines the plane X-axis.
TVector3 fAxisY
A vector contained in the plane that defines the plane Y-axis.
TVector3 fNormal
A vector that defines the plane orientation and the side of the active volume.
Int_t GetID() const
Returns an integer with the plane id number.
std::vector< TRestDetectorReadoutModule > fReadoutModules
< A list of TRestDetectorReadoutModule components contained in the readout plane.
void AddModule(const TRestDetectorReadoutModule &module)
Adds a new module to the readout plane.