// Author: Gero Flucke <mailto:flucke@mail.desy.de>
//____________________________________
// GFHistManager
//   Author:      Gero Flucke
//   Date:        Feb. 10th, 2002
//   last update: $Date: 2005/12/15 11:20:59 $  
//   by:          $Author: flucke $
//

#include <iostream>
using namespace std;
// #include <vector>
// RooT header:
#include <TROOT.h>
#include <TError.h>
#include <TH1.h>
#include <TH2.h>
#include <TF1.h>
#include <TCanvas.h>
#include <TFile.h>
#include <TString.h>
#include <TObjArray.h>
#include <TList.h>
#include <TLegend.h>
#include <TLegendEntry.h>
#if ROOT_VERSION_CODE < ROOT_VERSION(5,6,0)
#include <TStyle.h>
#endif

// my header:
#include "GFHistManager.h"
#include "GFUtils/GFHistArray.h"

ClassImp(GFHistManager)

const Int_t GFHistManager::kDefaultPadsPerCanX = 4;
const Int_t GFHistManager::kDefaultPadsPerCanY = 3;
const Int_t GFHistManager::kDefaultDepth = 0;
TString GFHistManager::fgLegendEntryOption = "l";


 GFHistManager::GFHistManager()
{
  this->Initialise();
  fBatch = kFALSE;
  fDrawDiffStyle = kTRUE;
  fLegendY1 = 0.75;
  fLegendX1 = 0.7;
  fLegendY2 = 0.99;
  fLegendX2 = 0.99;
  fCanvasWidth = 600;
  fCanvasHeight = 600;
}

 GFHistManager::GFHistManager(TH1* hist)
{
  // constructing with hist as first histogram 
  this->Initialise();
  
  this->AddHist(hist);
  fBatch = kFALSE;
  fDrawDiffStyle = kTRUE;
  fLegendY1 = 0.75;
  fLegendX1 = 0.7;
  fLegendY2 = 0.99;
  fLegendX2 = 0.99;
  fCanvasWidth = 600;
  fCanvasHeight = 600;
}

 GFHistManager::GFHistManager(TCollection* hists)
{
  // constructing with histos in 'hists' as first histogram 
  this->Initialise();

  this->AddHists(hists);
  fBatch = kFALSE;
  fDrawDiffStyle = kTRUE;
  fLegendY1 = 0.75;
  fLegendX1 = 0.7;
  fLegendY2 = 0.99;
  fLegendX2 = 0.99;
  fCanvasWidth = 600;
  fCanvasHeight = 600;
}

//________________________________________________________
 void GFHistManager::Initialise()
{
  fDepth = kDefaultDepth;
  fNoX.Set(fDepth);
  fNoY.Set(fDepth);
#if ROOT_VERSION_CODE >= ROOT_VERSION(3,10,2) && ROOT_VERSION_CODE <= ROOT_VERSION(4,0,3)
  // TArrayI::Reset(Int_t) buggy in 3.10_02:
  for(Int_t i = 0; i < fNoX.GetSize(); ++i) fNoX[i] = kDefaultPadsPerCanX;
  for(Int_t i = 0; i < fNoY.GetSize(); ++i) fNoY[i] = kDefaultPadsPerCanY;
#else
  fNoX.Reset(kDefaultPadsPerCanX);
  fNoY.Reset(kDefaultPadsPerCanY);
#endif  
  fLogY.Set(fDepth);
  fLogY.Reset(); // set to 0

//   fCanvasWidth = 700;
//   fCanvasHeight = 500;
//   fCanvasWidth = 600;
//   fCanvasHeight = 600;

  fHistArrays = new TObjArray;
  for(Int_t i = 0; i < fDepth; ++i){
    fHistArrays->Add(new TObjArray);
  }
  fCanArrays = new TObjArray;
  fLegendArrays = NULL;
  fObjLists = NULL;
}

//________________________________________________________
 GFHistManager::~GFHistManager()
{
  // destructor: delete stored arrays, legends and canvases, but not the hists and objects!
  if(fHistArrays) {
    TIter iter(fHistArrays);
    while(TObjArray* array = static_cast<TObjArray*>(iter.Next())){
      array->Delete();
    }
    fHistArrays->Delete();
    delete fHistArrays;
  }
  if(fLegendArrays) {
    TIter legIter(fLegendArrays);
    while(TObjArray* array = static_cast<TObjArray*>(legIter.Next())){
      array->Delete();
    }
    fLegendArrays->Delete();
    delete fLegendArrays;
  }

  if(fObjLists) { 
    TIter listArrayIter(fObjLists);
    while(TObjArray* listArray = static_cast<TObjArray*>(listArrayIter.Next())){
      listArray->Delete();; // delete lists, but not its objects
    }
    fObjLists->Delete(); // delete arrays of lists
    delete fObjLists;// delete array of arrays of lists
  }

  if(fCanArrays) {
    TIter canIter(fCanArrays);
    while(TObjArray* array = static_cast<TObjArray*>(canIter.Next())){
      array->Delete();
    }
    fCanArrays->Delete();
    delete fCanArrays;
  }
}

//________________________________________________________
 void GFHistManager::Clear(Bool_t deleteHists)
{
  // delete all canvases and clear the lists of hists stored in the manager 
  // (hists and objects are deleted if deleteHists is true [by default it is false])

  TIter iterCanArrays(fCanArrays);
  while(TObjArray* arr = static_cast<TObjArray*>(iterCanArrays.Next())){
    arr->Delete(); // delete canvases
  }
  fCanArrays->Delete(); // delete arrays of canvases
  delete fCanArrays;

  if(fLegendArrays){ // by default there are no legends...
    TIter iterLegArrays(fLegendArrays);
    while(TObjArray* arr = static_cast<TObjArray*>(iterLegArrays.Next())){
      arr->Delete(); // delete legends
    }
    fLegendArrays->Delete(); // delete arrays of legends
    delete fLegendArrays;
  }

  if(fObjLists) { 
    TIter listArrayIter(fObjLists);
    while(TObjArray* listArray = static_cast<TObjArray*>(listArrayIter.Next())){
      if(deleteHists) {
	TIter listIter(listArray);
	while(TList* list = static_cast<TList*>(listIter.Next())){
	  list->Delete(); // delete objects if requested
	}
      }
      listArray->Delete(); // delete lists
    }
    fObjLists->Delete(); // delete arrays of lists
    delete fObjLists; // delete array of arrays of lists
  }

  TIter iterHistArrays(fHistArrays);
  while(TObjArray* arr = static_cast<TObjArray*>(iterHistArrays.Next())){
    TIter iterHistArrays2(arr);
    while(TObjArray* arr2 = static_cast<TObjArray*>(iterHistArrays2.Next())){
      if(deleteHists) arr2->Delete(); // delete histograms
      else            arr2->Clear();
    }
    arr->Delete();
  }
  fHistArrays->Delete(); // delete arrays of arrays of histograms
  delete fHistArrays;

  this->Initialise(); // here the arrays are rebuild and fDepth etc. adjusted
}

