Next / Previous / Contents / Shipman's homepage

15.11. Hier.__readRanksFile(): Read the ranks file

nomcompile3
# - - -   H i e r . _ _ r e a d R a n k s F i l e

    def __readRanksFile ( self, ranksFileName ):
        '''Read and store the ranks file

          [ ranksFileName is a string ->
              if ranksFileName can be opened for reading ->
                self.__rankList  +:=  Rank instances representing
                    the valid lines of that file in the same order ]
                self.txKeyLen  +:=  key lengths of those Rank instances
                Log()  +:=  error messages(s) about invalid lines
                    from that file, if any
              else ->
                Log()  +:=  error message(s)
                raise IOError ]
        '''

The Rank() constructor (see Section 16, “class Rank: One taxonomic rank”) works directly on a Scan instance to scan a ranks file line. First we instantiate that instance; if the file can't be opened, Scan() will raise IOError.

nomcompile3
        #-- 1 --
        # [ if ranksFileName can be opened for reading ->
        #     scan  :=  a Scan instance reading that file
        #   else ->
        #     Log()  +:=  error message
        #     raise IOError ]
        try:
            scan = Scan ( ranksFileName )
        except IOError, detail:
            message = ( "Can't open ranks file '%s': %s" %
                        (ranksFileName, detail) )
            Log().error(message)
            raise IOError(message)

The Rank() constructor (see Section 16, “class Rank: One taxonomic rank”) processes a line from the scan instance, raising SyntaxError if the line is invalid.

It will be convenient for those creating a ranks file if we find as many errors as possible per run. Therefore, as we iterate over the lines of the file, we'll catch any SyntaxError exceptions and keep going.

nomcompile3
        #-- 2 --
        # [ scan  :=  scan advanced to end of file
        #   Log()  +:=  error messages about bad contents in scan,
        #               if any
        #   self.__rankList  +:=  Rank instances representing
        #       valid lines
        #   self.txKeyLen  +:=  sum of key lengths from the file ]
        while not scan.atEndFile:
            #-- 2 body --
            # [ if the line in scan is a valid ranks file line ->
            #     self.__rankList  +:=  a Rank instance representing
            #         that line, whose depth is len(self.__rankList)
            #     self.txKeyLen  +:=  key length from that line
            #   else ->
            #     Log()  +:=  error message(s)
            #   In any case ->
            #     scan  :=  scan advanced to next line ]
            try:
                rank = Rank ( len(self.__rankList), scan )
                self.__rankList.append ( rank )
                self.txKeyLen += rank.keyLen
            except SyntaxError:
                pass
            scan.nextLine()

        #-- 3 --
        scan.close()