コード例 #1
0
ファイル: TrackCsvImporter.py プロジェクト: sernst/Cadence
    def _writeError(self, data):
        """ Writes import error data to the logger, formatting it for human readable display. """
        source = {}

        if 'data' in data:
            for n,v in DictUtils.iter(data['data']):
                source[' '.join(n.split('_')).title()] = v

        indexPrefix = ''
        if 'index' in data:
            indexPrefix = ' [INDEX: %s]:' % data.get('index', 'Unknown')

        result  = [
            'IMPORT ERROR%s: %s' % (indexPrefix, data['message']),
            'DATA: ' + DictUtils.prettyPrint(source)]

        if 'existing' in data:
            source = {}
            snapshot = data['existing'].snapshot
            if snapshot:
                snapshot = JSON.fromString(snapshot)
            if snapshot:
                for n,v in DictUtils.iter(snapshot):
                    source[' '.join(n.split('_')).title()] = v
            result.append('CONFLICT: ' + DictUtils.prettyPrint(source))

        if 'error' in data:
            self._logger.writeError(result, data['error'])
        else:
            self._logger.write(result)
コード例 #2
0
ファイル: test_LineSegment2D.py プロジェクト: sernst/Cadence
    def test_closestPointOnLine(self):
        """ doc... """
        count = 5000
        bound = 10000.0

        for i in range(count):
            start = PositionValue2D(
                x=random.uniform(-bound, bound),
                y=random.uniform(-bound, bound),
                xUnc=0.1,
                yUnc=0.1)

            end = PositionValue2D(
                x=random.uniform(-bound, bound) + start.x,
                y=random.uniform(-bound, bound) + start.y,
                xUnc=0.1,
                yUnc=0.1)

            line = LineSegment2D(start, end)
            if not line.isValid:
                continue

            target = line.getParametricPosition(random.uniform(0.0, 1.0))
            offset = random.uniform(1.0, bound)
            point  = line.adjustPointAlongLine(target, offset, inPlace=False)

            debug  = {
                'POINT':point,      'TARGET':target,
                'OFFSET':offset,    'DISTANCE':point.distanceTo(target) }

            self.assertAlmostEqual(
                offset, point.distanceTo(target).raw,
                msg='Invalid offset distance:\n'
                    + DictUtils.prettyPrint(debug, delimiter='\n'))

            point.rotate(Angle(degrees=90.0*random.choice([1.0, -1.0])), target)

            self.assertAlmostEqual(
                offset, point.distanceTo(target).raw,
                msg='Invalid rotated offset distance:\n'
                    + DictUtils.prettyPrint(debug, delimiter='\n'))

            pointOnLine = line.closestPointOnLine(point)
            xUnc = math.sqrt(pointOnLine.xUnc*pointOnLine.xUnc + target.xUnc*target.xUnc)
            yUnc = math.sqrt(pointOnLine.yUnc*pointOnLine.yUnc + target.yUnc*target.yUnc)
            debug = {
                'POINT':point,  'RESULT':pointOnLine,
                'INDEX':i,      'TARGET':target,
                'START':start,  'END':end,
                'X_UNC':xUnc,   'Y_UNC':yUnc }

            self.assertAlmostEqual(
                pointOnLine.x, target.x, delta=2.0*xUnc,
                msg='BAD RESULT [X]:\n' + DictUtils.prettyPrint(debug, delimiter='\n'))

            self.assertAlmostEqual(
                pointOnLine.y, target.y, delta=2.0*yUnc,
                msg='BAD RESULT [Y]:\n' + DictUtils.prettyPrint(debug, delimiter='\n'))
