/**
 * \class BDScalar
 *
 * \ingroup BeamDataUtil
 *
 * \brief Working base class for BDProcessors that watch a single value.
 *
 * This maintains a running average of the scalar value.  It can
 * be used in two ways:
 *
 * 1) Simply give the constructor a device name and it will use that
 * devices data for the scalar value
 *
 * 2) Subclass and override GetScalar() to handle unpacking/caculating
 * more complex values.
 *
 * \author (last to touch it) $Author: minoscvs $
 *
 * \version $Revision: 1.3 $
 *
 * \date $Date: 2005/04/27 17:36:10 $
 *
 * Contact: bv@bnl.gov
 *
 * Created on: Fri Apr 15 09:59:46 2005
 *
 * $Id: BDScalar.h,v 1.3 2005/04/27 17:36:10 minoscvs Exp $
 *
 */
#ifndef BDSCALAR_H
#define BDSCALAR_H

#include <BeamDataUtil/BDProcessor.h>

#include <Util/UtilRunningAverage.h>

class BDScalar : public BDProcessor {
public:
    /** Construct a BDScalar.
     *
     * \param max_dev maximum number of standard deviations before a
     * change is considered significant.
     *
     * \param nspills number of spills to average over
     *
     * \param device_name optionally set a device to watch.  See also
     * SetDevice().
     */
    BDScalar(float max_dev = 5.0, int nspills=10, const char* device_name=0);
    ~BDScalar();

    /** Set device name.
     *
     * If GetScalar() hasn't been overridden, this device name will be
     * used to pull out data to be used as the watched scalar.
     */
    void SetDevice(const char* device_name);

    // BDProcessor API

    /// Set the current spill blocks
    void SetSpill(const RawBeamMonHeaderBlock& rbmhb,
		  const RawBeamMonBlock& rbmb);

    /// Return true if the latest spill is a "significant change" from
    /// previous as determined by the maximum deviation allowed.
    bool BeamChanged();

    // Configure:

    /// Set the number of spills overwhich to maintain the running
    /// average
    void SetSpillQueueSize(int nspills);

    /// Set the number of standard deviations a toroid measurement is
    /// allowed to deviate from the average before it is considered
    /// a significant deviation.  Deviation is not checked until the
    /// configured number of spills have been collected.
    void SetAllowedSpillDeviation(float sigmas);

    /// Return the last scalar added
    double GetValue() const;

protected:

    // Subclass can implement this
    virtual double GetScalar(const RawBeamMonHeaderBlock& rbmhb,
			     const RawBeamMonBlock& rbmb);


private:

    UtilRunningAverage fPastSpills;
    float fMaxDev;
    bool fBeamChanged;
    const char* fDeviceName;
};


#endif  // BDSCALAR_H
