// @(#)root/roostats:$Id:  cranmer $
// Author: Kyle Cranmer, Akira Shibata
/*************************************************************************
 * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//_________________________________________________
/*
BEGIN_HTML
<p>
</p>
END_HTML
*/
//

#include <algorithm>
#include "RooStats/HistFactory/EstimateSummary.h"

ClassImp(RooStats::HistFactory::EstimateSummary)

using namespace std; 

namespace RooStats {
  namespace HistFactory {

    EstimateSummary::EstimateSummary(){
      nominal=0; 

      normName="Lumi";
      IncludeStatError = false;
      StatConstraintType=Gaussian;
      RelErrorThreshold=0.0;
      relStatError=NULL; 
      shapeFactorName="";
    }
    EstimateSummary::~EstimateSummary(){}

    void EstimateSummary::Print(const char * /*opt*/) const {
      cout << "EstimateSummary (name = " << name << " empty = " << name.empty() << ")"<< endl;
      cout << "  TObj name = " << this->GetName() << endl;
      cout << "  Channel = " << channel << endl;
      cout << "  NormName = " << normName << endl;
      cout << "  Nominal ptr = " << nominal << endl;
      if (nominal) cout << "  Nominal hist name = " << nominal->GetName() << endl;
      cout << "  Number of hist variations = " << systSourceForHist.size() 
     << " " << lowHists.size() << " " 
     << " " << highHists.size() << endl;
      cout << "  Number of overall systematics = " << overallSyst.size() << endl;
    }

    void EstimateSummary::AddSyst(const  string &sname, TH1* low, TH1* high){
      systSourceForHist.push_back(sname);
      lowHists.push_back(low);
      highHists.push_back(high);
    }

    bool EstimateSummary::operator==(const EstimateSummary &other) const {
      // Comparator for two Estimate summary objects. Useful to make sure two analyses are the same

      //this->print();
      //other.print();
      if(! (name==other.name)){
        cout << "names don't match : " << name << " vs " << other.name << endl;
        return false;
      }
      if(! (channel==other.channel)){
        cout << "channel names don't match : " << channel << " vs " << other.channel << endl;
        return false;
      }
      if(! (normName==other.normName)){
        cout << "norm names don't match : " << normName << " vs " << other.normName << endl;
        return false;
      }
      if(! (shapeFactorName==other.shapeFactorName)){
        cout << "norm names don't match : " << shapeFactorName << " vs " << other.shapeFactorName << endl;
        return false;
      }
      if (nominal && other.nominal)
      if(! CompareHisto( this->nominal,  other.nominal ) ) {
        cout << "nominal histo don't match" << endl;
        return false;
      }
      if(! (IncludeStatError==other.IncludeStatError)){
        cout << "Include Stat Error bools don't match : " << IncludeStatError << " vs " << other.IncludeStatError << endl;
        return false;
      }
      if(! (StatConstraintType==other.StatConstraintType)){
        cout << "Stat Constraint Types don't match : " << StatConstraintType << " vs " << other.StatConstraintType << endl;
        return false;
      }
      if(! (RelErrorThreshold==other.RelErrorThreshold)){
        cout << "Relative Stat Error Thresholds don't match : " << RelErrorThreshold << " vs " << other.RelErrorThreshold << endl;
        return false;
      }
      if (relStatError && other.relStatError)
      if(! CompareHisto( this->relStatError,  other.relStatError ) ) {
        cout << "relStatError histo don't match" << endl;
        return false;
      }
      if(! (shapeFactorName==other.shapeFactorName)){
        cout << "Shape Factor Names don't match : " << shapeFactorName << " vs " << other.shapeFactorName << endl;
        return false;
      }


      /// compare histo sys
      int counter=0;
      for( vector<string>::const_iterator itr=systSourceForHist.begin(); itr!=systSourceForHist.end(); ++itr){
        unsigned int ind = find(other.systSourceForHist.begin(), other.systSourceForHist.end(), *itr) - other.systSourceForHist.begin();
        if(ind<other.systSourceForHist.size() && systSourceForHist.size() == other.systSourceForHist.size()){
          if(! (CompareHisto( lowHists[ counter ], other.lowHists[ ind ]))){
            cout << "contents of sys histo low " << *itr << " did not match" << endl;
          }
          else if (!( CompareHisto( highHists[counter], other.highHists[ ind ]) ) ){
            cout << "contents of sys histo high " << *itr << " did not match" << endl;
          } 
        } else {
          cout << "mismatch in systSourceForHist : " << systSourceForHist.size() << " vs " << other.systSourceForHist.size() << endl;
          for( vector<string>::const_iterator itr_this=systSourceForHist.begin(); itr_this!=systSourceForHist.end(); ++itr_this){
            cout << "  this contains: " << *itr_this << endl;
          }
          for( vector<string>::const_iterator itr_other=other.systSourceForHist.begin(); itr_other!=other.systSourceForHist.end(); ++itr_other){
            cout << "  other contains: " << *itr_other << endl;
          }
          return false;
        }
        counter++;
      }
      /// compare overall sys
      if( overallSyst.size() != other.overallSyst.size()){
        cout << "mismatch in overallSyst : " << overallSyst.size() << " vs " << other.overallSyst.size() << endl;
        return false;
      }
      for( map<string, pair<double, double> >::const_iterator itr=overallSyst.begin(); itr!=overallSyst.end(); ++itr){
        map<string, pair<double, double> >::const_iterator found=other.overallSyst.find(itr->first);
        if(found==other.overallSyst.end()){
          cout << "mismatch in overallSyst, didn't find " << itr->first << endl;
          return false;
        }
        if(! (itr->second.first==found->second.first && itr->second.second==found->second.second)){
          cout << "mismatch in overall Syst value of " << itr->first << endl;
          return false;
        }
      }
      return true;
    }

