Index: src/ame.c =================================================================== --- src/ame.c (revision 5306) +++ src/ame.c (revision 5307) @@ -1053,7 +1053,6 @@ rsc_result_t** rsr; rsc_result_t* result; rsc_rank_t** rankings; - double highest_score = 0; //We use this to make sure that a pwm has scored on at least 1 seq. seq_num = get_num_strings(seq_ids); //number of sequences @@ -1061,8 +1060,9 @@ rsr = malloc(sizeof(rsc_result_t*)*motifs.num); for(i=0;i= HIGHER_VERBOSE) { - fprintf(stderr, "\n"); + ///*Debugging code. + if (args.verbose > HIGHER_VERBOSE) { + fprintf(stdout, "\n"); for (j=0; j < seq_num; j++) { - fprintf(stdout, "M: %s - Rankings[%i] -\tpwm: %.8f\tprank: %i\tf: %.8f\tfrank: %i\n", motifs.motifs[i].id, j, + fprintf(stdout, "M1: %s - Rankings[%i] -\tpwm: %.8f\tprank: %i\tf: %.8f\tfrank: %i\n", motifs.motifs[i*2].id, j, rankings[j]->pwm_score, rankings[j]->pwm_rank, rankings[j]->f_score, rankings[j]->f_rank); } @@ -1106,9 +1106,9 @@ ///Debugging code. if (args.verbose > HIGHER_VERBOSE) { - fprintf(stderr, "\n"); + fprintf(stdout, "\n"); for (j=0; j < seq_num; j++) { - fprintf(stdout, "M: %s - Seq: %s Rankings[%i] -\tpwm: %.8f\tprank: %i\tf: %.8f\tfrank: %i\n", motifs.motifs[i].id, get_nth_string(j,seq_ids), j, + fprintf(stdout, "M2: %s - Seq: %s Rankings[%i] -\tpwm: %.8f\tprank: %i\tf: %.8f\tfrank: %i\n", motifs.motifs[i*2].id, get_nth_string(j,seq_ids), j, rankings[j]->pwm_score, rankings[j]->pwm_rank, rankings[j]->f_score, rankings[j]->f_rank); } @@ -1129,7 +1129,8 @@ } } else { //If no sequence has scored at all, then we give a null result. - init_result (NULL, &motifs.motifs[i], seq_num, 1, 1, 1, -1); + // Bugfix, rsr[i] was not assigned the null result. + rsr[i] = init_result (NULL, &motifs.motifs[i], seq_num, 1, 1, 1, -1); } //Free up some space - TODO: Move this into a more appropriate place @@ -1552,7 +1553,7 @@ lowest_pval = pboth; init_result (lowest_motif_result, &motifs.motifs[motif_index*2], i+1, pboth, pboth, pboth, -1); if (args.verbose >= HIGH_VERBOSE) { - fprintf(stderr, "M: %s Threshold: %i a: %i b: %i c: %i d: %i Ptwo: %g P-left: %g P-right: %g P-this %g\n", + fprintf(stdout, "M3: %s Threshold: %i a: %i b: %i c: %i d: %i Ptwo: %g P-left: %g P-right: %g P-this %g\n", motifs.motifs[motif_index*2].id, i, a,b,c,d, pboth, pleft, pright, p); } } else { Index: website/cgi-bin/meme-chip.pl =================================================================== --- website/cgi-bin/meme-chip.pl (revision 5308) +++ website/cgi-bin/meme-chip.pl (revision 5321) @@ -351,9 +351,9 @@ $args = " |MEMESEQUENCES| -sf $datafile_name -$alphabet $options". " <|UP|> ". " -min-overlap 5 -dist pearson -evalue -thresh 0.1 -no-ssc ". - "|MEMEDIR|/meme.html |MOTIFDB|". - " |MEMEDIR|/meme.html sequences -ev |NSEQS|". - " --sdbg 0 |MEMEDIR|/meme.html sequences". + "|MEMEDIR|/meme.txt |MOTIFDB|". + " |MEMEDIR|/meme.txt sequences -ev |NSEQS|". + " --sdbg 0 |MEMEDIR|/meme.txt sequences". " <|DOWN|>". " -p |DREMESEQUENCES|". " <|UP|> ". Index: etc/meme-chip.txt =================================================================== --- etc/meme-chip.txt (revision 5308) +++ etc/meme-chip.txt (revision 5321) @@ -161,29 +161,29 @@ # "PSP" => [$pspargs, "FIXME: not used in this version"], "TOMTOMMEME" => [$tomtomargs.$tomtommemedir, "tomtom", ["tomtom.html", "tomtom.txt", "tomtom.xml"], - $tomtommemedir, + $tomtommemedir, "Motifs from |MOTIFDBNAMES|"." that match motifs ". "MEME discovers."], "AMA" => [$amaargs, "ama", ["", "ama.txt", "ama.xml"], $amadir, - "Estimated binding affinity of each MEME motif to each input sequence."], + "Estimated binding affinity of each MEME motif to each input sequence."], "AME" => [$ameargs, "ame", ["ame.html", "ame.txt", ""], $amedir, '|MOTIFDBNAMES|'." motifs enriched in the trimmed (central $CMAX". - "bp) input sequences."], + "bp) input sequences."], # "SPAMO" => [$spamoargs, "FIXME: not used in this version"], "TOMTOMDREME" => [$tomtomargs.$tomtomdremedir, "tomtom", ["tomtom.html", "tomtom.txt", "tomtom.xml"], - $tomtomdremedir, + $tomtomdremedir, "Motifs from |MOTIFDBNAMES|"." that match motifs ". "DREME discovers."], "DREME" => [$dremeargs, "dreme", ["", "dreme.txt", ""], $dremedir, - "Motifs discovered in the trimmed (central $CMAX". - "bp) input sequences.", + "Motifs discovered in the trimmed (central $CMAX". + "bp) input sequences.", undef, "dreme.txt"], "MEMEMAST" => [$mastargs." -oc $mememastdir", "mast", ["mast.html", "mast.txt", "mast.xml"], $mememastdir, @@ -229,6 +229,7 @@ #################################################################### my $args = join(' ', @ARGV); + # harvest any values defined in the command line in ":" variables # and store each as || to allow referencing in backend command lines # delete the part of the command line after : in case we need to @@ -257,12 +258,12 @@ my $argsleft = $args; $argsleft =~ s/\s+$//; # should be no white space at end but make sure &end_runs(\*HTMLFILE, $htmlstartind, $htmlreport, $htmlendind,$htmlreportinputs, - $htmlreportcommands, 1) + $htmlreportcommands, 1) unless $argsleft =~ /$/; # must end with while ($argsleft ne "") { my $name; die "malformed argument string: `$args'" - unless ($argsleft =~ /^(\s*?)<(\S+?)>(.*?)(.*?)"; @@ -275,13 +276,13 @@ next; } die "arguments for $2 defined more than once" - if exists($variables{$name}); + if exists($variables{$name}); my $value = $3; if (exists($arguments{$name})) { - $_ = ($arguments{$name}); - my $oldarg = \$$_[0]; - $$oldarg = $$oldarg.$value; - $args_log .= '<'.$name.'> '.$$_[0]." "; + $_ = ($arguments{$name}); + my $oldarg = \$$_[0]; + $$oldarg = $$oldarg.$value; + $args_log .= '<'.$name.'> '.$$_[0]." "; } else { print HTMLFILE "No predefined command line for `$name'
\n"; &end_runs (\*HTMLFILE, $htmlstartind, $htmlreport, $htmlendind,$htmlreportinputs, @@ -352,10 +353,10 @@ "seqs-sampled")); $final_seqs = "seqs-sampled"; $htmlreportinputs .= &report_job ( - "fasta-subsample (used)", ["seqs-sampled","",""], "", + "fasta-subsample (used)", ["seqs-sampled","",""], "", "a random sample of $MAXMEMESEQS of the centered sequences, used by MEME", $lowercase); $htmlreportinputs .= &report_job ( - "fasta-subsample (discarded)", ["seqs-discarded","",""], "", + "fasta-subsample (discarded)", ["seqs-discarded","",""], "", "the centered sequences omitted from the sample used by MEME", $lowercase); } else { $variables{'|SAMPLEDTEXT|'} = ""; @@ -380,12 +381,12 @@ &substitute ($oldcomment, \%variables); next; while ($$oldarg =~ /(\|\w+?\|)/) { - my $name = $1; - die "$name doesn't exist in `$$oldarg' or `$$oldcomment'" unless exists $variables{$name}; - my $name_search = $name; - # change all "|" to escaped "\|" so as not to confuse regex search - $name_search =~ s/\|/\\\|/g; - $$oldarg =~ s/$name_search/$variables{$name}/; + my $name = $1; + die "$name doesn't exist in `$$oldarg' or `$$oldcomment'" unless exists $variables{$name}; + my $name_search = $name; + # change all "|" to escaped "\|" so as not to confuse regex search + $name_search =~ s/\|/\\\|/g; + $$oldarg =~ s/$name_search/$variables{$name}/; } } @@ -416,8 +417,9 @@ print HTMLFILE $htmlendlist; # close the list used for command line reporting # log the run and finish the html &end_runs (\*HTMLFILE, $htmlstartind, $htmlreport, $htmlendind,$htmlreportinputs, - $htmlreportcommands, 0); + $htmlreportcommands, 0); + ################################################################################ # Subroutines # ################################################################################ @@ -543,7 +545,7 @@ my @db_no_paths = split (/, /, $databases); my $dbs_with_paths = ""; for (my $i = 0; $i < @db_no_paths; $i++) { - $dbs_with_paths .= $path."/".$db_no_paths[$i]." "; + $dbs_with_paths .= $path."/".$db_no_paths[$i]." "; } chop ($dbs_with_paths); # cut trailing space my $databasereport = $databases; @@ -569,9 +571,9 @@ # report_and_run # # run a job as specified un an entry in %arguments and return the -# output and command line reports +# output and command line reports # arguments (all string unless otherwise specified): -# $level: if defined, the number of indents for 1st table element +# $level: if defined, the number of indents for 1st table element # $bindir: directory containing executables # $args: command line arguments # $program: program name (executable's name) @@ -587,12 +589,26 @@ sub report_and_run { my ($level, $bindir, $args, $program, $outputs, $outputdir, $comment, $newstdin, $newstdout) = @_; + my $errorfile = $outputdir . "_stderr.txt"; + my $cmd = ""; + my $report = ""; + my $status = 0; + eval { + $cmd = &command_list (&run_job ($bindir, $program." ".$args, $newstdin, $newstdout, $errorfile, \$status), + $program, $outputs, $outputdir, $comment); + }; + if ($@) { + $cmd = $@; + } + eval { + $report = &report_job ($program, $outputs, $outputdir, $comment, undef, $level, $status); + }; + if ($@) { + $report = $@; + } - return ( - &command_list (&run_job ($bindir, $program." ".$args, $newstdin, $newstdout), - $program, $outputs, $outputdir, $comment), - &report_job ($program, $outputs, $outputdir, $comment, undef, - $level)); + + return ($cmd, $report); } ################################################################################ @@ -604,7 +620,7 @@ # STDOUT before completion; if a path should be appeneded to # the command or files, do that before calling run_job # arguments: -# $bindir: directory containing the binary; if empty or undef add no path +# $bindir: directory containing the binary; if empty or undef add no path # $commandline: command to execute with arguments # $stdin: alternative to standard input # $stdout: alternative to standard output @@ -615,7 +631,7 @@ # ################################################################################ sub run_job { - my($bindir, $commandline, $stdin, $stdout) = @_; + my($bindir, $commandline, $stdin, $stdout, $stderr, $status_ref) = @_; $_ = ($bindir?$bindir."/":"").$commandline; my @run_options = split; # hints from http://perldoc.perl.org/functions/open.html @@ -629,12 +645,29 @@ open OLDOUT, ">&STDOUT" or die "Can't dup STDOUT: $!"; open STDOUT, '>', $stdout or die "Can't redirect STDOUT: $!"; } + if ($stderr) { + open OLDERR, ">&STDERR" or die "Can't dup STDERR: $!"; + open STDERR, '>', $stderr or die "Can't redirect STDERR: $!"; + } # hints from http://perldoc.perl.org/functions/system.html and # http://stackoverflow.com/questions/1348639/how-can-i-reinitialize-perls-stdin-stdout-stderr - system(@run_options) == 0 or die "running `$commandline' ".defined($stdin) ? "< $stdin":"". - defined($stdout)?" > $stdout":""."' failed: $!"; - open STDIN, "<&OLDIN" or die "Can't redirect STDIN: $!" if ($stdin); - open STDOUT, ">&OLDOUT" or die "Can't dup \$oldout: $!" if ($stdout); + system(@run_options); + if (defined $status_ref) { + $$status_ref = $?; + } + if ($? == -1) { + print STDERR "Failed to execute command '$commandline': $!\n"; + } + elsif ($? & 127) { + printf STDERR "Process executing command '$commandline' died with signal %d, %s coredump.\n", + ($? & 127), ($? & 128) ? 'with' : 'without'; + } + elsif ($? != 0) { + printf STDERR "Process executing command '$commandline' exited with value %d indicating failure.\n", $? >> 8; + } + open STDIN, "<&OLDIN" or die "Can't reset STDIN: $!" if ($stdin); + open STDOUT, ">&OLDOUT" or die "Can't reset STDOUT: $!" if ($stdout); + open STDERR, ">&OLDERR" or die "Can't reset STDERR: $!" if ($stderr); return $commandline . ($stdin ? " < $stdin" : "") . ($stdout ? " > $stdout" : ""); } @@ -651,7 +684,7 @@ # arguments: # $command: use to identify output file(s) # if undefined leave blank -# if "input" replace "output" by "input" in file description +# if "input" replace "output" by "input" in file description # $outputs: array of file names for outputs: report # each only if the file exists # - if name is of form . report as @@ -662,7 +695,7 @@ # $outputdir: if defined, add to front of each output file # assumes no path separator ends the given name # $comment: if defined, add to end of output line -# $lowercase: if defined, don't change case of $command +# $lowercase: if defined, don't change case of $command # $level: if defined and > 0, indent by 2 * nonbreaking spaces # returns: # string containing HTML to report output files @@ -675,8 +708,15 @@ $outputdir, $comment, $lowercase, - $level + $level, + $status ) = @_; + my $errorfile = $outputdir."_stderr.txt"; + if ($outputdir) { + $outputdir = $outputdir."/"; # add path separator + } else { # make sure it's empty string, not undefined + $outputdir = ""; + } my $commandwidth = 225; my $filewidth = 150; my $indent = $level && $level > 0 ? ' ' x ($level*4) : ""; @@ -685,48 +725,33 @@ (defined($command)? # if command contains "input" don't call it output ## ($command =~ /input/? $command: - ($lowercase?$command:uc($command))." output"):"").":"; - if ($outputdir) { - $outputdir = $outputdir."/"; # add path separator - } else { # make sure it's empty string, not undefined - $outputdir = ""; + ($lowercase?$command:uc($command))." output"):"").":"; + if (-s $errorfile) { + $outputstring .= "
".$indent."("; + if ($status) { + $outputstring .= "Errors Occurred"; + } else { + $outputstring .= "Warnings"; + } + $outputstring .= ")"; } - my $emptyseen = 0; + + $outputstring .= ""; foreach my $filespec (@$outputs) { - my $format = $filespec; - # only report nonempty outputs, but leave space for the empty ones - $outputstring .= "" unless $emptyseen; - # if $filespec is empty or undefined don't add the path - if ($filespec) { - $filespec = $outputdir."$filespec" ; # add the path if any - if (-s $filespec) { - my $totalwidth = &fixwidth($emptyseen, $filewidth); - if ($emptyseen) { # finish off the empty cells, start full one - $outputstring .= "\n"; - } - $outputstring =~ s/FIXWIDTH/$totalwidth/; - $outputstring .= ""; - if ($format =~ /^([\w-.]+)\.([\w-]+)$/) { - $format = uc $2; - $format = "plain text" if $format eq "TXT"; - } - $outputstring .= "$format"; - $outputstring .= ""; - $emptyseen = 0; - } else { # although specified output doesn't exist: empty cell - $emptyseen++; - } - } else { # no output specified: empty cell - $emptyseen++; - } - } - - if ($emptyseen) { - # patch this in here because an empty string at the end of outputs can - # be missed by the foreach loop - $outputstring .= "" unless $outputstring =~ /FIXWIDTH/; - my $totalwidth = &fixwidth($emptyseen, $filewidth); - $outputstring =~ s/FIXWIDTH/$totalwidth/; + my $format = $filespec; + # only report nonempty outputs, but leave space for the empty ones + $outputstring .= ""; + # if $filespec is empty or undefined don't add the path + if ($filespec) { + $filespec = $outputdir."$filespec" ; # add the path if any + if (-s $filespec) { + if ($format =~ /^([\w-.]+)\.([\w-]+)$/) { + $format = uc $2; + $format = "plain text" if $format eq "TXT"; + } + $outputstring .= "$format"; + } + } $outputstring .= ""; } $outputstring .= "$comment" if ($comment); @@ -734,14 +759,6 @@ return $outputstring; } -sub fixwidth { - my ($emptyseen, $width) = @_; - return $width if $emptyseen < 1; - # for each veritical line we lose, we lose its width + 1 px padding either side - return $width * $emptyseen + ($emptyseen - 1)*3; -} - - ################################################################################ # # create_HTML_header @@ -759,25 +776,25 @@ MEME ChIP Output @@ -852,7 +869,7 @@ $htmlstartlist ."\n\n". $htmlreportinputs . "
\n" . $htmlendlist; print $htmlfile "

Commands

\n". - $htmlstartlist."\n". + $htmlstartlist."\n". $htmlreportcommands.$endcommandlist."\n".$htmlendlist; &finish_html (\*HTMLFILE); @@ -864,7 +881,7 @@ # command_list # # put a command line into a HTML code format, with -# any redirects sanitised +# any redirects sanitised # arguments: # $command: string to turn into HTML # returns: