예제 #1
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)
예제 #2
0
    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
예제 #3
0
 def rawLabel(self):
     if self._asciiLabels:
         return self.asciiRawLabel
     return '%s %s %s' % (
         NumericUtils.roundToSigFigs(self.raw, 6),
         StringUtils.unichr(0x00B1),
         self.uncertainty)
예제 #4
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)
예제 #5
0
 def asciiRawLabel(self):
     return '%s +/- %s' % (NumericUtils.roundToSigFigs(self.raw,
                                                       6), self.uncertainty)
예제 #6
0
 def rawLabel(self):
     if self._asciiLabels:
         return self.asciiRawLabel
     return '%s %s %s' % (NumericUtils.roundToSigFigs(
         self.raw, 6), StringUtils.unichr(0x00B1), self.uncertainty)
예제 #7
0
 def uncertainty(self):
     return NumericUtils.roundToSigFigs(abs(self._rawUncertainty), 1)
예제 #8
0
    def _process(self):
        """_processDeviations doc..."""
        errors  = []

        for entry in self.entries:
            if 'fractional' in entry:
                errors.append(entry['fractional'])

        res = NumericUtils.getMeanAndDeviation(errors)
        self.logger.write('Fractional Stride Error %s' % res.label)

        label = 'Fractional Stride Errors'
        self._paths.append(self._makePlot(
            label=label,
            data=errors,
            histRange=(-1.0, 1.0) ))
        self._paths.append(self._makePlot(
            label=label,
            data=errors,
            isLog=True,
            histRange=(-1.0, 1.0) ))

        # noinspection PyUnresolvedReferences
        d = np.absolute(np.array(errors))
        self._paths.append(self._makePlot(
            label='Absolute %s' % label,
            data=d, histRange=(0.0, 1.0) ))
        self._paths.append(self._makePlot(
            label='Absolute %s' % label,
            data=d,
            isLog=True,
            histRange=(0.0, 1.0) ))

        highDeviationCount = 0

        for entry in self.entries:
            if 'measured' not in entry:
                # Skip tracks that have no measured stride value for comparison
                continue

            if entry['deviation'] > 2.0:
                highDeviationCount += 1

            track = entry['track']
            delta = NumericUtils.roundToSigFigs(100.0*abs(entry['delta']), 3)

            self._csv.addRow({
                'fingerprint':track.fingerprint,
                'uid':track.uid,
                'measured':entry['measured'].label,
                'entered':entry['entered'].label,
                'dev':entry['deviation'],
                'delta':delta})

        if not self._csv.save():
            self.logger.write(
                '[ERROR]: Failed to save CSV file %s' % self._csv.path)

        percentage = NumericUtils.roundToOrder(
            100.0*float(highDeviationCount)/float(len(self.entries)), -2)
        self.logger.write(
            '%s significant %s (%s%%)' % (
                highDeviationCount,
                label.lower(),
                percentage))

        if percentage > (100.0 - 95.45):
            self.logger.write(
                '[WARNING]: Large deviation count exceeds normal ' +
                'distribution expectations.')
