#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>

#include "RooAbsPdf.h"
#include "RooDataSet.h"
#include "RooSimultaneous.h"

// #define _DEBUG_
#include "QFramework/TQLibrary.h"

#include "QFramework/TQStringUtils.h"
#include "QFramework/TQIterator.h"

#include "SFramework/TSFitter.h"

ClassImp(TSFitter)


//__________________________________________________________________________________|___________

TSFitter::TSFitter() : TSStatisticsCalculator("TSFitter") {
}


//__________________________________________________________________________________|___________

TSFitter::TSFitter(RooWorkspace * ws) : TSStatisticsCalculator("TSFitter",ws) {
  DEBUGclass("creating fitter");
}


//__________________________________________________________________________________|___________

TSFitter::~TSFitter() {
}


//__________________________________________________________________________________|___________

TQFolder * TSFitter::runCalculation(TQFolder * options) {
  DEBUGclass("starting calculation");
  if (!fWorkspace || !fModelConfig || !options) {
    return NULL;
  }

  // dataset name
  TString datasetName(options->getTagStringDefault("dataset","asimovData"));

  TQTaggable fitOptions;
  options->exportTags(&fitOptions, "", "fit.*");
  fitOptions.renameTags("fit.", "");
  fitOptions.setTagString("id",options->GetName());
  
  // load nominal snapshot to start from
  TString snapshotName = fitOptions.getTagStringDefault("initSnapshot","SnSh_AllVars_Nominal");
  if(!fWorkspace->loadSnapshot(snapshotName)){
    error(TString::Format("unable to load snapshot '%s'",snapshotName.Data()));
    return NULL;
  }

  /* get the Point Of Interest, PDF, and data */
  RooAbsPdf *	pdf		= fModelConfig->GetPdf();
  RooDataSet *	data		= (RooDataSet*)fWorkspace->data(datasetName.Data());
  RooArgSet nuis(this->getNuisanceParameters(options));
  RooArgSet pois(this->getPOIs(options));

  // stop if dataset could not be found
  if (!data) {
    error(TString::Format("runCalculation(): Could not find dataset '%s'. Stopping ...", datasetName.Data()));
    return NULL;
  }
  
  // restrict data and PDF to a certain category (channel)
  TString category; 
  if (options->getTagString("category",category)){
    if (!pdf->InheritsFrom(RooSimultaneous::Class())) {
      error("runCalculation(): PDF is not a RooSimultaneous. Stopping ...");
      return NULL;
    }
    
    // get PDF of single category
    RooAbsPdf * pdftmp = ((RooSimultaneous*)pdf)->getPdf(category.Data());
    if (!pdftmp) {
      error(TString::Format("runCalculation(): Could not find PDF of "
                            "category '%s'. Stopping ...", category.Data()));
      return NULL;
    }
    
    // get data of single category
    RooAbsData * datatmp = data->reduce(TString::Format("channelCat==channelCat::%s", category.Data()).Data());
    if (!datatmp) {
      error(TString::Format("runCalculation(): Could not find data of "
                            "category '%s'. Stopping ...", category.Data()));
      return NULL;
    }
    
    pdf = pdftmp;
    data = (RooDataSet*)datatmp;
    info(TString::Format("Running fit on category '%s' and dataset '%s' ...", category.Data(), datasetName.Data()));
  } else {
    info(TString::Format("Running fit on dataset '%s' ...", datasetName.Data()));
  }

  RooArgSet allVars;
  allVars.add(nuis);
  allVars.add(pois);
  
  // the results folder
  DEBUGclass("starting fit");
  TQFolder * result = fitPdfToData(pdf, data, nuis, &fitOptions);
  TString snapshot = options->getTagStringDefault("saveSnapshot",TString::Format("SnSh_AllVars_Unconditional_%s", datasetName.Data()));
  fWorkspace->saveSnapshot(snapshot.Data(),allVars);
  return result;
}
 TSFitter.cxx:1
 TSFitter.cxx:2
 TSFitter.cxx:3
 TSFitter.cxx:4
 TSFitter.cxx:5
 TSFitter.cxx:6
 TSFitter.cxx:7
 TSFitter.cxx:8
 TSFitter.cxx:9
 TSFitter.cxx:10
 TSFitter.cxx:11
 TSFitter.cxx:12
 TSFitter.cxx:13
 TSFitter.cxx:14
 TSFitter.cxx:15
 TSFitter.cxx:16
 TSFitter.cxx:17
 TSFitter.cxx:18
 TSFitter.cxx:19
 TSFitter.cxx:20
 TSFitter.cxx:21
 TSFitter.cxx:22
 TSFitter.cxx:23
 TSFitter.cxx:24
 TSFitter.cxx:25
 TSFitter.cxx:26
 TSFitter.cxx:27
 TSFitter.cxx:28
 TSFitter.cxx:29
 TSFitter.cxx:30
 TSFitter.cxx:31
 TSFitter.cxx:32
 TSFitter.cxx:33
 TSFitter.cxx:34
 TSFitter.cxx:35
 TSFitter.cxx:36
 TSFitter.cxx:37
 TSFitter.cxx:38
 TSFitter.cxx:39
 TSFitter.cxx:40
 TSFitter.cxx:41
 TSFitter.cxx:42
 TSFitter.cxx:43
 TSFitter.cxx:44
 TSFitter.cxx:45
 TSFitter.cxx:46
 TSFitter.cxx:47
 TSFitter.cxx:48
 TSFitter.cxx:49
 TSFitter.cxx:50
 TSFitter.cxx:51
 TSFitter.cxx:52
 TSFitter.cxx:53
 TSFitter.cxx:54
 TSFitter.cxx:55
 TSFitter.cxx:56
 TSFitter.cxx:57
 TSFitter.cxx:58
 TSFitter.cxx:59
 TSFitter.cxx:60
 TSFitter.cxx:61
 TSFitter.cxx:62
 TSFitter.cxx:63
 TSFitter.cxx:64
 TSFitter.cxx:65
 TSFitter.cxx:66
 TSFitter.cxx:67
 TSFitter.cxx:68
 TSFitter.cxx:69
 TSFitter.cxx:70
 TSFitter.cxx:71
 TSFitter.cxx:72
 TSFitter.cxx:73
 TSFitter.cxx:74
 TSFitter.cxx:75
 TSFitter.cxx:76
 TSFitter.cxx:77
 TSFitter.cxx:78
 TSFitter.cxx:79
 TSFitter.cxx:80
 TSFitter.cxx:81
 TSFitter.cxx:82
 TSFitter.cxx:83
 TSFitter.cxx:84
 TSFitter.cxx:85
 TSFitter.cxx:86
 TSFitter.cxx:87
 TSFitter.cxx:88
 TSFitter.cxx:89
 TSFitter.cxx:90
 TSFitter.cxx:91
 TSFitter.cxx:92
 TSFitter.cxx:93
 TSFitter.cxx:94
 TSFitter.cxx:95
 TSFitter.cxx:96
 TSFitter.cxx:97
 TSFitter.cxx:98
 TSFitter.cxx:99
 TSFitter.cxx:100
 TSFitter.cxx:101
 TSFitter.cxx:102
 TSFitter.cxx:103
 TSFitter.cxx:104
 TSFitter.cxx:105
 TSFitter.cxx:106
 TSFitter.cxx:107
 TSFitter.cxx:108
 TSFitter.cxx:109
 TSFitter.cxx:110
 TSFitter.cxx:111
 TSFitter.cxx:112
 TSFitter.cxx:113
 TSFitter.cxx:114
 TSFitter.cxx:115
 TSFitter.cxx:116