/***************************************************************************
 *   Copyright (C) 2004 by Roberto Virga                                   *
 *   rvirga@users.sourceforge.net                                          *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Library General Public License as       *
 *   published by the Free Software Foundation; either version 2 of the    *
 *   License, or (at your option) any later version.                       *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this program; if not, write to the                 *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifndef KBSKBSSETIDATA_H
#define KBSKBSSETIDATA_H

#include <qdatetime.h>
#include <qdom.h>
#include <qstring.h>
#include <qvaluelist.h>

namespace KBSSETI
{
  QString formatRA(double ra);
  QString formatDec(double dec, bool sign=true);
}

struct KBSSETITapeInfo
{
  QString name;
  QDateTime start_time;
  double start_time_jd;
  QDateTime last_block_time;
  double last_block_time_jd;
  unsigned last_block_done,
           missed,
           tape_quality;
  
  bool parse(const QDomElement &node);
};
 
struct KBSSETICoordinateT
{
  QDateTime time;
  double ra,
         dec;
  
  bool parse(const QDomElement &node);
};

struct KBSSETICoords
{
  QValueList<KBSSETICoordinateT> coordinate_t;
  
  bool parse(const QDomElement &node);
};

struct KBSSETIDataDesc
{
  struct {
    double ra,
           dec;
  } start, end;
  double true_angle_range;
  QDateTime time_recorded;
  double time_recorded_jd;
  unsigned nsamples;
  KBSSETICoords coords;
  
  bool parse(const QDomElement &node);
  
  static double teraFLOPs(double angle_range);
  double teraFLOPs() const;
};

struct KBSSETIReceiverCfg
{
  unsigned s4_id;
  QString name;
  double beam_width,
         center_freq,
         latitude,
         longitude,
         elevation,
         diameter;
  struct {
    double orientation;
    QValueList<double> corr_coeff;
  } az;
  QValueList<double> zen_corr_coeff;
  
  bool parse(const QDomElement &node);
};

struct KBSSETIRecorderCfg
{
  QString name;
  unsigned bits_per_sample,
           sample_rate,
           beams;
  QString version;
  
  bool parse(const QDomElement &node);
};

struct KBSSETISplitterCfg
{
  QString version,
          data_type;
  unsigned fft_len,
           ifft_len;
  QString filter,
          window;
  
  bool parse(const QDomElement &node);
};

struct KBSSETIChirpParameterT
{
  unsigned chirp_limit,
           fft_len_flags;
  
  bool parse(const QDomElement &node);
};

struct KBSSETIChirps
{
  QValueList<KBSSETIChirpParameterT> chirp_parameter_t;
  
  bool parse(const QDomElement &node);
};

struct KBSSETIAnalysisCfg
{
  double spike_thresh;
  unsigned spikes_per_spectrum;
  struct {
    double null_chi_sq_thresh,
           chi_sq_thresh,
           power_thresh,
           peak_power_thresh;
    unsigned pot_length;
  } gauss;
  struct {
    double thresh,
           display_thresh;
    unsigned max,
             min,
             fft_max,
             pot_length;
  } pulse;
  struct {
    double thresh;
    unsigned max,
             min,
             pot_length;
  } triplet;
  struct {
    double overlap_factor;
    unsigned t_offset;
    double min_slew,
           max_slew;
  } pot;
  double chirp_resolution;
  unsigned analysis_fft_lengths;
  struct {
    unsigned boxcar_length,
             chunk_size;
  } bsmooth;
  KBSSETIChirps chirps;
  unsigned pulse_beams,
           max_signals;
  
  bool parse(const QDomElement &node);
};

struct KBSSETIGroupInfo
{
  QString name;
  KBSSETITapeInfo tape_info;
  KBSSETIDataDesc data_desc;
  KBSSETIReceiverCfg receiver_cfg;
  KBSSETIRecorderCfg recorder_cfg;
  KBSSETISplitterCfg splitter_cfg;
  KBSSETIAnalysisCfg analysis_cfg;
  
  bool parse(const QDomElement &node);
};

struct KBSSETISubbandDesc
{
  unsigned number;
  double center,
         base,
         sample_rate;
  
  bool parse(const QDomElement &node);
};

struct KBSSETIWorkunitHeader
{
  QString name;
  KBSSETIGroupInfo group_info;
  KBSSETISubbandDesc subband_desc;
  
  bool parse(const QDomElement &node);
};

struct KBSSETIRFI
{
  unsigned checked,
           found;
};

struct KBSSETISpike
{
  double peak_power,
         mean_power;
  QDateTime time;
  double time_jd,
         ra,
         decl;
  unsigned q_pix;
  double freq,
         detection_freq,
         barycentric_freq;
  unsigned fft_len;
  double chirp_rate;
  KBSSETIRFI rfi;
  unsigned reserved;  
  
  static const QString type;
  bool parse(const QDomElement &node);
  double score() const;
  double resolution() const;
  double signal_ratio() const;
};

struct KBSSETIGaussian
{
  double peak_power,
         mean_power;
  QDateTime time;
  double time_jd,
         ra,
         decl;
  unsigned q_pix;
  double freq,
         detection_freq,
         barycentric_freq;
  unsigned fft_len;
  double chirp_rate;
  KBSSETIRFI rfi;
  unsigned reserved;  
  double sigma,
         chisqr,
         null_chisqr;
  double max_power;
  QValueList<unsigned> pot;
  
  static const QString type;
  
  bool parse(const QDomElement &node);
  
  double score() const;
  bool interesting() const;
  double resolution() const;
  double signal_ratio() const;
};

struct KBSSETIPulse
{
  double peak_power,
         mean_power;
  QDateTime time;
  double time_jd,
         ra,
         decl;
  unsigned q_pix;
  double freq,
        detection_freq,
        barycentric_freq;
  unsigned fft_len;
  double chirp_rate;
  KBSSETIRFI rfi;
  unsigned reserved;
  double period,
         snr,
         thresh;
  unsigned len_prof;
  QValueList<unsigned> pot;
  
  static const QString type;
  
  bool parse(const QDomElement &node);
  
  double score() const;
  double resolution() const;
  double signal_ratio() const;
};

struct KBSSETITriplet
{
  double peak_power,
         mean_power;
  QDateTime time;
  double time_jd,
         ra,
         decl;
  unsigned q_pix;
  double freq,
         detection_freq,
         barycentric_freq;
  unsigned fft_len;
  double chirp_rate;
  KBSSETIRFI rfi;
  unsigned reserved;
  double period;

  static const QString type; 
   
  bool parse(const QDomElement &node);
  
  double score() const;
  double resolution() const;
  double signal_ratio() const;
};

struct KBSSETIBestSpike
{
  KBSSETISpike spike;
  struct {
    double score;
    unsigned bin;
    double fft_ind;
  } bs; 
  
  bool parse(const QDomElement &node);
};

struct KBSSETIBestGaussian
{
  KBSSETIGaussian gaussian;
  struct {
    double score,
           display_power_thresh;
    unsigned bin,
             fft_ind;
  } bg; 
  
  bool parse(const QDomElement &node);
};

struct KBSSETIBestPulse
{
  KBSSETIPulse pulse;
  struct {
    double score;
    unsigned freq_bin;
    double time_bin;
  } bp; 
  
  bool parse(const QDomElement &node);
};

struct KBSSETIBestTriplet
{
  KBSSETITriplet triplet;
  struct {
    double score,
           bperiod;
    unsigned tpotind[3][2],
             freq_bin;
    double time_bin,
           scale;
  } bt; 
  
  bool parse(const QDomElement &node);
};

struct KBSSETIState
{
  unsigned ncfft;
  double cr;
  unsigned fl;
  double prog;
  int potfreq;
  unsigned potactivity,
           signal_count;
  KBSSETIBestSpike best_spike;
  KBSSETIBestGaussian best_gaussian;
  KBSSETIBestPulse best_pulse;
  KBSSETIBestTriplet best_triplet;
  
  bool parse(const QDomElement &node);
};

struct KBSSETIResult
{
  KBSSETIWorkunitHeader workunit_header;
  KBSSETIState state;
  QValueList<KBSSETISpike> spike;
  QValueList<KBSSETIGaussian> gaussian;
  QValueList<KBSSETIPulse> pulse;
  QValueList<KBSSETITriplet> triplet;
  
  bool parse(const QDomElement &node);
  
  int bestSpike(double *score=NULL) const;
  int bestGaussian(double *score=NULL) const;
  int bestPulse(double *score=NULL) const;
  int bestTriplet(double *score=NULL) const;
};

#endif