예제 #9
0
    def _process(self):
        """_processDeviations doc..."""
        errors  = []

        for entry in self.entries:
            if 'fractional' in entry:
                errors.append(entry['fractional'])

        res = NumericUtils.getMeanAndDeviation(errors)
        self.logger.write('Fractional Pace Error %s' % res.label)

        label = 'Fractional Pace Errors'
        d     = errors
        self._paths.append(self._makePlot(
            label=label,
            data=d,
            histRange=(-1.0, 1.0)))
        self._paths.append(self._makePlot(
            label=label,
            data=d,
            isLog=True,
            histRange=(-1.0, 1.0)))

        # noinspection PyUnresolvedReferences
        d = np.absolute(np.array(d))
        self._paths.append(self._makePlot(
            label='Absolute %s' % label,
            data=d,
            histRange=(0.0, 1.0) ))
        self._paths.append(self._makePlot(
            label='Absolute %s' % label,
            data=d,
            isLog=True,
            histRange=(0.0, 1.0) ))

        highDeviationCount = 0

        for entry in self.entries:
            if 'measured' not in entry:
                # entry['drawFunc']('purple')
                continue

            if entry['deviation'] > 2.0:
                entry['drawFunc']('red')
                highDeviationCount += 1
            else:
                entry['drawFunc'](
                    'black' if abs(entry['deviation']) < 2.0 else '#FFAAAA')

            track = entry['track']
            delta = NumericUtils.roundToSigFigs(100.0*abs(entry['delta']), 3)

            pairTrack = entry.get('pairTrack')
            if pairTrack:
                pairedFingerprint = pairTrack.fingerprint
                pairedUid         = pairTrack.uid
            else:
                pairedFingerprint = ''
                pairedUid         = ''

            self._csv.addRow({
                'fingerprint':track.fingerprint,
                'uid':track.uid,
                'measured':entry['measured'].label,
                'entered':entry['entered'].label,
                'dev':entry['deviation'],
                'delta':delta,
                'pairedUid':pairedUid,
                'pairedFingerprint':pairedFingerprint})

        for sitemap in self.owner.getSitemaps():
            # Remove drawing from the sitemap cache and save the drawing file
            try:
                sitemap.cache.extract('drawing').save()
            except Exception:
                self.logger.write('[WARNING]: No sitemap saved for %s-%s' % (
                    sitemap.name, sitemap.level))

        if not self._csv.save():
            self.logger.write(
                '[ERROR]: Failed to save CSV file %s' % self._csv.path)

        if not self._errorCsv.save():
            self.logger.write(
                '[ERROR]: Failed to save CSV file %s' % self._errorCsv.path)

        percentage = NumericUtils.roundToOrder(
            100.0*float(highDeviationCount)/float(len(self.entries)), -2)
        self.logger.write('%s significant %s (%s%%)' % (
            highDeviationCount,
            label.lower(),
            percentage))
        if percentage > (100.0 - 95.45):
            self.logger.write(
                '[WARNING]: Large deviation count exceeds normal ' +
                'distribution expectations.')
예제 #10
0
        if not_found:
            missing.append(uid_entry)
    tracks = ordered

    if missing:
        print('MISSING UIDS:')
        for not_found_uid in missing:
            print('  * {}'.format(not_found_uid))
        print('\n\n')

#_______________________________________________________________________________
# TRACK ITERATOR
for track in tracks:
    print(track.echoForVerification())
    print('        size: (%s, %s) | field (%s, %s)' % (
        track.width, track.length, track.widthMeasured, track.lengthMeasured))
    print('        hidden: %s | custom: %s' % (
        'Y' if track.hidden else 'N',
        'Y' if track.custom else 'N'))
    aTrack = track.getAnalysisPair(aSession)
    print('        curve[%s]: %s (%s)' % (
        aTrack.curveSegment,
        NumericUtils.roundToSigFigs(aTrack.segmentPosition, 4),
        NumericUtils.roundToSigFigs(aTrack.curvePosition, 4)))
    print('        snapshot: %s' % DictUtils.prettyPrint(track.snapshotData))
    print('        imports: %s' % track.echoImportFlags())
    print('        analysis: %s\n' % track.echoAnalysisFlags())

