+ final PhylogenyNode s = g.getLink();
+ if ( s == null ) {
+ throw new IllegalArgumentException( "mapped species tree node is null" );
+ }
+ if ( s.getNodeData().isHasTaxonomy() ) {
+ g.getNodeData().setTaxonomy( s.getNodeData().getTaxonomy() );
+ if ( g.isInternal() ) {
+ if ( g.getChildNode1().isInternal() && g.getChildNode1().getNodeData().isHasTaxonomy()
+ && ( g.getChildNode1().getNodeData().getTaxonomy() == s.getNodeData().getTaxonomy() ) ) {
+ g.getChildNode1().getNodeData().setTaxonomy( null );
+ }
+ if ( g.getChildNode2().isInternal() && g.getChildNode2().getNodeData().isHasTaxonomy()
+ && ( g.getChildNode2().getNodeData().getTaxonomy() == s.getNodeData().getTaxonomy() ) ) {
+ g.getChildNode2().getNodeData().setTaxonomy( null );
+ }
+ }
+ }
+ else if ( ForesterUtil.isEmpty( g.getName() ) && !ForesterUtil.isEmpty( s.getName() ) ) {
+ g.setName( s.getName() );
+ if ( g.isInternal() ) {
+ if ( g.getChildNode1().isInternal() && ( g.getChildNode1().getName() == s.getName() ) ) {
+ g.getChildNode1().setName( "" );
+ }
+ if ( g.getChildNode2().isInternal() && ( g.getChildNode2().getName() == s.getName() ) ) {
+ g.getChildNode2().setName( "" );
+ }
+ }
+ }
+ }
+
+ private final static void addScientificNamesMappedToReducedSpecificity( final String s1,
+ final String s2,
+ final SortedSet<String> scientific_names_mapped_to_reduced_specificity ) {
+ scientific_names_mapped_to_reduced_specificity.add( s1 + " -> " + s2 );
+ }
+
+ private final static void determineEvent( final PhylogenyNode s,
+ final PhylogenyNode g,
+ final boolean most_parsimonious_duplication_model,
+ final GSDIsummaryResult res ) {
+ boolean oyako = false;
+ if ( ( g.getChildNode1().getLink() == s ) || ( g.getChildNode2().getLink() == s ) ) {
+ oyako = true;
+ }
+ if ( g.getLink().getNumberOfDescendants() == 2 ) {
+ if ( oyako ) {
+ g.getNodeData().setEvent( Event.createSingleDuplicationEvent() );
+ res.increaseDuplicationsSum();
+ }
+ else {
+ g.getNodeData().setEvent( Event.createSingleSpeciationEvent() );
+ res.increaseSpeciationsSum();
+ }
+ }
+ else {
+ if ( oyako ) {
+ final Set<PhylogenyNode> set = new HashSet<PhylogenyNode>();
+ for( PhylogenyNode n : g.getChildNode1().getAllExternalDescendants() ) {
+ n = n.getLink();
+ while ( ( n.getParent() != s ) && ( n.getParent() != null ) ) {
+ n = n.getParent();
+ if ( n.isRoot() ) {
+ break;
+ }
+ }
+ set.add( n );
+ }
+ boolean multiple = false;
+ for( PhylogenyNode n : g.getChildNode2().getAllExternalDescendants() ) {
+ n = n.getLink();
+ while ( ( n.getParent() != s ) && ( n.getParent() != null ) ) {
+ n = n.getParent();
+ if ( n.isRoot() ) {
+ break;
+ }
+ }
+ if ( set.contains( n ) ) {
+ multiple = true;
+ break;
+ }
+ }
+ if ( multiple ) {
+ g.getNodeData().setEvent( Event.createSingleDuplicationEvent() );
+ res.increaseDuplicationsSum();
+ }
+ else {
+ if ( most_parsimonious_duplication_model ) {
+ g.getNodeData().setEvent( Event.createSingleSpeciationEvent() );
+ res.increaseSpeciationsSum();
+ }
+ else {
+ g.getNodeData().setEvent( Event.createSingleSpeciationOrDuplicationEvent() );
+ res.increaseSpeciationOrDuplicationEventsSum();
+ }
+ }
+ }
+ else {
+ g.getNodeData().setEvent( Event.createSingleSpeciationEvent() );
+ res.increaseSpeciationsSum();
+ }
+ }
+ }
+
+ private final static void stripSpeciesTree( final Phylogeny species_tree,
+ final List<PhylogenyNode> species_tree_ext_nodes,
+ final NodesLinkingResult res ) {
+ for( final PhylogenyNode s : species_tree_ext_nodes ) {
+ if ( !res.getMappedSpeciesTreeNodes().contains( s ) ) {
+ species_tree.deleteSubtree( s, true );
+ res.getStrippedSpeciesTreeNodes().add( s );
+ }
+ }
+ species_tree.clearHashIdToNodeMap();
+ species_tree.externalNodesHaveChanged();