5 use List
::Util qw
/sum/;
10 use Bio
::Graphics
::Gel
;
12 use CXGN
::Apache
::Error
;
14 use CXGN
::TomatoGenome
::BACSubmission
;
15 use CXGN
::DB
::Connection
;
16 use CXGN
::DB
::Physical
;
17 use CXGN
::DB
::DBICFactory
;
19 use CXGN
::Fish
; # helper routines for FISH data.
21 use CXGN
::Genomic
::Search
::Clone
;
27 use CXGN
::Page
::FormattingHelpers qw
/ page_title_html
37 use CXGN
::People
::BACStatusLog
;
38 use CXGN
::People
::PageComment
;
39 use CXGN
::People
::Person
;
40 use CXGN
::Search
::CannedForms
;
41 use CXGN
::TomatoGenome
::BACPublish
;
42 use CXGN
::Tools
::Identifiers qw
/link_identifier/;
43 use CXGN
::Tools
::List qw
/all distinct any min max str_in/;
44 use CXGN
::Tools
::Text
;
46 use CatalystX
::GlobalContext
'$c';
48 # some of the newer parts of the page are in a controller object
49 my $self = $c->controller('Clone::Genomic');
52 marker_page
=> '/search/markers/markerinfo.pl?marker_id=',
53 map_page
=> '/cview/map.pl?map_id=',
54 overgo_report_page
=> '/maps/physical/overgo_stats.pl',
55 agi_page
=> 'http://www.genome.arizona.edu/fpc/tomato/',
56 bac_page
=> '/maps/physical/clone_info.pl?id=',
57 sgn_search_page
=> '/search/direct_search.pl',
58 plate_design_page
=> '/maps/physical/list_overgo_plate_probes.pl?plate_no=',
59 list_bacs_by_plate
=> '/maps/physical/list_bacs_by_plate.pl?by_plate=',
60 mapviewer
=> '/cview/view_chromosome.pl?show_physical=1&map_id=',
61 overgo_explanation
=> '/maps/physical/overgo_process_explained.pl',
62 read_info_page
=> '/maps/physical/clone_read_info.pl'
64 $link_pages{physical_map_page
} = $link_pages{'map_page'} . '1&physical=1';
65 $link_pages{contig_page
} = $link_pages{'agi_page'};
67 # Start a new SGN page.
68 my $page = CXGN
::Page
->new( 'BAC Data', 'Rob Buels' );
69 my $dbh = CXGN
::DB
::Connection
->new();
70 my $chado = CXGN
::DB
::DBICFactory
->open_schema('Bio::Chado::Schema');
72 $page->jsan_use(qw
/ MochiKit.Base MochiKit.Async /);
74 # Get arguments from Apache.
75 my %params = $page->get_all_encoded_arguments;
77 #### bac status stuff ####
78 #if someone is logged in, get their information so they can have the option of updating the status of this bac
79 our ( $person, $person_id, $fname, $lname, $username, $user_type ) =
80 ( '', '', '', '', '', '' );
82 $person_id = CXGN
::Login
->new($dbh)->has_session();
84 $person = CXGN
::People
::Person
->new( $dbh, $person_id );
86 $person_id = $person->get_sp_person_id();
87 $fname = $person->get_first_name() || '';
88 $lname = $person->get_last_name() || '';
89 $username = "$fname $lname";
90 $user_type = $person->get_user_type();
91 @person_projects = $person->get_projects_associated_with_person;
95 ## get the clone in question ###
96 #support legacy identifiers, but complain
98 my $clonequery = CXGN
::Genomic
::Search
::Clone
->new->new_query;
99 $clonequery->from_request( \
%params );
101 #is a random clone wanted?
102 if ( $params{random
} and $params{random
} eq 'yes' ) {
103 ( $params{id
} ) = $dbh->selectrow_array(<<EOSQL);
104 select clone_id from genomic.clone
105 where bad_clone is null or bad_clone='0'
112 $clone = CXGN
::Genomic
::Clone
->retrieve(
113 $params{id
} + 0 ) #the +0 makes sure it's numeric
114 or clone_not_found_page
( $page,
115 "No clone with id $params{id} could be found.", $clonequery );
118 elsif ( $params{bac_id
} ) {
120 $clone = CXGN
::Genomic
::Clone
->retrieve( $params{bac_id
} + 0 )
121 or clone_not_found_page
( $page,
122 "No clone with id $params{bac_id} could be found.", $clonequery );
125 elsif ( $params{cu_name
} || $params{az_name
} ) {
126 my $search = CXGN
::Genomic
::Search
::Clone
->new;
127 my $query = $search->new_query;
128 my $clonename = $params{cu_name
} || $params{az_name
};
129 my $orig_clonename = $clonename;
130 $clonename =~ s/^P(\d{3})(\D{1})(\d{2})/LE_HBa0$1$2$3/;
131 $query->clone_name("='$clonename'");
132 my $result = $search->do_search($query);
133 $result->total_results > 1
134 and $page->error_page(
135 "SGN bug: multiple clones with clone name $orig_clonename were found.");
137 #clone_not_found_page($page, "Multiple clones with clone name $orig_clonename (a.k.a. $clonename) were found. That's an internal bug.", $link_pages, \%params,$clonequery);
138 $result->total_results < 1
139 and clone_not_found_page
( $page,
140 "No clones with clone name $orig_clonename were found.", $clonequery );
142 $clone = $result->next_result;
145 # make sure we have a clone at this point
146 unless ( $clone && $clone->clone_id ) {
147 clone_not_found_page
( $page,
148 "No clones found matching the search criteria.", $clonequery );
151 my $clone_id = $clone->clone_id;
153 ####################################
155 ####################################
157 my $head_extra = <<EOEXTRA;
158 <style type="text/css">
164 /*FORM.changebutton BUTTON[type="submit"] {
168 background-color: #fff;
174 FORM.changebutton BUTTON {
177 background-color: #fff;
179 border: 1px solid #fff;
183 FORM.changebutton BUTTON:hover {
184 border: 1px solid #444;
188 SPAN.bgcolorstatus1 FORM.changebutton BUTTON,
189 SPAN.bgcolorstatus1 SPAN.colorme {
190 background-color: #ddd;
192 border: 1px solid #444;
195 SPAN.bgcolorstatus2 FORM.changebutton BUTTON,
196 SPAN.bgcolorstatus2 SPAN.colorme {
197 background-color: #ffff66;
199 border: 1px solid #444;
201 SPAN.bgcolorstatus3 FORM.changebutton BUTTON,
202 SPAN.bgcolorstatus3 SPAN.colorme {
203 background-color: #66ff66;
205 border: 1px solid #444;
207 SPAN.bgcolorstatus4 FORM.changebutton BUTTON,
208 SPAN.bgcolorstatus4 SPAN.colorme {
209 background-color: #9999ff;
211 border: 1px solid #444;
220 my $az_name = $clone->clone_name;
221 $page->header( "Clone $az_name", undef, $head_extra );
222 print page_title_html
("Clone $az_name");
224 print info_section_html
(
225 title
=> 'Clone & library',
227 contents
=> '<table style="margin: 0 auto"><tr><td>'
228 . $c->render_mason( '/genomic/clone/clone_summary.mas', clone
=> $clone )
231 '/genomic/library/library_summary.mas',
232 library
=> $clone->library_object
235 __title
=> 'Ordering Information',
237 'BAC clones can be ordered from the <a href="http://ted.bti.cornell.edu/cgi-bin/TFGD/order/order.cgi?item=clone">clone ordering page at TFGD</a>',
238 __tableattrs
=> 'width="100%" height="100%"',
240 . '</td></tr></table>'
243 my $overgo_html = render_overgo
( $clone, $dbh );
245 #get data on our computational associations with markers
246 my $computational_associations_html =
247 render_computational_associations
( $clone, $dbh );
249 #get data on manual associations
250 my $manual_associations_html = do {
251 my $mas = $dbh->selectall_arrayref( <<EOSQL, undef, $clone->clone_id );
252 select marker_id,pubmed_id,sp_person_id,comment, first_name, last_name, organization
253 from physical.manual_associations
254 join sgn_people.sp_person using(sp_person_id)
258 if ( $mas and @
$mas ) {
259 join '', map "$_\n", map {
260 my ( $marker_id, $pubmed_id, $sp_person_id, $comment_text, $fname,
263 my $marker = CXGN
::Marker
->new( $dbh, $marker_id );
264 '<div style="border: 1px solid #bbb">' . info_table_html
(
265 Marker
=> qq|<a href
="$link_pages{marker_page}$marker_id">|
266 . $marker->name_that_marker . '</a>',
269 ?
qq|<a href
="http://www.ncbi.nlm.nih.gov/pubmed/$pubmed_id">PubMed
$pubmed_id</a
>|
270 : '<span class="ghosted">unpublished</span>'
273 'Submitted by' => "$fname $lname " . ( $org ?
"($org)" : '' ),
278 Comment
=> $comment_text || '<span class="ghosted">none</span>',
289 my $physical_map_link = do {
291 || $computational_associations_html
292 || $manual_associations_html )
294 my $chr = $clone->chromosome_num;
296 "/cview/view_chromosome.pl?map_id=p9&hilite="
299 qq|<a href
="$url">View on physical
map chromosome
$chr</a
>|;
308 $dbh->selectall_arrayref( <<EOQ, undef, $clone->clone_id );
309 select map_id, chromo_num
313 if ( $on_fish_map && @
$on_fish_map ) {
315 "/cview/view_chromosome.pl?map_id=$on_fish_map->[0][0]&hilite="
317 . "&chr_nr=$on_fish_map->[0][1]";
318 qq|<a href
="$url">View on FISH
map chromosome
$on_fish_map->[0][1]</a
>|;
322 my $reg_info = $clone->reg_info_hashref;
324 #output physical mapping stuff
325 if ( $self->_is_tomato($clone) ) {
326 print info_section_html
(
327 title
=> 'Physical mapping',
329 contents
=> info_section_html
(
330 title
=> 'Fingerprint Contig Builds (FPC)',
332 contents
=> join "\n",
333 '<dl class="fpc_results">',
336 my ( $ad, $bd ) = map m
|(20\d\d
).+</dt
>|, $a, $b;
338 } #< sort by date in the FPC desc
341 { #< do a search and render links for each gbrowse FPC data source
344 { -attributes
=> { Name
=> $clone->clone_name } } );
345 my $ext_desc = ( $ds->extended_description
346 || 'no extended description' );
352 '<dt><a href="', $_->url,
353 '">', $ds->description,
354 '</a></dt> ', '<dd>',
360 '<dt class="ghosted">not present in '
362 . '</dt><dd class="ghosted">'
363 . $ext_desc . '</dd>';
366 grep $_->description =~
367 /FPC/i, #< select list of GBrowse FPC data sources
368 map $_->data_sources,
369 $c->enabled_feature('gbrowse2')
371 render_old_arizona_fpc
( $dbh, $clone ),
377 qq|Marker matches
- overgo
<a
class="context_help" href
="/maps/physical/overgo_process_explained.pl">what
's this?</a>|,
378 contents => $overgo_html,
382 title => qq|Marker matches - BLAST|,
383 contents => $computational_associations_html,
387 title => qq|Marker matches - manual|,
388 contents => $manual_associations_html,
392 title => qq|Physical map (from marker matches)|,
393 contents => $physical_map_link,
394 empty_message => 'Not on Physical Map
',
399 contents => $fish_link,
401 empty_message => 'Not on FISH
map',
404 title => "FISH images",
405 contents => CXGN::Fish::fish_image_html_table(
406 CXGN::DB::Connection->new,
412 title => "IL Mapping",
414 if ( str_in( $user_type, qw/sequencer curator/ ) ) {
416 my $q = CXGN::Genomic::Search::Clone->new->new_query;
417 $q->clone_id( '=?
', $clone_id );
420 qq|<a style="font-weight: bold" href="clone_reg.pl?$qstr">Edit IL mapping info</a>|;
427 !any( map $_->{val}, @{$reg_info}{qw/il_proj il_chr il_bin/} ),
428 contents => info_table_html(
431 'Assigned to project
' =>
432 qq|<span id="clone_il_mapping_project">$reg_info->{il_proj}{disp}</span>|,
433 'IL
-mapped to chromosome
' =>
434 qq|<span id="clone_il_mapping_chr">$reg_info->{il_chr}{disp}</span>|,
435 'IL
-mapped to IL segment
' =>
436 qq|<span id="clone_il_mapping_line">$reg_info->{il_bin}{disp}</span>|,
440 'IL mapping notes
' =>
441 qq|<span id="clone_il_mapping_notes">$reg_info->{il_notes}{disp}</span>|,
449 print info_section_html(
450 title => 'Physical mapping
',
453 empty_message => 'not available
',
457 #output sequencing status
458 print info_section_html(
459 title => 'Sequencing
',
461 contents => sequencing_content( $self, $c, $clone, $person, $dbh, $chado ),
464 # compute content for prelim. annot section
465 my $latest_seq = $clone->latest_sequence_name;
467 print info_section_html(
468 title => 'Sequence Annotations
',
470 contents => info_table_html(
474 map '<a href
="' . $_->url . '">' . $_->text . '</a
>',
477 $gb->xrefs($latest_seq), $gb->xrefs( $clone->clone_name )
478 } $c->enabled_feature('gbrowse2
')
480 || '<span
class="ghosted">'
482 . ' has
no browsable sequence annotations
</span
>',
484 $self->_is_tomato($clone)
485 ? render_tomato_bac_annot_download( $c, $clone )
486 : '<span
class="ghosted">not available
</span
>'
491 #print field for page comments
492 print CXGN::People::PageComment->new( $dbh, "BAC", $clone->clone_id )
496 print info_section_html(
497 title => 'Search again
',
500 CXGN::Search::CannedForms::clone_search_form( $page, $clonequery ),
505 ######################################################################
509 ######################################################################
511 #compare an in-vitro and in-silico restriction fragment set
512 #against eachother, rate how well they match up on a scale of 0 to 1
513 sub frag_match_score {
514 my @a = @{ shift() };
515 my @b = @{ shift() };
521 min( $a / $b, $b / $a );
525 #print join(',',@max_hs),"\n";
526 return sum(@max_hs) / max( scalar(@a), scalar(@b) );
529 sub clone_not_found_page {
531 my ( $page, $message, $query ) = @_;
532 $page->header('Clone
not found
.');
535 print page_title_html('CLONE NOT FOUND
');
537 print qq|<h2>$message</h2>\n|;
539 print info_section_html(
540 title => 'Search again
',
542 CXGN::Search::CannedForms::clone_search_form( $page, $query ),
550 sub sequencing_content {
551 my ( $self, $c, $clone, $person, $dbh, $chado ) = @_;
552 my $clone_id = $clone->clone_id;
554 my $bac_status_log = CXGN::People::BACStatusLog->new($dbh);
557 my $sequencing_content = '';
559 #print STDERR "user type '$user_type'\n";
560 my $welcome_message_html = do {
562 && str_in( $person->get_user_type, qw/sequencer curator/ ) )
565 . $person->get_first_name . ' '
566 . $person->get_last_name
567 . "</b>. You are logged in as a $user_type.\n";
572 my $sequencing_status_html = do {
573 my ( $status, ) = $bac_status_log->get_status( $clone->clone_id );
577 my $chr = $clone->chromosome_num;
579 my $sequencing_project_html =
580 sequencing_project_html( $user_type, $chr, $clone );
582 my $latest_seq = $clone->latest_sequence_name;
583 my $seqlen = $clone->seqlen;
585 $latest_seq && !( $latest_seq =~ /-\d+$/ ) && $clone->seq !~ /N/;
586 my %sequencing_files =
587 $self->_is_tomato($clone)
588 ? CXGN::TomatoGenome::BACPublish::sequencing_files( $clone,
589 $c->config->{'ftpsite_root
'} )
590 : $self->_potato_seq_files( $c, $clone );
592 #make info on the full sequence of this clone
593 my $sequence_info = do {
595 my $tot_len = commify_number($seqlen);
598 if ( $sequencing_files{seq} ) {
599 $dl_links .= <<EOHTML
600 <a href="clone_annot_download.pl?id=$clone_id&annot_set=all&annot_format=seq">[Download fasta]</a><br />
604 if ( $sequencing_files{tar
} ) {
606 sprintf( "%0.2f", ( -s
$sequencing_files{tar
} ) / 1_000_000
);
607 $dl_links .= <<EOHTML
608 <a href="clone_annot_download.pl?id=$clone_id&annot_set=all&annot_format=tar">[Download full submission]</a> ($tarsize MB)
613 my $gb = $clone->genbank_accession($chado);
616 ?
( link_identifier
( $gb, 'genbank_accession' ) || $gb )
620 <table width="100%"><tr>
626 <td><a href="/maps/physical/clone_sequence.pl?clone_id=$clone_id">[View]</a><br />
633 qq|<span
class="ghosted">Sequence
not available
.</span
>|;
637 #make an ftp site link
638 my $ftp_link = $self->_ftp_seq_repos_link( $c, $clone );
640 #make displays of the in-vitro restriction fragments we have in our
641 #records, versus the predicted in-silico fragments. also, set a flag
642 #if any of them have low match scores
643 my $low_restriction_match_score = 0; #< flag
644 my $restriction_match_threshold = 0.70;
645 my $restriction_frags_html = do {
646 my @iv_frags = $clone->in_vitro_restriction_fragment_sizes();
649 my $fingerprint_id = shift @
$_;
650 my $enzyme = shift @
$_;
653 qq|<img border
="1" style
="margin-right: 1em" src
="clone_restriction_gel_image.pl?id=$clone_id&enzyme=$enzyme&fp_id=$fingerprint_id" />|;
655 $clone->in_silico_restriction_fragment_sizes($enzyme) )
657 $is_frags = [ grep { $_ > 1000 } @
$is_frags ];
659 ( frag_match_score
( $is_frags, $iv_frags ) +
660 frag_match_score
( $iv_frags, $is_frags ) ) / 2;
661 $low_restriction_match_score = 1
662 if $match_score < $restriction_match_threshold;
663 my $frag_listing = info_table_html
(
666 "$enzyme <i>in vitro</i> ("
668 . ')' => join( ', ', @
$iv_frags ),
669 "$enzyme <i>in silico</i> ("
671 . ')' => join( ', ', @
$is_frags ),
673 #__tableattrs => 'style="margin-top: 30px"',
674 "Fragment Lengths Match Score" =>
675 sprintf( "%.2f", $match_score ),
679 'Restriction Fragments' => <<EOHTML,
680 <table><tr><td>$gel_img</td><td valign="middle">$frag_listing</td></tr></table>
685 my $frag_listing = info_table_html
(
688 "$enzyme <i>in vitro</i> ("
690 . ')' => join( ', ', @
$iv_frags ),
694 'Restriction Fragments' => <<EOHTML,
695 <table><tr><td>$gel_img</td><td valign="middle">$frag_listing</td></tr></table>
703 ### if this clone has a sequence, check it for various kinds of
705 my $warnings_html = do {
708 unless ($is_finished) {
709 push @warnings, 'sequence is not finished to HTGS3';
712 my $feature_query = $dbh->prepare(<<EOQ);
713 select fl.fmin, fl.fmax, f1.name
715 join feature f2 using(feature_id)
716 join featureloc fl on f2.feature_id=srcfeature_id
717 join feature f1 on fl.feature_id=f1.feature_id
718 join feature_dbxref fd on fl.feature_id=fd.feature_id
719 where fd.dbxref_id=(select dbxref_id from dbxref where accession=?)
723 #given a list of 2-element arrayrefs which are ranges,
724 #find the sum number of bases they cover, *not counting overlaps*
727 map { #warn "got range ".$_->start.", ".$_->end."\n";
729 } Bio
::Range
->disconnected_ranges(
731 Bio
::Range
->new( -start
=> $_->[0], -end
=> $_->[1] )
736 #check for too much vector in the sequence
737 $feature_query->execute( 'Cross_match_vector', $clone->clone_id );
738 my $matches = $feature_query->fetchall_arrayref;
739 if ( $matches && @
$matches ) {
740 if ( sum_ranges
(@
$matches) / $seqlen > 0.1 ) {
742 "more than 10% of sequence matches cloning vector";
745 my $seq_middle = Bio
::Range
->new(
746 -start
=> int( 0.1 * $seqlen ),
747 -end
=> int( 0.9 * $seqlen )
750 #convert the vector matches to ranges so we can work with them more easily
751 my @vector_ranges = map {
753 -start
=> $_->[0] + 1,
757 if ( any
( map { $_->overlaps($seq_middle) } @vector_ranges )
761 "vector found in middle 80% of sequence";
766 #check for E.coli blast hits in the sequence
767 $feature_query->execute( 'BLAST_E_coli_K12', $clone->clone_id );
768 $matches = $feature_query->fetchall_arrayref;
769 if ( $matches && @
$matches ) {
771 "full sequence contains matches to E. coli K12 genome";
774 #check for tomato chloroplast hits
775 $feature_query->execute( 'BLAST_tomato_chloroplast',
777 $matches = $feature_query->fetchall_arrayref;
778 if ( $matches && @
$matches ) {
780 "full sequence contains matches to Tomato chloroplast genome";
783 #check for hits to other bacs
784 $feature_query->execute( 'BLAST_tomato_bacs', $clone->clone_id );
785 $matches = $feature_query->fetchall_arrayref;
788 index( $_->[2], $clone->clone_name_with_chromosome ) != 0
793 && sum_ranges
(@
$matches) / $seqlen > 0.2 )
796 "more than 20% of full sequence matches other tomato genomic clones";
799 #check for the low restriction match score flag
800 if ($low_restriction_match_score) {
802 "poor correspondence with <i>in vitro</i> restriction fragments<br/>(match score below $restriction_match_threshold)";
805 #check this sequence's length vs. estimated length
807 $clone->estimated_length
809 abs( $seqlen - $clone->estimated_length ) /
810 $clone->estimated_length ) > 0.4
815 "sequence length %s is %0.1f%% different from estimated length %s",
816 commify_number
($seqlen),
818 commify_number
( $clone->estimated_length )
824 . join( '', map { "<li>$_</li>\n" } @warnings )
831 my $htgs_phase_html = (
833 '1 - fragmented, unordered',
834 '2 - fragmented, ordered',
836 )[ $clone->seqprops->{htgs_phase
} ]
838 my $sequenced_by_html = do {
839 if ( my $seq_shortname = $clone->seqprops->{sequenced_by
} ) {
841 #look up the organization for that shortname
842 my $matching_orgs = $dbh->selectcol_arrayref(
843 'select name from sgn_people.sp_organization where shortname = ?',
844 undef, $seq_shortname
846 if ( @
$matching_orgs == 1 ) {
850 qq|<span
class="ghosted">$seq_shortname</span
>|;
853 elsif ( my $ul = $clone->seqprops->{upload_account_name
} ) {
854 "Uploaded by account '$ul'";
857 '<span class="ghosted">not recorded</span>';
861 my $agp_map_link = do {
862 if ( my @agp_pos = agp_positions
($clone) ) {
864 "/cview/view_chromosome.pl?map_id=agp&hilite="
868 qq|<a href
="$url">View on AGP
map chromosome
$agp_pos[0][0]</a
>|;
875 return $sequencing_project_html . info_table_html
(
876 'Sequencing Project' => $self->_clone_seq_project_name($clone),
877 'Sequencing Status' => $sequencing_status_html,
878 'Full Sequence' => $sequence_info,
879 Warnings
=> $warnings_html || qq|<span
class="ghosted">none
</span
>|,
881 $self->_is_tomato($clone)
882 ?
( 'Chromosome Assembly' => $agp_map_link
883 || 'this clone is not part of a chromosome assembly' )
886 'HTGS phase' => $htgs_phase_html,
887 'Sequencing Organization' => $sequenced_by_html,
888 'End Sequences' => do {
891 if ( my @chromats = $clone->chromat_objects ) {
892 join '', map { "$_\n" } (
893 '<ul style="margin: 0; padding-left: 2em">',
897 . $_->read_link_html(
898 $link_pages{read_info_page
} )
906 '<span class="ghosted">None</span>';
912 __tableattrs
=> 'width="100%"',
913 ) . $restriction_frags_html;
917 sub sequencing_project_html
{
918 my ( $user_type, $chr, $clone ) = @_;
920 my ( undef, $organism, $accession ) =
921 $clone->library_object->accession_name;
922 return '' unless $organism =~ /lycopersicum/i;
925 if ( $chr eq 'unmapped' ) {
926 qq|<div
class="specialnote">This clone is registered to be sequenced
, but has
not been successfully mapped to any chromosome
.</div
>|;
929 qq|This clone is being sequenced by the Chromosome
$chr Sequencing Project
. (<a href
="/about/tomato_sequencing.pl">View projects
</a
>)|;
932 "This clone is not assigned to any sequencing project.\n";
937 if ( $user_type eq 'curator' or $user_type eq 'sequencer' ) {
938 my $q = CXGN
::Genomic
::Search
::Clone
->new->new_query;
939 $q->clone_id( '=?', $clone->clone_id );
940 my $clone_reg_link = 'clone_reg.pl?' . $q->to_query_string;
941 qq| To change this clone
's sequencing project assignment or other registry information, use the <a href="$clone_reg_link">Clone Registry Editor</a>.|;
944 qq|<span class="ghosted">Log in as a curator or sequencer to edit this clone's registry information
.</span
>|;
949 sub render_tomato_bac_annot_download
{
950 my ( $c, $clone ) = @_;
952 #look at the keys in the sequencing_files hash to figure out the
953 #analysis formats we have available.
954 my %sequencing_files =
955 CXGN
::TomatoGenome
::BACPublish
::sequencing_files
( $clone,
956 $c->config->{'ftpsite_root'} );
959 distinct
( grep { $_ }
960 map { my ($k) = /_([^_]+)$/; $k } keys %sequencing_files );
962 my @available_analyses =
963 grep { #find analyses that have all their files available
964 my $a = $_ eq 'all' ?
'' : $_ . '_';
965 all
( map { $sequencing_files{ $a . $_ } } @formats )
966 } 'all', CXGN
::TomatoGenome
::BACSubmission
->list_analyses;
968 if ( @formats && @available_analyses ) {
969 my $set_select = simple_selectbox_html
(
970 choices
=> \
@available_analyses,
972 id
=> 'annot_set_selector',
974 my $type_select = simple_selectbox_html
(
975 choices
=> \
@formats,
977 id
=> 'annot_format_selector',
979 my $id = $clone->clone_id;
982 <form name="clone_annot_download" method="GET" action="/genomic/clone/$id/annotation/download">
983 <table><tr><td><label for="annot_set_selector">Analysis:</label></td><td>$set_select</td></tr>
984 <tr><td><label for="annot_format_selector">Format:</label></td><td>$type_select <input type="hidden" name="id" value="$id" /><input type="submit" value="Download" /></td></tr>
985 <tr><td> </td></tr>
991 return qq|<span
class="ghosted">temporarily unavailable
</span
>|;
994 } # end prelim annot section
996 # NOTE: this function used to be in CXGN::Genomic::Clone
997 # =head2 agp_positions
999 # Usage: my $pos = $clone->agp_position
1000 # Desc : get this clone's position in its chromosome's AGP file,
1001 # or undef if it's not in there
1003 # Ret : nothing if not in AGP file, otherwise a list of
1004 # [ chromonum, global start, global end, local start, local end, length ]
1010 my $chr = $clone->chromosome_num;
1012 $chr >= 1 && $chr <= 12
1015 my ( undef, $agp_file ) =
1016 CXGN
::TomatoGenome
::BACPublish
::tpf_agp_files
($chr);
1018 return unless $agp_file;
1019 unless ( -r
$agp_file ) {
1020 warn "agp file $agp_file not readable";
1024 my $name = $clone->clone_name_with_chromosome
1027 open my $agp, '<', $agp_file
1028 or die "$! reading $agp_file";
1032 my @record = map $_ + 0, ( $chr, @fields[ 1, 2, 6, 7 ] );
1033 $record[5] = $record[2] - $record[1] + 1;
1040 sub render_old_arizona_fpc
{
1041 my ( $dbh, $clone ) = @_;
1043 my $clone_id = $clone->clone_id;
1045 my $map_id = CXGN
::DB
::Physical
::get_current_map_id
();
1047 # Get FPC Contigging data.
1048 my ( $fpc_version, $fpc_date ) =
1049 CXGN
::DB
::Physical
::get_current_fpc_version_and_date
($dbh);
1050 my $fpc_sth = $dbh->prepare_cached(<<EOQ);
1051 SELECT bc.bac_contig_id,
1054 FROM physical.bac_associations AS ba
1055 INNER JOIN physical.ba_plausibility AS bap
1056 ON bap.bac_assoc_id=ba.bac_assoc_id
1057 INNER JOIN physical.bac_contigs AS bc
1058 ON ba.bac_contig_id=bc.bac_contig_id
1059 WHERE ba.bac_id=? AND bc.fpc_version=?
1062 $fpc_sth->execute( $clone_id, $fpc_version );
1063 my $contig_sth = $dbh->prepare_cached(<<EOQ);
1065 FROM physical.bac_associations AS ba
1066 INNER JOIN physical.ba_plausibility AS bap
1067 USING (bac_assoc_id)
1068 INNER JOIN physical.bacs AS b
1069 ON ba.bac_id=b.bac_id
1070 WHERE ba.bac_contig_id=?
1075 my @incoherent_ctgs;
1076 while ( my ( $ctg_id, $contig, $coherent ) = $fpc_sth->fetchrow_array ) {
1079 $contig_sth->execute( $ctg_id, $map_id );
1080 while ( my ($thisbacid) = $contig_sth->fetchrow_array ) {
1081 my $thisbac = CXGN
::Genomic
::Clone
->retrieve($thisbacid);
1082 my $thisbacname = $thisbac->clone_name_with_chromosome
1083 || $thisbac->clone_name;
1084 if ( $thisbacid == $clone_id ) {
1086 qq{<b
><span style
="color:red">$thisbacname</span></b
>};
1090 qq{<a href
="$link_pages{bac_page}$thisbacid">$thisbacname</a
>};
1093 push @coherent_ctgs,
1094 qq{<b
>$contig :</b> [<span style="color: red">coherent</span
>], }
1095 . ( scalar @ctg_members )
1096 . qq{ members
: <br
/>\n};
1097 push @coherent_ctgs, "" . join( ",\n", @ctg_members ) . "<br />\n";
1101 $contig_sth->execute( $ctg_id, $map_id );
1102 while ( my ($thisbacid) = $contig_sth->fetchrow_array ) {
1103 ( $thisbacid == $clone_id ) && next;
1104 my $thisbac = CXGN
::Genomic
::Clone
->retrieve($thisbacid);
1105 my $thisbacname = $thisbac->clone_name_with_chromosome
1106 || $thisbac->clone_name;
1108 qq{<a href
="$link_pages{bac_page}$thisbacid">$thisbacname</a
>};
1110 push @incoherent_ctgs,
1111 qq{<b
>$contig :</b> [<span style="color: red">incoherent</span
>], }
1112 . ( scalar @ctg_members )
1113 . qq{ members
:<br
/>\n};
1114 push @incoherent_ctgs,
1115 "" . join( ",\n", @ctg_members ) . "<br />\n";
1119 $contig_sth->finish;
1121 if ( @coherent_ctgs || @incoherent_ctgs ) {
1124 '<dt>Tomato FPC (AGI 2005)</dt>',
1125 '<dd>', @coherent_ctgs, @incoherent_ctgs, '</dd>',
1130 '<dt class="ghosted">not present in Tomato FPC (AGI 2005)</dt><dd class="ghosted"></dd>';
1135 my ( $clone, $dbh ) = @_;
1137 # Get Overgo Plating data.
1138 my $map_id = CXGN
::DB
::Physical
::get_current_map_id
();
1140 my $overgo_version = CXGN
::DB
::Physical
::get_current_overgo_version
($dbh);
1141 my $op_sth = $dbh->prepare(
1142 "SELECT oap.plausible,
1143 pm.overgo_plate_row,
1144 pm.overgo_plate_col,
1148 FROM physical.overgo_associations AS oa
1149 INNER JOIN physical.oa_plausibility AS oap
1150 ON oap.overgo_assoc_id=oa.overgo_assoc_id
1151 INNER JOIN physical.probe_markers AS pm
1152 ON oa.overgo_probe_id=pm.overgo_probe_id
1153 INNER JOIN physical.overgo_plates AS op
1154 ON pm.overgo_plate_id=op.plate_id
1156 AND oa.overgo_version=?
1160 $op_sth->execute( $clone->clone_id, $overgo_version, $map_id );
1162 #format the overgo plating data into html
1164 my ( $dbh, $plausible, $row, $col, $marker_id, $map_id, $plateno ) = @_;
1165 my ( $map_name, $marker_name ) = ( '', '' );
1166 if ( my $marker = CXGN
::Marker
->new( $dbh, $marker_id ) ) {
1167 $marker_name = $marker->name_that_marker();
1169 if ( my $map = CXGN
::Map
->new( $dbh, { map_id
=> $map_id } ) ) {
1170 $map_name = $map->short_name();
1173 qq|<a href
="$link_pages{marker_page}$marker_id">$marker_name</a
>|,
1174 qq|<a href
="$link_pages{map_page}$map_id">$map_name</a
>|,
1175 qq|<a href
="$link_pages{plate_design_page}$plateno&highlightwell=$row$col">plate
$plateno</a
>|,
1176 qq|<a href
="$link_pages{plate_design_page}$plateno&highlightwell=$row$col">$row$col</a
>|
1179 my @matches = @
{ $op_sth->fetchall_arrayref };
1180 my @plausible_matches =
1181 map { fmt_overgo
( $dbh, @
$_ ) } grep { $_->[0] } @matches;
1182 my @conflicted_matches =
1183 map { fmt_overgo
( $dbh, @
$_ ) } grep { !$_->[0] } @matches;
1185 #output overgo information
1186 my @matches_headings = qw
/Probe Map Plate Well/;
1187 my $plausible_matches_html =
1189 ? columnar_table_html
(
1190 headings
=> \
@matches_headings,
1191 data
=> \
@plausible_matches,
1195 my $conflicted_matches_html =
1197 ? columnar_table_html
(
1198 headings
=> \
@matches_headings,
1199 data
=> \
@conflicted_matches,
1203 if ( $plausible_matches_html || $conflicted_matches_html ) {
1205 'Plausible matches' => $plausible_matches_html
1206 || '<span class="ghosted">None</span>',
1207 'Conflicted matches' => $conflicted_matches_html
1208 || '<span class="ghosted">None</span>',
1209 'Additional Info' =>
1210 qq|<a href
="$link_pages{overgo_report_page}">Overgo Plating Progress Report
</a
>|,
1220 sub render_computational_associations
{
1221 my ( $clone, $dbh ) = @_;
1222 my $cas = $dbh->selectall_arrayref( <<EOSQL, undef, $clone->clone_id );
1223 select marker_id,e_value,identity,score,parameters
1224 from physical.computational_associations
1228 if ( $cas and @
$cas ) {
1230 #alter the data to make it more suitable for display
1231 foreach my $r (@
$cas) {
1233 #change the marker ID to an html link
1234 $r->[0] = qq|<a href
="$link_pages{marker_page}$r->[0]">|
1235 . CXGN
::Marker
->new( $dbh, $r->[0] )->name_that_marker . '</a>';
1236 $r->[3] = sprintf( '%0.2f', $r->[3] );
1239 columnar_table_html
(
1240 headings
=> [ 'Marker', 'Evalue', 'Identity %', 'Score', 'Params' ],