Exemple #1
0
    def _calculateDeviation(
            self, track, value, uncertainty, highMeasuredUncertainty, measured,
            prefix, label
    ):
        if not measured:
            return None

        out = dict()

        measuredUncertainty = measured*(
            0.12 if highMeasuredUncertainty else 0.06)

        v = NumericUtils.toValueUncertainty(value, uncertainty)
        mv = NumericUtils.toValueUncertainty(measured, measuredUncertainty)
        unc = math.sqrt(v.uncertainty**2 + mv.uncertainty**2)

        deviation = v.value - mv.value
        out['%sDev' % prefix] = deviation/measured

        try:
            out['%sDelta' % prefix] = abs(deviation)/unc
        except ZeroDivisionError:
            self.logger.write([
                '[ERROR]: Track without %s uncertainty' % label,
                'TRACK: %s (%s)' % (track.fingerprint, track.uid) ])
            raise

        return out
Exemple #2
0
 def test_isNumber(self):
     """test_isNumber doc..."""
     self.assertTrue(NumericUtils.isNumber(1.234))
     self.assertTrue(NumericUtils.isNumber(100))
     self.assertTrue(NumericUtils.isNumber(-24))
     self.assertFalse(NumericUtils.isNumber('12'))
     self.assertFalse(NumericUtils.isNumber(self))
Exemple #3
0
    def _resolveSpatialCoincidences(self, pair):
        """ Correct for cases where projected prints reside at the same spatial location on the
            curve series by adjusting one of the tracks projection position slightly. """

        segment = pair['segment']

        try:
            nextSegment = self.segments[self.segments.index(segment) + 1]
            nextOffset = nextSegment.offset
        except Exception:
            nextOffset = 1.0e8

        # Adjust a pair print if it resides at the same position as its curve series track
        if NumericUtils.equivalent(pair['distance'], 0.0):
            self._adjustPositionForward(pair, nextOffset)

        try:
            # Retrieve the next pair track in the segment if one exists
            nextPair = segment.pairs[segment.pairs.index(pair) + 1]
        except Exception:
            return

        pDist = pair['distance']
        npDist = nextPair['distance']

        # Adjust pair tracks that reside at the same spatial position
        if npDist <= pDist or NumericUtils.equivalent(pDist, npDist):
            self._adjustPositionForward(nextPair, nextOffset)
Exemple #4
0
    def __unicode__(self):
        isPy2 = bool(sys.version < '3')

        return '<%s (%s, %s)>' % (
            self.__class__.__name__,
            NumericUtils.toValueUncertainty(self.x, self.xUnc, asciiLabel=isPy2).label,
            NumericUtils.toValueUncertainty(self.y, self.yUnc, asciiLabel=isPy2).label)
Exemple #5
0
    def _adjustPositionForward(self, pair, maxOffset =1.0e8):
        """_adjustPositionForward doc..."""

        delta = 0.001
        segment = pair['segment']
        offset = segment.offset + pair['distance']

        while maxOffset <= (offset + delta) or NumericUtils.equivalent(maxOffset, offset + delta):
            delta *= 0.5

        point = pair['line'].start.clone()
        segment.line.adjustPointAlongLine(point, delta, inPlace=True)
        dist = segment.line.start.distanceTo(point).raw

        if not NumericUtils.equivalent(pair['distance'] + delta, dist, machineEpsilonFactor=1000.0):
            self.stage.logger.write([
                '[ERROR]: Forward adjust failure in CurveSeries.adjustPositionForward',
                'TRACK: %s [%s]' % (pair['track'].fingerprint, pair['track'].uid),
                'EXPECTED: %s' % (pair['distance'] + delta),
                'ACTUAL: %s' % dist,
                'DELTA: %s' % delta])

        pair['line'].start.copyFrom(point)

        track = pair['track']
        pair['distance'] = dist

        if not self.saveToAnalysisTracks:
            return

        at = track.getAnalysisPair(self.stage.analysisSession)
        at.curvePosition = segment.offset + dist
        at.segmentPosition = dist
Exemple #6
0
 def test_isNumber(self):
     """test_isNumber doc..."""
     self.assertTrue(NumericUtils.isNumber(1.234))
     self.assertTrue(NumericUtils.isNumber(100))
     self.assertTrue(NumericUtils.isNumber(-24))
     self.assertFalse(NumericUtils.isNumber('12'))
     self.assertFalse(NumericUtils.isNumber(self))
Exemple #7
0
 def echo(self, asciiLabel=False):
     """echo doc..."""
     return '(%s, %s)' % (NumericUtils.toValueUncertainty(
         self.x, self.xUnc, asciiLabel=asciiLabel).rawLabel,
                          NumericUtils.toValueUncertainty(
                              self.y, self.yUnc,
                              asciiLabel=asciiLabel).rawLabel)