//________________________________________________________
 void GFHistManager::Draw()
{
  // draw all layers of histograms (ignore if in batch mode)
  if(fBatch) return; // for speed up...
  for(Int_t i = 0; i < fDepth; ++i){
    this->Draw(i);
  }
}

//________________________________________________________
 void GFHistManager::Draw(Int_t layer)
{
  if(fBatch) return;
  this->DrawReally(layer);
}


//________________________________________________________
 void GFHistManager::DrawReally(Int_t layer)
{
  if(layer < 0 || layer > fDepth-1) {
    this->Warning("DrawReally","Layer %d does not exist, possible are 0 to %d.", 
		  layer, fDepth-1);
    return;
  }

  this->MakeCanvases(layer);

  TIter canIter(static_cast<TObjArray*>(fCanArrays->At(layer)));
  TIter histIter(static_cast<TObjArray*>(fHistArrays->At(layer)));

  Int_t histNo = 0; // becomes number of histograms in layer
  while(TCanvas* can = static_cast<TCanvas*>(canIter.Next())){
    Int_t nPads = this->NumberOfSubPadsOf(can);
    for(Int_t i = 0; i <= nPads; ++i){
      if (i == 0 && nPads != 0) i = 1;
      can->cd(i);
      if(GFHistArray* histsOfPad = static_cast<GFHistArray*>(histIter.Next())){
	TIter hists(histsOfPad);
	TH1* firstHist = static_cast<TH1*>(hists.Next());
	firstHist->Draw();
	this->DrawFuncs(firstHist);
	while(TH1* h = static_cast<TH1*>(hists.Next())){
	  h->Draw(Form("SAME%s", h->GetOption()));
	  this->DrawFuncs(h);
	}
	if(histsOfPad->GetEntriesFast() > 1){
	  const Double_t max = this->MaxOfHists(histsOfPad);
	  if(//firstHist->GetMaximumStored() != -1111. &&  ????
	     max > firstHist->GetMaximumStored()){
	    firstHist->SetMaximum((fLogY[layer] ? 1.1 : 1.05) * max);
	  }
	  const Double_t min = this->MinOfHists(histsOfPad);
	  if(min < 0.) firstHist->SetMinimum(min * 1.05);
	}
	if(fLogY[layer] 
	   && (firstHist->GetMinimum() > 0. 
	      || (firstHist->GetMinimum() == 0. 
		  && firstHist->GetMinimumStored() == -1111.)))gPad->SetLogy();
	// draw other objects:
	this->DrawObjects(layer, histNo);
	// draw legends on top of all
	if(fLegendArrays && layer <= fLegendArrays->GetLast() && fLegendArrays->At(layer)){
	  if(fDrawDiffStyle) GFHistManager::MakeDifferentStyle(histsOfPad);
	  this->DrawLegend(layer, histNo);
	}
	gPad->Modified();
	histNo++;
      }
    } // loop over pads
  } // loop over canvases
}

//________________________________________________________
 void GFHistManager::DrawLegend(Int_t layer, Int_t histNo)
{
  // histNo starting at '0'
  // We must already be in the correct pad, layer and histNo must exist

  if(fLegendArrays && layer <= fLegendArrays->GetLast() && fLegendArrays->At(layer)){
    TObjArray* legends = static_cast<TObjArray*>(fLegendArrays->At(layer));
    TObject* legend = (histNo <= legends->GetLast() ? legends->At(histNo) : NULL);
    if(legend) legend->Draw();
  }
}

//________________________________________________________
 void GFHistManager::DrawObjects(Int_t layer, Int_t histNo)
{
  // histNo starting at '0'
  // We must already be in the correct pad, layer and histNo must exist
  if(fObjLists && layer <= fObjLists->GetLast() && fObjLists->At(layer)){
    TObjArray* layerLists = static_cast<TObjArray*>(fObjLists->At(layer));
    if(histNo <= layerLists->GetLast() && layerLists->At(histNo)){
      TObjLink *lnk = static_cast<TList*>(layerLists->At(histNo))->FirstLink();
      while (lnk) {
	lnk->GetObject()->Draw(lnk->GetOption());
	lnk = lnk->Next();
      }
    }
  }
}

//________________________________________________________
 void GFHistManager::Print(const char* filename, Bool_t add)
{
  // print all layers of histograms to ps-file 'filename'
  // if 'add == true' puts '(' or ')' only if 'filename' ends with it, 
  // e.g. if i is loop variable 
  //   GFHistManager *man = ...;
  //   TString name("XXX.ps");
  //   if(i == 0) man->Print(name + '(');
  //   else if(i == last) man->Print(name + ')');
  //   else man->Print(name, kTRUE);


  const Bool_t rootIsBatch = gROOT->IsBatch();
  if(fBatch){
    gROOT->SetBatch();
    for(Int_t i = 0; i < fDepth; ++i){
      this->DrawReally(i);
    }
  }
  gROOT->SetBatch(rootIsBatch);

  TObjArray cans;
  TIter canArrayIter(fCanArrays);
  while(TObjArray* canArray = static_cast<TObjArray*>(canArrayIter.Next())){
    cans.AddAll(canArray);
  }

  const Int_t nCans = cans.GetEntriesFast();
  if(nCans == 1) {
    cans.At(0)->Print(filename);
    return;
  }

  TString plainName(filename);
  const Bool_t starting = plainName.EndsWith("(");
  if(starting) {
    const Ssiz_t ind = plainName.Last('(');
    plainName.Remove(ind);
    //    plainName.ReplaceAll("(", "");
  }
  const Bool_t ending = plainName.EndsWith(")");
  if(ending) {
    const Ssiz_t ind = plainName.Last(')');
    plainName.Remove(ind);
//     plainName.ReplaceAll(")", "");
  }

  for(Int_t i = 0; i < nCans; ++i){
    if(i == 0 && !ending && (!add || starting)) {
      cans.At(i)->Print(plainName + "(");
    } else if(i == nCans - 1 && !starting && (!add || ending)) {
      cans.At(i)->Print(plainName + ")");
    } else {
      cans.At(i)->Print(plainName);
    }
  }
}

