/* ======================================================================== *\
!
! *
! * This file is part of MARS, the MAGIC Analysis and Reconstruction
! * Software. It is distributed to you in the hope that it can be a useful
! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
! * It is distributed WITHOUT ANY WARRANTY.
! *
! * Permission to use, copy, modify and distribute this software and its
! * documentation for any purpose is hereby granted without fee,
! * provided that the above copyright notice appear in all copies and
! * that both that copyright notice and this permission notice appear
! * in supporting documentation. It is provided "as is" without express
! * or implied warranty.
! *
!
!
!   Author(s): Wolfgang Wittek, 08/2003 <mailto:wittek@mppmu.mpg.de>
!   Author(s): Thomas Bretz, 08/2003 <mailto:tbretz@astro.uni-wuerzburg.de>
!   Author(s): Marcos Lopez, 05/2004 <mailto:marcos@gae.ucm.es>
!
!   Copyright: MAGIC Software Development, 2000-2003
!
!
\* ======================================================================== */

/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//   MMySuperCuts                                                         //
//                                                                         //
//   this is the container for the parameters of the supercuts             //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
#include "MMySuperCuts.h"

#include <math.h>
#include <fstream>

#include "MParList.h"

#include "MLog.h"
#include "MLogManip.h"

ClassImp(MMySuperCuts);

using namespace std;

// --------------------------------------------------------------------------
//
// constructor
//
//  MMySuperCuts::MMySuperCuts(const char *name, const char *title)
//    : fParameters(18), fStepsizes(18),
//      fLengthUp(fParameters.GetArray()),   fLengthLo(fParameters.GetArray()+3),
//      fWidthUp(fParameters.GetArray()+6), fWidthLo(fParameters.GetArray()+9),
//      fDistUp(fParameters.GetArray()+12),  fDistLo(fParameters.GetArray()+15)
//  {
MMySuperCuts::MMySuperCuts(const char *name, const char *title)
  : fParameters(48), fStepsizes(48),
    fLengthUp(fParameters.GetArray()),   fLengthLo(fParameters.GetArray()+4),
    fWidthUp(fParameters.GetArray()+4*2), fWidthLo(fParameters.GetArray()+4*3),
    fDistUp(fParameters.GetArray()+4*4),  fDistLo(fParameters.GetArray()+4*5),
    fAsymUp(fParameters.GetArray()+4*6),  fAsymLo(fParameters.GetArray()+4*7),
    fConcUp(fParameters.GetArray()+4*8),  fConcLo(fParameters.GetArray()+4*9),
    fLeakage1Up(fParameters.GetArray()+4*10),  fLeakage1Lo(fParameters.GetArray()+4*11)

{

    fName  = name  ? name  : "MMySuperCuts";
    fTitle = title ? title : "Container for the supercut parameters";

    // set supercut parameters to their default values
    InitParameters();
}


