首页 > 解决方案 > 自定义类 - 设置时成员变量为空

问题描述

标题可能是错误的措辞,我不太熟悉我应该使用的正确语言。

对于这个问题,我有这个测试区域,我在playground.cc其中创建了一个类的实例RooSNLikelihood(第 86 行)。从这里,我为实例提供RooSNLikelihood了一个指向 aTGraph*和的指针std::vector<Double_t>。这是通过通过SetROOTPointers该类中的函数传递它们来完成的。当我调用std::vector.size()我的向量或任何成员函数时TGraphSetROOTPointers信息会按我的预期打印出来。我附上了一个代码片段,您可以在其中看到向量的大小为 108。但是,稍后playground.cc我调用customFunc->plotOn(frame)(第 102 行),这又调用了类evaluate()中的函数RooSNLikelihood。不幸的是,当它被调用时,meanevents成员变量为空。在事件的情况下,它会打印出 0(而不是 108),并且对 TGraph 的任何评估都会导致 seg 错误,因为它是一个空指针。

Warning in <TUnixSystem::SetDisplay>: DISPLAY not set, setting it to BLAH
108
Creating the frame
Plotting the function on the frame
[#0] ERROR:Plotting -- RooAbsReal::bob:plotOn: WARNING: variable is not an explicit dependent: t0
[#0] ERROR:Plotting -- RooAbsReal::bob:createPlotProjection: "t0" is not a dependent and will be ignored.
Getting the events in the burst = 0 0
Creating the norm


 *** Break *** segmentation violation

我在这里做错了什么,以至于成员变量被“遗忘”了吗?如果需要更多信息,请告诉我。我已经“附加”了三个必要的文件。

有人可以提供的任何帮助将不胜感激。

干杯,

雷米

游乐场.cc

#include "RooSNLikelihood.hh"

using namespace RooFit;

TFile* outputFile;
TTree* outputTree;

TGraph* g;
TGraph* g2;

double theMean(Double_t* x, Double_t*){
  double num = g->Eval(x[0]);  
  return num;
}

double l(Double_t* x, Double_t*){
  double like = g2->Eval(x[0]);
  return like;
}

int main(int argc, char* argv[]){

  int lBound = atoi(argv[1]);
  int uBound = atoi(argv[2]);
  char* filename = argv[3];

  RooRandom::randomGenerator()->SetSeed(3020);
  
  //The variable time with 1 ms bins.
  RooRealVar t("t", "t", -0.02, 10);
  t.setBins(10020);
  // This is the observable (t_0, time of core bounce).
  RooRealVar t0("t0", "t0", 0);
  // Create a formula for the derivative - t0.
  RooFormulaVar formula("t-t0", "t-t0", RooArgSet(t,t0));
  // Need to create a coefficient for the pdf. Since our pdf will
  // be a sum of functions (but there is only one function).
  RooRealVar coef("c", "c", 1);
  
  // This file contains the TGraph (which is the mean as a function of time).
  TFile* file = new TFile(filename, "OPEN");
  TTree* tree = (TTree*)file->Get("mean");
  g = (TGraph*)file->Get("mean-time");
  g->SetName("g");
  TF1* mean = new TF1("fun", theMean, -0.02, 10);

  // Convert this into RooAbsReal.
  RooAbsReal* func = bindFunction(mean, formula);
  
  // Get the derivative of this function.
  RooAbsReal* der = (RooAbsReal*)func->derivative(t, 1);

  // This will exist temporarily to test the custom RooFit function. 
  // From here, I will just open a random TTree and get the data. 
  std::vector<Double_t> evts;

  TFile* testFile = new TFile("/project/halo/remington/Programs/snowglobes/out/garching-5kpc/SimData/OUTPUT-SimData-Neutron-Batch-67.root", "OPEN");
  TTree* testTree = (TTree*)testFile->Get("background");

  testTree->Draw("time", "", "goff");
  Int_t testLength = testTree->GetSelectedRows();

  for (Int_t v = 0; v < testLength; v++){
    evts.push_back( testTree->GetV1()[v] );
  }

  std::sort(evts.begin(), evts.end());

  RooSNLikelihood* customFunc = new RooSNLikelihood("bob", "iterator", t0);
  
  std::cout << evts.size() << std::endl;

  customFunc->SetROOTPointers(g,evts);
  
  // Make the Canvas for later.
  TCanvas* c = new TCanvas("c", "c", 800, 800);
  c->Divide(3,1);


  // Make a frame and plot the above on it.
  std::cout << "Creating the frame" << std::endl;
  RooPlot* frame = t0.frame(Range(-0.1, 0.1));
  c->cd(1);
  std::cout << "Plotting the function on the frame" << std::endl;
  customFunc->plotOn(frame);
  std::cout << "Drawing the frame" << std::endl;
  frame->Draw();
  
  // Close the original data file.
  //file->Close();

  return 0;
     
}

RooSNLikelihood.cc

#include "RooSNLikelihood.hh"

// Class constructor for RooSNLikelihood.
RooSNLikelihood::RooSNLikelihood(const char *name, const char *title, RooAbsReal& _t0) :

  RooAbsReal(name, title)
  //t0("t0", "Time of core bounce", this, _t0)
{

  // Here, I want to set some of the ROOT stuff for later. I was originally thinking of using
  // a dedicated function like SetROOTPointers, but we shall just do it in the constructor.

  // What is the mean we shall be using later?
  //mean = graph;
  // What is the event signal we shall use later?
  //events = vec;

}

// Class copy constructor of RooSNLikelihood.
RooSNLikelihood::RooSNLikelihood(const RooSNLikelihood& other, const char* name) :

  RooAbsReal(other, name)
  //t0(this,other.t0)

{
}

void RooSNLikelihood::SetROOTPointers(TGraph* graph, std::vector<Double_t> vec){

  // Just need to set the file and tree variables.
  mean = graph;
  events = vec;

}


Double_t RooSNLikelihood::evaluate() const
{

  // Okay, so here we will construct the likelihood function.
  // To do so we will make use of the mean event evolution (TGraph theMean).
  Double_t likelihood = 0.0;

  // First thing first let us get the number of events in the burst.
  // Use this to sum over (as per the Likelihood section in the paper
  // I haven't finished...)
  Int_t numEvtInBurst = events.size();
  std::cout << "Getting the events in the burst = " << numEvtInBurst << " " << events.size() << std::endl;

  std::cout << "Creating the norm" << std::endl;
  // Get the normalization constant. Ratio of events in burst compared to
  // mean events at a time t_N.
  Double_t norm = (Double_t)numEvtInBurst / ( mean->Eval( events.at(numEvtInBurst-1),0,0 ) );

  std::cout << "Beginning the for loop" << std::endl;
  // Use this to sum over the events.
  for (Int_t j = 0; j < numEvtInBurst; j++){

    // Get the current event time.
    Double_t t = events.at(j);

    // Evaluate the mean at this time minus t0.
    Double_t evalMean = mean->Eval(t-t0, 0, 0);

    // First likelihood term.
    Double_t firstTerm = norm*evalMean;
    // Second likelihood term.
    Double_t secondTerm = -1*(j+1)*TMath::Log(evalMean*norm);
    // There is a third term that is constant for all points so we remove it.

    likelihood += firstTerm + secondTerm;

    std::cout << "The likleihood at t_0 = " << t0 << ", is " << likelihood << std::endl;

  }

  return likelihood;

}

RooSNLikelihood.hh

#include <RooWorkspace.h>
#include <RooRealSumPdf.h>
#include <RooMinimizer.h>
#include <RooCFunction1Binding.h>
#include <RooTFnBinding.h>

// Some ROOT stuff.
#include <TF1.h>
#include <TGraph.h>
#include <TFile.h>
#include <TTree.h>
#include <TH1F.h>
#include <TMath.h>
#include <TDirectory.h>
#include <TSystem.h>
#include <TFitResultPtr.h>
#include <TCanvas.h>
#include <TROOT.h>

// Some stuff from Andreas minimization code.
#if !defined(__CINT__) || defined (__MAKECINT__)
#include "Riostream.h"
#include "TStopwatch.h"
#include "Math/GSLMinimizer.h"
#include "Math/Functor.h"
#endif

//using namespace std;

// Here we will create the likelihood function, using the base RooAbsReal.
// Will create a class called RooSNLikelihood. Will accept a name, title,
// t and t0. The former two are const char* and the latter are RooAbsReal.
class RooSNLikelihood : public RooAbsReal {

  public:
    RooSNLikelihood(const char*, const char*, RooAbsReal&);

    RooSNLikelihood(const RooSNLikelihood& other, const char* name=0);

    virtual TObject* clone(const char* newname) const {return new RooSNLikelihood(*this, newname);}

    inline virtual ~RooSNLikelihood() { };

    void SetROOTPointers(TGraph*, std::vector<Double_t>);

  protected:
    // Documentation suggests always using proxies to store RooAbsArg.
    RooRealProxy t0;
    // This function returns the evaluation.
    Double_t evaluate() const;

  private:
    //ClassDef(RooSNLikelihood,1) // This is useless in principle.

    // Some ROOT stuff I would like to use.
    TTree* ROOTTTree;
    TFile* ROOTTFile;
    TGraph* mean;
    std::vector<Double_t> events;

}; // end of class description.

标签: c++classroot

解决方案


推荐阅读