// //________________________________________________________
// void GFHistManager::Print(const char* filename, Int_t layer)
// {
//   // print all canvases of layer into .ps-files with name of their first histogram
//   Bool_t rootIsBatch = gROOT->IsBatch();
//   gROOT->SetBatch();
//   this->DrawReally(layer);

//   TIter canIter(static_cast<TObjArray*>(fCanArrays->At(layer)));
//   Int_t nCan = 0;
//   while(TCanvas* can = static_cast<TCanvas*>(canIter.Next())){
//     TObjArray* histLayer = static_cast<TObjArray*>(fHistArrays->At(layer));
//     TObjArray* firstHistInCan =
//       static_cast<TObjArray*>(histLayer->At(nCan*fNoX[layer]*fNoY[layer]));
//     ++nCan;
//     if(firstHistInCan){
//       TString psFile("/tmp/");
//       psFile+=firstHistInCan->First()->GetName();
//       can->Print(psFile+=".ps");
//     }
//   } // loop over canvases
//   gROOT->SetBatch(rootIsBatch);
// }


//________________________________________________________
 void GFHistManager::Update()
{
  // call Update() to all canvases
  for(Int_t i = 0; i < fDepth; ++i){
    this->Update(i);
  }
}

//________________________________________________________
 void GFHistManager::Update(Int_t layer)
{
  if(!this->CheckDepth("Update", layer, kFALSE)) {
    return;
  }
  TIter canIter(static_cast<TObjArray*>(fCanArrays->At(layer)));

  Int_t numPreviousCansHists = 0;
  const Int_t numHistsLayer = this->GetNumHistsOf(layer);
  while(TCanvas* can = static_cast<TCanvas*>(canIter.Next())){
    Int_t nPads = this->NumberOfSubPadsOf(can);
    for(Int_t i = 0; i <= nPads; ++i){
      if (i == 0) {
	if (nPads != 0) can->cd(++i);// subpads: step into first (prefix-increment!)
	else can->cd(i);             // no subpads: step into canvas
      }
      const Int_t histNo = numPreviousCansHists + i - 1;   
      if (histNo >= numHistsLayer) continue;
      // draw other objects
      this->DrawObjects(layer, histNo);
      // draw legends on top of all
      if(fLegendArrays && fLegendArrays->GetSize() > layer && fLegendArrays->At(layer)){
	this->DrawLegend(layer, histNo);
      }
      const TH1 *h1 = this->GetHistsOf(layer, histNo)->First();
      if(fLogY[layer] 
	 && (h1->GetMinimum() > 0. 
	     || (h1->GetMinimum() == 0. && h1->GetMinimumStored() == -1111.))) {
	gPad->SetLogy();
      } else {
	gPad->SetLogy(kFALSE);
      }
      gPad->Modified();
//       gPad->Update();
//       gPad->Modified();
//       gPad->Update();
    }
//     can->Update();
    can->Modified();
    can->Update();
//     can->Modified();
    numPreviousCansHists += nPads;
  } // loop over canvases
}


//_____________________________________________________
 TLegendEntry* GFHistManager::AddHist(TH1* hist, Int_t layer, const char* legendTitle,
				     const char* legOpt)
{
  // add hist to 'layer'th list  of histos (expands, if layer does not already exist!)
  if(!hist){
    this->Warning("AddHist", "adding NULL pointer will be ignored!");
    return NULL;
  }

  if(!this->CheckDepth("AddHist", layer)) return NULL;
  GFHistArray* newHist = new GFHistArray;
  newHist->Add(hist);
  TObjArray* layerHistArrays = static_cast<TObjArray*>(fHistArrays->At(layer));
  layerHistArrays->Add(newHist);
  if(legendTitle){
    TObjArray* legends = this->MakeLegends(layer);
    TLegend* legend = new TLegend(fLegendX1, fLegendY1, fLegendX2, fLegendY2);
#if ROOT_VERSION_CODE < ROOT_VERSION(5,6,0)
    if (TString(gStyle->GetName()) == "Plain") legend->SetBorderSize(1);
#endif
    legends->AddAtAndExpand(legend, layerHistArrays->IndexOf(newHist));
    return legend->AddEntry(hist, legendTitle, legOpt ? legOpt : fgLegendEntryOption.Data());
  }
  return NULL;
}

//_____________________________________________________
 void GFHistManager::AddHists(TCollection* hists, Int_t layer, const char* legendTitle,
			     const char* legOpt)
{
  // add contents of 'hists' to 'layer'th list of histos (should be histograms!!!)
  TIter iter(hists);
  while(TObject* hist = iter.Next()){
    if(!hist->InheritsFrom(TH1::Class())){
      this->Warning("AddHists", "Trying to add a non-histogram object, ignore!");
    } else this->AddHist(static_cast<TH1*>(hist), layer, legendTitle, legOpt);
  }
}

//_____________________________________________________
 TLegendEntry* GFHistManager::AddHistSame(TH1* hist, Int_t layer, Int_t histNum,
					 const char* legendTitle, const char* legOpt)
{
  // adds hist to layer to draw it in the same pad as histNum's histo of that layer 
  if(!hist){
    this->Warning("AddHistSame", "adding NULL pointer will be ignored!");
    return NULL;
  }
  if (histNum > 0 && this->CheckDepth("AddHistSame", layer, kTRUE) //maybe added layer?
      && !this->GetHistsOf(layer, histNum-1)) {
    this->Error("AddHistSame", "usage as AddHist only for next free histNum, not %d", histNum);
    return NULL;
  }
  GFHistArray *histsArray = this->GetHistsOf(layer, histNum, kTRUE);// expand!
  TLegendEntry* result = NULL;
  if(histsArray) {
    histsArray->Add(hist); 
    if(legendTitle){
      TObjArray* legends = this->MakeLegends(layer);
      TLegend* legend = NULL;
      if(legends->GetLast() >= histNum
	 && legends->At(histNum)){
	legend = static_cast<TLegend*>(legends->At(histNum));
      } else {
	legend = new TLegend(fLegendX1, fLegendY1, fLegendX2, fLegendY2);
#if ROOT_VERSION_CODE < ROOT_VERSION(5,6,0)
	if (TString(gStyle->GetName()) == "Plain") legend->SetBorderSize(1);
#endif
	legends->AddAtAndExpand(legend, histNum);
      }
      result = legend->AddEntry(hist,legendTitle, legOpt ? legOpt : fgLegendEntryOption.Data());
    }
  }
  return result;
}

