Hi Couet,
I have not measured the time down to sub-second resolution, but when I disable the c1->SaveAs(saveName) line the loop never executes in longer than a second. The total time the loop takes to execute with 2,000,000 iterations (with data histogram sizes increased) is 49 seconds. In comparison it takes 25 seconds to do 1,000,000 iterations, and 12 seconds to do 500,000.
This is with the line
gStyle->SetCanvasPreferGL(kTRUE);
which was an optimization to speed up the drawing process I had read about. Without it, I noticed the same slowdown in the draw part of the loop as with the save part. This is from running my compiled code, and in this case I do not see the canvas or plots on my screen.
I just tried loading this code into a ROOT session and executing it, and noticed that I do see the canvas, and the loop time increases with the iteration even with canvas saving disabled and that optimization line included. I am now suspecting that maybe the plots weren’t getting drawn in my compiled code with that optimization line, so maybe the slowdown is unavoidable.
I have a couple ideas to re-write to code to try to make it more memory friendly and faster, so if the slowdown is unavoidable the way I have written it I will move on to another approach. I ultimately wanted to turn a few thousand of these images into a gif, and this may be impossible the way I have written it.
If you have any other suggestions please let me know. If not, thank you for your help.
[code]//C++ include files
#include
#include
#include
#include
#include <time.h>
#include <TStyle.h>
#include “stdio.h”
//Root include files
#include “TFile.h”
#include “TH1D.h”
#include “TH2D.h”
#include “TSystem.h”
#include “TCanvas.h”
#include “TPad.h”
#include “TLegend.h”
#include “TArray.h”
#include “TROOT.h”
using namespace std;
int main(int argc, char** argv) {
time_t startTime, endTime, lapTime, firstTime;
//Code reads histograms from root file, plots values in real time as they change, saves canvas they are plotted to as a gif
//Creating fake data to show the issue
TH1D* detectorDataHistArray[24];
TString histNames[24];
for (UInt_t detector=0; detector < 24; detector++) {
histNames[detector]=“test”;
histNames[detector].Append(to_string(detector));
detectorDataHistArray[detector] = new TH1D(histNames[detector],histNames[detector],2000000,0,2000000);
detectorDataHistArray[detector]->FillRandom(“gaus”,2000000);
}
//Speeds up draw speed
gStyle->SetCanvasPreferGL(kTRUE);
//Set up canvas that will be saved as images
TCanvas* c1 = new TCanvas(“c1”,"",200,10,1900,900);
//Create pads
TPad *pad1 = new TPad(“pad1”,“2D Array”,0.0,0.0,0.4,1.0);
TPad *pad2 = new TPad(“pad2”,“Ch0-5”,0.4,0.76,1.0,1.0);
TPad *pad3 = new TPad(“pad2”,“Ch6-11”,0.4,0.52,1.0,0.76);
TPad *pad4 = new TPad(“pad2”,“Ch12-17”,0.4,0.28,1.0,0.52);
TPad *pad5 = new TPad(“pad2”,“Ch18-23”,0.4,0.04,1.0,0.28);
pad1->Draw();
pad2->Draw();
pad3->Draw();
pad4->Draw();
pad5->Draw();
//Set Pad Margins
pad1->SetRightMargin(0.15);
pad1->SetLeftMargin(0.05);
pad2->SetRightMargin(0.0);
pad3->SetRightMargin(0.0);
pad4->SetRightMargin(0.0);
pad5->SetRightMargin(0.0);
pad2->SetLeftMargin(0.07);
pad3->SetLeftMargin(0.07);
pad4->SetLeftMargin(0.07);
pad5->SetLeftMargin(0.07);
//Create grid for 2D array
pad1->cd();
c1->SetGridx();
c1->SetGridy();
//Set color palette of z-axis
gStyle->SetPalette(51);
//Create 1D histograms
TH1D* detectorReadHistArray[24]; //Stores histograms that are read from root files
TH1D* detectorWriteHistArray[24]; //Histograms that will be displayed on the plot
//Will store bin limits from read-in histograms
Double_t minBin;
Double_t maxBin;
Double_t nBins;
for (UInt_t detector=0; detector < 24; detector++) {
//The commented lines read detector this the name histNames[detector] from the root file, store in detectorReadHistArray[detector]
//histNames[detector] = “histName_ch”;
//histNames[detector].Append(to_string(detector));
//detectorReadHistArray[detector] = (TH1D*)rootFile->Get(histNames[detector]);
detectorReadHistArray[detector] = detectorDataHistArray[detector];
//Get bin limits
minBin = detectorReadHistArray[detector]->GetXaxis()->GetXmin();
maxBin = detectorReadHistArray[detector]->GetXaxis()->GetXmax();
nBins = detectorReadHistArray[detector]->GetSize();
//Create histograms
histNames[detector] = "chan: ";
histNames[detector].Append(to_string(detector));
detectorWriteHistArray[detector] = new TH1D(histNames[detector],"",nBins,minBin,maxBin);
detectorWriteHistArray[detector]->SetMarkerColor(detector%6+1);
detectorWriteHistArray[detector]->SetLineColor(detector%6+1);
}
//Tried to speed up code by loading detectorReadHistArray values into an array and reading from that rather than using GetBinContent
Double_t *arrayOfHistogramValues[24];
for (UInt_t detector=0; detector < 24; detector++) {
arrayOfHistogramValues[detector]=detectorReadHistArray[detector]->GetArray();
}
//Create a 2D histogram
TH2D* TwoDimHist = new TH2D(“TwoDimHist”,“Example 2D histogram”,6,0,6,4,0,4);
//These specify the locations of the detectors on the 2D plot
UInt_t detectorXLocations[24] = { 5, 6, 3, 4, 5, 4, 1, 1, 5, 3, 5, 1, 3, 2, 1, 4, 6, 4, 3, 6, 2, 2, 2, 6 };
UInt_t detectorYLocations[24] = { 2, 3, 1, 4, 4, 3, 4, 2, 3, 2, 1, 3, 4, 3, 1, 2, 1, 1, 3, 2, 4, 2, 1, 4 };
//Variables needed for loop code
UInt_t numberOfBinsToPlot=500000; //number of bins to plot total
Double_t valueToPlot;
Int_t globalBinNumber;
UInt_t numberOfBinsToDisplay=3; //number of bins to display at once
UInt_t minTimeBin; //Lower limit of displayed bins
TString saveName;
time(&startTime);
time(&firstTime);
for (ULong64_t timeBin=1; timeBin < detectorReadHistArray[0]->GetSize()-1; timeBin++) {
//Get the global bin number corresponding to the first bin on the 0th detector 1D histogram
globalBinNumber=detectorReadHistArray[0]->GetBin(timeBin);
//Fill histograms
for (UInt_t detector=0; detector < 24; detector++) {
valueToPlot=arrayOfHistogramValues[detector][timeBin-1];
TwoDimHist->SetBinContent(detectorXLocations[detector],detectorYLocations[detector],valueToPlot);
detectorWriteHistArray[detector]->SetBinContent(timeBin,valueToPlot);
}
//Plot 2D histogram
pad1->cd();
TwoDimHist->Draw("colz");
c1->Modified();
c1->Update();
//Updated code to only display numberOfBinsToDisplay bins of data
minTimeBin = timeBin > numberOfBinsToDisplay ? timeBin-numberOfBinsToDisplay : 0;
//Set the display range
detectorWriteHistArray[0]->GetXaxis()->SetRange(minTimeBin,timeBin);
detectorWriteHistArray[6]->GetXaxis()->SetRange(minTimeBin,timeBin);
detectorWriteHistArray[12]->GetXaxis()->SetRange(minTimeBin,timeBin);
detectorWriteHistArray[18]->GetXaxis()->SetRange(minTimeBin,timeBin);
//Plot 1D histograms
pad2->cd();
if (timeBin==1) {
detectorWriteHistArray[0]->Draw("L");
}
else {
detectorWriteHistArray[0]->Draw("Lsame");
}
detectorWriteHistArray[1]->Draw("Lsame");
detectorWriteHistArray[2]->Draw("Lsame");
detectorWriteHistArray[3]->Draw("Lsame");
detectorWriteHistArray[4]->Draw("Lsame");
detectorWriteHistArray[5]->Draw("Lsame");
pad3->cd();
if (timeBin==1) {
detectorWriteHistArray[6]->Draw("L");
}
else {
detectorWriteHistArray[6]->Draw("Lsame");
}
detectorWriteHistArray[7]->Draw("Lsame");
detectorWriteHistArray[8]->Draw("Lsame");
detectorWriteHistArray[9]->Draw("Lsame");
detectorWriteHistArray[10]->Draw("Lsame");
detectorWriteHistArray[11]->Draw("Lsame");
pad4->cd();
if (timeBin==1) {
detectorWriteHistArray[12]->Draw("L");
}
else {
detectorWriteHistArray[12]->Draw("Lsame");
}
detectorWriteHistArray[13]->Draw("Lsame");
detectorWriteHistArray[14]->Draw("Lsame");
detectorWriteHistArray[15]->Draw("Lsame");
detectorWriteHistArray[16]->Draw("Lsame");
detectorWriteHistArray[17]->Draw("Lsame");
pad5->cd();
if (timeBin==1) {
detectorWriteHistArray[18]->Draw("L");
}
else {
detectorWriteHistArray[18]->Draw("Lsame");
}
detectorWriteHistArray[19]->Draw("Lsame");
detectorWriteHistArray[20]->Draw("Lsame");
detectorWriteHistArray[21]->Draw("Lsame");
detectorWriteHistArray[22]->Draw("Lsame");
detectorWriteHistArray[23]->Draw("Lsame");
c1->Modified();
c1->Update();
saveName="image";
saveName.Append(to_string(timeBin));
saveName.Append(".gif");
//Timing
time(&lapTime);
cout<<"Time for rest of loop: "<<difftime(lapTime,startTime)<<endl;
time(&startTime);
// c1->SaveAs(saveName);
//Timing
time(&lapTime);
cout<<"Time to print: "<<difftime(lapTime,startTime)<<endl;
time(&startTime);
if (timeBin >= numberOfBinsToPlot) {
//Timing
time(&endTime);
cout<<"Time for loop: "<<difftime(endTime,firstTime)<<endl;
exit(0);
}
if ( timeBin%1 == 0) {
cout<<"On bin "<<timeBin<<" of "<<detectorReadHistArray[0]->GetSize()-1<<endl;
}
}
}
[/code]