Exemple #8
0
def print_track(track, aSession):
    """

    @param track:
    @param aSession:
    @return:
    """

    limb_id = "{}{}".format("l" if track.left else "r", "p" if track.pes else "m")

    print(track.echoForVerification())
    print(
        "        size: (%s, %s) | field (%s, %s)"
        % (track.width, track.length, track.widthMeasured, track.lengthMeasured)
    )

    aTrack = track.getAnalysisPair(aSession)
    print(
        "        curve[#%s -> %s]: %s (%s)"
        % (
            aTrack.curveIndex,
            aTrack.curveSegment,
            NumericUtils.roundToSigFigs(aTrack.segmentPosition, 4),
            NumericUtils.roundToSigFigs(aTrack.curvePosition, 4),
        )
    )
    print("        snapshot: {}\n".format(DictUtils.prettyPrint(track.snapshotData)))

    return dict(limb_id=limb_id, track=track, aTrack=aTrack)
    def project(self, track, data =None):
        """ Tests the specified segment and modifies the data dictionary with the results of the
            test if it was successful. """

        data = self._initializeData(data, track)

        position = track.positionValue
        debugItem = {'TRACK':self.track.fingerprint if self.track else 'NONE'}
        debugData = {}
        data['debug'].append({'print':debugItem, 'data':debugData})

        # Make sure the track resides in a generally forward direction relative to
        # the direction of the segment. The prevents tracks from matching from behind.
        angle = self.line.angleBetweenPoint(position)
        if abs(angle.degrees) > 100.0:
            debugItem['CAUSE'] = 'Segment position angle [%s]' % angle.prettyPrint
            return

        # Calculate the closest point on the line segment. If the point and line are not
        # properly coincident, the testPoint will be None and the attempt should be aborted.
        testPoint = self.line.closestPointOnLine(position, contained=True)
        if not testPoint:
            debugItem['CAUSE'] = 'Not aligned to segment'
            return

        testLine = LineSegment2D(testPoint, position.clone())

        # Make sure the test line intersects the segment line at 90 degrees, or the
        # value is invalid.
        angle = testLine.angleBetweenPoint(self.line.end)
        if not NumericUtils.equivalent(angle.degrees, 90.0, 2.0):
            debugItem['CAUSE'] = 'Projection angle [%s]' % angle.prettyPrint
            debugData['testLine'] = testLine
            debugData['testPoint'] = testPoint
            return

        # Skip if the test line length is greater than the existing test line
        length = data.get('projectionLength', 1.0e10)
        if testLine.length.raw > length:
            debugItem['CAUSE'] = 'Greater length [%s > %s]' % (
                NumericUtils.roundToSigFigs(length, 5),
                NumericUtils.roundToSigFigs(testLine.length.raw, 5) )
            debugData['testLine'] = testLine
            debugData['testPoint'] = testPoint
            return

        # Populate the projection values if the projection was successful
        p  = testPoint.clone()
        # p.xUnc = position.xUnc
        # p.yUnc = position.yUnc
        data['segment'] = self
        data['projectionLength'] = position.distanceTo(p).raw
        data['line'] = LineSegment2D(p, position)

        data['distance'] = self.line.start.distanceTo(p).raw
        debugData['distance'] = data['distance']

        return data
Exemple #10
0
    def _postAnalyze(self):
        """_postAnalyze doc..."""
        self._csv.save()

        meanDiff = NumericUtils.getMeanAndDeviation(self._diffs)
        self.logger.write('Rotation %s' % meanDiff.label)

        self._paths.append(self._makePlot(
            label='Rotation Differences',
            data=self._diffs,
            histRange=[-180, 180]))

        self._paths.append(self._makePlot(
            label='Rotation Differences',
            data=self._diffs,
            histRange=[-180, 180],
            isLog=True))

        circs    = []
        circsUnc = []
        diffs    = []
        diffsUnc = []
        entries  = self.owner.getStage('lengthWidth').entries

        for entry in entries:
            track = entry['track']
            if track.uid not in self.deviations:
                # Skip those tracks with no deviation value (solo tracks)
                continue

            diffDeg = self.deviations[track.uid]
            diffs.append(abs(diffDeg.value))
            diffsUnc.append(diffDeg.uncertainty)

            # Compute the circularity of the track from its aspect ratio. If
            # the aspect is less than or equal to 1.0 use the aspect value
            # directly. However, if the value is greater than one, take the
            # reciprocal so that large and small aspect ratios can be compared
            # equally.
            aspect = entry['aspect']
            if aspect.value > 1.0:
                a = 1.0/aspect.raw
                aspect = NumericUtils.toValueUncertainty(a, a*(aspect.rawUncertainty/aspect.raw))

            circs.append(abs(aspect.value - 1.0))
            circsUnc.append(aspect.uncertainty)

        pl = self.plot
        self.owner.createFigure('circular')
        pl.errorbar(x=circs, y=diffs, xerr=circsUnc, yerr=diffsUnc, fmt='.')
        pl.xlabel('Aspect Circularity')
        pl.ylabel('Rotation Deviation')
        pl.title('Rotation Deviation and Aspect Circularity')
        self._paths.append(self.owner.saveFigure('circular'))

        self.mergePdfs(self._paths)
        self._paths = []
