def print_(self, printHashes=False, margin='', result=None): """ Print information about the database. @param printHashes: If C{True}, print all hashes and associated subjects. @param margin: A C{str} that should be inserted at the start of each line of output. @param result: A C{MultilineString} instance, or C{None} if a new C{MultilineString} should be created. @return: If C{result} was C{None}, return a C{str} representation of the database, else C{None}. """ if result is None: result = MultilineString(margin=margin) returnNone = False else: returnNone = True coro = self._component.call('print_', printHashes=printHashes, margin=margin) loop = asyncio.get_event_loop() result.append(loop.run_until_complete(coro), verbatim=True) if not returnNone: return str(result)
def print_(self, printSequence=False, printFeatures=False, description='Read', margin='', result=None): """ Print the details of a scanned read. @param fp: A file pointer to print to. @param verbose: If C{True}, print details of landmark and trig point matches. @param printSequence: If C{True}, print the sequence. @param printFeatures: If C{True}, print details of landmark and trig point features. @param description: A C{str} description to print before the scanned read id. This allows us to be specific about what a read is, e.g., a query or a subject. @param margin: A C{str} that should be inserted at the start of each line of output. @param result: A C{MultilineString} instance, or C{None} if a new C{MultilineString} should be created. @return: If C{result} was C{None}, return a C{str} representation of the scanned read, else C{None}. """ read = self.read if result is None: result = MultilineString(margin=margin) returnNone = False else: returnNone = True append = result.append coveredIndices = len(self.coveredIndices()) append('%s: %s' % (description, read.id)) result.indent() if printSequence: append('Sequence: %s' % read.sequence) append('Length: %d' % len(read.sequence)) append('Covered indices: %d (%.2f%%)' % (coveredIndices, coveredIndices / float(len(read.sequence)) * 100.0)) # Print read landmarks and trig points. append('Landmark count %d, trig point count %d' % (len(self.landmarks), len(self.trigPoints))) if printFeatures: result.indent() for landmark in self.landmarks: append(str(landmark)) for trigPoint in self.trigPoints: append(str(trigPoint)) result.outdent() result.outdent() if not returnNone: return str(result)
def printAnalysis(analysis, margin='', result=None): """ Convert an analysis to a nicely formatted string. @param analysis: A C{dict} with information about the score and its calculation. @param margin: A C{str} that should be inserted at the start of each line of output. @param result: A C{MultilineString} instance, or C{None} if a new C{MultilineString} should be created. @return: If C{result} was C{None}, return a C{str} human-readable version of the last analysis, else C{None}. """ if result is None: result = MultilineString(margin=margin) returnNone = False else: returnNone = True result.extend([ 'Score method: %s' % analysis['scoreClass'].__name__, 'Minimum hash count: %(minHashCount)d' % analysis, 'Bin count: %(binCount)d' % analysis, 'Score: %(score).4f' % analysis, ]) if not returnNone: return str(result)
def printAnalysis(analysis, margin='', result=None): """ Convert an analysis to a nicely formatted string. @param analysis: A C{dict} with information about the score and its calculation. @param margin: A C{str} that should be inserted at the start of each line of output. @param result: A C{MultilineString} instance, or C{None} if a new C{MultilineString} should be created. @return: If C{result} was C{None}, return a C{str} human-readable version of the last analysis, else C{None}. """ if result is None: result = MultilineString(margin=margin) returnNone = False else: returnNone = True result.extend([ 'Score method: %s' % analysis['scoreClass'].__name__, ('Matched offset range in query: %(minQueryOffset)d to ' '%(maxQueryOffset)d' % analysis), ('Matched offset range in subject: %(minSubjectOffset)d to ' '%(maxSubjectOffset)d' % analysis), ('Match score: %(matchScore).4f' % analysis), ('Mismatch score: %(mismatchScore).4f' % analysis), 'Score: %(score).4f' % analysis, ]) if not returnNone: return str(result)
def testOneLineLength(self): """ If a multiline string has one thing appended to it, its length must be the length of that string. """ s = MultilineString() s.append('test') self.assertEqual(4, len(s))
def testOneLineTrue(self): """ If a multiline string has one thing appended to it, it must be considered True in a Boolean test. """ s = MultilineString() s.append('test') self.assertTrue(s)
def testAppendOneLine(self): """ If a multiline string has one thing appended to it, its str representation must be just that string. """ s = MultilineString() s.append('test') self.assertEqual('test', str(s))
def testExtendTwoLines(self): """ If a multiline string is extended by two strings, its str representation must have the two strings, separated by a newline. """ s = MultilineString() s.extend(['test1', 'test2']) self.assertEqual('test1\ntest2', str(s))
def testExtendTwoLinesLineCount(self): """ If a multiline string is extended by two strings, its line count must be 2. """ s = MultilineString() s.extend(['test1', 'test2']) self.assertEqual(2, s.lineCount())
def testOneLineLineCount(self): """ If a multiline string has one thing appended to it, its line count must be one. """ s = MultilineString() s.append('test') self.assertEqual(1, s.lineCount())
def testTwoLinesLineCount(self): """ If a multiline string has two things appended to it, its line count must be 2. """ s = MultilineString() s.append('test1') s.append('test2') self.assertEqual(2, s.lineCount())
def testAppendTwoLines(self): """ If a multiline string has two things appended to it, its str representation must have the two strings, separated by a newline. """ s = MultilineString() s.append('test1') s.append('test2') self.assertEqual('test1\ntest2', str(s))
def testAppendTwoLinesWithMargin(self): """ If a multiline string with a left margin has two things appended to it, its str representation must have the two strings, separated by a newline and each line must start with the margin. """ s = MultilineString(margin='+ ') s.append('test1') s.append('test2') self.assertEqual('+ test1\n+ test2', str(s))
def testAppendVerbatim(self): """ If a multiline string is given a verbatim string to append, its representation must be as expected. """ s = MultilineString() s.indent() s.append('test1') s.append(' test2\n test3', verbatim=True) s.append('test4') self.assertEqual(' test1\n test2\n test3\n test4', str(s))
def print_(self, printHashes=False, margin='', result=None): """ Print information about this connector. @param printHashes: If C{True}, print all hashes and associated subjects from the backend. @param margin: A C{str} that should be inserted at the start of each line of output. @param result: A C{MultilineString} instance, or C{None} if a new C{MultilineString} should be created. @return: If C{result} was C{None}, return a C{str} representation of the connector, else C{None}. """ if result is None: result = MultilineString(margin=margin) returnNone = False else: returnNone = True if printHashes: result.append('Backends:') result.indent() self._backend.print_(margin=margin, result=result) result.outdent() if not returnNone: return str(result)
def printAnalysis(analysis, margin='', result=None): """ Convert an analysis to a nicely formatted string. @param analysis: A C{dict} with information about the score and its calculation. @param margin: A C{str} that should be inserted at the start of each line of output. @param result: A C{MultilineString} instance, or C{None} if a new C{MultilineString} should be created. @return: If C{result} was C{None}, return a C{str} human-readable version of the last analysis, else C{None}. """ if result is None: result = MultilineString(margin=margin) returnNone = False else: returnNone = True result.extend([ 'Score method: %s' % analysis['scoreClass'].__name__, ('Matched offset range in query: %(minQueryOffset)d to ' '%(maxQueryOffset)d' % analysis), ('Matched offset range in subject: %(minSubjectOffset)d to ' '%(maxSubjectOffset)d' % analysis), ('Total (query+subject) AA offsets in matched hashes: ' '%(matchedOffsetCount)d' % analysis), ('Subject AA offsets in matched hashes: ' '%(matchedSubjectOffsetCount)d' % analysis), ('Query AA offsets in matched hashes: ' '%(matchedQueryOffsetCount)d' % analysis), ('Total (query+subject) AA offsets in hashes in matched region: ' '%(totalOffsetCount)d' % analysis), ('Weighted Subject AA offsets in matched hashes: ' '%(weightedMatchedSubjectOffsetCount)d' % analysis), ('Weighted Query AA offsets in matched hashes: ' '%(weightedMatchedQueryOffsetCount)d' % analysis), ('Matched region score %(matchedRegionScore).4f ' '(%(matchedOffsetCount)d / %(totalOffsetCount)d)' % analysis), ('Query normalizer: %(normaliserQuery).4f (%(numeratorQuery)d / ' '%(denominatorQuery)d)' % analysis), ('Subject normalizer: %(normaliserSubject).4f ' '(%(numeratorSubject)d / %(denominatorSubject)d)' % analysis), 'Score: %(score).4f' % analysis, ]) if not returnNone: return str(result)
def printAnalysis(analysis, margin='', result=None): """ Convert an analysis to a nicely formatted string. @param analysis: A C{dict} with information about the score and its calculation. @param margin: A C{str} that should be inserted at the start of each line of output. @param result: A C{MultilineString} instance, or C{None} if a new C{MultilineString} should be created. @return: If C{result} was C{None}, return a C{str} human-readable version of the last analysis. """ if result is None: result = MultilineString(margin=margin) returnNone = False else: returnNone = True result.extend([ 'Overall score method: %s' % analysis['scoreClass'].__name__, 'Overall score: %s' % analysis['score'], ('Total (query+subject) AA offsets in matched pairs in all bins: ' '%(matchedOffsetCount)d' % analysis), ('Subject AA offsets in matched pairs in all bins: ' '%(matchedSubjectOffsetCount)d' % analysis), ('Query AA offsets in matched pairs in all bins: ' '%(matchedQueryOffsetCount)d' % analysis), ('Total (query+subject) AA offsets in hashes in matched region: ' '%(totalOffsetCount)d' % analysis), ('Matched region score %(matchedRegionScore).4f ' '(%(matchedOffsetCount)d / %(totalOffsetCount)d)' % analysis), ('Query normalizer: %(normalizerQuery).4f (%(numeratorQuery)d / ' '%(denominatorQuery)d)' % analysis), ('Subject normalizer: %(normalizerSubject).4f ' '(%(numeratorSubject)d / %(denominatorSubject)d)' % analysis), ('Total query offsets that are in a bin: ' '%(queryOffsetsInBinsCount)d' % analysis), ('Total subject offsets that are in a bin: ' '%(subjectOffsetsInBinsCount)d' % analysis), ('Number of bins included in the score calculation: ' '%(numberOfBinsConsidered)d' % analysis), ]) if not returnNone: return str(result)
def print_(self, printHashes=False, margin='', result=None): """ Print information about the database. @param printHashes: If C{True}, print all hashes and associated subjects. @param margin: A C{str} that should be inserted at the start of each line of output. @param result: A C{MultilineString} instance, or C{None} if a new C{MultilineString} should be created. @return: If C{result} was C{None}, return a C{str} representation of the database, else C{None}. """ if result is None: result = MultilineString(margin=margin) returnNone = False else: returnNone = True self.dbParams.print_(margin=margin, result=result) totalResidues = self.totalResidues() result.extend([ 'Connector class: %s' % self._connector.__class__.__name__, 'Subject count: %d' % self.subjectCount(), 'Hash count: %d' % self.hashCount(), 'Total residues: %d' % totalResidues, ]) append = result.append if totalResidues: append('Coverage: %.2f%%' % (100.0 * self.totalCoveredResidues() / totalResidues)) else: append('Coverage: 0.00%') append('Checksum: %d' % self.checksum()) append('Connector:') connector = self._connector.print_(printHashes=printHashes, margin=margin) if connector: append(connector, verbatim=True) if not returnNone: return str(result)
def testNonDefaultIndent(self): """ If a multiline string has two things appended to it, and the second is indented, its str representation must have the two strings, separated by a newline, and the second string must be indented using the indent value passed to __init__. """ s = MultilineString(indent='\t') s.append('test1') s.indent() s.append('test2') self.assertEqual('test1\n\ttest2', str(s))
def testDefaultIndent(self): """ If a multiline string has two things appended to it, and the second is indented, its str representation must have the two strings, separated by a newline, and the second string must be indented by two spaces (the default). """ s = MultilineString() s.append('test1') s.indent() s.append('test2') self.assertEqual('test1\n test2', str(s))
def print_(self, margin='', result=None): """ Print details of the clustering. @param margin: A C{str} that should be inserted at the start of each line of output. @param result: A C{MultilineString} instance, or C{None} if a new C{MultilineString} should be created. @return: If C{result} was C{None}, return a C{str} representation of the statistical measures from running the k-means clustering, else C{None}. """ try: trueLabels, clusterLabels = self.trueLabels, self.clusterLabels except AttributeError: # Looks like clustering has not been run. Ask the user to run it, # seeing as we don't want to silently use a default value of k. raise RuntimeError('Did you forget to run cluster()?') if result is None: result = MultilineString(margin=margin) returnNone = False else: returnNone = True append = result.append append('Homogeneity: %0.3f' % (homogeneity_score(trueLabels, clusterLabels))) append('Completeness: %0.3f' % (completeness_score(trueLabels, clusterLabels))) append('V-measure: %0.3f' % (v_measure_score(trueLabels, clusterLabels))) append('Adjusted Rand Index: %0.3f' % (adjusted_rand_score(trueLabels, clusterLabels))) append('Adjusted Mutual Information: %0.3f' % (adjusted_mutual_info_score(trueLabels, clusterLabels))) append('Silhouette Coefficient: %0.3f' % silhouette_score(self.affinity, clusterLabels, metric='sqeuclidean', sample_size=300)) if not returnNone: return str(result)
def print_(self, margin='', result=None): """ Print details of the clustering. @param margin: A C{str} that should be inserted at the start of each line of output. @param result: A C{MultilineString} instance, or C{None} if a new C{MultilineString} should be created. @return: If C{result} was C{None}, return a C{str} representation of the statistical measures from running the affinity propagation clustering, else C{None}. """ try: self.clusterLabels except AttributeError: # Looks like clustering has not been run. Run it. self.cluster() if result is None: result = MultilineString(margin=margin) returnNone = False else: returnNone = True append = result.append trueLabels, clusterLabels = self.trueLabels, self.clusterLabels append('Estimated number of clusters: %d' % self.nClusters) append('Homogeneity: %0.3f' % (homogeneity_score(trueLabels, clusterLabels))) append('Completeness: %0.3f' % (completeness_score(trueLabels, clusterLabels))) append('V-measure: %0.3f' % (v_measure_score(trueLabels, clusterLabels))) append('Adjusted Rand Index: %0.3f' % (adjusted_rand_score(trueLabels, clusterLabels))) append('Adjusted Mutual Information: %0.3f' % (adjusted_mutual_info_score(trueLabels, clusterLabels))) append('Silhouette Coefficient: %0.3f' % silhouette_score( self.affinity, clusterLabels, metric='sqeuclidean')) if not returnNone: return str(result)
def testTwoLinesLength(self): """ If a multiline string has two things appended to it, its length must be the sum of the two lengths plus one for the newline separator. """ s = MultilineString() s.append('123') s.append('45678') self.assertEqual(9, len(s))
def __str__(self): """ Summarize the variable's statistics. @return: A C{str} summary of the variable's statistics. """ summary = self.summary() result = MultilineString() result.append('%s:' % self._description) result.indent() result.extend([ 'Count: %d' % summary['count'], 'Max: %s' % summary['max'], 'Mean: %.4f' % summary['mean'], 'Median: %.4f' % summary['median'], 'Min: %s' % summary['min'], 'SD: %.4f' % summary['sd'], 'Variance: %.4f' % summary['variance'], ]) return str(result)
def print_(self, printHashes=False, margin='', result=None): """ Print information about this connector and its backends. @param printHashes: If C{True}, print all hashes and associated subjects from the backends. @param margin: A C{str} that should be inserted at the start of each line of output. @param result: A C{MultilineString} instance, or C{None} if a new C{MultilineString} should be created. @return: If C{result} was C{None}, return a C{str} representation of the connector, else C{None}. """ if result is None: result = MultilineString(margin=margin) returnNone = False else: returnNone = True if printHashes: extend = result.extend append = result.append append('Backends:') sessionIds = [self._sessionIdToName.keys()] names = [ self._sessionIdToName[sessionId] for sessionId in sessionIds ] calls = [ self.call('print_-%d' % sessionId, margin=margin + ' ') for sessionId in sessionIds ] callResults = yield from asyncio.gather(*calls) for name, callResult in zip(names, callResults): result.indent() extend([ 'Backend name: %s' % name, 'Backend details:', ]) append(callResult, verbatim=True) result.outdent() if not returnNone: return str(result)
def print_(self, printQuery=True, printSequences=False, printFeatures=False, printHistograms=False, queryDescription='Query title', sortHSPsByScore=True, margin='', result=None): """ Print a result in a human-readable format. If self._storeFullAnalysis is True, full information about all matched subjects (i.e., including matches that were not significant) will be printed. If not, only basic information about significant matches will appear. @param printQuery: If C{True}, also print details of the query. @param printSequences: If C{True}, also print query and subject sequences. @param printFeatures: If C{True}, print details of landmark and trig point features. @param printHistograms: If C{True}, print details of histograms. @param queryDescription: A C{str} description to print before the query (when printQuery is C{True}. @param sortHSPsByScore: If C{True}, HSPs for a subject should be printed in order of decreasing score. If C{False}, print sorted by histogram bin number. @param margin: A C{str} that should be inserted at the start of each line of output. @param result: A C{MultilineString} instance, or C{None} if a new C{MultilineString} should be created. @return: If C{result} was C{None}, return a C{str} representation of the scanned read, else C{None}. """ if result is None: result = MultilineString(margin=margin) returnNone = False else: returnNone = True append = result.append extend = result.extend indent = result.indent outdent = result.outdent if printQuery: backend = Backend() backend.configure(self.connector.dbParams) scannedQuery = backend.scan(self.query) scannedQuery.print_(printSequence=printSequences, printFeatures=printFeatures, description=queryDescription, margin=margin, result=result) self._findParams.print_(margin=margin, result=result) # Sort matched subjects (if any) in order of decreasing score so we # can print them in a useful order. # # The following sorted() call will fail (with TypeError) under # Python 3 because bestScore is None when there are no significant # matches (which can happen when self._storeFullAnalysis is True). subjectIndices = sorted( iter(self.analysis.keys()), reverse=True, key=lambda index: self.analysis[index]['bestBinScore']) if not sortHSPsByScore: indexGetter = itemgetter('index') extend([ 'Overall matches: %d' % len(subjectIndices), 'Significant matches: %d' % len(list(self.significantSubjects())), 'Query hash count: %d' % self.queryHashCount, ]) if subjectIndices: append('Matched subjects:') indent() for subjectCount, subjectIndex in enumerate(subjectIndices, start=1): analysis = self.analysis[subjectIndex] subject = self.connector.getSubjectByIndex(subjectIndex) minHashCount = min(self.queryHashCount, subject.hashCount) significantBins = analysis['significantBins'] append('Subject %d:' % subjectCount) indent() extend([ 'Title: %s' % subject.read.id, 'Best HSP score: %s' % analysis['bestBinScore'], ]) if printSequences: append('Sequence: %s' % subject.read.sequence) extend([ 'Index in database: %s' % subjectIndex, 'Subject hash count: %s' % subject.hashCount, 'Subject/query min hash count: %s' % minHashCount, 'Significance cutoff: %f' % (self._findParams.significanceFraction * minHashCount), 'Number of HSPs: %d' % len(significantBins), ]) if not sortHSPsByScore: significantBins = deepcopy(significantBins) significantBins.sort(key=indexGetter) indent() for hspCount, bin_ in enumerate(significantBins, start=1): binCount = len(bin_['bin']) append('HSP %d (bin %d): %d matching hash%s, score %f' % (hspCount, bin_['index'], binCount, '' if binCount == 1 else 'es', bin_['score'])) if printFeatures: indent() for binItem in bin_['bin']: extend([ 'Landmark %s' % binItem['subjectLandmark'], 'Trig point %s' % binItem['subjectTrigPoint'], ]) outdent() outdent() if printHistograms and self._storeFullAnalysis: histogram = analysis['histogram'] significantBinIndices = set( [bin_['index'] for bin_ in significantBins]) maxCount = max(len(bin_) for bin_ in histogram.bins) append('Histogram:') indent() extend([ 'Number of bins: %d' % len(histogram.bins), 'Bin width: %.10f' % histogram.binWidth, 'Max bin count: %r' % maxCount, 'Max (scaled) offset delta: %d' % histogram.max, 'Min (scaled) offset delta: %d' % histogram.min, ]) # Calculate column widths for displaying ranges neatly. maxAbsoluteValue = max( [-histogram.min, histogram.max, -histogram.max]) if maxAbsoluteValue == 0: # All printed range values will be '+0.0', of length 4. rangeWidth = 4 else: # Add 3 because we have the sign, a decimal point, and # one digit of precision. rangeWidth = 3 + int(ceil(log10(maxAbsoluteValue))) rangeSeparator = ' to ' rangeColumnWidth = 2 * rangeWidth + len(rangeSeparator) first = True for binIndex, bin_ in enumerate(histogram.bins): binCount = len(bin_) if binCount: if first: append('Non-empty bins:') indent() append('%s %s %*s %s' % ('Index', 'Count', rangeColumnWidth, 'Range', 'Significant')) first = False binLow = histogram.min + binIndex * histogram.binWidth # 5, 5, 11 embedded in the format string below are # the lengths of 'Index', 'Range', and 'Significant'. append('%5d %5d %+*.1f%s%+*.1f %11s' % (binIndex, binCount, rangeWidth, binLow, rangeSeparator, rangeWidth, binLow + histogram.binWidth, 'Yes' if binIndex in significantBinIndices else '')) if first: append('All bins were empty.') else: outdent() outdent() if not returnNone: return str(result)
def testEmpty(self): """ If a multiline string has nothing added to it, its str representation must be the empty string. """ self.assertEqual('', str(MultilineString()))
def compare(self, other): """ Compare our parameters against another C{DatabaseParameters} instance. @param other: A C{DatabaseParameters} instance. @return: A C{str} summary of the parameter differences if any, else C{None}. """ err = MultilineString() err.append('Summary of differences:') err.indent() ourLandmarks = self.landmarkFinderNames() otherLandmarks = other.landmarkFinderNames() if ourLandmarks != otherLandmarks: err.append("Param 'landmarks' values %r and %r differ." % (ourLandmarks, otherLandmarks)) ourTrigPoints = self.trigPointFinderNames() otherTrigPoints = other.trigPointFinderNames() if ourTrigPoints != otherTrigPoints: err.append("Param 'trigPoints' values %r and %r differ." % (ourTrigPoints, otherTrigPoints)) for param in ('limitPerLandmark', 'maxDistance', 'minDistance', 'distanceBase', 'featureLengthBase', 'randomLandmarkDensity', 'randomTrigPointDensity', 'acAlphaHelixFilename', 'acAlphaHelix310Filename', 'acAlphaHelixCombinedFilename', 'acAlphaHelixPiFilename', 'acExtendedStrandFilename'): ours = getattr(self, param) others = getattr(other, param) if ours != others: err.append('Param %r values %r and %r differ.' % (param, ours, others)) # We have an error if the multi-line string result has more than # the initial 'Summary of differences' heading line. return str(err) if err.lineCount() > 1 else None
def print_(self, margin='', result=None): """ Print parameter values. @param margin: A C{str} that should be inserted at the start of each line of output. @param result: A C{MultilineString} instance, or C{None} if a new C{MultilineString} should be created. @return: If C{result} was C{None}, return a C{str} representation of the parameters, else C{None}. """ if result is None: result = MultilineString(margin=margin) returnNone = False else: returnNone = True append = result.append append('Parameters:') result.indent() if self.landmarkFinders: append('Landmark finders:') result.indent() for finder in self.landmarkFinders: append(finder.__class__.__name__) result.outdent() else: append('Landmark finders: none') if self.trigPointFinders: append('Trig point finders:') result.indent() for finder in self.trigPointFinders: append(finder.__class__.__name__) result.outdent() else: append('Trig point finders: none') result.extend([ 'Limit per landmark: %d' % self.limitPerLandmark, 'Max distance: %d' % self.maxDistance, 'Min distance: %d' % self.minDistance, 'Distance base: %f' % self.distanceBase, 'Feature length base: %f' % self.featureLengthBase, 'Random landmark density: %f' % self.randomLandmarkDensity, 'Random trig point density: %f' % self.randomTrigPointDensity, 'AC AlphaHelix filename: %s' % basename(self.acAlphaHelixFilename), 'AC AlphaHelix 3-10 filename: %s' % basename(self.acAlphaHelix310Filename), 'AC AlphaHelix Combined filename: %s' % basename(self.acAlphaHelixCombinedFilename), 'AC AlphaHelix pi filename: %s' % basename(self.acAlphaHelixPiFilename), 'AC ExtendedStrand filename: %s' % basename(self.acExtendedStrandFilename), ]) result.outdent() if not returnNone: return str(result)
def print_(self, margin='', result=None): """ Print find parameter values. @param margin: A C{str} that should be inserted at the start of each line of output. @param result: A C{MultilineString} instance, or C{None} if a new C{MultilineString} should be created. @return: If C{result} was C{None}, return a C{str} representation of the parameters, else C{None}. """ if result is None: result = MultilineString(margin=margin) returnNone = False else: returnNone = True result.append('Find parameters:') result.indent() result.extend([ 'Significance method: %s' % self.significanceMethod, 'Significance fraction: %f' % self.significanceFraction, 'Bin Score Method: %s' % self.binScoreMethod, 'Feature match score: %f' % self.featureMatchScore, 'Feature mismatch score: %f' % self.featureMismatchScore, 'Overall Score Method: %s' % self.overallScoreMethod, 'Delta scale: %f' % self.deltaScale, 'Weights: ' ]) result.indent() for key in sorted(self.weights): result.append('%s: %f' % (key, self.weights[key])) result.outdent() result.outdent() if not returnNone: return str(result)