/* ======================================================================== *\
!
! *
! * 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): Thomas Bretz 3/2004 <mailto:tbretz@astro.uni-wuerzburg.de>
!
!   Copyright: MAGIC Software Development, 2000-2004
!
!
\* ======================================================================== */

//////////////////////////////////////////////////////////////////////////////
//
// MSrcPosCalc
//
// Calculate the current source position in the camera from the (already
// corrected) local pointing position of the telescope (MPointingPos) by
// derotating the position (given in x and y coordinates in the camera
// plane) at culmination time by the current rotation angle of the
// starfield dtermined from MObservatory and MPointingPos
//
// The conversion factor between the camera plain (mm) and the
// sky (deg) is taken from MGeomCam.
//
// Input Container:
//   MPointingPos
//   MObservatory
//   MGeomCam
//
// Output Container:
//   MSrcPosCam
//
// To be done:
//   - wobble mode missing
//
//////////////////////////////////////////////////////////////////////////////
#include "MSrcPosCalc.h"

#include "MParList.h"

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

#include "MRawRunHeader.h"
#include "MObservatory.h"
#include "MSrcPosCam.h"
#include "MAstroSky2Local.h"
#include "MPointingPos.h"
#include "MGeomCam.h"

ClassImp(MSrcPosCalc);

using namespace std;

// --------------------------------------------------------------------------
//
// Initialize fY and fY with 0
//
MSrcPosCalc::MSrcPosCalc(const char *name, const char *title)
    : fX(0), fY(0)
{
    fName  = name  ? name  : "MSrcPosCalc";
    fTitle = title ? title : "Derotates the source position in the camera";
}

// --------------------------------------------------------------------------
//
// Search and if necessary create MSrcPosCam in the parameter list
//
Int_t MSrcPosCalc::PreProcess(MParList *pList)
{
    fGeom = (MGeomCam*)pList->FindObject("MGeomCam");
    if (!fGeom)
    {
        *fLog << err << "MGeomCam not found... aborting." << endl;
        return kFALSE;
    }

    fPointPos = (MPointingPos*)pList->FindObject("MPointingPos");
    if (!fPointPos)
    {
        *fLog << err << "MPointPos not found... aborting." << endl;
        return kFALSE;
    }

    fObservatory = (MObservatory*)pList->FindObject("MObservatory");
    if (!fObservatory)
    {
        *fLog << err << "MObservatory not found... aborting." << endl;
        return kFALSE;
    }

    fSrcPos = (MSrcPosCam*)pList->FindCreateObj("MSrcPosCam");
    if (!fSrcPos)
        return kFALSE;

    return kTRUE;
}

// --------------------------------------------------------------------------
//
// Search the parameter list for MObservatory and MTime
//
Bool_t MSrcPosCalc::ReInit(MParList *pList)
{
    if (fX!=0 || fY!=0)
        return kTRUE;

    *fLog << warn << "fX==0 && fY==0: Using arbitrary source position!" << endl;

    //
    // This is a workaround for current crab misspointing - DO NOT USE!
    // It will be removed soon!
    //
    const MRawRunHeader *h = (MRawRunHeader*)pList->FindObject("MRawRunHeader");
    if (!h)
    {
        *fLog << err << "MRawRunHeader not found... aborting." << endl;
        return kFALSE;
    }

    const MTime &t = h->GetRunStart();

    const Double_t rho = fPointPos->RotationAngle(*fObservatory, t);

    // Calculate x, y of Zeta Tauri

    Double_t tm = t.GetAxisTime();

    Double_t x = 1.7267e6-6.03285e-3*tm; // [mm]
    Double_t y = -189.823+974.908*exp(-52.3083*(tm*1e-5-2861.5)); // [mm]

    const Double_t cs = TMath::Cos(rho-fDrho);
    const Double_t sn = TMath::Sin(rho-fDrho);

    const Double_t dx = fR*cs;
    const Double_t dy = fR*sn;

    fSrcPos->SetXY(x-dx, y-dy);

    *fLog << dbg << t << " - Position: x=" << x-dx << "mm y=" << y-dy << "mm" << endl;

    return kTRUE;
}

// --------------------------------------------------------------------------
//
// Derotate fX/fY by the current rotation angle, set MSrcPosCam
//
Int_t MSrcPosCalc::Process()
{
    if (fX==0 && fY==0)
        return kTRUE;

    // Define source position in the camera plain
    TVector2 v(fX, fY);

    // rotate the source position by the current rotation angle
    const Double_t rho = fPointPos->RotationAngle(*fObservatory);
    v=v.Rotate(-rho);

    // Convert coordinates into camera plain (mm)
    v *= 1./fGeom->GetConvMm2Deg();

    // Set current source position
    fSrcPos->SetXY(v);

    return kTRUE;
}
