/* * TraitGuesser.java * * Copyright (c) 2002-2015 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.app.beauti.options; import dr.app.beauti.traitspanel.GuessTraitException; import dr.evolution.util.TaxonList; import java.io.Serializable; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * @author Andrew Rambaut * @author Walter Xie */ public class TraitGuesser implements Serializable { private static final long serialVersionUID = 1786080930502001515L; private final TraitData traitData; public TraitGuesser(TraitData traitData) { this.traitData = traitData; } public enum GuessType { DELIMITER, REGEX } private GuessType guessType = GuessType.DELIMITER; private int order = 0; private String delimiter; private String regex; private static final String REGEX_CHARACTERS = "|[].*()-^$"; //////////////////////////////////////////////////////////////// public TraitData getTraitData() { return traitData; } public GuessType getGuessType() { return guessType; } public void setGuessType(GuessType guessType) { this.guessType = guessType; } public int getOrder() { return order; } public void setOrder(int order) { this.order = order; } public String getDelimiter() { return delimiter; } public void setDelimiter(String delimiter) { this.delimiter = delimiter; } public String getRegex() { return regex; } public void setRegex(String regex) { this.regex = regex; } //////////////////////////////////////////////////////////////// public void guessTrait(TaxonList taxa) { for (int i = 0; i < taxa.getTaxonCount(); i++) { String value = null; try { switch (guessType) { case DELIMITER: value = guessTraitByDelimiter(taxa.getTaxonId(i), delimiter); break; case REGEX: value = guessTraitFromRegex(taxa.getTaxonId(i), regex); break; default: throw new IllegalArgumentException("unknown GuessType"); } } catch (GuessTraitException gfe) { // } taxa.getTaxon(i).setAttribute(traitData.getName(), value); } } private String guessTraitByDelimiter(String label, String delimiter) throws GuessTraitException { StringBuilder sb = new StringBuilder(); for (int i = 0; i < delimiter.length(); i++) { if (REGEX_CHARACTERS.contains("" + delimiter.charAt(i))) { sb.append("\\").append(delimiter.charAt(i)); } else { sb.append(delimiter.charAt(i)); } } if (sb.toString().length() < 1) { throw new IllegalArgumentException("No delimiter"); } String[] tokens = label.split(sb.toString()); if (tokens.length < 2) { throw new IllegalArgumentException("Can not find delimiter in taxon label (" + label + ")\n or invalid delimiter (" + delimiter + ")."); } if (order >= 0) { if (order >= tokens.length) { throw new IllegalArgumentException("Insufficent delimiters in taxon lable (" + label + ")\n to find requested field."); } return tokens[order]; } else { if (tokens.length + order < 0) { throw new IllegalArgumentException("Insufficent delimiters in taxon lable (" + label + ")\n to find requested field."); } return tokens[tokens.length + order]; } } private String guessTraitFromRegex(String label, String regex) throws GuessTraitException { String t; if (!regex.contains("(")) { // if user hasn't specified a replace element, assume the whole regex should match regex = "(" + regex + ")"; } try { Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(label); if (!matcher.find()) { throw new GuessTraitException("Regular expression doesn't find a match in taxon label, " + label); } if (matcher.groupCount() < 1) { throw new GuessTraitException("Trait value group not defined in regular expression"); } t = matcher.group(1); // TODO: not working? } catch (NumberFormatException nfe) { throw new GuessTraitException("Badly formatted trait value in taxon label, " + label); } return t; } }