コード例 #3
0
ファイル: trackwayPrinter.py プロジェクト: sernst/Cadence
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)
コード例 #4
0
ファイル: ApiRouterView.py プロジェクト: sernst/Ziggurat
    def _createResponse(self):
        super(ApiRouterView, self)._createResponse()

        controllerClass = self.category + 'Controller'
        package         = self._root + '.' + controllerClass

        try:
            # Filter illegal actions
            if not self.category or not self.action or self.action.startswith('_'):
                retuls = self._createErrorResponse(
                    ident='ERROR:' + self.apiID,
                    label='Invalid Action',
                    message='The specified action is invalid')

            # Import the Controller class
            res        = __import__(package, globals(), locals(), [controllerClass])
            controller = getattr(res, controllerClass)(self)

            # If authorized execute the action method, otherwise create a invalid request response
            method = getattr(controller, self.action)
            result = None
            if inspect.ismethod(method) and controller(method):
                result = method()
            else:
                if not self._explicitResponse and not isinstance(result, ViewResponse):
                    result = self._createErrorResponse(
                        ident='ERROR:' + self.apiID,
                        label='Unauthorized Request',
                        message='This unauthorized request was rejected')

            if isinstance(result, ViewResponse):
                self._explicitResponse = result

            # If an explicit response is set render that instead:
            if self._explicitResponse:
                self._createExplicitResponse()
                return

        except Exception as err:
            me = self.echo()
            me['Package'] = package
            me['Controller'] = controllerClass

            self._logger.writeError('API ROUTING FAILURE: %s\n%s' % (
                self.__class__.__name__,
                DictUtils.prettyPrint(me, '\n  ') ), err)

            self._explicitResponse = self._createErrorResponse(
                ident='ERROR:' + self.apiID,
                label='Invalid Request',
                message='This unknown or invalid request was aborted')
            self._createExplicitResponse()
            return

        self._response['__ztime__'] = self.outgoingTimecode
コード例 #5
0
    def _executeMayaCommand(cls, payload, createReply=True):
        cmd = getattr(mc, str(payload['command']), None)
        if cmd is None:
            return NimbleResponseData(
                kind=DataKindEnum.MAYA_COMMAND,
                error=DataErrorEnum.UNRECOGNIZED_MAYA_COMMAND,
                response=NimbleResponseData.FAILED_RESPONSE)

        args = None
        kwargs = None
        try:
            kwargs = DictUtils.cleanDictKeys(payload['kwargs'], True)
            args = payload['args']

            try:
                result = cmd(*args, **kwargs)
            except Exception:
                # Attempts to remove an empty key if one is somehow created
                if '' in kwargs:
                    del kwargs['']
                else:
                    raise
                result = cmd(*args, **kwargs)

            if createReply:
                return cls.createReply(DataKindEnum.MAYA_COMMAND, result)
            else:
                return result
        except Exception as err:
            print('ERROR:', cmd, args, kwargs)
            message = '\n'.join([
                'Failed to execute maya command with payload:',
                'CMD {}'.format(cmd),
                'PAYLOAD: {}'.format(DictUtils.prettyPrint(payload)),
                'ARGS: {}'.format(args),
                'KWARGS: {}'.format(DictUtils.prettyPrint(kwargs))
            ])

            return NimbleResponseData(
                kind=DataKindEnum.MAYA_COMMAND,
                error=cls._getDetailedError(message, err),
                response=NimbleResponseData.FAILED_RESPONSE)
コード例 #6
0
 def __call__(self, *args, **kwargs):
     try:
         return self._createApp(
             ArgsUtils.getAsDict('environ', kwargs, args, 0),
             ArgsUtils.get('start_response', None, kwargs, args, 1) )
     except Exception as err:
         self.logger.writeError([
             'ERROR: Application Creation Failed',
             'ARGS: %s' % ListUtils.prettyPrint(args),
             'KWARGS: %s' % DictUtils.prettyPrint(kwargs) ], err)
         raise
