41 #include "TRestComponent.h"
71 RESTDebug <<
"Entering TRestComponent constructor( cfgFileName, name )" <<
RESTendl;
72 RESTDebug <<
"File: " << cfgFileName <<
" Name: " << name <<
RESTendl;
127 Bool_t expIncrease) {
152 if (v == varName)
return n;
173 std::string responseVariable =
fResponse->GetVariable();
176 if (respVarIndex == -1) {
177 RESTError <<
"The response variable `" << responseVariable <<
"`, defined inside TRestResponse,"
179 RESTError <<
"could not be found inside the component." <<
RESTendl;
180 RESTError <<
"Please, check the component variable names." <<
RESTendl;
184 std::vector<std::pair<Double_t, Double_t> > response =
fResponse->
GetResponse(point[respVarIndex]);
187 for (
const auto& resp : response) {
188 std::vector<Double_t> newPoint = point;
189 newPoint[respVarIndex] = resp.first;
218 Double_t normFactor = 1;
219 for (
size_t n = 0; n < GetDimensions(); n++) normFactor *=
fNbins[n] / (
fRanges[n].Y() -
fRanges[n].X());
221 return normFactor *
GetRate(point);
243 if (point.size() != GetDimensions()) {
244 RESTError <<
"The size of the point given is : " << point.size() <<
RESTendl;
245 RESTError <<
"The density distribution dimensions are : " << GetDimensions() <<
RESTendl;
246 RESTError <<
"Point must have the same dimension as the distribution" <<
RESTendl;
251 RESTError <<
"TRestComponent::GetRawRate. The component has no nodes!" <<
RESTendl;
252 RESTError <<
"Try calling TRestComponent::Initialize" <<
RESTendl;
254 RESTInfo <<
"Trying to initialize" <<
RESTendl;
263 RESTError <<
"TRestComponent::GetRawRate. Active node has not been defined" <<
RESTendl;
267 for (
size_t n = 0; n < point.size(); n++) {
269 if (point[n] <
fRanges[n].X() || point[n] >
fRanges[n].Y())
return 0;
272 Int_t centerBin[GetDimensions()];
273 Double_t centralDensity = GetDensity()->GetBinContent(GetDensity()->GetBin(point.data()), centerBin);
274 if (!Interpolation())
return centralDensity;
276 std::vector<Int_t> direction;
277 std::vector<Double_t> nDist;
278 for (
size_t dim = 0; dim < GetDimensions(); dim++) {
282 if (centerBin[dim] == 1 || centerBin[dim] ==
fNbins[dim]) {
283 direction.push_back(0);
285 }
else if (x2 - point[dim] > point[dim] - x1) {
287 direction.push_back(-1);
288 nDist.push_back(1 - 2 * (point[dim] - x1) / (x2 - x1));
290 direction.push_back(1);
291 nDist.push_back(1 - 2 * (x2 - point[dim]) / (x2 - x1));
298 Int_t nPoints = (Int_t)TMath::Power(2, (Int_t)GetDimensions());
301 for (
int n = 0; n < nPoints; n++) {
304 Double_t weightDistance = 1;
306 for (
const auto& c : cell) {
308 weightDistance *= (1 - nDist[cont]);
310 weightDistance *= nDist[cont];
314 for (
size_t k = 0; k < cell.size(); k++) cell[k] = cell[k] * direction[k] + centerBin[k];
316 Double_t density = GetDensity()->GetBinContent(cell.data());
317 sum += density * weightDistance;
328 THnD* dHist = GetDensityForActiveNode();
329 if (!dHist)
return 0;
331 Double_t integral = 0;
332 for (Int_t n = 0; n < dHist->GetNbins(); ++n) {
333 Int_t centerBin[GetDimensions()];
334 std::vector<Double_t> point;
336 dHist->GetBinContent(n, centerBin);
337 for (
size_t d = 0; d < GetDimensions(); ++d) point.push_back(
GetBinCenter(d, centerBin[d]));
340 for (
size_t d = 0; d < GetDimensions(); ++d) {
341 if (point[d] <
fRanges[d].X() || point[d] >
fRanges[d].Y()) skip =
true;
343 if (!skip) integral +=
GetRate(point);
354 Double_t maxRate = 0;
358 if (rate > maxRate) maxRate = rate;
385 ROOT::RVecD TRestComponent::GetRandom() {
386 Double_t* tuple =
new Double_t[GetDimensions()];
390 for (
size_t n = 0; n < GetDimensions(); n++) result.push_back(0);
391 RESTWarning <<
"TRestComponent::GetRandom. Component might not be initialized! Use "
392 "TRestComponent::Initialize()."
397 GetDensity()->GetRandom(tuple);
399 for (
size_t n = 0; n < GetDimensions(); n++) result.push_back(tuple[n]);
403 ROOT::RDF::RNode TRestComponent::GetMonteCarloDataFrame(Int_t N) {
404 ROOT::RDF::RNode df = ROOT::RDataFrame(N);
407 auto fillRndm = [&]() {
408 ROOT::RVecD randomValues = GetRandom();
411 df = df.Define(
"Rndm", fillRndm);
414 for (
size_t i = 0; i <
fVariables.size(); ++i) {
416 auto FillRand = [i](
const ROOT::RVecD& randomValues) {
return randomValues[i]; };
417 df = df.Define(varName, FillRand, {
"Rndm"});
421 std::vector<std::string> columns = df.GetColumnNames();
422 std::vector<std::string> excludeColumns = {
"Rndm"};
423 columns.erase(std::remove_if(columns.begin(), columns.end(),
424 [&excludeColumns](std::string elem) {
425 return std::find(excludeColumns.begin(), excludeColumns.end(), elem) !=
426 excludeColumns.end();
430 std::string user = getenv(
"USER");
431 std::string fOutName =
"/tmp/rest_output_" + user +
".root";
432 df.Snapshot(
"AnalysisTree", fOutName, columns);
434 df = ROOT::RDataFrame(
"AnalysisTree", fOutName);
449 std::vector<std::string> scanVariables, Int_t binScanSize,
450 TString drawOption) {
451 if (drawVariables.size() > 2 || drawVariables.size() == 0) {
452 RESTError <<
"TRestComponent::DrawComponent. The number of variables to be drawn must "
458 if (scanVariables.size() > 2 || scanVariables.size() == 0) {
459 RESTError <<
"TRestComponent::DrawComponent. The number of variables to be scanned must "
466 std::vector<int> scanIndexes;
467 for (
const auto& x : scanVariables) scanIndexes.push_back(
GetVariableIndex(x));
471 for (
const auto& x : scanIndexes) {
472 if (
fNbins[x] % binScanSize != 0) {
473 RESTWarning <<
"The variable " << scanVariables[n] <<
" contains " <<
fNbins[x]
474 <<
" bins and it doesnt match with a bin size " << binScanSize <<
RESTendl;
475 RESTWarning <<
"The bin size must be a multiple of the number of bins." <<
RESTendl;
476 RESTWarning <<
"Redefining bin size to 1." <<
RESTendl;
479 nPlots *=
fNbins[x] / binScanSize;
487 if (scanIndexes.size() == 2) {
488 nPlotsX =
fNbins[scanIndexes[0]] / binScanSize;
489 nPlotsY =
fNbins[scanIndexes[1]] / binScanSize;
495 RESTInfo <<
"Number of plots to be generated: " << nPlots <<
RESTendl;
496 RESTInfo <<
"Canvas size : " << nPlotsX <<
" x " << nPlotsY <<
RESTendl;
504 fCanvas =
new TCanvas(this->GetName(), this->GetName(), 0, 0, nPlotsX * 640, nPlotsY * 480);
505 fCanvas->Divide(nPlotsX, nPlotsY, 0.01, 0.01);
507 std::vector<int> variableIndexes;
508 for (
const auto& x : drawVariables) variableIndexes.push_back(
GetVariableIndex(x));
510 for (
int n = 0; n < nPlotsX; n++)
511 for (
int m = 0; m < nPlotsY; m++) {
512 TPad* pad = (TPad*)
fCanvas->cd(n * nPlotsY + m + 1);
513 pad->SetFixedAspectRatio(
true);
515 THnD* hnd = GetDensity();
517 int binXo = binScanSize * n + 1;
518 int binXf = binScanSize * n + binScanSize;
519 int binYo = binScanSize * m + 1;
520 int binYf = binScanSize * m + binScanSize;
522 if (scanVariables.size() == 2) {
523 hnd->GetAxis(scanIndexes[0])->SetRange(binXo, binXf);
524 hnd->GetAxis(scanIndexes[1])->SetRange(binYo, binYf);
525 }
else if (scanVariables.size() == 1) {
526 binXo = binScanSize * nPlotsY * n + binScanSize * m + 1;
527 binXf = binScanSize * nPlotsY * n + binScanSize * m + binScanSize;
528 hnd->GetAxis(scanIndexes[0])->SetRange(binXo, binXf);
531 if (variableIndexes.size() == 1) {
532 TH1D* h1 = hnd->Projection(variableIndexes[0]);
535 if (scanIndexes.size() == 2)
540 if (scanIndexes.size() == 1)
544 TH1D* newh = (TH1D*)h1->Clone(hName.c_str());
545 newh->SetTitle(hName.c_str());
546 newh->SetStats(
false);
547 newh->GetXaxis()->SetTitle((TString)drawVariables[0]);
548 newh->SetMarkerStyle(kFullCircle);
549 newh->Draw(
"PLC PMC");
551 TString entriesStr =
"Entries: " +
IntegerToString(newh->GetEntries());
552 TLatex* textLatex =
new TLatex(0.62, 0.825, entriesStr);
554 textLatex->SetTextColor(1);
555 textLatex->SetTextSize(0.05);
556 textLatex->Draw(
"same");
560 if (variableIndexes.size() == 2) {
561 TH2D* h2 = hnd->Projection(variableIndexes[0], variableIndexes[1]);
564 if (scanIndexes.size() == 2)
569 if (scanIndexes.size() == 1)
573 TH2D* newh = (TH2D*)h2->Clone(hName.c_str());
574 newh->SetStats(
false);
575 newh->GetXaxis()->SetTitle((TString)drawVariables[0]);
576 newh->GetYaxis()->SetTitle((TString)drawVariables[1]);
577 newh->SetTitle(hName.c_str());
578 newh->Draw(drawOption);
580 TString entriesStr =
"Entries: " +
IntegerToString(newh->GetEntries());
581 TLatex* textLatex =
new TLatex(0.62, 0.825, entriesStr);
583 textLatex->SetTextColor(1);
584 textLatex->SetTextSize(0.05);
585 textLatex->Draw(
"same");
596 void TRestComponent::LoadResponse(
const TRestResponse& resp) {
622 RESTWarning <<
"The number of variables does not match with the number of defined ranges!"
626 RESTWarning <<
"The number of variables does not match with the number of defined bins!" <<
RESTendl;
629 RESTMetadata <<
" === Variables === " <<
RESTendl;
631 RESTMetadata <<
" - Name: " << varName <<
" Range: (" <<
fRanges[n].X() <<
", " <<
fRanges[n].Y()
639 RESTMetadata <<
" === Parameterization === " <<
RESTendl;
644 RESTMetadata <<
" Use : PrintNodes() for additional info" <<
RESTendl;
648 RESTMetadata <<
" Nodes were automatically generated using these parameters" <<
RESTendl;
653 RESTMetadata <<
" - Increases exponentially" <<
RESTendl;
655 RESTMetadata <<
" - Increases linearly" <<
RESTendl;
661 RESTMetadata <<
"A response matrix was loaded inside the component" <<
RESTendl;
662 RESTMetadata <<
"You may get more details using TRestComponent::GetResponse()->PrintMetadata()"
675 std::cout << std::endl;
685 while (ele !=
nullptr) {
687 TVector2 v = Get2DVectorParameterWithUnits(
"range", ele, TVector2(-1, -1));
690 if (name.empty() || (v.X() == -1 && v.Y() == -1) || bins == 0) {
691 RESTWarning <<
"TRestComponentFormula::fVariable. Problem with definition." <<
RESTendl;
692 RESTWarning <<
"Name: " << name <<
" range: (" << v.X() <<
", " << v.Y() <<
") bins: " << bins
704 RESTError <<
"TRestComponent::InitFromConfigFile. No cVariables where found!" <<
RESTendl;
724 if (v > pDown && v < pUp) {
743 if (v > pDown && v < pUp) {
750 RESTError <<
"Parametric node : " << node <<
" was not found in component" <<
RESTendl;
760 THnD* TRestComponent::GetDensityForNode(Double_t node) {
769 RESTError <<
"Parametric node : " << node <<
" was not found in component" <<
RESTendl;
777 THnD* TRestComponent::GetDensityForActiveNode() {
780 RESTError <<
"The active node is invalid" <<
RESTendl;
804 if (v1 >= 0 && GetDensityForActiveNode())
return GetDensityForActiveNode()->Projection(v1);
829 if (v1 >= 0 && v2 >= 0)
830 if (GetDensityForActiveNode())
return GetDensityForActiveNode()->Projection(v1, v2);
840 std::string varName3) {
857 if (v1 >= 0 && v2 >= 0 && v3 >= 0)
858 if (GetDensityForActiveNode())
return GetDensityForActiveNode()->Projection(v1, v2, v3);
It defines a background/signal model distribution in a given parameter space (tipically x,...
Double_t fFirstParameterValue
It defines the first parametric node value in case of automatic parameter generation.
Double_t fLastParameterValue
It defines the upper limit for the automatic parametric node values generation.
UInt_t fSeed
Seed used in random generator.
Double_t fStepParameterValue
It defines the increasing step for automatic parameter list generation.
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.
Double_t GetAllNodesIntegratedRate()
This method returns the integrated total rate for all the nodes The result will be returned in s-1.
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...
void RegenerateParametricNodes(Double_t from, Double_t to, Double_t step, Bool_t expIncrease=false)
It allows to produce a parameter nodes list providing the initial value, the final value and the step...
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...
Bool_t fExponential
It true the parametric values automatically generated will grow exponentially.
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.
Double_t GetMaxRate()
This method returns the total rate for the node that has the highest contribution The result will be ...
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.