How can I make TGraphs persistent in a loop?

Dear ROOTers,

I have the following problem: I’m analyzing some data which involves some nested loops, and for each instance of the outermost loop (iDUT), I produce some plots, that I want to display while the program is running. The canvas pops up alright, but no plots are displayed until the end of the loop is reached; then the plots corresponding to the last loop element are displayed. I guess that’s a persistence problem, or related to the fact that I re-fill the TGraphs as soon as a new loop start, so I tried cloning the TGraphs or creating new TGraphs for each iDUT-loop element, but to no effect. Any idea how I could make those plots appear during the loop?

I attached (I hope all of) the relevant code below.

Thanks a lot,
Martin

  int Ch = 2; // plot channel 1 or 2
  int DUT;
  bool System;
  int Slot;
  const int nChannels = 2;
  const int nPulses = 10;
  const int MAX_NUM_RUNS = 69;
  int nRuns;
  const int nPoints = nChannels*nPulses*MAX_NUM_RUNS;
  time_t timestamp[nChannels][nPulses][MAX_NUM_RUNS];
  double Amp[nChannels][nPulses][MAX_NUM_RUNS];
  double FT[nChannels][nPulses][MAX_NUM_RUNS];
  double FT_err[nChannels][nPulses][MAX_NUM_RUNS];
  double Fit[nChannels][nPulses][MAX_NUM_RUNS];
  double Fit_err[nChannels][nPulses][MAX_NUM_RUNS];

  tree->Branch("DUT",&DUT,"DUT/I");
  tree->Branch("System",&System,"System/O");
  tree->Branch("Slot",&Slot,"slot/I");
  tree->Branch("nChannels",&nChannels,"nChannels/I");
  tree->Branch("nPulses",&nPulses,"nPulses/I");
  tree->Branch("nRuns",&nRuns,"nRuns/I");
  tree->Branch("nPoints",&nPoints,"nPoints/I");
  tree->Branch("timestamp",timestamp,"timestamp[nPoints]/L");
  tree->Branch("Amp",Amp,"Amp[nPoints]/D");
  tree->Branch("FT",FT,"FT[nPoints]/D");
  tree->Branch("FT_err",FT_err,"FT_err[nPoints]/D");
  tree->Branch("Fit",Fit,"Fit[nPoints]/D");
  tree->Branch("Fit_err",Fit_err,"Fit_err[nPoints]/D");

  if (plotCurve) {
    TGraph *gr_amp[nPulses];
    TGraphErrors *gr_ft[nPulses];
    TGraphErrors *gr_fit[nPulses];
    for (int i=0; i<nPulses; i++) {
      gr_amp[i] = new TGraph();
      gr_ft[i] = new TGraphErrors();
      gr_fit[i] = new TGraphErrors();
    }
  }

  for (int iDUT=0; iDUT<nDUT; iDUT++) {
    DUT = firstDUT + iDUT;
    System = (bool)system[DUT-1];
    Slot = slot[DUT-1];
    TString dataFileName = dataDir + "DUT";
    dataFileName += DUT;
    dataFileName += "/";
    nRuns = (DUT<7) ? 69 : 68;
    for (int C=1; C<=nChannels; C++) {
      for (int P=1; P<=nPulses; P++) {
	for (int R=1; R<=nRuns; R++) {
	  time_t timest;
	  double amp, ampft, errft, ampfit, errfit;
	  getPulseHeight(dataFileName,DUT,C,P,R,plotPulse,timest,amp,ampft,errft,ampfit,errfit);
	  timestamp[C-1][P-1][R-1] = timest;
	  Amp[C-1][P-1][R-1] = amp;
	  FT[C-1][P-1][R-1] = ampft;
	  FT_err[C-1][P-1][R-1] = errft;
	  Fit[C-1][P-1][R-1] = ampfit;
	  Fit_err[C-1][P-1][R-1] = errfit;
	  if (plotCurve) {
	    if (Ch==C) {
	      gr_amp[P-1]->SetPoint(R-1,(double)R,amp);
	      gr_ft[P-1]->SetPoint(R-1,(double)R,ampft);
	      gr_ft[P-1]->SetPointError(R-1,0,errft);
	      gr_fit[P-1]->SetPoint(R-1,(double)R,ampfit);
	      gr_fit[P-1]->SetPointError(R-1,0,errfit);
	    }
	  }
	}
      }
    }
    tree->Fill();

    // plot pulse height curves
    if (plotCurve) {
      double maxamp = TMath::MaxElement(nPulses*MAX_NUM_RUNS,&Amp[Ch-1][0][0]);
      double maxft = TMath::MaxElement(nPulses*MAX_NUM_RUNS,&FT[Ch-1][0][0]);
      double maxfit = TMath::MaxElement(nPulses*MAX_NUM_RUNS,&Fit[Ch-1][0][0]);
      char titleamp[FILENAME_LENGTH];
      char titleft[FILENAME_LENGTH];
      char titlefit[FILENAME_LENGTH];
      char* sys = system[DUT-1] ? "SYS" : "PRE";
      sprintf(titleamp,"DUT %d (%s), channel %d: amplitude from file",DUT,sys,Ch);
      sprintf(titleft,"DUT %d (%s), channel %d: pulse height from FT (500 kHz line)",DUT,sys,Ch);
      sprintf(titlefit,"DUT %d (%s), channel %d: pulse height from fit",DUT,sys,Ch);
      TCanvas * c0 = (TCanvas *)gROOT->FindObject("c0");
      if (!c0) {
	c0 = canvas(cc_xx,3*cc_yy);
	c0->Divide(1,3);
      }
      c0->cd();
      for (int iP=1; iP<=nPulses; iP++) {
	if (iP==1) {
	  c0->cd(1);
	  gr_amp[iP-1]->Draw("apl");
	  gr_amp[iP-1]->SetMinimum(0);
	  gr_amp[iP-1]->SetMaximum(maxamp);
	  gr_amp[iP-1]->SetTitle(titleamp);
	  gr_amp[iP-1]->GetXaxis()->SetTitle("Run");
	  c0->cd(2);
	  gr_ft[iP-1]->Draw("apl");
	  gr_ft[iP-1]->SetMinimum(0);
	  gr_ft[iP-1]->SetMaximum(maxft);
	  gr_ft[iP-1]->SetTitle(titleft);
	  gr_ft[iP-1]->GetXaxis()->SetTitle("Run");
	  c0->cd(3);
	  gr_fit[iP-1]->Draw("apl");
	  gr_fit[iP-1]->SetMinimum(0);
	  gr_fit[iP-1]->SetMaximum(maxfit);
	  gr_fit[iP-1]->SetTitle(titlefit);
	  gr_fit[iP-1]->GetXaxis()->SetTitle("Run");
	}
	else {
	  c0->cd(1);
	  gr_amp[iP-1]->Draw("pl");
	  c0->cd(2);
	  gr_ft[iP-1]->Draw("pl");
	  c0->cd(3);
	  gr_fit[iP-1]->Draw("pl");
	}
	gr_amp[iP-1]->SetLineColor(iP);
	gr_ft[iP-1]->SetLineColor(iP);
	gr_fit[iP-1]->SetLineColor(iP);
      }
      gr_amp[9]->SetLineColor(12); // 10 is white
      gr_ft[9]->SetLineColor(12); // 10 is white
      gr_fit[9]->SetLineColor(12); // 10 is white
    }

  }

  tree->Write();
  outFile->Close();

Hi,

To increase the rate at which the screen is refresh (but this will slow down your processing, so you may or may not want to do this every loop), add something like: if (i && (i%kUPDATE) == 0) { if (i == kUPDATE) hpx->Draw(); c0->Modified(); c0->Update(); if (gSystem->ProcessEvents()) break; }
Cheers,
Philippe.

Thanks, that helped!