コード例 #7
0
ファイル: MayaRouter.py プロジェクト: sernst/Nimble
    def _executeMayaCommand(cls, payload, createReply =True):
        cmd = getattr(mc, str(payload['command']), None)
        if cmd is None:
            return NimbleResponseData(
                kind=DataKindEnum.MAYA_COMMAND,
                error=DataErrorEnum.UNRECOGNIZED_MAYA_COMMAND,
                response=NimbleResponseData.FAILED_RESPONSE )

        args = None
        kwargs = None
        try:
            kwargs = DictUtils.cleanDictKeys(payload['kwargs'], True)
            args = payload['args']

            try:
                result = cmd(*args, **kwargs)
            except Exception:
                # Attempts to remove an empty key if one is somehow created
                if '' in kwargs:
                    del kwargs['']
                else:
                    raise
                result = cmd(*args, **kwargs)

            if createReply:
                return cls.createReply(DataKindEnum.MAYA_COMMAND, result)
            else:
                return result
        except Exception as err:
            print('ERROR:', cmd, args, kwargs)
            message = '\n'.join([
                'Failed to execute maya command with payload:',
                'CMD {}'.format(cmd),
                'PAYLOAD: {}'.format(DictUtils.prettyPrint(payload)),
                'ARGS: {}'.format(args),
                'KWARGS: {}'.format(DictUtils.prettyPrint(kwargs)) ])

            return NimbleResponseData(
                kind=DataKindEnum.MAYA_COMMAND,
                error=cls._getDetailedError(message, err),
                response=NimbleResponseData.FAILED_RESPONSE )
コード例 #8
0
ファイル: CurveSeries.py プロジェクト: sernst/Cadence
    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)
コード例 #9
0
ファイル: TrackExporter.py プロジェクト: sernst/Cadence
    def process(self, session, difference =True):
        """Doc..."""

        if self.results is not None:
            return True

        results = []
        model = Tracks_Track.MASTER

        if session is None:
            session = model.createSession()

        trackStores = session.query(model).all()
        index = 0
        indices = NumericUtils.linearSpace(0, len(trackStores), roundToIntegers=True)[1:]

        for trackStore in trackStores:
            track = trackStore.getMatchingTrack(session)
            if track is None:
                self.modifications += 1
                results.append({'uid':trackStore.uid, 'action':self.DELETED_IDENTIFIER})

                self.logger.write(
                    u'<div>DELETED: %s</div>' %  DictUtils.prettyPrint(
                        trackStore.toDict(uniqueOnly=True)))
            else:
                if difference:
                    diff = trackStore.toDiffDict(track.toDict())
                    if diff is not None:
                        self.modifications += 1
                        results.append(diff)

                        self.logger.write(
                            u'<div>MODIFIED: %s</div>' % trackStore.fingerprint)
                else:
                    results.append(track.toDict())

            index += 1
            if index in indices:
                self.logger.write(
                    u'<div style="color:#33CC33">%s%% Complete</div>' % StringUtils.toUnicode(
                        10*(indices.index(index) + 1)))

        self.logger.write(u'<div style="color:#33CC33">100% Complete</div>')

        self.results = results
        return True
コード例 #10
0
ファイル: ListUtils.py プロジェクト: moliqingwa/PyAid
    def prettyPrint(cls, source, separator=', '):
        """prettyPrint doc..."""
        out = []

        from pyaid.dict.DictUtils import DictUtils

        for v in source:
            if isinstance(v, (list, tuple)):
                v = cls.prettyPrint(v, separator=',')
            if isinstance(v, dict):
                v = DictUtils.prettyPrint(v)
            elif isinstance(v, StringUtils.BINARY_TYPE):
                v = StringUtils.strToUnicode(v)
            else:
                v = StringUtils.toUnicode(v)
            out.append(v)

        return '[%s]' % separator.join(out)
コード例 #11
0
ファイル: ListUtils.py プロジェクト: sernst/PyAid
    def prettyPrint(cls, source, separator = ', '):
        """prettyPrint doc..."""
        out = []

        from pyaid.dict.DictUtils import DictUtils

        for v in source:
            if isinstance(v, (list, tuple)):
                v = cls.prettyPrint(v, separator=',')
            if isinstance(v, dict):
                v = DictUtils.prettyPrint(v)
            elif isinstance(v, StringUtils.BINARY_TYPE):
                v = StringUtils.strToUnicode(v)
            else:
                v = StringUtils.toUnicode(v)
            out.append(v)

        return '[%s]' % separator.join(out)
