#!/usr/bin/perl ###################################################### # STAINFINDER PROGRAM # Author : Wijan Prapong # # This program takes input from a TreeView file and # allows users to view various stains simultaneously ###################################################### use strict; use CGI qw/:standard/; use CGI::Carp qw (fatalsToBrowser); $|=1; my $query = new CGI; # The $rootDir, $webDir, and $mainDir variables are used to allow # easy updates if the scans should ever move to a different location my $rootDir = '/share/tissue/archive/'; my $webDir = '/scans/Composites/'; my $mainDir = '/share/tissue/archive/scans/Composites/'; my %jpgAndAbHash; my $submit = $query->param('Display checked images'); my $submit2 = $query->param('Reset to default'); my $submit3 = $query->param('Clear all checkboxes'); my @imageSize = (1504,1440); #default image size of Bliss jpgs my $resizeFactor = $query->param('resizeFactor'); my $screenSize = $query->param('screenSize'); my @cookieValue = ($resizeFactor, $screenSize); my @cookieParams = $query->cookie('cookieParams'); my @cookieAntibodies = $query->cookie('cookieAntibodies'); my @defaultParams = @cookieParams || ('12.5%','1024x768'); my $uniqID = $query->param('uniqid') || die "A uniqid must be passed into the Stain Finder. Check your Tree View settings.\n"; my @cdtAntibodies = split("!",$uniqID); my $jpgName = shift(@cdtAntibodies); $jpgName =~ s/.jpg//g; my $fpNum = shift(@cdtAntibodies); my ($fpFile, @fpVars, @paraffinFile); #--Read paraffin file data exported from FileMaker Pro--# opendir (DIR, "$mainDir") || die "Cannot open directory $mainDir: $!\n"; @paraffinFile = grep /par_block/, readdir(DIR); closedir (DIR); if (@paraffinFile && $fpNum){ open(FILE, "$mainDir"."@paraffinFile") || die "can't open file: $!"; while (){ @fpVars = split("\t", $_); #expects tab delimited file $fpFile = shift(@fpVars); if ($fpFile == $fpNum){ $fpFile = join (" | ", @fpVars); last; close FILE; }else{ $fpFile = ""; } } close FILE; } my (@allAntibodyNames, @goodAntibodyNames, @badAntibodyNames); my @jpgParts = split ("_", $jpgName); my $sector = $jpgParts[0]; my $tissueArray = $jpgParts[1]; my $column = $jpgParts[2]; my $row = $jpgParts[3]; #--These variables are not actually used by the program--# # my $slice = $jpgParts[4]; # my $blissCode = $jpgParts[5]; # my $scannerPos = $jpgParts[6]; @allAntibodyNames = &GetAntibodyNamesFromDirectories; if(@cookieAntibodies){ @cdtAntibodies = @cookieAntibodies; } &CheckAntibodyNames; my @antibodyChoices = $query->param('antibodyChoices'); @antibodyChoices = sort(@antibodyChoices); #---------------------Cookie Setup----------------------# my $setCookie1 = $query->param('setCookie1'); my $deleteCookie1 = $query->param('deleteCookie1'); my $setCookie2 = $query->param('setCookie2'); my $deleteCookie2 = $query->param('deleteCookie2'); my ($cookie1, $cookie2); if ($setCookie1){ # set cookie if box is checked $cookie1 = $query->cookie(-name=>'cookieParams', -value=>\@cookieValue, -expires=>'+10y'); }elsif($deleteCookie1){ $cookie1 = $query->cookie(-name=>'cookieParams', -value=>\@cookieParams, -expires=>'-10y'); $query->param(-name=>'resizeFactor', -value=>'12.5%'); $query->param(-name=>'screenSize', -value=>'1024x768'); } if ($setCookie2){ # set cookie if box is checked $cookie2 = $query->cookie(-name=>'cookieAntibodies', -value=>\@antibodyChoices, -expires=>'+10y'); }elsif($deleteCookie2){ $cookie2 = $query->cookie(-name=>'cookieAntibodies', -value=>\@cookieAntibodies, -expires=>'-10y'); } if (($setCookie1 || $deleteCookie1) && ($setCookie2 || $deleteCookie2)){ print $query->header(-cookie=>[$cookie1, $cookie2]); }elsif($setCookie1 || $deleteCookie1){ print $query->header(-cookie=>$cookie1); }elsif($setCookie2 || $deleteCookie2){ print $query->header(-cookie=>$cookie2); }else{ print $query->header; } print $query->start_html("Stain Finder"); #---------------------Form Setup----------------------# print $query->start_form(); print "Display initial images at "; print $query->popup_menu(-name=>'resizeFactor', -value=>['12.5%', '25%', '50%', '100%'], -default=>$defaultParams[0]); print "of their original size
"; print "Monitor resolution of your computer "; print $query->popup_menu(-name=>'screenSize', -value=>['640x480', '800x600', '1024x768', '1280x1024', '1600x1024'], -default=>$defaultParams[1]); print br; if (!@cookieParams){ # parameter cookie does not exist if ($setCookie1){ print font({-color=>'red'}, "A cookie has been set on your computer with the default settings of images at $resizeFactor and a screen size of $screenSize"); }else{ print $query->checkbox(-name=>'setCookie1', -label=>'Save these settings as the default on this computer (a cookie will be set on your computer)'); } }else{ if ($deleteCookie1){ print font({-color=>'red'}, "All cookies have been removed from your computer and the default settings have been returned to 12.5% and a screen size of 1024x768"); }else{ print $query->checkbox(-name=>'deleteCookie1', -label=>'Remove saved settings from this computer (Return to defaults of 12.5% and 1024x768)'); } } print br, hr; $resizeFactor =~ tr/%//d; my $imageWidth = $imageSize[0] * ($resizeFactor / 100); my $imageHeight = $imageSize[1] * ($resizeFactor / 100); $screenSize = substr($screenSize, 0, index($screenSize, "x")); print "Show stains from the following antibodies:
"; if($submit2){ print $query->checkbox_group(-name=>'antibodyChoices', -values=>\@allAntibodyNames, -default=>\@goodAntibodyNames, -override=>1, -columns=>4); }elsif($submit3){ @goodAntibodyNames=(); print $query->checkbox_group(-name=>'antibodyChoices', -values=>\@allAntibodyNames, -default=>\@goodAntibodyNames, -override=>1, -columns=>4); }else{ if(@cookieAntibodies){ print $query->checkbox_group(-name=>'antibodyChoices', -values=>\@allAntibodyNames, -default=>\@cookieAntibodies, -override=>1, -columns=>4); }else{ print $query->checkbox_group(-name=>'antibodyChoices', -values=>\@allAntibodyNames, -default=>\@goodAntibodyNames, -columns=>4); } } print br; print $query->hidden(-name=>'uniqid', -value=>$uniqID); if (!@cookieAntibodies){ # cookie does not exist if ($setCookie2){ print font({-color=>'red'}, "A cookie has been set on your computer. All subsequent displays will default to the antibodies currently chosen." ); }else{ print $query->checkbox(-name=>'setCookie2', -label=>'Save these antibodies as the default choices on this computer (a cookie will be set on your computer)' ); } }else{ if ($deleteCookie2){ print font({-color=>'red'}, "The cookie with the default antibody choices has been removed from your computer."); }else{ print $query->checkbox(-name=>'deleteCookie2', -label=>'Remove saved antibody choices from this computer (Use antibodies passed in from the CDT file);'); } } print br; print $query->submit(-name=>'Display checked images'); print " "; print $query->submit(-name=>'Reset to default'); print " "; print $query->submit(-name=>'Clear all checkboxes'); if (@badAntibodyNames){ my $displayBadNames = join("; ", @badAntibodyNames); print br, br; print font({-color=>'red'}, b('NOTE:').'The following antibodies from the CDT file are not checked because there were no matching directories available:' .br .b($displayBadNames) .br); } print $query->end_form; my (@jpgsWithFullPath); if ($submit){ &GetFullJpgName(\%jpgAndAbHash); &CreateTable; } print $query->end_html; ################################################# sub GetAntibodyNamesFromDirectories{ ################################################# # This subroutine checks for directories that match the same sector and # tissue array as the uniqid that is passed in. It returns the names of # all the valid antibodies as determined from the directory structure. my (@availableABs, @dirTemp, $dirRegExp, $tmpHolder); $dirRegExp = "C-TA-0*$tissueArray-0*$sector."; opendir (DIR, "$mainDir") || die "Cannot open directory $mainDir: $!\n"; @dirTemp = grep /$dirRegExp/, readdir(DIR); closedir (DIR); foreach (@dirTemp){ $tmpHolder = substr($_, rindex($_, ".")+1); push (@availableABs, substr($_, rindex($_, ".")+1)); $_ = "$webDir"."$_"; $jpgAndAbHash{substr($_, rindex($_, ".")+1)} = $_; } @availableABs = sort keys (%jpgAndAbHash); return @availableABs; } ################################################# sub CheckAntibodyNames{ ################################################# # This subroutine is called when antibodies are passed in from the CDT # file. It checks the CDT antibody names against the antibody names from # the directory structure, and splits the CDT antibodies into two arrays # of good names and bad names. foreach (@cdtAntibodies){ # strip anything that comes after a parentheses if(index($_, "(") != -1){ $_ = substr($_, 0, index($_, "(")); } } foreach (@cdtAntibodies) { if($jpgAndAbHash{$_}) { push(@goodAntibodyNames, $_); }else{ push(@badAntibodyNames, $_); } } } ################################################# sub GetFullJpgName{ ################################################# # This subroutine takes the chosen antibodies and appends the jpg name # to the directory value of the corresponding hash pairs my (@directories, $tmpHolder, @jpgTemp, $jpgRegExp); $jpgRegExp = "$sector"."_"."$tissueArray"."_"."$column"."_"."$row"."_"; foreach (@antibodyChoices){ $tmpHolder = $jpgAndAbHash{$_}; push (@directories, $jpgAndAbHash{$_}); opendir (JPG, "$rootDir"."$tmpHolder") || die "Cannot open directory $tmpHolder $!\n"; @jpgTemp = grep /$jpgRegExp/, readdir(JPG); closedir (JPG); if (@jpgTemp){ $jpgAndAbHash{$_} = "$tmpHolder"."/"."@jpgTemp"; }else{ $jpgAndAbHash{$_} = "No image found"; } } } ################################################# sub CreateTable{ ################################################# # This subroutine takes the jpg names and creates a table in # HTML for browser display if($fpNum){ print br,b("Slides from FP#$fpNum $fpFile"); } my (@rows, $row); my $numImagesPerRow = int($screenSize/$imageWidth); $numImagesPerRow = 1 if ($numImagesPerRow < 1); my $numRows = int(@antibodyChoices/$numImagesPerRow)+1; my $i = 0; #number of stains displayed my $j = 0; #number of row elements displayed while($i < @antibodyChoices){ $row .= td(&MakeOneStainTable($antibodyChoices[$i])); $j++; if ($j == $numImagesPerRow){ push(@rows, $row); $j = 0; $row = undef; } $i++; } #--this section unneeded if filler cells not desired--# my $numFillerCells; if ($numRows > 1 && @antibodyChoices%$numImagesPerRow){ $numFillerCells = $numImagesPerRow-(@antibodyChoices%$numImagesPerRow); } while($numFillerCells > 0){ #if filler cells needed $row .= td({-bgcolor=>'silver'},' '); $numFillerCells--; if ($numFillerCells == 0){ push(@rows, $row); $row = undef; } } push(@rows, $row) if defined $row; print table({-cellpadding=>'0', -border=>3, -bordercolor=>'black'}, Tr([@rows]) ); } ################################################# sub MakeOneStainTable{ ################################################# # This subroutine makes a table that contains one individual # stain (meaning rows containing image, antibody name, and # other formatting) my ($antibodyName) = @_; my (@rows); push(@rows, td({-bgcolor=>'black'}, ' ' )); push(@rows, &GetAbNameCell($antibodyName)); push(@rows, &GetImageCell($antibodyName)); push(@rows, td({-bgcolor=>'black'}, ' ' )); return table({-border=>1, -bordercolor=>'black'}, Tr([@rows]) ); } ################################################# sub GetImageCell{ ################################################# # This subroutine creates a table element containing the image # or an image not found list if the image is missing my ($antibodyName) = @_; if ($jpgAndAbHash{$antibodyName} eq "No image found"){ return td({-align=>'CENTER', -valign=>'MIDDLE', -width=>$imageWidth, -height=>$imageHeight}, 'No image found' ); }else{ return td({-align=>'CENTER'}, img {src=>'/tissue'."$jpgAndAbHash{$antibodyName}", width=>$imageWidth, height=>$imageHeight} ); } } ################################################# sub GetAbNameCell{ ################################################# # This subroutine prints the name of the antibody as a clickable # link within one table data element my ($antibodyName) = @_; if ($jpgAndAbHash{$antibodyName} eq "No image found"){ return td({-align=>'CENTER', -bgcolor=>'silver'}, b($antibodyName) ); }else{ return td({-align=>'CENTER', -bgcolor=>'silver'}, a({-href=>'/tissue'."$jpgAndAbHash{$antibodyName}", -target=>'_blank'}, b($antibodyName) ) ); } }