//_____________________________________________________
 void GFHistManager::AddHistsSame(GFHistArray* hists, Int_t layer,
				 const char* legendTitle, const char* legOpt)
{
  // adds hists to layer
  // each hist is AddHistSame(hist, layer, pad = 0...n)
  if(!hists){
    this->Warning("AddHistsSame", "adding NULL pointer will be ignored!");
    return;
  }
  for(Int_t i = 0; i < hists->GetEntriesFast(); ++i){
    this->AddHistSame((*hists)[i], layer, i, legendTitle, legOpt);
  }
}

//_____________________________________________________
 void GFHistManager::AddHistsSame(GFHistArray* hists, Int_t layer, Int_t histNum)
{
  // adds hists to layer to draw it in the same pad as histNum's histo of that layer
  if(!hists){
    this->Warning("AddHistsSame", "adding NULL pointer will be ignored!");
    return;
  }
  GFHistArray* histsArray = this->GetHistsOf(layer, histNum, kTRUE);
  if(histsArray) histsArray->AddAll(hists);
}

//_____________________________________________________
 void GFHistManager::AddLayers(GFHistManager* other)
{
  // append the layers from other to this, hists are not cloned, but legends?
  if(!other) return;
  const Int_t oldDepth = fDepth;
  for(Int_t iLayer = 0; iLayer < other->GetNumLayers(); ++iLayer){
    for(Int_t iPad = 0; iPad < other->GetNumHistsOf(iLayer); ++iPad){
      GFHistArray* hists = other->GetHistsOf(iLayer, iPad);
      this->AddHistsSame(hists, oldDepth + iLayer, iPad);
      TLegend* leg = other->GetLegendOf(iLayer, iPad);
      if(leg) this->AddLegend(static_cast<TLegend*>(leg->Clone()), iLayer, iPad);
    }
  }
}

//_____________________________________________________
 void GFHistManager::AddLayer(GFHistManager* other, Int_t layer)
{
  // append the layer 'layer' from other to this, hists are not cloned, but legends?
  if(!other || layer >= other->GetNumLayers()) return;

  const Int_t newLayer = fDepth;
  for(Int_t iPad = 0; iPad < other->GetNumHistsOf(layer); ++iPad){
    GFHistArray* hists = other->GetHistsOf(layer, iPad);
    this->AddHist(hists->At(0), newLayer);
    for(Int_t iHist = 1; iHist < hists->GetEntriesFast(); ++iHist){
      this->AddHistSame(hists->At(iHist), newLayer, iPad);
    }
    TLegend* leg = other->GetLegendOf(layer, iPad);
    if(leg) this->AddLegend(static_cast<TLegend*>(leg->Clone()), newLayer, iPad);
  }
}

//_____________________________________________________
 TLegend* GFHistManager::AddLegend(Int_t layer, Int_t histoNum, 
				  const char* header, Bool_t referAll)
{
  // adds a legend referencing all hists in same pad 'histoNum' of layer
  // 

  // FIXME: use help of other AddLegend method?
  if(!this->CheckHistNum("AddLegend", layer, histoNum)) return NULL;

  TObjArray* legendsOfLayer = this->MakeLegends(layer);
  TLegend* legend = (legendsOfLayer->GetSize() <= histoNum ? 
		     NULL : static_cast<TLegend*>(legendsOfLayer->At(histoNum)));
  if(!legend) {
    legend = new TLegend(fLegendX1, fLegendY1, fLegendX2, fLegendY2);
#if ROOT_VERSION_CODE < ROOT_VERSION(5,6,0)
    if (TString(gStyle->GetName()) == "Plain") legend->SetBorderSize(1);
#endif
    legendsOfLayer->AddAtAndExpand(legend, histoNum);
  }

  if(header) legend->SetHeader(header);
  GFHistArray* hists = this->GetHistsOf(layer, histoNum);
  TList* legendEntries = legend->GetListOfPrimitives();

  if(referAll){
    TIter histsIter(hists);
    while(TObject* hist = histsIter.Next()){
      Bool_t addNew = kTRUE;
      TIter legEntrIter(legendEntries);
      while(TLegendEntry* entry = static_cast<TLegendEntry*>(legEntrIter())){
	if(hist == entry->GetObject()) {addNew = kFALSE; break;}
      }  
      if(addNew) legend->AddEntry(hist, hist->GetName(), fgLegendEntryOption);
    }
  }

  if(layer < fCanArrays->GetEntriesFast()) {
    this->Update(layer); // if canvas already drawn
  }
  return legend;
}

//_____________________________________________________
 Bool_t GFHistManager::RemoveLegend(Int_t layer, Int_t nPad)
{
  // true if there was a legend
  if(!this->CheckHistNum("RemoveLegend", layer, nPad)) return kFALSE;

  TLegend* leg = this->GetLegendOf(layer, nPad);
  if(!leg) return kFALSE;

  TObjArray* legendsOfLayer = this->MakeLegends(layer);
  if(!legendsOfLayer->Remove(leg)) {
    this->Error("RemoveLegend", "inconsistent state for layer %d, nPad %d", layer, nPad);
    return kFALSE;
  }
  delete leg;

  if(layer < fCanArrays->GetEntriesFast()) {
    this->Update(layer); // if canvas already drawn
  }

  return kTRUE;
}

//_____________________________________________________
 void GFHistManager::AddLegend(TLegend* leg, Int_t layer, Int_t histoNum)
{
  // hist and layer must already exist
  if(!this->CheckHistNum("AddLegend", layer, histoNum)) return;

  TObjArray* legendsOfLayer = this->MakeLegends(layer);
  TLegend* legend = (legendsOfLayer->GetSize() < histoNum ? 
		     NULL : static_cast<TLegend*>(legendsOfLayer->At(histoNum)));
  if(legend) {
    this->Error("AddLegend", "legend exists, replacing it");
    delete legend;
  }
  legend = leg;
  legendsOfLayer->AddAtAndExpand(legend, histoNum);

  if(layer < fCanArrays->GetEntriesFast()) {
    this->Update(layer); // if canvas already drawn
  }
}


//_____________________________________________________
 void GFHistManager::AddObject(TObject* obj, Int_t layer, Int_t histoNum, Option_t* opt)
{
  // hist and layer must already exist
  if(!this->CheckHistNum("AddObject", layer, histoNum)) return;

  TList* objList = this->MakeObjList(layer, histoNum);
  objList->Add(obj, opt);

  if(layer < fCanArrays->GetEntriesFast()) {
    this->Update(layer); // if canvas already drawn
  }
}