Exemple #11
0
    def __unicode__(self):
        isPy2 = bool(sys.version < '3')

        return '<%s (%s, %s)>' % (
            self.__class__.__name__,
            NumericUtils.toValueUncertainty(
                self.x, self.xUnc, asciiLabel=isPy2).label,
            NumericUtils.toValueUncertainty(
                self.y, self.yUnc, asciiLabel=isPy2).label)
Exemple #12
0
    def test_weightedAverage(self):
        """ doc... """
        values = [
            NumericUtils.toValueUncertainty(11.0, 1.0),
            NumericUtils.toValueUncertainty(12.0, 1.0),
            NumericUtils.toValueUncertainty(10.0, 3.0) ]

        result = NumericUtils.weightedAverage(*values)

        self.assertEqual(result.value, 11.4, 'Value Match')
        self.assertEqual(result.uncertainty, 0.7, 'Value Match')
Exemple #13
0
    def test_weightedAverage(self):
        """ doc... """
        values = [
            NumericUtils.toValueUncertainty(11.0, 1.0),
            NumericUtils.toValueUncertainty(12.0, 1.0),
            NumericUtils.toValueUncertainty(10.0, 3.0)
        ]

        result = NumericUtils.weightedAverage(*values)

        self.assertEqual(result.value, 11.4, 'Value Match')
        self.assertEqual(result.uncertainty, 0.7, 'Value Match')
Exemple #14
0
    def test_toValueUncertainty(self):
        """test_toValueUncertainty doc..."""
        value = NumericUtils.toValueUncertainty(math.pi, 0.00456)
        self.assertEqual(value.value, 3.142, 'Values do not match %s' % value.label)
        self.assertEqual(value.uncertainty, 0.005, 'Uncertainties do not match %s' % value.label)

        value = NumericUtils.toValueUncertainty(100.0*math.pi, 42.0)
        self.assertEqual(value.value, 310.0, 'Values do not match %s' % value.label)
        self.assertEqual(value.uncertainty, 40.0, 'Uncertainties do not match %s' % value.label)

        value = NumericUtils.toValueUncertainty(0.001*math.pi, 0.000975)
        self.assertEqual(value.value, 0.003, 'Values do not match %s' % value.label)
        self.assertEqual(value.uncertainty, 0.001, 'Uncertainties do not match %s' % value.label)
Exemple #15
0
def makePlot(label, tracks):
    tracks = tracks.copy()

    xBounds = [
        NumericUtils.roundToOrder(tracks.length.min() - 0.05, -1, math.floor),
        NumericUtils.roundToOrder(tracks.length.max() + 0.05, -1, math.ceil)]
    yBounds = [
        NumericUtils.roundToOrder(tracks.width.min() - 0.05, -1, math.floor),
        NumericUtils.roundToOrder(tracks.width.max() + 0.05, -1, math.ceil)]

    fig = plotlyTools.make_subplots(
        rows=1, cols=2,
        subplot_titles=('Length vs Width','Aspect Ratios'),
        print_grid=False)

    traces = []
    for site in tracks.site.unique():
        color = PlotConfigs.SITE_SPECS[site]['color']
        siteSlice = tracks[tracks.site == site]
        traces.append(plotlyGraph.Scatter(
            name=site,
            mode='markers',
            xaxis='x1', yaxis='y1',
            marker=plotlyGraph.Marker(color=color),
            x=siteSlice.length,
            y=siteSlice.width))

        traces.append(plotlyGraph.Box(
            name=site,
            y=siteSlice.length/siteSlice.width,
            marker=plotlyGraph.Marker(color=color),
            xaxis='x2', yaxis='y2'))

    fig['data'] += plotlyGraph.Data(traces)
    fig['layout'].update(
        title='%s Length & Width by Tracksite' % label,
        xaxis1=plotlyGraph.XAxis(
            title='Length (m)',
            range=xBounds,
            autorange=False ),
        yaxis1=plotlyGraph.YAxis(
            title='Width (m)',
            range=yBounds,
            autorange=False ))

    url = plotly.plot(
        filename='A16/%s-Length-Width' % label,
        figure_or_data=fig,
        auto_open=False)
    print('PLOT[%s]:' % label, PlotlyUtils.toEmbedUrl(url))
