Я не уверен, как правильно сформулировать этот вопрос, но это то, что я пытаюсь сделать.
Отдельную гистограмму можно построить с помощью cern 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");
}
Что я делаю неправильно?
Заранее спасибо.
Вам нужен еще один шаг. Как говорит @twalberg, у вас есть строка, а не указатель на объект. Для root вы можете просто изменить код так, чтобы я добавил еще одну строку.
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 был приведен к нужному объекту.
Когда вы используете root в интерактивном режиме, это происходит волшебным образом за кулисами.
Создание строки, которая говорит «Electron0», приведение char *
указывая на начало строки в TH1F *
и разыменование его, как если бы строка символов была на самом деле struct TH1F *
(или же class TH1F *
) скорее всего просто приведет к аварийному завершению программы, и это не то же самое, что обращение к переменной с именем electron0
,
Вероятно, вам лучше всего вместо того, чтобы называть кучу переменных electron0
, electron1
и т.д …, создать массив как в TH1F electron[NELECTRONS];
, а затем ссылаться на них как electron[0]
, electron[1]
и т. д. (В качестве альтернативы, если объекты расположены динамически, используйте TH1F *electron[NELECTRONS];
и хранить указатели (с соответствующими ссылками на них (*(electron[0]).Draw(...)
или же electron[0]->Draw(...)
).