2012-10-04 2 views
1

이 문구를 올바르게 표현하는 방법을 모르겠지만이 작업을 수행하려고합니다. 하나의 막대 그래프는 다음 명령을 CERN ROOT를 사용하여 그릴 수 있습니다가변 변수 이름을 사용하여 ROOT에 히스토그램을 그릴 경우

,

(TH1F*)electron->Draw(); 

그러나 나는 등등 electron1, elecron2, electron3과 같은 순서로 명명 된 히스토그램의 수십, 내가 원하는 한 간단한 루프를 작성하여 모두 그려보십시오. 나는 sprintf와 간단한 for 루프를 사용해 보았지만 ROOT는 그것을 좋아하지 않는다.

char name[20]; 
(TH1F*)electron->Draw(); 
for(int j=0;j<5;j++){ 
      sprintf(name, "%s%d","electron",j); 
      (TH1F*)name->Draw("same"); 
} 

내가 뭘 잘못하고 있니?

미리 감사드립니다.

답변

3

당신은 하나의 추가 단계가 필요합니다. @twalberg가 말했듯이, 당신이 문자열이 아닌 객체 포인터를 가지고있다. 들어 당신이 할 수있는 루트는 하나의 추가 라인을 추가하도록 코드를 변경하는 것입니다.

char name[20]; 
electron->Draw(); 
for(int j=0;j<5;j++){ 
    sprintf(name, "%s%d","electron",j); 
    TH1F *h = (TH1F*)gDirectory->Get(name); // THIS IS THE MISSING LINE 
    if (h) h->Draw("same"); // make sure the Get succeeded 
} 

추가 행은 로컬 TDirectory의 이름으로 참조 된 객체를 가져옵니다. gDirectory가 올바른 종류의 객체에 캐스트되도록 캐스트가 필요합니다.

루트를 대화식으로 사용하면이 장면이 마술처럼 뒤에서 일어납니다.

+0

정답입니다. ROOT의 스타일을 완벽하게 따르는 동안,'std :: string'과'boost :: lexical_cast'를 사용하면 훨씬 더 이상적인 C++이지만, 작동하지 않으므로 대부분의 ROOT 사용자에게 혼란을 줄 수도 있습니다 CINT 매크로에서도 잘 작동합니다. –

+0

감사합니다. 당신이 아마 뿌리가 C++의 많은 것을 생각하지 않는다는 것을 알고있을 겁니다. –

+0

곧 모든 것들은 clint가 cint를 대체하는 root-6의 릴리스와 함께 바뀔 것입니다. 누구나 현대적인 C++에 대한 높은 기능 수준의 프로그램을 제공 할 것입니다. 한때 알고리즘을 데이터 컨테이너에 매핑하는 몇 가지 라인에서 다양한 히스토그램을 작성하고 채우기 위해 20k 라인에 대해 스파게티 된 루트 매크로가 수행됩니다. 예, 우리가 ROOT 분석 매크로에 적절한 C++을 작성할 수있게되면 우리가 할 수있는 일을 할 수있게 될 것입니다. –

2

"electron0"는 TH1F *에 문자열의 시작 부분에 char * 가리키는 캐스팅,라는 문자열을 생성하고, 문자열이 실제로 있다면으로 역 참조 struct TH1F * (또는 class TH1F *)이 가장 가능성이 단지 충돌하려고하는 이 프로그램은 electron0이라는 변수를 참조하는 것과 같지 않습니다.

아마 가장 좋은 건 오히려 변수 electron0, electron1 등의 무리를 명명보다,하는 것입니다 ..., TH1F electron[NELECTRONS];에서와 같은 배열을 만든 다음, electron[0], electron[1] 등 (또는 그들을 참조하는 객체의 경우 동적으로 할당하는 TH1F *electron[NELECTRONS];를 사용하고 (*(electron[0]).Draw(...) 또는 electron[0]->Draw(...))를 참조하기 위해 적절한 indirections로 (포인터를 저장합니다.