Greetings! I have some questions concerning THStacks,
Say I want to create a THStrack for as many histograms as I want. And these come from root files that all have the same folder names and the same histogram names in this way:
for file 1:
find folder 1
find histo 1
add to stack
for file 2:
find folder 1 w/ same name
find histo 1 w/ same name
add to stack
etc.
And then write this stack to an output root file. Is this possible? How can I customize the way the histograms are stacked? Say I want them to have specific colors, I can do this from input, but the number would be limited.
EDIT: I’m trying to do it this way:
//Open the config file.
ifstream inFile;
inFile.open ("config.in", ios::in);
if (!inFile){
std::cerr << "Error: Can't open input file:" << std::endl;
exit(1);
}
//Get whatever is needed from the config file.
TEnv *config_file = new TEnv("config_file");
config_file->ReadFile("config.in", kEnvChange);
string input_filenames = config_file->GetValue("input_filenames", "file" );
string rebin_histoName = config_file->GetValue("histo_name" , "histogram");
double rebin_histoValue = config_file->GetValue("rebin_histo" , 0. );
double ScaleFactor = config_file->GetValue("ScaleFactor" , 0. );
std::cout <<"Opening: " << input_filenames << std::endl;
std::cout << rebin_histoName << " will be rebinned to " << rebin_histoValue << std::endl;
//Put the names in a List.
TList *FileList = new TList();
std::ifstream inFileNames;
string line;
inFileNames.open(input_filenames);
if (!inFile){
std::cerr << "The ROOT file names list could not be opened." << endl;
exit(1);
}
while(getline(inFileNames, line)){
TFile *add_file = TFile::Open(line.c_str());
if(!add_file){
std::cout << "Root file could not be opened." << std::endl;
}
FileList->Add(add_file);
}
FileList->Print();
//Create the output file
TIter fileIter(FileList);
TKey *file_key;
while((file_key = (TKey*) fileIter())){
TFile *output = TFile::Open(TString::Format("Normalized_%s", file_key->GetName()) , "RECREATE");
std::cout << "Opening output: " << output->GetName() << std::endl;
//Open the input root file
TFile *input_file = TFile::Open(file_key->GetName());
TDirectory *input_dir = gDirectory;
To make a THStack Structure and then write my histograms to it, but It doesn’t work.
That won’t work. I also don’t understand why you iterate over the files twice. Or why you open one output file per input file - how can you assemble your THStack then? And I don’t see where you are building the THStack - where are the input histograms? This might work better:
TH1::AddDirectory(false); // keep histograms independent from their directory
THStack *outStack = new THStack(...);
while(getline(inFileNames, line)){
TFile *add_file = TFile::Open(line.c_str());
if(!add_file){
std::cout << "Root file could not be opened." << std::endl;
continue;
}
file->cd("someDirectory");
while(TObject *file_key: gDirectory->GetKeys()) {
if (TH1* hist = dynamic_cast<TH1*>(((TKey*)file_key)->ReadObj())) {
// this is a TH1.
outStack->Add(hist);
}
}
} // loop over files
TFile *output = TFile::Open(TString::Format("Normalized_%s", file_key->GetName()) , "RECREATE");
outStack->Write();
Since ROOT 6.09/01 you can use the "PFC" drawing option to let the THStack select suitable colors automatically. See https://root.cern/doc/master/classTHistPainter.html#HP061 Otherwise the color defined for each histogram will be used.
Thank you for your answer! The reason I opened twice was so I could keep the folder structure (of the input files, that for convenience is the same, so the same histograms with the same cuts are stacked) in the output file, but I realize I can do this without opening the file twice. I’ll post here if I have more doubts.
/home/fernando/Desktop/Normalizer_Appli/Histo_Merger/Forum/histo_merger2.C:64:23: error: variable declaration in condition must have an initializer
while(TObject *file_key: gDirectory->GetKeys()){
I’m getting errors stacking in the output file. I get the error that the input file is not writable, so it tries to write the to the input file and not to the output file. Or I get a segmentation violation.
Is it better to just open each file individually and stack them by hand, basically? Or do I add them, say, to a list or a map and then stack them in the output file?