Using Perl/Python for SPIDER Scripting

As an alternative to SPIDER's procedural operations, the user can control SPIDER using Perl, Python, or shell scripts. This is feasible because SPIDER has little connectivity between routines dedicated to imaging operations and procedural operations. To implement this capability we have included three new operations in SPIDER Versions 7.10+.

SPIDER Operations For External Scripting

  1. MD with the PIPE option will open a named pipe to communicate register settings from SPIDER to the Perl/Python script.
  2. MD with the TO RESULTS option will divert the normal terminal interaction with user to the Results file.
  3. The PIPE REG operation will send the value of a register from SPIDER to the named pipe where it can be accessed from a Perl/Python script.

Scripting Notes

  1. The output of the Perl/Python control script can be piped directly into SPIDER. SPIDER communicates back to the control script via a "named pipe" (also called a FIFO). This mechanism should work in Unix and should also be adaptable for use under Windows 2000. (The code for writing to a pipe under SGI Fortran is non-standard and a Linux implementation may require addition of a C routine to communicate with the pipe). Named pipe communication only works for processes running on same processor.
  2. Some SPIDER operations take a "file name template" such as img*** to access files with a uniform number of digits e.g. img001.dat in the numerical portion of the name. Therefore we recommend that you not try to use the simpler numbering convention of: img1.dat ... img999.dat
  3. We do not recommend mixing SPIDER procedures and External Scripting without carefull testing. It may NOT work as expected!
  4. The following example is a first attempt a demonstrating usage. Clever Perl programmers can invent much more compact code. In particular, in Perl it is possible to use a second processing Perl script to obviate the need for the rather long: spi(" "); string which I use to transfer info to the output pipe. See an example in Python.

Comparison of SPIDER Procedures and Perl Scripting

Larger current versions of these examples are available in: b01.scr, b02.scr & b01.perl


Native SPIDER Sample Perl Script

; file: b01.scr ArDean Leith July 2001 	 
; Usage: spider scr @b01 	 

[testvar]=12 	          ; Set contents of: [testvar]
[testvar]                 ; Echo value of:   [testvar]	
	
IQ FI [exists]       	
b01                       ; Test existance of this file

[exists]                  ; Echo: 1 if b01.scr exists 	
	
DO [iter]=1,2             ; File loop example 	
	
   @b02([iter],[exists])  ; Invoke SPIDER procedure 
   VM	
   echo "b02 Returned: {***[exists]} 
	
ENDDO
 		
EN





([filenum],[exists])  
; b02.scr 	

IQ FI [exists]        ; Recovers existence flag in [exists]
jnk{***[filenum]}     ; File name	

RE 
   

#!/usr/bin/perl
# spiscript.perl (Should be executable) ArDean Leith July 2001
# Usage: spiscript.perl | spider dat

$\ = "\n";                           # Set Perl output record separator

$first = 1;                          # Flag for first pipe return

#spi("MD");           
#spi("TERM OFF");                    # Divert terminal output to RESULTS file

$pipename = "TMP_SPIDER_PIPE.pipe";  # Pipe name
print STDERR "Opening pipe: $pipename \n"; 
$FIFO = &openregpipe($pipename);     # Open pipe from SPIDER

spi("[testvar]=12");                 # Set contents of SPIDER variable: [testvar]
$regval = getreg("[testvar]");       # Retrieve SPIDER variable: [testvar]
print STDERR "  [testvar] = $regval \n";
	
spi("IQ FI [exists]");               # SPIDER pipe test
spi("spiscript.perl");               # Test existance of this file
	
$regval = getreg("[exists]");        # [exists] = 1 if spiscript.perl exists
print STDERR " [exists] = $regval \n";
		
for ($ifile=1; $ifile < 3; $ifile++) # File loop example
   {
   $iret=&b02($ifile);               # Invoke a Perl SPIDER procedure (b02)
   }
spi("EN");                           # End SPIDER session
exit;
	
	

sub b02        # A Perl SPIDER procedure example ----------------------------------
   {                                # INPUT:  File number
   local($ival,$str);
   $str = sprintf("%3.3d",$_[0]);   # SPIDER likes 001 type names
   spi("IQ FI [yes-exists]");       # Recovers information in [yesexists]
   spi("jnk$str");                  # Appends "jnk" to file number to make filename
   $ival = getreg("[yes-exists]");  # Ask SPIDER for variable: [yes-exists]
   return $ival;                    # Returns: value of variable: [yes-exists]
   }
 	
	
# My Common Perl support routines for SPIDER Usage -----------------------------
	
sub openregpipe             # Opens FIFO for SPIDER register input  ------------
  {                         # INPUT:  pipe name    (Argument #1)
  use IO::Handle;
  local($pipename,$iret);
  STDOUT->autoflush(1);
  $pipename = $_[0];        # Get pipe name from argument #1
  if (! -p $pipename)
      {$iret = system("mkfifo $pipename"); }
  open(FIFO, "+<".$pipename ) || die  $!;

  spi("MD");
  spi("PIPE");              # Opens output pipe in SPIDER
  spi($pipename);           # Name of pipe

  return FIFO;              # Returns pipe id
  }


	
sub getreg                 # Gets SPIDER register variable value from pipe -------
  {                        # INPUT: register number (argument # 1)
  local($reg,$regno,$regval);
  $\ = "\n";               # Set output record separator

  $reg = $_[0];            # Get register from argument #1 to this subroutine

  spi("PI REG");           # Tell SPIDER to put register variable value on pipe
  spi("$reg");             # Register variable wanted

  # FOR SGI USE FOLLOWING  LINE
  #($regval) = unpack("f",);     # Read register value from pipe

  # FOR INTEL BASED LINUX WITH SPIDER COMPILED WITH: -byteswapio USE THESE 5 LINES
  ($t0,$t1,$t2) = unpack("Nff",); # Read register value from pipe
  if ($first)              # I do not know why the difference or what t0 & t1 are!
     { $regval = $t1; $first = 0; }
  else
     { $regval = $t2; }

  return $regval;
  }
	
	
sub spi
  {   # Pipes argument to SPIDER after variable substitution ---------------
  #print STDERR "GOT:" . $_[0];
  local($string,$ret);
  s/"/\\"/g;                      # Substitutes: \" for: " 
  $string = $_[0];
  $ret    = eval qq/"$string"/;
  print $ret;                     # This sends string down the pipe
  }


Source: scripting.html     Last update: 21 Sept. 2007     ArDean Leith