Example #1
0
drawing.text("circle of radius 5 at (200, 10)", (100, 10), scene=True, stroke='blue')

# now place another circle and rect in map (not scene) coordinates below the federal marker
drawing.rect((xScene, yScene - 100), 4, 10, scene=False, fill='red')

# and another at (100, 200), also in map coordinates
drawing.rect((100, 200), 10, 4, scene=False)


#==================================================================================================
#  CREATE A GROUP CONTAINING A RECT, SHOWING HOW TO USE (INSTANCE) IT ROTATED AND TRANSLATED

drawing.createGroup('r1')
drawing.rect((0, 0), 10, 30, scene=False, groupId='r1') # add this rect to the group

drawing.use('r1', (400, 100), rotation=10, fill='blue')
drawing.use('r1', (400, 200), rotation=20, fill='blue')
drawing.use('r1', (400, 300), rotation=30, fill='blue')
drawing.use('r1', (400, 400), rotation=40, fill='blue')
drawing.use('r1', (400, 500), rotation=50, fill='blue')

#==================================================================================================

drawing.save()

#==================================================================================================
""" The general format for the command line invocation of inkscape is:

for PDF export:

inkscape -f sourceFile.svg -A destinationFile.pdf
Example #2
0
#
#     drawing.circle((x, z), r, scene=True, fill='none', stroke='blue', stroke_width=1)
#
#     # compute the averge uncertainty in cm (also stored in fractional meters)
#     u = 100*(track.widthUncertainty + track.lengthUncertainty)/2.0
#
#     drawing.circle((x, z), u, scene=True, fill='red', stroke='red', stroke_width=1)


#==================================================================================================
#  CREATE A GROUP CONTAINING A RECT, SHOWING HOW TO USE (INSTANCE) IT ROTATED AND TRANSLATED

drawing.createGroup('g1')
drawing.rect((0, 0), 10, 40, scene=False, groupId='g1') # add this rect to the group

drawing.use('g1', (400, 100), rotation=10)
drawing.use('g1', (400, 200), rotation=20)
drawing.use('g1', (400, 300), rotation=30)
drawing.use('g1', (400, 400), rotation=40)
drawing.use('g1', (400, 500), rotation=50)

#==================================================================================================
# #  CREATE A GROUP CONTAINING A CIRCLE, SHOWING HOW TO USE (INSTANCE) IT SCALED
#
# drawing.createGroup('g1')
# drawing.circle((0, 0), 10, scene=False, groupId='g1') # add this circle to the group
#
# drawing.use('g1', (400, 100), scale=1, scaleY=1)
# drawing.use('g1', (400, 200), scale=1, scaleY=1.1)
# drawing.use('g1', (400, 300), scale=1, scaleY=1.5)
# drawing.use('g1', (400, 400), scale=1, scaleY=2)
Example #3
0
class RotationStage(AnalysisStage):
    """ Compares the rotational values from the field measurements, where they
        exist, with the measurements entered digitally determine the level of
        equivalence between the data sets.
    """

    DRAWING_FOLDER_NAME = 'Rotation-Comparison-Maps'

    #___________________________________________________________________________
    def __init__(self, key, owner, **kwargs):
        """Creates a new instance of RotationStage."""
        super(RotationStage, self).__init__(
            key, owner,
            label='Rotation Comparison',
            **kwargs)

        self._paths = []
        self._diffs = []
        self._data  = []
        self._csv   = None

        self._currentDrawing = None

    #===========================================================================
    #                                                             G E T / S E T

    #___________________________________________________________________________
    @property
    def deviations(self):
        return self.cache.get('trackDeviations')

    #===========================================================================
    #                                                         P R O T E C T E D

    #___________________________________________________________________________
    def _preAnalyze(self):
        """_preAnalyze doc..."""
        self.cache.set('trackDeviations', {})
        self._diffs = []
        self._data  = []
        self._currentDrawing = None

        csv = CsvWriter()
        csv.path = self.getPath('Rotation-Report.csv', isFile=True)
        csv.addFields(
            ('uid', 'UID'),
            ('fingerprint', 'Fingerprint'),
            ('delta', 'Discrepancy'),
            ('entered', 'Entered'),
            ('measured', 'Measured'),
            ('deviation', 'Deviation'),
            ('relative', 'Relative'),
            ('axis', 'Axis'),
            ('axisPairing', 'Axis Pairing'))
        self._csv = csv

    #___________________________________________________________________________
    def _analyzeSitemap(self, sitemap):

        # start a drawing for the SVG and PDF files
        fileName = sitemap.name + "_" + sitemap.level + '_rotation.svg'
        path = self.getPath(self.DRAWING_FOLDER_NAME, fileName, isFile=True)
        self._currentDrawing = CadenceDrawing(path, sitemap)

        # create a group to be instanced for the map annotations
        self._currentDrawing.createGroup('pointer')
        self._currentDrawing.line(
            p1=(0, 0),
            p2=(0, -10),
            scene=False,
            groupId='pointer')

        # and place a grid and the federal coordinates in the drawing file
        self._currentDrawing.grid()
        self._currentDrawing.federalCoordinates()

        super(RotationStage, self)._analyzeSitemap(sitemap)

        if self._currentDrawing:
            self._currentDrawing.save()

    #___________________________________________________________________________
    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')


#_______________________________________________________________________________
    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 = []

#_______________________________________________________________________________
    def _makePlot(self, label, data, isLog =False, histRange =None, color ='r', binCount = 72):
        """_makePlot doc..."""

        pl = self.plot
        self.owner.createFigure('histogram')

        pl.hist(data, binCount, range=histRange, log=isLog, facecolor=color, alpha=0.75)
        pl.title('%s Distribution%s' % (label, ' (log)' if isLog else ''))
        pl.xlabel('Difference (Degrees)')
        pl.ylabel('Frequency')
        pl.grid(True)

        axis = pl.gca()
        xlims = axis.get_xlim()
        pl.xlim((max(histRange[0], xlims[0]), min(histRange[1], xlims[1])))

        path = self.getTempPath('%s.pdf' % StringUtils.getRandomString(16), isFile=True)
        self.owner.saveFigure('histogram', path)
        return path
Example #4
0
drawing.line((100,100), (200, 100), scene=True, stroke='red', stroke_width=4)

# label it with text at (20, 10)
drawing.text("circle of radius 5", (20, 10), scene=True)

# now place another circle and rect in map coordinates (not scene coordinates) at the federal marker
drawing.rect((xFed + 40, yFed), 20, 20, fill='none', scene=False)



# now overlay onto the above measured-dimension bars the corresponding length indicators
drawing.use(
            'bar',
            (100, 200),
            scale=1.0,
            scaleY=lengthRatio*trackLength,
            rotation=trackRotation,
            scene=True,
            stroke='red',
            stroke_width=2.0)

# draw the remaining portion of the length bar
drawing.use(
            'bar',
            (100, 200),
            scale=1.0,
            scaleY=(1.0 - lengthRatio)*trackLength,
            rotation=trackRotation + 180.0,
            #rotation=trackRotation + 45.0,
            scene=True,
            stroke='orange',
Example #5
0
             -200,
             100,
             scene=False,
             groupId='rect2')


drawing.createGroup('circ')
drawing.circle((0, 0),
               50,
               scene=False,
               groupId='circ',
               fill='none',
               stroke='blue',
               stroke_width=2)

drawing.use('rect', (0, 0), scene=True, fill='yellow', scale=1, scaleY=1)
drawing.use('rect', (0, 0), scene=True, fill='red', scale=1, scaleY=1, rotation=45)
#drawing.use('rect2', (0, 0), scene=True, fill='red', scale=1, scaleY=1)
drawing.use('circ', (0, 0), scene=True, rotation=0, scale=2, scaleY=2, fill='none', stroke='blue')

#drawing.use('rect',  (1000, -100), scene=True, fill='yellow', scale=1, scaleY=1, rotation=0.0)
#drawing.use('rect2', (1000, -1000), scene=True, fill='yellow', scale=1, scaleY=1)
#drawing.use('circ',  (1000, -1000), scene=True, rotation=0, scale=1, scaleY=1, fill='none', stroke='blue')

#==================================================================================================

drawing.grid(size=10, stroke='red')
drawing.circle((0,0), 5, fill='none', stroke='red')
drawing.federalCoordinates()

drawing.save(toPDF=True)