// $Id: chainparam.h,v 1.36 2018/01/03 21:32:54 mkkuhner Exp $

/*
Copyright 2002-2005 Mary K. Kuhner, Peter Beerli, and Joseph Felsenstein

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

*/

/* Authors: Peter Beerli, Mary Kuhner, Jon Yamato and Joseph Felsenstein */


/********************************************************************
 ChainParameters is a collection class used for internal communication
 throughout Lamarc.

 ChainParameters contains information needed to run chains, including
 managing the different arrangers.

 Written by Jim Sloan, revised by Mary Kuhner

 reworked by Elizabeth Walkup 2004/08/06 to mesh with
 front-end/back-end separation
********************************************************************/

#ifndef CHAINPARAMETERS_H
#define CHAINPARAMETERS_H

#include <vector>
#include <stdlib.h>

#include "vectorx.h"
#include "constants.h"
#include "arrangervec.h"

class Arranger;

//------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------

class ChainParameters
{
  private:
    ArrangerVec  m_arrangers;    // we own this
    DoubleVec1d  m_temperatures; // sorted in ascending order
    long         m_tempinterval; // how often to swap between heated chains
    bool         m_tempadapt;    // adpative change of the temperatures
    long         m_nChains_initial;
    long         m_nSamples_initial;
    long         m_interval_initial;
    long         m_nDiscard_initial;
    long         m_nChains_final;
    long         m_nSamples_final;
    long         m_interval_final;
    long         m_nDiscard_final;
    long         m_nreps;
    bool         m_bayesian;     // are we doing Bayesian or frequentist?
    bool         m_runprofilereps; // if true run additional replicates
    // to improve generation of
    // profile-likelihood boundaries
    // ignored if the run is bayesian

    bool ValidTemperatures() const;

    ChainParameters();                                      // undefined
    ChainParameters(const ChainParameters& src);            // undefined
    ChainParameters& operator=(const ChainParameters& src); // undefined

  protected:
    void SortAndNormalizeTemperatures();

  public:
    ChainParameters(
        DoubleVec1d temperatures,
        long        tempInterval,
        bool        tempAdapt,
        long        nChains_initial,
        long        nSamples_initial,
        long        interval_initial,
        long        nDiscard_initial,
        long        nChains_final,
        long        nSamples_final,
        long        interval_final,
        long        nDiscard_final,
        long        nreps,
        bool        bayesian,
        double      dropTiming,
        double      sizeTiming,
        double      hapTiming,
        double      probhapTiming,
        double      bayesTiming,
        double      locusTiming,
        double      zilchTiming,
        double      stairTiming,
        double      epochsizeTiming
        );
    ~ChainParameters();

    // Get Functions
    double GetArrangerTiming(const string& atype) const;
    ArrangerVec CloneArrangers() const;
    StringVec1d GetAllStringsForActiveArrangers() const;

    StringVec1d ToXML(unsigned long nspaces) const;

    long GetTempInterval()             const { return m_tempinterval; };
    bool GetTempAdapt()                const { return m_tempadapt; };
    double GetTemperature(long i)      const { return m_temperatures[i]; };
    DoubleVec1d GetAllTemperatures()   const { return m_temperatures; };
    long GetNChains(long i)            const;
    long GetNSamples(long i)           const;
    long GetInterval(long i)           const;
    long GetNDiscard(long i)           const;
    long GetNReps()                    const { return m_nreps; };
    bool IsBayesian()                  const { return m_bayesian; };
    // getter used by CollectionManger ctor
    long GetNAllChains()               const;
    bool RunProfileReps()              const;
    long GetNProfileReps(long nparams) const;
    long GetNRepsAndNProfileReps(long nparams)    const;

    // Validation
    bool IsValidChain()                const;

};

// This free function throws an exception of type data_error
// and containing the specified message.  It's meant only as
// a convenience.

void DoError(const string& what);

#endif // CHAINPARAMETERS_H

//____________________________________________________________________________________