Exemple #16
0
    def _processGaugeData(self, bundle, trackway, data):
        pesCount = bundle.leftPes.count + bundle.rightPes.count
        record = {'name':trackway.name, 'count':pesCount}

        gaugeData = data['gauges']

        try:
            value = NumericUtils.getWeightedMeanAndDeviation(gaugeData.abs)
            record['abs'] = value.value
            record['absUnc'] = value.uncertainty
            self._trackwayGauges.abs.append((pesCount, value))
        except ZeroDivisionError:
            return

        widthValue = NumericUtils.getWeightedMeanAndDeviation(gaugeData.width)
        record['width'] = widthValue.value
        record['widthUnc'] = widthValue.uncertainty
        self._trackwayGauges.width.append((pesCount, widthValue))

        if gaugeData.pace:
            value = NumericUtils.getWeightedMeanAndDeviation(gaugeData.pace)
            record['pace'] = value.value
            record['paceUnc'] = value.uncertainty
            self._trackwayGauges.pace.append((pesCount, value))
        else:
            record['pace'] = ''
            record['paceUnc'] = ''

        if gaugeData.stride:
            value = NumericUtils.getWeightedMeanAndDeviation(gaugeData.stride)
            record['stride'] = value.value
            record['strideUnc'] = value.uncertainty
            self._trackwayGauges.stride.append((pesCount, value))
        else:
            record['stride'] = ''
            record['strideUnc'] = ''

        self._trackwayCsv.addRow(record)

        plot = ScatterPlot(
            data=data['points'],
            title='%s Width-Normalized Gauges (%s)' % (trackway.name, widthValue.label),
            xLabel='Track Position (m)',
            yLabel='Gauge (AU)')
        self._paths.append(plot.save(self.getTempFilePath(extension='pdf')))

        analysisTrackway = trackway.getAnalysisPair(self.analysisSession)
        analysisTrackway.simpleGauge = widthValue.raw
        analysisTrackway.simpleGaugeUnc = widthValue.rawUncertainty
Exemple #17
0
 def rawLabel(self):
     if self._asciiLabels:
         return self.asciiRawLabel
     return '%s %s %s' % (
         NumericUtils.roundToSigFigs(self.raw, 6),
         StringUtils.unichr(0x00B1),
         self.uncertainty)
Exemple #18
0
    def _plot(self):
        """_plot doc..."""

        x = []
        y = []
        yUnc = []

        for value in self.data:
            entry = self._dataItemToValue(value)
            y.append(entry['y'])
            x.append(entry.get('x', len(x)))
            yUnc.append(entry.get('yUnc', 0.0))

        if NumericUtils.equivalent(max(yUnc), 0.0):
            yUnc = None

        pl = self.pl
        pl.bar(x, y, yerr=yUnc, facecolor=self.color, edgecolor=self.strokeColor, log=self.isLog)
        pl.title(self.title)
        pl.xlabel(self.xLabel)
        pl.ylabel(self.yLabel)
        if self.xLimits:
            pl.xlim(*self.xLimits)
        if self.yLimits:
            pl.ylim(*self.yLimits)
        pl.grid(True)
    def _drawMeasuredWidth(self, track, drawing):
        if NumericUtils.equivalent(track.widthMeasured, 0.0):
            return

        if track.uid in self.trackDeviations:
            data = self.trackDeviations[track.uid]
            if data['wSigma'] > 2.0:
                strokeWidth = 3.0
                color = 'red'
            else:
                strokeWidth = 1.0
                color = 'green'
        else:
            strokeWidth = 1.0
            color = 'green'

        w   = 100*track.widthMeasured
        rot = math.radians(track.rotation)
        x1  = w/2.0
        x2  = -w/2.0

        drawing.line(
             (track.x + x1*math.cos(rot), track.z - x1*math.sin(rot)),
             (track.x + x2*math.cos(rot), track.z - x2*math.sin(rot)),
             scene=True,
             stroke=color,
             stroke_width=strokeWidth)
    def _drawMeasuredLength(self, track, drawing):
        if NumericUtils.equivalent(track.lengthMeasured, 0.0):
            return

        if track.uid in self.trackDeviations:
            data = self.trackDeviations[track.uid]
            if data['lSigma'] > 2.0:
                  strokeWidth = 3.0
                  color = 'red'
            else:
                strokeWidth = 1.0
                color = 'green'
        else:
            strokeWidth = 1.0
            color = 'green'

        l   = 100*track.lengthMeasured
        rot = math.radians(track.rotation)
        z1  = track.lengthRatio*l
        z2  = z1 - l

        drawing.line(
             (track.x + z1*math.sin(rot), track.z + z1*math.cos(rot)),
             (track.x + z2*math.sin(rot), track.z + z2*math.cos(rot)),
             scene=True,
             stroke=color,
             stroke_width=strokeWidth)
Exemple #21
0
    def _extrapolateByLength(self, lengthAdjust, pre =False):
        """_extrapolateByLength doc..."""

        length = self.length
        targetLengthSqr = (length.raw + lengthAdjust)**2

        s = self.start
        e = self.end
        deltaX = e.x - s.x
        deltaY = e.y - s.y

        delta = lengthAdjust
        if NumericUtils.equivalent(deltaX, 0.0):
            # Vertical lines should invert delta if start is above the end
            delta *= -1.0 if deltaY < 0.0 else 1.0
        elif deltaX < 0.0:
            # Other lines should invert delta if start is right of the end
            delta *= -1.0

        if pre:
            delta *= -1.0
            startY = s.y
            prevX = s.x
            point = self.end
        else:
            startY = e.y
            prevX = e.x
            point = self.start

        if NumericUtils.equivalent(deltaX, 0.0):
            return s.x, startY + delta

        i = 0
        while i < 100000:
            x = prevX + delta
            y = s.y + deltaY*(x - s.x)/deltaX
            testLengthSqr = math.pow(x - point.x, 2) + math.pow(y - point.y, 2)

            if NumericUtils.equivalent(testLengthSqr/targetLengthSqr, 1.0, 0.000001):
                return x, y
            elif testLengthSqr > targetLengthSqr:
                delta *= 0.5
            else:
                prevX = x
            i += 1

        raise ValueError('Unable to extrapolate line segment to specified length')
