#!/usr/bin/env perl ##---------------------------------------------------------------------------## ## File: ## @(#) configure ## Author: ## Robert Hubley ## Description: ## A configuration utility for the RepeatMasker distribution. ## #****************************************************************************** #* Copyright (C) Institute for Systems Biology 2003-2019 Developed by #* Robert Hubley. #* #* This work is licensed under the Open Source License v2.1. To view a copy #* of this license, visit http://www.opensource.org/licenses/osl-2.1.php or #* see the license.txt file contained in this distribution. #* ############################################################################### =head1 NAME configure - Configure the RepeatMasker distribution =head1 SYNOPSIS perl ./configure =head1 DESCRIPTION An installation script for the RepeatMasker distribution =head1 CONFIGURATION OVERRIDES =head1 SEE ALSO =over 4 RepeatMasker =back =head1 COPYRIGHT Copyright 2003-2024 Robert Hubley, Institute for Systems Biology =head1 AUTHOR Robert Hubley =cut # # Module Dependence # use strict; use Config; use Cwd; use FindBin; use Getopt::Long; use Pod::Text; use Data::Dumper; use lib $FindBin::Bin; use RepeatMaskerConfig; use POSIX qw(:sys_wait_h); # No output buffering $|=1; # # Release Version # my $version = $RepeatMaskerConfig::VERSION; my $df_version = $RepeatMaskerConfig::DFAM_VERSION; # # First...make sure we are running in the same directory # as the script is located. This avoids problems where # this script ends up in someones path and they run it # unqualified from another installation directory. # if ( getcwd() ne $FindBin::RealBin ) { print "\n The RepeatMasker configure script must be run from\n" . " inside the RepeatMasker installation directory:\n\n" . " $FindBin::RealBin\n\n" . " Perhaps this is not the \"configure\" you are looking for?\n\n"; exit; } # # Option processing # e.g. # -t: Single letter binary option # -t=s: String parameters # -t=i: Number parameters # my @getopt_args = ( '-version', '-perlbin=s', '-force_rebuild' ); # Add configuration parameters as additional command-line options push @getopt_args, RepeatMaskerConfig::getCommandLineOptions(); # # Get the supplied command line options, and set flags # my %options = (); Getopt::Long::config( "noignorecase", "bundling_override" ); unless ( GetOptions( \%options, @getopt_args ) ) { usage(); } # # Provide the POD text from this file and # from the config file by merging them # together. The heading "CONFIGURATION # OVERRIDES" provides the insertion point # for the configuration POD. # sub usage { my $p = Pod::Text->new(); $p->output_fh(*STDOUT); my $pod_str; open IN,"<$0" or die "Could not open self ($0) for generating documentation!"; while (){ if ( /^=head1\s+CONFIGURATION OVERRIDES\s*$/ ) { my $c_pod = RepeatMaskerConfig::getPOD(); if ( $c_pod ) { $pod_str .= $_ . $c_pod; } }else { $pod_str .= $_; } } close IN; print "$0 - $version\n"; $p->parse_string_document($pod_str); exit(1); } # # Resolve configuration settings using the following precedence: # command line first, then environment, followed by config # file. # RepeatMaskerConfig::resolveConfiguration(\%options); my $config = $RepeatMaskerConfig::configuration; ## ## Perl interpreter location ## my $perlLocation = $^X; if ( $options{'perlbin'} ) { my $tbin = ""; if ( -d $options{'perlbin'} ) { if ( -x ( $options{'perlbin'} . "/perl" ) ) { $tbin = $options{'perlbin'} . "/perl"; } elsif ( -x ( $options{'perlbin'} . "/bin/perl" ) ) { $tbin = $options{'perlbin'} . "/bin/perl"; } else { die "Could not find perl using supplied -perlbin parameter $options{'perlbin'}\n" . "as $options{'perlbin'}/perl or $options{'perlbin'}/bin/perl. Please fix\n" . "and rerun configure.\n"; } } elsif ( -x $options{'perlbin'} ) { $tbin = $options{'perlbin'}; } if ( $tbin ne $perlLocation ) { my $optStr; foreach my $key ( keys %options ) { if ( $key ne "perlbin" ) { $optStr .= " -$key " . $options{$key}; } } # Rerun with intended version of perl exec( "$tbin $FindBin::RealBin/configure $optStr" ); } } ## ## Check for perl version ## if ( $] && $] < 5.008 ) { print "RepeatMasker should be used with perl 5.008 or higher.\n" . "Perl $] is being used to run configure."; exit; } ## ## Check for RepeatMasker dependencies ## BEGIN { my @modDependencies = ( "Tie::File", "Getopt::Long", "POSIX", "File::Copy", "File::Path", "Data::Dumper", "Cwd", "Storable" ); my @missingModules = (); foreach my $module ( @modDependencies ) { unless ( eval "require " . $module . ";" ) { push @missingModules, $module; } } if ( @missingModules ) { print "\nThe following perl modules required by RepeatMasker " . "are missing from\nyour system. Please install these or " . "or upgrade your perl version\nto 5.8.x first:\n " . join( "\n ", @missingModules ) . "\n"; exit; } } # # Check for XS version of Scalar::Util # eval "use Scalar::Util qw(weaken);"; if ( $@ ) { print "\nThe CPAN module Scalar::Util included in this version of perl\n" . "is not compiled with the XS option. RepeatMasker requires the\n" . "XS version of the module. Please reinstall XS Scalar::Util from\n" . "CPAN and restart the configure process.\n\n"; exit; } # # Check Storable Version # my $storableVersion = `$perlLocation -mStorable -e 'print \$Storable::VERSION' 2>/dev/null`; if ( $storableVersion < 2.06 ) { print "\nYour perl installation contains an old Storable CPAN module\n" . "( version = $storableVersion ). Please upgrade your Storable module " . "to\nversion 2.06 or higher and then re-run the configure program.\n\n"; exit; } # # Test python3 and h5py # system('python3 -c "import h5py"'); if ( $? ) { die "\nPython3 and the h5py module is a pre-requisite for RepeatMasker.\n" . "Either python3 could not be found in your path or h5py is not installed.\n" . "Please very both before rerunning configure.\n\n"; } ## ## Alter perl invocation headers ## print " -- Setting perl interpreter...\n"; my @progFiles = ( "RepeatMasker", "ProcessRepeats", "RepeatProteinMask", "DupMasker", "addRepBase.pl", "util/calcDivergenceFromAlign.pl", "util/createRepeatLandscape.pl", "util/maskFile.pl", "util/rmOutToGFF3.pl", "util/buildRMLibFromEMBL.pl", "util/rmToUCSCTables.pl" ); # perlLocation will be used in shebang lines, so it must be # an absolute path. However $^X is not always absolute (e.g. macOS). # In most cases, $Config{perlpath} is still an absolute path. if ( !File::Spec->file_name_is_absolute($perlLocation) ) { $perlLocation = $Config{perlpath} . $Config{_exe}; } if ( ! File::Spec->file_name_is_absolute($perlLocation) || ! -x $perlLocation ) { die "Could not find an absolute path for the running perl interpreter!\n" . "Try specifying your perl path manually with the -perlbin option.\n"; } my $perlLocEsc = $perlLocation; $perlLocEsc =~ s/\//\\\//g; foreach my $file ( @progFiles ) { if ( -s $file ) { system("$perlLocation -i -0pe \'s/^#\\!.*perl.*/#\\!$perlLocEsc/g\;' $file" ); }else { die " $file is missing from RepeatMasker distribution"; } } ## ## Introduce ourselves ## system( "clear" ); print "RepeatMasker Configuration Program\n"; my $answer; my $goodParam; # So that we can get the engine versions require NCBIBlastSearchEngine; require WUBlastSearchEngine; require CrossmatchSearchEngine; require HMMERSearchEngine; ## ## RepeatMasker location ## my $rmLocation = "$FindBin::Bin"; if ( -d "$rmLocation/Libraries" && $config->{'LIBDIR'}->{'value'} eq "" ){ $config->{'LIBDIR'}->{'value'} = $rmLocation . "/Libraries"; } if ( ! RepeatMaskerConfig::validateParam('LIBDIR') ) { RepeatMaskerConfig::promptForParam('LIBDIR'); } my $LIBDIR = $config->{'LIBDIR'}->{'value'}; my $c_df_version = $df_version; $c_df_version =~ s/\.//g; print "\n\nChecking for libraries...\n\n"; # First check that we have a default library directory, if not try to create it if ( ! -d "$LIBDIR/famdb" ) { print " ** Creating library directory $LIBDIR/famdb **\n"; mkdir("$LIBDIR/famdb"); } ## Handle error reporting if we suspect that the famdb folder is corrupt if ( -e "$LIBDIR/famdb/merge.working" ) { my $dlTime = `cat $LIBDIR/famdb/merge.working`; die "It appears a previous attempt to merge Dfam and Repbase failed on $dlTime" . "The files in $LIBDIR/famdb may be corrupt.\n" . "Please remove all files from this folder, install new Dfam files, and rerun configure to retry.\n\n"; } if ( -e "$LIBDIR/famdb/download.working" ) { my $dlTime = `cat $LIBDIR/famdb/download.working`; die "It appears a previous attempt to automatically download Dfam $df_version failed on $dlTime" . "The files in $LIBDIR/famdb may not be complete.\n" . "Please remove all files from this folder and rerun configure to begin a new download.\n\n"; } # Check to see if there is an existing rmlib.config file (RepeatMasker's library configuration status file) my $rmlibConfig = {}; if ( -e "$LIBDIR/famdb/rmlib.config" ) { $rmlibConfig = readConfig("$LIBDIR/famdb/rmlib.config"); } $rmlibConfig->{'famdb_files'} = {} if ( ! exists $rmlibConfig->{'famdb_files'} ); # Flag merging of repbase my $hasRepbase = 0; $hasRepbase = 1 if ( -s "$LIBDIR/RMRBSeqs.embl" ); # Now compare current files with previously processed files my ( $hasFamDBRoot, $mergeRB, $rebuildRMLib, $gzip, $famdb_prefix ) = compareFiles( $LIBDIR, $rmlibConfig ); $rebuildRMLib = 1 if ( $options{'force_rebuild'} ); if ( ! $hasFamDBRoot ) { if ( $gzip ) { die "The FamDB database in $LIBDIR/famdb appears be compressed (gzipd). Please uncompress the FamDB partitions and rerun configure.\n\n"; } do { print " *** No libraries present ***\n\n"; print "Choose:\n"; print " 1. Download minimal $df_version (partition 0) using wget or curl\n"; print " (please see https://dfam.org/releases/current/families/FamDB/README.txt for full list of Dfam partitions.)\n"; print " 2. Exit and download libraries manually (Dfam $df_version or newer).\n"; print "\n\nEnter Selection: "; $answer = ; $answer =~ s/[\n\r]+//g; } while ( $answer ne "1" && $answer ne "2" ); if ( $answer eq "2" ) { print "\n\nPlease download a copy of the Dfam database ( famdb HDF5 format )\n" . "from: https://www.dfam.org/releases/Dfam_$df_version/families/FamDB\n\n" . "Minimally you may download just the root partition (file ending\n" . "with \"*.0.h5\"), uncompress it ( gunzip ), store in the\n" . "$LIBDIR/famdb folder,\n" . "and rerun the configure program. See\n" . " https://www.dfam.org/releases/Dfam_$df_version/families/FamDB/README\n" . "for more details on the taxanomic coverage of each partition.\n\n\n"; exit(0); } system( "clear" ); my $hasWget = `sh -c 'command -v wget'`; $hasWget =~ s/[\n\r]+//g; my $hasCurl = `sh -c 'command -v curl'`; $hasCurl =~ s/[\n\r]+//g; # Create a sentinel open OUT,">$LIBDIR/famdb/download.working" or die "Could not open $LIBDIR/famdb/download.working for writing!\n"; print OUT "" . localtime() . "\n"; close OUT; if ( $hasCurl ne "" ) { print "Downloading Dfam $df_version root partition using $hasCurl\n"; system("$hasCurl https://www.dfam.org/releases/Dfam_$df_version/families/FamDB/dfam$c_df_version" ."_full.0.h5.gz -o $LIBDIR/famdb/dfam$c_df_version" ."_full.0.h5.gz"); if ( $? ) { unlink("$LIBDIR/famdb/dfam$c_df_version" . "_full.0.h5.gz") if ( -e "$LIBDIR/famdb/dfam$c_df_version" . "_full.0.h5.gz" ); unlink("$LIBDIR/famdb/download.working"); die "curl failed to download https://www.dfam.org/releases/Dfam_$df_version/families/FamDB/dfam$c_df_version"."_full.0.h5.gz.\n" . "Please check your connnectivity and try again.\n"; } }elsif ( $hasWget ne "" ) { print "Downloading Dfam $df_version root partition using $hasWget\n"; system("$hasWget https://www.dfam.org/releases/Dfam_$df_version/families/FamDB/dfam$c_df_version" . "_full.0.h5.gz -O $LIBDIR/famdb/dfam$c_df_version" . "_full.0.h5.gz"); if ( $? ) { unlink("$LIBDIR/famdb/dfam$c_df_version" . "_full.0.h5.gz") if ( -e "$LIBDIR/famdb/dfam$c_df_version" . "_full.0.h5.gz" ); unlink("$LIBDIR/famdb/download.working"); die "wget failed to download https://www.dfam.org/releases/Dfam_$df_version/families/FamDB/dfam$c_df_version"."_full.0.h5.gz.\n" . "Please check your connnectivity and try again.\n"; } }else { print "Neither wget nor curl are in this users path. Cannot automatically\n" . "download the Dfam database.\n\n" . "Please download a copy of the database ( famdb HDF5 format )\n" . "from: https://www.dfam.org/releases/Dfam_$df_version/families/FamDB\n" . "Minimally you may download just the root partition (file ending with \"*.0.h5\"),\n" . "uncompress it ( gunzip ), and store in $LIBDIR/famdb folder,\n" . "and rerun the configure program. See\n" . " https://www.dfam.org/releases/Dfam_$df_version/families/FamDB/README\n" . "for more details on the taxanomic coverage of each partition.\n\n\n"; } if ( -s "$LIBDIR/famdb/dfam$c_df_version"."_full.0.h5.gz" ) { print "Uncompressing Dfam $df_version root partition\n"; defined(my $pid = fork) or die "Couldn't fork: $!"; if (!$pid) { # Child system("gunzip $LIBDIR/famdb/dfam$c_df_version"."_full.0.h5.gz"); exit; } else { # Parent while (! waitpid($pid, WNOHANG)) { sleep 2; print "."; } } print "\n"; }else { die "Failed to download https://www.dfam.org/releases/Dfam_$df_version/families/FamDB/dfam_$c_df_version"."_full.0.h5.gz to the\n" . "$LIBDIR/famdb folder. Please remove any files from this directory and manually download/uncompress\n" . "the Dfam FamDB partitions and restart configure.\n"; } unlink("$LIBDIR/famdb/download.working"); # re-compare current files with previously processed files ( $hasFamDBRoot, $mergeRB, $rebuildRMLib, $gzip, $famdb_prefix ) = compareFiles( $LIBDIR, $rmlibConfig ); } #print "hasFamDBroot = $hasFamDBRoot\n"; #print "famdb_prefix = $famdb_prefix\n"; #print "mergeRB = $mergeRB\n"; #print "rebuildRMlib = $rebuildRMLib\n"; #print "Dumper: " . Dumper($rmlibConfig) . "\n"; # Installation scenarios # 1: Both Dfam *and* RepBase RepeatMasker Edition if ( $mergeRB ) { #my $dbInfo = `$rmLocation/famdb.py -i $LIBDIR/famdb info`; #if ( $dbInfo !~ /Database:\s+Dfam\s+withRBRM/ ) { defined(my $pid = fork) or die "Couldn't fork: $!"; if (!$pid) { # Child system("$FindBin::RealBin/addRepBase.pl -libdir $LIBDIR"); exit; } else { # Parent while (! waitpid($pid, WNOHANG)) { sleep 2; print "."; } } print "\n"; if ( -e "$LIBDIR/famdb/merge.working" ) { die "Merging RepBase failed!"; } foreach my $partition ( keys( %{$rmlibConfig->{'famdb_files'}} ) ) { my @stat = stat("$LIBDIR/famdb/$partition"); $rmlibConfig->{'famdb_files'}->{$partition}->{'repbase_merged'} = 1; $rmlibConfig->{'famdb_files'}->{$partition}->{'size'} = $stat[7]; } #print "\n"; #$answer = ; #} # 2: Dfam partioned FamDB only }else { print " - Found a FamDB root partition\n\n"; #print "\n"; #$answer = ; } my $dbInfo = `$rmLocation/famdb.py -i $LIBDIR/famdb info`; writeConfig($rmlibConfig, "$LIBDIR/famdb/rmlib.config"); if ( ! $options{'trf_prgm'} ) { print "\n"; $answer = ; RepeatMaskerConfig::promptForParam('TRF_PRGM'); } ## ## Search Engine Configuration ## if ( ! ( $options{'abblast_dir'} || $options{'rmblast_dir'} || $options{'hmmer_dir'} || $options{'crossmatch_dir'} ) ) { searchEngineMenu(); }else { # Assumption: if at least one engine is specified on the command line then the intention # is to not prompt for any engines. } if ( $rebuildRMLib ) { print "Building FASTA version of RepeatMasker.lib ..."; defined(my $pid = fork) or die "Couldn't fork: $!"; if (!$pid) { # Child # Anthony made a really fast version system("$rmLocation/famdb.py -i $LIBDIR/famdb fasta_all > $LIBDIR/RepeatMasker.lib"); exit; } else { # Parent while (! waitpid($pid, WNOHANG)) { sleep 2; print "."; } } print "\n"; } # # Freeze RMLIB/RepeatPeps library for RepeatModeler use among others # if ( RepeatMaskerConfig::validateParam('RMBLAST_DIR') ) { my $binDir = $config->{'RMBLAST_DIR'}->{'value'}; print "Building RMBlast frozen libraries..\n"; system( "$binDir/makeblastdb -dbtype nucl -in " . "$LIBDIR/RepeatMasker.lib > /dev/null 2>&1" ); system( "$binDir/makeblastdb -dbtype prot -in " . "$LIBDIR/RepeatPeps.lib > /dev/null 2>&1" ); } if ( RepeatMaskerConfig::validateParam('ABBLAST_DIR') ) { my $binDir = $config->{'ABBLAST_DIR'}->{'value'}; print "Building WUBlast/ABBlast frozen libraries..\n"; system( "$binDir/xdformat -n -I " . "$LIBDIR/RepeatMasker.lib > /dev/null 2>&1" ); system( "$binDir/xdformat -p -I " . "$LIBDIR/RepeatPeps.lib > /dev/null 2>&1" ); } # Save settings RepeatMaskerConfig::updateConfigFile(); print "The program is installed with a the following repeat libraries:\n"; print "$dbInfo\n"; print "Further documentation on the program may be found here:\n"; print " $rmLocation/repeatmasker.help\n\n"; ####################### S U B R O U T I N E S ############################## sub searchEngineMenu { my $configFile = shift; my @searchEngines = ( { name => "CROSSMATCH_DIR", desc => "Crossmatch", defname => "crossmatch", status => 0, }, { name => "RMBLAST_DIR", desc => "RMBlast", defname => "rmblast", status => 0, }, { name => "HMMER_DIR", desc => "HMMER3.1 & DFAM", defname => "hmmer", status => 0, }, { name => "ABBLAST_DIR", desc => "ABBlast", defname => "abblast", status => 0, } ); my $done = 0; my $defaultEngine = ""; do { system( "clear" ); print "\n\n\n"; print "Add a Search Engine:\n"; my $i; for ( $i = 0 ; $i <= $#searchEngines ; $i++ ) { print " " . ( $i + 1 ) . ". $searchEngines[$i]->{'desc'}: [ "; if ( $searchEngines[ $i ]->{'status'} == 0 ) { print "Un-configured ]\n"; } elsif ( $searchEngines[ $i ]->{'status'} == 1 ) { print "Configured ]\n"; } else { print "Configured, Default ]\n"; } } print "\n"; print " " . ( $i + 1 ) . ". Done\n"; print "\n\nEnter Selection: "; $answer = ; $answer =~ s/[\n\r]+//g; if ( $answer =~ /\d+/ && $answer > 0 && $answer <= ( $#searchEngines + 2 ) ) { if ( $answer == ( $#searchEngines + 2 ) ) { if ( $defaultEngine eq "" ) { print "You must configure at least one search engine!\n"; print "\n"; $answer = ; } else { $done = 1; } } else { RepeatMaskerConfig::promptForParam($searchEngines[$answer-1]->{'name'}); if ( $defaultEngine ne "" ) { system("clear"); print "\n\n\n"; print "Do you want " . $searchEngines[$answer-1]->{'desc'} . " to be your default\nsearch engine for Repeatmasker? (Y/N) "; print " [ Y ]: "; my $isDefault = ; $isDefault =~ s/[\n\r]+//g; if ( $isDefault =~ /^\s*$/ || $isDefault =~ /\s*[yY]\s*/ ) { for ( $i = 0 ; $i <= $#searchEngines ; $i++ ) { $searchEngines[$i]->{'status'} = 1 if ( $searchEngines[$i]->{'status'} == 2 ); } $searchEngines[ $answer - 1 ]->{'status'} = 2; $RepeatMaskerConfig::configuration->{'DEFAULT_SEARCH_ENGINE'}->{'value'} = $searchEngines[$answer-1]->{'defname'}; $defaultEngine = $answer; }else { $searchEngines[ $answer - 1 ]->{'status'} = 1; } }else { $searchEngines[ $answer - 1 ]->{'status'} = 2; # RMH: Added 8/7/24 -- didn't set default engine if only one engine was chosen $RepeatMaskerConfig::configuration->{'DEFAULT_SEARCH_ENGINE'}->{'value'} = $searchEngines[$answer-1]->{'defname'}; $defaultEngine = $answer; } } } else { print "Invalid selection!\n"; print "\n"; $answer = ; } } while ( $done == 0 ); } sub readConfig { my $fileName = shift; my $fileContents = ""; my $oldSep = $/; undef $/; my $in; open $in, "$fileName"; $fileContents = <$in>; $/ = $oldSep; close $in; return eval( $fileContents ); } sub writeConfig { my $data = shift; my $fileName = shift; my $data_dumper = new Data::Dumper( [ $data ] ); $data_dumper->Purity( 1 )->Terse( 1 )->Deepcopy( 1 ); open OUT, ">$fileName"; print OUT $data_dumper->Dump(); close OUT; } sub compareFiles { my $LIBDIR = shift; my $rmlibConfig = shift; my $hasFamDBRoot = 0; my $famdb_prefix = ""; my @famdb_files = (); my $mergeRB = 0; my $rebuildRMLib = 0; my $gzip = 0; $rmlibConfig->{'files'} = (); my %seen = (); opendir DIR, "$LIBDIR/famdb" or die "Could not open $LIBDIR/famdb directory\n"; while ( my $entry = readdir(DIR) ) { next if ( $entry =~ /^\.+$/ || -d "$LIBDIR/famdb/$entry" ); push @{$rmlibConfig->{'files'}}, $entry; if ( -s "$LIBDIR/famdb/$entry" && $entry =~ /(\S+)\.(\d+)\.h5$/ ) { $seen{$entry} = 1; # FamDB file if ( $famdb_prefix ne "" && $famdb_prefix ne $1 ) { my $other = $1; if ( $famdb_prefix eq "min_init" || $other eq "min_init" ) { die "There appears to be more than one FamDB database in the\n" . "$LIBDIR/famdb directory: $famdb_prefix and $other\n" . "Please remove the minimial library 'min_init' and rerun configure\n\n"; } die "There appears to be more than one FamDB database in the $LIBDIR/famdb directory: $famdb_prefix and $other\n\n"; } $famdb_prefix = $1; if ( $2 eq "0" ) { $hasFamDBRoot = 1; } my @stat = stat("$LIBDIR/famdb/$entry"); if ( exists $rmlibConfig->{'famdb_files'}->{$entry} && $rmlibConfig->{'famdb_files'}->{$entry}->{'size'} != $stat[7] ) { die "There appears to be a problem with the FamDB database. The file $entry has changed size from $rmlibConfig->{'famdb_files'}->{$entry}->{'size'} to $stat[7]. Please remove all files from this directory, download (at a minimum) the root partition of a FamDB database, and re-run configure.\n\n"; } elsif ( exists $rmlibConfig->{'famdb_files'}->{$entry} ) { if ( $hasRepbase && ! exists $rmlibConfig->{'famdb_files'}->{$entry}->{'repbase_merged'} ) { $mergeRB = 1; $rebuildRMLib = 1; } }else { if ( $hasRepbase ) { $mergeRB = 1 } $rebuildRMLib = 1; $rmlibConfig->{'famdb_files'}->{$entry} = {}; $rmlibConfig->{'famdb_files'}->{$entry}->{'size'} = $stat[7]; } }elsif ( -s "$LIBDIR/famdb/$entry" && $entry =~ /(\S+)\.(\d+)\.h5.gz/ ) { $gzip = 1; } } # If a partition is deleted make sure we rebuild the RMlib accordingly foreach my $partition ( keys( %{$rmlibConfig->{'famdb_files'}} ) ) { if ( ! exists $seen{$partition} ) { delete $rmlibConfig->{'famdb_files'}->{$partition}; $rebuildRMLib = 1; } } closedir(DIR); return ( $hasFamDBRoot, $mergeRB, $rebuildRMLib, $gzip, $famdb_prefix ); } 1;