From 5dd4e110bde22d9cabe57ef91edfe1f5d11cebb8 Mon Sep 17 00:00:00 2001 From: Shawn Laffan Date: Tue, 17 May 2016 20:56:13 +1000 Subject: [PATCH] Add support for mutable args in the randomisation args handling. Include a test, but it will be skipped for now since the mutable params are currently mostly for the GUI. s part of this work, Biodiverse::Common::get_metadata avoids the cache if called as a class method. Updates issue #565 --- lib/Biodiverse/Common.pm | 2 +- lib/Biodiverse/Randomise.pm | 22 ++++++++++------ t/28-Randomisation.t | 52 +++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 9 deletions(-) diff --git a/lib/Biodiverse/Common.pm b/lib/Biodiverse/Common.pm index 3dbbfa7b2..9d2fcd423 100644 --- a/lib/Biodiverse/Common.pm +++ b/lib/Biodiverse/Common.pm @@ -1771,7 +1771,7 @@ sub get_metadata { # Some metadata depends on given arguments, # and these could change across the life of an object. - if ($use_cache) { + if (blessed ($self) && $use_cache) { $cache = $self->get_cached_metadata; $metadata = $cache->{$subname}; } diff --git a/lib/Biodiverse/Randomise.pm b/lib/Biodiverse/Randomise.pm index 90e6151a8..245426700 100644 --- a/lib/Biodiverse/Randomise.pm +++ b/lib/Biodiverse/Randomise.pm @@ -343,14 +343,21 @@ sub run_randomisation { #print "\n\n\nMAXITERS IS $max_iters\n\n\n"; - # load any predefined args - overriding user specified ones - my $ref = $self->get_param ('ARGS'); - if (defined $ref) { + # load any predefined args, overriding user specified ones + # unless they are flagged as mutable. + if (my $ref = $self->get_param ('ARGS')) { + my $metadata = $self->get_metadata (sub => $function); + my $params = $metadata->get_parameters; + my %mutables; + foreach my $p (@$params) { + next if !$p->get_mutable; + my $name = $p->get_name; + $mutables{$name} = $args{$name}; + } %args = %$ref; + @args{keys %mutables} = values %mutables; } - else { - $self->set_param (ARGS => \%args); - } + $self->set_param (ARGS => \%args); my $rand_object = $self->initialise_rand (%args); @@ -849,14 +856,13 @@ sub get_common_rand_metadata { default => 0, increment => 1, tooltip => 'Add the first n randomised basedatas and their outputs to the project', - always_sensitive => 1, mutable => 1, }, $parameter_metadata_class), ); #@common = (); # override until we allow some args to be overridden on subsequent runs. @common = ( - @common, # DEBUG + #@common, # DEBUG bless ({ name => 'labels_not_to_randomise', label_text => 'Labels to not randomise', diff --git a/t/28-Randomisation.t b/t/28-Randomisation.t index 8cd272788..c4b488ff8 100644 --- a/t/28-Randomisation.t +++ b/t/28-Randomisation.t @@ -9,6 +9,7 @@ use Carp; use FindBin qw/$Bin/; use Test::Lib; use List::Util qw /first sum0/; +use List::MoreUtils qw /any_u/; use Test::More; use Test::Deep; @@ -55,6 +56,57 @@ sub main { } +sub test_mutable_parameters { + my $target_arg = 'add_basedatas_to_project'; + my $metadata = Biodiverse::Randomise->get_metadata (sub => 'rand_csr_by_group'); + my $params = $metadata->get_parameters; + my $has_target = any_u {$_->get_name eq $target_arg} @$params; + + SKIP: { + skip "missing mutable target $target_arg", 2 + if !$has_target; + + my $c = 300000; + my $bd = get_basedata_object_from_site_data(CELL_SIZES => [$c, $c]); + + my $sp = $bd->add_spatial_output(name => 'sp_to_test_mutables'); + $sp->run_analysis ( + calculations => ['calc_richness'], + spatial_conditions => ['sp_self_only()'], + ); + my $rand = $bd->add_randomisation_output (name => 'test_mutable_params'); + + + my %analysis_args = ( + function => 'rand_csr_by_group', + iterations => 1, + $target_arg => 1, # need a better one to test + ); + + $rand->run_analysis(%analysis_args); + + my $args = $rand->get_param('ARGS'); + + $rand->run_analysis( + %analysis_args, + $target_arg => 10, + ); + is ( + $args->{add_basedatas_to_project}, + 1, + "mutable arg $target_arg set as expected on first iter", + ); + + $args = $rand->get_param('ARGS'); + + is ( + $args->{add_basedatas_to_project}, + 10, + "mutable arg $target_arg changed as expected", + ); + }; +} + sub test_rand_structured_richness_same { my $c = 100000; my $bd = get_basedata_object_from_site_data(CELL_SIZES => [$c, $c]);