Exemple #22
0
    def test_linearSpace(self):
        """test_linearSpace doc..."""

        result = NumericUtils.linearSpace(0.0, 1.0, 10)
        self.assertTrue(len(result) == 10)
        self.assertAlmostEqual(0, result[0])
        self.assertAlmostEqual(1.0, result[-1])

        result = NumericUtils.linearSpace(-25.0, 25.0, 51)
        self.assertTrue(len(result) == 51)
        self.assertAlmostEqual(-25.0, result[0])
        self.assertAlmostEqual(25.0, result[-1])

        try:
            self.assertTrue(result.index(0.0))
        except Exception:
            self.fail('Unexpected linear spacing')
Exemple #23
0
    def test_linearSpace(self):
        """test_linearSpace doc..."""

        result = NumericUtils.linearSpace(0.0, 1.0, 10)
        self.assertTrue(len(result) == 10)
        self.assertAlmostEqual(0, result[0])
        self.assertAlmostEqual(1.0, result[-1])

        result = NumericUtils.linearSpace(-25.0, 25.0, 51)
        self.assertTrue(len(result) == 51)
        self.assertAlmostEqual(-25.0, result[0])
        self.assertAlmostEqual(25.0, result[-1])

        try:
            self.assertTrue(result.index(0.0))
        except Exception:
            self.fail('Unexpected linear spacing')
Exemple #24
0
    def angleBetween(self, position):
        """angleBetween doc..."""

        myLength = self.length
        posLength = position.length
        denom = myLength.raw * posLength.raw
        denomUnc = math.sqrt(
            myLength.rawUncertainty * myLength.rawUncertainty +
            posLength.rawUncertainty * posLength.rawUncertainty)

        if denom == 0.0:
            return Angle(radians=0.0, uncertainty=0.5 * math.pi)

        nom = self.x * position.x + self.y * position.y
        nomUnc = (abs(position.x) * self.xUnc + abs(self.x) * position.xUnc +
                  abs(position.y) * self.yUnc +
                  abs(self.y) * position.yUnc) / denom

        b = nom / denom
        bUnc = abs(1.0/denom)*nomUnc + \
            abs(nom/math.pow(denom, 2))*denomUnc

        if NumericUtils.equivalent(b, 1.0):
            return Angle()

        try:
            if NumericUtils.equivalent(b, -1.0):
                a = math.pi
            else:
                a = math.acos(b)
        except Exception:
            print('[ERROR]: Unable to calculate angle between', b)
            return Angle()

        if NumericUtils.equivalent(a, math.pi):
            return Angle(radians=a, uncertainty=180.0)

        try:
            aUnc = abs(1.0 / math.sqrt(1.0 - b * b)) * bUnc
        except Exception:
            print('[ERROR]: Unable to calculate angle between uncertainty', b,
                  a)
            return Angle()

        return Angle(radians=a, uncertainty=aUnc)
Exemple #25
0
    def angleBetween(self, position):
        """angleBetween doc..."""

        myLength = self.length
        posLength = position.length
        denom = myLength.raw*posLength.raw
        denomUnc = math.sqrt(
            myLength.rawUncertainty*myLength.rawUncertainty +
            posLength.rawUncertainty*posLength.rawUncertainty)

        if denom == 0.0:
            return Angle(radians=0.0, uncertainty=0.5*math.pi)

        nom = self.x*position.x + self.y*position.y
        nomUnc = (abs(position.x)*self.xUnc +
            abs(self.x)*position.xUnc +
            abs(position.y)*self.yUnc +
            abs(self.y)*position.yUnc)/denom

        b = nom/denom
        bUnc = abs(1.0/denom)*nomUnc + \
            abs(nom/math.pow(denom, 2))*denomUnc

        if NumericUtils.equivalent(b, 1.0):
            return Angle()

        try:
            if NumericUtils.equivalent(b, -1.0):
                a = math.pi
            else:
                a = math.acos(b)
        except Exception:
            print('[ERROR]: Unable to calculate angle between', b)
            return Angle()

        if NumericUtils.equivalent(a, math.pi):
            return Angle(radians=a, uncertainty=180.0)

        try:
            aUnc = abs(1.0/math.sqrt(1.0 - b*b))*bUnc
        except Exception:
            print('[ERROR]: Unable to calculate angle between uncertainty', b, a)
            return Angle()

        return Angle(radians=a, uncertainty=aUnc)
    def _analyzeTrack(self, track, series, trackway, sitemap):
        trackId = '%s (%s)' % (track.fingerprint, track.uid)

        if NumericUtils.equivalent(track.width, 0.0):
            self.logger.write('[ERROR]: Zero track width %s' % trackId)
        if NumericUtils.equivalent(track.widthUncertainty, 0.0):
            self.logger.write('[ERROR]: Zero track width uncertainty %s' % trackId)

        if NumericUtils.equivalent(track.length, 0.0):
            self.logger.write('[ERROR]: Zero track length %s' % trackId)
        if NumericUtils.equivalent(track.lengthUncertainty, 0.0):
            self.logger.write('[ERROR]: Zero track length uncertainty %s' % trackId)

        self._tracks.append(track)
        x = track.xValue
        self._uncs.append(x.uncertainty)
        z = track.zValue
        self._uncs.append(z.uncertainty)
