/**
 * \class BDProfMon
 *
 * \ingroup BeamDataUtil
 *
 * \brief A BDSwicDevice specific for Profile Monitor data.
 *
 * This provides access to the underlying SWIC data assuming it came
 * from a profile monitor.
 *
 * SWIC scanner have 96 channels.  For profile monitors these are
 * partitioned into a horizontal and vertical section, each with 1/2
 * the channels.  Of these 48 only 44 channels are used.
 *
 * \author (last to touch it) $Author: bv $
 *
 * \version $Revision: 1.4 $
 *
 * \date $Date: 2005/12/14 21:03:20 $
 *
 * Contact: bv@bnl.gov
 *
 * Created on: Fri Apr 15 13:09:38 2005
 *
 * $Id: BDProfMon.h,v 1.4 2005/12/14 21:03:20 bv Exp $
 *
 */

#ifndef BDPROFMON_H
#define BDPROFMON_H

#include <BeamDataUtil/BDSwicDevice.h>

#include <vector>

#include <TGraphErrors.h>
#include <TGraph.h>


class BDProfMon : public BDSwicDevice {
public:
    BDProfMon();
    BDProfMon(const RawBeamData& swic_data);
    virtual ~BDProfMon();

    /** \brief Set the RawBeamData from a swic scanner device.
     *
     */
    virtual void SetData(const RawBeamData& swic_data);

    /** \brief Mask off any bad channels.
     *
     * The mask is defined on basic SWIC channels (0-95).  You do not
     * have to worry about masking unused channels, that will be done
     * internally.
     */
    virtual bool SetMask(const std::vector<double>& mask);

    /** \brief Convert a horizontal channel [1-44] to an index in to
     *	the basic SWIC channels (0-95).
     *
     * \return an int which will be negative if an illegal channel is
     * given, o.w. the associated swic channel is given.
     */
    static int Xindex(int channel);

    /** \brief Convert a vertical channel [1-44] to an index in to
     *	the basic SWIC channels (0-95).
     *
     * \return an int which will be negative if an illegal channel is
     * given, o.w. the associated swic channel is given.
     */
    static int Yindex(int channel);

    /** \brief Return the distance from the origin to the wire on the
     * given profile monitor channel [1-44]
     *
     * Origin is half way between channels 22 and 23.  Units in Munits.
     */
    double WirePosition(int channel) const;

    /** \brief Calculate statistical values.
     *
     * Statistics are mean and RMS using a charge weighted distribution.
     *
     * \return a double giving total intensity in both X and Y views.
     *
     * Units are in Munits.
     */
    double GetStats(double& xmean, double &ymean, double &xrms, double &yrms) const;

    /** \brief Calculate values from a Gaussian fit.
     *
     * Statistics are the mean and sigma from a fit to a single Gaussian
     *
     * \return a double giving total fit area in both X and Y views.
     *
     * Units are in Munits.
     */
    
    double GetGaussFit(double& xmean, double &ymean, double &xsigma, double &ysigma) const;
    

private:
    /** \brief Do not use.  Use Xindex() or Yindex() instead
     */
    virtual int Index(const int channel);
    void SuppressDeadHot(TGraphErrors *prof) const;

    void UpdateCache();
    double GetStats(TGraphErrors *prof, double& mean, double& rms) const    ;
    double fSpacing;		// wire spacing depends on which profile monitor

};


#endif  // BDPROFMON_H
