Classify worm.pl

From Colettapedia
Jump to navigation Jump to search
#!/usr/bin/env perl
use strict;
use warnings;
use POSIX; #used to get timestamp
use File::Copy; #for the move() function
use File::stat; #to figure out time of file creation
use Linux::Inotify2; # kernel-level notifications

sub ProcessTiff($);

my $image_dir = "/home/eckleyd/ImageData/SortWorms/ImagesToBeScored";
my $source_dir = "$image_dir/1";
my $storage_dir = "/home/eckleyd/ImageData/SortWorms/ScoredImages";
my $logfile = "/home/eckleyd/RealTimeClassification/log.txt";
my $output_html = "/home/eckleyd/RealTimeClassification/itworked.html";

my $inotify = new Linux::Inotify2
    or die "unable to create new inotify object: $!";

# add watchers
$inotify->watch ($source_dir, IN_CLOSE, sub {
        my $e = shift;
        my $name = $e->fullname;
        print "events for $name have been lost\n" if $e->IN_Q_OVERFLOW;
        # check the file first:
        # -e = Does it exist? this callback will fire on the backend of a wndchrm
        #      ProcessTiff() operation which changes the name of the file, and moves it out of the way.
        # -s = Is the file non-zero in size?
        if( -e $name && -s $name && $name =~ /\.tif/  ) {
                print "File detected: $name";
                # check the filesize to make sure the file was actually written to disk
                # as opposed to being simply touched or created and released the lock
                my $filesize = stat( $name)->size;
                print ", size: $filesize\n";
                if( $filesize > 150000 ) {
                        &ProcessTiff( $name );
                }
        }
});

# manual event loop
1 while $inotify->poll;

sub ProcessTiff($)
{
        print "Processing file...\n";
        my $input_file = shift;
        my $seconds_since_epoch = stat( $input_file )->mtime; 
        my $timestamp = POSIX::strftime( "%F_%T", localtime( $seconds_since_epoch ) );
        my $creation_date = POSIX::strftime( "%F", localtime( $seconds_since_epoch) );
         
        #print $timestamp;
        move( $input_file, "$source_dir/$timestamp.tif" );

        $input_file = "$source_dir/$timestamp.tif";

        print "File renamed to: $input_file\n";
        # just in case
        unlink $output_html;
        #my $classify_command = "/home/colettace/src/wnd-charm/wndchrm/trunk/wndchrm classify -l -S1441 /home/eckleyd/terminal_bulb/AgeS1441L.fit $input_file /home/eckleyd/RealTimeClassification/$output_html";
        my $classify_command = "wndchrm classify -l -S1441 /home/eckleyd/terminal_bulb/AgeS1441L.fit $image_dir $output_html";
        print "\n\n" . $classify_command . "\n\n";
        system( $classify_command );
        if ($? == -1) {
                die "failed to execute: $!\n";
        }
        elsif ($? & 127) {
                printf STDERR "wndchrm died with signal %d, %s coredump\n", ($? & 127), ($? & 128) ? 'with' : 'without';
                die;
        }

        my $text;
        # slurp the file into a scalar
        if( !open( FH, $output_html ) )
        {
                die "could not open $output_html: $!\n";
        }
        $text = do { local( $/ ) ; <FH> } ;
        close FH;
        unlink $output_html;

        #print $text;

        # find the line with the interpolated value
        my $individual_results;
        if( !( $text =~ /<TABLE ID=\"IndividualImages_split0".*?>(.*)table>/s ) )
        {
                die "couldn't find interpolated values in file $output_html\n"
        }
        $individual_results = $1;
        #print $individual_results;
        my $line_item;
        if( !( $individual_results =~ /<tr><td>(.*)<\/td><\/tr>/s ) ) {
                die "couldn't pull out individual image line item out of report html $output_html\n";
        }
        $line_item = $1;
        #print $line_item;
        my @columns = split '</td><td>', $line_item;
        #my $count = 0;
        #foreach( @columns) {
        #       print $count . " $_\n";
        #       $count++;
        #}
        # The interpolated value is in the second to last column
        my $num_cols = $#columns;
        my $interpolated_value = $columns[$num_cols-1];
        my $predicted_class = $columns[$num_cols-3];
        my $normalization_factor = $columns[1];
        my $num_classes = $num_cols - 7; 
        my @marginal_probabilities = splice( @columns, 2, $num_classes );
        #my $count = 0;
        #foreach (@marginal_probabilities ) {
        #       print $count . " $_\n";
        #       $count++;
        #}
        print "File: $input_file, interpolated value: $interpolated_value\n";
        my $target_dir = "$storage_dir/$creation_date";
        mkdir $target_dir;
        if( !-e $target_dir or !-d $target_dir)
        {
                die "Could not make storage directory $target_dir: $!\n";
        }
        $target_dir = "$target_dir/$predicted_class";
        mkdir $target_dir;
        if( !-e $target_dir or !-d $target_dir)
        {
                die "Could not make storage directory $target_dir: $!\n";
        }
        my $cmd = "find $source_dir -name \"${timestamp}*\"";
        #print $cmd . "\n";
        my @files = `$cmd`;
        foreach ( @files )
        {
                chomp $_;
                move( $_ , $target_dir ) or die "********ERROR******* Could not move file $_ to $target_dir: $!\n";
                print "Moved $_ to $target_dir\n";
        }
        open(LOG, '>>', $logfile) or print STDERR "*****ERROR***** could not open log file $logfile: $!\n";
        my $summary_str = "File:\t$input_file\nInterp. val:\t$interpolated_value\nPred. class:\t$predicted_class\nNorm. factor:\t$normalization_factor\nMarg probs.:\t";
        print LOG "$input_file\t$interpolated_value\t$predicted_class\t$normalization_factor\t";
        foreach (@marginal_probabilities) {
                print LOG "$_\t";
                $summary_str .= "$_\t";
        }
        print LOG "\n";
        $summary_str .= "\n";
        close LOG;
        print "\nSUMMARY:\n";
        print $summary_str;
        print "Continuing to monitor directory $source_dir...\n\n";
}