/*
Copyright (C) 2011 Diego Darriba, David Posada
This program 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.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package es.uvigo.darwin.jmodeltest.model;
import java.io.PushbackReader;
import java.io.Serializable;
import java.io.StringReader;
import pal.tree.ReadTree;
import pal.tree.Tree;
import pal.tree.TreeParseException;
import es.uvigo.darwin.jmodeltest.ModelTest;
import es.uvigo.darwin.jmodeltest.io.TextOutputStream;
public class Model implements Serializable {
private static final long serialVersionUID = 4173257281316945987L;
private String name, partition, treeString;
private Tree tree;
private int id;
private int K;
private int numTi;
private int numTv;
private int numGammaCat;
private boolean pF, pT, pR, pI, pG, pV;
private boolean isInAICinterval, isInAICcinterval, isInBICinterval,
isInDTinterval;
private double lnL;
/* Unconstrained LK */
private double unconstrainedLnL;
private double lnLIgnoringGaps;
/* statistical */
private double AIC, AICd, AICw, cumAICw, uAICd;
private double AICc, AICcd, AICcw, cumAICcw, uAICcd;
private double BIC, BICd, BICw, cumBICw, uBICd;
private double DT, DTd, DTw, cumDTw;
private double fA, fG, fC, fT, titv, kappa;
private double Ra, Rb, Rc, Rd, Re, Rf, pinv, shape;
private long computationTime;
public Model(int mid, String mname, String mpartition, int mparameters,
boolean mpF, boolean mpT, boolean mpV, boolean mpR, boolean mpI,
boolean mpG, int mTi, int mTv) {
id = mid;
name = mname;
partition = mpartition; // model substitution specification (e.g. GTR =
// 012345)
K = mparameters;
pF = mpF; // includes unequal base frequencies
pT = mpT; // includes ti/tv
pV = mpV; // only for phyml: includes a Ti/Tv, apart from R(x)
pR = mpR; // includes Rates R(x)
pI = mpI; // includes p-inv
pG = mpG; // includes gamma
numTi = mTi; // number of transition rates
numTv = mTv; // number of transversion rates
lnL = 0.0;
pinv = 0.0;
shape = ModelTest.INFINITY;
}
public Model(int mid, String mname, String mpartition, int mparameters) {
id = mid;
name = mname;
partition = mpartition; // model substitution specification (e.g. GTR =
// 012345)
K = mparameters;
pF = false; // includes unequal base frequencies
pT = false; // includes ti/tv
pV = false; // only for phyml: includes a Ti/Tv, apart from R(x)
pR = false; // includes Rates R(x)
pI = false; // includes p-inv
pG = false; // includes gamma
numTi = 0; // number of transition rates
numTv = 0; // number of transversion rates
lnL = 0.0;
pinv = 0.0;
shape = ModelTest.INFINITY;
}
/****************************
* print ************************************ * Print model components * *
************************************************************************/
public void print(TextOutputStream stream) {
stream.println(" Model = " + getName());
stream.println(" partition = " + getPartition());
if (getLnL() == 0) {
stream.println(" OPTIMIZATION FAILED!");
} else {
stream.printf(" -lnL = %.4f", getLnL());
stream.printf("\n K = %d", getK());
/*
* stream.printf ("\n optimized substitution parameters = %d",
* Model.freeParameters[id]); if (ModelTest.countBLasParameters ==
* true) stream.printf ("\n optimized branch lengths = %d",
* ModelTest.numBranches); if (ModelTest.optimizeMLTopology)
* stream.printf ("\n optimized topology = %d", 1);
*/
if (ispF()) {
stream.printf("\n freqA = %5.4f ", getfA());
stream.printf("\n freqC = %5.4f ", getfC());
stream.printf("\n freqG = %5.4f ", getfG());
stream.printf("\n freqT = %5.4f ", getfT());
}
if (ispT()) {
stream.printf("\n kappa = %.4f", getKappa());
stream.printf(" (ti/tv = %.4f)", getTitv());
}
if (ispR()) {
stream.printf("\n R(a) [AC] = %.4f", getRa());
stream.printf("\n R(b) [AG] = %.4f", getRb());
stream.printf("\n R(c) [AT] = %.4f", getRc());
stream.printf("\n R(d) [CG] = %.4f", getRd());
stream.printf("\n R(e) [CT] = %.4f", getRe());
stream.printf("\n R(f) [GT] = %.4f", 1.0);
}
if (ispI())
stream.printf("\n p-inv = %5.4f", getPinv());
if (ispG()) {
stream.printf("\n gamma shape = %6.4f", getShape());
}
stream.println(" ");
}
}
public String printForTesting() {
StringBuilder str = new StringBuilder();
str.append(getName() + " ");
str.append(ispF() ? (getfA() + " " + getfC() + " " + getfG() + " "
+ getfT() + " ") : ("NA NA NA NA "));
str.append(ispT() ? (getKappa() + " " + getTitv() + " ") : ("NA NA "));
str.append(ispR() ? (getRa() + " " + getRb() + " " + getRc() + " "
+ getRd() + " " + getRe() + " " + getRf() + " ")
: ("NA NA NA NA NA NA "));
str.append(ispI() ? (getPinv() + " ") : ("NA "));
str.append(ispG() ? (getShape() + " ") : ("NA "));
str.append(getPartition());
return str.toString();
}
public void setCumBICw(double cumBICw) {
this.cumBICw = cumBICw;
}
public double getCumBICw() {
return cumBICw;
}
public void setLnL(double lnL) {
this.lnL = lnL;
}
public double getLnL() {
return lnL;
}
public void setLnLIgnoringGaps(double lnLIgnoringGaps) {
this.lnLIgnoringGaps = lnLIgnoringGaps;
}
public double getLnLIgnoringGaps() {
return lnLIgnoringGaps;
}
public double getUnconstrainedLnL() {
return unconstrainedLnL;
}
public void setUnconstrainedLnL(double unconstrainedLnL) {
this.unconstrainedLnL = unconstrainedLnL;
}
public void setAIC(double aIC) {
AIC = aIC;
}
public double getAIC() {
return AIC;
}
public void setAICd(double aICd) {
AICd = aICd;
}
public double getAICd() {
return AICd;
}
public void setAICw(double aICw) {
AICw = aICw;
}
public double getAICw() {
return AICw;
}
public void setUAICd(double uAICd) {
this.uAICd = uAICd;
}
public double getUAICd() {
return uAICd;
}
public void setCumAICw(double cumAICw) {
this.cumAICw = cumAICw;
}
public double getCumAICw() {
return cumAICw;
}
public void setAICc(double aICc) {
AICc = aICc;
}
public double getAICc() {
return AICc;
}
public void setAICcd(double aICcd) {
AICcd = aICcd;
}
public double getAICcd() {
return AICcd;
}
public void setAICcw(double aICcw) {
AICcw = aICcw;
}
public double getAICcw() {
return AICcw;
}
public void setCumAICcw(double cumAICcw) {
this.cumAICcw = cumAICcw;
}
public void setUAICcd(double uAICcd) {
this.uAICcd = uAICcd;
}
public double getUAICcd() {
return uAICcd;
}
public double getCumAICcw() {
return cumAICcw;
}
public void setBICd(double bICd) {
BICd = bICd;
}
public double getBICd() {
return BICd;
}
public void setBIC(double bIC) {
BIC = bIC;
}
public double getBIC() {
return BIC;
}
public void setBICw(double bICw) {
BICw = bICw;
}
public double getBICw() {
return BICw;
}
public void setUBICd(double uBICd) {
this.uBICd = uBICd;
}
public double getUBICd() {
return uBICd;
}
public void setDT(double dT) {
DT = dT;
}
public double getDT() {
return DT;
}
public void setCumDTw(double cumDTw) {
this.cumDTw = cumDTw;
}
public double getCumDTw() {
return cumDTw;
}
public void setDTw(double dTw) {
DTw = dTw;
}
public double getDTw() {
return DTw;
}
public void setDTd(double dTd) {
DTd = dTd;
}
public double getDTd() {
return DTd;
}
public String getName() {
return name;
}
public void setPartition(String partition) {
this.partition = partition;
}
public String getPartition() {
return partition;
}
public Tree getTree() {
return tree;
}
public void setTreeString(String tree) throws TreeParseException {
this.treeString = tree;
if (tree == null)
throw new TreeParseException("Attempting to set a null tree");
StringReader sr = new StringReader(tree);
this.tree = new ReadTree(new PushbackReader(sr));
}
public String getTreeString() {
return treeString;
}
public void setfG(double fG) {
this.fG = fG;
}
public double getfG() {
return fG;
}
public void setfA(double fA) {
this.fA = fA;
}
public double getfA() {
return fA;
}
public void setfC(double fC) {
this.fC = fC;
}
public double getfC() {
return fC;
}
public void setfT(double fT) {
this.fT = fT;
}
public double getfT() {
return fT;
}
public void setTitv(double titv) {
this.titv = titv;
}
public double getTitv() {
return titv;
}
public void setKappa(double kappa) {
this.kappa = kappa;
}
public double getKappa() {
return kappa;
}
public void setRa(double ra) {
Ra = ra;
}
public double getRa() {
return Ra;
}
public void setShape(double shape) {
this.shape = shape;
}
public double getShape() {
return shape;
}
public void setPinv(double pinv) {
this.pinv = pinv;
}
public double getPinv() {
return pinv;
}
public void setRf(double rf) {
Rf = rf;
}
public double getRf() {
return Rf;
}
public void setRe(double re) {
Re = re;
}
public double getRe() {
return Re;
}
public void setRd(double rd) {
Rd = rd;
}
public double getRd() {
return Rd;
}
public void setRc(double rc) {
Rc = rc;
}
public double getRc() {
return Rc;
}
public void setRb(double rb) {
Rb = rb;
}
public double getRb() {
return Rb;
}
public int getId() {
return id;
}
public void setNumGammaCat(int numGammaCat) {
this.numGammaCat = numGammaCat;
}
public int getNumGammaCat() {
return numGammaCat;
}
public int getK() {
return K;
}
public int getNumTi() {
return numTi;
}
public boolean ispV() {
return pV;
}
public boolean ispG() {
return pG;
}
public boolean ispI() {
return pI;
}
public boolean ispR() {
return pR;
}
public boolean ispT() {
return pT;
}
public boolean ispF() {
return pF;
}
public void setInDTinterval(boolean isInDTinterval) {
this.isInDTinterval = isInDTinterval;
}
public boolean isInDTinterval() {
return isInDTinterval;
}
public void setInBICinterval(boolean isInBICinterval) {
this.isInBICinterval = isInBICinterval;
}
public boolean isInBICinterval() {
return isInBICinterval;
}
public void setInAICcinterval(boolean isInAICcinterval) {
this.isInAICcinterval = isInAICcinterval;
}
public boolean isInAICcinterval() {
return isInAICcinterval;
}
public void setInAICinterval(boolean isInAICinterval) {
this.isInAICinterval = isInAICinterval;
}
public boolean isInAICinterval() {
return isInAICinterval;
}
public int getNumTv() {
return numTv;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (pF ? 1231 : 1237);
result = prime * result + (pG ? 1231 : 1237);
result = prime * result + (pI ? 1231 : 1237);
result = prime * result
+ ((partition == null) ? 0 : partition.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Model other = (Model) obj;
if (pF != other.pF)
return false;
if (pG != other.pG)
return false;
if (pI != other.pI)
return false;
if (partition == null) {
if (other.partition != null)
return false;
} else if (!partition.equals(other.partition))
return false;
return true;
}
public long getComputationTime() {
return computationTime;
}
public void setComputationTime(long computationTime) {
this.computationTime = computationTime;
}
public void update(Model model) {
if (this.equals(model)) {
lnL = model.lnL;
numGammaCat = model.numGammaCat;
shape = model.shape;
pinv = model.pinv;
kappa = model.kappa;
treeString = model.treeString;
tree = model.tree;
computationTime = model.computationTime;
}
}
} // class Model