import hep.aida.*;
import org.freehep.application.*;
import org.freehep.application.studio.*;

public class Example7
{
   public static void main(String[] argv) throws java.io.IOException
   {
      IAnalysisFactory     af     = IAnalysisFactory.create();
      // The line below is the AIDA way to open a data set.
      //ITree                     tree = af.createTreeFactory().create("JAS3DataSet.aida");
      // We use instead the following JAS3 specific way to open a tree so that we can access the
      // already opened tree.
      ITree tree = (ITree) ((Studio) Application.getApplication()).getLookup().lookup(ITree.class); 
      tree.cd("/JAS3DataSet.aida");
      IHistogramFactory hf     = af.createHistogramFactory(tree);
      IFitFactory                fitf    = af.createFitFactory();
      IFitter                        fitter = fitf.createFitter("chi2","minuit");
      IFunctionFactory    funcf = af.createFunctionFactory(tree);
      ITupleFactory          tupf  = af.createTupleFactory(tree);
      IFitData                    data = fitf.createFitData();

      ITuple tuple = (ITuple) tree.find("tuple");
      IHistogram1D hist = hf.createHistogram1D("hist","double gaussian Hist",60, -1, 3);
      IHistogram1D normalizedHist = hf.createHistogram1D("normalizedHist","normalized double gaussian Hist",60, -1, 3);
      IEvaluator eval = tupf.createEvaluator("doubleGauss");
      tuple.project(hist, eval);
      tuple.project(normalizedHist, eval);

      double histNorm = (hist.axis().upperEdge()-hist.axis().lowerEdge())*hist.entries()/hist.axis().bins();
      normalizedHist.scale(1./histNorm);

      IFunction gaussSum = funcf.createFunctionFromScript("gaussSum",1,"N*( a*exp( -0.5*(mu0-x[0])*(mu0-x[0])/(s0*s0) )+(1-a)*exp( -0.5*(mu1-x[0])*(mu1-x[0])/(s1*s1) ))","N,a,mu0,s0,mu1,s1","");
      double[] pars = {170, 0.7, 1, 0.1, 1, 0.3};
      gaussSum.setParameters(pars);

      fitter.setConstraint("mu0=mu1");

      IFitResult binnedFitResult = fitter.fit(hist,gaussSum);

      data.createConnection( tuple, new IEvaluator[] { eval } );
      data.range(0).excludeAll();
      data.range(0).include(hist.axis().lowerEdge(), hist.axis().upperEdge());

      gaussSum.setParameters( binnedFitResult.fittedParameters() );
      gaussSum.setParameter( "N",1);

      fitter.fitParameterSettings("N").setFixed(true);

      fitter.setFitMethod("uml");
      IFitResult unbinnedFitResult = fitter.fit(data,gaussSum);
      unbinnedFitResult.fittedFunction().setParameter("N",binnedFitResult.fittedParameter("N"));

      IPlotter plotter = af.createPlotterFactory().create("Example7 Plot");
      plotter.createRegions(1,2);
      plotter.region(0).plot(hist);
      plotter.region(0).plot(binnedFitResult.fittedFunction());
      plotter.region(1).plot(normalizedHist);
      plotter.region(1).plot(unbinnedFitResult.fittedFunction());
      plotter.show();
   }
}

