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++;
}