2 package SGN
::Controller
::AJAX
::Pedigrees
;
5 use List
::Util qw
| any
|;
6 use File
::Slurp qw
| read_file
|;
8 use Bio
::GeneticRelationships
::Individual
;
9 use Bio
::GeneticRelationships
::Pedigree
;
10 use CXGN
::Pedigree
::AddPedigrees
;
12 BEGIN { extends
'Catalyst::Controller::REST'; }
15 default => 'application/json',
17 map => { 'application/json' => 'JSON', 'text/html' => 'JSON' },
22 isa
=> 'DBIx::Class::Schema',
27 sub upload_pedigrees
: Path
('/ajax/pedigrees/upload') Args
(0) {
32 print STDERR
"User not logged in... not uploading pedigrees.\n";
33 $c->stash->{rest
} = {error
=> "You need to be logged in to upload pedigrees." };
37 if (!any
{ $_ eq "curator" || $_ eq "submitter" } ($c->user()->roles) ) {
38 $c->stash->{rest
} = {error
=> "You have insufficient privileges to add pedigrees." };
42 my $time = DateTime
->now();
43 my $user_id = $c->user()->get_object()->get_sp_person_id();
44 my $user_name = $c->user()->get_object()->get_username();
45 my $timestamp = $time->ymd()."_".$time->hms();
46 my $subdirectory = 'pedigree_upload';
48 my $upload = $c->req->upload('pedigrees_uploaded_file');
49 my $upload_tempfile = $upload->tempname;
51 # my $temp_contents = read_file($upload_tempfile);
52 # $c->stash->{rest} = { error => $temp_contents };
55 my $upload_original_name = $upload->filename();
57 # check file type by file name extension
59 if ($upload_original_name =~ /\.xls$|\.xlsx/) {
60 $c->stash->{rest
} = { error
=> "Pedigree upload requires a tab delimited file. Excel files (.xls and .xlsx) are currently not supported. Please convert the file and try again." };
66 my $uploader = CXGN
::UploadFile
->new();
69 ## Store uploaded temporary file in archive
70 print STDERR
"TEMP FILE: $upload_tempfile\n";
71 my $archived_filename_with_path = $uploader->archive($c, $subdirectory, $upload_tempfile, $upload_original_name, $timestamp);
73 if (!$archived_filename_with_path) {
74 $c->stash->{rest
} = {error
=> "Could not save file $upload_original_name in archive",};
78 $md5 = $uploader->get_md5($archived_filename_with_path);
79 unlink $upload_tempfile;
81 # check if all accessions exist
83 open(my $F, "<", $archived_filename_with_path) || die "Can't open archive file $archived_filename_with_path";
84 my $schema = $c->dbic_schema("Bio::Chado::Schema");
88 my %legal_cross_types = ( biparental
=> 1, open => 1, self
=> 1);
95 for(my $i=0; $i<3; $i++) {
96 if ($acc[$i] =~ /\,/) {
97 my @a = split /\s*\,\s*/, $acc[$i]; # a comma separated list for an open pollination can be given
98 foreach (@a) { $stocks{$_}++ if $_ };
101 $stocks{$acc[$i]}++ if $acc[$i];
104 # check if the cross types are recognized...
105 if ($acc[3] && !exists($legal_cross_types{lc($acc[3])})) {
106 $errors{"not legal cross type: $acc[3] (should be biparental, self, or open)"}=1;
109 my @unique_stocks = keys(%stocks);
110 %errors = $self->check_stocks($c, \
@unique_stocks);
113 $c->stash->{rest
} = { error
=> "There were problems loading the pedigree for the following accessions: ".(join ",", keys(%errors)).". Please fix these errors and try again. (errors: ".(join ", ", values(%errors)).")" };
118 open($F, "<", $archived_filename_with_path) || die "Can't open file $archived_filename_with_path";
128 ## NEW FILE STRUCTURE: progeny_name, female parent, male parent, cross_type
133 my ($progeny, $female, $male, $cross_type) = split /\t/;
135 if (!$female && !$male) {
136 print STDERR
"No parents specified... skipping.\n";
140 print STDERR
"No progeny specified... skipping.\n";
144 if (($female eq $male) && ($cross_type ne 'self')) {
145 $cross_type = "self";
148 elsif ($female && !$male) {
149 if ($cross_type ne 'open') {
150 print STDERR
"No male parent specified and cross_type is not open... setting to unknown\n";
151 $cross_type = 'unknown';
155 if($cross_type eq "self") {
156 $female_parent = Bio
::GeneticRelationships
::Individual
->new( { name
=> $female });
157 $male_parent = Bio
::GeneticRelationships
::Individual
->new( { name
=> $female });
159 elsif($cross_type eq "biparental") {
160 $female_parent = Bio
::GeneticRelationships
::Individual
->new( { name
=> $female });
161 $male_parent = Bio
::GeneticRelationships
::Individual
->new( { name
=> $male });
163 elsif($cross_type eq "open") {
164 $female_parent = Bio
::GeneticRelationships
::Individual
->new( { name
=> $female });
165 my $population_name = "";
166 my @male_parents = split /\s*\,\s*/, $male;
169 $population_name = join "_", @male_parents;
172 $population_name = $female."_open";
174 $male_parent = Bio
::GeneticRelationships
::Population
->new( { name
=> $population_name});
175 $male_parent->set_members(\
@male_parents);
178 my $population_cvterm_id = $c->model("Cvterm")->get_cvterm_row($schema, "population", "stock_type");
179 my $male_parent_cvterm_id = $c->model("Cvterm")->get_cvterm_row($schema, "male_parent", "stock_relationship");
181 # create population stock entry
183 my $pop_rs = $schema->resultset("Stock::Stock")->create(
185 name
=> $population_name,
186 uniquename
=> $population_name,
187 type_id
=> $population_cvterm_id->cvterm_id(),
190 # generate population connections to the male parents
191 foreach my $p (@male_parents) {
192 my $p_row = $schema->resultset("Stock::Stock")->find({ uniquename
=> $p });
193 my $connection = $schema->resultset("Stock::StockRelationship")->create(
195 subject_id
=> $pop_rs->stock_id,
196 object_id
=> $p_row->stock_id,
197 type_id
=> $male_parent_cvterm_id->cvterm_id(),
200 $male = $population_name;
203 my $p = Bio
::GeneticRelationships
::Pedigree
->new(
205 cross_type
=> $cross_type,
206 female_parent
=> $female_parent,
207 male_parent
=> $male_parent,
213 my $add = CXGN
::Pedigree
::AddPedigrees
->new( { schema
=>$c->dbic_schema("Bio::Chado::Schema"), pedigrees
=>\
@pedigrees });
215 my $ok = $add->validate_pedigrees();
216 $add->add_pedigrees();
219 $c->stash->{rest
} = { error
=> "An error occurred while storing the provided pedigree. Please check your file and try again ($@)\n" };
222 $c->stash->{rest
} = { success
=> 1 };
228 my $stock_names = shift;
230 my $schema = $c->dbic_schema("Bio::Chado::Schema");
233 my $error_alert = "";
235 foreach my $stock_name (@
$stock_names) {
237 my $number_of_stocks_found;
238 my $stock_lookup = CXGN
::Stock
::StockLookup
->new(schema
=> $schema);
239 $stock_lookup->set_stock_name($stock_name);
240 $stock = $stock_lookup->get_stock();
241 $number_of_stocks_found = $stock_lookup->get_matching_stock_count();
242 if ($number_of_stocks_found > 1) {
243 $errors{$stock_name} = "Multiple stocks found matching $stock_name\n";
245 if (!$number_of_stocks_found) {
246 $errors{$stock_name} = "No stocks found matching $stock_name\n";