/*
* TransformParsers.java
*
* Copyright (c) 2002-2017 Alexei Drummond, Andrew Rambaut and Marc Suchard
*
* This file is part of BEAST.
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership and licensing.
*
* BEAST is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* BEAST 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with BEAST; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
package dr.util;
import dr.inference.model.Parameter;
import dr.xml.*;
import java.util.ArrayList;
import java.util.List;
/**
* @author Marc A. Suchard
*/
public class TransformParsers {
public static XMLObjectParser COMPOUND_PARSER = new AbstractXMLObjectParser() {
@Override
public Object parseXMLObject(XMLObject xo) throws XMLParseException {
// return new
Parameter parameter = (Parameter) xo.getChild(Parameter.class);
Transform transform = new Transform.Collection(xo.getAllChildren(Transform.ParsedTransform.class),
parameter);
return transform;
}
@Override
public XMLSyntaxRule[] getSyntaxRules() {
return new XMLSyntaxRule[] {
new ElementRule(Transform.ParsedTransform.class, 1, Integer.MAX_VALUE),
new ElementRule(Parameter.class),
};
}
@Override
public String getParserDescription() {
return null;
}
@Override
public Class getReturnType() {
return Transform.Collection.class;
}
@Override
public String getParserName() {
return COMPOUND;
}
};
public static XMLObjectParser COMPOSE_PARSER = new AbstractXMLObjectParser() {
@Override
public Object parseXMLObject(XMLObject xo) throws XMLParseException {
XMLObject outerXo = xo.getChild(OUTER);
XMLObject innerXo = xo.getChild(INNER);
Transform.ParsedTransform outerPT = (Transform.ParsedTransform)
outerXo.getChild(Transform.ParsedTransform.class);
Transform.ParsedTransform innerPT = (Transform.ParsedTransform)
innerXo.getChild(Transform.ParsedTransform.class);
if (!outerPT.equivalent(innerPT)) {
throw new XMLParseException("Not equivalent transformations");
}
if (outerPT.transform instanceof Transform.UnivariableTransform &&
innerPT.transform instanceof Transform.UnivariableTransform) {
Transform.ParsedTransform composition = outerPT.clone();
composition.transform = new Transform.Compose((Transform.UnivariableTransform) outerPT.transform,
(Transform.UnivariableTransform) innerPT.transform);
return composition;
} else {
throw new XMLParseException("Not composable transform types");
}
}
@Override
public XMLSyntaxRule[] getSyntaxRules() {
return new XMLSyntaxRule[] {
new ElementRule(OUTER, new XMLSyntaxRule[] {
new ElementRule(Transform.ParsedTransform.class),
}),
new ElementRule(INNER, new XMLSyntaxRule[] {
new ElementRule(Transform.ParsedTransform.class),
}),
};
}
@Override
public String getParserDescription() {
return null;
}
@Override
public Class getReturnType() {
return Transform.ParsedTransform.class;
}
@Override
public String getParserName() {
return COMPOSE;
}
};
public static XMLObjectParser INVERSE_PARSER = new AbstractXMLObjectParser() {
@Override
public Object parseXMLObject(XMLObject xo) throws XMLParseException {
Transform.ParsedTransform parsedTransform = (Transform.ParsedTransform)
xo.getChild(Transform.ParsedTransform.class);
Transform xform = parsedTransform.transform;
if (xform instanceof Transform.UnivariableTransform) {
Transform.ParsedTransform inverseTransform = parsedTransform.clone();
inverseTransform.transform = new Transform.Inverse((Transform.UnivariableTransform)
parsedTransform.transform);
return inverseTransform;
} else {
throw new XMLParseException("Not invertible transform type");
}
}
@Override
public XMLSyntaxRule[] getSyntaxRules() {
return new XMLSyntaxRule[] {
new ElementRule(Transform.ParsedTransform.class),
};
}
@Override
public String getParserDescription() {
return null;
}
@Override
public Class getReturnType() {
return Transform.ParsedTransform.class;
}
@Override
public String getParserName() {
return INVERSE;
}
};
public static XMLObjectParser TRANSFORM_PARSER = new AbstractXMLObjectParser() {
public Object parseXMLObject(XMLObject xo) throws XMLParseException {
Transform thisTransform = Transform.NONE;
String name = (String) xo.getAttribute(TYPE);
System.err.println("name: " + name);
thisTransform = null;
for (Transform.Type type: Transform.Type.values()) {
if (name.equalsIgnoreCase(type.getName())) {
thisTransform = type.getTransform();
}
}
if (thisTransform == null) {
throw new XMLParseException("Unrecognized transform type, " + name);
}
if (xo.getAttribute(INVERSE, false)) {
if (thisTransform instanceof Transform.UnivariableTransform) {
thisTransform = new Transform.Inverse((Transform.UnivariableTransform)thisTransform);
} else {
throw new XMLParseException("Non-invertible transform type, " + name);
}
}
Transform.ParsedTransform transform = new Transform.ParsedTransform();
transform.transform = thisTransform;
if (xo.hasAttribute(START)) {
transform.start = xo.getIntegerAttribute(START);
transform.end = xo.getAttribute(END, Integer.MAX_VALUE);
transform.every = xo.getAttribute(EVERY, 1);
// todo: check values are valid
transform.start--; // zero-indexed
} else {
transform.parameters = new ArrayList<Parameter>();
for (Parameter param : xo.getAllChildren(Parameter.class)) {
transform.parameters.add(param);
}
}
return transform;
}
public XMLSyntaxRule[] getSyntaxRules() {
return new XMLSyntaxRule[]{
AttributeRule.newStringRule(TYPE),
AttributeRule.newIntegerRule(START, true),
AttributeRule.newIntegerRule(END, true),
AttributeRule.newIntegerRule(EVERY, true),
AttributeRule.newBooleanRule(INVERSE, true),
new ElementRule(Transform.ParsedTransform.class, 0, 1),
new ElementRule(Parameter.class, 0, Integer.MAX_VALUE)
};
}
public String getParserDescription() {
return null;
}
public Class getReturnType() {
return Transform.ParsedTransform.class;
}
public String getParserName() {
return TRANSFORM;
}
};
public static final String TRANSFORM = "transform";
public static final String TYPE = "type";
public static final String START = "start";
public static final String END = "end";
public static final String EVERY = "every";
public static final String INVERSE = "inverseTransform";
public static final String COMPOSE = "composedTransform";
public static final String OUTER = "outer";
public static final String INNER = "inner";
public static final String COMPOUND = "compoundTransform";
}