session.close()
aSession.close()
예제 #11
0
    def _analyzeTrackSeries(self, series, trackway, sitemap):

        if len(series.tracks) < 2:
            # At least two tracks are required to make the comparison
            return

        for track in series.tracks:
            fieldAngle = Angle(
                degrees=track.rotationMeasured \
                    if track.rotationMeasured \
                    else  0.0)
            dataAngle  = Angle(degrees=track.rotation)
            strideLine = StrideLine(track=track, series=series)

            if track.hidden or strideLine.pairTrack.hidden:
                continue

            try:
                strideLine.vector.normalize()
            except ZeroDivisionError:
                pair = strideLine.pairTrack
                self.logger.write([
                    '[ERROR]: Stride line was a zero length vector',
                    'TRACK: %s (%s, %s) [%s]' % (
                        track.fingerprint,
                        NumericUtils.roundToSigFigs(track.x, 3),
                        NumericUtils.roundToSigFigs(track.z, 3),
                        track.uid),
                    'PAIRING: %s (%s, %s) [%s]' % (
                        pair.fingerprint,
                        NumericUtils.roundToSigFigs(pair.x, 3),
                        NumericUtils.roundToSigFigs(pair.z, 3),
                        pair.uid) ])
                continue

            axisAngle = strideLine.angle
            if track.left:
                fieldAngle.radians += axisAngle.radians
            else:
                fieldAngle.radians = axisAngle.radians - fieldAngle.radians

            # Adjust field angle into range [-180, 180]
            fieldAngle.constrainToRevolution()
            if fieldAngle.degrees > 180.0:
                fieldAngle.degrees -= 360.0

            fieldAngleUnc = Angle(degrees=5.0)
            fieldAngleUnc.radians += \
                0.03/math.sqrt(1.0 - math.pow(strideLine.vector.x, 2))
            fieldDeg = NumericUtils.toValueUncertainty(
                value=fieldAngle.degrees,
                uncertainty=fieldAngleUnc.degrees)

            # Adjust data angle into range [-180, 180]
            dataAngle.constrainToRevolution()
            if dataAngle.degrees > 180.0:
                dataAngle.degrees -= 360.0

            dataAngleUnc = Angle(degrees=track.rotationUncertainty)
            dataDeg = NumericUtils.toValueUncertainty(
                value=dataAngle.degrees,
                uncertainty=dataAngleUnc.degrees)

            angle1 = Angle(degrees=dataDeg.value)
            angle2 = Angle(degrees=fieldDeg.value)

            # fill color for the disks to be added to the map are based on
            # diffDeg
            diffDeg = NumericUtils.toValueUncertainty(
                value=angle1.differenceBetween(angle2).degrees,
                uncertainty=min(90.0, math.sqrt(
                    math.pow(dataAngleUnc.degrees, 2) +
                    math.pow(fieldAngleUnc.degrees, 2))) )

            self._diffs.append(diffDeg.value)

            deviation = diffDeg.value/diffDeg.uncertainty
            self.deviations[track.uid] = diffDeg

            # for now, convert +/- 180 headings to 0-360, using e and m
            # comment the next four lines toggle comments for entered and
            # measured below to revert
            e = dataDeg.value
            m = fieldDeg.value
            if e < 0.0:
                e += 360.0
            if m < 0.0:
                m += 360.0

            data = dict(
                uid=track.uid,
                fingerprint=track.fingerprint,
                entered=str(e),
                measured=str(m),
                delta=abs(diffDeg.value),
                deviation=deviation,
                relative=NumericUtils.roundToOrder(track.rotationMeasured, -2),
                axis=NumericUtils.roundToOrder(axisAngle.degrees, -2),
                axisPairing='NEXT' if strideLine.isNext else 'PREV')
            self._csv.createRow(**data)

            data['track'] = track
            self._data.append(data)

            # draw the stride line pointer for reference in green
            self._currentDrawing.use(
                'pointer',
                (track.x, track.z),
                scene=True,
                rotation=axisAngle.degrees,
                stroke_width=1,
                scale=0.5,
                stroke='green')

            # indicate in blue the map-derived estimate of track rotation
            self._currentDrawing.use(
                'pointer',
                (track.x, track.z),
                scene=True,
                rotation=dataDeg.value,
                stroke_width=1,
                stroke='blue')

            # add the measured (spreadsheet) estimate of rotation
            self._currentDrawing.use(
                'pointer',
                (track.x, track.z),
                scene=True,
                rotation=fieldDeg.value,
                stroke_width=1,
                stroke='red')

            # place a translucent disk of radius proportional to the difference
            # in degrees
            radius = 100.0*diffDeg.value/180.0
            self._currentDrawing.circle(
                (track.x, track.z),
                radius,
                scene=True,
                fill='red',
                stroke_width=0.5,
                stroke='red',
                fill_opacity='0.5')
예제 #12
0
 def asciiRawLabel(self):
     return '%s +/- %s' % (
         NumericUtils.roundToSigFigs(self.raw, 6),
         self.uncertainty)
예제 #13
0
 def uncertainty(self):
     return NumericUtils.roundToSigFigs(abs(self._rawUncertainty), 1)
예제 #14
0
 def prettyPrint(self):
     return StringUtils.toText(NumericUtils.roundToSigFigs(self.degrees, 3))
예제 #15
0
 def __str__(self):
     return '<%s %s>' % (self.__class__.__name__, NumericUtils.roundToSigFigs(self.degrees, 3))