51 #include "TRestDetectorReadoutModule.h"
52 bool RESTREADOUT_DECODINGFILE_ERROR =
false;
71 fReadoutChannel.clear();
79 fDaqIdRange = {-1, -1};
100 Int_t maxID = GetChannel(0)->GetDaqID();
101 Int_t minID = GetChannel(0)->GetDaqID();
102 for (
size_t ch = 0; ch < this->GetNumberOfChannels(); ch++) {
103 Int_t daqID = GetChannel(ch)->GetDaqID();
112 fDaqIdRange = {minID, maxID};
126 Int_t totalNumberOfPixels = 0;
127 for (
size_t ch = 0; ch < this->GetNumberOfChannels(); ch++)
128 totalNumberOfPixels += GetChannel(ch)->GetNumberOfPixels();
130 if (fMappingNodes == 0) {
131 fMappingNodes = TMath::Sqrt(totalNumberOfPixels);
132 fMappingNodes = 2 * fMappingNodes;
135 cout <<
"Performing readout mapping optimization (This might require long "
138 cout <<
"--------------------------------------------------------------------"
141 cout <<
"Total number of pixels : " << totalNumberOfPixels << endl;
142 cout <<
"Nodes : " << fMappingNodes << endl;
144 fMapping.Initialize(fMappingNodes, fMappingNodes, GetSize().X(), GetSize().Y());
146 for (
size_t ch = 0; ch < this->GetNumberOfChannels(); ch++) {
147 for (
int px = 0; px < this->GetChannel(ch)->GetNumberOfPixels(); px++) {
148 Double_t xPix = this->GetChannel(ch)->GetPixel(px)->GetCenter().X();
149 Double_t yPix = this->GetChannel(ch)->GetPixel(px)->GetCenter().Y();
151 Int_t nodeX = fMapping.GetNodeX(xPix);
152 Int_t nodeY = fMapping.GetNodeY(yPix);
158 if (showWarnings && fMapping.isNodeSet(nodeX, nodeY)) {
160 cout <<
"TRestDetectorReadoutModule. WARNING. Node is already SET!!" << endl;
161 cout <<
"Trying to associate channel : " << ch <<
" Pixel : " << px << endl;
162 cout <<
"Pixel coordinates : ( " << xPix <<
" , " << yPix <<
" ) " << endl;
164 Int_t tempCh = fMapping.GetChannelByNode(nodeX, nodeY);
165 Int_t tempPix = fMapping.GetPixelByNode(nodeX, nodeY);
166 RESTWarning <<
"Already associated channel : " << tempCh <<
" pixel : " << tempPix
168 Double_t xP = this->GetChannel(tempCh)->GetPixel(tempPix)->GetCenter().X();
169 Double_t yP = this->GetChannel(tempCh)->GetPixel(tempPix)->GetCenter().Y();
170 RESTWarning <<
"Pixel coordinates : ( " << xP <<
" , " << yP <<
" ) " << RESTendl;
173 cout <<
"Increasing the number of mapping of nodes may solve this issue." << endl;
176 fMapping.SetNode(nodeX, nodeY, ch, px);
180 for (
int i = 0; i < fMappingNodes; i++) {
181 printf(
"Completed : %.2lf %%\r",
182 100. * (i * (Double_t)fMappingNodes) / fMappingNodes / fMappingNodes);
184 for (
int j = 0; j < fMappingNodes; j++) {
185 Double_t x = fMapping.GetX(i);
186 Double_t y = fMapping.GetY(j);
187 const auto transformedCoordinates = TransformToPlaneCoordinates({x, y});
189 if (!fMapping.isNodeSet(i, j)) {
190 for (
size_t ch = 0; ch < GetNumberOfChannels() && !fMapping.isNodeSet(i, j); ch++) {
191 for (
int px = 0; px < GetChannel(ch)->GetNumberOfPixels() && !fMapping.isNodeSet(i, j);
193 if (IsInsidePixel(ch, px, transformedCoordinates)) {
194 fMapping.SetNode(i, j, ch, px);
202 if (!fMapping.AllNodesSet())
203 cout <<
"Not all nodes set" << endl;
205 cout <<
"All Nodes set" << endl;
207 for (
int i = 0; i < fMappingNodes; i++)
208 for (
int j = 0; j < fMappingNodes; j++) {
209 if (!fMapping.isNodeSet(i, j)) {
210 Double_t x = fMapping.GetX(i);
211 Double_t y = fMapping.GetY(j);
212 const auto transformedCoordinates = TransformToPlaneCoordinates({x, y});
214 cout <<
"Node NOT SET : " << i <<
" , " << j <<
" Mapping x : " << x <<
" y : " << y << endl;
216 for (
size_t ch = 0; ch < GetNumberOfChannels(); ch++) {
217 for (
int px = 0; px < GetChannel(ch)->GetNumberOfPixels(); px++) {
218 if (IsInsidePixel(ch, px, transformedCoordinates)) {
219 cout <<
"X : " << transformedCoordinates.X() <<
" , "
220 << transformedCoordinates.Y() <<
" Is inside channel : " << ch
221 <<
" pixel : " << px << endl;
228 cout <<
"Nodes not set : " << fMapping.GetNumberOfNodesNotSet() << endl;
235 fDecodingFile = decodingFile;
237 if (fDecodingFile ==
"Not defined" || fDecodingFile.empty() || RESTREADOUT_DECODINGFILE_ERROR) {
244 RESTWarning <<
"The decoding file does not exist!" << RESTendl;
245 RESTWarning <<
"--------------------------------" << RESTendl;
246 RESTWarning <<
"File : " << fDecodingFile << RESTendl;
247 RESTWarning <<
"Default decoding will be used. readoutChannel=daqChannel" << RESTendl;
248 RESTWarning <<
"To avoid this message and use the default decoding define : "
251 RESTWarning <<
"--------------------------------" << RESTendl;
252 RESTWarning <<
"Press a KEY to continue..." << RESTendl;
255 RESTREADOUT_DECODINGFILE_ERROR =
true;
258 std::vector<std::pair<Int_t, Int_t>> rdChannel;
260 FILE* f = fopen(fDecodingFile.c_str(),
"r");
263 if (fscanf(f,
"%d\t%d\n", &daq, &readout) <= 0) {
264 RESTError <<
"TRestDetectorReadoutModule::UpdateDecoding. Problem reading decoding"
266 RESTError <<
"This error might need support at REST forum" << RESTendl;
272 rdChannel.push_back(std::make_pair(readout, daq + fFirstDaqChannel));
278 if (fDecoding && (
unsigned int)this->GetNumberOfChannels() != rdChannel.size()) {
279 RESTError <<
"TRestDetectorReadout."
280 <<
" The number of channels defined in the readout is not the same"
281 <<
" as the number of channels found in the decoding." << RESTendl;
285 for (
size_t ch = 0; ch < this->GetNumberOfChannels(); ch++) {
288 rdChannel.push_back(std::make_pair(
id,
id + fFirstDaqChannel));
293 const auto& [readout, daq] = rdChannel[ch];
294 if (!this->GetChannel(readout)) {
295 RESTError <<
"Problem setting readout channel " << readout <<
" with daq id: " << daq << RESTendl;
298 this->GetChannel(readout)->SetDaqID(daq);
299 this->GetChannel(readout)->SetChannelID(readout);
302 this->SetMinMaxDaqIDs();
309 if (daqID >= GetMinDaqID() && daqID <= GetMaxDaqID()) {
323 if (!IsInside(position)) {
327 const auto transformedCoordinates = TransformToModuleCoordinates(position);
328 const auto& x = transformedCoordinates.X();
329 const auto& y = transformedCoordinates.Y();
331 Int_t nodeX = fMapping.GetNodeX(x);
332 Int_t nodeY = fMapping.GetNodeY(y);
334 Int_t channel = fMapping.GetChannelByNode(nodeX, nodeY);
335 Int_t pixel = fMapping.GetPixelByNode(nodeX, nodeY);
342 Int_t totalNodes = fMapping.GetNumberOfNodesX() * fMapping.GetNumberOfNodesY();
346 while (!this->IsInsidePixel(channel, pixel, position)) {
348 if (xAxis == 1 && forward == 1)
350 else if (xAxis == 0 && forward == 1)
352 else if (xAxis == 1 && forward == 0)
354 else if (xAxis == 0 && forward == 0)
357 Int_t nNodes = fMapping.GetNumberOfNodesX();
359 if (nodeX < 0) nodeX = nNodes - 1;
360 if (nodeY < 0) nodeY = nNodes - 1;
361 if (nodeX >= nNodes) nodeX = 0;
362 if (nodeY >= nNodes) nodeY = 0;
364 if (count >= repeat) {
365 if (xAxis == 1 && forward == 1) {
368 }
else if (xAxis == 0 && forward == 0) {
372 }
else if (xAxis == 1 && forward == 0) {
375 }
else if (xAxis == 0 && forward == 1) {
384 channel = fMapping.GetChannelByNode(nodeX, nodeY);
385 pixel = fMapping.GetPixelByNode(nodeX, nodeY);
387 if (count > totalNodes / 10) {
388 RESTWarning <<
"TRestDetectorReadoutModule. I did not find any channel for hit position (" << x
389 <<
"," << y <<
") in internal module coordinates" << RESTendl;
391 for (
size_t ch = 0; ch < GetNumberOfChannels(); ch++)
392 for (
int px = 0; px < GetChannel(ch)->GetNumberOfPixels(); px++)
393 if (IsInsidePixel(ch, px, position)) {
394 cout <<
"( " << x <<
" , " << y <<
") Should be in channel " << ch
395 <<
" pixel : " << px << endl;
397 cout <<
"Corresponding node : nX: " << fMapping.GetNodeX_ForChannelAndPixel(ch, px)
398 <<
" nY : " << fMapping.GetNodeY_ForChannelAndPixel(ch, px) << endl;
399 cout <<
"Channel : " << ch <<
" Pixel : " << px << endl;
400 cout <<
"Pix X : " << GetChannel(ch)->GetPixel(px)->GetCenter().X()
401 <<
" Pix Y : " << GetChannel(ch)->GetPixel(px)->GetCenter().Y() << endl;
416 const TVector2 positionRotated = TransformToModuleCoordinates(position);
418 return (positionRotated.X() >= 0 && positionRotated.X() <= fSize.X() && positionRotated.Y() >= 0 &&
419 positionRotated.Y() <= fSize.Y());
427 const TVector2 pos = TransformToModuleCoordinates(position);
428 for (
int idx = 0; idx < GetChannel(channel)->GetNumberOfPixels(); idx++) {
429 if (GetChannel(channel)->GetPixel(idx)->IsInside(pos)) {
441 if (channel < 0 || pixel < 0) {
445 const TVector2 pos = TransformToModuleCoordinates(position);
446 if (GetChannel(channel)->GetPixel(pixel)->IsInside(pos)) {
459 TVector2 newPos = TransformToModuleCoordinates(position);
461 Double_t dx = 0, dy = 0;
462 if (newPos.X() < 0) {
464 }
else if (fSize.X() - newPos.X() < 0) {
465 dx = fSize.X() - newPos.X();
467 if (newPos.Y() < 0) {
469 }
else if (fSize.Y() - newPos.Y() < 0) {
470 dy = fSize.Y() - newPos.Y();
480 return GetPixelVertex(channel, pixel, 0);
491 TVector2 pixPosition = GetChannel(channel)->GetPixel(pixel)->GetVertex(vertex);
493 pixPosition = pixPosition.Rotate(fRotation);
494 pixPosition = pixPosition + fOrigin;
506 TVector2 pixCenter = GetChannel(channel)->GetPixel(pixel)->GetCenter();
508 pixCenter = pixCenter.Rotate(fRotation);
509 pixCenter = pixCenter + fOrigin;
521 Bool_t type = GetChannel(channel)->GetPixel(pixel)->GetTriangle();
527 return GetPixelVertex(pix, 0);
531 TVector2 pixPosition = pix->
GetVertex(vertex);
532 pixPosition = pixPosition.Rotate(fRotation);
533 pixPosition = pixPosition + fOrigin;
538 TVector2 corner1(GetPixelVertex(pix, 0));
539 TVector2 corner2(GetPixelVertex(pix, 2));
540 TVector2 center = (corner1 + corner2) / 2.;
556 TVector2 vertex(0, 0);
557 const TVector2& origin = fOrigin;
561 else if (n % 4 == 1) {
562 vertex.Set(fSize.X(), 0);
563 vertex = vertex.Rotate(fRotation);
565 vertex = vertex + origin;
566 }
else if (n % 4 == 2) {
567 vertex.Set(fSize.X(), fSize.Y());
568 vertex = vertex.Rotate(fRotation);
570 vertex = vertex + origin;
571 }
else if (n % 4 == 3) {
572 vertex.Set(0, fSize.Y());
573 vertex = vertex.Rotate(fRotation);
575 vertex = vertex + origin;
592 if (oX + fTolerance < 0 || oY + fTolerance < 0 || sX - fTolerance > fSize.X() ||
593 sY - fTolerance > fSize.Y()) {
595 cout <<
"REST Warning (AddChannel) pixel outside the module boundaries" << endl;
596 cout <<
"Channel: " << fReadoutChannel.size() <<
", Pixel : " << i << endl;
597 cout <<
"Pixel origin = (" << oX <<
" , " << oY <<
")" << endl;
598 cout <<
"Pixel size = (" << sX <<
" , " << sY <<
")" << endl;
599 cout <<
"Module size = (" << fSize.X() <<
" , " << fSize.Y() <<
")" << endl;
604 fReadoutChannel.emplace_back(channel);
605 auto& lastChannel = fReadoutChannel.back();
607 if (lastChannel.GetName().empty()) {
608 lastChannel.SetName(fName);
610 if (lastChannel.GetType().empty()) {
611 lastChannel.SetType(fType);
624 if (DetailLevel >= 0) {
625 RESTMetadata <<
"-- Readout module : " << GetModuleID() << RESTendl;
626 RESTMetadata <<
"----------------------------------------------------------------" << RESTendl;
627 RESTMetadata <<
"-- Decoding File: " << fDecodingFile << RESTendl;
628 RESTMetadata <<
"Decoding was defined : " << (fDecoding ?
"Yes" :
"No") << RESTendl;
629 RESTMetadata <<
"-- First DAQ Channel: " << fFirstDaqChannel << RESTendl;
630 RESTMetadata <<
"-- Number of mapping nodes: " << fMappingNodes << RESTendl;
631 RESTMetadata <<
"-- Origin position : X = " << fOrigin.X() <<
" mm "
632 <<
" Y : " << fOrigin.Y() <<
" mm" << RESTendl;
633 RESTMetadata <<
"-- Size : X = " << fSize.X() <<
" Y : " << fSize.Y() << RESTendl;
634 RESTMetadata <<
"-- Rotation : " << fRotation *
units(
"degrees") <<
" degrees" << RESTendl;
635 RESTMetadata <<
"-- Total channels : " << GetNumberOfChannels() << RESTendl;
636 RESTMetadata <<
"-- Tolerance : " << fTolerance << RESTendl;
637 RESTMetadata <<
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << RESTendl;
639 for (
size_t n = 0; n < GetNumberOfChannels(); n++) {
640 fReadoutChannel[n].Print(DetailLevel - 1);
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.
TRestDetectorReadoutModule()
Default TRestDetectorReadoutModule constructor.
void AddChannel(TRestDetectorReadoutChannel &channel)
Adds a new channel to the module.
Bool_t IsInsidePixel(Int_t channel, Int_t pixel, const TVector2 &position)
Determines if the position TVector2 pos is found at a specific pixel id inside the readout channel gi...
TVector2 GetPixelCenter(Int_t channel, Int_t pixel)
Returns the center pixel position for a given channel and pixel indexes.
void Initialize()
TRestDetectorReadoutModule initialization.
void DoReadoutMapping()
Starts the readout mapping initialization. This process is computationally expensive but it greatly o...
void SetDecodingFile(const std::string &decodingFile)
Set the decoding file in the readout module.
TVector2 GetPixelOrigin(Int_t channel, Int_t pixel)
Returns the pixel origin (left-bottom) position for a given channel and pixel indexes.
Bool_t GetPixelTriangle(Int_t channel, Int_t pixel)
Returns the pixel type for a given channel and pixel indexes.
Bool_t IsInside(const TVector2 &position) const
Determines if the position x,y relative to the readout plane are inside this readout module.
Int_t FindChannel(const TVector2 &position)
Returns the channel index corresponding to the absolute coordinates (absX, absY), but relative to the...
Bool_t IsInsideChannel(Int_t channel, const TVector2 &position)
Determines if the position TVector2 pos is found in any of the pixels of the readout channel index gi...
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...
Bool_t IsDaqIDInside(Int_t daqID)
Determines if a given daqID number is in the range of the module.
void SetMinMaxDaqIDs()
Initializes the max and min values for the daq channel number.
virtual ~TRestDetectorReadoutModule()
Default TRestDetectorReadoutModule destructor.
void Draw()
Not implemented.
void Print(Int_t DetailLevel=0)
Prints the module details and channels if fullDetail is enabled.
TVector2 GetDistanceToModule(const TVector2 &position)
Creates a TVector2 with shortest norm going from the given position pos to the module....
A class to store the readout pixel definition used in TRestDetectorReadoutChannel.
Bool_t GetTriangle() const
Returns true if the pixel is a triangle.
TVector2 GetVertex(int n) const
Returns the specified pixel vertex position.
Int_t GetChar(std::string hint="Press a KEY to continue ...")
Helps to pause the program, printing a message before pausing.