Exemple #27
0
    def test_toValueUncertainty(self):
        """test_toValueUncertainty doc..."""
        value = NumericUtils.toValueUncertainty(math.pi, 0.00456)
        self.assertEqual(value.value, 3.142,
                         'Values do not match %s' % value.label)
        self.assertEqual(value.uncertainty, 0.005,
                         'Uncertainties do not match %s' % value.label)

        value = NumericUtils.toValueUncertainty(100.0 * math.pi, 42.0)
        self.assertEqual(value.value, 310.0,
                         'Values do not match %s' % value.label)
        self.assertEqual(value.uncertainty, 40.0,
                         'Uncertainties do not match %s' % value.label)

        value = NumericUtils.toValueUncertainty(0.001 * math.pi, 0.000975)
        self.assertEqual(value.value, 0.003,
                         'Values do not match %s' % value.label)
        self.assertEqual(value.uncertainty, 0.001,
                         'Uncertainties do not match %s' % value.label)
Exemple #28
0
 def test_orderOfMagnitude(self):
     """test_orderOfMagnitude doc..."""
     testOrder = -9
     while testOrder < 10:
         for i in range(25):
             value  = random.uniform(1.0, 9.9)*math.pow(10.0, testOrder)
             result = NumericUtils.orderOfMagnitude(value)
             msg    = 'Invalid Order %s != %s (%s)' % (result, testOrder, value)
             self.assertEqual(testOrder, result,  msg)
         testOrder += 1
Exemple #29
0
    def zValue(self):
        """ Returns the z value as an uncertainty named tuple in units of meters
        """
        r    = math.pi/180.0*float(self.rotation)
        rUnc = math.pi/180.0*float(self.rotationUncertainty)
        wUnc = self.widthUncertainty
        lUnc = self.lengthUncertainty
        zUnc = lUnc*abs(math.cos(r)) + wUnc*abs(math.sin(r)) \
            + rUnc*abs(wUnc*math.cos(r) - lUnc*math.sin(r))

        return NumericUtils.toValueUncertainty(0.01*float(self.z), zUnc)
Exemple #30
0
 def test_orderOfMagnitude(self):
     """test_orderOfMagnitude doc..."""
     testOrder = -9
     while testOrder < 10:
         for i in range(25):
             value = random.uniform(1.0, 9.9) * math.pow(10.0, testOrder)
             result = NumericUtils.orderOfMagnitude(value)
             msg = 'Invalid Order %s != %s (%s)' % (result, testOrder,
                                                    value)
             self.assertEqual(testOrder, result, msg)
         testOrder += 1
Exemple #31
0
    def _processAspectRatios(self):
        """_processAspectRatios doc..."""
        aspects    = []
        pesAspects = []
        manAspects = []

        for entry in self.entries:
            value = entry['aspect'].value
            aspects.append(value)
            if entry['track'].pes:
                pesAspects.append(value)
            else:
                manAspects.append(value)

        self.logger.write('%s\nASPECT RATIO' % ('='*80))
        self.logger.write('Total: %s' %
            NumericUtils.getMeanAndDeviation(aspects).label)
        self.logger.write('Pes: %s' %
            NumericUtils.getMeanAndDeviation(pesAspects).label)
        self.logger.write('Manus: %s' %
            NumericUtils.getMeanAndDeviation(manAspects).label)

        h = Histogram(data=aspects, color='green')
        h.title = 'Aspect Ratios'
        h.yLabel = 'Count'
        h.xLabel = 'Aspect Ratio (width/length)'
        self._paths.append(h.save(self.getTempFilePath(extension='pdf')))

        h = Histogram(data=pesAspects, color='green')
        h.title = 'Aspect Ratios (Pes)'
        h.yLabel = 'Count'
        h.xLabel = 'Aspect Ratio (width/length)'
        self._paths.append(h.save(self.getTempFilePath(extension='pdf')))

        h = Histogram(data=manAspects, color='green')
        h.title = 'Aspect Ratios (Manus)'
        h.yLabel = 'Count'
        h.xLabel = 'Aspect Ratio (width/length)'
        self._paths.append(h.save(self.getTempFilePath(extension='pdf')))