//_____________________________________________________
 void GFHistManager::WriteCanvases(TFile* file)
{
  // write canvases with their content to file  (overwrite)
  if(!file) {
    this->Warning("WriteCanvases", "no file given, ignore!");
    return;
  }

  TDirectory* saveDir = gDirectory;
  file->cd();
  for(Int_t i = 0; i < fDepth; ++i){
    TIter canvases(static_cast<TObjArray*>(fCanArrays->At(i)));
    while(TCanvas* can = static_cast<TCanvas*>(canvases.Next())){
      can->Write(0, kOverwrite);
    }
  }
  saveDir->cd();
}

//_____________________________________________________
 void GFHistManager::WriteHistos(TFile* file)
{
  // write histos to file (overwrite)

  if(!file) {
    this->Warning("WriteHistos", "no file given, ignore!");
    return;
  }

  TDirectory* saveDir = gDirectory;
  file->cd();
  for(Int_t i = 0; i < fDepth; ++i){
    TIter iterHistsArr(static_cast<TObjArray*>(fHistArrays->At(i)));
    while(TObjArray* arr2 = static_cast<TObjArray*>(iterHistsArr.Next())){
      TIter iterHistArr2(arr2);
      while(TObject* hist = iterHistArr2.Next()){
	hist->Write(0, kOverwrite);
      }
    }
  }
  saveDir->cd();
}

//_____________________________________________________
 void GFHistManager::MakeCanvases(Int_t layer)
{
  // no check done whether layer is consistent with depth...

  Int_t nHists = static_cast<TObjArray*>(fHistArrays->At(layer))->GetEntriesFast();
  Int_t nCanvases = nHists / (fNoX[layer] * fNoY[layer]);
  if(nHists > nCanvases * fNoX[layer] * fNoY[layer]){
    ++nCanvases;
  }

  Bool_t oneCanvas = kFALSE;
  while(nHists < fNoX[layer] * fNoY[layer]){
    oneCanvas = kTRUE;
//     fNoX[layer] > 1 ? --(fNoX[layer]) : --(fNoY[layer]);
    (fNoX[layer] > 1 && fNoX[layer] >= fNoY[layer]) ? --(fNoX[layer]) : --(fNoY[layer]);
//  if(nHists < fNoX[layer] * fNoY[layer]) fNoY[layer] > 1 ? --(fNoY[layer]) : --(fNoX[layer]);
    if(nHists < fNoX[layer] * fNoY[layer])
      (fNoY[layer] > 1 && fNoY[layer] >= fNoX[layer]) ? --(fNoY[layer]) : --(fNoX[layer]);
  }
//   if(oneCanvas && nHists > fNoX[layer] * fNoY[layer]) ++(fNoX[layer]);
//   if(oneCanvas && nHists > fNoX[layer] * fNoY[layer]) 
//     (fNoX[layer] > fNoY[layer]) ? ++(fNoY[layer]) : ++(fNoX[layer]);
  while(oneCanvas && nHists > fNoX[layer] * fNoY[layer]){
    (fNoX[layer] > fNoY[layer]) ? ++(fNoY[layer]) : ++(fNoX[layer]);
  }

  if(fCanArrays->GetSize() > layer && fCanArrays->At(layer)){
    static_cast<TObjArray*>(fCanArrays->At(layer))->Delete();
  } else {
    fCanArrays->AddAtAndExpand(new TObjArray, layer);
  }

  TString canName("canvas");
  (canName += layer) += "_";

  for(Long_t i = 0; i < nCanvases; i++){
    Int_t width = fCanvasWidth, height = fCanvasHeight;
//  on screen this is nice, but Print for different canvas sizes in one .ps fails...
//     if(fNoX[layer] < fNoY[layer]){
//       width = (width * 11) / 14;
//       height *= 73; height /= 50;
//     } else if(fNoX[layer] > fNoY[layer]){ // new!
//       width = (width * 73) / 50;
//       //      height *= 11; height /= 14;
//     }

    while(gROOT->FindObject(canName+i)){
      canName += 'n';
    }

    TCanvas* can = new TCanvas(canName+i, canName+i, 10, 10, width, height);
    if (fNoX[layer] != 1 || fNoY[layer] != 1) can->Divide(fNoX[layer], fNoY[layer]);
    static_cast<TObjArray*>(fCanArrays->At(layer))->Add(can);
  }
}


//________________________________________________________
 Int_t GFHistManager::NumberOfSubPadsOf(TCanvas* can)
{
  Int_t n = 0;

  TIter next(can->GetListOfPrimitives());
  while (TObject* obj = next()) {
    if (obj->InheritsFrom(TPad::Class())){
      ++n;
    }
  }

  return n;
}

//________________________________________________________
 void GFHistManager::SetLegendX1Y1X2Y2(Double_t x1, Double_t y1, Double_t x2,Double_t y2)
{
  fLegendX1 = x1;
  fLegendY1 = y1;
  fLegendX2 = x2;
  fLegendY2 = y2;
}

//________________________________________________________
 void GFHistManager::SetLegendX1(Double_t x1) {fLegendX1 = x1;}
//________________________________________________________
 void GFHistManager::SetLegendY1(Double_t y1) {fLegendY1 = y1;}
//________________________________________________________
 void GFHistManager::SetLegendX2(Double_t x2) {fLegendX2 = x2;}
//________________________________________________________
 void GFHistManager::SetLegendY2(Double_t y2) {fLegendY2 = y2;}

//________________________________________________________
 void GFHistManager::SetNumHistsX(UInt_t numX)
{
  for(Int_t i = 0; i < fDepth; ++i){
    fNoX[i] = numX;
  }
}

//________________________________________________________
 void GFHistManager::SetNumHistsX(UInt_t numX, Int_t layer)
{
  if(this->CheckDepth("SetNumHistsX", layer, kFALSE)) {
    fNoX[layer] = numX;
  }
}

//________________________________________________________
 void GFHistManager::SetNumHistsY(UInt_t numY)
{
  for(Int_t i = 0; i < fDepth; ++i){
    fNoY[i] = numY;
  }
}

//________________________________________________________
 void GFHistManager::SetNumHistsY(UInt_t numY, Int_t layer)
{
  if(this->CheckDepth("SetNumHistsY", layer, kFALSE)) {
    fNoY[layer] = numY;
  }
}