    bool EstimateSummary::CompareHisto( const TH1 * one, const TH1 * two) const {

       if (!one && !two) return true; 
       if (!one) return false; 
       if (!two) return false; 
      
      for(int i=1; i<=one->GetNbinsX(); ++i){
        if(!(one->GetBinContent(i)-two->GetBinContent(i)==0)) return false;
      }
      return true;
      //if(one->Integral()-two->Integral()==0) return true;
      //cout << "Integral of " << one->GetName() <<  " : " << one->Integral() << " vs Integral ov " << two->GetName() << " : " << two->Integral() << endl;
    }

  }
}

 EstimateSummary.cxx:1
 EstimateSummary.cxx:2
 EstimateSummary.cxx:3
 EstimateSummary.cxx:4
 EstimateSummary.cxx:5
 EstimateSummary.cxx:6
 EstimateSummary.cxx:7
 EstimateSummary.cxx:8
 EstimateSummary.cxx:9
 EstimateSummary.cxx:10
 EstimateSummary.cxx:11
 EstimateSummary.cxx:12
 EstimateSummary.cxx:13
 EstimateSummary.cxx:14
 EstimateSummary.cxx:15
 EstimateSummary.cxx:16
 EstimateSummary.cxx:17
 EstimateSummary.cxx:18
 EstimateSummary.cxx:19
 EstimateSummary.cxx:20
 EstimateSummary.cxx:21
 EstimateSummary.cxx:22
 EstimateSummary.cxx:23
 EstimateSummary.cxx:24
 EstimateSummary.cxx:25
 EstimateSummary.cxx:26
 EstimateSummary.cxx:27
 EstimateSummary.cxx:28
 EstimateSummary.cxx:29
 EstimateSummary.cxx:30
 EstimateSummary.cxx:31
 EstimateSummary.cxx:32
 EstimateSummary.cxx:33
 EstimateSummary.cxx:34
 EstimateSummary.cxx:35
 EstimateSummary.cxx:36
 EstimateSummary.cxx:37
 EstimateSummary.cxx:38
 EstimateSummary.cxx:39
 EstimateSummary.cxx:40
 EstimateSummary.cxx:41
 EstimateSummary.cxx:42
 EstimateSummary.cxx:43
 EstimateSummary.cxx:44
 EstimateSummary.cxx:45
 EstimateSummary.cxx:46
 EstimateSummary.cxx:47
 EstimateSummary.cxx:48
 EstimateSummary.cxx:49
 EstimateSummary.cxx:50
 EstimateSummary.cxx:51
 EstimateSummary.cxx:52
 EstimateSummary.cxx:53
 EstimateSummary.cxx:54
 EstimateSummary.cxx:55
 EstimateSummary.cxx:56
 EstimateSummary.cxx:57
 EstimateSummary.cxx:58
 EstimateSummary.cxx:59
 EstimateSummary.cxx:60
 EstimateSummary.cxx:61
 EstimateSummary.cxx:62
 EstimateSummary.cxx:63
 EstimateSummary.cxx:64
 EstimateSummary.cxx:65
 EstimateSummary.cxx:66
 EstimateSummary.cxx:67
 EstimateSummary.cxx:68
 EstimateSummary.cxx:69
 EstimateSummary.cxx:70
 EstimateSummary.cxx:71
 EstimateSummary.cxx:72
 EstimateSummary.cxx:73
 EstimateSummary.cxx:74
 EstimateSummary.cxx:75
 EstimateSummary.cxx:76
 EstimateSummary.cxx:77
 EstimateSummary.cxx:78
 EstimateSummary.cxx:79
 EstimateSummary.cxx:80
 EstimateSummary.cxx:81
 EstimateSummary.cxx:82
 EstimateSummary.cxx:83
 EstimateSummary.cxx:84
 EstimateSummary.cxx:85
 EstimateSummary.cxx:86
 EstimateSummary.cxx:87
 EstimateSummary.cxx:88
 EstimateSummary.cxx:89
 EstimateSummary.cxx:90
 EstimateSummary.cxx:91
 EstimateSummary.cxx:92
 EstimateSummary.cxx:93
 EstimateSummary.cxx:94
 EstimateSummary.cxx:95
 EstimateSummary.cxx:96
 EstimateSummary.cxx:97
 EstimateSummary.cxx:98
 EstimateSummary.cxx:99
 EstimateSummary.cxx:100
 EstimateSummary.cxx:101
 EstimateSummary.cxx:102
 EstimateSummary.cxx:103
 EstimateSummary.cxx:104
 EstimateSummary.cxx:105
 EstimateSummary.cxx:106
 EstimateSummary.cxx:107
 EstimateSummary.cxx:108
 EstimateSummary.cxx:109
 EstimateSummary.cxx:110
 EstimateSummary.cxx:111
 EstimateSummary.cxx:112
 EstimateSummary.cxx:113
 EstimateSummary.cxx:114
 EstimateSummary.cxx:115
 EstimateSummary.cxx:116
 EstimateSummary.cxx:117
 EstimateSummary.cxx:118
 EstimateSummary.cxx:119
 EstimateSummary.cxx:120
 EstimateSummary.cxx:121
 EstimateSummary.cxx:122
 EstimateSummary.cxx:123
 EstimateSummary.cxx:124
 EstimateSummary.cxx:125
 EstimateSummary.cxx:126
 EstimateSummary.cxx:127
 EstimateSummary.cxx:128
 EstimateSummary.cxx:129
 EstimateSummary.cxx:130
 EstimateSummary.cxx:131
 EstimateSummary.cxx:132
 EstimateSummary.cxx:133
 EstimateSummary.cxx:134
 EstimateSummary.cxx:135
 EstimateSummary.cxx:136
 EstimateSummary.cxx:137
 EstimateSummary.cxx:138
 EstimateSummary.cxx:139
 EstimateSummary.cxx:140
 EstimateSummary.cxx:141
 EstimateSummary.cxx:142
 EstimateSummary.cxx:143
 EstimateSummary.cxx:144
 EstimateSummary.cxx:145
 EstimateSummary.cxx:146
 EstimateSummary.cxx:147
 EstimateSummary.cxx:148
 EstimateSummary.cxx:149
 EstimateSummary.cxx:150
 EstimateSummary.cxx:151
 EstimateSummary.cxx:152
 EstimateSummary.cxx:153
 EstimateSummary.cxx:154
 EstimateSummary.cxx:155
 EstimateSummary.cxx:156
 EstimateSummary.cxx:157
 EstimateSummary.cxx:158
 EstimateSummary.cxx:159
 EstimateSummary.cxx:160
 EstimateSummary.cxx:161
 EstimateSummary.cxx:162
 EstimateSummary.cxx:163
 EstimateSummary.cxx:164
 EstimateSummary.cxx:165
 EstimateSummary.cxx:166
 EstimateSummary.cxx:167
 EstimateSummary.cxx:168