Exemple #32
0
    def slope(self):
        """ Returns the slope of the line as a ValueUncertainty named tuple. """
        s       = self.start
        e       = self.end
        deltaX  = e.x - s.x
        deltaY  = e.y - s.y

        try:
            slope   = deltaY/deltaX
            unc     = abs(1.0/deltaX)*(s.yUnc + e.yUnc) + abs(slope/deltaX)*(s.xUnc + e.xUnc)
            return NumericUtils.toValueUncertainty(slope, unc)
        except Exception:
            return None
    def _postAnalyze(self):
        """_postAnalyze doc..."""

        label = 'Both'
        lows, mids, highs, tsValues, twValues, totals = self._processSparsenessResults(None)
        self._paths.append(self._scatterSparseness(label, lows, mids, highs))
        self._paths.append(self._histogramSeriesSparseness(label, tsValues))
        self._paths.append(self._histogramTrackwaySparseness(label, twValues))

        totalAve = NumericUtils.weightedAverage(*totals)
        self.logger.write('Total Average Spareness: %s' % totalAve.label)

        label = 'Pes'
        lows, mids, highs, tsValues, twValues, totals = self._processSparsenessResults('pes')
        self._paths.append(self._scatterSparseness(label, lows, mids, highs))
        self._paths.append(self._histogramSeriesSparseness(label, tsValues))
        self._paths.append(self._histogramTrackwaySparseness(label, twValues))

        totalAve = NumericUtils.weightedAverage(*totals)
        self.logger.write('Total Average Pes Spareness: %s' % totalAve.label)

        label = 'Manus'
        lows, mids, highs, tsValues, twValues, totals = self._processSparsenessResults('manus')
        self._paths.append(self._scatterSparseness(label, lows, mids, highs))
        self._paths.append(self._histogramSeriesSparseness(label, tsValues))
        self._paths.append(self._histogramTrackwaySparseness(label, twValues))

        totalAve = NumericUtils.weightedAverage(*totals)
        self.logger.write('Total Average Manus Spareness: %s' % totalAve.label)

        self.mergePdfs(self._paths, 'Trackway-Curve-Stats.pdf')

        # Add the reference series to the session object for storage in the Analysis_Trackway
        # table. This data persists because it is used later to rebuild track curves in other
        # analyzers.
        for uid, data in DictUtils.iter(self.data):
            trackway = data['trackway']
            result = trackway.getAnalysisPair(self.analysisSession, createIfMissing=True)
            result.curveSeries = data['dense'].firstTrackUid if data['dense'] else ''
    def _calculateAverageSpacing(cls, series):
        """ Determines the average spacing of the tracks in the track series for use as a
            comparative measure of sparseness to the other track series in the trackway. If the
            series is not ready or does not have a sufficient number of tracks, this method will
            return None.

            :param: series | TrackSeries
                The series on which to determine the average spacing.

            :return: ValueUncertainty
                A value uncertainty instance that represents the average spacing of the series,
                or None if it's the calculation is aborted. """

        if not series.isReady:
            # Skip trackways with invalid series
            return None

        tracks = series.tracks
        if not tracks or len(tracks) < 2:
            # Ignore series with less than two tracks
            return None

        length = 0.0
        uncs    = []

        for i in ListUtils.range(len(tracks) - 1):
            line = LineSegment2D(
                start=tracks[i].positionValue,
                end=tracks[i + 1].positionValue)
            spacing = line.length
            length += spacing.value
            uncs.append(spacing.uncertainty)

        unc = NumericUtils.sqrtSumOfSquares(*uncs)

        return NumericUtils.toValueUncertainty(
            value=length/float(len(tracks)),
            uncertainty=unc/float(len(tracks)) )
def getNormalityColor(normality, goodChannel, badChannel):
    if NumericUtils.equivalent(normality, -1.0, 0.01):
        return ColorValue({'r':100, 'g':100, 'b':100})

    test  = min(1.0, max(0.0, normality))
    limit = NORMAL_THRESHOLD
    slope = 1.0/(1.0 - limit)
    intercept = -slope*limit
    test = min(1.0, max(0.0, slope*test + intercept))

    color = dict(r=0.0, b=0.0, g=0.0)
    color[badChannel] = max(0, 255.0*min(1.0, 1.0 - 1.0*test))
    color[goodChannel] = max(0, min(255, 255.0*test))
    return ColorValue(color)
    def _processSparsenessResults(self, key):
        """_processSparsenessResults doc..."""

        index       = 0
        means       = []
        totals      = []
        twValues    = []
        tsValues    = []

        lows        = dict(x=[], y=[], error=[], color='#666666')
        mids        = dict(x=[], y=[], error=[], color='#33CC33')
        highs       = dict(x=[], y=[], error=[], color='#CC3333')

        for uid, entry in DictUtils.iter(self.data):
            # For each test list in track ratings process the data and filter it into the correct
            # segments for plotting.

            data = (entry['pes'] + entry['manus']) if not key else entry[key]
            data = ListUtils.sortObjectList(data, 'value')
            index += 1

            if len(data) < 2:
                continue

            average = NumericUtils.weightedAverage(*data[1:])
            means.append(average)
            totals.extend(data[1:])
            twValues.append(average.value)

            maxVal = data[0]
            for v in data[1:]:
                if v.value > maxVal.value:
                    maxVal = v

            if maxVal.value < 15.0:
                target = lows
            elif maxVal.value < 50.0:
                target = mids
            else:
                target = highs

            for v in data[1:]:
                tsValues.append(v.value)

                target['x'].append(index)
                target['y'].append(v.value)
                target['error'].append(v.uncertainty)

        return lows, mids, highs, tsValues, twValues, totals