//________________________________________________________
 void GFHistManager::SetNumHistsXY(UInt_t numX, UInt_t numY)
{
  this->SetNumHistsX(numX);
  this->SetNumHistsY(numY);
}

//________________________________________________________
 void GFHistManager::SetNumHistsXY(UInt_t numX, UInt_t numY, Int_t layer)
{
  this->SetNumHistsX(numX, layer);
  this->SetNumHistsY(numY, layer);
}

//________________________________________________________
 void GFHistManager::SetLogY(Bool_t yesNo)
{
  for(Int_t i = 0; i < fDepth; ++i){
    this->SetLogY(i);
  }
}

//________________________________________________________
 void GFHistManager::SetLogY(Int_t layer, Bool_t yesNo)
{
  if(this->CheckDepth("SetLogY", layer, kFALSE)) {
    fLogY[layer] = yesNo ? 1 : 0;
    if(layer < fCanArrays->GetEntriesFast()) {
      this->Update(layer); // if canvas already drawn
    }
  }
}

//________________________________________________________
 void GFHistManager::SetHistsOption(Option_t* option)
{
  for(Int_t i = 0; i < fDepth; ++i){
    this->SetHistsOption(option, i);
  }
}

//________________________________________________________
 void GFHistManager::SetHistsOption(Option_t* option, Int_t layer)
{
  if(!this->CheckDepth("SetHistsOption", layer, kFALSE)) return;

  TIter iter2(static_cast<TObjArray*>(fHistArrays->At(layer)));
  while(TObjArray* arr = static_cast<TObjArray*>(iter2.Next())){
    TIter iter(arr); // arr is GFHistArray* !
    while(TH1* hist = static_cast<TH1*>(iter.Next())){
      TString opt(option); opt.ToLower();
      if(!hist->InheritsFrom(TH2::Class()) && opt.Contains("box")){
	opt.ReplaceAll("box",0);
      }
      hist->SetOption(opt);
    }
  }
}

//________________________________________________________
 void GFHistManager::SetHistsMinMax(Double_t minMax, Bool_t min)
{
  for(Int_t i = 0; i < fDepth; ++i){
    this->SetHistsMinMax(minMax, min, i);
  }
}

//________________________________________________________
 void GFHistManager::SetHistsMinMax(Double_t minMax, Bool_t min, Int_t layer)
{
  if(!this->CheckDepth("SetHistsMinMax", layer, kFALSE)) return;

  TIter iter2(static_cast<TObjArray*>(fHistArrays->At(layer)));
  while(TObjArray* arr = static_cast<TObjArray*>(iter2.Next())){
    TIter iter(arr); // arr is GFHistArray* !
    while(TH1* hist = static_cast<TH1*>(iter.Next())){
      if(min) hist->SetMinimum(minMax);
      else hist->SetMaximum(minMax);
    }
  }
  if(layer < fCanArrays->GetEntriesFast()) {
    this->Update(layer); // if canvas already drawn
  }
}


//________________________________________________________
 void GFHistManager::AddHistsOption(Option_t* option)
{
  for(Int_t i = 0; i < fDepth; ++i){
    this->AddHistsOption(option, i);
  }
}

//________________________________________________________
 void GFHistManager::AddHistsOption(Option_t* option, Int_t layer)
{
  // if 'layer' exists, add 'option' to all hists so far existing in this layer
  // (ignore option 'box' for 1-D histograms)
  if(!this->CheckDepth("AddHistsOption", layer, kFALSE)) return;

  TIter iter2(static_cast<TObjArray*>(fHistArrays->At(layer)));
  while(TObjArray* arr = static_cast<TObjArray*>(iter2.Next())){
    TIter iter(arr); // arr is GFHistArray* !
    while(TH1* hist = static_cast<TH1*>(iter.Next())){
      TString opt(option); opt.ToLower();
      if(!hist->InheritsFrom(TH2::Class()) && opt.Contains("box",TString::kIgnoreCase)){
	opt.ReplaceAll("box",0);
      }
      hist->SetOption(opt += hist->GetOption());
    }
  }
}


//________________________________________________________
 void GFHistManager::SetHistsXTitle(const char* title)
{
  for(Int_t i = 0; i < fDepth; ++i){
    this->SetHistsXTitle(title, i);
  }
}

//________________________________________________________
 void GFHistManager::SetHistsXTitle(const char* title, Int_t layer)
{
  if(!this->CheckDepth("SetHistsXTitle", layer, kFALSE)) return;

  TIter iter2(static_cast<TObjArray*>(fHistArrays->At(layer)));
  while(TObjArray* arr = static_cast<TObjArray*>(iter2.Next())){
    TIter iter(arr); // arr is GFHistArray* !
    while(TH1* hist = static_cast<TH1*>(iter.Next())){
      hist->SetXTitle(title);
    }
  }
}

//________________________________________________________
 void GFHistManager::SetHistsYTitle(const char* title)
{
  for(Int_t i = 0; i < fDepth; ++i){
    this->SetHistsYTitle(title, i);
  }
}

//________________________________________________________
 void GFHistManager::SetHistsYTitle(const char* title, Int_t layer)
{
  if(!this->CheckDepth("SetHistsYTitle", layer, kFALSE)) return;

  TIter iter2(static_cast<TObjArray*>(fHistArrays->At(layer)));
  while(TObjArray* arr = static_cast<TObjArray*>(iter2.Next())){
    TIter iter(arr);// arr is GFHistArray* !
    while(TH1* hist = static_cast<TH1*>(iter.Next())){
      hist->SetYTitle(title);
    }
  }
}


//________________________________________________________
 void GFHistManager::SetHistsFillColor(Color_t color)
{
  for(Int_t i = 0; i < fDepth; ++i){
    this->SetHistsFillColor(color, i);
  }
}

//________________________________________________________
 void GFHistManager::SetHistsFillColor(Color_t color, Int_t layer)
{
  if(!this->CheckDepth("SetHistsFillColor", layer, kFALSE)) return;

  TIter iter2(static_cast<TObjArray*>(fHistArrays->At(layer)));
  while(TObjArray* arr = static_cast<TObjArray*>(iter2.Next())){
    TIter iter(arr); // arr is GFHistArray* !
    while(TH1* hist = static_cast<TH1*>(iter.Next())){
      hist->SetFillColor(color);
    }
  }
}

//________________________________________________________
 void GFHistManager::SetHistsLineWidth(Width_t width)
{
  for(Int_t i = 0; i < fDepth; ++i){
    this->SetHistsLineWidth(width, i);
  }
}

