//------------------------------------------------------------------------------
THStack* PlotAlignmentValidation::addHists(const char *selection, const TString &residType,
					   bool printModuleIds)
{
  enum ResidType {
    xPrimeRes, yPrimeRes, xPrimeNormRes, yPrimeNormRes, xRes, yRes, xNormRes, /*yResNorm*/
    ResXvsXProfile,  ResXvsYProfile, ResYvsXProfile, ResYvsYProfile
  };
  ResidType rType = xPrimeRes;
  if (residType == "xPrime") rType = xPrimeRes;
  else if (residType == "yPrime") rType = yPrimeRes;
  else if (residType == "xPrimeNorm") rType = xPrimeNormRes;
  else if (residType == "yPrimeNorm") rType = yPrimeNormRes;
  else if (residType == "x") rType = xRes;
  else if (residType == "y") rType = yRes;
  else if (residType == "xNorm") rType = xNormRes;
  // else if (residType == "yNorm") rType = yResNorm;
  else if (residType == "ResXvsXProfile") rType = ResXvsXProfile;
  else if (residType == "ResYvsXProfile") rType = ResYvsXProfile;
  else if (residType == "ResXvsYProfile") rType = ResXvsYProfile;
  else if (residType == "ResYvsYProfile") rType = ResYvsYProfile;
  else {
    std::cout << "PlotAlignmentValidation::addHists: Unknown residual type "
	      << residType << std::endl; 
    return 0;
  }

  cout << "PlotAlignmentValidation::addHists: using selection " << selection << endl;
  THStack * retHistoStack = new THStack();
  double legendY = 0.80;
  TLegend * myLegend = new TLegend(0.17, legendY, 0.85, 0.88);
  setLegendStyle( *myLegend );

  for(std::vector<TkOfflineVariables*>::iterator itSourceFile = sourceList.begin();
      itSourceFile != sourceList.end(); ++itSourceFile) {

    //  TFile *f = (*sourceList.begin())->getFile();
    TFile *f = (*itSourceFile)->getFile();
    //  TTree *tree= (*sourceList.begin())->getTree();
    TTree *tree= (*itSourceFile)->getTree();
    int myLineColor = (*itSourceFile)->getLineColor();
    int myLineStyle = (*itSourceFile)->getLineStyle();
    TString myLegendName = (*itSourceFile)->getName();
    if (!f || !tree) {
      std::cout << "PlotAlignmentValidation::addHists: no tree or no file" << std::endl;
      return 0;
    }

    // Todo: TLegend?
  
    // first loop on tree to find out which entries (i.e. modules) fulfill the selection
    // 'Entry$' gives the entry number in the tree
    Long64_t nSel = tree->Draw("Entry$", selection, "goff");
    if (nSel == -1) return 0; // error in selection
    if (nSel == 0) {
      std::cout << "PlotAlignmentValidation::addHists: no selected module." << std::endl;
      return 0;
    }
    // copy entry numbers that fulfil the selection
    const std::vector<double> selected(tree->GetV1(), tree->GetV1() + nSel);

    TH1 *h = 0;       // becomes result
    UInt_t nEmpty = 0;// selected, but empty hists
    Long64_t nentries =  tree->GetEntriesFast();
    std::vector<double>::const_iterator iterEnt = selected.begin();

    // second loop on tree:
    // for each selected entry get the hist from the file and merge
    TkOffTreeVariables *treeMem = 0; // ROOT will initialise
    tree->SetBranchAddress("TkOffTreeVariables", &treeMem);
    for (Long64_t i = 0; i < nentries; i++){
      if (i < *iterEnt - 0.1             // smaller index (with tolerance): skip
	  || iterEnt == selected.end()) { // at the end: skip 
	continue;
      } else if (TMath::Abs(i - *iterEnt) < 0.11) {
	++iterEnt; // take this entry!
      } else std::cout << "Must not happen: " << i << " " << *iterEnt << std::endl;

      tree->GetEntry(i);
      if (printModuleIds) {
	std::cout << treeMem->moduleId << ": " << treeMem->entries << " entries" << std::endl;
      }
      if (treeMem->entries <= 0) {  // little speed up: skip empty hists
	++nEmpty;
	continue;
      }
      TString hName;
      switch(rType) {
      case xPrimeRes:     hName = treeMem->histNameX.c_str();          break;
      case yPrimeRes:     hName = treeMem->histNameY.c_str();          break;
      case xPrimeNormRes: hName = treeMem->histNameNormX.c_str();      break;
      case yPrimeNormRes: hName = treeMem->histNameNormY.c_str();      break;
      case xRes:          hName = treeMem->histNameLocalX.c_str();     break;
      case yRes:          hName = treeMem->histNameLocalY.c_str();     break;
      case xNormRes:      hName = treeMem->histNameNormLocalX.c_str(); break;
	/*case yResNorm:      hName = treeMem->histNameNormLocalY.c_str(); break;*/
      case ResXvsXProfile: hName = treeMem->profileNameResXvsX.c_str();    break;
      case ResXvsYProfile: hName = treeMem->profileNameResXvsY.c_str();    break;
      case ResYvsXProfile: hName = treeMem->profileNameResYvsX.c_str();    break;
      case ResYvsYProfile: hName = treeMem->profileNameResYvsY.c_str();    break;
      }
      TKey *histKey = f->FindKeyAny(hName);
      TH1 *newHist = (histKey ? static_cast<TH1*>(histKey->ReadObj()) : 0);
      if (!newHist) {
	std::cout << "Hist " << hName << " not found in file, break loop." << std::endl;
	break;
      }
      newHist->SetLineColor(myLineColor);
      newHist->SetLineStyle(myLineStyle);
      if (!h) { // first hist: clone, but rename keeping only first part of name
	TString name(newHist->GetName());
	Ssiz_t pos_ = 0;
	for (UInt_t i2 = 0; i2 < 3; ++i2) pos_ = name.Index("_", pos_+1);
	name = name(0, pos_); // only up to three '_'
	h = static_cast<TH1*>(newHist->Clone("summed_"+name));
	//      TString myTitle = Form("%s: %lld modules", selection, nSel);
	//	h->SetTitle( myTitle );
      } else { // otherwise just add
	h->Add(newHist);
      }
      delete newHist;
    }

    std::cout << "PlotAlignmentValidation::addHists" << "Result is merged from " << nSel-nEmpty
	      << " modules, " << nEmpty << " hists were empty." << std::endl;

    if (nSel-nEmpty == 0) continue;

    myLegend->AddEntry(myLegendName, myLegendName, "L");
    
    retHistoStack->Add(h);
  }
  myLegend->Draw();
  return retHistoStack;
}
Example #2
0
int MPTreeDrawer (TString detName, int structId, int layerRing, int stripReadoutMode=0)
{
    setTDRStyle();

    DetName.push_back("BPIX");
    DetName.push_back("FPIX");
    DetName.push_back("TIB");
    DetName.push_back("TOB");

    for(unsigned int i=0; i<DetName.size(); i++) {
        if(DetName.at(i)!=detName) continue;
        DetIndex=i;
        break;
    }
    if(DetIndex<0) {
        printf("Wrong detector name. Possible names are:");
        for(unsigned int i=0; i<DetName.size(); i++) printf("%s ",DetName.at(i).Data());
            printf("\nStopping...");
        return 1;
    }
    VLayer = structId;
    LayerRing = layerRing;
    StripReadMode = stripReadoutMode;

    if(nLayers[DetIndex]==1) { LayerRing=0; VLayer=0; }


    logFile = fopen ( "log.txt","w" );

    runsFile = fopen ( "runs.txt","w" );

    TFile *file = new TFile ( inputFileName );

    TString moduleType="";
    TString readoutMode="";
    if ( DetIndex<2 ) {
        moduleType="Pixel";

    } else {
        moduleType="Strip";
        readoutMode = (StripReadMode==0?"_peak":"_deconvolution");

    }
    TString TreeBaseDir("Si"+moduleType+calibrationType+"Calibration"+readoutMode+"_result_");

    std::vector<int> iovs;
    std::vector<int> iovs_;
    double totLumi=0.0;
    int nIOVs;

// Finding the IOV borders from the directory names in each ROOT file
    TList *list = file->GetListOfKeys();
    int nKeys = list->GetSize();
    for ( int keyNum=0; keyNum<nKeys; keyNum++ ) {
        TKey* key = ( TKey* ) list->At ( keyNum );
        TString str ( key->GetName() );
        if ( !str.BeginsWith ( TreeBaseDir ) ) {
            continue;
        }
        str.ReplaceAll ( TreeBaseDir,"" );
        int run = str.Atoi();
// Putting run number to the list of IOVs of the file
        iovs.push_back ( run );
        iovs_.push_back ( run );
    }
    nIOVs=iovs.size();
    if(nIOVs<1) {
        printf("No trees found with name: %s...\nExiting...\n",TreeBaseDir.Data());
        return -1;
    }
// Changing the run number if it is 1
    if ( iovs_[0]==1 && nIOVs>2 ) {
        iovs_[0]=2*iovs[1]-iovs[2];
    }
    iovs_[0]=190000;	// Setting the first run of the first IOV to a custom value
    iovs_.push_back(209091);	// Setting the last run of the last IOV to a custom value


    // Direct values from the tree
    UInt_t detId;
    Float_t value;
    // Struct of additional values from the tree
    struct treeStr{
        Float_t delta;
        Float_t error;
        UInt_t paramIndex;
    };
    Float_t error=0.f;
    treeStr treeStruct;
    std::vector<TGraphErrors*> graphLA;
    std::vector<TGraphErrors*> graphLAinput;
    int nDetParts=-1;
    bool isOldFormat = false;

    // Looping over entries in each iov tree
    for ( int iov=0; iov<nIOVs+1; iov++ ) {
        char treeName[300];
        sprintf ( treeName,"%s%d",TreeBaseDir.Data(),iovs[iov] );
    // Reading tree for input tree
        if(iov==nIOVs) {
            TString TreeBaseDirIn = TreeBaseDir;
            TreeBaseDirIn.ReplaceAll("_result_","_input");
            sprintf ( treeName,"%s",TreeBaseDirIn.Data());
        }
        TTree *tree = 0;
        tree = ( TTree* ) ( TDirectoryFile* ) file->Get ( treeName );
        Long64_t nEntries = tree->GetEntries();

        int runNr = (iov<nIOVs)?iovs.at(iov):555;
        if(tree) printf ( "Got Tree %d\twith name: %s for IOV: %d - %lld entries\n",iov,treeName,runNr,nEntries );

        fprintf(runsFile,"%d\n",iovs_.at(iov));
        if(iov>=nIOVs-nPointsToSkip && iov<nIOVs) continue;

        tree->SetBranchAddress ( "detId",&detId );
        tree->SetBranchAddress ( "value",&value );
        if(tree->GetBranch("error")) isOldFormat = true;
        if(isOldFormat) tree->SetBranchAddress ( "error",&error ); else
        tree->SetBranchAddress ( "treeStruct",&treeStruct );


        double iovWidth=-1.f;
        if(iovWidthIsFixed || runNr==555) iovWidth = fixedIOVwidth[DetIndex]; 
        else {
    // Getting more precise value of luminosity (calculation started from the first IOV run)
            iovWidth = lumisInIOV(iovs_.at(0),iovs_.at(iov+1)) - lumisInIOV(iovs_.at(0),iovs_.at(iov));
            if(iovWidth<0.0) {
    // Getting less precise value of luminosity (calculation started from this IOV run)
                iovWidth = lumisInIOV(iovs_.at(iov),iovs_.at(iov+1));
                printf("Less precise estimation of luminosity for IOV: %d (%d-%d)\n",iov+1,iovs_.at(iov),iovs_.at(iov+1));
            }
        }
        if(iovWidth<0 && iov<nIOVs) {
            printf("   ERROR!!! Luminosity for IOV %d with runs: %d - %d not found. Skipping.\n",iov,iovs_.at(iov),iovs_.at(iov+1));
            continue;
        }
        iovWidth*=lumiScale;                           // Correcting luminosity to the real (lumiCalc provides slightly larger value)
        if(!iovWidthIsFixed) iovWidth/=1000.0;         // Converting from /pb to /fb
        totLumi+=iovWidth;                             // Updating total luminosity of all IOVs


        for ( Long64_t entry=0; entry<nEntries; entry++ ) {
        //             printf("  Entry %lld\n",entry);
            tree->GetEntry ( entry );
            if(!isOldFormat) error = treeStruct.error;
            int histoId=histoIdx ( detId );
            // fprintf ( logFile,"  entry: %lld\thistoId: %d\tvalue: %.3f\terror: %.3f\n",entry,histoId,value,error );
            if ( histoId<0 ) {
                continue;
            }
            while(histoId>=(int)graphLA.size() && iov<nIOVs) {
                TGraphErrors* graph = new TGraphErrors ( nIOVs-nPointsToSkip );
                graphLA.push_back(graph);
            }
            while(histoId>=(int)graphLAinput.size() && iov>=nIOVs) {
        //printf("0. histoId: %d size: %d\n",histoId,(int)graphLAinput.size());
                TGraphErrors* graph = new TGraphErrors ( 1 );
                graphLAinput.push_back(graph);
            }
            if ( DetIndex==0 || DetIndex==2 || DetIndex==3 ) {
                if(iov<nIOVs) {
                    graphLA.at(histoId)->SetPoint ( iov, totLumi - 0.5*iovWidth, value*3.81 );	// BPIX, TIB, TOB
                    graphLA.at(histoId)->SetPointError ( iov,0.f,error*3.81 );
                } else {    // For line of input LA value
                //printf("1. histoId: %d size: %d\n",histoId,(int)graphLAinput.size());
                    Double_t centerY;
                    Double_t centerX;
                    graphLA.at(histoId)->GetPoint(graphLA.at(histoId)->GetN()/2,centerX,centerY);
                    graphLAinput.at(histoId)->SetPoint ( 0, centerX, value*3.81 );	// BPIX, TIB, TOB
                    graphLAinput.at(histoId)->SetPointError ( 0,centerX*2.5,error*3.81 );
                }
            } else if ( DetIndex==1 ) {
                if(iov<nIOVs) {
                    graphLA.at(histoId)->SetPoint ( iov, totLumi + 0.5*iovWidth, value* ( -1.3 ) );	// FPIX
                    graphLA.at(histoId)->SetPointError ( iov,0.f,error*1.3 );
                } else {    // For line of input LA value
                    Double_t centerY;
                    Double_t centerX;
                    graphLA.at(histoId)->GetPoint(graphLA.at(histoId)->GetN()/2,centerX,centerY);
                    graphLAinput.at(histoId)->SetPoint ( 0, centerX + 0.5*iovWidth, value* ( -1.3 ) );	// FPIX
                    graphLAinput.at(histoId)->SetPointError ( 0,centerX*2.5,error*1.3 );
                }
            }
        }	  // End of loop over entries
    }	// End of loop over IOVs
    nDetParts=graphLA.size();
    printf("Found %d different substructures\n",nDetParts);
    // if(LayerRing==0) nRings[DetIndex]=nDetParts;        // Updating the number of rings to draw
    if(nDetParts<1) {
        fclose(logFile);
        fclose(runsFile);
        return 1;
    }

    float minY_ = minY_det[DetIndex];
    float maxY_ = maxY_det[DetIndex];

    if(minY!=0.f || maxY!=0.f) {
        minY_ = minY;
        maxY_ = maxY;
    }

    if(autoScaleY) {
        minY_=999.9;
        maxY_=-999.9;
    }
    fprintf ( logFile,"File: %s\n",inputFileName.Data() );
    for ( int i=0; i<nDetParts; i++ ) {
    // fprintf ( logFile,"ID: %d Values: ",i );
        for ( int j=0; j<graphLA.at(i)->GetN(); j++ ) {
    // Updating min and max values of LA for axis of the plot
            Double_t val;
            Double_t null;
            graphLA.at(i)->GetPoint ( j,null,val );
            fprintf(logFile,"detPart: %d\tiov %d\tRun: %d\tValue: %.3f\n",i+1,j+1,iovs.at(j),val);
            if ( val<minY_ && autoScaleY && val!=0.0) {
                minY_=val;
            }
            if ( val>maxY_ && autoScaleY && val!=0.0) {
                maxY_=val;
            }
    // fprintf ( logFile," %.3f",val );
        }
    // fprintf ( logFile,"\n" );
    }	// End of loop over Detector parts

    if(autoScaleY) {
        minY_= ( minY_>0 ) ?minY_*0.98:minY_*1.02;
        maxY_= ( maxY_>0 ) ?maxY_*1.05:maxY_*0.95;
    }

    //Drawing canvas
    //    TCanvas *c1 = new TCanvas ( "c1","Canvas1",1000,600 );
    TCanvas *c1 = new TCanvas ( "c1","Canvas1");
    // Drawing empty histogram
    TString Y_title;
    if(calibrationType=="LorentzAngle") Y_title = "tan(#theta_{LA}^{shift}) "; else
    if(calibrationType=="Backplane") Y_title = "#DeltaW_{BP}^{shift} "; else
    Y_title = "??? ";
    drawEmptyHisto ( 0.0,totLumi,"2012 Integrated Luminosity [fb^{-1}]",minY_,maxY_,Y_title,"empty1" );
    // Drawing each graph for input values
    if(drawInput) {
        for ( int i=0; i<nDetParts; i++ ) {
            setGraphStyle ( graphLAinput.at(i),i,1 );
            graphLAinput.at(i)->SetMarkerStyle(0);
            graphLAinput.at(i)->Draw( "Lsame" );
        }
    }
    // Drawing each graph for output values
    for ( int i=0; i<nDetParts; i++ ) {
        setGraphStyle ( graphLA.at(i),i,0 );
        graphLA.at(i)->Draw ( "Psame" );
    }

    TString structName = ( LayerRing==0 ) ?"L":"R";
    TString structNameFull = ( LayerRing==0 ) ?"Layer":"Ring";

    //Drawing legend pane
    TLegend *leg;
    leg = new TLegend ( 0.7,0.77,0.98,0.95,NULL,"brNDC" );
        
    int nCols = (nDetParts>3)?2:1;

    for(int i=0; i<=nDetParts/2; i++) {
        int i2=0;
        TString legName_("");
        if(LayerRing==1) {
            i2 = i+nDetParts/2;
            legName_+="Layer";
        }
        if(LayerRing==0) {
            i2 = nDetParts-1-i;
            legName_+="Ring";
        }
        if(nDetParts<4) {
            i2 = i*2+1;
            i = i2-1;
        }
        char legName[100];
        if(i<nDetParts/2) {
            sprintf(legName,"%s %d",legName_.Data(),i+1);
            leg->AddEntry( graphLA.at(i),legName,"p" );
            sprintf(legName,"%s %d",legName_.Data(),i2+1);
            leg->AddEntry( graphLA.at(i2),legName,"p" );
            if(i==nDetParts/2-1 && nDetParts%2==0) break;
        } else {
            sprintf(legName,"%s %d",legName_.Data(),i+1);
            leg->AddEntry( graphLA.at(i),legName,"p" );
        }
    }
    setLegendStyle ( leg,nCols,nDetParts);


    if ( drawLegend ) {
        leg->Draw();
    }

    //    // Drawing CMS Preliminary label
    //    TLatex *TextCMS = new TLatex(0.2,0.89,"CMS Preliminary 2012");
    //    TextCMS->SetTextColor(1);
    //    TextCMS->SetNDC();
    //    TextCMS->SetTextFont(62);
    //    TextCMS->Draw();

    char Data_[150];
    sprintf(Data_,"%s %s %d",DetName.at(DetIndex).Data(),structNameFull.Data(),VLayer);
    TLatex *TextData = new TLatex(0.2,0.89,Data_);
    TextData->SetTextColor(1);
    TextData->SetNDC();
    TextData->SetTextFont(62);
    TextData->Draw();

    char savePath[150];

    gROOT->ProcessLine(".mkdir -p "+outputPath);
    sprintf ( savePath,"%s/%s_%s_%s%d%s",outputPath.Data(),calibrationType.Data(),DetName.at(DetIndex).Data(),structName.Data(),VLayer, readoutMode.Data() );
    c1->Print( TString ( savePath ) +=".eps" );
    //    c1->SaveAs ( TString ( savePath ) +=".pdf" );
    //    c1->SaveAs ( TString ( savePath ) +=".C" );
    //    c1->SaveAs ( TString ( savePath ) +=".root" );

    fclose ( logFile );

    fclose ( runsFile );

    return 0;
}
//------------------------------------------------------------------------------
void PlotAlignmentValidation::plotDMR(const std::string& variable, Int_t minHits, const std::string& options)
{
  // If several, comma-separated values are given,
  // call plotDMR with each value separately.
  // If a comma is found, the string is divided to two.
  // (no space allowed)
  std::size_t findres = variable.find(",");
  if ( findres != std::string::npos) {
    std::string substring1 = variable.substr(0,         findres);
    std::string substring2 = variable.substr(findres+1, std::string::npos);
    plotDMR(substring1, minHits, options);
    plotDMR(substring2, minHits, options);
    return;
   }

  // Variable name should end with X or Y. If it doesn't, recursively calls plotDMR twice with
  // X and Y added, respectively
  if (variable == "mean" || variable == "median" || variable == "meanNorm" ||
      variable == "rms" || variable == "rmsNorm") {
    plotDMR(variable+"X", minHits, options);
    plotDMR(variable+"Y", minHits, options);
    return;
  }

  TRegexp layer_re("layer=[0-9]+");
  bool plotPlain = false, plotSplits = false, plotLayers = false;
  int plotLayerN = 0;
  Ssiz_t index, len;
  if (options.find("plain") != std::string::npos) { plotPlain = true; }
  if (options.find("split") != std::string::npos) { plotSplits = true; }
  if (options.find("layers") != std::string::npos) { plotLayers = true; }
  if ((index = layer_re.Index(options, &len)) != -1) {
    if (plotLayers) {
      std::cerr << "Warning: option 'layers' overrides 'layer=N'" << std::endl;
    } else {
      std::string substr = options.substr(index+6, len-6);
      plotLayerN = atoi(substr.c_str());
    }
  }

  // Defaults to plotting only plain plot if empty (or invalid)
  // option string is given
  if (!plotPlain && !plotSplits) { plotPlain = true; }

  // This boolean array tells for which detector modules to plot split DMR plots
  // They are plotted for BPIX, FPIX, TIB and TOB
  static bool plotSplitsFor[6] = { true, true, true, false, true, false };

  // If layers are plotted, these are the numbers of layers for each subdetector
  static int numberOfLayers[6] = { 3, 2, 4, 3, 6, 9 };

  DMRPlotInfo plotinfo;

  setNiceStyle(); 
  gStyle->SetOptStat(0);
  
  TCanvas c("canv", "canv", 600, 600);
  setCanvasStyle( c );

  plotinfo.variable = variable;
  plotinfo.minHits = minHits;
  plotinfo.plotPlain = plotPlain;
  plotinfo.plotLayers = plotLayers;

  if (variable == "meanX") {          plotinfo.nbins = 50;  plotinfo.min = -0.001; plotinfo.max = 0.001; }
  else if (variable == "meanY") {     plotinfo.nbins = 50;  plotinfo.min = -0.005; plotinfo.max = 0.005; }
  else if (variable == "medianX") {   plotinfo.nbins = 50;  plotinfo.min = -0.005; plotinfo.max = 0.005; }
  else if (variable == "medianY") {   plotinfo.nbins = 50;  plotinfo.min = -0.005; plotinfo.max = 0.005; }
  else if (variable == "meanNormX") { plotinfo.nbins = 100; plotinfo.min = -2.0;   plotinfo.max = 2.0; }
  else if (variable == "meanNormY") { plotinfo.nbins = 100; plotinfo.min = -2.0;   plotinfo.max = 2.0; }
  else if (variable == "rmsX") {      plotinfo.nbins = 100; plotinfo.min = 0.0;    plotinfo.max = 0.1; }
  else if (variable == "rmsY") {      plotinfo.nbins = 100; plotinfo.min = 0.0;    plotinfo.max = 0.1; }
  else if (variable == "rmsNormX") {  plotinfo.nbins = 100; plotinfo.min = 0.3;    plotinfo.max = 1.8; }
  else if (variable == "rmsNormY") {  plotinfo.nbins = 100; plotinfo.min = 0.3;    plotinfo.max = 1.8; }
  else {
    std::cerr << "Unknown variable " << variable << std::endl;
    plotinfo.nbins = 100; plotinfo.min = -0.1; plotinfo.max = 0.1;
  }

  for (int i=1; i<=6; ++i) {

    // Skip strip detectors if plotting any "Y" variable
    if (i != 1 && i != 2 && variable.length() > 0 && variable[variable.length()-1] == 'Y') {
      continue;
    }
 
    // Skips plotting too high layers
    if (plotLayerN > numberOfLayers[i-1]) {
      continue;
    }

    plotinfo.plotSplits = plotSplits && plotSplitsFor[i-1];
    if (!plotinfo.plotPlain && !plotinfo.plotSplits) {
      continue;
    }

    // Sets dimension of legend according to the number of plots

    int nPlots = 1;
    if (plotinfo.plotSplits) { nPlots = 3; }
    if (plotinfo.plotLayers) { nPlots *= numberOfLayers[i-1]; }
    nPlots *= sourceList.size();

    double legendY = 0.80;
    if (nPlots > 3) { legendY -= 0.01 * (nPlots - 3); }
    if (legendY < 0.6) {
      std::cerr << "Warning: Huge legend!" << std::endl;
      legendY = 0.6;
    }

    THStack hstack("hstack", "hstack");
    plotinfo.maxY = 0;
    plotinfo.subDetId = i;
    plotinfo.nLayers = numberOfLayers[i-1];
    plotinfo.legend = new TLegend(0.17, legendY, 0.85, 0.88);
    setLegendStyle(*plotinfo.legend);
    plotinfo.hstack = &hstack;
    plotinfo.h = plotinfo.h1 = plotinfo.h2 = 0;
    plotinfo.firsthisto = true;
    
    for(std::vector<TkOfflineVariables*>::iterator it = sourceList.begin();
	it != sourceList.end(); ++it) {

      int minlayer = plotLayers ? 1 : plotLayerN;
      int maxlayer = plotLayers ? plotinfo.nLayers : plotLayerN;

      plotinfo.vars = *it;

      for (int layer = minlayer; layer <= maxlayer; layer++) {

	if (plotinfo.plotPlain) {
	  plotDMRHistogram(plotinfo, 0, layer);
	}

	if (plotinfo.plotSplits) {
	  plotDMRHistogram(plotinfo, -1, layer);
	  plotDMRHistogram(plotinfo, 1, layer);
	}

	if (plotinfo.plotPlain) {
	  if (plotinfo.h) { setDMRHistStyleAndLegend(plotinfo.h, plotinfo, 0, layer); }
	}

	if (plotinfo.plotSplits) {
	  // Add delta mu to the histogram
	  if (plotinfo.h1 != 0 && plotinfo.h2 != 0 && !plotinfo.plotPlain) {
	    std::ostringstream legend;
	    std::string unit = " #mum";
	    legend.precision(2);
	    float factor = 10000.0f;
	    if (plotinfo.variable == "meanNormX" || plotinfo.variable == "meanNormY" ||
		plotinfo.variable == "rmsNormX" || plotinfo.variable == "rmsNormY") {
	      factor = 1.0f;
	      unit = "";
	    }
	    float deltamu = factor*(plotinfo.h2->GetMean(1) - plotinfo.h1->GetMean(1));
	    legend << plotinfo.vars->getName();
	    if (layer > 0) {
	      legend << ", layer " << layer;
	    }
	    legend << ": #Delta#mu = " << deltamu << unit;
	    plotinfo.legend->AddEntry(static_cast<TObject*>(0), legend.str().c_str(), ""); 
	  }
	  if (plotinfo.h1) { setDMRHistStyleAndLegend(plotinfo.h1, plotinfo, -1, layer); }
	  if (plotinfo.h2) { setDMRHistStyleAndLegend(plotinfo.h2, plotinfo, 1, layer); }
	}
      
      }

    }
    
    if (plotinfo.h != 0 || plotinfo.h1 != 0 || plotinfo.h2 != 0) {

      hstack.Draw("nostack");
      hstack.SetMaximum(plotinfo.maxY*1.3);
      setTitleStyle(hstack, variable.c_str(), "#modules", plotinfo.subDetId);
      setHistStyle(*hstack.GetHistogram(), variable.c_str(), "#modules", 1);

      plotinfo.legend->Draw(); 
 
      std::ostringstream plotName;
      plotName << outputDir << "/D";
     
      if (variable=="medianX") plotName << "medianR_";
      else if (variable=="medianY") plotName << "medianYR_";
      else if (variable=="meanX") plotName << "meanR_";
      else if (variable=="meanY") plotName << "meanYR_";
      else if (variable=="meanNormX") plotName << "meanNR_";
      else if (variable=="meanNormY") plotName << "meanNYR_";
      else if (variable=="rmsX") plotName << "rmsR_";
      else if (variable=="rmsY") plotName << "rmsYR_";
      else if (variable=="rmsNormX") plotName << "rmsNR_";
      else if (variable=="rmsNormY") plotName << "rmsNYR_";

      switch (i) {
      case 1: plotName << "BPIX"; break;
      case 2: plotName << "FPIX"; break;
      case 3: plotName << "TIB"; break;
      case 4: plotName << "TID"; break;
      case 5: plotName << "TOB"; break;
      case 6: plotName << "TEC"; break;
      }

      if (plotPlain && !plotSplits) { plotName << "_plain"; }
      else if (!plotPlain && plotSplits) { plotName << "_split"; }
      if (plotLayers) { plotName << "_layers"; }
      if (plotLayerN > 0) { plotName << "_layer" << plotLayerN; }
 
      plotName << ".eps";

      c.Update(); 
      c.Print(plotName.str().c_str());
      
    }
    
  }

}
void  PlotAlignmentValidation::plotDMR(const std::string variable, Int_t minHits )
{
 setNiceStyle(); 
 gStyle->SetOptStat(0);

 // TList treeList=getTreeList();

 TCanvas *c = new TCanvas("canv", "canv", 600, 600);
 setCanvasStyle( *c );
 //loop over sub-detectors 
 for (int i=1;i<7;++i){
 
   int histo_Counter=1;
   TLegend *leg_hist = new TLegend(0.17,0.8,0.85,0.88);
   setLegendStyle(*leg_hist);
   //loop over file list
   //TTree *tree= (TTree*)treeList.First();
   //binning
   int nbinsX=100;
   double xmin=0;
   double xmax=0;
   float maxY=0;
   bool isHisto = false;
   std::string plotVar=variable;
   THStack *hstack=new THStack("hstack","hstack");

   for(std::vector<TkOfflineVariables*>::iterator it = sourceList.begin();
       it != sourceList.end(); ++it){
      
     //while ( tree ){
     plotVar=variable;
     TString subdet = "entries>=";
     subdet+=minHits; 
     subdet+=" && subDetId==";
     subdet+=i;
      
     char binning [50]="";
     sprintf (binning, ">>myhisto(%d,  %f , %f)", nbinsX, xmin, xmax);
     TH1F *h = 0;
     
     if (histo_Counter==1&&plotVar=="meanX")(*it)->getTree()->Draw( (plotVar+=">>myhisto(50,-0.005,0.005)").c_str(),subdet,"goff");
     else if (histo_Counter==1&&plotVar=="meanY")(*it)->getTree()->Draw( (plotVar+=">>myhisto(50,-0.005,0.005)").c_str(),subdet,"goff");
     else if (histo_Counter==1&&plotVar=="medianX")(*it)->getTree()->Draw( (plotVar+=">>myhisto(50,-0.005,0.005)").c_str(),subdet,"goff");
     else if (histo_Counter==1&&plotVar=="meanNormX")(*it)->getTree()->Draw( (plotVar+=">>myhisto(100,-2,2)").c_str(),subdet,"goff");
     else if (histo_Counter==1&&plotVar=="rmsX")(*it)->getTree()->Draw( (plotVar+=">>myhisto(100,0.,0.1)").c_str(),subdet,"goff");
     else if (histo_Counter!=1)(*it)->getTree()->Draw( (plotVar+=binning).c_str(),subdet,"goff");

     if (gDirectory) gDirectory->GetObject("myhisto", h);
     std::pair<float,float> fitResults(9999., 9999.);
     if (h){
       if (h->GetEntries()>0) {
	 isHisto = true;
	 h->SetDirectory(0);
	 //general draw options
	 h->SetLineWidth(2);
	 //first histo only, setting optStat...
	 if (histo_Counter==1)
	   setHistStyle(*h,plotVar.c_str() ,"#modules", 1 ); //set color later

	 h->SetLineColor( (*it)->getLineColor() );
	 h->SetLineStyle( (*it)->getLineStyle() );
	   //h->SetMarkerStyle(20+file_Counter);
      
	 //draw options
	 
	 if (maxY<h->GetMaximum()){
	   maxY=h->GetMaximum();
	 }
      
	 //fit histogram for median and mean
	 if (variable=="medianX"||variable =="meanX")fitResults=fitGauss(h, (*it)->getLineColor() );

	 if (histo_Counter==1){
	   //get mean and sigma from fit: gauss for 2sigma range
	   hstack->Add(h);
	   nbinsX=h->GetXaxis()->GetNbins();
	   xmin=h->GetXaxis()->GetXmin();
	   xmax=h->GetXaxis()->GetXmax();
	  
	 }else if (histo_Counter!=1 &&  h->GetEntries()>0)hstack->Add(h);
     
	 char legend [50]="";
	 std::string legEntry = (*it)->getName();
	 if (variable=="medianX"||variable =="meanX")sprintf (legend, "%s: #mu = %4.2f#mum, #sigma = %4.2f#mum ",legEntry.c_str(),fitResults.first ,fitResults.second);
	 else sprintf (legend, "%s ",legEntry.c_str());
	 if(h)
	   leg_hist->AddEntry(h,legend,"l");
	 else
	   std::cerr<< "histogram did not exist!";
       }
     }
     //     tree= (TTree*)treeList.After( tree );
     //     file_Counter++;
     histo_Counter++;
        
   }
    
   if (isHisto){
     hstack->Draw("nostack");
     hstack->SetMaximum(maxY*1.3);
     setTitleStyle(*hstack,plotVar.c_str() ,"#modules",i);
     setHistStyle(*hstack->GetHistogram(),plotVar.c_str() ,"#modules", 1 );
     leg_hist->Draw(); 

     std::string histName="D";
     if (variable=="medianX") histName+="medianR_";
     else if (variable=="meanX") histName+="meanR_";
     else if (variable=="meanY") histName+="meanYR_";
     else if (variable=="rmsX") histName+="rmsR_";
     std::string subDetector ="";
     switch (i){
     case 1 : subDetector+="TPB";break;
     case 2 : subDetector+="TPE";break;
     case 3 : subDetector+="TIB";break;
     case 4 : subDetector+="TID";break;
     case 5 : subDetector+="TOB";break;
     case 6 : subDetector+="TEC";break;
     }
 
     char PlotName[100];
     sprintf( PlotName, "%s/%s%s.eps",outputDir.c_str(), histName.c_str(), subDetector.c_str() );
     c->Update(); 
     c->Print(PlotName);
     //c->Update();
     //c->Close();
    
   }
   delete hstack;
   hstack=0; 
  
 }
 
 delete c;
 c=0;
}