// --------------------------------------------------------------------------
//
// set default values for the supercut parameters
//
void MMySuperCuts::InitParameters()
{
    //---------------------------------------------------
    //  these are the default values
    //
    fLengthUp[0] =  0.302;
    fLengthUp[1] =  0.0;//0.03;
    fLengthUp[2] =  0.0;
    fLengthUp[3] =  0.0;
//      fLengthUp[4] =  0.0;
//      fLengthUp[5] =  0.0;
//      fLengthUp[6] =  0.0;
//      fLengthUp[7] =  0.0;

    fLengthLo[0] =  0.052;
    fLengthLo[1] =  0.;
    fLengthLo[2] =  0.;
    fLengthLo[3] =  0.;
//      fLengthLo[4] =  0.;
//      fLengthLo[5] =  0.;
//      fLengthLo[6] =  0.;
//      fLengthLo[7] =  0.;

    fWidthUp[0] =  0.121;
    fWidthUp[1] =  0.0;
    fWidthUp[2] =  0.0;
    fWidthUp[3] =  0.0;
//      fWidthUp[4] =  0.0;
//      fWidthUp[5] =  0.0;
//      fWidthUp[6] =  0.0;
//      fWidthUp[7] =  0.0;

    fWidthLo[0] =  0.057;
    fWidthLo[1] =  0.;
    fWidthLo[2] =  0.;
    fWidthLo[3] =  0.;
//      fWidthLo[4] =  0.;
//      fWidthLo[5] =  0.;
//      fWidthLo[6] =  0.;
//      fWidthLo[7] =  0.;

    fDistUp[0] =  1.;
    fDistUp[1] =  0.0;
    fDistUp[2] =  0.0;
    fDistUp[3] =  0.0;
//      fDistUp[4] =  0.0;
//      fDistUp[5] =  0.0;
//      fDistUp[6] =  0.0;
//      fDistUp[7] =  0.0;

    fDistLo[0] =  0.3;
    fDistLo[1] =  0.0;
    fDistLo[2] =  0.0;
    fDistLo[3] =  0.0;
//      fDistLo[4] =  0.0;
//      fDistLo[5] =  0.0;
//      fDistLo[6] =  0.0;
//      fDistLo[7] =  0.0;
    
    // dummy values

    fAsymUp[0] =  100;
    fAsymUp[1] =  0.0;
    fAsymUp[2] =  0.0;
    fAsymUp[3] =  0.0;

    fAsymLo[0] = -100;
    fAsymLo[1] =  0.0;
    fAsymLo[2] =  0.0;
    fAsymLo[3] =  0.0;
    

    fConcUp[0] =  1.;
    fConcUp[1] =  0.0;
    fConcUp[2] =  0.0;
    fConcUp[3] =  0.0;

    fConcLo[0] = 0;
    fConcLo[1] =  0.0;
    fConcLo[2] =  0.0;
    fConcLo[3] =  0.0;
    
    fLeakage1Up[0] =  1.;
    fLeakage1Up[1] =  0.0;
    fLeakage1Up[2] =  0.0;
    fLeakage1Up[3] =  0.0;
   //   fLeakage1Up[4] =  0.0;
//      fLeakage1Up[5] =  0.0;
//      fLeakage1Up[6] =  0.0;
//      fLeakage1Up[7] =  0.0;

    fLeakage1Lo[0] = -1.e10;
    fLeakage1Lo[1] =  0.0;
    fLeakage1Lo[2] =  0.0;
    fLeakage1Lo[3] =  0.0;
   //   fLeakage1Lo[4] =  0.0;
//      fLeakage1Lo[5] =  0.0;
//      fLeakage1Lo[6] =  0.0;
//      fLeakage1Lo[7] =  0.0;


    //---------------------------------------------------
    // fStepsizes 
    // if == 0.0    the parameter will be fixed in the minimization
    //    != 0.0    initial step sizes for the parameters

    // LengthUp
    fStepsizes[0] = 0.01;
    fStepsizes[1] = 0.01;
    fStepsizes[2] = 0.1;
    fStepsizes[3] = 0.1;
//      fStepsizes[4] = 0.0;
//      fStepsizes[5] = 0.0;
//      fStepsizes[6] = 0.0;
//      fStepsizes[7] = 0.0;

    // LengthLo
    fStepsizes[4]  = 0.01;
    fStepsizes[5]  = 0.01;
    fStepsizes[6]  = 0.1;
    fStepsizes[7] = 0.1;
//      fStepsizes[12] = 0.0;
//      fStepsizes[13] = 0.0;
//      fStepsizes[14] = 0.0;
//      fStepsizes[15] = 0.0;

    // WidthUp
    fStepsizes[8] = 0.01;
    fStepsizes[9] = 0.01;
    fStepsizes[10] = 0.1;
    fStepsizes[11] = 0.1;
//      fStepsizes[20] = 0.0;
//      fStepsizes[21] = 0.0;
//      fStepsizes[22] = 0.0;
//      fStepsizes[23] = 0.0;

    // WidthLo
    fStepsizes[12] = 0.01;
    fStepsizes[13] = 0.01;
    fStepsizes[14] = 0.1;
    fStepsizes[15] = 0.1;
//      fStepsizes[28] = 0.0;
//      fStepsizes[29] = 0.0;
//      fStepsizes[30] = 0.0;
//      fStepsizes[31] = 0.0;

    // DistUp
    fStepsizes[16] = 0.1;
    fStepsizes[17] = 0.1;
    fStepsizes[18] = 0.1;
    fStepsizes[19] = 0.1;
//      fStepsizes[36] = 0.0;
//      fStepsizes[37] = 0.0;
//      fStepsizes[38] = 0.0;
//      fStepsizes[39] = 0.0;

    // DistLo
    fStepsizes[20] = 0.1;
    fStepsizes[21] = 0.1;
    fStepsizes[22] = 0.1;
    fStepsizes[23] = 0.1;
//      fStepsizes[44] = 0.0;
//      fStepsizes[45] = 0.0;
//      fStepsizes[46] = 0.0;
//      fStepsizes[47] = 0.0;

    for(int i=24;i<48;i++)
	fStepsizes[i] = .1;

}


