/***************************************************************************
**
**  This file is part of QGpCompatibility.
**
**  QGpCompatibility is free software: you can redistribute it and/or modify
**  it under the terms of the GNU General Public License as published by
**  the Free Software Foundation, either version 3 of the License, or
**  (at your option) any later version.
**
**  QGpCompatibility 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 General Public License
**  along with Foobar.  If not, see <http://www.gnu.org/licenses/>
**
**  See http://www.geopsy.org for more information.
**
**  Created: 2003-05-19
**  Copyright: 2003-2019
**    Marc Wathelet
**    Marc Wathelet (ULg, Liège, Belgium)
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#ifndef MULTIMODALDATA_H
#define MULTIMODALDATA_H

#include "QGpCompatibilityDLLExport.h"

namespace QGpCompatibility {

class CompatMultiModalCurves;

/* Storage for measured multi modal curves, all sampled with the same omega set of value. Only one value per omega is accepted, an error estimate can be added to each point.

The set of periods is the same for all modes, for higher modes which don't exist over a critical period, the slowness is set to 0. Missing values for a particular mode are interpolated from the closest value available for this mode. 
*/

class QGPCOMPATIBILITY_EXPORT CompatMultiModalData
{
public:
  // Default constructor
  CompatMultiModalData();
  // Allocates an empty structure
  CompatMultiModalData(int modesCount,int omegasCount);
  // Allocates an empty structure based on an existing one with another number of modes
  CompatMultiModalData(const CompatMultiModalData* o,int modesCount, double invalidValue);
  // Set the values o as the measurements
  CompatMultiModalData(const CompatMultiModalCurves* o);
  // Destructor: get rid of all unused memory
  ~CompatMultiModalData();
  
  // I/O functions
  // -------------
  // Store in an inversion report
  void dataToReport(QDataStream& s);
  // Load from an inversion report
  void reportToData(QDataStream& s);
  // Version 3 of CompatInversionReport, statistical weight of all point
  void reportToDataWeight(QDataStream& s, bool loadIt);
  
  // Tracks stddev that fall below a defined threshold
  bool checkStdDev(double ratio);
  
  // Set the average of the ith value (measurements) of mode m
  void setMean(int i, int mode,double mean) {_measurements[mode][i]=mean;}
  // Returns the ith value(measurements) of mode m
  double measurement(int i, int mode) const {return _measurements[mode][i];}
  // Set the stddev of the ith value (measurements) of mode m
  void setStddev(int i, int mode,double stddev) {_stddev[mode][i]=stddev;}
  // Returns the stddev of the ith value (measurements) of mode m
  double stddev(int i, int mode) const {return _stddev[mode][i];}
  // Set the weith of the ith measurements of mode m
  void setWeight(int i, int m, double w) {_weight[m][i]=w;}
  // Returns the weith of the ith measurements of mode m
  double Weight(int i, int m) {return _weight[m][i];}
  // Returns the measurements of mode iMode
  QVector<double> * measurements(int iMode);
  // Returns the stddev of mode iMode
  QVector<double> * stddev(int iMode);
  // Returns the weight of mode iMode
  QVector<double> * weight(int iMode);
  // Compatibility with new framework
  ModalCurve curve(int iMode);

  // Compares the measurments of two objects
  bool isSameData(const CompatMultiModalData * o) const;
  // return the log comments
  QString & log() {return _log;}
  // add new lines to existing comments
  void addLog(QString& s) {_log+=s+"\n";}
  //Transfers values from the autocorrCurve sub-object to measurements
  void valuesToData(CompatMultiModalCurves * o); 
  // Tells whether curve pointed by pDisp is inside +/-devRatio*stddev
  bool insideDev(double devRatio, int iMode, Point2D * pDisp, int countPoints);
protected:
  // Number of modes
  int _modesCount;
  // Number of frequencies
  int _omegasCount;
  
  // Storage for measured values
  double ** _measurements;  
  // Storage for their error estimates
  double ** _stddev;
  // Storage for error estimates weight
  double ** _weight;
  // Any comment on how the measurement curve was generated
  QString _log;
  
  // De-allocates the storage for measured values
  void deleteData();
  // Allocates the storage for measured values
  void allocatesData();
};

} // namespace QGpCompatibility

#endif // COMPATMULTIMODALDATA_H
