////////////////////////////////////////////////////////////////////////
// $Id: TimeCalScheme.cxx,v 1.7 2005/03/22 12:53:04 tagg Exp $
//
// Prototype PE gain Calibrator class
//
// rjn@hep.ucl.ac.uk
////////////////////////////////////////////////////////////////////////
#include "TimeCalScheme.h"

#include "MessageService/MsgService.h"
#include "Plex/PlexSEIdAltL.h"
#include "Plex/PlexStripEndId.h"
#include "DatabaseInterface/DbiValidityRec.h"
#include "Validity/VldRange.h"
#include "Conventions/Munits.h"

CVSID("$Id: TimeCalScheme.cxx,v 1.7 2005/03/22 12:53:04 tagg Exp $");
ClassImp(TimeCalScheme)

TimeCalScheme::TimeCalScheme()
{
  Registry r;
  // No configurable options.
  InitializeConfig(r); 
}


//.....................................................................
void TimeCalScheme::DoReset( const VldContext& context )
{
  MSG("Calib",Msg::kVerbose) << "TimeCalScheme::DoReset()" << endl;
  
  fResPtr.NewQuery(context,0);
  
  if(fResPtr.GetNumRows()==0) {
    MAXMSG("Calib",Msg::kWarning,10) 
      << "No rows in database table with validity context "
      << context.AsString() << "  No calibration will be applied." << endl;
    IncrementErrors(kTimeCalibrator,kMissingTable);
  }  
}

//.....................................................................
void TimeCalScheme::ConfigModified()
{						
  // No configurable options.
}

//.....................................................................
void TimeCalScheme::PrintConfig( std::ostream& /*os*/ ) const
{
  // Nothing to print.
}

 
//.....................................................................
DoubleErr TimeCalScheme::GetCalibratedTime(DoubleErr rawtime,  
					  FloatErr,
					  const PlexStripEndId& seid) const
{
  /// 
  /// Purpose: Apply time calibration
  ///
  /// In: raw time in seconds
  ///     raw charge
  ///     strip end
  ///
  /// Out: calibrated time.
  ///
  /// Must be implimented by: TimeCalibrator
  ///

  // Now need to get the row which corresponds to the stripendnum.
  const CalTimeCalibration* dpgc = fResPtr.GetRowByIndex(seid.BuildPlnStripEndKey());

  if(dpgc==0) {
    if(fResPtr.GetNumRows()>0) {
      MAXMSG("Calib",Msg::kWarning,10) 
	<< "TimeCalScheme: No database row for StripEnd " << seid.AsString() << "\n";
      
      IncrementErrors(kTimeCalibrator,kMissingRow,seid);
    }
    return rawtime + FloatErr(0,50*Munits::ns); // Add error of 50ns, since we really don't know.
  }
  return dpgc->GetTime(rawtime);
}


//.....................................................................
DoubleErr TimeCalScheme::DecalTime(DoubleErr caltime,    
				  FloatErr,
				  const PlexStripEndId& seid) const
{
  ///
  /// Inverse-calibration for use by Monte-Carlo 
  ///
  /// Purpose: Go from calibrated time to raw time
  ///
  /// Input: True time
  ///        Raw charge
  ///        Strip end
  ///
  /// Output: Raw, uncalibrated time.
  ///
  /// Must be implimented by: TimeCalibrator
  ///

  // Now need to get the row which corresponds to the stripendnum.
  const CalTimeCalibration* dpgc = fResPtr.GetRowByIndex(seid.BuildPlnStripEndKey());

  if(dpgc==0) {
    // Print warning message / log errors if-and-only-if the table is not empty:
    if(fResPtr.GetNumRows()>0) { 
      MAXMSG("Calib",Msg::kWarning,10) 
	<< "TimeCalScheme: No database row for StripEnd " << seid.BuildPlnStripEndKey() << "\n";
      
      IncrementErrors(kTimeCalibrator,kMissingRow,seid);
    }

    return caltime + FloatErr(0,50*Munits::ns); // Add error of 50ns, since we really don't know.;
  }

  // No inverse function exists in the row function, so I'll kludge one here.
  // NJT 7/04
  return (caltime +  (double)dpgc->GetOffset())*(double)dpgc->GetScale();
}




