// $Id: tempident.h,v 1.18 2018/01/03 21:33:04 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 */


/*******************************************************************
  TemperatureIdentity contains the temperature-dependent parts of
  a Chain; having this as a separate object facilitates swapping two
  Chains by swapping their TemperatureIdentities.  (This is easier
  than swapping their Trees because too many sub-objects hold pointers
  into the Tree.)

  Written by Mary Kuhner 3/24/04
********************************************************************/

#ifndef TEMPIDENT_H
#define TEMPIDENT_H

#include <string>
#include "chainout.h"

class Tree;
class CollectionManager;
class ChainState;

class TemperatureIdentity
{
  private:
    // variables to manage sampling
    bool m_iscold;                      // is this the cold chain?
    long m_naccepted;                   // how many accepted samples so far?
    long m_badtrees;                    // how many trees exceeding MAXEVENTS?
    long m_tinypoptrees;                // how many trees with too small populations?
    long m_zerodltrees;                 // how many trees with zero data likelihood?
    long m_stretchedtrees;              // how many trees with too long branches

    // variables to manage heating
    double m_temperature;               // MCMCMC "temperature" for heating

    // variables to manage temperature swapping (adaptive heating)
    long m_swapsmade;                   // how many swaps since last temperature change??
    long m_swapstried;                  // how many attempted since last change?
    long m_totalswapsmade;              // how many swaps this chain?
    long m_totalswapstried;             // how many attempted this chain?
    long m_averagetemp;                 // summation of temperatures visited

    // variables to manage recordkeeping
    long m_totaltrees;                  // how many trees seen?
    ratemap m_acceptances;              // per-arranger acceptance rates
    ChainOut m_chainout;                // summary of chain success
    void   ClearAcceptances();

  public:
    TemperatureIdentity(double temperature, StringVec1d arrstrings);

    // We accept defaults for copy ctor, operator=, and dtor

    void SetTemperature(double temperature);
    void ClearSwaps() { m_swapstried = 0; m_swapsmade = 0; };
    void ClearTotalSwaps() { ClearSwaps(); m_totalswapstried=0; m_totalswapsmade=0; };
    void SwapTried() { ++m_swapstried; ++m_totalswapstried; };

    double GetTemperature()             const { return m_temperature; };
    double GetSwapRate()                const;
    double GetTotalSwapRate()           const;
    bool  IsCold()                      const { return m_iscold; };

    void  StartChain();
    ChainOut& EndChain();
    void  NoteBadTree() { ++m_badtrees; };
    void  NoteTinyPopTree() {++m_tinypoptrees; };
    void  NoteStretchedTree() {++m_stretchedtrees; };
    void  NoteZeroDLTree() {++m_zerodltrees; };
    void  ScoreRearrangement(const std::string & arrangername, bool accepted);
    void  Sample(CollectionManager& collmanager, ChainState & chstate, long initialOrFinal, bool lastchain);
    void  NoteSwap(TemperatureIdentity& hot, ChainState & hotstate, ChainState & coldstate);

};

#endif // TEMPIDENT_H

//____________________________________________________________________________________
