comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:bc03dbb6eb37
1 package SDRecord;
2 # Perl module for reading/writing SD records from/to STDIN/STDOUT
3 # Methods: new
4 # readRec
5 # writeRec
6 # writeData
7 # copy
8 # addData
9 #
10 # Data: LINES - reference to array of record text lines
11 # DATA - reference to hash array of record data fields
12 # DATAREF - reference to hash array of line numbers for data fields
13
14 my $LINES = 'LINES';
15 my $DATA = 'DATA';
16 #DM 27 Sept 1999 - also store line number of beginning each data field
17 #so we can extract multi-line fields more easily from the LINES array
18 my $DATAREF = 'DATAREF';
19
20 ############################################################
21 # Constructor
22 sub new {
23 my $this = {};
24 bless $this;
25 return $this;
26 }
27
28 ############################################################
29 # readRec() - read next SD record from STDIN
30 # Input params:
31 # 'LINES' => any value - save lines
32 # 'DATA' => any value - save data
33 sub readRec {
34 my $this = shift;
35 my %params = @_;#input parameters
36 my @lines;#array for storing all text lines
37 my %data;#hash array for storing all data key,value pairs
38 my %dataref;#hash array for storing line number references for each data field
39 my ($fieldName,$ob,$cb);
40
41 #clear current data
42 delete $this->{$LINES};
43 delete $this->{$DATA};
44 delete $this->{$DATAREF};
45
46 #read lines from STDIN to the next record delimiter
47 #store in @lines array
48 #DM 16 Nov 1999 - can now cope with DOS text files directly
49 $/ = "\n";#Default Unix line separator
50 while (<>) {
51 chomp;#Get rid of Unix line separator
52 $/ = "\r";
53 chomp;#Get rid of DOS line separator
54 $/ = "\n";#Reset to normal Unix
55 last if ($_ eq '$$$$');#end of record
56 push @lines,$_;
57 #print "$_\n";
58 }
59
60 #check if we read anything
61 if (scalar(@lines) > 0) {
62 #store ref to @lines if required
63 $this->{$LINES} = \@lines if (defined $params{$LINES});
64 #search for data fields if required
65 if (defined $params{$DATA}) {
66 $fieldName = '';
67 my $lineNum = 0;
68 foreach $line (@lines) {
69 $lineNum++;
70 #DM 12 Jul 1999 - include the first three title lines as
71 #pseudo data fields
72 if ($lineNum <= 3) {
73 $data{"_TITLE$lineNum"} = $line;
74 #DM 20 Dec 1999 - include dimensionality (2D/3D) as pseudo data field
75 if ($lineNum == 2) {
76 $data{"_NDIM"} = substr($line,20,1);
77 }
78 }
79 #DM 05 Aug 1999 - include number of atoms as pseudo data field
80 elsif ($lineNum == 4) {
81 my @fields = split(" ",$line);
82 $data{"_NATOMS"} = $fields[0] if (scalar(@fields)>0);
83 }
84 if (index($line,'>') == 0) {#found a data field
85 $ob = index($line,'<');#first open bracket
86 $cb = rindex($line,'>');#last close bracket
87 if (($ob != -1) && ($cb != -1)) { #save field name
88 $fieldName = substr($line,$ob+1,$cb-$ob-1);
89 $dataref{$fieldName} = $lineNum-1;#store ref to line number
90 }
91 }
92 #if field name defined, then store first line of value
93 elsif ($fieldName ne '') {
94 $data{$fieldName} = $line;
95 $fieldName = '';#clear field name
96 }
97 }
98 #store ref to %data in $this
99 $this->{$DATA} = \%data;
100 $this->{$DATAREF} = \%dataref;
101 }
102 return 1;
103 }
104 else {
105 return 0;
106 }
107 }
108
109 ############################################################
110 # writeRec() - write current record to STDOUT (mol + data)
111 sub writeRec {
112 my $this = shift;
113 if (defined $this->{$LINES}) {
114 foreach $line (@{$this->{$LINES}}) {
115 print "$line\n";
116 }
117 print "\$\$\$\$\n";
118 }
119 }
120
121 ############################################################
122 # writeMol() - write current mol record to STDOUT
123 sub writeMol {
124 my $this = shift;
125 if (defined $this->{$LINES}) {
126 foreach $line (@{$this->{$LINES}}) {
127 print "$line\n";
128 last if ($line eq "M END");
129 }
130 }
131 }
132
133 ############################################################
134 # writeData() - list data field/values to STDOUT
135 sub writeData {
136 my $this = shift;
137 my ($keys ,$value, $lineNum );
138 if (defined $this->{$DATA}) {
139 foreach $key (sort keys %{$this->{$DATA}}) {
140 $value = $this->{$DATA}->{$key};
141 $lineNum = $this->{$DATAREF}->{$key};
142 #print "$key eq $value (line $lineNum)\n";
143 print "\$$key eq \"$value\"\n";
144 }
145 }
146 }
147
148 ############################################################
149 # copy() - create deep copy of SDRecord
150 # Input params:
151 # 'LINES' = any value - deep copy of lines
152 # 'DATA' = any value - deep copy of data and dataref
153
154 sub copy {
155 my $this = shift;
156 my %params = @_;#input parameters
157 my $clone = new SDRecord;
158 if ((defined $params{$LINES}) && (defined $this->{$LINES})) {
159 my @lines = @{$this->{$LINES}};
160 $clone->{$LINES} = \@lines;
161 }
162 if (defined $params{$DATA}) {
163 if (defined $this->{$DATA}) {
164 my %data = %{$this->{$DATA}};
165 $clone->{$DATA} = \%data;
166 }
167 # DM 24 Jul 2001 - DATAREF was missing from deep copy
168 # We copy the dataref array using the same DATA input parameter
169 # i.e. if the data is copied then so is dataref
170 if (defined $this->{$DATAREF}) {
171 my %dataref = %{$this->{$DATAREF}};
172 $clone->{$DATAREF} = \%dataref;
173 }
174 }
175 return $clone;
176 }
177
178 ############################################################
179 # addData() - adds data to data hash array
180 sub addData {
181 my $this = shift;
182 my %params = @_;#input parameters
183 #if the array is already defined then add to it
184 if (defined $this->{$DATA}) {
185 my ($keys ,$value );
186 while (($key, $value) = each (%params)) {
187 $this->{$DATA}->{$key} = $value;
188 }
189 }
190 #if not defined, then create it
191 else {
192 $this->{$DATA} = \%params;
193 }
194 }
195
196 ############################################################
197 # addDataAndLines() - adds data to data hash array,
198 # and adds corresponding lines also so that record may be
199 # rewritten with the new fields
200 sub addDataAndLines {
201 my $this = shift;
202 my %params = @_;#input parameters
203
204 while (($key, $value) = each (%params)) {
205 #DM 23 Oct 2000
206 #Check if data field already exists, if so replace value
207 #Note: this only works for single line data fields
208 if (defined $this->{$DATA}->{$key}) {
209 my $keyRef = $this->{$DATAREF}->{$key};
210 ${$this->{$LINES}}[$keyRef+1] = $value;
211 }
212 #else add the corresponding lines to the lines arrays
213 else {
214 my $keyRef = scalar(@{$this->{$LINES}});
215 $this->{$DATAREF}->{$key} = $keyRef;
216 push @{$this->{$LINES}},"> <$key>";
217 push @{$this->{$LINES}},"$value";
218 push @{$this->{$LINES}},"";
219 }
220 }
221
222 #DM 23 Oct 2000 - add data after adding the lines
223 $this->addData(%params);
224
225 }
226
227 1;