// --------------------------------------------------------------------------
//
// Set the parameter values from the array 'd'
//
//
Bool_t MMySuperCuts::SetParameters(const TArrayD &d)
{
    if (d.GetSize() != fParameters.GetSize())
    {
        *fLog << err << "Sizes of d and of fParameters are different : "
              << d.GetSize() << ",  " << fParameters.GetSize() << endl;
        return kFALSE;
    }

    fParameters = d;

    return kTRUE;
}

// --------------------------------------------------------------------------
//
// Set the step sizes from the array 'd'
//
//
Bool_t MMySuperCuts::SetStepsizes(const TArrayD &d)
{
    if (d.GetSize() != fStepsizes.GetSize())
    {
        *fLog << err << "Sizes of d and of fStepsizes are different : "
              << d.GetSize() << ",  " << fStepsizes.GetSize() << endl;
        return kFALSE;
    }

    fStepsizes = d;

    return kTRUE;
}



void MMySuperCuts::Print(const Option_t* opt) const
{
    //    for(Int_t i=0; i<48; i++)
    //	cout << i << " " << fParameters[i] << endl;

    printf("Hillas_up/lo = A + B*log(SIZE) + C*log^2(SIZE) + D*DIST^2\n");
    printf("                A       B       C       D\n");
    printf("Length_Up  [0-3]: %7.3f %7.3f %7.3f %7.3f\n",fParameters[0],fParameters[1],fParameters[2],fParameters[3]);
    printf("Length_Lo  [4-7]: %7.3f %7.3f %7.3f %7.3f\n",fParameters[4],fParameters[5],fParameters[6],fParameters[7]);

    printf("Width_Up  [8-11]: %7.3f %7.3f %7.3f %7.3f\n",fParameters[8],fParameters[9],fParameters[10],fParameters[11]);
    printf("Width_Lo [12-15]: %7.3f %7.3f %7.3f %7.3f\n",fParameters[12],fParameters[13],fParameters[14],fParameters[15]);

    printf("Dist_Up  [16-19]: %7.3f %7.3f %7.3f %7.3f\n",fParameters[16],fParameters[17],fParameters[18],fParameters[19]);
    printf("Dist_Lo  [20-23]: %7.3f %7.3f %7.3f %7.3f\n",fParameters[20],fParameters[21],fParameters[22],fParameters[23]);

    printf("Asym_Up  [24-27]: %7.3f %7.3f %7.3f %7.3f\n",fParameters[24],fParameters[25],fParameters[26],fParameters[27]);
    printf("Asym_Lo  [28-31]: %7.3f %7.3f %7.3f %7.3f\n",fParameters[28],fParameters[29],fParameters[30],fParameters[31]);

    printf("Conc_Up  [32-35]: %7.3f %7.3f %7.3f %7.3f\n",fParameters[32],fParameters[33],fParameters[34],fParameters[35]);
    printf("Conc_Lo  [36-39]: %7.3f %7.3f %7.3f %7.3f\n",fParameters[36],fParameters[37],fParameters[38],fParameters[39]);

    printf("Leak_Up  [40-43]: %7.3f %7.3f %7.3f %7.3f\n",fParameters[40],fParameters[41],fParameters[42],fParameters[43]);
    printf("Leak_Lo  [44-47]: %7.3f %7.3f %7.3f %7.3f\n",fParameters[44],fParameters[45],fParameters[46],fParameters[47]);
}








