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


// Collector classes store information from the ongoing chain for
// later analysis.  They are related via a base class for convenience
// in initialization, but mostly used via pointer-to-derived because
// they summarize such different information.

// Mary 2003/12/17

#ifndef COLLECTOR_H
#define COLLECTOR_H

#include <fstream>
#include <utility>                      // for pair
#include <vector>
#include "chainstate.h"
#include "tree.h"
#include "vectorx.h"
#include "mathx.h"

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

typedef std::vector<std::pair<ForceParameters,long> > ParamSumm;
typedef std::vector<std::pair<std::vector<double>,long> > StickSumm;

class ArrangerVec;

//------------------------------------------------------------------------------------
// Abstract base class for all Collectors
//------------------------------------------------------------------------------------

class Collector
{
  public:
    Collector();
    virtual ~Collector() {};
    virtual void Score(ChainState& chstate) = 0;
    virtual void CorrectForFatalAttraction(long) { };
    virtual void UpdateArrangers(ArrangerVec&, ChainState&) const { };
    virtual void WriteCollectionWhenScore(std::ofstream* out);
    virtual void WriteLastSummary() = 0;
    virtual void WriteAllSummaries(std::ofstream& out) = 0;

  private:
    // This class is not meant to be copied
    Collector(const Collector&);  // not defined
    Collector& operator=(const Collector&);  // not defined

  protected:
    bool m_areWriting;
    std::ofstream *m_sumout; //non-owning pointer
};

//------------------------------------------------------------------------------------
// Tree summary collector, also includes jointed stick (if any)
//------------------------------------------------------------------------------------

class TreeCollector : public Collector
{
  public:
    TreeCollector(); //Can't be default because of ForceParameters object.
    virtual ~TreeCollector();
    // these two are used directly by postlike routines
    vector<TreeSummary*> treeSummaries;  // public for speed of access
    ForceParameters forceParameters;     // public for speed of access

    virtual void Score(ChainState& chstate);
    virtual void WriteLastSummary();
    virtual void WriteAllSummaries(std::ofstream& out);
    virtual void CorrectForFatalAttraction(long region);
    virtual void AddTreeSummary(TreeSummary* ts);
    void SetStartParameters(const ForceParameters& src)
    { forceParameters = src; };
    long TreeCount() const;

  private:
    bool m_findbesttree;
    double m_besttreedatallike;
};

//------------------------------------------------------------------------------------
// Parameter summary collectors
//------------------------------------------------------------------------------------

class ParamCollector : public Collector
{
  public:
    virtual void Score(ChainState& chstate);
    virtual void AddParamSummary(ForceParameters fp, long ncopy);
    virtual void WriteLastSummary();
    virtual void WriteAllSummaries(std::ofstream& out);
    virtual void UpdateArrangers(ArrangerVec& arrangers, ChainState& chstate) const;
    const ParamSumm& GetParamSumm() const { return m_paramsum; }
    const DoubleVec1d GetLastParameterVec() const;

  private:
    ParamSumm m_paramsum;
    virtual void WriteParamSumm(unsigned long index);
};

//------------------------------------------------------------------------------------
// Map summary collector
//------------------------------------------------------------------------------------

class MapCollector : public Collector
{
  public:
    MapCollector(long region);
    virtual bool DoWeCollectFor(bool lastchain);
    virtual void Score(ChainState& chstate);
    virtual void AddMapSummary(DoubleVec2d& maplikes, long ncopy);
    virtual void WriteLastSummary();
    virtual void WriteAllSummaries(std::ofstream& out);
    virtual DoubleVec2d GetMapSummary();

  private:
    MapCollector(); //undefined
    long m_region;
    long m_nsamples;
    DoubleVec2d m_mapsum;     //Never logs!
    DoubleVec2d m_lastmapsum; //Logs if we're 'floating', 0's and a 1 if 'jumping'
    long m_lastcount;

    virtual void WriteVec1D(std::ofstream& sumout, DoubleVec1d& vec, rangeset range);
    virtual void AccumulateMap();
};

#endif // COLLECTOR_H

//____________________________________________________________________________________