//________________________________________________________
 void GFHistManager::SetHistsLineWidth(Width_t width, Int_t layer)
{
  if(!this->CheckDepth("SetHistsLineWidth", layer, kFALSE)) return;

  TIter iter2(static_cast<TObjArray*>(fHistArrays->At(layer)));
  while(TObjArray* arr = static_cast<TObjArray*>(iter2.Next())){
    TIter iter(arr); // arr is GFHistArray* !
    while(TH1* hist = static_cast<TH1*>(iter.Next())){
      hist->SetLineWidth(width);
    }
  }
}

//________________________________________________________
 void GFHistManager::SetHistsLineStyle(Int_t s)
{
  for(Int_t i = 0; i < fDepth; ++i){
    this->SetHistsLineStyle(s, i);
  }
}

//________________________________________________________
 void GFHistManager::SetHistsLineStyle(Int_t s, Int_t layer, Int_t numHistInPad)
{
  // sets style 's' toall hists in 'layer'.
  // if numHistInPad >= 0: only the given histNum in each pad is changed in style
  // (default is numHistInPad = -1)
  if(!this->CheckDepth("SetHistsLineStyle", layer, kFALSE)) return;

  TIter iter2(static_cast<TObjArray*>(fHistArrays->At(layer)));
  while(GFHistArray* arr = static_cast<GFHistArray*>(iter2.Next())){
    if(numHistInPad < 0 || numHistInPad >= arr->GetEntriesFast()){ // all hist in pad
      TIter iter(arr); // arr is GFHistArray* !
      while(TH1* hist = static_cast<TH1*>(iter.Next())){
	hist->SetLineStyle(s);
      }
    } else {
      (*arr)[numHistInPad]->SetLineStyle(s);
    }
  }
}


//________________________________________________________
 void GFHistManager::SetHistsLineColor(Color_t color)
{
  for(Int_t i = 0; i < fDepth; ++i){
    this->SetHistsLineColor(color, i);
  }
}

//________________________________________________________
 void GFHistManager::SetHistsLineColor(Color_t color, Int_t layer)
{
  if(!this->CheckDepth("SetHistsLineColor", layer, kFALSE)) return;

  TIter iter2(static_cast<TObjArray*>(fHistArrays->At(layer)));
  while(TObjArray* arr = static_cast<TObjArray*>(iter2.Next())){
    TIter iter(arr); // arr is GFHistArray* !
    while(TH1* hist = static_cast<TH1*>(iter.Next())){
      hist->SetLineColor(color);
    }
  }
}

//________________________________________________________
 Bool_t GFHistManager::CheckDepth(const char* method, Int_t layer, 
				 Bool_t mayExpand)
{
  // true, if layer is possible, if (mayExpand) expands to layer >= 0
  if(layer < 0){
    this->Warning("CheckDepth", "Layer below 0 (%d) called in '%s'!",
		  layer, method);
    return kFALSE;
  }

  if(layer > fDepth-1){
    if(mayExpand) {
      this->ExpandTo(layer);
      return kTRUE;
    } else {
      this->Warning("CheckDepth", "Layer %d called in '%s', max. is %d",
		  layer, method, fDepth-1);
      return kFALSE;
    }
  }
  return kTRUE;
}

//________________________________________________________
 void GFHistManager::ExpandTo(Int_t layer)
{
  if(layer+1 <= fDepth){
    this->Error("ExpandTo",
		"Shrinking forbidden, fDepth = %d, should expand to = %d",
		fDepth, layer+1);
    return;
  }

  fNoX.Set(layer+1);
  fNoY.Set(layer+1);
  fLogY.Set(layer+1);

  for(Int_t i = fDepth; i <= layer; ++i){
    fNoX[i] = kDefaultPadsPerCanX;
    fNoY[i] = kDefaultPadsPerCanY;
    fLogY[i]= 0;
    fHistArrays->AddAtAndExpand(new TObjArray, i);
    fCanArrays->AddAtAndExpand(new TObjArray, i);
  }

  fDepth = layer+1;
}

//________________________________________________________
 Bool_t GFHistManager::CheckHistNum(const char* method, Int_t layer, 
				 Int_t histNum, Bool_t mayExpand)
{
  // true if hist 'histNum' exists in 'layer' 
  // if(mayExpand == kTRUE) expands to this size if necessary! (default: kFALSE)
  if(!this->CheckDepth(method, layer, mayExpand)) return kFALSE; 
  

  TObjArray * layerArr = static_cast<TObjArray*>(fHistArrays->At(layer));
  if(histNum < 0) {
    this->Warning("CheckHistNum", "histogram number %d requested!", histNum);
    return kFALSE;
  }
  while(histNum >= layerArr->GetEntriesFast()){
    if(mayExpand){
      layerArr->AddAtAndExpand(new GFHistArray, layerArr->GetEntriesFast());
    } else {
      this->Warning("CheckHistNum", "layer %d has only %d histograms, number %d requested!",
		    layer, layerArr->GetEntriesFast(), histNum);
      return kFALSE;
    }
  }
  return kTRUE;
}

//________________________________________________________
 TObjArray* GFHistManager::MakeLegends(Int_t layer)
{
  //  returns array of legends of 'layer' (to be called if 'layer' really exist!)
  // creates if necessary
  if(!fLegendArrays) fLegendArrays = new TObjArray(fDepth);
  if(layer > fLegendArrays->GetLast() || !fLegendArrays->At(layer)) {
    fLegendArrays->AddAtAndExpand(new TObjArray, layer);
  }

  return static_cast<TObjArray*>(fLegendArrays->At(layer));
}

//________________________________________________________
 TList* GFHistManager::MakeObjList(Int_t layer, Int_t histoNum)
{
  // return list of objects to be drawn upon hists in pad histoNum of 'layer' 
  // (to be called if 'layer' really exist!)
  if(!fObjLists) fObjLists = new TObjArray(fDepth);
  if(layer > fObjLists->GetLast() || !fObjLists->At(layer)){
    fObjLists->AddAtAndExpand(new TObjArray(this->GetNumHistsOf(layer)),layer);
  }
  TObjArray* layerLists = static_cast<TObjArray*>(fObjLists->At(layer));
  if(histoNum > layerLists->GetLast() || !layerLists->At(histoNum)){
    layerLists->AddAtAndExpand(new TList, histoNum); 
  }

  return static_cast<TList*>(layerLists->At(histoNum));
}

