#ifndef UTSUSEMIREDUCTIONCOMMON
#define UTSUSEMIREDUCTIONCOMMON

#include "UtsusemiHeader.hh"
#include "StringTools.hh"

//////////////////////////////////
// UtsusemiReductionCommon
/////////////////////////////////

//! Functions to do data correction
/*!
 *  - calculate Phi from Pixel position
 *  - normalized by bin width
 *
 *
 */
class UtsusemiReductionCommon:
  public ManipulatorBase< ElementContainerMatrix >
{
private:
    Double CalcPhi_delta_px;
    Double CalcPhi_delta_py;
    Double CalcPhi_delta_pz;
    static const std::string _MessageTag;
    void Initialize();
    StringTools* st;
    UtsusemiCheckDataProcess UCP;
    void SetPositionDeviationForCalcPhi(double d_px, double d_py, double d_pz);
public:
    UtsusemiReductionCommon();
        //!< Constructor
        /*!<
         */
    UtsusemiReductionCommon(ElementContainerMatrix *ecm);
        //!< Constructor
        /*!<
         *  @param ecm ElementContainerMatrix for the target
         */
    ~UtsusemiReductionCommon();
        //!< Destructor
        /*!<
         */
    bool CalcPhi(ElementContainerMatrix *ecm, double d_px=0, double d_py=0, double d_pz=0);
        //!< executes calclulation of Phi to store in header
        /*!<
         *   @param ecm (ElementContainerMatrix*) Target data
         *   @param d_px (Double) delta-x of volume of a pixel
         *   @param d_py (Double) delta-y of volume of a pixel
         *   @param d_pz (Double) delta-z of volume of a pixel
         *   @retval true  suceeded
         *   @retval false failed
         */
    bool CalcPhi(double d_px=0, double d_py=0, double d_pz=0);
        //!< executes calclulation of Phi
        /*!<
         *   @param d_px (Double) delta-x of volume of a pixel
         *   @param d_py (Double) delta-y of volume of a pixel
         *   @param d_pz (Double) delta-z of volume of a pixel
         *   @retval true  suceeded
         *   @retval false failed
         */

    bool NormByBinWidth(ElementContainerMatrix *ecm, std::string key="");
    bool NormByBinWidth(std::string key="");
        //!< Intensity normalized by binning width
        /*!<
         *   @retval true : suceeded
         *   @retval false: failed
         */

    bool NormBySolidAngle( ElementContainerMatrix *ecm, Double L2=0.0, Double dS=0.0 );
    bool NormBySolidAngle( Double L2=0.0, Double dS=0.0 );
    bool SolidAngleCorrect( ElementContainerMatrix *ecm=NULL );
    bool NormByKickers( ElementContainerMatrix *ecm=NULL, Double normFactor=1.0 );
    bool NormByKickers( Double normFactor );
};
#endif
