// $Id: constants.h,v 1.109 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 */


#ifndef CONSTANTS_H
#define CONSTANTS_H

#include <string>

// Defines various symbols used to control debugging of experimental code blocks.
#include "local_build.h"

#include "definitions.h"

using std::string;

/***************************************************************
  This file contains constants which control the behavior of
the program.  They are divided into sections:

(1)  Constants which the user may wish to change, in order
     to adapt the program to his/her needs
(2)  Debugging constants which the user should probably not
     change unless sure of his/her reasons
(3)  Internal constants which should not be changed at all
(4)  The tag library (relating tags to literals) which should
     not be changed except to translate the program to a
     different language

If you change anything in this file you must 'make clean' the
entire project.  Unix Make utilities may not think you need to
go so far; but they lie.

****************************************************************/

class Registry;

extern Registry registry;

//------------------------------------------------------------------------------------
//  User-changable constants
//------------------------------------------------------------------------------------

// Only for Metrowerks compiles, see Makefile for other platforms
// If you do not want to use the menu at all, set this constant
// to 0.  The program will then read from 'infile' and
// write to 'outfile' and no menu will be displayed.  Be sure
// that all necessary information is present in 'infile' if
// you use this option.
#ifdef __MWERKS__
#define MENU 1
#endif

// Enumerations
enum verbosity_type {CONCISE, NORMAL, VERBOSE, NONE};
enum paramlistcondition { paramlist_YES, paramlist_MIX, paramlist_NO };
enum likelihoodtype { ltype_ssingle, ltype_replicate, ltype_region,
                      ltype_gammaregion };
enum proftype { profile_PERCENTILE, profile_FIX, profile_NONE };
enum noval {noval_none}; //used when I need a null instantiation for a template

// if you edit model_type, also edit numPossibleDataModels and allDataModels()
// in defaults.cpp
enum model_type {F84,Brownian,Stepwise,KAllele,GTR,MixedKS};
enum method_type {method_PROGRAMDEFAULT, method_USER, method_FST, method_WATTERSON};
enum priortype {LINEAR, LOGARITHMIC};
enum pstatus { pstat_invalid, pstat_unconstrained, pstat_constant, pstat_identical, pstat_identical_head,
               pstat_multiplicative, pstat_multiplicative_head };
/* Invalid--nonexistant parameter such as diagonal migration value
   Unconstrained--ordinary parameter
   Constant--constrained to constant value
   Identical_head--first member of group constrained to be identical (in ParamVec order)
   Identical--any other member of group constrained to be identical
   Multiplicative_head--first member of multiplicative group
   Multiplicative--any other member of multiplicative group
   Epochtime--boundary time of an epoch (handled specially because can't be Bayes-arranged)
*/
/* Deleted (for now?) pstatus values:  valid, symmetricNm, symmetricM
   (use 'mean' instead of symmetricM, 'standard' instead of valid, and don't
   use symmetricNm unless we allow our general migration model to vary based
   on population size.
*/

enum growth_type {growth_CURVE, growth_STICK, growth_STICKEXP};
enum growth_scheme {growth_EXP, growth_STAIRSTEP};
enum selection_type {selection_DETERMINISTIC, selection_STOCHASTIC};

// for marking study samples vs panel sources
enum data_source {dsource_study, dsource_panel };

enum force_type { force_COAL, force_MIG, force_DISEASE, force_REC,
                  force_GROW, force_REGION_GAMMA, force_EXPGROWSTICK,
                  force_LOGISTICSELECTION, force_LOGSELECTSTICK, force_DIVERGENCE,
                  force_DIVMIG, force_NONE };

// Query functions for force_type
bool IsMigrationLike(force_type f);
bool IsLocalPartForce(force_type f); 

//---------------------------------------------------------------
// Debugging constants
// (you had better know what you are doing before changing any of
// these)
//---------------------------------------------------------------

// When STATIONARIES is defined, the program will run without use of
// data, producing a report of the stationary distribution of the sampler
// This is a useful debugging tool and can also be used to obtain
// stationaries of otherwise difficult distributions via Monte Carlo.
// NEVER turn this on if you mean to analyze your data--it will
// cause the data to be totally ignored!
#ifdef STATIONARIES
const string INTERVALFILE = "interval.out";
const string MIGFILE = "migcount";
const string DISFILE = "discount";
const string RECFILE = "reccount";
const string SELECTFILE = "selectstuff";
const string EPOCHFILE = "epochtimes";
#endif // STATIONARIES

#ifdef LAMARC_QA_SINGLE_DENOVOS
// When LAMARC_QA_SINGLE_DENOVOS is defined, the program generates
// a slew of denovo trees and calculates the likely parameter
// values of each separately. See lamarc/config/local_build.h
// for more info
const std::string SINGLE_DENOVO_INFO = "denovo_info.txt";
const std::string SINGLE_DENOVO_FILE = "denovo_params.txt";
#endif // LAMARC_QA_SINGLE_DENOVOS

