def testSubjectsCompareEqualEvenWithDifferingHashCounts(self): """ Two otherwise identical Subject instances must compare equal even if their hash counts differ. """ read = AARead('id', 'AA') self.assertEqual(Subject(read, 1), Subject(read, 2))
def testSubjectsOfIncompatibleReadTypesCompareUnequal(self): """ Two Subject instances that have reads that cannot be compared must compare unequal. """ read1 = AARead('id', 'AA') read2 = SSAARead('id', 'AA', 'HH') self.assertNotEqual(Subject(read1), Subject(read2))
def testAddTwoSubjectsWithIndex(self): """ Adding two subjects to a SubjectStore and giving their indices must have the expected result. """ ss = SubjectStore() subject1 = Subject(AARead('id1', 'AA')) subject2 = Subject(AARead('id2', 'AA')) ss.add(subject1, '1') ss.add(subject2, '2') self.assertEqual(2, len(ss))
def addSubject(self, subject): """ Ask a backend to add a subject. @param subject: A C{dark.read.AARead} instance. The subject sequence is passed as a read instance even though in many cases it will not be an actual read from a sequencing run. @raises BackendException: if no backends are available. @return: A tuple of 1) a C{bool} to indicate whether the subject was already in the database, and 2) the C{str} subject index. """ if not self._backends: raise BackendException('Database has no backends.') # We could check to see if self._disconnectedBackends is non-empty # and issue a warning if so. But there's no reason we can't add a # subject to one of the connected backends. subject = Subject(subject.id, subject.sequence, 0, subject.quality) preExisting, subjectIndex = self._subjectStore.add(subject) if preExisting: return True, subjectIndex # Pick a backend to add the subject to. Do this by choosing a # session id at random. sessionId = choice([self._sessionIdToName.keys()]) preExisting, BackendSubjectIndex, hashCount = (yield from self._component.call( 'addSubject-%s' % sessionId, subject.id, subject.sequence, subject.quality)) # Sanity check that the backend had not seen the subject before and # that it used the subjectIndex we gave it. assert (preExisting is False) assert (subjectIndex == BackendSubjectIndex) # Store the hash count returned by the backend so that our subject # store is accurate. subject.hashCount = hashCount # Update our own checksum and that of the specific backend to which # the subject was added. name = self._sessionIdToName[sessionId] update = (subject.id, subject.sequence) self._checksum.update(update) self._backends[name]['checksum'].update(update) self._backends[name]['subjectCount'] += 1 return False, subjectIndex
def testGetSubjects(self): """ getSubjects must return the expected result. """ ss = SubjectStore() subject1 = Subject(AARead('id1', 'AA')) subject2 = Subject(AARead('id2', 'CC')) ss.add(subject1, '1') ss.add(subject2, '2') result = set(ss.getSubjects()) self.assertEqual(set([subject1, subject2]), result)
def testAddSubjectWithIndex(self): """ Adding one subject to a SubjectStore and giving a subject index must return the expected result. """ subject = Subject(AARead('id', 'AA')) preExisting, subjectIndex = SubjectStore().add(subject, '3') self.assertFalse(preExisting) self.assertEqual('3', subjectIndex)
def testLengthIsOneAfterAddSubject(self): """ Adding a subject to a new SubjectStore results in SubjectStore with length one. """ ss = SubjectStore() subject = Subject(AARead('id', 'AA')) ss.add(subject) self.assertEqual(1, len(ss))
def testLengthIsOneAfterAddSameSubjectTwice(self): """ Adding a subject to a new SubjectStore twice (with an identical index) results in SubjectStore with length one. """ ss = SubjectStore() subject = Subject(AARead('id', 'AA')) ss.add(subject) ss.add(subject) self.assertEqual(1, len(ss))
def testGetIndexBySubjectKeyError(self): """ If a non-existent subject is passed to getIndexBySubject, a KeyError must be raised. """ dbParams = DatabaseParameters(landmarks=[AlphaHelix], trigPoints=[]) db = Database(dbParams) error = "^'id'$" six.assertRaisesRegex(self, KeyError, error, db.getIndexBySubject, Subject(AARead('id', 'FF')))
def testGetSubjectBySubject(self): """ If a subject is added, getIndexBySubject must be able to return it given an identical subject to look up. """ dbParams = DatabaseParameters(landmarks=[AlphaHelix], trigPoints=[]) db = Database(dbParams) _, index, _ = db.addSubject(AARead('id', 'FRRRFRRRF')) self.assertEqual( index, db.getIndexBySubject(Subject(AARead('id', 'FRRRFRRRF'))))
def testGetSubjectByIndex(self): """ If a subject is added, getSubjectByIndex must be able to return it given its string index. """ dbParams = DatabaseParameters(landmarks=[AlphaHelix], trigPoints=[]) db = Database(dbParams) subject = AARead('id', 'FRRRFRRRF') _, index, _ = db.addSubject(subject) self.assertEqual(Subject(AARead('id', 'FRRRFRRRF')), db.getSubjectByIndex(index))
def testOneReadTwoLandmarksGetSubjects(self): """ If one subject with two landmarks (and hence one hash) is added, an entry is appended to the database subject info. """ dbParams = DatabaseParameters(landmarks=[AlphaHelix], trigPoints=[]) db = Database(dbParams) db.addSubject(AARead('id', 'FRRRFRRRFAFRRRFRRRF')) subject = list(db.getSubjects())[0] read = AARead('id', 'FRRRFRRRFAFRRRFRRRF') self.assertEqual(Subject(read, 1), subject) self.assertEqual(1, subject.hashCount)
def testAddSubjectTwiceWithSameIndex(self): """ Adding a subject to a SubjectStore and giving a subject index and then re-adding it with the same index must return the expected result. """ subject = Subject(AARead('id', 'AA')) ss = SubjectStore() ss.add(subject, '3') preExisting, subjectIndex = ss.add(subject, '3') self.assertTrue(preExisting) self.assertEqual('3', subjectIndex)
def testAddSubjectTwiceWithDifferentIndex(self): """ Adding a subject to a SubjectStore and giving a subject index and then re-adding it with a different index must raise a SubjectStoreException. """ subject = Subject(AARead('id', 'AA')) ss = SubjectStore() ss.add(subject, '3') error = ("^Already stored index \(3\) for subject 'id' does not match " "subsequently passed index \(4\) for the subject\.$") six.assertRaisesRegex(self, SubjectStoreException, error, ss.add, subject, '4')
def testOneReadOneLandmarkGetSubjects(self): """ If one subject with just one landmark (and hence no hashes) is added, an entry is appended to the database subject info. """ dbParams = DatabaseParameters(landmarks=[AlphaHelix], trigPoints=[]) db = Database(dbParams) db.addSubject(AARead('id', 'FRRRFRRRF')) subjects = list(db.getSubjects()) self.assertEqual(1, len(subjects)) subject = subjects[0] self.assertEqual(Subject(AARead('id', 'FRRRFRRRF')), subject) self.assertEqual(0, subject.hashCount)
def testSaveRestoreNonEmpty(self): """ After a save/restore of a non-empty subject store, the subject store must be as expected. """ ss = SubjectStore() subject = Subject(AARead('id', 'AA'), 6) ss.add(subject, '3') fp = StringIO() ss.save(fp) fp.seek(0) ss = SubjectStore.restore(fp) self.assertEqual(1, len(ss)) self.assertEqual('3', ss.getIndexBySubject(subject)) result = ss.getSubjectByIndex('3') self.assertEqual(subject, result) self.assertEqual(6, result.hashCount)
def testHashCountIsStored(self): """ A Subject must store the hashcount it is passed. """ read = AARead('id', 'AA') self.assertEqual(6, Subject(read, 6).hashCount)
def testHashCountDefaultsToZero(self): """ A Subject must store a hashcount of zero if the hashcount isn't given. """ read = AARead('id', 'AA') self.assertEqual(0, Subject(read).hashCount)
def testLen(self): """ A Subject must return the correct (sequence) length via len(). """ self.assertEqual(2, len(Subject(AARead('id', 'AA'))))
def testIdenticalSubjectsCompareEqual(self): """ Two identical Subject instances must compare equal. """ read = AARead('id', 'AA') self.assertEqual(Subject(read), Subject(read))