use of beast.core.BEASTInterface in project beast2 by CompEvol.
the class XMLParser method parseTemplate.
// parseFile
/**
* extract all elements (runnable or not) from an XML fragment.
* Useful for retrieving all non-runnable elements when a template
* is instantiated by Beauti
* @throws ParserConfigurationException
* @throws IOException
* @throws SAXException *
*/
public List<BEASTInterface> parseTemplate(final String xml, final HashMap<String, BEASTInterface> idMap, final boolean initialise) throws XMLParserException, SAXException, IOException, ParserConfigurationException {
needsInitialisation = initialise;
// parse the XML file into a DOM document
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// factory.setValidating(true);
doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
doc.normalize();
processPlates(doc, PLATE_ELEMENT);
// XMLParserUtils.saveDocAsXML(doc, "/tmp/beast2.xml");
// new HashMap<>();
IDMap = idMap;
likelihoodMap = new HashMap<>();
IDNodeMap = new HashMap<>();
final List<BEASTInterface> beastObjects = new ArrayList<>();
// find top level beast element
final NodeList nodes = doc.getElementsByTagName("*");
if (nodes == null || nodes.getLength() == 0) {
throw new XMLParserException("Expected top level beast element in XML");
}
final Node topNode = nodes.item(0);
// sanity check that we are reading a beast 2 file
final double version = getAttributeAsDouble(topNode, "version");
if (!topNode.getNodeName().equals(BEAST_ELEMENT) || version < 2.0 || version == Double.MAX_VALUE) {
return beastObjects;
}
// only process templates
// String typeName = getAttribute(topNode, "type");
// if (typeName == null || !typeName.equals("template")) {
// return beastObjects;
// }
// sanity check that required packages are installed
initIDNodeMap(topNode);
parseNameSpaceAndMap(topNode);
final NodeList children = topNode.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
if (children.item(i).getNodeType() == Node.ELEMENT_NODE) {
final Node child = children.item(i);
Log.warning.println(child.getNodeName());
if (!child.getNodeName().equals(MAP_ELEMENT)) {
beastObjects.add(createObject(child, BEAST_INTERFACE_CLASS));
}
}
}
initBEASTObjects();
return beastObjects;
}
use of beast.core.BEASTInterface in project beast2 by CompEvol.
the class XMLParser method parseFragment.
/**
* Parse an XML fragment representing a Plug-in
* Only the run element or if that does not exist the last child element of
* the top level <beast> element is considered.
* @throws XMLParserException
*/
public BEASTInterface parseFragment(final String xml, final boolean initialise) throws XMLParserException {
needsInitialisation = initialise;
// parse the XML fragment into a DOM document
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
} catch (SAXException | IOException | ParserConfigurationException e) {
throw new RuntimeException(e);
}
doc.normalize();
processPlates(doc, PLATE_ELEMENT);
IDMap = new HashMap<>();
likelihoodMap = new HashMap<>();
IDNodeMap = new HashMap<>();
// find top level beast element
final NodeList nodes = doc.getElementsByTagName("*");
if (nodes == null || nodes.getLength() == 0) {
throw new XMLParserException("Expected top level beast element in XML");
}
final Node topNode = nodes.item(0);
initIDNodeMap(topNode);
parseNameSpaceAndMap(topNode);
final NodeList children = topNode.getChildNodes();
if (children.getLength() == 0) {
throw new XMLParserException("Need at least one child element");
}
int i = children.getLength() - 1;
while (i >= 0 && (children.item(i).getNodeType() != Node.ELEMENT_NODE || !children.item(i).getNodeName().equals("run"))) {
i--;
}
if (i < 0) {
i = children.getLength() - 1;
while (i >= 0 && children.item(i).getNodeType() != Node.ELEMENT_NODE) {
i--;
}
}
if (i < 0) {
throw new XMLParserException("Need at least one child element");
}
final BEASTInterface beastObject = createObject(children.item(i), BEAST_INTERFACE_CLASS);
initBEASTObjects();
return beastObject;
}
use of beast.core.BEASTInterface in project beast2 by CompEvol.
the class XMLParser method parseInputs.
private List<NameValuePair> parseInputs(Node node, String clazzName) throws XMLParserException {
List<NameValuePair> inputInfo = new ArrayList<>();
// first, process attributes
NamedNodeMap atts = node.getAttributes();
if (atts != null) {
for (int i = 0; i < atts.getLength(); i++) {
final String name = atts.item(i).getNodeName();
if (!(name.equals("id") || name.equals("idref") || name.equals("spec") || name.equals("name"))) {
final String value = atts.item(i).getNodeValue();
if (value.startsWith("@")) {
final String idRef = value.substring(1);
final Element element = doc.createElement("input");
element.setAttribute("idref", idRef);
// add child in case things go belly up, and an XMLParserException is thrown
node.appendChild(element);
final BEASTInterface beastObject = createObject(element, BEAST_INTERFACE_CLASS);
// it is save to remove the element now
node.removeChild(element);
inputInfo.add(new NameValuePair(name, beastObject));
} else {
inputInfo.add(new NameValuePair(name, value));
}
}
}
}
// process element nodes
final NodeList children = node.getChildNodes();
int childElements = 0;
String text = "";
for (int i = 0; i < children.getLength(); i++) {
final Node child = children.item(i);
if (child.getNodeType() == Node.ELEMENT_NODE) {
final String element = child.getNodeName();
// resolve name of the input
String name = getAttribute(child, "name");
if (name == null) {
name = element;
}
// resolve base class
String specClass = BEAST_INTERFACE_CLASS;
if (element2ClassMap.containsKey(element)) {
specClass = element2ClassMap.get(element);
}
final String spec = getAttribute(child, "spec");
if (spec != null) {
specClass = spec;
}
String classname = null;
// determine clazzName from specName, taking name spaces in account
classname = resolveClass(specClass);
if (classname == null) {
classname = specClass;
}
// test for special cases: <xyz>value</xyz> and <input name="xyz">value</input>
// where value is a string
boolean done = false;
atts = child.getAttributes();
if (atts.getLength() == 0 || (element.equals("input") && atts.getLength() == 1 && name != null)) {
NodeList grantchildren = child.getChildNodes();
boolean hasElements = false;
for (int j = 0; j < grantchildren.getLength(); j++) {
if (grantchildren.item(j).getNodeType() == Node.ELEMENT_NODE) {
hasElements = true;
break;
}
}
if (!hasElements) {
String content = child.getTextContent();
inputInfo.add(new NameValuePair(name, content));
done = true;
}
}
// create object from element, if not already done so
if (!done) {
final BEASTInterface childItem = createObject(child, classname);
if (childItem != null) {
inputInfo.add(new NameValuePair(name, childItem));
}
}
childElements++;
} else if (child.getNodeType() == Node.CDATA_SECTION_NODE || child.getNodeType() == Node.TEXT_NODE) {
text += child.getTextContent();
}
}
if (!text.matches("\\s*")) {
inputInfo.add(new NameValuePair("value", text));
}
if (childElements == 0) {
final String content = node.getTextContent();
if (content != null && content.length() > 0 && content.replaceAll("\\s", "").length() > 0) {
try {
inputInfo.add(new NameValuePair("value", content));
} catch (Exception e) {
//
}
}
}
return inputInfo;
}
use of beast.core.BEASTInterface in project beast2 by CompEvol.
the class RandomTree method initStateNodes.
// taxonset intersection test
// private boolean intersects(final BitSet bitSet, final BitSet bitSet2) {
// for (int k = bitSet.nextSetBit(0); k >= 0; k = bitSet.nextSetBit(k + 1)) {
// if (bitSet2.get(k)) {
// return true;
// }
// }
// return false;
// }
// returns true if bitSet is a subset of bitSet2
// private boolean isSubset(final BitSet bitSet, final BitSet bitSet2) {
// boolean isSubset = true;
// for (int k = bitSet.nextSetBit(0); isSubset && k >= 0; k = bitSet.nextSetBit(k + 1)) {
// isSubset = bitSet2.get(k);
// }
// return isSubset;
// }
@SuppressWarnings("unchecked")
@Override
public void initStateNodes() {
// find taxon sets we are dealing with
taxonSets = new ArrayList<>();
m_bounds = new ArrayList<>();
distributions = new ArrayList<>();
taxonSetIDs = new ArrayList<>();
lastMonophyletic = 0;
if (taxaInput.get() != null) {
taxa.addAll(taxaInput.get().getTaxaNames());
} else {
taxa.addAll(m_taxonset.get().asStringList());
}
// pick up constraints from outputs, m_inititial input tree and output tree, if any
List<MRCAPrior> calibrations = new ArrayList<>();
calibrations.addAll(calibrationsInput.get());
// pick up constraints in m_initial tree
for (final Object beastObject : getOutputs()) {
if (beastObject instanceof MRCAPrior && !calibrations.contains(beastObject)) {
calibrations.add((MRCAPrior) beastObject);
}
}
if (m_initial.get() != null) {
for (final Object beastObject : m_initial.get().getOutputs()) {
if (beastObject instanceof MRCAPrior && !calibrations.contains(beastObject)) {
calibrations.add((MRCAPrior) beastObject);
}
}
}
for (final MRCAPrior prior : calibrations) {
final TaxonSet taxonSet = prior.taxonsetInput.get();
if (taxonSet != null && !prior.onlyUseTipsInput.get()) {
final Set<String> usedTaxa = new LinkedHashSet<>();
if (taxonSet.asStringList() == null) {
taxonSet.initAndValidate();
}
for (final String taxonID : taxonSet.asStringList()) {
if (!taxa.contains(taxonID)) {
throw new IllegalArgumentException("Taxon <" + taxonID + "> could not be found in list of taxa. Choose one of " + taxa);
}
usedTaxa.add(taxonID);
}
final ParametricDistribution distr = prior.distInput.get();
final Bound bounds = new Bound();
if (distr != null) {
List<BEASTInterface> beastObjects = new ArrayList<>();
distr.getPredecessors(beastObjects);
for (int i = beastObjects.size() - 1; i >= 0; i--) {
beastObjects.get(i).initAndValidate();
}
try {
bounds.lower = distr.inverseCumulativeProbability(0.0) + distr.offsetInput.get();
bounds.upper = distr.inverseCumulativeProbability(1.0) + distr.offsetInput.get();
} catch (MathException e) {
Log.warning.println("At RandomTree::initStateNodes, bound on MRCAPrior could not be set " + e.getMessage());
}
}
if (prior.isMonophyleticInput.get()) {
// add any monophyletic constraint
taxonSets.add(lastMonophyletic, usedTaxa);
distributions.add(lastMonophyletic, distr);
m_bounds.add(lastMonophyletic, bounds);
taxonSetIDs.add(prior.getID());
lastMonophyletic++;
} else {
// only calibrations with finite bounds are added
if (!Double.isInfinite(bounds.lower) || !Double.isInfinite(bounds.upper)) {
taxonSets.add(usedTaxa);
distributions.add(distr);
m_bounds.add(bounds);
taxonSetIDs.add(prior.getID());
}
}
}
}
// assume all calibration constraints are MonoPhyletic
// TODO: verify that this is a reasonable assumption
lastMonophyletic = taxonSets.size();
// sort constraints such that if taxon set i is subset of taxon set j, then i < j
for (int i = 0; i < lastMonophyletic; i++) {
for (int j = i + 1; j < lastMonophyletic; j++) {
Set<String> intersection = new LinkedHashSet<>(taxonSets.get(i));
intersection.retainAll(taxonSets.get(j));
if (intersection.size() > 0) {
final boolean isSubset = taxonSets.get(i).containsAll(taxonSets.get(j));
final boolean isSubset2 = taxonSets.get(j).containsAll(taxonSets.get(i));
// o taxonset1 does not intersect taxonset2
if (!(isSubset || isSubset2)) {
throw new IllegalArgumentException("333: Don't know how to generate a Random Tree for taxon sets that intersect, " + "but are not inclusive. Taxonset " + taxonSetIDs.get(i) + " and " + taxonSetIDs.get(j));
}
// swap i & j if b1 subset of b2
if (isSubset) {
swap(taxonSets, i, j);
swap(distributions, i, j);
swap(m_bounds, i, j);
swap(taxonSetIDs, i, j);
}
}
}
}
// build tree of mono constraints such that j is parent of i if i is a subset of j but i+1,i+2,...,j-1 are not.
// The last one, standing for the virtual "root" of all monophyletic clades is not associated with an actual clade
final int[] parent = new int[lastMonophyletic];
children = new List[lastMonophyletic + 1];
for (int i = 0; i < lastMonophyletic + 1; i++) {
children[i] = new ArrayList<>();
}
for (int i = 0; i < lastMonophyletic; i++) {
int j = i + 1;
while (j < lastMonophyletic && !taxonSets.get(j).containsAll(taxonSets.get(i))) {
j++;
}
parent[i] = j;
children[j].add(i);
}
// make sure upper bounds of a child does not exceed the upper bound of its parent
for (int i = lastMonophyletic - 1; i >= 0; --i) {
if (parent[i] < lastMonophyletic) {
if (m_bounds.get(i).upper > m_bounds.get(parent[i]).upper) {
m_bounds.get(i).upper = m_bounds.get(parent[i]).upper - 1e-100;
}
}
}
final PopulationFunction popFunction = populationFunctionInput.get();
simulateTree(taxa, popFunction);
if (rootHeightInput.get() != null) {
scaleToFit(rootHeightInput.get() / root.getHeight(), root);
}
nodeCount = 2 * taxa.size() - 1;
internalNodeCount = taxa.size() - 1;
leafNodeCount = taxa.size();
HashMap<String, Integer> taxonToNR = null;
// preserve node numbers where possible
if (m_initial.get() != null) {
if (leafNodeCount == m_initial.get().getLeafNodeCount()) {
// dont ask me how the initial tree is rubbish (i.e. 0:0.0)
taxonToNR = new HashMap<>();
for (Node n : m_initial.get().getExternalNodes()) {
taxonToNR.put(n.getID(), n.getNr());
}
}
} else {
taxonToNR = new HashMap<>();
String[] taxa = getTaxaNames();
for (int k = 0; k < taxa.length; ++k) {
taxonToNR.put(taxa[k], k);
}
}
// multiple simulation tries may produce an excess of nodes with invalid nr's. reset those.
setNodesNrs(root, 0, new int[1], taxonToNR);
initArrays();
if (m_initial.get() != null) {
m_initial.get().assignFromWithoutID(this);
}
for (int k = 0; k < lastMonophyletic; ++k) {
final MRCAPrior p = calibrations.get(k);
if (p.isMonophyleticInput.get()) {
final TaxonSet taxonSet = p.taxonsetInput.get();
if (taxonSet == null) {
throw new IllegalArgumentException("Something is wrong with constraint " + p.getID() + " -- a taxonset must be specified if a monophyletic constraint is enforced.");
}
final Set<String> usedTaxa = new LinkedHashSet<>();
if (taxonSet.asStringList() == null) {
taxonSet.initAndValidate();
}
usedTaxa.addAll(taxonSet.asStringList());
/* int c = */
traverse(root, usedTaxa, taxonSet.getTaxonCount(), new int[1]);
// boolean b = c == nrOfTaxa + 127;
}
}
}
use of beast.core.BEASTInterface in project beast2 by CompEvol.
the class JSONParser method useAnnotatedConstructor.
@SuppressWarnings({ "rawtypes", "unchecked" })
private BEASTInterface useAnnotatedConstructor(JSONObject node, String _id, String clazzName, List<NameValuePair> inputInfo) throws JSONParserException {
Class<?> clazz = null;
try {
clazz = Class.forName(clazzName);
} catch (ClassNotFoundException e) {
// cannot get here, since we checked the class existed before
e.printStackTrace();
}
Constructor<?>[] allConstructors = clazz.getDeclaredConstructors();
for (Constructor<?> ctor : allConstructors) {
// collect Param annotations on constructor parameters
Annotation[][] annotations = ctor.getParameterAnnotations();
List<Param> paramAnnotations = new ArrayList<>();
for (Annotation[] a0 : annotations) {
for (Annotation a : a0) {
if (a instanceof Param) {
paramAnnotations.add((Param) a);
}
}
}
for (NameValuePair pair : inputInfo) {
pair.processed = false;
}
Class<?>[] types = ctor.getParameterTypes();
if (types.length > 0 && paramAnnotations.size() == types.length) {
try {
// if all constructor parameters have Param annotations, try to call constructor
// first, build up argument list, then create object
Object[] args = new Object[types.length];
for (int i = 0; i < types.length; i++) {
Param param = paramAnnotations.get(i);
Type type = types[i];
if (type.getTypeName().equals("java.util.List")) {
if (args[i] == null) {
// no need to parameterise list due to type erasure
args[i] = new ArrayList();
}
List<Object> values = XMLParser.getListOfValues(param, inputInfo);
((List<Object>) args[i]).addAll(values);
} else {
args[i] = getValue(param, (Class<?>) type, inputInfo);
}
}
// ensure all inputs are used
boolean allUsed = true;
for (NameValuePair pair : inputInfo) {
if (!pair.processed) {
allUsed = false;
}
}
// if all inputs are used, call the constructor, otherwise, look for another constructor
if (allUsed) {
try {
Object o = ctor.newInstance(args);
BEASTInterface beastObject = (BEASTInterface) o;
register(node, beastObject);
return beastObject;
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new JSONParserException(node, "Could not create object: " + e.getMessage(), 1012);
}
}
} catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
// we get here when a param value cannot be constructed from a default value
// let's try the next constructor (if any)
}
}
}
return null;
}
Aggregations