// When true, track data likelihoods into file 'like1'
#define LIKETRACK 0

//---------------------------------------------------------------
//  Internal program constants
//  (you had better know *exactly* what you are doing if you
//  change any of these--the program may not survive)
//---------------------------------------------------------------

const double MAX_LENGTH = 200.0;     // maximum branch length
                                     // this must be less than
                                     // DBL_MAX because of use in
                                     // Active/InactiveStairStickCoal
                                     // events.

const long BASES = 4;                // number of nucleotides
const long baseA = 0;                // codes for nucleotides
const long baseC = 1;
const long baseG = 2;
const long baseT = 3;
const long baseEnd = 4;              // allows one-past-the-end use

const int  INVARIANTS   = 4;         // possible invariant sites
const std::string SINGLEBASES[INVARIANTS] = {"A","C","G","T"};

const long markerCell     = 0;       // indicates a marker dlcell
const long invariantCell  = 1;       // indicates a invariant dlcell

const long FLAGLONG     = -99;       // arbitrary flag values
const double FLAGDOUBLE = -99.0;
const long FLAGINVAR    = -999;

const double DF         = 2.0;       // degrees of freedom for
                                     // likelihood ratio test
const long NCHAINTYPES = 2;          // how many kinds of chains?
const long IDSIZE = 2;               // size of branch ID number
const long NELEM = 2;                // allowed parents or children
                                     // of a branch

const long XML_RANDOM_NAME_LENGTH   = 100000;

// The following should be provided by the compiler, but
// we have found this to be unportable, so we define them
// ourselves.

const double NEG_MAX = -999999999.9; // the smallest reasonable double

//------------------------------------------------------------------------------------
// Registry of constant string tags
// (you might wish to change these if changing language)
//------------------------------------------------------------------------------------

const unsigned long INDENT_DEPTH = 2;  // output of input xml indentation depth

// The precision of the numbers written to the summary output file.
// NOTE:  When writing tree summaries with growth, the precision *must*
// be at least as large as the minimum timestep allowable.
const int SUMFILE_PRECISION = 18;

class lamarccodes
{
  public:
    static const int cleanReturn;
    static const int badAllocation;
    static const int fileError;
    static const int optionError;
    static const int denovoCompileError;
    static const int unknownError;
};

class lamarcstrings
{
  public:
    static const std::string COAL       ;
    static const std::string MIG        ;
    static const std::string DISEASE    ;
    static const std::string REC        ;
    static const std::string GROW       ;
    static const std::string LOGISTICSELECTION;
    static const std::string DIVERGENCE ;
    static const std::string DIVMIG     ;

    static const std::string REGION_GAMMA;
    static const std::string INVALID    ;
    static const std::string STICK      ;
    static const std::string TIP        ;
    static const std::string BASE       ;
    static const std::string SNP        ;
    static const std::string DNA        ;
    static const std::string NUC        ;
    static const std::string MICROSAT   ;
    static const std::string EXPGROWSTICK;
    static const std::string LOGSELECTSTICK;

    static const std::string PANEL;
    static const std::string STUDY;
    static const std::string EMPTY;

    static const std::string F84;
    static const std::string GTR;
    static const std::string STEPWISE;
    static const std::string BROWNIAN;
    static const std::string KALLELE;
    static const std::string MIXEDKS;

    static const std::string ELECTRO    ;

    static const std::string longNameUSER;
    static const std::string longNamePROGRAMDEFAULT;
    static const std::string longNameFST;
    static const std::string longNameWATTERSON;

    static const std::string shortNameUSER;
    static const std::string shortNamePROGRAMDEFAULT;
    static const std::string shortNameFST;
    static const std::string shortNameWATTERSON;

    static const std::string longBrownianName;
    static const std::string longF84Name;
    static const std::string longGTRName;
    static const std::string longKAlleleName;
    static const std::string longStepwiseName;
    static const std::string longMixedKSName;

    static const std::string shortBrownianName;
    static const std::string shortF84Name;
    static const std::string shortGTRName;
    static const std::string shortKAlleleName;
    static const std::string shortStepwiseName;
    static const std::string shortMixedKSName;

    static const std::string longCurveName;
    static const std::string longStickExpName;
    static const std::string longStickName;
    static const std::string shortCurveName;
    static const std::string shortStickExpName;
    static const std::string shortStickName;

    static const std::string longExpName;
    static const std::string longStairStepName;
    static const std::string shortExpName;
    static const std::string shortStairStepName;

    static const std::string longDSelectionName;
    static const std::string longSSelectionName;
    static const std::string shortDSelectionName;
    static const std::string shortSSelectionName;
};

#endif // CONSTANTS_H

//____________________________________________________________________________________