コード例 #12
0
ファイル: trackMatchPrinter.py プロジェクト: sernst/Cadence
models = {'Track':Tracks_Track.MASTER}
session = Tracks_Track.MASTER.createSession()
verbose = True

for label,model in models.iteritems():
    query = session.query(model).filter(model.uid.in_((
        'track1l2ic-1s7-rZ3g4I0Yzvzd',
        'track1l2id-1sZ-UvtVfQoOAOPo')) )
    items = query.all()
    print('\n\n\n%s' % (60*'-'))
    print('MODEL:', label)
    print('COUNT:', len(items))

    if not items:
        print('No matching items found')
    else:
        for item in items:
            if verbose:
                print('[TRACK]: %s [%s]:\n  * hidden: %s\n  * complete: %s\n  * next: %s\n%s' % (
                    item.fingerprint, item.uid,
                    'Y' if item.hidden else 'N', 'Y' if item.isComplete else 'N', item.next,
                    '\n  * ' + DictUtils.prettyPrint(item.toDict(uniqueOnly=True), '\n  * ')))
                print('  * Length Uncertainty: %s' % item.rotationUncertainty)
            else:
                print('%s[H:%s|C:%s] "%s" -> "%s"' % (
                    item.fingerprint,
                    'Y' if item.hidden else 'N',
                    'Y' if item.isComplete else 'N',
                    item.uid, item.next))
コード例 #13
0
ファイル: MayaRouter.py プロジェクト: sernst/Nimble
    def runPythonImport(cls, payload):
        try:
            kwargs       = payload.get('kwargs', {})
            targetModule = StringUtils.toStr2(payload.get('module'))
            targetMethod = StringUtils.toStr2(payload.get('method'))
            targetClass  = StringUtils.toStr2(payload.get('class'))
            target       = targetClass if targetClass is not None else targetMethod
            if target is None:
                parts        = targetModule.rsplit('.', 1)
                targetModule = parts[0]
                target       = parts[1]
        except Exception as err:
            NimbleEnvironment.logError([
                'ERROR: Failed to parse python import payload',
                'PAYLOAD: ' + DictUtils.prettyPrint(payload)], err)
            return NimbleResponseData(
                kind=DataKindEnum.PYTHON_IMPORT,
                error=cls._getDetailedError('\n'.join([
                    'ERROR: Failed to parse python import payload',
                    'PAYLOAD: ' + DictUtils.prettyPrint(payload)]), err),
                response=NimbleResponseData.FAILED_RESPONSE)

        # Dynamically import the specified module and reload it to make sure any changes have
        # been updated
        try:
            module = __import__(
                StringUtils.toStr2(targetModule),
                globals(), locals(),
                [StringUtils.toStr2(target)] if target else [])
            reload(module)
            target = getattr(module, target)
        except Exception as err:
            NimbleEnvironment.logError([
                'ERROR: Failed to import python target',
                'MODULE: %s' % targetModule,
                'TARGET: %s' % target,
                'PAYLOAD: ' + DictUtils.prettyPrint(payload)], err)
            return NimbleResponseData(
                kind=DataKindEnum.PYTHON_IMPORT,
                error=cls._getDetailedError(
                    'Failed to import python module', err),
                response=NimbleResponseData.FAILED_RESPONSE)

        try:
            result = dict()
            if targetClass is not None:
                tc = target()
                result = getattr(tc, targetMethod)(**kwargs) \
                    if targetMethod else \
                    tc(**kwargs)
            elif targetMethod is not None:
                result = target(**kwargs)
            else:
                # Find a NimbleScriptBase derived class definition and if it exists, run it to
                # populate the results
                for name,value in DictUtils.iter(Reflection.getReflectionDict(target)):
                    if not inspect.isclass(value):
                        continue

                    if NimbleScriptBase in value.__bases__:
                        result = getattr(target, name)()(**kwargs)
                        found  = True

            # If a result dictionary contains an error key format the response as a failure
            errorMessage = None
            try:
                errorMessage = ArgsUtils.extract(
                    NimbleEnvironment.REMOTE_RESULT_ERROR_KEY, None, result)
            except Exception as err:
                pass

            return cls.createReply(DataKindEnum.PYTHON_IMPORT, result, errorMessage=errorMessage)
        except Exception as err:
            msg = 'ERROR: Failed to execute remote script'
            NimbleEnvironment.logError([
                msg,
                'PAYLOAD: ' + DictUtils.prettyPrint(payload),
                'TARGET: ' + str(target)], err)
            return NimbleResponseData(
                kind=DataKindEnum.PYTHON_IMPORT,
                error=cls._getDetailedError(msg, err),
                response=NimbleResponseData.FAILED_RESPONSE)
