41#include "TRestComponent.h"
71 RESTDebug <<
"Entering TRestComponent constructor( cfgFileName, name )" <<
RESTendl;
72 RESTDebug <<
"File: " << cfgFileName <<
" Name: " << name <<
RESTendl;
120 if (v == varName)
return n;
141 std::string responseVariable =
fResponse->GetVariable();
144 if (respVarIndex == -1) {
145 RESTError <<
"The response variable `" << responseVariable <<
"`, defined inside TRestResponse,"
147 RESTError <<
"could not be found inside the component." <<
RESTendl;
148 RESTError <<
"Please, check the component variable names." <<
RESTendl;
152 std::vector<std::pair<Double_t, Double_t> > response =
fResponse->
GetResponse(point[respVarIndex]);
155 for (
const auto& resp : response) {
156 std::vector<Double_t> newPoint = point;
157 newPoint[respVarIndex] = resp.first;
186 Double_t normFactor = 1;
187 for (
size_t n = 0; n < GetDimensions(); n++) normFactor *=
fNbins[n] / (
fRanges[n].Y() -
fRanges[n].X());
189 return normFactor *
GetRate(point);
211 if (point.size() != GetDimensions()) {
212 RESTError <<
"The size of the point given is : " << point.size() <<
RESTendl;
213 RESTError <<
"The density distribution dimensions are : " << GetDimensions() <<
RESTendl;
214 RESTError <<
"Point must have the same dimension as the distribution" <<
RESTendl;
219 RESTError <<
"TRestComponent::GetRawRate. The component has no nodes!" <<
RESTendl;
220 RESTError <<
"Try calling TRestComponent::Initialize" <<
RESTendl;
222 RESTInfo <<
"Trying to initialize" <<
RESTendl;
231 RESTError <<
"TRestComponent::GetRawRate. Active node has not been defined" <<
RESTendl;
235 Int_t centerBin[GetDimensions()];
236 Double_t centralDensity = GetDensity()->GetBinContent(GetDensity()->GetBin(point.data()), centerBin);
237 if (!Interpolation())
return centralDensity;
239 std::vector<Int_t> direction;
240 std::vector<Double_t> nDist;
241 for (
size_t dim = 0; dim < GetDimensions(); dim++) {
245 if (centerBin[dim] == 1 || centerBin[dim] ==
fNbins[dim]) {
246 direction.push_back(0);
248 }
else if (x2 - point[dim] > point[dim] - x1) {
250 direction.push_back(-1);
251 nDist.push_back(1 - 2 * (point[dim] - x1) / (x2 - x1));
253 direction.push_back(1);
254 nDist.push_back(1 - 2 * (x2 - point[dim]) / (x2 - x1));
261 Int_t nPoints = (Int_t)TMath::Power(2, (Int_t)GetDimensions());
264 for (
int n = 0; n < nPoints; n++) {
267 Double_t weightDistance = 1;
269 for (
const auto& c : cell) {
271 weightDistance *= (1 - nDist[cont]);
273 weightDistance *= nDist[cont];
277 for (
size_t k = 0; k < cell.size(); k++) cell[k] = cell[k] * direction[k] + centerBin[k];
279 Double_t density = GetDensity()->GetBinContent(cell.data());
280 sum += density * weightDistance;
291 THnD* dHist = GetDensityForActiveNode();
293 Double_t integral = 0;
294 if (dHist !=
nullptr) {
295 TH1D* h1 = dHist->Projection(0);
296 integral = h1->Integral();
312ROOT::RVecD TRestComponent::GetRandom() {
313 Double_t* tuple =
new Double_t[GetDimensions()];
317 for (
size_t n = 0; n < GetDimensions(); n++) result.push_back(0);
318 RESTWarning <<
"TRestComponent::GetRandom. Component might not be initialized! Use "
319 "TRestComponent::Initialize()."
324 GetDensity()->GetRandom(tuple);
326 for (
size_t n = 0; n < GetDimensions(); n++) result.push_back(tuple[n]);
330ROOT::RDF::RNode TRestComponent::GetMonteCarloDataFrame(Int_t N) {
331 ROOT::RDF::RNode df = ROOT::RDataFrame(N);
334 auto fillRndm = [&]() {
335 ROOT::RVecD randomValues = GetRandom();
338 df = df.Define(
"Rndm", fillRndm);
341 for (
size_t i = 0; i <
fVariables.size(); ++i) {
343 auto FillRand = [i](
const ROOT::RVecD& randomValues) {
return randomValues[i]; };
344 df = df.Define(varName, FillRand, {
"Rndm"});
348 std::vector<std::string> columns = df.GetColumnNames();
349 std::vector<std::string> excludeColumns = {
"Rndm"};
350 columns.erase(std::remove_if(columns.begin(), columns.end(),
351 [&excludeColumns](std::string elem) {
352 return std::find(excludeColumns.begin(), excludeColumns.end(), elem) !=
353 excludeColumns.end();
357 std::string user = getenv(
"USER");
358 std::string fOutName =
"/tmp/rest_output_" + user +
".root";
359 df.Snapshot(
"AnalysisTree", fOutName, columns);
361 df = ROOT::RDataFrame(
"AnalysisTree", fOutName);
376 std::vector<std::string> scanVariables, Int_t binScanSize,
377 TString drawOption) {
378 if (drawVariables.size() > 2 || drawVariables.size() == 0) {
379 RESTError <<
"TRestComponent::DrawComponent. The number of variables to be drawn must "
385 if (scanVariables.size() > 2 || scanVariables.size() == 0) {
386 RESTError <<
"TRestComponent::DrawComponent. The number of variables to be scanned must "
393 std::vector<int> scanIndexes;
394 for (
const auto& x : scanVariables) scanIndexes.push_back(
GetVariableIndex(x));
398 for (
const auto& x : scanIndexes) {
399 if (
fNbins[x] % binScanSize != 0) {
400 RESTWarning <<
"The variable " << scanVariables[n] <<
" contains " <<
fNbins[x]
401 <<
" bins and it doesnt match with a bin size " << binScanSize <<
RESTendl;
402 RESTWarning <<
"The bin size must be a multiple of the number of bins." <<
RESTendl;
403 RESTWarning <<
"Redefining bin size to 1." <<
RESTendl;
406 nPlots *=
fNbins[x] / binScanSize;
414 if (scanIndexes.size() == 2) {
415 nPlotsX =
fNbins[scanIndexes[0]] / binScanSize;
416 nPlotsY =
fNbins[scanIndexes[1]] / binScanSize;
422 RESTInfo <<
"Number of plots to be generated: " << nPlots <<
RESTendl;
423 RESTInfo <<
"Canvas size : " << nPlotsX <<
" x " << nPlotsY <<
RESTendl;
431 fCanvas =
new TCanvas(this->GetName(), this->GetName(), 0, 0, nPlotsX * 640, nPlotsY * 480);
432 fCanvas->Divide(nPlotsX, nPlotsY, 0.01, 0.01);
434 std::vector<int> variableIndexes;
435 for (
const auto& x : drawVariables) variableIndexes.push_back(
GetVariableIndex(x));
437 for (
int n = 0; n < nPlotsX; n++)
438 for (
int m = 0; m < nPlotsY; m++) {
439 TPad* pad = (TPad*)
fCanvas->cd(n * nPlotsY + m + 1);
440 pad->SetFixedAspectRatio(
true);
442 THnD* hnd = GetDensity();
444 int binXo = binScanSize * n + 1;
445 int binXf = binScanSize * n + binScanSize;
446 int binYo = binScanSize * m + 1;
447 int binYf = binScanSize * m + binScanSize;
449 if (scanVariables.size() == 2) {
450 hnd->GetAxis(scanIndexes[0])->SetRange(binXo, binXf);
451 hnd->GetAxis(scanIndexes[1])->SetRange(binYo, binYf);
452 }
else if (scanVariables.size() == 1) {
453 binXo = binScanSize * nPlotsY * n + binScanSize * m + 1;
454 binXf = binScanSize * nPlotsY * n + binScanSize * m + binScanSize;
455 hnd->GetAxis(scanIndexes[0])->SetRange(binXo, binXf);
458 if (variableIndexes.size() == 1) {
459 TH1D* h1 = hnd->Projection(variableIndexes[0]);
462 if (scanIndexes.size() == 2)
467 if (scanIndexes.size() == 1)
471 TH1D* newh = (TH1D*)h1->Clone(hName.c_str());
472 newh->SetTitle(hName.c_str());
473 newh->SetStats(
false);
474 newh->GetXaxis()->SetTitle((TString)drawVariables[0]);
475 newh->SetMarkerStyle(kFullCircle);
476 newh->Draw(
"PLC PMC");
478 TString entriesStr =
"Entries: " +
IntegerToString(newh->GetEntries());
479 TLatex* textLatex =
new TLatex(0.62, 0.825, entriesStr);
481 textLatex->SetTextColor(1);
482 textLatex->SetTextSize(0.05);
483 textLatex->Draw(
"same");
487 if (variableIndexes.size() == 2) {
488 TH2D* h2 = hnd->Projection(variableIndexes[0], variableIndexes[1]);
491 if (scanIndexes.size() == 2)
496 if (scanIndexes.size() == 1)
500 TH2D* newh = (TH2D*)h2->Clone(hName.c_str());
501 newh->SetStats(
false);
502 newh->GetXaxis()->SetTitle((TString)drawVariables[0]);
503 newh->GetYaxis()->SetTitle((TString)drawVariables[1]);
504 newh->SetTitle(hName.c_str());
505 newh->Draw(drawOption);
507 TString entriesStr =
"Entries: " +
IntegerToString(newh->GetEntries());
508 TLatex* textLatex =
new TLatex(0.62, 0.825, entriesStr);
510 textLatex->SetTextColor(1);
511 textLatex->SetTextSize(0.05);
512 textLatex->Draw(
"same");
523void TRestComponent::LoadResponse(
const TRestResponse& resp) {
549 RESTWarning <<
"The number of variables does not match with the number of defined ranges!"
553 RESTWarning <<
"The number of variables does not match with the number of defined bins!" <<
RESTendl;
556 RESTMetadata <<
" === Variables === " <<
RESTendl;
558 RESTMetadata <<
" - Name: " << varName <<
" Range: (" <<
fRanges[n].X() <<
", " <<
fRanges[n].Y()
566 RESTMetadata <<
" === Parameterization === " <<
RESTendl;
571 RESTMetadata <<
" Use : PrintNodes() for additional info" <<
RESTendl;
576 RESTMetadata <<
"A response matrix was loaded inside the component" <<
RESTendl;
577 RESTMetadata <<
"You may get more details using TRestComponent::GetResponse()->PrintMetadata()"
590 std::cout << std::endl;
600 while (ele !=
nullptr) {
602 TVector2 v = Get2DVectorParameterWithUnits(
"range", ele, TVector2(-1, -1));
605 if (name.empty() || (v.X() == -1 && v.Y() == -1) || bins == 0) {
606 RESTWarning <<
"TRestComponentFormula::fVariable. Problem with definition." <<
RESTendl;
607 RESTWarning <<
"Name: " << name <<
" range: (" << v.X() <<
", " << v.Y() <<
") bins: " << bins
619 RESTError <<
"TRestComponent::InitFromConfigFile. No cVariables where found!" <<
RESTendl;
639 if (v > pDown && v < pUp) {
658 if (v > pDown && v < pUp) {
665 RESTError <<
"Parametric node : " << node <<
" was not found in component" <<
RESTendl;
675THnD* TRestComponent::GetDensityForNode(Double_t node) {
684 RESTError <<
"Parametric node : " << node <<
" was not found in component" <<
RESTendl;
692THnD* TRestComponent::GetDensityForActiveNode() {
695 RESTError <<
"The active node is invalid" <<
RESTendl;
719 if (v1 >= 0 && GetDensityForActiveNode())
return GetDensityForActiveNode()->Projection(v1);
744 if (v1 >= 0 && v2 >= 0)
745 if (GetDensityForActiveNode())
return GetDensityForActiveNode()->Projection(v1, v2);
755 std::string varName3) {
772 if (v1 >= 0 && v2 >= 0 && v3 >= 0)
773 if (GetDensityForActiveNode())
return GetDensityForActiveNode()->Projection(v1, v2, v3);
It defines a background/signal model distribution in a given parameter space (tipically x,...
UInt_t fSeed
Seed used in random generator.
void InitFromConfigFile() override
It customizes the retrieval of XML data values of this class.
void PrintMetadata() override
Prints on screen the information about the metadata members of TRestAxionSolarFlux.
Int_t fActiveNode
It is used to define the node that will be accessed for rate retrieval.
Int_t FindActiveNode(Double_t node)
It returns the position of the fParameterizationNodes element for the variable name given by argument...
Int_t fSamples
It introduces a fixed number of samples (if 0 it will take all available samples)
Int_t GetVariableIndex(std::string varName)
It returns the position of the fVariable element for the variable name given by argument.
Double_t GetBinCenter(Int_t nDim, const Int_t bin)
It returns the bin center of the given component dimension.
void PrintNodes()
It prints out on screen the values of the parametric node.
Double_t GetRawRate(std::vector< Double_t > point)
It returns the intensity/rate (in seconds) corresponding to the generated distribution or formula eva...
std::string fParameter
It is used to parameterize a set of distribution densities (e.g. WIMP or axion mass)
Double_t GetNormalizedRate(std::vector< Double_t > point)
It returns the intensity/rate (in seconds) corresponding to the generated distribution or formula eva...
TRestComponent()
Default constructor.
TH1D * GetHistogram(Double_t node, std::string varName)
It returns a 1-dimensional projected histogram for the variable names provided in the argument.
Float_t fPrecision
A precision used to select the node value with a given range defined as a fraction of the value.
std::vector< Int_t > fNbins
The number of bins in which we should divide each variable.
TCanvas * DrawComponent(std::vector< std::string > drawVariables, std::vector< std::string > scanVariables, Int_t binScanSize=1, TString drawOption="")
A method allowing to draw a series of plots representing the density distributions.
void Initialize() override
It initializes the random number. We avoid to define the section name here since we will never define...
TRestResponse * fResponse
A pointer to the detector response.
Double_t GetTotalRate()
This method integrates the rate to all the parameter space defined in the density function....
std::vector< TVector2 > fRanges
The range of each of the variables used to create the PDF distribution.
std::vector< Double_t > fParameterizationNodes
It defines the nodes of the parameterization (Initialized by the dataset)
Bool_t HasNodes()
It returns true if any nodes have been defined.
TCanvas * fCanvas
A canvas for drawing the active node component.
Double_t GetRate(std::vector< Double_t > point)
It returns the intensity/rate (in seconds) corresponding to the generated distribution or formula eva...
TRandom3 * fRandom
Internal process random generator.
std::vector< std::string > fVariables
A list with the branches that will be used to create the distribution space.
~TRestComponent()
Default destructor.
void RegenerateHistograms(UInt_t seed=0)
It will produce a histogram with the distribution defined using the variables and the weights for eac...
Int_t SetActiveNode(Double_t node)
It returns the position of the fParameterizationNodes element for the variable name given by argument...
std::vector< THnD * > fNodeDensity
The generated N-dimensional variable space density for a given node.
std::string fNature
It defines the component type (unknown/signal/background)
A response matrix that might be applied to a given component inside a TRestComponent.
void LoadResponse(Bool_t transpose=true)
It loads into the fResponseMatrix data member the response from a file.
std::vector< std::pair< Double_t, Double_t > > GetResponse(Double_t input)
This method will return a vector of std::pair, each pair will contain the output energy together with...
void PrintMetadata() override
Prints on screen the information about the metadata members of TRestAxionSolarFlux.
std::string IntegerToString(Int_t n, std::string format="%d")
Gets a string from an integer.
Int_t StringToInteger(std::string in)
Gets an integer from a string.
std::vector< int > IntegerToBinary(int number, size_t dimension=0)
It returns an integer vector with the binary digits decomposed.