Exemple #37
0
    def getDebugReport(self):
        out = ['\nTRACKWAY[%s]:' % self.trackway.name]
        for segment in self.segments:
            out.append(
                '  TRACK: %s' % (segment.track.fingerprint if segment.track else 'NONE'))

            for item in segment.pairs:
                out.append(
                    '    * %s (%s)' % (
                        item['track'].fingerprint,
                        NumericUtils.roundToSigFigs(item['distance'], 5) ))
                for debugItem in item['debug']:
                    out.append('      - %s' % DictUtils.prettyPrint(debugItem['print']))

        return '\n'.join(out)
    def _drawWidth(self, track, drawing, color ='orange', strokeWidth =0.5):
        if NumericUtils.equivalent(track.widthMeasured, 0.0):
            return

        w   = 100*track.width
        rot = math.radians(track.rotation)
        x1  = w/2.0
        x2  = -w/2.0

        drawing.line(
             (track.x + x1*math.cos(rot), track.z - x1*math.sin(rot)),
             (track.x + x2*math.cos(rot), track.z - x2*math.sin(rot)),
             scene=True,
             stroke=color,
             stroke_width=strokeWidth)
Exemple #39
0
    def test_roundToOrder(self):
        """test_roundToOrder doc..."""
        self.assertAlmostEqual(123.3, NumericUtils.roundToOrder(123.345, -1))

        # Using the round operator, which rounds 5 up when odd, down when even
        self.assertAlmostEqual(123.34, NumericUtils.roundToOrder(123.345, -2))
        self.assertAlmostEqual(123.36, NumericUtils.roundToOrder(123.355, -2))

        self.assertAlmostEqual(123, NumericUtils.roundToOrder(123.345, 0))
        self.assertAlmostEqual(120, NumericUtils.roundToOrder(123.345, 1))
        self.assertAlmostEqual(100, NumericUtils.roundToOrder(123.345, 2))
Exemple #40
0
    def distanceTo(self, position):
        """distanceBetween doc..."""
        xDelta = self.x - position.x
        yDelta = self.y - position.y
        distance = math.sqrt(xDelta * xDelta + yDelta * yDelta)

        # Use the absolute value because the derivatives in error propagation are always
        # absolute values
        xDelta = abs(xDelta)
        yDelta = abs(yDelta)
        try:
            error = (xDelta * (self.xUnc + position.xUnc) + yDelta *
                     (self.yUnc + position.yUnc)) / distance
        except ZeroDivisionError:
            error = 1.0

        return NumericUtils.toValueUncertainty(distance, error)
Exemple #41
0
 def __str__(self):
     return '<%s %s>' % (self.__class__.__name__, NumericUtils.roundToSigFigs(self.degrees, 3))
Exemple #42
0
 def test_sqrtSumOfSquares(self):
     """test_sqrtSumOfSquares doc..."""
     self.assertEqual(1.0, NumericUtils.sqrtSumOfSquares(-1.0))
     self.assertEqual(math.sqrt(2), NumericUtils.sqrtSumOfSquares(1.0, 1.0))
     self.assertEqual(math.sqrt(4.25),
                      NumericUtils.sqrtSumOfSquares(2.0, 0.5))
Exemple #43
0
 def test_equivalent(self):
     """test_equivalent doc..."""
     self.assertTrue(NumericUtils.equivalent(1.0, 1.001, 0.01))
     self.assertFalse(NumericUtils.equivalent(1.0, 1.011, 0.01))
Exemple #44
0
 def xValue(self):
     return NumericUtils.toValueUncertainty(self.x, self.xUnc)
Exemple #45
0
 def value(self):
     return NumericUtils.toValueUncertainty(self.radians, self.uncertainty)
Exemple #46
0
 def yValue(self):
     return NumericUtils.toValueUncertainty(self.y, self.yUnc)
Exemple #47
0
 def rawLabel(self):
     if self._asciiLabels:
         return self.asciiRawLabel
     return '%s %s %s' % (NumericUtils.roundToSigFigs(
         self.raw, 6), StringUtils.unichr(0x00B1), self.uncertainty)
Exemple #48
0
 def value(self):
     uncertainty = self.uncertainty
     order = NumericUtils.orderOfLeastSigFig(uncertainty)
     return NumericUtils.roundToOrder(self._raw, order)
Exemple #49
0
 def uncertainty(self):
     return NumericUtils.roundToSigFigs(abs(self._rawUncertainty), 1)
Exemple #50
0
 def prettyPrint(self):
     return StringUtils.toText(NumericUtils.roundToSigFigs(self.degrees, 3))
Exemple #51
0
 def asciiRawLabel(self):
     return '%s +/- %s' % (NumericUtils.roundToSigFigs(self.raw,
                                                       6), self.uncertainty)
Exemple #52
0
 def valueDegrees(self):
     return NumericUtils.toValueUncertainty(self.degrees, self.uncertaintyDegrees)