1 package CXGN
::Phenome
::QtlLoadDetailPage
;
2 use CatalystX
::GlobalContext
qw( $c );
5 processes and loads qtl data obtained from the the web forms
6 (qtl_form.pl) on the user specific directory and the database.
10 Isaak Y Tecle (iyt2@cornell.edu)
17 my $qtl_load_detail_page = CXGN::Phenome::QtlLoadDetailPage->new();
20 use CXGN::DB::Connection;
21 use CXGN::Phenome::Qtl;
22 use CXGN::Phenome::Qtl::Tools;
23 use CXGN::Phenome::Population;
24 use CXGN::Phenome::UserTrait;
25 use CXGN::Chado::Phenotype;
26 use CXGN::Chado::Cvterm;
27 use CXGN::Chado::Organism;
28 use CXGN::Phenome::Individual;
31 use CXGN::Map::Version;
33 use CXGN::LinkageGroup;
34 use List::MoreUtils qw /uniq/;
35 use CXGN::Marker::Modifiable;
36 use CXGN::Marker::Tools;
37 use CXGN::Marker::Location;
38 use CXGN::Phenome::GenotypeExperiment;
39 use CXGN::Phenome::Genotype;
40 use CXGN::Phenome::GenotypeRegion;
43 use CXGN::People::Person;
45 use Bio::Chado::Schema;
46 use Storable qw /store retrieve/;
49 use CatalystX::GlobalContext qw( $c );
53 my $self = bless {}, $class;
55 my $dbh = CXGN::DB::Connection->new();
56 my $login = CXGN::Login->new($dbh);
57 my $sp_person_id = $login->verify_session();
59 $self->set_sp_person_id($sp_person_id);
63 $self->process_data();
71 my $page = CXGN::Page->new( "SGN", "isaak" );
72 my $dbh = $self->get_dbh();
74 my $login = CXGN::Login->new($dbh);
75 my $sp_person_id = $login->verify_session();
76 my $referring_page = $c->req->base . 'qtl/form';
78 my %args = $page->get_all_encoded_arguments();
79 $args{pop_common_name_id} = $self->common_name_id();
81 my $type = $args{type};
82 my $pop_id = $args{pop_id};
83 my $args_ref = \%args;
85 my $qtl_obj = CXGN::Phenome::Qtl->new( $sp_person_id, $args_ref );
86 $qtl_obj->create_user_qtl_dir($c);
87 my $qtl_tools = CXGN::Phenome::Qtl::Tools->new();
90 $self->set_population_id($pop_id);
91 $qtl_obj->set_population_id($pop_id);
94 my ( $pop_name, $desc, $pop_detail, $message );
96 if ( $type eq 'begin' )
98 $self->show_pop_form();
101 elsif ( $type eq 'pop_form' )
103 $self->post_pop_form($qtl_obj, $qtl_tools);
106 elsif ( $type eq 'trait_form' )
108 $self->post_trait_form($qtl_obj, $args{'trait_file'}, $pop_id);
112 elsif ( $type eq 'pheno_form' )
114 $self->post_pheno_form($qtl_obj, $args{'pheno_file'}, $pop_id);
117 elsif ( $type eq 'geno_form' )
119 $self->post_geno_form($qtl_obj, $args{'geno_file'}, $pop_id);
122 elsif ( $type eq 'stat_form' )
124 $self->post_stat_form($args_ref);
133 my $safe_char = "a-zA-Z0-9_.-";
134 my ( $temp_pheno_file, $name );
137 $p_file =~ s/[^$safe_char]//g;
139 if ( $p_file =~ /^([$safe_char]+)$/ ) {
145 die "Phenotype file name contains invalid characters";
148 my $phe_upload = $c->req->upload('pheno_file');
150 if ( defined $phe_upload ) {
151 $name = $phe_upload->filename;
153 my ( $qtl_dir, $user_dir ) = $qtl->get_user_qtl_dir($c);
154 my $qtlfiles = retrieve("$user_dir/qtlfiles");
156 my $trait_file = $qtlfiles->{trait_file};
157 $self->compare_file_names( $name, $trait_file );
158 $qtlfiles->{pheno_file} = $name;
159 store $qtlfiles, "$user_dir/qtlfiles";
163 die "Catalyst::Request::Upload object for phenotype file not defined.";
167 if ( $p_file eq $name ) {
168 $temp_pheno_file = $qtl->apache_upload_file( $phe_upload, $c );
169 return $temp_pheno_file;
181 my ( $temp_geno_file, $name );
183 my $safe_char = "a-zA-Z0-9_.-";
186 $g_file =~ s/[^$safe_char]//g;
188 if ( $g_file =~ /^([$safe_char]+)$/ ) {
194 die "Genotype file name contains invalid characters";
197 my $gen_upload = $c->req->upload('geno_file');
199 if ( defined $gen_upload ) {
200 $name = $gen_upload->filename;
202 my ( $qtl_dir, $user_dir ) = $qtl->get_user_qtl_dir($c);
203 my $qtlfiles = retrieve("$user_dir/qtlfiles");
205 my $trait_file = $qtlfiles->{trait_file};
206 my $pheno_file = $qtlfiles->{pheno_file};
208 $self->compare_file_names( $name, $trait_file );
209 $self->compare_file_names( $name, $pheno_file );
211 $qtlfiles->{geno_file} = $name;
212 store $qtlfiles, "$user_dir/qtlfiles";
216 die "Catalyst::Request::Upload object for genotype file not defined.";
220 if ( $g_file eq $name ) {
221 $temp_geno_file = $qtl->apache_upload_file( $gen_upload, $c );
222 return $temp_geno_file;
232 my ( $temp_trait_file, $name );
234 print STDERR "Trait file: $c_file\n";
235 my $safe_char = "a-zA-Z0-9_.-";
238 $c_file =~ s/[^$safe_char]//g;
240 if ( $c_file =~ /^([$safe_char]+)$/ ) {
246 die "Trait file name contains invalid characters";
249 my $trait_upload = $c->req->upload('trait_file');
251 if ( defined $trait_upload )
253 $name = $trait_upload->filename;
254 my ( $qtl_dir, $user_dir ) = $qtl->get_user_qtl_dir($c);
256 $qtlfiles->{trait_file} = $name;
257 store( $qtlfiles, "$user_dir/qtlfiles" );
262 die "Catalyst::Request::Upload object for trait file not defined.";
266 if ( $c_file eq $name )
268 $temp_trait_file = $qtl->apache_upload_file( $trait_upload, $c );
269 return $temp_trait_file;
274 sub load_pop_details {
276 my $pop_args = shift;
277 my %pop_details = %{$pop_args};
279 my $org = $pop_details{organism};
280 my $name = $pop_details{pop_name};
281 my $desc = $pop_details{pop_desc};
282 my $cross_id = $pop_details{pop_type};
283 my $female = $pop_details{pop_female_parent};
284 my $male = $pop_details{pop_male_parent};
285 my $recurrent = $pop_details{pop_recurrent_parent};
286 my $donor = $pop_details{pop_donor_parent};
287 my $comment = $pop_details{pop_comment};
288 my $is_public = $pop_details{pop_is_public};
289 my $common_name_id = $pop_details{pop_common_name_id};
291 my $dbh = $self->get_dbh();
292 my $login = CXGN::Login->new($dbh);
293 my $sp_person_id = $login->verify_session();
295 my ( $female_id, $male_id, $recurrent_id, $donor_id );
297 my $population = CXGN::Phenome::Population->new_with_name( $dbh, $name );
298 my $population_id = $population->get_population_id();
299 if ($population_id) {
300 $self->population_exists( $population, $name );
303 print STDERR "storing parental accessions...\n";
306 $female_id = $self->store_accession($female);
307 print STDERR "female: $female_id\n";
311 $male_id = $self->store_accession($male);
312 print STDERR "male: $male_id\n";
316 $recurrent_id = $self->store_accession($recurrent);
320 $donor_id = $self->store_accession($donor);
323 my $pop = CXGN::Phenome::Population->new($dbh);
324 $pop->set_name($name);
325 $pop->set_description($desc);
326 $pop->set_sp_person_id($sp_person_id);
327 $pop->set_cross_type_id($cross_id);
328 $pop->set_female_parent_id($female_id);
329 $pop->set_male_parent_id($male_id);
330 $pop->set_recurrent_parent_id($recurrent_id);
331 $pop->set_donor_parent_id($donor_id);
332 $pop->set_comment($comment);
333 $pop->set_web_uploaded('t');
334 $pop->set_common_name_id($common_name_id);
337 my $pop_id = $dbh->last_insert_id( "population", "phenome" );
339 $pop = CXGN::Phenome::Population->new( $dbh, $pop_id );
340 $pop->store_data_privacy($is_public);
342 return $pop_id, $name, $desc;
345 sub store_accession {
347 my $accession = shift;
348 my $dbh = $self->get_dbh();
350 print STDERR "organism_id: $accession\n";
351 my ( $species, $cultivar ) = split( /cv|var|cv\.|var\./, $accession );
352 $species =~ s/^\s+|\s+$//;
354 $cultivar =~ s/^\s+|\s+$//;
355 $species = ucfirst($species);
357 print STDERR "$accession: species:$species, cultivar:$cultivar\n";
358 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
360 my $organism = CXGN::Chado::Organism->new_with_species( $schema, $species );
361 $self->check_organism( $organism, $species, $cultivar );
363 my $existing_organism_id = $organism->get_organism_id();
364 my $organism_name = $organism->get_species();
367 my $sth = $dbh->prepare(
368 "SELECT accession_id, chado_organism_id, common_name
370 WHERE common_name ILIKE ?"
372 $sth->execute($cultivar);
373 my ( $accession_id, $chado_organism_id, $common_name ) =
374 $sth->fetchrow_array();
376 "select existing accession: $accession_id, $chado_organism_id, $common_name\n";
379 unless ($chado_organism_id) {
380 $sth = $dbh->prepare(
381 "UPDATE sgn.accession
382 SET chado_organism_id = ?
383 WHERE accession_id = $accession_id"
385 $sth->execute($existing_organism_id);
388 elsif ( !$accession_id ) {
390 $sth = $dbh->prepare(
391 "INSERT INTO sgn.accession
392 (common_name, chado_organism_id)
395 $sth->execute( $cultivar, $existing_organism_id );
396 $accession_id = $dbh->last_insert_id( "accession", "sgn" );
398 #my $accession = CXGN::Accession->new($dbh, $accession_id);
399 #$common_name = $accession->accession_common_name();
401 "inserted: $accession_id, $chado_organism_id, $common_name\n";
404 my ( $accession_names_id, $accession_name );
406 unless ( !$common_name ) {
407 $sth = $dbh->prepare(
408 "SELECT accession_name_id, accession_name
409 FROM sgn.accession_names
410 WHERE accession_name ILIKE ?"
412 $sth->execute($common_name);
414 ( $accession_names_id, $accession_name ) = $sth->fetchrow_array();
416 "selected existing accession_names: $accession_names_id, $accession_name\n";
418 unless ($accession_names_id) {
419 $sth = $dbh->prepare(
420 "INSERT INTO sgn.accession_names
421 (accession_name, accession_id)
424 $sth->execute( $common_name, $accession_id );
426 $accession_names_id =
427 $dbh->last_insert_id( "accession_names", "sgn" );
429 "inserted accession_names : $common_name, $accession_id\n";
433 unless ( !$accession_names_id ) {
434 $sth = $dbh->prepare(
435 "UPDATE sgn.accession
436 SET accession_name_id = ?
437 WHERE accession_id = ?"
439 $sth->execute( $accession_names_id, $accession_id );
440 print STDERR "updated accession: with $accession_names_id\n";
450 return $accession_id;
458 Usage: my ($true_or_false) = $self->store_traits($file);
459 Desc: reads traits, their definition, and unit from
460 user submitted tab-delimited traits file and stores traits
461 that does not exist in the db or exist but with different units
463 Args: tab delimited trait file, with full path
464 Side Effects: accesses database
472 my $pop_id = $self->get_population_id();
473 my $sp_person_id = $self->get_sp_person_id();
474 my $dbh = $self->get_dbh();
476 open( F, "<$file" ) || die "Can't open file $file.";
480 my @fields = split /\t/, $header;
481 @fields = map { lc( $_ ) } @fields;
483 my ( $trait, $trait_id, $trait_name, $unit, $unit_id );
485 if ( $fields[0] !~ /trait|name/
486 || $fields[1] !~ /definition/
487 || $fields[2] !~ /unit/
491 "Data columns in the traits file need to be in the order of:
492 <b>traits -> definition -> unit</b>. <br/>
493 Now they are in the order of <b><i>$fields[0] -> $fields[1]
494 -> $fields[2]</i></b>.\n";
496 $self->trait_columns($error);
504 my (@values) = split /\t/;
507 CXGN::Phenome::UserTrait->new_with_name( $dbh, $values[0] );
510 $trait = CXGN::Phenome::UserTrait->new($dbh);
512 $trait->set_cv_id(17);
513 $trait->set_name( $values[0] );
514 $trait->set_definition( $values[1] );
515 $trait->set_sp_person_id($sp_person_id);
516 $trait_id = $trait->store();
518 $trait = CXGN::Phenome::UserTrait->new( $dbh, $trait_id );
519 $trait_id = $trait->get_user_trait_id();
521 unless ( !$values[2] ) {
522 $unit_id = $trait->get_unit_id( $values[2] );
524 $unit_id = $trait->insert_unit( $values[2] );
528 if ( ($trait_id) && ($pop_id) && ($unit_id) ) {
529 $trait->insert_user_trait_unit( $trait_id, $unit_id,
537 unless ( !$values[2] ) {
538 $trait_id = $trait->get_user_trait_id();
539 $unit_id = $trait->get_unit_id( $values[2] );
541 $unit_id = $trait->insert_unit( $values[2] );
544 if ( ($trait_id) && ($pop_id) && ($unit_id) ) {
545 $trait->insert_user_trait_unit( $trait_id, $unit_id,
557 print STDERR "An error occurred storing traits: $@\n";
562 print STDERR "Committing...traits\n";
568 =head2 store_individual
570 Usage: $individual_id = $self->store_individual($dbh, $name, $pop_id, $sp_person_id);
571 Desc: stores individual genotypes is they don't
572 exist in the same pop in the db
574 Args: db handle, individual name, population id sp_person_id
575 Side Effects: accesses database
580 sub store_individual {
582 my $ind_name = shift;
583 my $pop_id = $self->get_population_id();
584 my $sp_person_id = $self->get_sp_person_id();
585 my $dbh = $self->get_dbh();
586 my $common_name_id = $self->common_name_id();
588 my ( $individual, $individual_id, $individual_name );
590 CXGN::Phenome::Individual->new_with_name( $dbh, $ind_name, $pop_id );
593 if ( scalar(@individuals) == 0 )
595 $individual = CXGN::Phenome::Individual->new($dbh);
596 $individual->set_name($ind_name);
597 $individual->set_population_id($pop_id);
598 $individual->set_sp_person_id($sp_person_id);
599 $individual->set_common_name_id($common_name_id);
600 $individual_id = $individual->store();
602 $individual_name = $individual->get_name();
605 elsif ( scalar(@individuals) == 1 ) {
607 print STDERR "There is a genotype with name $ind_name
608 in the same population ($pop_id). \n";
609 die "There might be a phenotype data for the same trait
610 for the same genotype $ind_name. I can't store
611 duplicate phenotype data. So I am quitting..\n";
613 elsif ( scalar(@individuals) > 0 ) {
614 die "There are two genotypes with the same name ($ind_name)
615 in the population: $pop_id.\n";
620 print STDERR "An error occurred storing individuals: $@\n";
626 print STDERR "STORED individual $individual_name.\n";
631 =head2 store_trait_values
633 Usage: my ($true_or_false) = &store_trait_values($dbh, $file, $pop_id, $sp_person_id);
634 Desc: stores phenotype values for traits evaluated for individuals of a population.
636 Args: db handle, tab delimited phenotype file with full path, population id, sp_person_id
637 Side Effects: accesses database
642 sub store_trait_values {
645 my $pop_id = $self->get_population_id();
646 my $sp_person_id = $self->get_sp_person_id();
647 my $dbh = $c->dbc->dbh;
648 open( F, "<$file" ) || die "Can't open file $file.";
652 my @fields = split /\t/, $header;
655 my ( $trait_name, $trait_id );
657 for ( my $i = 1 ; $i < @fields ; $i++ )
659 $trait[$i] = CXGN::Phenome::UserTrait->new_with_name( $dbh, $fields[$i] );
660 $trait_name = $trait[$i]->get_name();
661 $trait_id = $trait[$i]->get_user_trait_id();
667 my (@values) = split /\t/;
669 my $individual = $self->store_individual( $values[0] );
671 die "The genotype does not exist in the database.
672 Therefore, it can not store the associated
674 unless ($individual);
676 my $individual_id = $individual->get_individual_id();
677 my $individual_name = $individual->get_name();
679 for ( my $i = 1 ; $i < @values ; $i++ ) {
680 my $phenotype = CXGN::Chado::Phenotype->new($dbh);
681 $phenotype->set_unique_name(
682 qq | $individual_name $pop_id .":". $i |);
683 $phenotype->set_observable_id(
684 $trait[$i]->get_user_trait_id() );
685 if (!$values[$i]) {$values[$i] = undef;}
686 if ($values[$i] && $values[$i] =~ /NA|-|\s+/ig)
690 $phenotype->set_value($values[$i]);
691 $phenotype->set_individual_id($individual_id);
692 $phenotype->set_sp_person_id($sp_person_id);
693 my $phenotype_id = $phenotype->store();
695 $trait[$i]->insert_phenotype_user_trait_ids(
696 $trait[$i]->get_user_trait_id(),
705 print STDERR "An error occurred storing trait values: $@\n";
710 print STDERR "Committing...trait values to tables public.phenotype
711 and user_trait_id and phenotype_id to phenotype_user_trait\n";
733 my $dbh = $self->get_dbh();
734 my $pop_id = $self->get_population_id();
736 my $pop = CXGN::Phenome::Population->new( $dbh, $pop_id );
737 my $pop_name = $pop->get_name();
738 my $parent_m = $pop->get_male_parent_id();
739 my $parent_f = $pop->get_female_parent_id();
740 my $desc = $pop->get_description();
742 my $acc = CXGN::Accession->new( $dbh, $parent_f );
743 my $female_name = $acc->accession_common_name();
744 my $chado_org_id_f = $acc->chado_organism_id();
746 $acc = CXGN::Accession->new( $dbh, $parent_m );
747 my $male_name = $acc->accession_common_name();
748 my $chado_org_id_m = $acc->chado_organism_id();
750 my $existing_map_id = CXGN::Map::Tools::population_map( $dbh, $pop_id );
752 my ( $map, $map_id, $map_version_id );
753 if ($existing_map_id) {
755 CXGN::Map::Version->map_version( $dbh, $existing_map_id );
756 $map = CXGN::Map->new( $dbh, { map_id => $existing_map_id } );
760 $map = CXGN::Map->new_map( $dbh, $pop_name );
761 $map_version_id = $map->{map_version_id};
763 $map_id = $map->{map_id};
765 my $species_m = $self->species($chado_org_id_m);
766 my $species_f = $self->species($chado_org_id_f);
770 . $female_name . ' x '
771 . $species_m . ' cv. '
773 print STDERR "map long name: $long_name\n";
774 $map->{long_name} = $long_name;
775 $map->{map_type} = 'genetic';
776 $map->{parent_1} = $parent_f;
777 $map->{parent_2} = $parent_m;
778 $map->{abstract} = $desc;
779 $map->{population_id} = $pop_id;
780 $map_id = $map->store();
783 if ($map_version_id) {
784 $lg_result = $self->store_lg( $map_version_id, $file );
787 print STDERR " STORED LINKAGE GROUPS\n";
790 print STDERR "FAILED STORING LINKAGE GROUPS\n";
794 if ( $map_id && $map_version_id && $lg_result ) {
795 return $map_id, $map_version_id;
798 print STDERR "Either map or map_version or
799 linkage_groups storing did not work\n";
807 Usage: my $species = $self->species($org_id)
808 Desc: when given the chado.organism_id, it returns the
809 genus and species name (in abbreviated format)
810 Ret: abbreviated species name
811 Args: chado organism id
812 Side Effects: access db
820 my $dbh = $self->get_dbh();
822 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
824 my $org = CXGN::Chado::Organism->new( $schema, $org_id );
826 return my $species = $org->get_abbreviation();
843 my ( $map_version_id, $file ) = @_;
844 my $dbh = $self->get_dbh();
846 open F, "<$file" or die "can't open $file\n";
852 my @chrs = split /\t/, $chr;
855 die "The first cell of 2nd row must be empty." unless !$chrs[0];
858 my $lg = CXGN::LinkageGroup->new( $dbh, $map_version_id, \@chrs );
859 my $result = $lg->store();
862 print STDERR "Succeeded storing linkage groups
863 on map_version_id $map_version_id\n";
866 print STDERR "Failed storing linkage groups
867 on map_version_id $map_version_id\n";
883 sub store_marker_and_position {
885 my ( $file, $map_version_id ) = @_;
886 my $dbh = $self->get_dbh();
887 open F, "<$file" or die "can't open $file\n";
892 chomp( $markers, $chrs, $positions );
895 my @markers = split /\t/, $markers;
898 my @positions = split /\t/, $positions;
901 my @chromosomes = split /\t/, $chrs;
905 for ( my $i = 0 ; $i < @markers ; $i++ )
907 print STDERR $markers[$i] . "\t" . $positions[$i] . "\n";
909 my ( $marker_name, $subs ) =
910 CXGN::Marker::Tools::clean_marker_name( $markers[$i] );
913 CXGN::Marker::Tools::marker_name_to_ids( $dbh, $marker_name );
914 if ( @marker_ids > 1 ) {
915 die "Too many IDs found for marker '$marker_name'";
917 my ($marker_id) = @marker_ids;
921 $marker_obj = CXGN::Marker::Modifiable->new( $dbh, $marker_id );
924 $marker_obj = CXGN::Marker::Modifiable->new($dbh);
925 $marker_obj->set_marker_name($marker_name);
926 my $inserts = $marker_obj->store_new_data();
928 if ( $inserts and @{$inserts} ) {
931 die "Oops, I thought I was inserting some new data";
933 $marker_id = $marker_obj->marker_id();
935 my $loc = $marker_obj->new_location();
936 my $pos = $positions[$i];
937 my $conf = 'uncalculated';
938 my $protocol = 'unknown';
939 $loc->marker_id($marker_id);
941 $loc->map_version_id($map_version_id);
942 $loc->lg_name( $chromosomes[$i] );
943 $loc->position($pos);
944 $loc->confidence($conf);
945 $loc->subscript($subs);
947 $marker_obj->add_experiment(
948 { location => $loc, protocol => $protocol } );
949 my $inserts = $marker_obj->store_new_data();
951 if ( $inserts and @{$inserts} ) {
956 die "Oops, I thought I was inserting some new data";
964 "Failed loading markers and their positions; rolling back.\n";
969 print STDERR "Succeeded. loading markers and their position\n";
977 =head2 store_genotype
990 my ( $file, $map_version_id ) = @_;
991 my $dbh = $self->get_dbh();
992 my $pop_id = $self->get_population_id();
994 open F, "<$file" or die "can't open $file\n";
999 chomp( $markers, $chrs, $positions );
1001 my @markers = split /\t/, $markers;
1004 my @chrs = split /\t/, $chrs;
1007 my $pop = CXGN::Phenome::Population->new( $dbh, $pop_id );
1008 my $pop_name = $pop->get_name();
1009 my $sp_person_id = $pop->get_sp_person_id();
1011 my $map = CXGN::Map->new( $dbh, { map_version_id => $map_version_id } );
1012 my $map_id = $map->get_map_id();
1014 my $linkage = CXGN::LinkageGroup->new( $dbh, $map_version_id );
1017 die "I need a valid reference map before I can
1018 start loading the genotype data\n";
1023 my $experiment = CXGN::Phenome::GenotypeExperiment->new($dbh);
1024 $experiment->set_background_accession_id(100);
1025 $experiment->set_experiment_name($pop_name);
1026 $experiment->set_reference_map_id($map_id);
1027 $experiment->set_sp_person_id($sp_person_id);
1028 $experiment->set_preferred(1);
1029 my $experiment_id = $experiment->store();
1031 while ( my $row = <F> ) {
1033 my @plant_genotype = split /\t/, $row;
1034 my $plant_name = shift(@plant_genotype);
1036 CXGN::Phenome::Individual->new_with_name( $dbh, $plant_name,
1039 my $individual_id = $individual[0]->get_individual_id();
1041 die "There are two genotypes with the same name or no genotypes
1042 in the same population. Can't assign genotype values."
1043 unless ( scalar(@individual) == 1 );
1045 if ( $individual[0] ) {
1047 my $genotype = CXGN::Phenome::Genotype->new($dbh);
1049 $genotype->set_genotype_experiment_id($experiment_id);
1050 $genotype->set_individual_id($individual_id);
1052 #$genotype->set_experiment_name($pop_name);
1053 #$genotype->set_reference_map_id($map_id);
1054 #$genotype->set_sp_person_id($sp_person_id);
1055 my $genotype_id = $genotype->store();
1057 my $mapmaker_genotype;
1058 for ( my $i = 0 ; $i < @plant_genotype ; $i++ ) {
1059 my $genotype_region =
1060 CXGN::Phenome::GenotypeRegion->new($dbh);
1063 CXGN::Marker::Tools::clean_marker_name( $markers[$i] );
1065 CXGN::Marker->new_with_name( $dbh, $marker_name );
1067 my $lg_id = $linkage->get_lg_id( $chrs[$i] );
1069 if ( !$plant_genotype[$i]
1070 || ( $plant_genotype[$i] =~ /\-/ ) )
1075 $genotype_region->set_genotype_id($genotype_id);
1076 $genotype_region->set_marker_id_nn( $marker->marker_id() );
1077 $genotype_region->set_marker_id_ns( $marker->marker_id() );
1078 $genotype_region->set_marker_id_sn( $marker->marker_id() );
1079 $genotype_region->set_marker_id_ss( $marker->marker_id() );
1080 $genotype_region->set_lg_id($lg_id);
1081 $genotype_region->set_sp_person_id($sp_person_id);
1084 if ( $plant_genotype[$i] =~ /\d/ ) {
1085 $mapmaker_genotype = 1;
1087 elsif ( $plant_genotype[$i] =~ /\D/ ) {
1088 $mapmaker_genotype = undef;
1092 if ($mapmaker_genotype) {
1093 $genotype_region->set_mapmaker_zygocity_code(
1094 $plant_genotype[$i] );
1097 $genotype_region->set_zygocity_code(
1098 $plant_genotype[$i] );
1100 $genotype_region->set_type("map");
1101 $genotype_region->store();
1107 "There is mismatch between the list of genotypes/lines ($plant_genotype[0]
1108 in your phenotype and genotype datasets\n";
1116 print STDERR "An error occurred loading genotype data:
1117 $@. ROLLED BACK CHANGES.\n";
1121 print STDERR "All is fine. Committing...genotype data\n";
1128 =head2 accessors get_sp_person_id, set_sp_person_id
1138 sub get_sp_person_id {
1140 return $self->{sp_person_id};
1143 sub set_sp_person_id {
1145 $self->{sp_person_id} = shift;
1148 =head2 accessors get_population_id, set_population_id
1158 sub get_population_id {
1160 return $self->{population_id};
1163 sub set_population_id {
1165 $self->{population_id} = shift;
1168 =head2 accessors get_dbh, set_dbh
1180 return $self->{dbh};
1185 $self->{dbh} = shift;
1188 =head2 common_name_id
1199 sub common_name_id {
1201 my $sp_person_id = $self->get_sp_person_id();
1202 my $qtl = CXGN::Phenome::Qtl->new($sp_person_id);
1203 my ( $qtl_dir, $user_qtl_dir ) = $qtl->get_user_qtl_dir($c);
1206 if ( -e "$user_qtl_dir/organism.txt" ) {
1207 open C, "<$user_qtl_dir/organism.txt" or die "Can't open file: !$\n";
1210 if ( $row =~ /(\d)/ ) {
1226 Usage: $self->error_page(@errors);
1227 Desc: when feed with error messages, it generates an
1228 error page with a list of the messages and a link
1229 back to the previous page where required data field(s)
1230 was/were not properly filled.
1231 Ret: page with the appropriate message
1232 Args: a list of messages to print...
1242 $c->forward_to_mason_view('/qtl/qtl_load/missing_data.mas',
1243 missing_data => \@error,
1244 guide => $self->guideline(),
1248 =head2 check_organism
1250 Usage: $self->check_organism($organism);
1251 Desc: checks if organism object is defined and if the
1252 the parental species is supported by sgn (chado.organism).
1253 in case organism object is not defined (a query to the chado.organism
1254 using a species name does not return a value, it generates
1255 a page with advise to check for the spelling of the scientific species name.
1256 Ret: a page with advice
1257 Args: organism object, species name, cultivar name
1263 sub check_organism {
1264 my ($self, $organism, $species, $cultivar) = @_ ;
1266 unless ( !$cultivar ) {
1267 $cultivar = " cv. $cultivar";
1272 $c->forward_to_mason_view('/qtl/qtl_load/check_organism.mas',
1273 species => $species,
1274 cultivar => $cultivar,
1275 guide => $self->guideline(),
1284 =head2 population_exists
1286 Usage: $self->population_exists($population, $population_name);
1287 Desc: checks if there is already a population with the same name
1288 and if so it generates a page with the appropriate advice to the user
1290 Ret: a page with advice
1291 Args: population object, population name
1297 sub population_exists {
1298 my ($self, $pop, $name) = @_;
1302 $c->forward_to_mason_view('/qtl/qtl_load/population_exists.mas',
1304 guide => $self->guideline()
1313 return qq |<a href="/qtl/submission/guide">Guidelines</a> |;
1316 =head2 trait_columns
1318 Usage: $self->trait_columns($error);
1319 Desc: checks if the trait file has the right order
1320 of data columns and if not advises the submitter
1321 with the appropriate message
1323 Ret: a page with advice
1331 my ($self, $trait_error) = @_;
1334 $c->forward_to_mason_view('/qtl/qtl_load/trait_columns.mas',
1335 error => $trait_error,
1336 guide => $self->guideline()
1342 =head2 accessors compare_file_names
1344 Usage: $f = $self->compare_file_names($file1, $file2);
1345 Desc: useful for checking if data files submitted for the traits,
1346 phenotype and genotype are different. helpful to avoid indvertent
1347 uploading of the same file for different fields.
1349 Ret: a page with advice if the same files are uploaded
1350 Args: file names to compare
1356 sub compare_file_names {
1357 my ($self, $file1, $file2) = @_;
1359 unless ( $file1 ne $file2 ) {
1360 $c->forward_to_mason_view('/qtl/qtl_load/compare_file_names.mas',
1363 guide => $self->guideline()
1370 Usage: $self->send_email($subj, $message, $pop_id);
1371 Desc: sends email at each step of the qtl data upload
1374 Args: subject, message, population_id
1382 my ( $subj, $message, $pop_id ) = @_;
1383 my $dbh = $self->get_dbh();
1384 my $sp_person_id = $self->get_sp_person_id();
1385 my $person = CXGN::People::Person->new( $dbh, $sp_person_id );
1388 qq |http://solgenomics.net/solpeople/personal-info.pl?sp_person_id=$sp_person_id |;
1390 my $username = $person->get_first_name() . " " . $person->get_last_name();
1392 qq |\nQTL population id: $pop_id \nQTL data owner: $username ($user_profile) |;
1394 print STDERR "\n$subj\n$message\n";
1395 CXGN::Contact::send_email( $subj, $message,
1396 'sgn-db-curation@sgn.cornell.edu' );
1401 sub post_stat_form {
1402 my ($self, $args_ref) = @_;
1404 my $sp_person_id = $self->get_sp_person_id();
1405 my $qtl_obj = CXGN::Phenome::Qtl->new($sp_person_id, $args_ref );
1406 my $qtl_tools = CXGN::Phenome::Qtl::Tools->new();
1407 my $stat_param = $qtl_obj->user_stat_parameters();
1408 my @missing = $qtl_tools->check_stat_fields($stat_param);
1409 my $pop_id = $args_ref->{pop_id};
1411 my ($stat_file, $type);
1413 $self->error_page(@missing);
1416 $stat_file = $qtl_obj->user_stat_file( $c, $pop_id );
1420 if ($type eq 'confirm') {
1421 my $referer = $c->req->base . "qtl/form/stat_form/$pop_id";
1422 if (-e $stat_file && $c->req->referer eq $referer)
1424 my $qtlpage = $c->req->base . "qtl/population/$pop_id";
1425 my $message = qq | QTL statistical parameters set: Step 5 of 5.
1426 QTL data upload for<a href="$qtlpage">population
1427 $pop_id</a> is completed. |;
1429 $self->send_email( '[QTL upload: Step 5]', $message, $pop_id );
1430 $self->redirect_to_next_form($c->req->base . "qtl/form/confirm/$pop_id");
1435 $c->res->redirect($c->req->referer);
1440 $c->res->redirect($c->req->referer);
1447 $self->send_email( '[QTL upload: Step 1]', 'A user is at the QTL data upload Step 1 of 5', 'NA' );
1448 $self->redirect_to_next_form($c->req->base . "qtl/form/pop_form");
1452 my ($self, $qtl_obj, $qtl_tools) = @_;
1454 my $pop_detail = $qtl_obj->user_pop_details();
1455 my @error = $qtl_tools->check_pop_fields($pop_detail);
1457 my ( $pop_id, $pop_name, $desc );
1460 $self->error_page(@error);
1464 ( $pop_id, $pop_name, $desc ) =
1465 $self->load_pop_details($pop_detail);
1470 $self->send_email( '[QTL upload: Step 1]', 'QTL population data uploaded: Step 1 of 5 completed', $pop_id );
1471 $self->redirect_to_next_form($c->req->base . "qtl/form/trait_form/$pop_id");
1475 sub post_trait_form {
1476 my ($self, $qtl_obj, $trait_file, $pop_id) = @_;
1480 $self->error_page("Trait file");
1483 my $uploaded_file = $self->trait_upload($qtl_obj, $trait_file);
1488 $traits_in_db = $self->store_traits($uploaded_file);
1491 if ($pop_id && $traits_in_db)
1493 $self->send_email('[QTL upload: Step 2]', 'QTL traits uploaded: Step 2 of 5', $pop_id);
1494 $self->redirect_to_next_form($c->req->base . "qtl/form/pheno_form/$pop_id");
1501 sub post_pheno_form {
1502 my ($self, $qtl_obj, $pheno_file, $pop_id) = @_;
1506 $self->error_page('Phenotype dataset file');
1509 my $uploaded_file = $self->pheno_upload($qtl_obj, $pheno_file);
1511 my $phenotype_in_db;
1514 $phenotype_in_db = $self->store_trait_values($uploaded_file);
1517 if ($phenotype_in_db && $pop_id)
1519 $self->send_email('[QTL upload: Step 3]', 'QTL phenotype data uploaded: Step 3 of 5', $pop_id);
1520 $self->redirect_to_next_form($c->req->base . "qtl/form/geno_form/$pop_id");
1525 sub post_geno_form {
1526 my ($self, $qtl_obj, $geno_file, $pop_id) = @_;
1530 $self->error_page('Genotype dataset file');
1533 my ($map_id, $map_version_id);
1534 my $uploaded_file = $self->geno_upload( $qtl_obj, $geno_file);
1538 ( $map_id, $map_version_id ) = $self->store_map($uploaded_file);
1542 $self->error_page('Genotype dataset file');
1545 my $genotype_uploaded;
1547 if ($map_version_id)
1549 my $result = $self->store_marker_and_position($uploaded_file, $map_version_id);
1553 $c->throw_404("Couldn't store markers and position.");
1556 my $genotype_uploaded = $self->store_genotype($uploaded_file, $map_version_id);
1558 if ($genotype_uploaded)
1560 $self->send_email( '[QTL upload: Step 4]', 'QTL genotype data uploaded : Step 4 of 5', $pop_id );
1561 $self->redirect_to_next_form($c->req->base . "qtl/form/stat_form/$pop_id");
1565 $c->throw_404("failed storing genotype data.");
1570 sub redirect_to_next_form {
1571 my ($self, $next_form) = @_;
1572 $c->res->redirect("$next_form");