コード例 #14
0
ファイル: trackPropertyOutput.py プロジェクト: sernst/Cadence
from __future__ import print_function, absolute_import, unicode_literals, division
from pyaid.dict.DictUtils import DictUtils

from pyglass.app.PyGlassEnvironment import PyGlassEnvironment

PyGlassEnvironment.initializeFromInternalPath(__file__)

from cadence.models.tracks.Tracks_Track import Tracks_Track

model   = Tracks_Track.MASTER
session = model.createSession()

result  = session.query(model).filter(model.uid == 'track1l2i9-11o-zTs69ewQDfdS').all()

for track in result:
    print('FINGERPRINT:', track.fingerprint)
    print('PREVIOUS:', track.getPreviousTrack())
    print(DictUtils.prettyPrint(track.toDict()))
コード例 #15
0
    def runPythonImport(cls, payload):
        try:
            kwargs = payload.get('kwargs', {})
            targetModule = StringUtils.toStr2(payload.get('module'))
            targetMethod = StringUtils.toStr2(payload.get('method'))
            targetClass = StringUtils.toStr2(payload.get('class'))
            target = targetClass if targetClass is not None else targetMethod
            if target is None:
                parts = targetModule.rsplit('.', 1)
                targetModule = parts[0]
                target = parts[1]
        except Exception as err:
            NimbleEnvironment.logError([
                'ERROR: Failed to parse python import payload',
                'PAYLOAD: ' + DictUtils.prettyPrint(payload)
            ], err)
            return NimbleResponseData(
                kind=DataKindEnum.PYTHON_IMPORT,
                error=cls._getDetailedError(
                    '\n'.join([
                        'ERROR: Failed to parse python import payload',
                        'PAYLOAD: ' + DictUtils.prettyPrint(payload)
                    ]), err),
                response=NimbleResponseData.FAILED_RESPONSE)

        # Dynamically import the specified module and reload it to make sure any changes have
        # been updated
        try:
            module = __import__(StringUtils.toStr2(targetModule), globals(),
                                locals(),
                                [StringUtils.toStr2(target)] if target else [])
            reload(module)
            target = getattr(module, target)
        except Exception as err:
            NimbleEnvironment.logError([
                'ERROR: Failed to import python target',
                'MODULE: %s' % targetModule,
                'TARGET: %s' % target,
                'PAYLOAD: ' + DictUtils.prettyPrint(payload)
            ], err)
            return NimbleResponseData(
                kind=DataKindEnum.PYTHON_IMPORT,
                error=cls._getDetailedError('Failed to import python module',
                                            err),
                response=NimbleResponseData.FAILED_RESPONSE)

        try:
            result = dict()
            if targetClass is not None:
                tc = target()
                result = getattr(tc, targetMethod)(**kwargs) \
                    if targetMethod else \
                    tc(**kwargs)
            elif targetMethod is not None:
                result = target(**kwargs)
            else:
                # Find a NimbleScriptBase derived class definition and if it exists, run it to
                # populate the results
                for name, value in DictUtils.iter(
                        Reflection.getReflectionDict(target)):
                    if not inspect.isclass(value):
                        continue

                    if NimbleScriptBase in value.__bases__:
                        result = getattr(target, name)()(**kwargs)
                        found = True

            # If a result dictionary contains an error key format the response as a failure
            errorMessage = None
            try:
                errorMessage = ArgsUtils.extract(
                    NimbleEnvironment.REMOTE_RESULT_ERROR_KEY, None, result)
            except Exception as err:
                pass

            return cls.createReply(DataKindEnum.PYTHON_IMPORT,
                                   result,
                                   errorMessage=errorMessage)
        except Exception as err:
            msg = 'ERROR: Failed to execute remote script'
            NimbleEnvironment.logError([
                msg, 'PAYLOAD: ' + DictUtils.prettyPrint(payload),
                'TARGET: ' + str(target)
            ], err)
            return NimbleResponseData(
                kind=DataKindEnum.PYTHON_IMPORT,
                error=cls._getDetailedError(msg, err),
                response=NimbleResponseData.FAILED_RESPONSE)
