/* ======================================================================== *\
!
! *
! * 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): Oscar Blanch    12/2001 <mailto:blanch@ifae.es>
!
!   Copyright: MAGIC Software Development, 2000-2001
!
!
\* ======================================================================== */

/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//  MBlindPixelCalc                                                        //
//                                                                         //
//  This is the specific image cleaning for a list of pixels. This task    //
//  sets the pixels listed in fPixelsID to unused so they should not be    //
//  used for analysis (eg calculation of hillas parameters).               //
//                                                                         //
//  If you specify an array of pixel IDs this pixels are disabled.         //
//  In all other cases the task tries to determin the starfield from the   //
//  MMcRunHeader and disables pixels correspoding to the starfield.        //
//                                                                         //
//  Implemented star fields:                                               //
//   - Crab: 400, 401, 402, 437, 438, 439                                  //
//                                                                         //
//  Input Containers:                                                      //
//   MCerPhotEvt                                                           //
//                                                                         //
//  Output Containers:                                                     //
//   MBlindPixels                                                          //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
#include "MBlindPixelCalc.h"

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

#include "MParList.h"
#include "MCerPhotPix.h"
#include "MCerPhotEvt.h"
#include "MBlindPixels.h"
#include "MMcRunHeader.hxx"

ClassImp(MBlindPixelCalc);

// --------------------------------------------------------------------------
//
// Default constructor.
//
MBlindPixelCalc::MBlindPixelCalc(const char *name, const char *title)

{
    fName  = name  ? name  : "MBlindPixelCalc";
    fTitle = title ? title : "Task which removes a list of pixel from analysis";
}

// --------------------------------------------------------------------------
//
//  - Try to find or create MBlindPixels in parameter list.
//  - get the MCerPhotEvt from the parlist (abort if missing)
//  - if no pixels are given by the user try to determin the starfield
//    from the monte carlo run header.
//
Bool_t MBlindPixelCalc::PreProcess (MParList *pList)
{
    fPixels = (MBlindPixels*)pList->FindCreateObj("MBlindPixels");
    if (!fPixels)
	return kFALSE; 
    
    fEvt = (MCerPhotEvt*)pList->FindObject("MCerPhotEvt");
    if (!fEvt)
    {
        *fLog << dbginf << "MCerPhotEvt not found... aborting." << endl;
        return kFALSE;
    }

    const UShort_t size = fPixelsID.GetSize();

    if (size == 0)
    {
        if (!pList->FindObject("MMcRunHeader"))
        {
            *fLog << warn << "Warning - Neither blind pixels are given nor a MMcRunHeader was found... removing MBlindPixelCalc from list." << endl;
            return kSKIP;
        }
        return kTRUE;
    }

    // Set as blind pixels the global blind pixels, which are given
    // through the macros

    UShort_t numids = fPixelsID.GetSize();

    for(Int_t i = 0; i<numids; i++)
	fPixels->SetPixelBlind(fPixelsID[i]);

    return kTRUE;
}


// --------------------------------------------------------------------------
//
// Remove the pixels.
//
Bool_t MBlindPixelCalc::Process()
{
    const UShort_t entries = fEvt->GetNumPixels();

    //
    // remove the pixels in fPixelsID if they are set to be used,
    // (set them to 'unused' state)
    //
    for (UShort_t i=0; i<entries; i++)
    {
        MCerPhotPix &pix = (*fEvt)[i];

	if (fPixels->IsBlind(pix.GetPixId()))
            pix.SetPixelUnused();
    }

    return kTRUE;
}

// --------------------------------------------------------------------------
//
//  Set pixels to no be used. 
//  This member function (public) should be called from the macro (or
//  analysis program) setting the desired blind pixels.
//  In the future, the blind pixels may be extracted from information which
//  is already in the root file.  
//
void MBlindPixelCalc::SetPixels(Int_t num, Short_t *ids)
{
    fPixelsID.Adopt(num, ids);
}

// --------------------------------------------------------------------------
//
//  - Check whether pixels to disable are available. If pixels are
//    given by the user nothing more is done.
//  - Otherwise try to determin the blind pixels from the starfield
//    given in MMcRunHeader.
//
Bool_t MBlindPixelCalc::ReInit(MParList *pList)
{
    //
    // If pixels are given by the user, we are already done
    //
    if (fPixelsID.GetSize() > 0)
        return kTRUE;

    //
    // Set as blind some particular pixels because of a particular
    // Star Field of View.
    //
    MMcRunHeader *mcrun = (MMcRunHeader*)pList->FindObject("MMcRunHeader");
    if (!mcrun)
        return kTRUE;

    Int_t rah, ram, ras;
    Int_t ded, dem, des;
    mcrun->GetStarFieldRa(&rah, &ram, &ras);
    mcrun->GetStarFieldDec(&ded, &dem, &des);

    if (rah!=5 || ram!=34 || ras!=32 || ded!=22 || dem!=0 || des!=55)
    {
        *fLog << warn << "Warning - Detected Starfield unknown..." << endl;
        return kSKIP;
    }

    //
    // Case for Crab Nebula FOV
    //
    fPixels->Clear();
    fPixels->SetPixelBlind(400);
    fPixels->SetPixelBlind(401);
    fPixels->SetPixelBlind(402);
    fPixels->SetPixelBlind(437);
    fPixels->SetPixelBlind(438);
    fPixels->SetPixelBlind(439);

    *fLog << inf;
    *fLog << "FOV is centered at CRAB NEBULA: Setting 6 blind pixels" << endl;
    *fLog << "to avoid bias values of analysis due to CRAB NEBULA:" << endl;
    *fLog << "   Pixels: 400, 401, 402, 437, 438, 439" << endl;

    return kTRUE;
}


