=item * merge_types - Specify a list of relationship types, where related readings
should be treated as identical for the purposes of analysis.
+=item * exclude_type1 - Exclude those ranks whose groupings have only type-1 variants.
+
=back
=begin testing
my %lacunae;
foreach my $rank ( @ranks ) {
my $missing = [ @lacunose ];
- push( @groups, group_variants( $tradition, $rank, $missing, \@collapse ) );
+ my $rankgroup = group_variants( $tradition, $rank, $missing, \@collapse );
+ if( $opts{'exclude_type1'} ) {
+ # Check to see whether this is a "useful" group.
+ my( $rdgs, $grps ) = _useful_variant( $rankgroup );
+ next unless @$rdgs;
+ }
+ push( @groups, $rankgroup );
$lacunae{$rank} = $missing;
}
$DB::single = 1;
be a reference to an array, to which the sigla of lacunose witnesses at this
rank will be appended.
-Returns two ordered lists $readings, $groups, where $readings->[$n] is attested
-by the witnesses listed in $groups->[$n].
+Returns a hash $group_readings where $rdg is attested by the witnesses listed
+in $group_readings->{$rdg}.
=cut
my $groupings = [];
foreach my $ghash ( @groups ) {
my @grouping;
- foreach my $k ( sort keys %$ghash ) {
+ foreach my $k ( keys %$ghash ) {
push( @grouping, $ghash->{$k} );
}
push( @$groupings, \@grouping );
'Content' => $json );
my $answer;
+ my $used_idp;
if( $resp->is_success ) {
$answer = _desanitize_names( decode_json( $resp->content ), $witness_map );
+ $used_idp = 1;
} else {
# Fall back to the old method.
warn "IDP solver returned " . $resp->status_line . " / " . $resp->content
my $genealogical = 0;
foreach my $idx ( 0 .. $#groups ) {
my( $calc_groups, $result ) = @{$answer->[$idx]};
- $genealogical++ if $result;
+ if( $result ) {
+ $genealogical++;
+ # Prune the calculated groups, in case the IDP solver failed to.
+ if( $used_idp ) {
+ my @pruned_groups;
+ foreach my $cg ( @$calc_groups ) {
+ my @pg = _prune_group( $cg, $stemma );
+ push( @pruned_groups, \@pg );
+ }
+ $calc_groups = \@pruned_groups;
+ }
+ }
my $input_group = $groups[$idx];
foreach my $k ( sort keys %$input_group ) {
my $cg = shift @$calc_groups;
return $variant_row;
}
+sub _prune_group {
+ my( $group, $stemma ) = @_;
+ # Get these into a form prune_subtree will recognize. Make a "contighash"
+ my $hypohash = {};
+ map { $hypohash->{$_} = 1 } @$group;
+ # ...with reference values for hypotheticals.
+ map { $hypohash->{$_} = [] } $stemma->hypotheticals;
+ # Make our subgraph
+ my $subgraph = $stemma->graph->copy;
+ map { $subgraph->delete_vertex( $_ ) unless exists $hypohash->{$_} }
+ $subgraph->vertices;
+ # ...and find the root.
+ my( $root ) = $subgraph->predecessorless_vertices;
+ # Now prune and return the remaining vertices.
+ _prune_subtree( $subgraph, $root, $hypohash );
+ return $subgraph->vertices;
+}
+
sub _prune_subtree {
my( $tree, $root, $contighash ) = @_;
# First, delete hypothetical leaves / orphans until there are none left.