34 #include "TRestDetectorReadoutPlane.h"
54 for (
size_t md = 0; md < GetNumberOfModules(); md++) {
55 nChannels += fReadoutModules[md].GetNumberOfChannels();
65 fNormal = normal.Unit();
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;
92 for (
size_t md = 0; md < GetNumberOfModules(); md++) {
93 if (fReadoutModules[md].GetModuleID() == modID) {
94 return &fReadoutModules[md];
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)
247 const auto relativePosition = position - TVector2{fPosition.X(), fPosition.Y()};
254 return fReadoutModules[module].FindChannel(relativePosition);
262 const TVector3 diff = position - fPosition;
263 return diff.Dot(fNormal);
274 TVector3 pos = TVector3(0, 0, z);
276 return isZInsideDriftVolume(pos);
287 for (
size_t m = 0; m < GetNumberOfModules(); m++)
288 if (fReadoutModules[m].IsDaqIDInside(daqId))
return true;
303 TVector3 posNew = TVector3(position.X() - fPosition.X(), position.Y() - fPosition.Y(), position.Z());
305 Double_t distance = GetDistanceTo(posNew);
307 if (distance > 0 && distance < fHeight) {
326 Double_t distance = GetDistanceTo(position);
327 if (distance >= 0 && distance <= fHeight) {
328 const TVector2 positionInPlane = GetPositionInPlane(position);
329 for (
size_t m = 0; m < GetNumberOfModules(); m++) {
330 auto& module = fReadoutModules[m];
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, "
349 <<
" Y : " << fPosition.Y() <<
" mm, Z : " << fPosition.Z() <<
" mm" << RESTendl;
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;
356 RESTMetadata <<
"-- Cathode Position : X = " << GetCathodePosition().X() <<
" mm, "
357 <<
" Y : " << GetCathodePosition().Y() <<
" mm, Z : " << GetCathodePosition().Z()
358 <<
" mm" << RESTendl;
359 RESTMetadata <<
"-- Height : " << fHeight <<
" mm" << RESTendl;
360 RESTMetadata <<
"-- Charge collection : " << fChargeCollection << RESTendl;
361 RESTMetadata <<
"-- Total modules : " << GetNumberOfModules() << RESTendl;
362 RESTMetadata <<
"-- Total channels : " << GetNumberOfChannels() << RESTendl;
363 RESTMetadata <<
"----------------------------------------------------------------" << RESTendl;
365 for (
size_t i = 0; i < GetNumberOfModules(); i++) {
366 fReadoutModules[i].Print(DetailLevel - 1);
384 double xmin, xmax, ymin, ymax;
386 GetBoundaries(xmin, xmax, ymin, ymax);
388 TH2Poly* readoutHistogram =
new TH2Poly(
"ReadoutHistogram",
"ReadoutHistogram", xmin, xmax, ymin, ymax);
390 for (
size_t mdID = 0; mdID < this->GetNumberOfModules(); mdID++) {
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 = 1E9, xmax = -1E9, ymin = 1E9, ymax = -1E9;
424 for (
size_t mdID = 0; mdID < this->GetNumberOfModules(); mdID++) {
427 for (
int v = 0; v < 4; v++) {
431 if (x[v] < xmin) xmin = x[v];
432 if (y[v] < ymin) ymin = y[v];
433 if (x[v] > xmax) xmax = x[v];
434 if (y[v] > ymax) ymax = y[v];
439 void TRestDetectorReadoutPlane::UpdateAxes() {
440 const TVector3 zUnit = {0, 0, 1};
444 constexpr
double tolerance = 1E-6;
447 if ((fNormal - zUnit).Mag2() < tolerance) {
449 }
else if ((fNormal + zUnit).Mag2() < tolerance) {
455 TVector3 rotationAxis = zUnit.Cross(fNormal);
458 double rotationAngle = acos(zUnit.Dot(fNormal) / (zUnit.Mag() * fNormal.Mag()));
461 fAxisX.Rotate(rotationAngle, rotationAxis);
462 fAxisY.Rotate(rotationAngle, rotationAxis);
466 fAxisX.Rotate(fRotation, fNormal);
467 fAxisY.Rotate(fRotation, fNormal);
470 if (TMath::Abs(fNormal.Mag2() - 1.0) > tolerance || TMath::Abs(fAxisX.Mag2() - 1.0) > tolerance ||
471 TMath::Abs(fAxisY.Mag2() - 1.0) > tolerance) {
472 RESTError <<
"TRestDetectorReadoutPlane::UpdateAxes() : "
473 <<
"The normal vector, the X-axis vector and the Y-axis vector must be unitary."
477 if (TMath::Abs(fNormal.Dot(fAxisX)) > tolerance || TMath::Abs(fNormal.Dot(fAxisY)) > tolerance ||
478 TMath::Abs(fAxisX.Dot(fAxisY)) > tolerance) {
479 RESTError <<
"TRestDetectorReadoutPlane::UpdateAxes() : "
480 <<
"The normal vector, the X-axis vector and the Y-axis vector must be orthogonal."
485 if ((fAxisX.Cross(fAxisY) - fNormal).Mag2() > tolerance) {
487 <<
"TRestDetectorReadoutPlane::UpdateAxes() : "
488 <<
"The normal vector is not the cross product between the X-axis vector and the Y-axis vector."
494 void TRestDetectorReadoutPlane::SetRotation(Double_t radians) {
496 fRotation = TVector2::Phi_0_2pi(radians);
500 TVector2 TRestDetectorReadoutPlane::GetPositionInPlane(
const TVector3& point)
const {
503 return {fAxisX.Dot(point - fPosition),
504 fAxisY.Dot(point - fPosition)};
507 TVector3 TRestDetectorReadoutPlane::GetPositionInWorld(
const TVector2& point, Double_t height)
const {
508 return fPosition + point.X() * fAxisX + point.Y() * fAxisY + height * fNormal;
511 Double_t TRestDetectorReadoutPlane::GetDistanceToPlane(
const TVector3& point)
const {
512 return (point - fPosition).Dot(fNormal);
515 void TRestDetectorReadoutPlane::SetAxisX(
const TVector3& axis) {
516 const TVector3 axisInPlane = (axis - axis.Dot(fNormal) * fNormal).Unit();
517 if (axisInPlane.Mag2() < 1E-6) {
518 RESTError <<
"TRestDetectorReadoutPlane::SetAxisX() : "
519 <<
"The X-axis vector must not be parallel to the normal vector." << RESTendl;
524 const Double_t angle = fAxisX.Angle(axisInPlane);
526 SetRotation(fRotation - angle);
530 const double distance = GetDistanceToPlane(point);
531 if (distance < 0 || distance > fHeight) {
535 const TVector2 pointInPlane = GetPositionInPlane(point);
536 for (
size_t moduleIndex = 0; moduleIndex < GetNumberOfModules(); moduleIndex++) {
537 if (fReadoutModules[moduleIndex].IsInside(pointInPlane)) {
545 cout <<
"Adding module" << endl;
546 fReadoutModules.emplace_back(module);
549 auto& lastModule = fReadoutModules.back();
550 if (lastModule.GetName().empty()) {
551 lastModule.SetName(fName);
553 if (lastModule.GetType().empty()) {
554 lastModule.SetType(fType);
557 for (
size_t channelIndex = 0; channelIndex < lastModule.GetNumberOfChannels(); channelIndex++) {
559 if (channel->
GetName().empty()) {
560 channel->
SetName(lastModule.GetName());
562 if (channel->
GetType().empty()) {
563 channel->
SetType(lastModule.GetType());
std::string GetType() const
Returns the channel type.
void SetName(const std::string &name)
Sets the channel name.
TRestDetectorReadoutPixel * GetPixel(int n)
Returns a pointer to the pixel n by index.
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.
TVector2 GetPixelCenter(Int_t channel, Int_t pixel)
Returns the center pixel position for a given channel and pixel indexes.
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...
TRestDetectorReadoutChannel * GetChannel(size_t n)
Returns a pointer to a readout channel by index.
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.
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...
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.
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...
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.
void SetHeight(Double_t d)
Used to define the height of the readout volume with sign crosscheck.
void AddModule(const TRestDetectorReadoutModule &module)
Adds a new module to the readout plane.