[Bio] / FigKernelPackages / FileIOFunctions.pm Repository:
ViewVC logotype

Annotation of /FigKernelPackages/FileIOFunctions.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.9 - (view) (download) (as text)

1 : chenry 1.1 use strict;
2 :     use FileHandle;
3 : chenry 1.8 use Fcntl qw/:DEFAULT :seek :flock/;
4 :     use Symbol 'qualify_to_ref';
5 :    
6 :     my $have_fsync;
7 :     eval {
8 :     require File::Sync;
9 :     $have_fsync++;
10 :     };
11 :    
12 : chenry 1.1
13 :     #--- This function just prints the given array reference to file with a different array element on each line ---#
14 :     sub PrintArrayToFile {
15 : chenry 1.9 my ($Filename,$ArrayRef,$Append) = @_;
16 : chenry 1.1
17 : chenry 1.9 if (defined($Append) && $Append == 1) {
18 :     open (OUTPUT, ">>$Filename");
19 :     } else {
20 :     open (OUTPUT, ">$Filename");
21 :     }
22 :     foreach my $Item (@{$ArrayRef}) {
23 :     if (length($Item) > 0) {
24 :     print OUTPUT $Item."\n";
25 : chenry 1.1 }
26 :     }
27 : chenry 1.9 close(OUTPUT);
28 : chenry 1.1 }
29 :    
30 :     sub PrintTwoDimensionalArrayToFile {
31 :     my ($Filename,$ArrayRef,$Delimiter) = @_;
32 :    
33 :     if (open (OUTPUT, ">$Filename")) {
34 :     foreach my $Item (@{$ArrayRef}) {
35 :     if (@{$Item} > 0) {
36 :     print OUTPUT join($Delimiter,@{$Item})."\n";
37 :     }
38 :     }
39 :     close(OUTPUT);
40 :     } else {
41 :     die "Cannot open $Filename: $!";
42 :     }
43 :     }
44 :    
45 :    
46 :     #--- This function removes the specified line from the file with the input filename if the line exists in the file ---#
47 :     sub RemoveSpecificLineFromFile {
48 :     my ($Filename,$DelLine,$Delimiter) = @_;
49 :    
50 :     #Note that I donot specify the delimiter to the file upload function because I want to preserve the entire content of the file
51 :     my $FileArray = &LoadSingleColumnFile($Filename,"");
52 :     my $Count = 0;
53 :     foreach my $Item (@{$FileArray}) {
54 :     my @Data = split(/$Delimiter/,$Item);
55 :     if ($Data[0] eq $DelLine) {
56 :     delete $FileArray->[$Count];
57 :     }
58 :     $Count++;
59 :     }
60 :     &PrintArrayToFile($Filename,$FileArray);
61 :     }
62 :    
63 :     #--- This function adds the input line to the file with the input filename if the line does not already exist in the file ---#
64 :     sub AddLineToFileUnique {
65 :     my ($Filename,$NewLine,$Delimiter) = @_;
66 :     my $FileArray = &LoadSingleColumnFile($Filename,$Delimiter);
67 : chenry 1.3 my $LastLineLength = 0;
68 : chenry 1.1 foreach my $Item (@{$FileArray}) {
69 : chenry 1.3 $LastLineLength = length($Item);
70 : chenry 1.1 if ($Item eq $NewLine) {
71 :     return;
72 :     }
73 :     }
74 :     if (open (OUTPUT, ">>$Filename")) {
75 : chenry 1.3 if ($LastLineLength > 0) {
76 :     print OUTPUT "\n";
77 :     }
78 : chenry 1.1 print OUTPUT $NewLine."\n";
79 :     close(OUTPUT);
80 :     } else {
81 :     die "Cannot open $Filename: $!";
82 :     }
83 :     }
84 :    
85 :     #--- This function saves the input hash back to a file where each data item is stored on a separate line with the file headings stored in the first column of data ---#
86 :     sub SaveHashToHorizontalDataFile {
87 :     my ($Filename,$Delimiter,$DataHashRef) = @_;
88 :    
89 :     if (!defined($DataHashRef->{"orderedkeys"})) {
90 :     my @Keys = keys(%{$DataHashRef});
91 :     push(@{$DataHashRef->{"orderedkeys"}},@Keys);
92 :     }
93 :    
94 :     if ($Filename eq "") {
95 :     open (HASHTOHORIZONTALOUTPUT, ">&STDOUT");
96 :     } else {
97 :     open (HASHTOHORIZONTALOUTPUT, ">$Filename");
98 :     }
99 :    
100 :     if (open (HASHTOHORIZONTALOUTPUT, ">$Filename")) {
101 :     my @ReactionKeys = @{$DataHashRef->{"orderedkeys"}};
102 :     foreach my $Item (@ReactionKeys) {
103 :     if (defined($DataHashRef->{"keytranslation"}) && defined($DataHashRef->{"keytranslation"}->{$Item})) {
104 :     $Item = $DataHashRef->{"keytranslation"}->{$Item};
105 :     }
106 :     if (defined($DataHashRef->{$Item}) && @{$DataHashRef->{$Item}} > 0) {
107 :     print HASHTOHORIZONTALOUTPUT $Item.$Delimiter.join($Delimiter,@{$DataHashRef->{"$Item"}})."\n";
108 :     }
109 :     }
110 :     close(HASHTOHORIZONTALOUTPUT);
111 :     } else {
112 :     die "Cannot open $Filename: $!";
113 :     }
114 :    
115 :     return $DataHashRef;
116 :     }
117 :    
118 :     #--- This function loads a file where each data item is stored on a separate line with the file headings stored in the first column of data ---#
119 :     sub LoadHorizontalDataFile {
120 :     my ($Filename,$Delimiter,$HeadingTranslation) = @_;
121 :    
122 :     my $DataHashRef = {};
123 :    
124 :     if (open (INPUT, "<$Filename")) {
125 :     while (my $Line = <INPUT>) {
126 :     chomp($Line);
127 :     my @Data = split(/$Delimiter/,$Line);
128 :     if (defined($HeadingTranslation) && defined($HeadingTranslation->{$Data[0]})) {
129 :     $DataHashRef->{"keytranslation"}->{$HeadingTranslation->{$Data[0]}} = $Data[0];
130 :     $Data[0] = $HeadingTranslation->{$Data[0]};
131 :     }
132 :     for (my $i=1; $i < @Data; $i++) {
133 :     $DataHashRef->{$Data[0]}->[$i-1] = $Data[$i];
134 :     }
135 :     if (@Data > 1) {
136 :     push(@{$DataHashRef->{"orderedkeys"}},$Data[0]);
137 :     }
138 :     }
139 :     close(INPUT);
140 :     } else {
141 :     die "Cannot open $Filename: $!";
142 :     }
143 :    
144 :     return $DataHashRef;
145 :     }
146 :    
147 :    
148 :     #--- This function loads a file containing a simple list and returns a reference to an array containing that list ---#
149 :     #--- Note that when a delimiter is supplied, each line in the file is broken up with the delimiter, and only the first element from each line is stored in the returned list ---#
150 :     sub LoadSingleColumnFile {
151 :     my ($Filename,$Delimiter) = @_;
152 :    
153 :     my $DataArrayRef = [];
154 :     if (open (INPUT, "<$Filename")) {
155 :     while (my $Line = <INPUT>) {
156 :     chomp($Line);
157 :    
158 :     if (length($Delimiter) > 0) {
159 :     my @Data = split(/$Delimiter/,$Line);
160 :     $Line = $Data[0];
161 :     }
162 :    
163 :     push(@{$DataArrayRef},$Line);
164 :     }
165 :     close(INPUT);
166 :     } else {
167 :     die "Cannot open $Filename: $!";
168 :     }
169 :     return $DataArrayRef;
170 :     }
171 :    
172 :     #--- This function loads a file containing multiple columns of data with no file headings ---#
173 :     sub LoadMultipleColumnFile {
174 :     my ($Filename,$Delimiter) = @_;
175 :    
176 :     my $DataArrayRefArrayRef = [];
177 :     if (open (INPUT, "<$Filename")) {
178 :     while (my $Line = <INPUT>) {
179 :     chomp($Line);
180 :     my $Data = [];
181 :     $Data->[0] = $Line;
182 :     if (length($Delimiter) > 0) {
183 :     @{$Data} = split(/$Delimiter/,$Line);
184 :     }
185 :     push(@{$DataArrayRefArrayRef},$Data);
186 :     }
187 :     close(INPUT);
188 :     } else {
189 :     die "Cannot open $Filename: $!";
190 :     }
191 :     return $DataArrayRefArrayRef;
192 :     }
193 :    
194 :     #--- This function loads a file containing multiple columns of data with file headings at the top ---#
195 :     sub LoadMultipleLabeledColumnFile {
196 :     my ($Filename,$ColumnDelimiter,$ItemDelimiter,$HeadingRowNumber) = @_;
197 :     if (!defined($HeadingRowNumber) || $HeadingRowNumber eq "") {
198 :     $HeadingRowNumber = 0;
199 :     }
200 :     my $DataHashRefArrayRef = [];
201 :     if (open (INPUT, "<$Filename")) {
202 :     my $Line = <INPUT>;
203 :     for (my $i=0; $i < $HeadingRowNumber; $i++) {
204 :     $Line = <INPUT>;
205 :     }
206 :     chomp($Line);
207 :     if (length($ColumnDelimiter) > 0) {
208 :     my @Headings = split(/$ColumnDelimiter/,$Line);
209 : chenry 1.2 my $First = 1;
210 : chenry 1.1 while ($Line = <INPUT>) {
211 :     chomp($Line);
212 :     my @Data = split(/$ColumnDelimiter/,$Line);
213 :     my $ArrayRefHashRef;
214 :     for (my $i=0; $i < @Headings; $i++) {
215 :     if (defined($Data[$i]) && length($Data[$i]) > 0) {
216 : chenry 1.3 if (defined($ItemDelimiter) && length($ItemDelimiter) > 0) {
217 : chenry 1.1 my @TempArray = split(/$ItemDelimiter/,$Data[$i]);
218 :     foreach my $Item (@TempArray) {
219 :     push(@{$ArrayRefHashRef->{$Headings[$i]}},$Item);
220 :     }
221 :     } else {
222 :     $ArrayRefHashRef->{$Headings[$i]}->[0] = $Data[$i];
223 :     }
224 :     }
225 :     }
226 : chenry 1.2 if ($First == 1) {
227 :     $First = 0;
228 :     push(@{$ArrayRefHashRef->{"orderedkeys"}},@Headings);
229 :     }
230 :     push(@{$DataHashRefArrayRef},$ArrayRefHashRef);
231 : chenry 1.1 }
232 :     }
233 :     close(INPUT);
234 :     } else {
235 :     die "Cannot open $Filename: $!";
236 :     }
237 :     return $DataHashRefArrayRef;
238 :     }
239 :    
240 :     sub PrintHashArrayToFile {
241 : chenry 1.3 my ($Filename,$HashArrayRef,$HeaderRef,$ExtraHeaders) = @_;
242 : chenry 1.5
243 : chenry 1.2 if (!defined($HeaderRef) || $HeaderRef == 0 || $HeaderRef eq "") {
244 :     if (!defined($HashArrayRef->[0]) || !defined($HashArrayRef->[0]->{"orderedkeys"})) {
245 : chenry 1.5 return;
246 : chenry 1.2 } else {
247 :     $HeaderRef = $HashArrayRef->[0]->{"orderedkeys"};
248 :     }
249 :     }
250 : chenry 1.5
251 : chenry 1.1 if (open (HASHARRAYTOFILE, ">$Filename")) {
252 : chenry 1.3 if (defined($ExtraHeaders)) {
253 :     print HASHARRAYTOFILE $ExtraHeaders;
254 : chenry 1.1 }
255 : chenry 1.5 print HASHARRAYTOFILE join(";",@{$HeaderRef})."\n";
256 : chenry 1.1 for (my $i=0; $i < @{$HashArrayRef}; $i++) {
257 :     for (my $j=0; $j < @{$HeaderRef}; $j++) {
258 :     if ($j > 0) {
259 : chenry 1.5 print HASHARRAYTOFILE ";";
260 : chenry 1.1 }
261 :     if (defined($HashArrayRef->[$i]->{$HeaderRef->[$j]})) {
262 :     print HASHARRAYTOFILE join("|",@{$HashArrayRef->[$i]->{$HeaderRef->[$j]}});
263 :     }
264 :     }
265 : chenry 1.5 print HASHARRAYTOFILE "\n";
266 : chenry 1.1 }
267 :     close (HASHARRAYTOFILE);
268 :     }
269 :     }
270 :    
271 : chenry 1.4 sub LoadTable {
272 : chenry 1.5 my ($VariableHash,$Filename,$Delimiter,$ItemDelimiter,$HeadingLine,$HashColumns) = @_;
273 :    
274 : chenry 1.4 #Checking that the table file exists
275 :     if (!-e $Filename) {
276 : chenry 1.5 return undef;
277 : chenry 1.4 }
278 : chenry 1.5
279 : chenry 1.4 #Sanity checking input values
280 :     if (!defined($HeadingLine) || $HeadingLine eq "") {
281 :     $HeadingLine = 0;
282 :     }
283 :     if (!defined($Delimiter) || $Delimiter eq "") {
284 :     $Delimiter = ";";
285 :     }
286 : chenry 1.5 if ($Delimiter eq "|") {
287 :     $Delimiter = "\\|";
288 :     }
289 : chenry 1.4 if (!defined($ItemDelimiter) || $ItemDelimiter eq "") {
290 :     $ItemDelimiter = "";
291 : chenry 1.5 } elsif ($ItemDelimiter eq "|") {
292 :     $ItemDelimiter = "\\|";
293 : chenry 1.4 }
294 : chenry 1.5
295 : chenry 1.4 #Loading the data table
296 :     my $Table;
297 :     my $Prefix;
298 :     my @Headings;
299 :     if (!open (TABLEINPUT, "<$Filename")) {
300 :     return undef;
301 :     }
302 :     my $Line = <TABLEINPUT>;
303 :     for (my $i=0; $i < $HeadingLine; $i++) {
304 : chenry 1.5 $Prefix .= $Line;
305 : chenry 1.4 $Line = <TABLEINPUT>;
306 :     }
307 :     chomp($Line);
308 : chenry 1.5
309 : chenry 1.4 @Headings = split(/$Delimiter/,$Line);
310 :     while ($Line = <TABLEINPUT>) {
311 :     chomp($Line);
312 :     my @Data = split(/$Delimiter/,$Line);
313 :     my $ArrayRefHashRef;
314 :     for (my $i=0; $i < @Headings; $i++) {
315 :     if (defined($Data[$i]) && length($Data[$i]) > 0) {
316 :     if (defined($ItemDelimiter) && length($ItemDelimiter) > 0) {
317 :     my @TempArray = split(/$ItemDelimiter/,$Data[$i]);
318 :     foreach my $Item (@TempArray) {
319 :     push(@{$ArrayRefHashRef->{$Headings[$i]}},$Item);
320 :     }
321 :     } else {
322 :     $ArrayRefHashRef->{$Headings[$i]}->[0] = $Data[$i];
323 :     }
324 :     }
325 :     }
326 :     push(@{$Table->{"array"}},$ArrayRefHashRef);
327 :     }
328 :     close(TABLEINPUT);
329 : chenry 1.5
330 : chenry 1.4 #Loading file IO parameters
331 :     $Table->{"file IO settings"}->{"filename"}->[0] = $Filename;
332 : chenry 1.5 if ($Delimiter eq "\\|") {
333 :     $Delimiter = "|";
334 :     }
335 : chenry 1.4 $Table->{"file IO settings"}->{"delimiter"}->[0] = $Delimiter;
336 : chenry 1.5 if ($ItemDelimiter eq "\\|") {
337 :     $ItemDelimiter = "|";
338 :     }
339 : chenry 1.4 $Table->{"file IO settings"}->{"item delimiter"}->[0] = $ItemDelimiter;
340 :     $Table->{"file IO settings"}->{"file prefix"}->[0] = $Prefix;
341 :     push(@{$Table->{"file IO settings"}->{"orderedkeys"}},@Headings);
342 :     #Replacing variables in variable columns with variable values and loading hash with hash column keys
343 :     foreach my $ItemData (@{$Table->{"array"}}) {
344 :     if (defined($HashColumns) && $HashColumns ne "") {
345 :     foreach my $Heading (@{$HashColumns}) {
346 :     if (defined($ItemData->{$Heading})) {
347 :     for (my $i=0; $i < @{$ItemData->{$Heading}}; $i++) {
348 :     push(@{$Table->{$ItemData->{$Heading}->[$i]}},$ItemData);
349 : chenry 1.5 push(@{$Table->{"hash columns"}->{$Heading}->{$ItemData->{$Heading}->[$i]}},$ItemData);
350 : chenry 1.4 }
351 :     }
352 :     }
353 :     }
354 :     }
355 : chenry 1.5
356 : chenry 1.4 return $Table;
357 :     }
358 :    
359 :     sub SaveTable {
360 :     my ($TableRef) = @_;
361 : chenry 1.5
362 : chenry 1.4 #Checking that a filename exists
363 :     if (!defined($TableRef->{"array"}) || !defined($TableRef->{"file IO settings"}->{"filename"}) || !defined($TableRef->{"file IO settings"}->{"orderedkeys"})) {
364 :     return -1;
365 :     }
366 : chenry 1.5
367 : chenry 1.4 my $Filename = $TableRef->{"file IO settings"}->{"filename"}->[0];
368 :     my $Delimiter = ";";
369 :     my $ItemDelimiter = "|";
370 :     my $Prefix = "";
371 :     if (defined($TableRef->{"file IO settings"}->{"delimiter"})) {
372 : chenry 1.5 $Delimiter = $TableRef->{"file IO settings"}->{"delimiter"}->[0];
373 :     if ($Delimiter eq "\\|" || $Delimiter eq "\|") {
374 :     $Delimiter = "|";
375 : chenry 1.9 } elsif ($Delimiter eq "\\t") {
376 :     $Delimiter = "\t";
377 : chenry 1.5 }
378 : chenry 1.4 }
379 :     if (defined($TableRef->{"file IO settings"}->{"item delimiter"})) {
380 :     $ItemDelimiter = $TableRef->{"file IO settings"}->{"item delimiter"}->[0];
381 : chenry 1.5 if ($ItemDelimiter eq "\\|" || $ItemDelimiter eq "\|") {
382 :     $ItemDelimiter = "|";
383 : chenry 1.9 } elsif ($Delimiter eq "\\t") {
384 :     $Delimiter = "\t";
385 : chenry 1.5 }
386 : chenry 1.4 }
387 :     if (defined($TableRef->{"file IO settings"}->{"file prefix"})) {
388 :     $Prefix = $TableRef->{"file IO settings"}->{"file prefix"}->[0];
389 :     }
390 : chenry 1.5
391 : chenry 1.4 #Opening the file
392 :     if (defined($TableRef->{"file IO settings"}->{"append"})) {
393 :     if (!open (SAVINGTABLE, ">>$Filename")) {
394 :     return -1;
395 :     }
396 :     } else {
397 :     if (!open (SAVINGTABLE, ">$Filename")) {
398 :     return -1;
399 :     }
400 :     }
401 : chenry 1.5
402 :     if (defined($Prefix)) {
403 :     print SAVINGTABLE $Prefix;
404 :     }
405 :     print SAVINGTABLE join($Delimiter,@{$TableRef->{"file IO settings"}->{"orderedkeys"}})."\n";
406 : chenry 1.4 for (my $i=0; $i < @{$TableRef->{"array"}}; $i++) {
407 :     for (my $j=0; $j < @{$TableRef->{"file IO settings"}->{"orderedkeys"}}; $j++) {
408 :     if ($j > 0) {
409 : chenry 1.5 print SAVINGTABLE $Delimiter;
410 : chenry 1.4 }
411 :     if (defined($TableRef->{"array"}->[$i]->{$TableRef->{"file IO settings"}->{"orderedkeys"}->[$j]})) {
412 : chenry 1.9 if(ref($TableRef->{"array"}->[$i]->{$TableRef->{"file IO settings"}->{"orderedkeys"}->[$j]}) eq 'ARRAY') {
413 :     print SAVINGTABLE join($ItemDelimiter,@{$TableRef->{"array"}->[$i]->{$TableRef->{"file IO settings"}->{"orderedkeys"}->[$j]}});
414 :     } else {
415 :     print SAVINGTABLE $TableRef->{"array"}->[$i]->{$TableRef->{"file IO settings"}->{"orderedkeys"}->[$j]};
416 :     }
417 : chenry 1.4 }
418 :     }
419 : chenry 1.5 print SAVINGTABLE "\n";
420 : chenry 1.4 }
421 :     close (SAVINGTABLE);
422 :     }
423 :    
424 : chenry 1.5 sub copy_table_row {
425 :     my ($InRow) = @_;
426 :    
427 :     my $NewRow;
428 :     my @Headings = keys(%{$InRow});
429 :     foreach my $Heading (@Headings) {
430 :     push(@{$NewRow->{$Heading}},@{$InRow->{$Heading}});
431 :     }
432 :    
433 :     return $NewRow;
434 :     }
435 :    
436 : chenry 1.1 #--- This function loads a file with the following on each line: $A$Delimiter$B and maps $A to $B in the first returned hash reference and $B to $A in the second returned hash reference ---#
437 :     sub LoadSeparateTranslationFiles {
438 :     my ($Filename,$Delimiter) = @_;
439 :     my $HashReferenceForward = {};
440 :     my $HashReferenceReverse = {};
441 :    
442 :     if (open (INPUT, "<$Filename")) {
443 :     while (my $Line = <INPUT>) {
444 :     chomp($Line);
445 :     my @Data = split(/$Delimiter/,$Line);
446 :     if (@Data >= 2) {
447 : chenry 1.5 if (!defined($HashReferenceForward->{$Data[0]})) {
448 :     $HashReferenceForward->{$Data[0]} = $Data[1];
449 :     }
450 :     if (!defined($HashReferenceForward->{$Data[1]})) {
451 :     $HashReferenceReverse->{$Data[1]} = $Data[0];
452 :     }
453 : chenry 1.1 }
454 :     }
455 :     close(INPUT);
456 :     }
457 :    
458 :     return ($HashReferenceForward,$HashReferenceReverse);
459 :     }
460 :    
461 :     #--- This function breaks down the input filename into a directory, filename, and extension ---#
462 :     sub ParseFilename {
463 :     my ($Filename) = @_;
464 :    
465 :     my $Directory = "";
466 :     my $Extension = "";
467 : chenry 1.3 if ($Filename =~ m/^(.+\/)([^\/]+)\.([^\.]+)/) {
468 :     $Directory = $1;
469 :     $Filename = $2;
470 :     $Extension = $3;
471 : chenry 1.1 }
472 :    
473 :     return ($Filename,$Directory,$Extension);
474 :     }
475 :    
476 :     #--- This function compares the files listed in two separate directories and returns the list of new files and updated files ---#
477 :     sub CompareDirectories {
478 :     my ($NewDirectory,$OldDirectory,$ComparisonType) = @_;
479 :    
480 :     my $Command = "ls -la ".$NewDirectory." > ".$NewDirectory."FileList.txt";
481 :     system($Command);
482 :     $Command = "ls -la ".$OldDirectory." > ".$OldDirectory."FileList.txt";
483 :     system($Command);
484 :    
485 :     my $NewFileData = &LoadMultipleColumnFile($NewDirectory."FileList.txt","\\s");
486 :     my $OldFileData = &LoadMultipleColumnFile($OldDirectory."FileList.txt","\\s");
487 :    
488 :     my $UpdatedFiles = [];
489 :     my $NewFiles = [];
490 :    
491 :     my %FilenameHash;
492 :     foreach my $File (@{$OldFileData}) {
493 :     if ($ComparisonType eq "date") {
494 :     $FilenameHash{$File->[$#{$File}]} = $File->[$#{$File}-2].":".$File->[$#{$File}-1];
495 :     } elsif ($ComparisonType eq "size") {
496 :     $FilenameHash{$File->[$#{$File}]} = $File->[$#{$File}-3];
497 :     }
498 :     }
499 :     foreach my $File (@{$NewFileData}) {
500 :     if (defined($FilenameHash{$File->[$#{$File}]})) {
501 :     if ($ComparisonType eq "date" && $FilenameHash{$File->[$#{$File}]} ne $File->[$#{$File}-2].":".$File->[$#{$File}-1]) {
502 :     push(@{$UpdatedFiles},$File->[$#{$File}]);
503 :     } elsif ($ComparisonType eq "size" && $FilenameHash{$File->[$#{$File}]} ne $File->[$#{$File}-3]) {
504 :     push(@{$UpdatedFiles},$File->[$#{$File}]);
505 :     }
506 :     } else {
507 :     $FilenameHash{$File->[$#{$File}]} = $File->[$#{$File}-2].":".$File->[$#{$File}-1];
508 :     push(@{$NewFiles},$File->[$#{$File}]);
509 :     }
510 :     }
511 :    
512 :     return ($NewFiles,$UpdatedFiles);
513 :     }
514 :    
515 :     sub RemoveHFromFormula {
516 :     my ($Formula) = @_;
517 :     my @Data = split(/H/,$Formula);
518 :    
519 :     if (@Data == 1) {
520 :     return $Formula;
521 :     }
522 :    
523 :     while ($Data[1] =~ m/^\d/) {
524 :     $Data[1] = substr($Data[1],1);
525 :     }
526 :    
527 :     return $Data[0].$Data[1];
528 :     }
529 :    
530 :     sub CompareArrays {
531 :     my ($ArrayOne,$ArrayTwo) = @_;
532 :    
533 :     my $ArrayOneExtra = ();
534 :     my $ArrayTwoExtra = ();
535 :     my $ArrayOverlap = ();
536 :     my %ArrayTwoHash;
537 :    
538 :     for (my $i=0; $i < @{$ArrayOne}; $i++) {
539 :     my $Match = 0;
540 :     for (my $j=0; $j < @{$ArrayTwo}; $j++) {
541 :     if ($ArrayOne->[$i] eq $ArrayTwo->[$j]) {
542 :     $ArrayTwoHash{$ArrayOne->[$i]} = 1;
543 :     $Match = 1;
544 :     push(@{$ArrayOverlap},$ArrayOne->[$i]);
545 :     $j = @{$ArrayTwo};
546 :     }
547 :     }
548 :     if ($Match == 0) {
549 :     push(@{$ArrayOneExtra},$ArrayOne->[$i]);
550 :     }
551 :     }
552 :     for (my $j=0; $j < @{$ArrayTwo}; $j++) {
553 :     if (!defined($ArrayTwoHash{$ArrayTwo->[$j]})) {
554 :     push(@{$ArrayTwoExtra},$ArrayTwo->[$j]);
555 :     }
556 :     }
557 :    
558 :     return ($ArrayOneExtra,$ArrayTwoExtra,$ArrayOverlap);
559 :     }
560 :    
561 :     sub ReplaceLineSubstringsFromHash {
562 :     my ($Translation, $Line) = @_;
563 :    
564 :     my @Data = keys(%{$Translation});
565 :     for (my $i=0; $i < @Data; $i++) {
566 :     my $FindString = $Data[$i];
567 :     my $ReplaceString = $Translation->{$Data[$i]};
568 :     $Line =~ s/([\,\s\;\+\[])$FindString([\,\s\;\+\[])/$1$ReplaceString$2/g;
569 :     $Line =~ s/$FindString$/$ReplaceString/g;
570 :     $Line =~ s/^$FindString/$ReplaceString/g;
571 :     }
572 :    
573 :     return $Line;
574 :     }
575 :    
576 :     sub FindArrayElement {
577 :     my ($ArrayRef,$Value) = @_;
578 :    
579 :     if (!defined($ArrayRef)) {
580 :     return -1;
581 :     }
582 :    
583 :     for (my $i=0;$i < @{$ArrayRef};$i++) {
584 :     if ($ArrayRef->[$i] eq $Value) {
585 :     return $i;
586 :     }
587 :     }
588 :    
589 :     return -1;
590 :     }
591 :    
592 :     sub RemoveArrayElement {
593 :     my ($ArrayRef,$Value) = @_;
594 :    
595 : chenry 1.5 for (my $i=0;$i < @{$ArrayRef};$i++) {
596 :     if ($ArrayRef->[$i] eq $Value) {
597 :     splice(@{$ArrayRef},$i,1);
598 : chenry 1.1 $i--;
599 : chenry 1.5 }
600 :     }
601 : chenry 1.1
602 : chenry 1.5 return $ArrayRef;
603 : chenry 1.1 }
604 :    
605 :     sub FormatNumber {
606 :     my ($OriginalNumber,$Digits,$ZeroEquivalence) = @_;
607 : chenry 1.5
608 : chenry 1.1 if (abs($OriginalNumber) < $ZeroEquivalence) {
609 :     $OriginalNumber = "0.";
610 :     for (my $i=0; $i < $Digits;$i++) {
611 :     $OriginalNumber .= "0"
612 :     }
613 :     return $OriginalNumber
614 :     }
615 : chenry 1.5
616 : chenry 1.1 if ($OriginalNumber > 1 || $OriginalNumber < -1) {
617 :     $OriginalNumber = $OriginalNumber*(10**$Digits);
618 :     $OriginalNumber = int($OriginalNumber + .5 * ($OriginalNumber <=> 0));
619 :     $OriginalNumber = $OriginalNumber/(10**$Digits);
620 :     return $OriginalNumber;
621 :     }
622 : chenry 1.5
623 : chenry 1.1 my $Zeros = 0;
624 :     while (abs($OriginalNumber) < 10**$Zeros) {
625 : chenry 1.5 $Zeros--;
626 : chenry 1.1 }
627 : chenry 1.5
628 : chenry 1.1 $OriginalNumber = $OriginalNumber*10**-$Zeros;
629 :     $OriginalNumber = $OriginalNumber*(10**$Digits);
630 :     $OriginalNumber = int($OriginalNumber + .5 * ($OriginalNumber <=> 0));
631 :     $OriginalNumber = $OriginalNumber/(10**$Digits);
632 :     if ($Zeros > -4) {
633 : chenry 1.5 $OriginalNumber = $OriginalNumber/(10**-$Zeros);
634 : chenry 1.1 } else {
635 :     $OriginalNumber .= "e".$Zeros;
636 :     }
637 : chenry 1.5
638 : chenry 1.1 return $OriginalNumber;
639 :     }
640 :    
641 :     sub ConvertToSearchNames {
642 :     my ($InName) = @_;
643 : chenry 1.5
644 : chenry 1.1 if ($InName =~ m/-$/) {
645 :     return $InName;
646 :     }
647 : chenry 1.5
648 : chenry 1.1 #I convert all names to lowercase to help with matching
649 :     $InName = lc($InName);
650 :     #I remove all spaces from all names to help with matching
651 :     $InName =~ s/\s//g;
652 : chenry 1.5 $InName =~ s/,//g;
653 : chenry 1.1 $InName =~ s/-//g;
654 :     $InName =~ s/_//g;
655 :     $InName =~ s/\(//g;
656 :     $InName =~ s/\)//g;
657 :     $InName =~ s/\[//g;
658 :     $InName =~ s/\]//g;
659 :     $InName =~ s/\://g;
660 : chenry 1.5 $InName =~ s///g;
661 :     $InName =~ s/'//g;
662 : chenry 1.1 $InName =~ s/\;//g;
663 : chenry 1.5
664 : chenry 1.1 my $NameOne = $InName;
665 :     $InName =~ s/icacid/ate/g;
666 :     if ($NameOne eq $InName) {
667 :     return ($NameOne);
668 :     } else {
669 :     return ($NameOne,$InName);
670 :     }
671 :     }
672 : chenry 1.5
673 :     sub ConvertToNeutralFormula {
674 :     my ($NeutralFormula,$Charge) = @_;
675 :    
676 :     if (!defined($NeutralFormula)) {
677 :     $NeutralFormula = "";
678 :     } elsif ($NeutralFormula eq "H") {
679 :     #Do nothing
680 :     } elsif (defined($Charge) && $Charge ne "0") {
681 :     my $CurrentH = 0;
682 :     if ($NeutralFormula =~ m/H(\d+)/) {
683 :     $CurrentH = $1;
684 :     } elsif ($NeutralFormula =~ m/H[A-Z]/ || $NeutralFormula =~ m/H$/) {
685 :     $CurrentH = 1;
686 :     }
687 :     my $NewH = $CurrentH;
688 :     if ($Charge >= $CurrentH) {
689 :     $NewH = 0;
690 :     } else {
691 :     $NewH = $CurrentH - $Charge;
692 :     }
693 :     my $Replace = "H";
694 :     if ($NewH > 1) {
695 :     $Replace = "H".$NewH;
696 :     } elsif ($NewH == 0) {
697 :     $Replace = "";
698 :     }
699 :     if ($CurrentH == 0 && $NewH > 0) {
700 :     $NeutralFormula .= "H";
701 :     if ($NewH > 1) {
702 :     $NeutralFormula .= $NewH;
703 :     }
704 :     } elsif ($CurrentH == 1) {
705 :     $NeutralFormula =~ s/H$/$Replace/;
706 :     $NeutralFormula =~ s/H([A-Z])/$Replace$1/;
707 :     } else {
708 :     my $Match = "H".$CurrentH;
709 :     $NeutralFormula =~ s/$Match/$Replace/;
710 :     }
711 :     }
712 :    
713 :     return $NeutralFormula;
714 :     }
715 :    
716 : chenry 1.1 sub CountFileLines {
717 :     my ($filename) = @_;
718 :     my $lines = 0;
719 :     open(FILE, $filename) or die "Can't open `$filename': $!";
720 :     while(<FILE>) {
721 :     $lines++;
722 : chenry 1.5 }
723 : chenry 1.1 close FILE;
724 :     return $lines;
725 :     }
726 :    
727 :     sub ManipulateFormula {
728 :     my ($OriginalFormula) = @_;
729 :    
730 :     my %Atoms;
731 :     my $CurrentAtomType = "";
732 :     my $CurrentAtomNumber = "";
733 :     for (my $i=0; $i < length($OriginalFormula); $i++) {
734 :     my $CurrentLetter = substr($OriginalFormula,$i,1);
735 :     if ($CurrentLetter =~ m/[A-Z]/) {
736 :     if ($CurrentAtomType ne "") {
737 :     if ($CurrentAtomNumber eq "1") {
738 : chenry 1.5 $CurrentAtomNumber = "";
739 : chenry 1.1 }
740 :     $Atoms{$CurrentAtomType} = $CurrentAtomNumber;
741 :     }
742 :     $CurrentAtomType = $CurrentLetter;
743 :     $CurrentAtomNumber = "";
744 :     } elsif ($CurrentLetter =~ m/[a-z]/) {
745 :     $CurrentAtomType .= $CurrentLetter;
746 :     } elsif ($CurrentLetter =~ m/[\d]/) {
747 :     $CurrentAtomNumber .= $CurrentLetter;
748 :     } else {
749 :     if ($CurrentAtomType ne "") {
750 :     $Atoms{$CurrentAtomType} = $CurrentAtomNumber;
751 :     }
752 :     $CurrentAtomType = "";
753 :     }
754 :     }
755 :     if ($CurrentAtomType ne "") {
756 :     if ($CurrentAtomNumber eq "1") {
757 : chenry 1.5 $CurrentAtomNumber = "";
758 : chenry 1.1 }
759 :     $Atoms{$CurrentAtomType} = $CurrentAtomNumber;
760 :     }
761 :    
762 :     my @SortedAtoms = sort(keys(%Atoms));
763 :     my $StandardFormula;
764 :     my $CompareFormula;
765 :     for (my $i=0; $i < @SortedAtoms; $i++) {
766 :     $StandardFormula .= $SortedAtoms[$i];
767 :     $StandardFormula .= $Atoms{$SortedAtoms[$i]};
768 :     if ($SortedAtoms[$i] ne "H") {
769 :     $CompareFormula .= $SortedAtoms[$i];
770 :     $CompareFormula .= $Atoms{$SortedAtoms[$i]};
771 :     }
772 :     }
773 :    
774 :     return ($StandardFormula,$CompareFormula);
775 :     }
776 :    
777 :    
778 :    
779 :     sub ParseGPRFile {
780 :     my ($Filename,$ReactionData) = @_;
781 : chenry 1.5
782 : chenry 1.1 my $GPRData = &LoadMultipleColumnFile($Filename,"\t");
783 : chenry 1.5
784 : chenry 1.1 for (my $i=0; $i < @{$GPRData}; $i++) {
785 :     if (@{$GPRData->[$i]} >= 3) {
786 :     if (!defined($ReactionData->{$GPRData->[$i]->[2]})) {
787 :     $ReactionData->{$GPRData->[$i]->[2]}->{"ID"} = $GPRData->[$i]->[2];
788 :     }
789 :     if (length($GPRData->[$i]->[1]) > 0) {
790 :     $ReactionData->{$GPRData->[$i]->[2]}->{"EC"} = $GPRData->[$i]->[1];
791 :     }
792 :     for (my $j=4; $j < @{$GPRData->[$i]}; $j++) {
793 :     if (length($GPRData->[$i]->[$j]) > 0) {
794 :     if ($GPRData->[$i]->[$j] =~ m/_$/) {
795 :     $GPRData->[$i]->[$j] = chop($GPRData->[$i]->[$j]);
796 :     }
797 :     push(@{$ReactionData->{$GPRData->[$i]->[2]}->{"GENE ID"}},$GPRData->[$i]->[$j]);
798 :     }
799 :     }
800 :     }
801 :     }
802 : chenry 1.5
803 : chenry 1.1 return ($ReactionData);
804 :     }
805 :    
806 :     sub ParseSBMLFile {
807 :     my ($Filename,$ReactionData,$CompoundData) = @_;
808 : chenry 1.5
809 : chenry 1.1 my $SBMLData = &LoadSingleColumnFile($Filename,"");
810 : chenry 1.5
811 : chenry 1.1 my $HandlingSpecies = 0;
812 :     my $HandlingReactions = 0;
813 :     my $HandlingReactants = 0;
814 :     my $HandlingProducts = 0;
815 :     my $ReactionID = "";
816 :     my $ReactionReactants = "";
817 :     my $ReactionSign = "";
818 :     my $ReactionProducts = "";
819 :     for (my $i=0; $i < @{$SBMLData}; $i++) {
820 :     if ($SBMLData->[$i] =~ m/^<listOfSpecies>/) {
821 :     $HandlingSpecies = 1;
822 :     } elsif ($SBMLData->[$i] =~ m/^<\/listOfSpecies>/) {
823 :     $HandlingSpecies = 0;
824 :     } elsif ($SBMLData->[$i] =~ m/^<listOfReactions>/) {
825 :     $HandlingReactions = 1;
826 :     } elsif ($SBMLData->[$i] =~ m/^<\/listOfReactions>/) {
827 :     $HandlingReactions = 0;
828 :     } elsif ($HandlingSpecies == 1 && $SBMLData->[$i] =~ m/^<species/) {
829 :     #Parsing out the compound ID
830 :     if ($SBMLData->[$i] =~ m/id="([^"]+)"/) {
831 :     my $ID = $1;
832 :     if ($ID =~ m/^_/) {
833 :     $ID = substr($ID,1);
834 :     }
835 :     if ($ID =~ m/_[a-z]$/) {
836 :     chop($ID);
837 :     chop($ID);
838 :     }
839 :     if (length($ID) > 0) {
840 :     #Parsing out the compound name
841 :     if (!defined($CompoundData->{$ID})) {
842 :     $CompoundData->{$ID}->{"ID"} = $ID;
843 :     }
844 :     if ($SBMLData->[$i] =~ m/name="([^"]+)"/) {
845 :     my $Name = $1;
846 :     if ($Name =~ m/^_/) {
847 :     $Name = substr($Name,1);
848 :     }
849 :     $Name =~ s/_/ /g;
850 :     if (length($Name) > 0 && (!defined($CompoundData->{$ID}->{"NAME"}) || &FindArrayElement($CompoundData->{$ID}->{"NAME"},$Name) == -1)) {
851 :     push(@{$CompoundData->{$ID}->{"NAME"}},$Name);
852 :     }
853 :     }
854 :     }
855 :     }
856 :     } elsif ($HandlingReactions == 1 && $SBMLData->[$i] =~ m/^<reaction/) {
857 :     $ReactionSign = " <=> ";
858 :     if ($SBMLData->[$i] =~ m/reversible="false"/) {
859 :     $ReactionSign = " => ";
860 :     }
861 :     if ($SBMLData->[$i] =~ m/id="([^"]+)"/) {
862 :     $ReactionID = $1;
863 :     if (length($ReactionID) > 0) {
864 :     if (!defined($ReactionData->{$ReactionID})) {
865 :     $ReactionData->{$ReactionID}->{"ID"} = $ReactionID;
866 :     }
867 :     if ($SBMLData->[$i] =~ m/name="([^"]+)"/) {
868 :     my $Name = $1;
869 :     if ($Name =~ m/^_/) {
870 :     $Name = substr($Name,1);
871 :     }
872 :     $Name =~ s/_/ /g;
873 :     if (length($Name) > 0 && (!defined($ReactionData->{$ReactionID}->{"NAME"}) || &FindArrayElement($ReactionData->{$ReactionID}->{"NAME"},$Name) == -1)) {
874 :     push(@{$ReactionData->{$ReactionID}->{"NAME"}},$Name);
875 :     }
876 :     }
877 : chenry 1.5
878 : chenry 1.1 }
879 :     }
880 :     } elsif ($HandlingReactions == 1 && $SBMLData->[$i] =~ m/^<\/reaction>/) {
881 :     $ReactionID = "";
882 :     $ReactionReactants = "";
883 :     $ReactionSign = "";
884 :     $ReactionProducts = "";
885 :     } elsif ($HandlingReactions == 1 && $SBMLData->[$i] =~ m/^<html:p>EC Number:\s([^<]+)/) {
886 :     my $ECNumber = $1;
887 :     if (length($ECNumber) > 3 && (!defined($ReactionData->{$ReactionID}->{"EC"}) || &FindArrayElement($ReactionData->{$ReactionID}->{"EC"},$ECNumber) == -1)) {
888 :     push(@{$ReactionData->{$ReactionID}->{"EC"}},$ECNumber);
889 :     }
890 :     } elsif ($HandlingReactions == 1 && $SBMLData->[$i] =~ m/^<html:p>Confidence Level:\s([^<]+)/) {
891 :     my $Confidence = $1;
892 :     if (length($Confidence) > 0) {
893 :     $ReactionData->{$ReactionID}->{"CONFIDENCE"} = $Confidence;
894 :     }
895 :     } elsif ($HandlingReactions == 1 && $SBMLData->[$i] =~ m/^<html:p>LOCUS:/) {
896 :     $_ = $SBMLData->[$i];
897 :     my @GeneArray = /<html:p>LOCUS:([^\#]+)/g;
898 :     for (my $j=0; $j < @GeneArray; $j++) {
899 :     if (length($GeneArray[$j]) > 0 && (!defined($ReactionData->{$ReactionID}->{"GENES"}) || &FindArrayElement($ReactionData->{$ReactionID}->{"GENES"},$GeneArray[$j]) == -1)) {
900 :     push(@{$ReactionData->{$ReactionID}->{"GENES"}},$GeneArray[$j]);
901 :     }
902 :     }
903 :     } elsif ($HandlingReactions == 1 && $SBMLData->[$i] =~ m/^<listOfReactants>/) {
904 :     $HandlingReactants = 1;
905 :     } elsif ($HandlingReactions == 1 && $SBMLData->[$i] =~ m/^<\/listOfReactants>/) {
906 :     $HandlingReactants = 0;
907 :     } elsif ($HandlingReactions == 1 && $SBMLData->[$i] =~ m/^<listOfProducts>/) {
908 :     $HandlingProducts = 1;
909 :     } elsif ($HandlingReactions == 1 && $SBMLData->[$i] =~ m/^<\/listOfProducts>/) {
910 :     $HandlingProducts = 0;
911 :     if (length($ReactionID) > 0 && defined($ReactionData->{$ReactionID})) {
912 :     my $Equation = $ReactionReactants.$ReactionSign.$ReactionProducts;
913 :     $ReactionData->{$ReactionID}->{"EQUATION"} = $Equation;
914 :     }
915 :     } elsif ($HandlingReactions == 1 && $SBMLData->[$i] =~ m/^<speciesReference/) {
916 :     if ($SBMLData->[$i] =~ m/species="([^"]+)"/) {
917 :     my $SpeciesID = $1;
918 :     if ($SpeciesID =~ m/^_/) {
919 :     $SpeciesID = substr($SpeciesID,1);
920 :     }
921 :     my $Compartment = "";
922 :     if ($SpeciesID =~ m/_([a-z])$/) {
923 :     $Compartment = $1;
924 :     chop($SpeciesID);
925 :     chop($SpeciesID);
926 :     }
927 :     my $Stoichiometry = "";
928 :     if ($SBMLData->[$i] =~ m/stoichiometry="([^"]+)"/) {
929 :     $Stoichiometry = $1;
930 :     }
931 :     if (length($Stoichiometry) > 0 && length($SpeciesID) > 0) {
932 :     my $SpeciesString = "";
933 :     if ($Stoichiometry ne "1") {
934 :     $SpeciesString .= "(".$Stoichiometry.") ";
935 :     }
936 :     $SpeciesString .= "$SpeciesID";
937 :     if (length($Compartment) > 0 && $Compartment ne "c") {
938 :     $SpeciesString .= "[".$Compartment."]";
939 :     }
940 :     if ($HandlingReactants == 1) {
941 :     if (length($ReactionReactants) > 0) {
942 :     $ReactionReactants .= " + ";
943 :     }
944 :     $ReactionReactants .= $SpeciesString;
945 :     } elsif ($HandlingProducts == 1) {
946 :     if (length($ReactionProducts) > 0) {
947 :     $ReactionProducts .= " + ";
948 :     }
949 :     $ReactionProducts .= $SpeciesString;
950 :     }
951 :     }
952 :     }
953 :     }
954 :     }
955 : chenry 1.5
956 : chenry 1.1 return ($ReactionData,$CompoundData);
957 :     }
958 :    
959 :     sub SearchTranslationDataForMatchingID {
960 :     my ($Filename,$SearchText) = @_;
961 : chenry 1.5
962 : chenry 1.1 #Declaring the reference to the array where the results will ultimately be stored
963 :     my $MatchingIDs = ();
964 : chenry 1.5
965 : chenry 1.1 #If the search text is blank or the input file does not exist, I return an empty array
966 :     if (length($SearchText) == 0 || !(-e $Filename)) {
967 :     return $MatchingIDs;
968 :     }
969 : chenry 1.5
970 : chenry 1.1 #Loading the translation file
971 :     my %IDHash;
972 :     my $TranslationData = &LoadMultipleColumnFile($Filename,"\t");
973 :     my %UniqueKeysHash;
974 :     for (my $i=0; $i < @{$TranslationData}; $i++) {
975 :     if (@{$TranslationData->[$i]} >= 2) {
976 :     push(@{$UniqueKeysHash{$TranslationData->[$i]->[1]}},$TranslationData->[$i]->[0]);
977 :     }
978 :     }
979 :     #Searching through the keys of the translation file for my search text and storing matching ids in a hash
980 :     my @AllKeys = keys(%UniqueKeysHash);
981 :     for (my $i=0; $i < @AllKeys; $i++) {
982 :     if ($AllKeys[$i] =~ m/$SearchText/) {
983 :     for (my $j=0; $j < @{$UniqueKeysHash{$AllKeys[$i]}}; $j++) {
984 :     $IDHash{$UniqueKeysHash{$AllKeys[$i]}->[$j]} = 1;
985 :     }
986 :     }
987 :     }
988 : chenry 1.5
989 : chenry 1.1 #Putting the matching hash keys into an array and sorting it
990 :     push(@{$MatchingIDs},keys(%IDHash));
991 :     if (defined($MatchingIDs)) {
992 :     @{$MatchingIDs} = sort(@{$MatchingIDs})
993 :     }
994 : chenry 1.5
995 : chenry 1.1 return $MatchingIDs;
996 :     }
997 :    
998 :     sub BackupFile {
999 :     my ($CurrentFilename,$BackupFilename) = @_;
1000 : chenry 1.5
1001 : chenry 1.1 if (-e $CurrentFilename) {
1002 :     if (-e $BackupFilename) {
1003 :     unlink($BackupFilename);
1004 :     }
1005 :     rename($CurrentFilename,$BackupFilename);
1006 :     }
1007 :     }
1008 :    
1009 :     sub Date {
1010 : chenry 1.4 my ($Time) = @_;
1011 : chenry 1.5 if (!defined($Time)) {
1012 :     $Time = time();
1013 :     }
1014 : chenry 1.4 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($Time);
1015 : chenry 1.5
1016 : chenry 1.4 return ($mon+1)."/".($mday)."/".($year+1900);
1017 : chenry 1.1 }
1018 :    
1019 :     sub MergeArraysUnique {
1020 :     my @ArrayRefs = @_;
1021 : chenry 1.5
1022 : chenry 1.1 my $ResultArray = ();
1023 :     my %EntryHash;
1024 :     for (my $i=0; $i < @ArrayRefs; $i++) {
1025 :     if (defined($ArrayRefs[$i])) {
1026 :     for (my $j=0; $j < @{$ArrayRefs[$i]}; $j++) {
1027 :     if (!defined($EntryHash{$ArrayRefs[$i]->[$j]})) {
1028 :     push(@{$ResultArray},$ArrayRefs[$i]->[$j]);
1029 :     $EntryHash{$ArrayRefs[$i]->[$j]} = 1;
1030 :     }
1031 :     }
1032 :     }
1033 :     }
1034 : chenry 1.5
1035 : chenry 1.1 return $ResultArray
1036 :     }
1037 :    
1038 :     #Opens up every file in a directory, searches each line for the search expression, and replaces the objects matching the search expression according to the translation hash
1039 :     sub TranslateFileData {
1040 :     my ($TranslationHash,$FilenameExpression,$SearchExpression,$Recursive,$MakeUnique,$SortLines) = @_;
1041 : chenry 1.5
1042 : chenry 1.1 #Checking the search expression if one was provided
1043 :     if (defined($SearchExpression) && length($SearchExpression) > 0) {
1044 :     if (index($SearchExpression,"(") == -1 || index($SearchExpression,"(") == -1) {
1045 :     $SearchExpression = "(".$SearchExpression.")";
1046 :     }
1047 : chenry 1.5 }
1048 : chenry 1.1
1049 :     #Finding all matching filenames
1050 :     my @MatchingFiles;
1051 :     if ($Recursive == 1 && $FilenameExpression =~ m/\/$/) {
1052 :     @MatchingFiles = &RecursiveGlob($FilenameExpression);
1053 :     } else {
1054 :     @MatchingFiles = glob($FilenameExpression);
1055 :     }
1056 : chenry 1.5
1057 : chenry 1.1 #Exiting if no matching filenames were found
1058 :     if (@MatchingFiles == 0) {
1059 :     print "No matching files!\n";
1060 :     return;
1061 :     }
1062 : chenry 1.5
1063 : chenry 1.1 #Loading the translation file
1064 :     if (!(-e $TranslationHash)) {
1065 :     print "Could not find translation file: ".$TranslationHash."!\n";
1066 :     return;
1067 :     }
1068 :     my ($Ignore,$ReverseTranslation) = &LoadSeparateTranslationFiles($TranslationHash,"\t");
1069 :    
1070 :     #Scanning through all matching filenames
1071 :     my @TranslationKeys = keys(%{$ReverseTranslation});
1072 : chenry 1.5
1073 : chenry 1.1 for (my $i=0; $i < @MatchingFiles; $i++) {
1074 :     #Loading the file data into an array
1075 :     my $FileData = &LoadSingleColumnFile($MatchingFiles[$i],"");
1076 :     #Scanning through each fileline
1077 :     my $MatchCount = 0;
1078 :     for (my $j=0; $j < @{$FileData}; $j++) {
1079 :     if (defined($SearchExpression) && length($SearchExpression) > 0) {
1080 :     #This should be faster
1081 :     $_ = $FileData->[$j];
1082 :     my @MatchingGroups = /$SearchExpression/g;
1083 :     for (my $k=0; $k < @MatchingGroups;$k++) {
1084 :     if (defined($ReverseTranslation->{$MatchingGroups[$k]})) {
1085 :     $MatchCount++;
1086 :     my $VarOne = $MatchingGroups[$k];
1087 :     my $VarTwo = $ReverseTranslation->{$MatchingGroups[$k]};
1088 :     $FileData->[$j] =~ s/$VarOne/$VarTwo/;
1089 : chenry 1.5 }
1090 : chenry 1.1 }
1091 :     } else {
1092 :     #This will be slower
1093 :     for (my $k=0; $k < @TranslationKeys;$k++) {
1094 :     my $VarOne = $TranslationKeys[$k];
1095 :     my $VarTwo = $ReverseTranslation->{$TranslationKeys[$k]};
1096 :     $FileData->[$j] =~ s/$VarOne/$VarTwo/g;
1097 :     }
1098 :     }
1099 : chenry 1.5
1100 : chenry 1.1 }
1101 :     #Saving the modified file data back to the file
1102 :     print $MatchingFiles[$i]."\n";
1103 :     print $MatchCount."\n";
1104 :     #Making the array unique if requested
1105 :     if (defined($MakeUnique) && $MakeUnique == 1) {
1106 :     $FileData = &MergeArraysUnique($FileData);
1107 :     }
1108 :     #Sort file lines
1109 :     if (defined($SortLines) && $SortLines == 1) {
1110 :     @{$FileData} = sort(@{$FileData});
1111 :     }
1112 :     &PrintArrayToFile($MatchingFiles[$i],$FileData);
1113 : chenry 1.5 }
1114 : chenry 1.1 }
1115 :    
1116 :     sub RecursiveGlob {
1117 :     my($path) = @_;
1118 : chenry 1.5
1119 :     my @FileList;
1120 :    
1121 : chenry 1.1 ## append a trailing / if it's not there
1122 :     $path .= '/' if($path !~ /\/$/);
1123 : chenry 1.5
1124 : chenry 1.1 ## loop through the files contained in the directory
1125 :     for my $eachFile (glob($path.'*')) {
1126 :     ## if the file is a directory
1127 :     if( -d $eachFile) {
1128 :     ## pass the directory to the routine ( recursion )
1129 :     push(@FileList,RecursiveGlob($eachFile));
1130 :     } else {
1131 :     push(@FileList,$eachFile);
1132 :     }
1133 :     }
1134 : chenry 1.5
1135 : chenry 1.1 return @FileList;
1136 :     }
1137 :    
1138 :     sub PrintHashToFile {
1139 :     my($HashRef,$Filename) = @_;
1140 : chenry 1.5
1141 : chenry 1.1 if ($Filename == "") {
1142 :     open (HASHOUTPUT, ">&STDOUT");
1143 :     } else {
1144 :     open (HASHOUTPUT, ">$Filename");
1145 :     }
1146 :     my @Headings = keys(%{$HashRef});
1147 :     my @FirstHeadings;
1148 :     my @SecondHeadings;
1149 :     for (my $i=0; $i < @Headings; $i++) {
1150 :     if (ref($HashRef->{$Headings[$i]}) eq "HASH") {
1151 :     my @SubHeadings = keys(%{$HashRef->{$Headings[$i]}});
1152 :     for (my $j=0; $j < @SubHeadings;$j++) {
1153 :     push(@FirstHeadings,$Headings[$i]);
1154 :     push(@SecondHeadings,$SubHeadings[$j]);
1155 :     }
1156 :     } else {
1157 :     push(@FirstHeadings,$Headings[$i]);
1158 :     push(@SecondHeadings,$Headings[$i]);
1159 :     }
1160 :     }
1161 :     #Printing headers
1162 :     print HASHOUTPUT "FIRST HEADING;";
1163 :     print HASHOUTPUT join(";",@FirstHeadings)."\n";
1164 :     print HASHOUTPUT "SECOND HEADING;";
1165 :     print HASHOUTPUT join(";",@SecondHeadings)."\n";
1166 :     #Printing the number of data entries
1167 :     print HASHOUTPUT "Number of entries;";
1168 :     for (my $i=0; $i < @FirstHeadings; $i++) {
1169 :     if ($i > 0) {
1170 :     print HASHOUTPUT ";";
1171 :     }
1172 :     if ($FirstHeadings[$i] ne $SecondHeadings[$i]) {
1173 : chenry 1.5 if (defined($HashRef->{$FirstHeadings[$i]}->{$SecondHeadings[$i]})) {
1174 : chenry 1.1 if (@{$HashRef->{$FirstHeadings[$i]}->{$SecondHeadings[$i]}} == 1) {
1175 :     print HASHOUTPUT $HashRef->{$FirstHeadings[$i]}->{$SecondHeadings[$i]}->[0];
1176 :     } else {
1177 :     my $NumEntries = @{$HashRef->{$FirstHeadings[$i]}->{$SecondHeadings[$i]}};
1178 :     print HASHOUTPUT $NumEntries;
1179 :     }
1180 :     } else {
1181 :     print HASHOUTPUT 0;
1182 :     }
1183 :     } else {
1184 : chenry 1.5 if (defined($HashRef->{$FirstHeadings[$i]})) {
1185 : chenry 1.1 if (@{$HashRef->{$FirstHeadings[$i]}} == 1) {
1186 :     print HASHOUTPUT $HashRef->{$FirstHeadings[$i]}->[0];
1187 :     } else {
1188 :     my $NumEntries = @{$HashRef->{$FirstHeadings[$i]}};
1189 :     print HASHOUTPUT $NumEntries;
1190 :     }
1191 :     } else {
1192 :     print HASHOUTPUT 0;
1193 :     }
1194 :     }
1195 :     }
1196 :     print HASHOUTPUT "\n";
1197 :     #Printing data
1198 :     my $Continue = 1;
1199 :     my $Count = 0;
1200 :     while($Continue == 1) {
1201 :     print HASHOUTPUT ($Count+1).";";
1202 :     $Continue = 0;
1203 :     for (my $i=0; $i < @FirstHeadings; $i++) {
1204 :     if ($FirstHeadings[$i] ne $SecondHeadings[$i]) {
1205 :     if (defined($HashRef->{$FirstHeadings[$i]}->{$SecondHeadings[$i]})) {
1206 :     if (@{$HashRef->{$FirstHeadings[$i]}->{$SecondHeadings[$i]}} > 1 && defined($HashRef->{$FirstHeadings[$i]}->{$SecondHeadings[$i]}->[$Count])) {
1207 :     print HASHOUTPUT $HashRef->{$FirstHeadings[$i]}->{$SecondHeadings[$i]}->[$Count];
1208 :     $Continue = 1;
1209 :     }
1210 :     }
1211 :     } else {
1212 :     if (defined($HashRef->{$FirstHeadings[$i]})) {
1213 :     if (@{$HashRef->{$FirstHeadings[$i]}} > 1 && defined($HashRef->{$FirstHeadings[$i]}->[$Count])) {
1214 :     print HASHOUTPUT $HashRef->{$FirstHeadings[$i]}->[$Count];
1215 : chenry 1.5 $Continue = 1;
1216 : chenry 1.1 }
1217 :     }
1218 :     }
1219 :     print HASHOUTPUT ";";
1220 :     }
1221 :     $Count++;
1222 :     print HASHOUTPUT "\n";
1223 :     }
1224 :     close(HASHOUTPUT);
1225 :     }
1226 :    
1227 :     sub CreateHistogramHash {
1228 :     my($ArrayRef) = @_;
1229 : chenry 1.5
1230 : chenry 1.1 my $HashRef;
1231 :     for (my $i=0; $i < @{$ArrayRef}; $i++) {
1232 :     my @TempArray = split(/\|/,$ArrayRef->[$i]);
1233 :     for (my $j=0; $j < @TempArray; $j++) {
1234 :     if (defined($HashRef->{$TempArray[$j]})) {
1235 :     $HashRef->{$TempArray[$j]}->[0]++;
1236 :     } else {
1237 :     $HashRef->{$TempArray[$j]}->[0] = 1;
1238 :     }
1239 :     }
1240 :     }
1241 : chenry 1.5
1242 : chenry 1.1 return $HashRef;
1243 :     }
1244 :    
1245 : chenry 1.5 #init_hoh will take a directory like peg or rxn and create a hash of hashes
1246 : chenry 1.1 #my $dir_all = '/disks/www/Network_Data/MinOrg';
1247 :     #$dir_peg = "$dir_all/peg";
1248 :     #%hoh_peg = &init_hoh($dir_peg);
1249 :     # $hoh_peg{'peg.1234'}{REACTIONS} will be an @array of reactions associated with peg.1234
1250 :     sub init_hoh{
1251 : chenry 1.5 my $dir = shift @_;
1252 : chenry 1.1 my %hash;
1253 :     opendir my $DH, $dir or die "cannot open '$dir' $!";
1254 :     while (my $file = readdir $DH ) {
1255 :     chomp $file;
1256 :     next if $file =~ /~$/;
1257 :     next if -d $file;
1258 :     open my $FH, "<", "$dir/$file" or die "Cannot open '$dir/$file' $!";
1259 :     while ( my $line = <$FH> ) {
1260 :     chomp $line;
1261 :     next if /^#/ || !length($line);
1262 :     my ($key, @values ) = split(/\t/, $line);
1263 :     $hash{ $file }{ $key } = \@values;
1264 :     }
1265 :     close $FH;
1266 :     }
1267 :     return %hash;
1268 :     }
1269 :    
1270 :     sub AddElementsUnique {
1271 :     my ($ArrayRef,@NewElements) = @_;
1272 : chenry 1.5
1273 : chenry 1.1 my $ArrayValueHash;
1274 :     my $NewArray;
1275 :     if (defined($ArrayRef) && @{$ArrayRef} > 0) {
1276 :     for (my $i=0; $i < @$ArrayRef; $i++) {
1277 :     if (!defined($ArrayValueHash->{$ArrayRef->[$i]})) {
1278 :     push(@{$NewArray},$ArrayRef->[$i]);
1279 :     $ArrayValueHash->{$ArrayRef->[$i]} = @{$NewArray}-1;
1280 :     }
1281 :     }
1282 :     }
1283 : chenry 1.5
1284 : chenry 1.1 my $NumberOfMatches = 0;
1285 :     for (my $i=0; $i < @NewElements; $i++) {
1286 :     if (length($NewElements[$i]) > 0 && !defined($ArrayValueHash->{$NewElements[$i]})) {
1287 :     push(@{$NewArray},$NewElements[$i]);
1288 :     $ArrayValueHash->{$NewElements[$i]} = @{$NewArray}-1;
1289 :     } else {
1290 :     $NumberOfMatches++;
1291 :     }
1292 :     }
1293 : chenry 1.5
1294 : chenry 1.1 return ($NewArray,$NumberOfMatches);
1295 :     }
1296 :    
1297 :     sub PutArrayInHash {
1298 : chenry 1.6 my (@ArrayRef) = @_;
1299 : chenry 1.5
1300 : chenry 1.1 my $HashRef;
1301 : chenry 1.6 for (my $i=0; $i < @ArrayRef; $i++) {
1302 :     $HashRef->{$ArrayRef[$i]} = $i;
1303 : chenry 1.1 }
1304 : chenry 1.5
1305 : chenry 1.1 return $HashRef;
1306 :     }
1307 :    
1308 : chenry 1.4 sub RefineOrganismName {
1309 :     my ($Name) = @_;
1310 : chenry 1.5
1311 : chenry 1.4 my @Temp = split(/\s/,$Name);
1312 :     if (@Temp >= 2) {
1313 :     $Name = substr(shift(@Temp),0,1).". ".lc(join(" ",@Temp));
1314 :     }
1315 :     $Name =~ s/str\.\s//g;
1316 :     my $Find = "subsp. ".$Temp[0];
1317 :     $Name =~ s/$Find//g;
1318 : chenry 1.5
1319 : chenry 1.4 return $Name;
1320 :     }
1321 :    
1322 : chenry 1.6 sub RemoveDuplicates {
1323 :     my (@OriginalArray) = @_;
1324 :    
1325 :     my %Hash;
1326 :     foreach my $Element (@OriginalArray) {
1327 :     $Hash{$Element} = 1;
1328 :     }
1329 :     @OriginalArray = sort(keys(%Hash));
1330 :    
1331 :     return @OriginalArray;
1332 :     }
1333 :    
1334 : chenry 1.7 sub FormatCoefficient {
1335 :     my ($Original) = @_;
1336 :    
1337 :     #Converting scientific notation to normal notation
1338 :     if ($Original =~ m/[eE]/) {
1339 :     my $Coefficient = "";
1340 :     my @Temp = split(/[eE]/,$Original);
1341 :     my @TempTwo = split(/\./,$Temp[0]);
1342 :     if ($Temp[1] > 0) {
1343 :     my $Index = $Temp[1];
1344 :     if (defined($TempTwo[1]) && $TempTwo[1] != 0) {
1345 :     $Index = $Index - length($TempTwo[1]);
1346 :     if ($Index < 0) {
1347 :     $TempTwo[1] = substr($TempTwo[1],0,(-$Index)).".".substr($TempTwo[1],(-$Index))
1348 :     }
1349 :     }
1350 :     for (my $j=0; $j < $Index; $j++) {
1351 :     $Coefficient .= "0";
1352 :     }
1353 :     if ($TempTwo[0] == 0) {
1354 :     $TempTwo[0] = "";
1355 :     }
1356 :     if (defined($TempTwo[1])) {
1357 :     $Coefficient = $TempTwo[0].$TempTwo[1].$Coefficient;
1358 :     } else {
1359 :     $Coefficient = $TempTwo[0].$Coefficient;
1360 :     }
1361 :     } elsif ($Temp[1] < 0) {
1362 :     my $Index = -$Temp[1];
1363 :     $Index = $Index - length($TempTwo[0]);
1364 :     if ($Index < 0) {
1365 :     $TempTwo[0] = substr($TempTwo[0],0,(-$Index)).".".substr($TempTwo[0],(-$Index))
1366 :     }
1367 :     if ($Index > 0) {
1368 :     $Coefficient = "0.";
1369 :     }
1370 :     for (my $j=0; $j < $Index; $j++) {
1371 :     $Coefficient .= "0";
1372 :     }
1373 :     $Coefficient .= $TempTwo[0];
1374 :     if (defined($TempTwo[1])) {
1375 :     $Coefficient .= $TempTwo[1];
1376 :     }
1377 :     }
1378 :     $Original = $Coefficient;
1379 :     }
1380 :     #Removing trailing zeros
1381 :     if ($Original =~ m/(.+\..+)0+$/) {
1382 :     $Original = $1;
1383 :     }
1384 :     $Original =~ s/\.0$//;
1385 :    
1386 :     return $Original;
1387 :     }
1388 :    
1389 : chenry 1.8 sub ParseProcessorNumber {
1390 :     my ($InProcessorNumber) = @_;
1391 :    
1392 :     my $NumberOfProcessors = 1;
1393 :     my $NoHup = 0;
1394 :     if (defined($InProcessorNumber)) {
1395 :     if ($InProcessorNumber =~ m/^NH(.+)/) {
1396 :     $NumberOfProcessors = $1;
1397 :     $NoHup = 1;
1398 :     } else {
1399 :     $NumberOfProcessors = $InProcessorNumber;
1400 :     }
1401 :     }
1402 :    
1403 :     return ($NoHup,$NumberOfProcessors);
1404 :     }
1405 :    
1406 :     =head3 ManageFileLocking
1407 :     Definition:
1408 :     $model->ManageFileLocking($FileHandle,$Operation,$UseFcntl);
1409 :     Description:
1410 :     This function handles all file locking for the FIGMODEL package. Possible values for $Operation are:
1411 :     LOCK_EX: exclusive lock for writing
1412 :     LOCK_SH: shared lock for simultaneous reading
1413 :     LOCK_UN: removes the lock
1414 :     Example:
1415 :     =cut
1416 :    
1417 :     sub ManageFileLocking {
1418 :     my($FileHandle,$Operation,$UseFcntl) = @_;
1419 :    
1420 :     #Qualifying the filehandle
1421 :     $FileHandle = qualify_to_ref($FileHandle, caller());
1422 :    
1423 :     #Implementing the lock using flock
1424 :     if (!defined($UseFcntl) || $UseFcntl == 0) {
1425 :     if ($Operation == LOCK_EX) {
1426 :     my $arg = pack("ssll", F_WRLCK, SEEK_SET, 0, 0);
1427 :     my $rc = fcntl($FileHandle, F_SETLKW, $arg);
1428 :     return $rc;
1429 :     } elsif ($Operation == LOCK_SH) {
1430 :     my $arg = pack("ssll", F_RDLCK, SEEK_SET, 0, 0);
1431 :     my $rc = fcntl($FileHandle, F_SETLKW, $arg);
1432 :     return $rc;
1433 :     } elsif ($Operation == LOCK_UN) {
1434 :     my $arg = pack("ssll", F_UNLCK, SEEK_SET, 0, 0);
1435 :     my $rc = fcntl($FileHandle, F_SETLKW, $arg);
1436 :     return $rc;
1437 :     }
1438 :     } else {
1439 :     return CORE::flock($FileHandle, $Operation);
1440 :     }
1441 :     }
1442 :    
1443 : chenry 1.9 =head3 runexecutable
1444 :     Definition:
1445 :     my $OutputArray = runexecutable($Command);
1446 :     Description:
1447 :     Example:
1448 :     =cut
1449 :    
1450 :     sub runexecutable {
1451 :     my($Command) = @_;
1452 :    
1453 :     my $OutputArray;
1454 :     push(@{$OutputArray},`$Command`);
1455 :     return $OutputArray;
1456 :     }
1457 :    
1458 :     1;

MCS Webmaster
ViewVC Help
Powered by ViewVC 1.0.3