//________________________________________________________
 GFHistArray* GFHistManager::GetHistsOf(Int_t layer, Int_t histNum, Bool_t mayExpand)
{
  //  returns array of histograms for pad 'histNum' of 'layer'
  // if(mayExpand) creates if necessary!
  if(!this->CheckHistNum("GetHistsOf", layer, histNum, mayExpand)) return NULL;
  TObjArray* layerHists = static_cast<TObjArray*>(fHistArrays->At(layer));
  return static_cast<GFHistArray*>(layerHists->At(histNum));
}

//________________________________________________________
 TList* GFHistManager::GetObjectsOf(Int_t layer, Int_t histNo)
{
  if(!this->CheckHistNum("GetObjectsOf", layer, histNo, kFALSE)) return NULL;

  if(fObjLists && layer <= fObjLists->GetLast() && fObjLists->At(layer)){
    TObjArray* layerLists = static_cast<TObjArray*>(fObjLists->At(layer));
    if(histNo <= layerLists->GetLast() && layerLists->At(histNo)){
      return static_cast<TList*>(layerLists->At(histNo));
    }
  }

  return NULL;
}

//________________________________________________________
 Int_t GFHistManager::GetNumHistsOf(Int_t layer)
{
  if(!this->CheckDepth("GetNumHistsOf", layer, kFALSE)) return 0;
  TObjArray* layerHists = static_cast<TObjArray*>(fHistArrays->At(layer));
  if(layerHists) return layerHists->GetEntriesFast();
  return 0;
}

//________________________________________________________
 TLegend* GFHistManager::GetLegendOf(Int_t layer, Int_t histoNum)
{
  // if it already exists!
  if(!this->CheckHistNum("AddLegend", layer, histoNum)) return NULL;

  TObjArray* legendsOfLayer = this->MakeLegends(layer);
  TLegend* legend = (legendsOfLayer->GetSize() < histoNum ? 
		     NULL : static_cast<TLegend*>(legendsOfLayer->At(histoNum)));
  return legend;
}


//________________________________________________________
 void GFHistManager::MakeDifferentStyle(GFHistArray* hists)
{
  // easy version: adjust the histogram lines to colors
  // kBlack, kRed, kGreen, kBlue, kYellow, kMagenta, kCyan (c.f. $ROOTSYS/include/Gtypes.h)
  // 1       2     3       4      5        6         7 (skip 3 and 5: kGreen hardly visible...)
  //                                                           (... kYellow dito)
  // also set line style, set marker color to line color

  Color_t color = 0;
  for(Int_t i = 0; i < hists->GetEntriesFast(); ++i){
//     Color_t color = i+1;
    ++color;
    Style_t style = i+1;
    while(style > 4) style -= 4;
    if(color == 3) ++color; //omit kGreen
    if(color == 5) ++color; // and kYellow 
    if(color > 7 ) {
      ::Error("GFHistManager::MakeDifferentStyle", "Out of colors");
      break;
    }
    (*hists)[i]->SetLineColor(color);
    (*hists)[i]->SetMarkerColor(color);
    (*hists)[i]->SetLineStyle(style);
  }
}

//________________________________________________________
 Double_t GFHistManager::MaxOfHist(const TH1* h) const
{
  // Take bin with max content, adds error and returns (no *1.05 applied!),
  // but cares that - together with an error bar - another bin might be higher...
  // If the hists option contains nothing about errors: error is NOT added!

  TString option = h->GetOption();
  option.ToLower();
  option.ReplaceAll("same", 0);
  
  Int_t maxBin = h->GetMaximumBin();
  Double_t result = h->GetBinContent(maxBin);
  if(option.Contains('e') || (h->GetSumw2N() && !option.Contains("hist"))){
    for(Int_t bin = 1; bin <= h->GetNbinsX(); ++bin){ //FIXME: for 2/3D: loop over y/z!
      result = TMath::Max(result, (h->GetBinContent(bin) + h->GetBinError(bin))); 
    }
  }
  return result;
}

//________________________________________________________
 Double_t GFHistManager::MaxOfHists(const TObjArray* hists) const
{
  Double_t result = 0.;
  TIter nextHist(hists);
  while(TObject* hist = nextHist()){
    if(hist->InheritsFrom(TH1::Class())){
      result = TMath::Max(result, this->MaxOfHist(static_cast<TH1*>(hist)));
    } else {
      this->Warning("MaxOfHists", "Entry in input array is not a histogram!");
    }
  }
  return result;
}

//________________________________________________________
 Double_t GFHistManager::MinOfHists(const TObjArray* hists) const
{
  Double_t result = DBL_MAX;
  TIter nextHist(hists);
  while(TObject* hist = nextHist()){
    if(hist->InheritsFrom(TH1::Class())){
      result = TMath::Min(result, static_cast<TH1*>(hist)->GetMinimum());
    } else {
      this->Warning("MinOfHists", "Entry in input array is not a histogram!");
    }
  }

  return result;
}
//________________________________________________________
 TCanvas*  GFHistManager::GetCanvas(Int_t layer, Int_t number)
{
  // after draw!!
  if(!fCanArrays || fCanArrays->GetEntriesFast() <= layer) return NULL;
  TObjArray* cans = static_cast<TObjArray*>(fCanArrays->At(layer));
  if(cans && cans->GetEntriesFast() > number){
    return static_cast<TCanvas*>(cans->At(number));
  }
  return NULL;
}

//________________________________________________________
 Int_t GFHistManager::GetNumHistsX(Int_t layer) const
{
  if(layer >= 0 && layer < fDepth) return fNoX[layer];
  else return 0;
}

//________________________________________________________
 Int_t GFHistManager::GetNumHistsY(Int_t layer) const
{
  if(layer >= 0 && layer < fDepth) return fNoY[layer];
  else return 0;
}

//________________________________________________________
 void GFHistManager::GetLegendX1Y1X2Y2(Double_t& x1, Double_t& y1, 
				      Double_t& x2, Double_t& y2) const
{
   x1 = fLegendX1;
   y1 = fLegendY1;
   x2 = fLegendX2;
   y2 = fLegendY2;
}

//________________________________________________________
 void GFHistManager::DrawFuncs(const TH1* hist) const
{
  // calls Draw("SAME") for all TF1 in hist's GetListOfFunctions if necessary
  if(!hist || !TString(hist->GetOption()).Contains("HIST", TString::kIgnoreCase)) return;
  TIter nextprim(hist->GetListOfFunctions());
  while(TObject* next = nextprim()){
    if(next->InheritsFrom(TF1::Class())){
      next->Draw("SAME");
    }
  }
}


ROOT page - Class index - Top of the page

This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.