diff --git a/doc/doxygen/images/radialstrippedmask.png b/doc/doxygen/images/radialstrippedmask.png new file mode 100644 index 000000000..b4c928a32 Binary files /dev/null and b/doc/doxygen/images/radialstrippedmask.png differ diff --git a/examples/masks.rml b/examples/masks.rml index 15e8a9c2b..da33120f0 100644 --- a/examples/masks.rml +++ b/examples/masks.rml @@ -14,6 +14,17 @@ + + + + + + + + + + + diff --git a/source/framework/masks/inc/TRestPatternMask.h b/source/framework/masks/inc/TRestPatternMask.h index 12979a560..c16c6a89a 100644 --- a/source/framework/masks/inc/TRestPatternMask.h +++ b/source/framework/masks/inc/TRestPatternMask.h @@ -29,7 +29,7 @@ /// An abstract class used to encapsulate different mask pattern class definitions. class TRestPatternMask : public TRestMetadata { private: - /// It is used to introduce an offset on the pattern + /// It is used to introduce an offset on the pattern (not the mask, mask is always centered) TVector2 fOffset = TVector2(0, 0); //< /// An angle (in radians) used to introduce a rotation to the pattern diff --git a/source/framework/masks/inc/TRestRadialStrippedMask.h b/source/framework/masks/inc/TRestRadialStrippedMask.h new file mode 100644 index 000000000..b8d95caf2 --- /dev/null +++ b/source/framework/masks/inc/TRestRadialStrippedMask.h @@ -0,0 +1,70 @@ +/************************************************************************* + * This file is part of the REST software framework. * + * * + * Copyright (C) 2016 GIFNA/TREX (University of Zaragoza) * + * For more information see https://gifna.unizar.es/trex * + * * + * REST is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * REST is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have a copy of the GNU General Public License along with * + * REST in $REST_PATH/LICENSE. * + * If not, see https://www.gnu.org/licenses/. * + * For the list of contributors see $REST_PATH/CREDITS. * + *************************************************************************/ + +#ifndef REST_TRestRadialStrippedMask +#define REST_TRestRadialStrippedMask + +#include + +/// A class used to define a stripped mask pattern +class TRestRadialStrippedMask : public TRestPatternMask { + private: + void Initialize() override; + + /// The periodity of the stripped structure in radians + Double_t fStripsAngle = TMath::Pi() / 3; //< + + /// The width of the stripped structure in mm + Double_t fStripsThickness = 0.5; //< + + /// The spacers structure will be effective from this radius, in mm. Default is from 20 mm. + Double_t fInitialRadius = 20.; //< + + /// Radius of an internal circular region defined inside the fInitialRadius. If 0, there will be no region + Double_t fInternalRegionRadius = 0.; //< + + /// It defines the maximum number of cells/regions in each axis + Int_t fModulus = 10; + + public: + virtual Int_t GetRegion(Double_t& x, Double_t& y) override; + + /// It returns the gap/periodicity of the strips in degrees + Double_t GetStripsAngle() { return fStripsAngle * units("degrees"); } + + /// It returns the thickness of the strips in mm + Double_t GetStripsThickness() { return fStripsThickness; } + + /// It returns the modulus used to define a finite set of ids + Int_t GetModulus() { return fModulus; } + + void PrintMetadata() override; + void PrintMaskMembers() override; + void PrintMask() override; + + TRestRadialStrippedMask(); + TRestRadialStrippedMask(const char* cfgFileName, std::string name = ""); + ~TRestRadialStrippedMask(); + + ClassDefOverride(TRestRadialStrippedMask, 1); +}; +#endif diff --git a/source/framework/masks/src/TRestPatternMask.cxx b/source/framework/masks/src/TRestPatternMask.cxx index 74fa9143c..5388888b3 100644 --- a/source/framework/masks/src/TRestPatternMask.cxx +++ b/source/framework/masks/src/TRestPatternMask.cxx @@ -167,7 +167,7 @@ TCanvas* TRestPatternMask::DrawMonteCarlo(Int_t nSamples) { delete fCanvas; fCanvas = NULL; } - fCanvas = new TCanvas("canv", "This is the canvas title", 1400, 1200); + fCanvas = new TCanvas("canv", "This is the canvas title", 1200, 1200); fCanvas->Draw(); TPad* pad1 = new TPad("pad1", "This is pad1", 0.01, 0.02, 0.99, 0.97); @@ -183,17 +183,19 @@ TCanvas* TRestPatternMask::DrawMonteCarlo(Int_t nSamples) { TRandom3* rnd = new TRandom3(0); for (int n = 0; n < nSamples; n++) { - Double_t x = 2.5 * (rnd->Rndm() - 0.5) * fMaskRadius; - Double_t y = 2.5 * (rnd->Rndm() - 0.5) * fMaskRadius; + Double_t xO = 2.5 * (rnd->Rndm() - 0.5) * fMaskRadius; + Double_t yO = 2.5 * (rnd->Rndm() - 0.5) * fMaskRadius; + Double_t x = xO; + Double_t y = yO; Int_t id = GetRegion(x, y); if (points.count(id) == 0) { std::vector a; - a.push_back(TVector2(x, y)); + a.push_back(TVector2(xO, yO)); points[id] = a; } else { - points[id].push_back(TVector2(x, y)); + points[id].push_back(TVector2(xO, yO)); } } diff --git a/source/framework/masks/src/TRestRadialStrippedMask.cxx b/source/framework/masks/src/TRestRadialStrippedMask.cxx new file mode 100644 index 000000000..6985e92c3 --- /dev/null +++ b/source/framework/masks/src/TRestRadialStrippedMask.cxx @@ -0,0 +1,221 @@ +/************************************************************************* + * This file is part of the REST software framework. * + * * + * Copyright (C) 2016 GIFNA/TREX (University of Zaragoza) * + * For more information see https://gifna.unizar.es/trex * + * * + * REST is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * REST is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have a copy of the GNU General Public License along with * + * REST in $REST_PATH/LICENSE. * + * If not, see https://www.gnu.org/licenses/. * + * For the list of contributors see $REST_PATH/CREDITS. * + *************************************************************************/ + +///////////////////////////////////////////////////////////////////////// +/// This class defines a stripped pattern. It defines a periodicity +/// and a thickness for the strips. The method TRestRadialStrippedMask::GetRegion +/// will return a unique id for each region in between strips. +/// +/// The stripped structure is centered in (0,0) and it can be shifted using +/// the offset defined inside TRestPatternMask. The pattern will be only +/// delimited by the limits imposed inside TRestPatternMask. +/// +/// ### Specific stripped metadata parameters +/// +/// * **stripsAngle**: This parameter defines the strips angular periodicity. +/// * **stripsThickness**: The thickness of the strips. +/// * **modulus**: A number that defines the range of ids used to identify +/// the different regions inside the stripped pattern. If modulus is 10, +/// then we will only be able to identify up to 10 unique regions. If a +/// larger amount of regions is found, it will happen that two regions will +/// be assigned the same id. +/// +/// ### Common pattern metadata parameters +/// +/// On top of the metadata class parameters, we may define common pattern +/// parameters to induce an offset and rotation to the pattern. +/// +/// * **offset**: A parameter to shift the pattern window mask. +/// * **rotationAngle**: An angle given in radians to rotate the pattern. +/// * **maskRadius**: A radius defining the limits of the circular mask. +/// +/// ### Examples +/// +/// Mask pattern RML definitions can be found inside the file +/// `REST_PATH/examples/masks.rml`. +/// +/// The following definition ilustrates a complete RML implementation of a +/// TRestRadialStrippedMask. +/// +/// \code +/// +/// +/// +/// +/// +/// +/// +/// +/// \endcode +/// +/// The basic use of this class is provided by the TRestRadialStrippedMask::GetRegion +/// method. For example: +/// +/// \code +/// TRestRadialStrippedMask mask("masks.rml", "radialStrips"); +/// Int_t id = mask.GetRegion( 12.5, 4.3 ); +/// std::cout << "Region id is : " << id << endl; +/// \endcode +/// +/// The following figure may be generated using the TRestPatternMask::DrawMonteCarlo +/// method. +/// +/// \code +/// TRestRadialStrippedMask mask("masks.rml", "radialStrips"); +/// TCanvas *c = mask.DrawMonteCarlo(30000); +/// c->Draw(); +/// c->Print("radialstrippedmask.png"); +/// \endcode +/// +/// \htmlonly \endhtmlonly +/// ![An illustration of the montecarlo mask test using DrawMonteCarlo](strippedmask.png) +/// +///---------------------------------------------------------------------- +/// +/// REST-for-Physics - Software for Rare Event Searches Toolkit +/// +/// History of developments: +/// +/// 2022-05: First implementation of TRestRadialStrippedMask +/// Javier Galan +/// +/// \class TRestRadialStrippedMask +/// \author: Javier Galan - javier.galan@unizar.es +/// +///
+/// + +#include "TRestRadialStrippedMask.h" + +#include "TRandom3.h" + +ClassImp(TRestRadialStrippedMask); + +/////////////////////////////////////////////// +/// \brief Default constructor +/// +TRestRadialStrippedMask::TRestRadialStrippedMask() : TRestPatternMask() { Initialize(); } + +///////////////////////////////////////////// +/// \brief Constructor loading data from a config file +/// +/// If no configuration path is defined using TRestMetadata::SetConfigFilePath +/// the path to the config file must be specified using full path, absolute or +/// relative. +/// +/// The default behaviour is that the config file must be specified with +/// full path, absolute or relative. +/// +/// \param cfgFileName A const char* giving the path to an RML file. +/// \param name The name of the specific metadata. It will be used to find the +/// corresponding TRestRadialStrippedMask section inside the RML. +/// +TRestRadialStrippedMask::TRestRadialStrippedMask(const char* cfgFileName, std::string name) + : TRestPatternMask(cfgFileName) { + Initialize(); + + LoadConfigFromFile(fConfigFileName, name); + + if (GetVerboseLevel() >= TRestStringOutput::REST_Verbose_Level::REST_Info) PrintMetadata(); +} + +/////////////////////////////////////////////// +/// \brief Default destructor +/// +TRestRadialStrippedMask::~TRestRadialStrippedMask() {} + +/////////////////////////////////////////////// +/// \brief Function to initialize input/output event members and define +/// the section name +/// +void TRestRadialStrippedMask::Initialize() { + SetSectionName(this->ClassName()); + SetType("RadialStripped"); +} + +/////////////////////////////////////////////// +/// \brief It returns a number identifying the region where the particle +/// with coordinates (x,y) felt in. The method returns 0 if the particle +/// hits the pattern. +/// +/// The particle will be counter-rotated to emulate the mask rotation +/// using the method TRestPatternMask::ApplyCommonMaskTransformation +/// +Int_t TRestRadialStrippedMask::GetRegion(Double_t& x, Double_t& y) { + if (TRestPatternMask::GetRegion(x, y)) return 0; + + Double_t d = TMath::Sqrt(x * x + y * y); + + if (d < fInitialRadius) { + if (fInternalRegionRadius > 0 && d < fInternalRegionRadius) return 1; + + return 0; + } + + TVector2 point(x, y); + Double_t phi = point.Phi(); + + /// phi determines the region where the point is found + Int_t region = (Int_t)(phi / fStripsAngle); + region = 2 + region % fMaxRegions; + + Double_t angle = 0; + /// Checking if we hit an arm + while (angle < 2 * TMath::Pi()) { + if (point.Y() < fStripsThickness / 2. && point.Y() > -fStripsThickness / 2. && point.X() >= 0) + return 0; + + point = point.Rotate(fStripsAngle); + angle += fStripsAngle; + } + + return 1 + region % fModulus; +} + +///////////////////////////////////////////// +/// \brief Prints on screen the complete information about the metadata members from this class +/// +void TRestRadialStrippedMask::PrintMetadata() { + TRestPatternMask::PrintMetadata(); + + PrintMaskMembers(); + RESTMetadata << "++++" << RESTendl; +} + +///////////////////////////////////////////// +/// \brief Prints on screen the information about the metadata members of TRestRingsMask, +/// including common pattern headers, but without common metadata headers. +/// +void TRestRadialStrippedMask::PrintMask() { + PrintCommonPatternMembers(); + RESTMetadata << "----" << RESTendl; + PrintMaskMembers(); +} + +///////////////////////////////////////////// +/// \brief Prints on screen the information about the metadata members of TRestRingsMask, +/// excluding common metadata headers. +/// +void TRestRadialStrippedMask::PrintMaskMembers() { + RESTMetadata << " - Strips angle : " << fStripsAngle * units("degrees") << " degrees" << RESTendl; + RESTMetadata << " - Strips thickness : " << fStripsThickness << " mm" << RESTendl; +} diff --git a/source/framework/sensitivity/inc/TRestSensitivity.h b/source/framework/sensitivity/inc/TRestSensitivity.h index a6ab4169c..c60350f9e 100644 --- a/source/framework/sensitivity/inc/TRestSensitivity.h +++ b/source/framework/sensitivity/inc/TRestSensitivity.h @@ -41,7 +41,7 @@ class TRestSensitivity : public TRestMetadata { Bool_t fFrozen = false; //< Only needed if we add experiments by other means than RML /// It is used to generate a histogram with the signal distribution produced with different signal samples - TH1D* fSignalTest = nullptr; + TH1D* fSignalTest = nullptr; //< /// A canvas to draw TCanvas* fCanvas = nullptr; //! @@ -69,8 +69,8 @@ class TRestSensitivity : public TRestMetadata { std::vector GetAveragedCurve(); std::vector> GetLevelCurves(const std::vector& levels); - void ExportCurve(std::string fname, int n); - void ExportAveragedCurve(std::string fname); + void ExportCurve(std::string fname, Double_t factor = 1.e-10, Double_t power = 0.25, int n = 0); + void ExportAveragedCurve(std::string fname, Double_t factor = 1.e-10, Double_t power = 0.25); TH1D* SignalStatisticalTest(Double_t node, Int_t N); diff --git a/source/framework/sensitivity/src/TRestSensitivity.cxx b/source/framework/sensitivity/src/TRestSensitivity.cxx index 57d44be79..b9dc66893 100644 --- a/source/framework/sensitivity/src/TRestSensitivity.cxx +++ b/source/framework/sensitivity/src/TRestSensitivity.cxx @@ -168,7 +168,7 @@ std::vector TRestSensitivity::GetAveragedCurve() { return averagedCurve; } -void TRestSensitivity::ExportAveragedCurve(std::string fname) { +void TRestSensitivity::ExportAveragedCurve(std::string fname, Double_t factor, Double_t power) { std::vector curve = GetAveragedCurve(); if (curve.empty()) std::cout << "Curve is empty" << std::endl; if (curve.empty()) return; @@ -191,7 +191,7 @@ void TRestSensitivity::ExportAveragedCurve(std::string fname) { int m = 0; for (const auto& node : fParameterizationNodes) { - outputFile << node << " " << curve[m] << std::endl; + outputFile << node << " " << factor * TMath::Power(curve[m], power) << std::endl; m++; } @@ -200,7 +200,7 @@ void TRestSensitivity::ExportAveragedCurve(std::string fname) { RESTInfo << "TRestSensitivity::ExportCurve. File has been written successfully!" << RESTendl; } -void TRestSensitivity::ExportCurve(std::string fname, int n = 0) { +void TRestSensitivity::ExportCurve(std::string fname, Double_t factor, Double_t power, int n) { std::vector curve = GetCurve(n); if (curve.empty()) return; @@ -221,7 +221,7 @@ void TRestSensitivity::ExportCurve(std::string fname, int n = 0) { int m = 0; for (const auto& node : fParameterizationNodes) { - outputFile << node << " " << curve[m] << std::endl; + outputFile << node << " " << factor * TMath::Power(curve[m], power) << std::endl; m++; }