def testLandmarkFinderNamesNoLandmarkFinders(self): """ The landmarkFinderNames method must return an empty list when there are no landmark finders. """ dbParams = DatabaseParameters(landmarks=[]) self.assertEqual([], dbParams.landmarkFinderNames())
def testTrigPointFinderNamesNoTrigPointFinders(self): """ The trigPointFinderNames method must return an empty list when there are no trig point finders. """ dbParams = DatabaseParameters(trigPoints=[]) self.assertEqual([], dbParams.trigPointFinderNames())
def testSaveContentIncludesExpectedKeysAndValues(self): """ When a backend saves, its JSON content must include the expected keys and values. """ dbParams = DatabaseParameters(landmarks=[], trigPoints=[], limitPerLandmark=16, maxDistance=17, minDistance=18, distanceBase=19.0) be = Backend() be.configure(dbParams, 'backend', 33) fp = StringIO() be.save(fp) fp.seek(0) DatabaseParameters.restore(fp) SubjectStore.restore(fp) state = loads(fp.readline()[:-1]) # Keys self.assertEqual( set(['checksum', 'd', 'name', '_totalCoveredResidues']), set(state.keys())) # Values self.assertEqual(be.checksum(), state['checksum']) self.assertEqual({}, state['d']) self.assertEqual('backend', state['name']) self.assertEqual(0, state['_totalCoveredResidues'])
def testFromArgsNonexistentTrigPoint(self): """ If --trig is given on a command line with a non-existent trig point name, we should be able to catch it but currently cannot. """ parser = argparse.ArgumentParser() DatabaseParameters.addArgsToParser(parser)
def testTrigPointFinderNames(self): """ The trigPointFinderNames method must return the expected list of names of trig point finders. """ dbParams = DatabaseParameters(trigPoints=[Peaks, Troughs]) self.assertEqual(['Peaks', 'Troughs'], dbParams.trigPointFinderNames())
def testRestore(self): """ The restore method must produce the same parameter values that were present in a DatabaseParameters instance when it is saved. """ dbParams = DatabaseParameters(landmarks=[AlphaHelix, BetaStrand], trigPoints=[Peaks, Troughs], distanceBase=3.0, featureLengthBase=3.9, limitPerLandmark=10, maxDistance=77, minDistance=66, randomLandmarkDensity=0.1, randomTrigPointDensity=0.9) fp = StringIO() dbParams.save(fp) fp.seek(0) result = DatabaseParameters.restore(fp) self.assertEqual([AlphaHelix(), BetaStrand()], result.landmarkFinders) self.assertEqual([Peaks(), Troughs()], result.trigPointFinders) self.assertEqual(3.0, result.distanceBase) self.assertEqual(3.9, result.featureLengthBase) self.assertEqual(10, result.limitPerLandmark) self.assertEqual(77, result.maxDistance) self.assertEqual(66, result.minDistance) self.assertEqual(0.1, result.randomLandmarkDensity) self.assertEqual(0.9, result.randomTrigPointDensity)
def testFromArgsScalarParameters(self): """ All scalar arguments must be processed by fromArgs as expected. """ parser = argparse.ArgumentParser() DatabaseParameters.addArgsToParser(parser) args = parser.parse_args([ '--limitPerLandmark', '5', '--maxDistance', '10', '--minDistance', '3', '--distanceBase', '1.9', '--featureLengthBase', '2.3', '--randomLandmarkDensity', '0.7', '--randomTrigPointDensity', '0.3', ]) dbParams = DatabaseParameters.fromArgs(args) self.assertEqual(5, dbParams.limitPerLandmark) self.assertEqual(10, dbParams.maxDistance) self.assertEqual(3, dbParams.minDistance) self.assertEqual(1.9, dbParams.distanceBase) self.assertEqual(2.3, dbParams.featureLengthBase) self.assertEqual(0.7, dbParams.randomLandmarkDensity) self.assertEqual(0.3, dbParams.randomTrigPointDensity)
def testSaveReturnsItsArgument(self): """ The save function must return its (fp) argument. """ dbParams = DatabaseParameters(landmarks=[], trigPoints=[]) fp = StringIO() self.assertIs(fp, dbParams.save(fp))
def testChecksumAfterSaveRestore(self): """ A backend that has a sequence added to it, which is then saved and restored, and then has a second sequence is added to it must have the same checksum as a backend that simply has the two sequences added to it without interruption. """ seq1 = 'FRRRFRRRFASAASA' seq2 = 'MMMMMMMMMFRRRFR' dbParams1 = DatabaseParameters(landmarks=[AlphaHelix, BetaStrand], trigPoints=[Peaks, Troughs]) be1 = Backend() be1.configure(dbParams1, 'name1', 0) be1.addSubject(AARead('id1', seq1), '0') fp = StringIO() be1.save(fp) fp.seek(0) be1 = Backend.restore(fp) be1.addSubject(AARead('id2', seq2), '1') dbParams2 = DatabaseParameters(landmarks=[AlphaHelix, BetaStrand], trigPoints=[Peaks, Troughs]) be2 = Backend() be2.configure(dbParams2, 'name2', 0) be2.addSubject(AARead('id1', seq1), '0') be2.addSubject(AARead('id2', seq2), '1') self.assertEqual(be1.checksum(), be2.checksum())
def testSymmetricFindScoresDifferingSubjectAndQuery(self): """ The score of matching a sequence A against a sequence B must be the same as when matching B against A, including when the number of hashes in the two differs and the scores are not 1.0. """ subject = AARead('subject', 'AFRRRFRRRFASAASAFRRRFRRRF') query = AARead('query', 'FRRRFRRRFASAVVVVVV') dbParams1 = DatabaseParameters(landmarks=[AlphaHelix, BetaStrand], trigPoints=[Peaks]) db = Database(dbParams1) _, index, _ = db.addSubject(subject) hashCount1 = db.getSubjectByIndex(index).hashCount findParams = FindParameters(significanceFraction=0.0) result = db.find(query, findParams) score1 = result.analysis['0']['bestBinScore'] dbParams2 = DatabaseParameters(landmarks=[AlphaHelix, BetaStrand], trigPoints=[Peaks]) db = Database(dbParams2) _, index, _ = db.addSubject(query) hashCount2 = db.getSubjectByIndex(index).hashCount result = db.find(subject, findParams) score2 = result.analysis['0']['bestBinScore'] self.assertNotEqual(hashCount1, hashCount2) self.assertEqual(score1, score2) self.assertNotEqual(1.0, score1)
def testSymmetricFindScoresSameSubjectAndQuery(self): """ The score of matching a sequence A against a sequence B must be the same as when matching B against A, and that score must be 1.0 when the subject and the query are identical. """ sequence = 'AFRRRFRRRFASAASAFRRRFRRRF' subject = AARead('subject', sequence) query = AARead('query', sequence) dbParams = DatabaseParameters(landmarks=[AlphaHelix, BetaStrand], trigPoints=[Peaks]) db = Database(dbParams) db.addSubject(subject) findParams = FindParameters(significanceFraction=0.0) result = db.find(query, findParams) score1 = result.analysis['0']['bestBinScore'] dbParams = DatabaseParameters(landmarks=[AlphaHelix, BetaStrand], trigPoints=[Peaks]) db = Database(dbParams) db.addSubject(query) result = db.find(subject, findParams) score2 = result.analysis['0']['bestBinScore'] self.assertEqual(score1, score2) self.assertEqual(1.0, score1)
def testChecksumAfterSaveRestore(self): """ A database that has a sequence added to it, which is then saved and restored, and then has a second sequence is added to it must have the same checksum as a database that simply has the two sequences added to it without the intervening save/restore. """ seq1 = 'FRRRFRRRFASAASA' seq2 = 'MMMMMMMMMFRRRFR' dbParams1 = DatabaseParameters(landmarks=[AlphaHelix, BetaStrand], trigPoints=[Peaks, Troughs]) db1 = Database(dbParams1) db1.addSubject(AARead('id1', seq1)) fp = StringIO() db1.save(fp) fp.seek(0) db1 = Database.restore(fp) db1.addSubject(AARead('id2', seq2)) dbParams2 = DatabaseParameters(landmarks=[AlphaHelix, BetaStrand], trigPoints=[Peaks, Troughs]) db2 = Database(dbParams2) db2.addSubject(AARead('id1', seq1)) db2.addSubject(AARead('id2', seq2)) self.assertEqual(db1.checksum(), db2.checksum())
def testLandmarkFinderNames(self): """ The landmarkFinderNames method must return the expected list of names of landmark finders. """ dbParams = DatabaseParameters(landmarks=[AlphaHelix, BetaStrand]) self.assertEqual(['AlphaHelix', 'BetaStrand'], dbParams.landmarkFinderNames())
def testFromArgsNoTrigPoints(self): """ If --noTrigPoints is given on a command line, the returned parameters from fromArgs must have no trig points. """ parser = argparse.ArgumentParser() DatabaseParameters.addArgsToParser(parser) args = parser.parse_args(['--noTrigPoints']) dbParams = DatabaseParameters.fromArgs(args) self.assertEqual([], dbParams.trigPointFinders)
def testFinderOrderInvariant(self): """ The parameter checksum must be identical when finders are specified, no matter what order the finders are given. """ dbParams1 = DatabaseParameters(landmarks=[AlphaHelix, BetaStrand], trigPoints=[Peaks, Troughs]) dbParams2 = DatabaseParameters(landmarks=[BetaStrand, AlphaHelix], trigPoints=[Troughs, Peaks]) self.assertEqual(dbParams1.checksum, dbParams2.checksum)
def testFromArgsNoArgs(self): """ If no arguments are given on a command line, default parameters must be returned by fromArgs. """ parser = argparse.ArgumentParser() DatabaseParameters.addArgsToParser(parser) args = parser.parse_args([]) dbParams = DatabaseParameters.fromArgs(args) self.assertIs(None, dbParams.compare(DatabaseParameters()))
def testCompareDifferentFeatureLengthBase(self): """ The compare method must return a description of parameter differences when two parameter instances have different featureLength bases. """ dbParams1 = DatabaseParameters(featureLengthBase=1.0) dbParams2 = DatabaseParameters(featureLengthBase=2.0) expected = ("Summary of differences:\n" " Param 'featureLengthBase' values 1.0 and 2.0 differ.") self.assertEqual(expected, dbParams1.compare(dbParams2))
def testCompareDifferentLimitPerLandmark(self): """ The compare method must return a description of parameter differences when two parameter instances have different limit per landmark. """ dbParams1 = DatabaseParameters(limitPerLandmark=10) dbParams2 = DatabaseParameters(limitPerLandmark=20) expected = ("Summary of differences:\n" " Param 'limitPerLandmark' values 10 and 20 differ.") self.assertEqual(expected, dbParams1.compare(dbParams2))
def testCompareDifferentMinDistance(self): """ The compare method must return a description of parameter differences when two parameter instances have different min distances. """ dbParams1 = DatabaseParameters(minDistance=10) dbParams2 = DatabaseParameters(minDistance=20) expected = ("Summary of differences:\n" " Param 'minDistance' values 10 and 20 differ.") self.assertEqual(expected, dbParams1.compare(dbParams2))
def testFromArgsTrigPoints(self): """ If --trig is given on a command line, the returned parameters from fromArgs must have the expected trig point finders. """ parser = argparse.ArgumentParser() DatabaseParameters.addArgsToParser(parser) args = parser.parse_args(['--trig', 'Troughs', '--trig', 'Peaks']) dbParams = DatabaseParameters.fromArgs(args) self.assertEqual(['Peaks', 'Troughs'], sorted(dbParams.trigPointFinderNames()))
def testCompareDifferentLandmarkFinders(self): """ The compare method must return a description of parameter differences when two parameter instances have different landmark finders. """ dbParams1 = DatabaseParameters(landmarks=[AlphaHelix, BetaStrand]) dbParams2 = DatabaseParameters(landmarks=[AlphaHelix]) expected = ("Summary of differences:\n" " Param 'landmarks' values " "['AlphaHelix', 'BetaStrand'] and ['AlphaHelix'] differ.") self.assertEqual(expected, dbParams1.compare(dbParams2))
def testCompareDifferentTrigPointFinders(self): """ The compare method must return a description of parameter differences when two parameter instances have different trig point finders. """ dbParams1 = DatabaseParameters(trigPoints=[Peaks, Troughs]) dbParams2 = DatabaseParameters(trigPoints=[Peaks]) expected = ("Summary of differences:\n" " Param 'trigPoints' values " "['Peaks', 'Troughs'] and ['Peaks'] differ.") self.assertEqual(expected, dbParams1.compare(dbParams2))
def testCompareDifferentMaxDistanceAndMinDistance(self): """ The compare method must return a description of parameter differences when two parameter instances have multiple different attributes. """ dbParams1 = DatabaseParameters(maxDistance=10, minDistance=30) dbParams2 = DatabaseParameters(maxDistance=20, minDistance=40) expected = ("Summary of differences:\n" " Param 'maxDistance' values 10 and 20 differ.\n" " Param 'minDistance' values 30 and 40 differ.") self.assertEqual(expected, dbParams1.compare(dbParams2))
def testCompareDifferentRandomTrigPointDensity(self): """ The compare method must return a description of parameter differences when two parameter instances have different randomTrigPointDensity values. """ dbParams1 = DatabaseParameters(randomTrigPointDensity=0.2) dbParams2 = DatabaseParameters(randomTrigPointDensity=0.4) expected = ( "Summary of differences:\n" " Param 'randomTrigPointDensity' values 0.2 and 0.4 differ.") self.assertEqual(expected, dbParams1.compare(dbParams2))
def testFromArgsLandmarks(self): """ If --landmark is given on a command line, the returned parameters from fromArgs must have the expected landmark finders. """ parser = argparse.ArgumentParser() DatabaseParameters.addArgsToParser(parser) args = parser.parse_args( ['--landmark', 'AlphaHelix', '--landmark', 'BetaStrand']) dbParams = DatabaseParameters.fromArgs(args) self.assertEqual(['AlphaHelix', 'BetaStrand'], dbParams.landmarkFinderNames())
def testApplicationParams(self): """ Light matter parameters must be extracted from the input JSON file and stored correctly. """ dbParams = DatabaseParameters(landmarks=[AlphaHelix, BetaStrand], trigPoints=[AminoAcids]) savedDbParams = dbParams.save(StringIO()).getvalue() mockOpener = mockOpen(read_data=savedDbParams) with patch.object(builtins, 'open', mockOpener): readsAlignments = LightReadsAlignments('file.json', DB) diffs = readsAlignments.params.applicationParams.compare(dbParams) self.assertIs(diffs, None)
def addArgsToParser(self, parser): """ Add standard database creation or loading arguments to an argparse parser, depending on the allowable ways of specifying a database. @param parser: An C{argparse.ArgumentParser} instance. """ parser.add_argument( '--filePrefix', help=('The prefix of the name of a file containing saved ' 'data. The suffix "%s" will be added to database ' 'save files, "%s" to connector save files, and ' '"%s-N" to backend save files (where N is a numeric ' 'backend index).' % (Database.SAVE_SUFFIX, SimpleConnector.SAVE_SUFFIX, Backend.SAVE_SUFFIX))) if self._allowWamp: parser.add_argument( '--wampClient', action='store_true', default=False, help=('If True, use a database that is actually just a client ' 'of a remote WAMP distributed database.')) parser.add_argument( '--wampServer', action='store_true', default=False, help='If True, serve a WAMP-connected distributed database.') addWampArgsToParser(parser) if self._allowCreation: DatabaseParameters.addArgsToParser(parser) if self._allowPopulation: parser.add_argument( '--databaseFasta', help=('The name of a FASTA file containing the sequences that ' 'should be added to the database.')) parser.add_argument( '--databaseSequence', action='append', dest='databaseSequences', metavar='"id sequence"', help=('Amino acid sequences to add to the database. The ' 'sequence id will be the text up to the last space, if ' 'any, otherwise will be automatically assigned.'))
def testSaveRestoreWithNonDefaultParameters(self): """ When asked to save and then restore a backend with non-default parameters, a backend with the correct parameters must result. """ dbParams = DatabaseParameters(landmarks=[], trigPoints=[], limitPerLandmark=16, maxDistance=17, minDistance=18, distanceBase=19.0) be = Backend() be.configure(dbParams) fp = StringIO() be.save(fp) fp.seek(0) result = be.restore(fp) self.assertIs(None, dbParams.compare(result.dbParams))
def setAlphaHelices_3_10(helices): """ Make an Aho Corasick matcher for the given helices and monkey patch light.landmarks.ac_alpha_helix_3_10 to use it. Also set the acAlphaHelix310Filename database parameter to 'xxx', to make sure that the right Aho Corasick matcher is used. This function is used by tests that want to check against a specific set of helices instead of the full set. @param helices: An iterable of C{str} helix sequences. @return: A C{light.landmarks.ac_alpha_helix_3_10} instance with its acAlphaHelix310Filename set to 'xxx'. """ ac = ahocorasick.Automaton(ahocorasick.STORE_LENGTH) if ahocorasick.unicode: add = ac.add_word else: # The Aho Corasick module has been compiled without unicode # support, to reduce its memory use. Arrange to give it bytes. def add(s): """ Add a string to an Aho Corasick automaton as bytes. @param s: A C{str} to add. """ ac.add_word(s.encode('utf-8')) list(map(add, helices)) ac.make_automaton() light.landmarks.ac_alpha_helix_3_10._AC = ac dbParams = DatabaseParameters(acAlphaHelix310Filename='xxx') return AC_AlphaHelix_3_10(dbParams)
def testNoKeywordsDefaultParameters(self): """ The database returned from getDatabaseFromKeywords when it is passed no keywords must have the default database parameters. """ db = DatabaseSpecifier().getDatabaseFromKeywords() self.assertIs(None, db.dbParams.compare(DatabaseParameters()))