コード例 #16
0
ファイル: TrackLinkConnector.py プロジェクト: sernst/Cadence
    def _runTrack(self, source, session):
        """Doc..."""

        model = source.__class__
        trackSeries = session.query(model).filter(
            model.site == source.site,
            model.sector == source.sector,
            model.level == source.level,
            model.trackwayType == source.trackwayType,
            model.trackwayNumber == source.trackwayNumber,
            model.pes == source.pes,
            model.left == source.left).order_by(model.number.asc()).all()

        if not trackSeries:
            return False

        #-------------------------------------------------------------------------------------------
        # TRACK ORDERING
        #       Tracks numbers are strings to support naming conventions like 10b or 12c, where the
        #       number is possibly followed by a non-numeric set of characters. To establish track
        #       ordering the sequence should be sorted primarily by the numeric sequence and
        #       secondarily by the suffix first numerically and then alphabetically respectively.

        trackNumbers = dict()
        for track in trackSeries:
            result = self._TRACK_NUMBER_RE.search(track.number)
            if not result or result.group('prefix'):
                self.logger.write([
                    u'ERROR: Unable to parse track number: ' + StringUtils.toUnicode(track.number),
                    u'TRACK: ' + DictUtils.prettyPrint(track.toDict()) ])
                continue

            number = result.group('number')
            suffix = result.group('suffix')

            if number not in trackNumbers:
                trackNumbers[number] = {'track':None, 'extras':{}, 'number':int(number)}
            entry = trackNumbers[number]

            if number == track.number and not suffix:
                entry['track'] = track
            elif not suffix:
                self.logger.write([
                    u'ERROR: Invalid track number: ' + StringUtils.toUnicode(track.number),
                    u'TRACK: ' + DictUtils.prettyPrint(track.toDict()) ])
                continue
            else:
                entry['extras'][suffix] = track

            if track not in self.operatedTracks:
                self.operatedTracks.append(track)

        prev = None
        entries = list(trackNumbers.values())
        entries.sort(key=lambda x: x['number'])
        for entry in entries:
            track = entry['track']
            tracks = [] if track is None else [track]
            for key in sorted(entry['extras']):
                tracks.append(entry['extras'][key])

            for track in tracks:
                if not prev:
                    prev = track
                    continue

                # If the previous entry has an existing next that doesn't match
                if not self.overrideExisting and prev.next and prev.next != track.uid:
                    continue

                prev.next = track.uid
                self.modifiedTracks.append(prev)
                self.trackLinkages.append((prev, track))
                prev = track
コード例 #17
0
ファイル: TrackPrinter.py プロジェクト: sernst/Cadence
        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()