Skip to content

Commit

Permalink
Merge pull request #5195 from solgenomics/topic/seedlot_filter_by_trial
Browse files Browse the repository at this point in the history
Seedlot Search: add trial usage filter
  • Loading branch information
lukasmueller authored Nov 14, 2024
2 parents 8ee98f0 + 36d505f commit baaa953
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 21 deletions.
69 changes: 56 additions & 13 deletions lib/CXGN/Stock/Seedlot.pm
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,9 @@ sub list_seedlots {
my $only_good_quality = shift;
my $box_name = shift;
my $contents_cross_db_id = shift;
my $trial_name = shift; # name of trial used in a transaction (must also specify trial_usage)
my $trial_usage = shift; # transaction type (either 'source', 'sink', or 'source|sink')
# where the trial is the source, sink, or either of the matching seedlot's seed

select(STDERR);
$| = 1;
Expand All @@ -354,23 +357,23 @@ sub list_seedlots {
$search_criteria{'me.type_id'} = $type_id;
$search_criteria{'stock_relationship_objects.type_id'} = $collection_of_cvterm_id;
if ($seedlot_name) {
print STDERR "Adding seedlot name ($seedlot_name) to query...\n";
# print STDERR "Adding seedlot name ($seedlot_name) to query...\n";
$search_criteria{'me.uniquename'} = { 'ilike' => '%'.$seedlot_name.'%' };
}
if ($seedlot_id) {
print STDERR "Adding seedlot_id ($seedlot_id) to query...\n";
# print STDERR "Adding seedlot_id ($seedlot_id) to query...\n";
$search_criteria{'me.stock_id'} = { -in => $seedlot_id };
}
if ($breeding_program) {
print STDERR "Adding breeding_program $breeding_program to query...\n";
# print STDERR "Adding breeding_program $breeding_program to query...\n";
$search_criteria{'project.name'} = { 'ilike' => '%'.$breeding_program.'%' };
}
if ($location) {
print STDERR "Adding location $location to query...\n";
# print STDERR "Adding location $location to query...\n";
$search_criteria{'nd_geolocation.description'} = { 'ilike' => '%'.$location.'%' };
}
if ($contents_accession && scalar(@$contents_accession)>0) {
print STDERR "Adding contents accession: $contents_accession ...\n";
# print STDERR "Adding contents accession: $contents_accession ...\n";
$search_criteria{'subject.type_id'} = $accession_type_id;
if ($exact_match_uniquenames){
$search_criteria{'subject.uniquename'} = { -in => $contents_accession };
Expand Down Expand Up @@ -419,11 +422,11 @@ sub list_seedlots {
$search_criteria{'stockprops.value::numeric'} = { '>=' => $minimum_weight };
$search_criteria{'stockprops.type_id'} = $current_weight_cvterm_id;
}
if ($quality) {
print STDERR "Quality $quality\n";
$search_criteria{'stockprops.value' } = { '=' => $quality };
$search_criteria{'stockprops.type_id' } = $seedlot_quality_cvterm_id;
}
if ($quality) {
print STDERR "Quality $quality\n";
$search_criteria{'stockprops.value' } = { '=' => $quality };
$search_criteria{'stockprops.type_id' } = $seedlot_quality_cvterm_id;
}
if ($box_name) {
print STDERR "Box Name $box_name\n";
$search_criteria{'stockprops.value'} = { 'ilike' => '%'.$box_name.'%' };
Expand All @@ -432,6 +435,46 @@ sub list_seedlots {
push @seedlot_search_joins, 'stockprops';
}

if ($trial_name && $trial_usage) {

# Build query to get stocks that match the requested transactions
my @phs;
my $q = "SELECT subject_id, object_id";
$q .= " FROM public.stock_relationship";
$q .= " WHERE type_id = (SELECT cvterm_id FROM public.cvterm WHERE name = 'seed transaction')";

# Subquery to get stocks (plots, etc) in requested trial
my $sq = "SELECT DISTINCT(stock_id) FROM public.materialized_phenoview WHERE trial_id = (SELECT project_id FROM public.project WHERE name = ?)";
my @filters;

# Add source transaction (plot --> seedlot)
if ( $trial_usage =~ m/source/ ) {
push @filters, "object_id IN ($sq)";
push @phs, $trial_name;
}

# Add sink transaction (seedlot --> plot)
if ( $trial_usage =~ m/sink/ ) {
push @filters, "subject_id IN ($sq)";
push @phs, $trial_name;
}

# Add filters to main query
$q .= " AND (" . join(" OR ", @filters) . ")";

# Execute query
my @seedlot_ids;
my $h = $schema->storage->dbh()->prepare($q);
$h->execute(@phs);
while ( my ($subject_id, $object_id) = $h->fetchrow_array() ) {
push @seedlot_ids, $subject_id;
push @seedlot_ids, $object_id;
}

# Add Seedlot IDs as filter to overall seedlot query
$search_criteria{'me.stock_id'} = { -in => \@seedlot_ids };
}

my $rs = $schema->resultset("Stock::Stock")->search(
\%search_criteria,
{
Expand All @@ -452,7 +495,7 @@ sub list_seedlots {
while (my $row = $rs->next()) {
$seen_seedlot_ids{$row->stock_id}++;

$unique_seedlots{$row->uniquename}->{seedlot_stock_id} = $row->stock_id;
$unique_seedlots{$row->uniquename}->{seedlot_stock_id} = $row->stock_id;
$unique_seedlots{$row->uniquename}->{seedlot_stock_uniquename} = $row->uniquename;
$unique_seedlots{$row->uniquename}->{seedlot_stock_description} = $row->description;
$unique_seedlots{$row->uniquename}->{breeding_program_name} = $row->get_column('breeding_program_name');
Expand Down Expand Up @@ -495,11 +538,11 @@ sub list_seedlots {
$unique_seedlots{$_}->{owners_string} = $owners_string;
$unique_seedlots{$_}->{organization} = $stockprop_hash{$unique_seedlots{$_}->{seedlot_stock_id}}->{organization} ? $stockprop_hash{$unique_seedlots{$_}->{seedlot_stock_id}}->{organization} : 'NA';
$unique_seedlots{$_}->{box} = $stockprop_hash{$unique_seedlots{$_}->{seedlot_stock_id}}->{location_code} ? $stockprop_hash{$unique_seedlots{$_}->{seedlot_stock_id}}->{location_code} : 'NA';
$unique_seedlots{$_}->{seedlot_quality} = $stockprop_hash{$unique_seedlots{$_}->{seedlot_stock_id}}->{seedlot_quality} ? $stockprop_hash{$unique_seedlots{$_}->{seedlot_stock_id}}->{seedlot_quality} : '';
$unique_seedlots{$_}->{seedlot_quality} = $stockprop_hash{$unique_seedlots{$_}->{seedlot_stock_id}}->{seedlot_quality} ? $stockprop_hash{$unique_seedlots{$_}->{seedlot_stock_id}}->{seedlot_quality} : '';
$unique_seedlots{$_}->{current_count} = $stockprop_hash{$unique_seedlots{$_}->{seedlot_stock_id}}->{current_count} ? $stockprop_hash{$unique_seedlots{$_}->{seedlot_stock_id}}->{current_count} : 'NA';
$unique_seedlots{$_}->{current_weight_gram} = $stockprop_hash{$unique_seedlots{$_}->{seedlot_stock_id}}->{current_weight_gram} ? $stockprop_hash{$unique_seedlots{$_}->{seedlot_stock_id}}->{current_weight_gram} : 'NA';

push @seedlots, $unique_seedlots{$_};
push @seedlots, $unique_seedlots{$_};

}

Expand Down
7 changes: 6 additions & 1 deletion lib/SGN/Controller/AJAX/Seedlot.pm
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ sub list_seedlots :Path('/ajax/breeders/seedlots') :Args(0) {
my $exact_cross = $params->{exact_cross};
my $quality = $params->{quality};
my $only_good_quality = $params->{only_good_quality};
my $trial_name = $params->{trial_name};
my $trial_usage = $params->{trial_usage};

my $rows = $params->{length} || 10;
my $offset = $params->{start} || 0;
Expand Down Expand Up @@ -83,7 +85,10 @@ sub list_seedlots :Path('/ajax/breeders/seedlots') :Args(0) {
undef,
$quality,
$only_good_quality,
$box_name
$box_name,
undef,
$trial_name,
$trial_usage,
);
my @seedlots;
foreach my $sl (@$list) {
Expand Down
35 changes: 28 additions & 7 deletions mason/breeders_toolbox/seedlots.mas
Original file line number Diff line number Diff line change
Expand Up @@ -125,23 +125,39 @@ $user_role => undef
</div>
</div>

<!-- div class="form-group form-group-sm">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-9" >
<input id="search_seedlot_form_only_good_quality_checkbox" type="checkbox" /> Only show seedlots without quality issues
</div>
<!-- div class="form-group form-group-sm">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-9" >
<input id="search_seedlot_form_only_good_quality_checkbox" type="checkbox" /> Only show seedlots without quality issues
</div>
</div -->

<div class="form-group form-group-sm">
<div class="form-group form-group-sm">
<label class="col-sm-3 control-label">Quality: </label>
<div class="col-sm-9" >
<input class="form-control" id="search_seedlot_form_quality" type="text" />
</div>
</div>
<div class="form-group form-group-sm">
<label class="col-sm-3 control-label">Trial Usage: </label>
<div class="col-sm-9">
<div class="col-sm-5" style="padding-left: 0; padding-right: 5px">
<input class="form-control" id="search_seedlot_form_trial_name" type="text" placeholder="Trial Name" />
</div>
<div class="col-sm-7" style="padding-left: 5px; padding-right: 0">
<select class="form-control" id="search_seedlot_form_trial_usage">
<option value="">Select trial / seedlot usage...</option>
<option value="source">Trial --> Seedlot: Find seedlots that are derived from this trial</option>
<option value="sink">Seedlot --> Trial: Find seedlots that provided seed to this trial</option>
<option value="source|sink">Either of the above</option>
</select>
</div>
</div>
</div>

</form>
<center>
<button class="btn btn-primary" id="submit_seedlot_search" />Search</button>
<button class="btn btn-primary" id="submit_seedlot_search">Search</button>
</center>
</div>
</&>
Expand Down Expand Up @@ -218,6 +234,9 @@ jQuery(document).ready(function(){
jQuery("#search_seedlot_form_seedlot_name").autocomplete({
source: '/ajax/stock/seedlot_name_autocomplete',
});
jQuery("#search_seedlot_form_trial_name").autocomplete({
source: '/ajax/trials/trial_autocomplete'
});

var seedlots_table;

Expand Down Expand Up @@ -259,6 +278,8 @@ jQuery(document).ready(function(){
d.exact_cross = jQuery('#exact_cross').is(":checked") ? 1 : 0;
d.quality = jQuery('#search_seedlot_form_quality').val();
d.only_good_quality = jQuery('#search_seedlot_form_only_good_quality_checkbox').is(":checked") ? 1 : 0;
d.trial_name = jQuery('#search_seedlot_form_trial_name').val();
d.trial_usage = jQuery('#search_seedlot_form_trial_usage').val();
}
},
});
Expand Down

0 comments on commit baaa953

Please sign in to comment.