//_____________________________________________________________________________
///
/// \class FitStateConverged
///
/// FitStateConverged is the converged state - Iterate calculates
/// number of planes to fit during next iteration.
///
/// \author Sergei avva@fnal.gov
///

#include <string>

#include "Algorithm/AlgConfig.h"
#include "MessageService/MsgService.h"

#include "CandFitTrackSA/ConstFT.h"
#include "CandFitTrackSA/DataFT.h"
#include "CandFitTrackSA/MatrixCalculator.h"

#include "CandFitTrackSA/FitStateFactory.h"
#include "CandFitTrackSA/FitStateConverged.h"
#include "CandFitTrackSA/FitContext.h"

CVSID("$Id: FitStateConverged.cxx,v 1.3 2006/02/13 03:50:22 avva Exp $");

// The ID of class Line
static const std::string CONVERGED_FIT_STATE = "Converged";

// Create an anonymous namespace
// to make the function invisible from other modules
namespace {

FitState* CreateConvergedFS() { return new FitStateConverged; }

// register block
bool registered = FitStateFactory::Instance().RegisterFitState(
                                        CONVERGED_FIT_STATE, CreateConvergedFS);
}  // namespace


///
/// Name() - return name of the state 
///
const std::string& FitStateConverged::Name() const
{
    return CONVERGED_FIT_STATE;
}    


///
/// Iterate method
///
void FitStateConverged::Iterate(FitContext& context) const
{
    // reset number of iterations
    context.fNIterationsStep = 0;    
    // reset number of diverging iterations
    context.fNTriesDiverges = 0;   
    
    // save fit parameters as last good fit
    FitResult result = context.fMatCalc.GetFitResult();
    context.fLastGoodFit = result;
    ++context.fTimesConverged;
        
    if ( context.fConvergenceMaster.NextStep() ) {    
        if ( ! context.fConvergenceMaster.MaskIsValid() ) { 
            // apply the next mask
            context.fData.SetUHitUse( context.fConvergenceMaster.GetMaskUCur() );
            context.fData.SetVHitUse( context.fConvergenceMaster.GetMaskVCur() );
            context.fConvergenceMaster.SetMaskIsValid(kTRUE);
            MSG("FitTrackSA",Msg::kInfo) << "Updated U, V Masks.\n";
        }    
        context.fDChi2 = ConstFT::InitialDChi2;
        context.SetState(FitStateFactory::Instance().GetFitState("Iterating"));
        //context.Print();
        MSG("FitTrackSA",Msg::kInfo) << "Switched from Converged to Iterating\n";
    } else {
        context.SetState(FitStateFactory::Instance().GetFitState("Final"));
        //context.Print();
        MSG("FitTrackSA",Msg::kInfo) << "Switched from Converged to Final\n";
        return;
    }
}

