diff tools/rdock/lib/SDRecord.pm @ 0:bc03dbb6eb37 draft

planemo upload commit 781926e52355f7805db8d9a4ccafeff397b19aa4-dirty
author marpiech
date Mon, 29 Aug 2016 03:38:13 -0400
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/rdock/lib/SDRecord.pm	Mon Aug 29 03:38:13 2016 -0400
@@ -0,0 +1,227 @@
+package SDRecord;
+# Perl module for reading/writing SD records from/to STDIN/STDOUT
+# Methods:  new
+#           readRec
+#           writeRec
+#           writeData
+#           copy
+#           addData
+#
+# Data:     LINES    - reference to array of record text lines
+#           DATA     - reference to hash array of record data fields
+#           DATAREF  - reference to hash array of line numbers for data fields
+
+my $LINES = 'LINES';
+my $DATA = 'DATA';
+#DM 27 Sept 1999 - also store line number of beginning each data field
+#so we can extract multi-line fields more easily from the LINES array
+my $DATAREF = 'DATAREF';
+
+############################################################
+# Constructor
+sub new {
+  my $this = {};
+  bless $this;
+  return $this;
+}
+
+############################################################
+# readRec() - read next SD record from STDIN
+# Input params:
+#   'LINES' => any value - save lines
+#   'DATA'  => any value - save data
+sub readRec {
+  my $this = shift;
+  my %params = @_;#input parameters
+  my @lines;#array for storing all text lines
+  my %data;#hash array for storing all data key,value pairs
+  my %dataref;#hash array for storing line number references for each data field
+  my ($fieldName,$ob,$cb);
+
+  #clear current data
+  delete $this->{$LINES};
+  delete $this->{$DATA};
+  delete $this->{$DATAREF};
+
+  #read lines from STDIN to the next record delimiter
+  #store in @lines array
+  #DM 16 Nov 1999 - can now cope with DOS text files directly
+  $/ = "\n";#Default Unix line separator
+  while (<>) {
+    chomp;#Get rid of Unix line separator
+    $/ = "\r";
+    chomp;#Get rid of DOS line separator
+    $/ = "\n";#Reset to normal Unix
+    last if ($_ eq '$$$$');#end of record
+    push @lines,$_;
+    #print "$_\n";
+  }
+
+  #check if we read anything
+  if (scalar(@lines) > 0) {
+    #store ref to @lines if required
+    $this->{$LINES} = \@lines if (defined $params{$LINES});
+    #search for data fields if required
+    if (defined $params{$DATA}) {
+      $fieldName = '';
+      my $lineNum = 0;
+      foreach $line (@lines) {
+	$lineNum++;
+	#DM 12 Jul 1999 - include the first three title lines as
+	#pseudo data fields
+	if ($lineNum <= 3) {
+	  $data{"_TITLE$lineNum"} = $line;
+	  #DM 20 Dec 1999 - include dimensionality (2D/3D) as pseudo data field
+	  if ($lineNum == 2) {
+	    $data{"_NDIM"} = substr($line,20,1);
+	  }
+	}
+	#DM 05 Aug 1999 - include number of atoms as pseudo data field
+	elsif ($lineNum == 4) {
+	  my @fields = split(" ",$line);
+	  $data{"_NATOMS"} = $fields[0] if (scalar(@fields)>0);
+	}
+	if (index($line,'>') == 0) {#found a data field
+	  $ob = index($line,'<');#first open bracket
+	  $cb = rindex($line,'>');#last close bracket
+	  if (($ob != -1) && ($cb != -1)) { #save field name
+	    $fieldName = substr($line,$ob+1,$cb-$ob-1);
+	    $dataref{$fieldName} = $lineNum-1;#store ref to line number
+	  }
+	}
+	#if field name defined, then store first line of value
+	elsif ($fieldName ne '') {
+	  $data{$fieldName} = $line;
+	  $fieldName = '';#clear field name
+	}
+      }
+      #store ref to %data in $this
+      $this->{$DATA} = \%data;
+      $this->{$DATAREF} = \%dataref;
+    }
+    return 1;
+  }
+  else {
+    return 0;
+  }
+}
+
+############################################################
+# writeRec() - write current record to STDOUT (mol + data)
+sub writeRec {
+  my $this = shift;
+  if (defined $this->{$LINES}) {
+    foreach $line (@{$this->{$LINES}}) {
+      print "$line\n";
+    }
+    print "\$\$\$\$\n";
+  }
+}
+
+############################################################
+# writeMol() - write current mol record to STDOUT
+sub writeMol {
+  my $this = shift;
+  if (defined $this->{$LINES}) {
+    foreach $line (@{$this->{$LINES}}) {
+      print "$line\n";
+      last if ($line eq "M  END");
+    }
+  }
+}
+
+############################################################
+# writeData() - list data field/values to STDOUT
+sub writeData {
+  my $this = shift;
+  my ($keys ,$value, $lineNum );
+  if (defined $this->{$DATA}) {
+    foreach $key (sort keys %{$this->{$DATA}}) {
+      $value = $this->{$DATA}->{$key};
+      $lineNum = $this->{$DATAREF}->{$key};
+      #print "$key eq $value (line $lineNum)\n";
+      print "\$$key eq \"$value\"\n";
+    }
+  }
+}
+
+############################################################
+# copy() - create deep copy of SDRecord
+# Input params:
+#   'LINES' = any value - deep copy of lines
+#   'DATA'  = any value - deep copy of data and dataref
+
+sub copy {
+  my $this = shift;
+  my %params = @_;#input parameters
+  my $clone = new SDRecord;
+  if ((defined $params{$LINES}) && (defined $this->{$LINES})) {
+    my @lines = @{$this->{$LINES}};
+    $clone->{$LINES} = \@lines;
+  }
+  if (defined $params{$DATA}) {
+    if (defined $this->{$DATA}) {
+      my %data = %{$this->{$DATA}};
+      $clone->{$DATA} = \%data;
+    }
+    # DM 24 Jul 2001 - DATAREF was missing from deep copy
+    # We copy the dataref array using the same DATA input parameter
+    # i.e. if the data is copied then so is dataref
+    if (defined $this->{$DATAREF}) {
+      my %dataref = %{$this->{$DATAREF}};
+      $clone->{$DATAREF} = \%dataref;
+    }
+  }
+  return $clone;
+}
+
+############################################################
+# addData() - adds data to data hash array
+sub addData {
+  my $this = shift;
+  my %params = @_;#input parameters
+  #if the array is already defined then add to it
+  if (defined $this->{$DATA}) {
+    my ($keys ,$value );
+    while (($key, $value) = each (%params)) {
+      $this->{$DATA}->{$key} = $value;
+    }
+  }
+  #if not defined, then create it
+  else {
+    $this->{$DATA} = \%params;
+  }
+}
+
+############################################################
+# addDataAndLines() - adds data to data hash array,
+# and adds corresponding lines also so that record may be
+# rewritten with the new fields
+sub addDataAndLines {
+  my $this = shift;
+  my %params = @_;#input parameters
+
+  while (($key, $value) = each (%params)) {
+    #DM 23 Oct 2000
+    #Check if data field already exists, if so replace value
+    #Note: this only works for single line data fields
+    if (defined $this->{$DATA}->{$key}) {
+      my $keyRef = $this->{$DATAREF}->{$key};
+      ${$this->{$LINES}}[$keyRef+1] = $value;
+    }
+    #else add the corresponding lines to the lines arrays
+    else {
+      my $keyRef = scalar(@{$this->{$LINES}});
+      $this->{$DATAREF}->{$key} = $keyRef;
+      push @{$this->{$LINES}},">  <$key>";
+      push @{$this->{$LINES}},"$value";
+      push @{$this->{$LINES}},"";
+    }
+  }
+
+  #DM 23 Oct 2000 - add data after adding the lines
+  $this->addData(%params);
+
+}
+
+1;