簡體   English   中英

將對象作為參數傳遞給C ++中的函數時,可以從ROOT對象訪問方法嗎?

[英]Can you access methods from a ROOT object when you pass the object as an argument to a function in C++?

請原諒我的無知,但是我是C ++和ROOT的新手,我不確定自己在做什么錯。

我想要做的是編寫一個函數,該函數返回直方圖中n峰的bin位置。 以下是我的代碼:

#include <iostream>
#include <algorithm>
#include <iterator>

#include "TROOT.h"
#include "TCanvas.h"
#include "TH1.h"
#include "TF1.h"

using namespace std;

int *peak_counter1d(TH1F *histogram,int peak_num,int threshold = 5,int display = 0){
  if(display == 1){
    TCanvas *look = new TCanvas("look","look",500,400);
    histogram->Draw();
  }
  int total_bins = histogram->GetNBinsX();
  double peak_bins[peak_num];
  peak_bins[0] = histogram->GetMaximumBin();
  int counter = 1;
  int *check_array; // to put previously found peak bins
  while(counter < peak_num){
    double peak = threshold;
    double peak_loc = -500;
    check_array = new int[counter];
    for(int i=0; i<counter; i++){
      check_array[i] = peak_bins[i]; // fills the array with previously found peak bins
    }
    for(int i=0; i<total_bins; i++){
      if(peak < histogram->GetBinContent(i)){ 
        bool exists = find(begin(check_array),end(checkarray),i); // makes sure this is a peak we haven't already found
        if(!exists){
          peak = histogram->GetBinContent(i);
          peak_loc = i;
        }
      }
    }
    peak_bins[counter] = peak_loc;
    counter ++;
  }
  delete[] check_array;

  return peak_bins;
}

void testing(){
  gROOT->Reset();
  TH1F *histo = new TH1F("histo","try",100,0,10);
  TF1 *f1 = new TF1("f1","exp(-x/10)*sin(x)*sin(x)",0,10);
  double val;
  for(int i=0; i<100; i++){
    val = f1->Eval(i/10.0);
    //cout << i << "\t" << i/100.0 << "\t" << val << endl;
    histo->SetBinContent(i,val);
  }

  int *peak_bins;
  peak_bins = peak_counter1d(histo,3,5,1);
  for(int i=0; i<3; i++){
    cout << i << "\t" << *(peak_bins+i) << endl;
  }
}

當我在ROOT中執行此代碼時,得到以下信息:

root [] .x testing.cpp
Error: Can't call TH1F::GetNBinsX() in current scope testing.cpp:15:
Possible candidates are...
(in TH1F)
(in TH1)
*** Interpreter error recovered ***

我認為這是訪問函數內部的對象方法的問題,因為當我在testing()函數中調用histo-> GetNBinsX()方法時,我沒有遇到任何問題。 但是我不知道。

謝謝,如果我要執行其他災難性的可怕編碼操作,請告訴我。

已經指出,不能返回局部變量的地址,該局部變量在函數結束時將被銷毀。

您的另一個問題是關於:

histo->GetNbinsX()

不工作。 我試圖在腳本的主程序和子程序中都調用它:對於當前的ROOT版本,它對我來說非常合適。 在該問題中,您拼寫錯誤為GetNBinsX (是的,這與駱駝案政策更加一致)。 也許...?

無論如何,我相信您一定會很高興地知道ROOT可以使用一種非常智能的一維峰搜索算法:尋找TSpectrum類

您的代碼存在各種問題。

最明顯的是:

int *peak_counter1d(TH1F *histogram,int peak_num,int threshold = 5,int display = 0)
{
    //...
    double peak_bins[peak_num];
    //...
    return peak_bins;
}

您正在返回一個指向局部變量的指針。 返回指向局部變量的指針是未定義的行為

下一個問題是這樣的:

  int *check_array; // to put previously found peak bins
  while(counter < peak_num)
  {
      //...
      check_array = new int[counter];
  }
  delete[] check_array;

由於循環而未取消分配check_array因此存在潛在的內存泄漏。 另一個問題是,如果該循環永遠不會執行,則您要對未初始化的變量調用delete []

下一個問題是這樣的:

int * peak_counter1d(...)
{
    double peak_bins[peak_num];
    //...
    return peak_bins;
}

即使您可以安全地返回指向局部變量的指針,函數也會返回int *,但是您將返回double *

下一個問題是這樣的:

TCanvas *look = new TCanvas("look","look",500,400);

您正在分配look ,但是永遠不會取消分配它,甚至不會使用它。

您還可以在main執行相同的操作:

 TH1F *histo = new TH1F("histo","try",100,0,10);
  TF1 *f1 = new TF1("f1","exp(-x/10)*sin(x)*sin(x)",0,10);

C ++不是Java。 您不必使用new創建對象。

TH1F histo("histo","try",100,0,10);
  TF1 f1("f1","exp(-x/10)*sin(x)*sin(x)",0,10);

除最后一個問題外,如果您訴諸使用std::vector而不使用new[]創建動態數組,則可以解決所有這些問題。

應用這些更改,代碼應如下所示(未編譯):

#include <iostream>
#include <algorithm>
#include <iterator>
#include <vector>

#include "TROOT.h"
#include "TCanvas.h"
#include "TH1.h"
#include "TF1.h"

using namespace std;

vector<int> peak_counter1d(TH1F *histogram,int peak_num,int threshold = 5,int display = 0)
{
  if(display == 1)
  {
    // TCanvas *look = new TCanvas("look","look",500,400);
     histogram->Draw();
  }
  int total_bins = histogram->GetNBinsX();
  vector<int> peak_bins(peak_num);
  peak_bins[0] = histogram->GetMaximumBin();
  int counter = 1;
  vector<int> check_array; // to put previously found peak bins
  while(counter < peak_num){
    double peak = threshold;
    double peak_loc = -500;
    check_array.resize(counter);
    for(int i=0; i<counter; i++){
      check_array[i] = peak_bins[i]; // fills the array with previously found peak bins
    }
    for(int i=0; i<total_bins; i++){
      if(peak < histogram->GetBinContent(i)){ 
        bool exists = find(begin(check_array),end(checkarray),i); // makes sure this is a peak we haven't already found
        if(!exists){
          peak = histogram->GetBinContent(i);
          peak_loc = i;
        }
      }
    }
    peak_bins[counter] = peak_loc;
    counter ++;
  }
  return peak_bins;
}

void testing(){
  gROOT->Reset();
  TH1F histo("histo","try",100,0,10);
  TF1 f1("f1","exp(-x/10)*sin(x)*sin(x)",0,10);
  double val;
  for(int i=0; i<100; i++){
    val = f1.Eval(i/10.0);
    //cout << i << "\t" << i/100.0 << "\t" << val << endl;
    histo.SetBinContent(i,val);
  }

  vector<int> peak_bins = peak_counter1d(&histo,3,5,1);
  for(int i=0; i<3; i++){
    cout << i << "\t" << peak_bins[i] << endl;
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM