/**
 * \class BDTarget
 *
 * \ingroup BeamDataUtil
 *
 * \brief Info about beam at the target and the target itself.
 *
 * This collects info about the beam at the target and the target
 * itself.  It projects the beam via the last two BPMs and profile
 * monitors.  It also provides access to info about if the target is
 * in and at what location.
 *
 * \author (last to touch it) $Author: mdier $
 *
 * \version $Revision: 1.13 $
 *
 * \date $Date: 2005/11/02 21:53:43 $
 *
 * Contact: bv@bnl.gov
 *
 * Created on: Mon Apr 18 11:25:53 2005
 *
 * $Id: BDTarget.h,v 1.13 2005/11/02 21:53:43 mdier Exp $
 *
 */



#ifndef BDTARGET_H
#define BDTARGET_H

#include <BeamDataUtil/BDProcessor.h>
#include <BeamDataUtil/BDProfMon.h>

class RawBeamMonHeaderBlock;
class RawBeamMonBlock;
class RawBeamData;

#include <vector>

class BDTarget : public BDProcessor {
public:
    BDTarget();
    virtual ~BDTarget();

    /** Enumerate possible target+horns configuration.
     *
     * \note Implementation note: If extended, it should not be
     * allowed to go beyond 8 types as it is stored in 3 bits of
     * BeamMonSpill's status bits. */
    enum BeamType {
	kUnknown = 0,		///< Unknown beam classification
	kLE,			///< Nominal Low Energy
	kME,			///< Nominal (true) Medium Energy
	kHE,			///< Nominal (true) High Energy
	kPsME,			///< Nominal (pseudo) Medium Energy
	kPsHE			///< Nominal (pseudo) High Energy
    };

    // BDProcessor API

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

    BDProfMon& GetPM121() { return fPM121; }
    BDProfMon& GetPMTGT() { return fPMTGT; }

    /** Fill vectors with projected BPM centers on target (using BPM
     * at 121 and TGT) and intensities (using TGT).
     *
     * \note Position units are Munits, intensities are relative.
     */
    void BpmProjection(std::vector<double> &xp, std::vector<double> &yp,
		       std::vector<double> &xi, std::vector<double> &yi) const;

    /** Project Profile centers and widths to target.
     *
     * \return an int giving status, 0 if no device data
     *
     * \note Units are Munits.
     */
    int ProfileProjection(double &x, double &y, double &xrms, double &yrms) const;
    
    /** Target location.
     *
     * Fill is_in with true if target is in the beam link, fill
     * z_location with distance from nominal LE.
     * Using a non-zero spilltime will use the average position of the
     * target instead of the readout
     *
     * \return a BeamType enum giving what type of beam setup is used
     * given z_location
     *
     * \note Units of location are Munits.
     */
    BeamType TargetIn(bool &is_in, double& z_location, double spilltime=0) const;

private:
    const RawBeamData *fBpms[6], *fPMs[2], *fTgt[3];
    BDProfMon fPM121, fPMTGT;	

    // Return number of batches, including average in zero-th element
    int GetNbatches() const;
};


#endif  // BDTARGET_H
