PyMystic

PyMystic is a Python module that may be used to read AER files. It is written entirely in Python 3 and has no additional requirements. PyMystic primarily facilitates Design of Experiments analysis and batch processing of AFSIM Monte-Carlo runs. It may also aid in Mystic capability prototyping and custom data extraction.

PyMystic uses the schema embedded in the read AER file. This should make it cross-compatible with any version of AFSIM, so long as the rules underlying the schema itself have not changed. The contents of a schema will change between versions, so a script written using PyMystic is not necessarily cross-version-compatible. The contents of the event-pipe messages are documented by the event_pipe page from the version of AFSIM from which the file was created.

Usage

PyMystic defines a Reader class that can read Messages from an event-pipe file. In general a pymystic script is structured as follows:

import pymystic

with pymystic.Reader('somefilename.aer') as reader # create a reader
   for msg in reader: # Loop over every message in the AER file
      # process messages here
      pass

Messages are represented as Python dictionaries, where each key is tied to a value. For some keys, the associated value may itself be a dictionary.

API Documentation

class pymystic.Reader(filename, debug=False)

The Reader class will open an AER file, generate the schema from the header, and then allow the reading of messages.

This class may be used as an iterator, in which case it will yeild the messages in the loaded file in order.

__init__(filename, debug=False)

This method will load a file of the given filename, which may be processed with other Reader methods. Files must have the .aer extension. The filename may include a relative or absolute path to the file.

You may use this class as a context manager as follows:

with Reader("filename.aer") as reader:
   # Use the reader here
   pass
Parameters
  • filename – The name and extension of the input file.

  • debug (bool, optional) – Print debug strings while parsing the AER file.

close()

This method will close the loaded replay file. This allows users to explicitly release the file handle in the event of an error.

process(msgdata)

This method converts MessageData into a Message.

Parameters

msgdata – A MessageData tuple output by either pymystic.Reader.scan() or pymystic.Reader.scan_iter().

Returns

A dictionary, representing the message.

read()

This method will read and return the next message in the loaded file.

Returns

A dictionary, representing next message in the currently loaded file, or None if EOF has been reached.

scan()

This method reads only the header data of the next message in the file, allowing the user to filter messages by type. In order to parse the data into a dictionary, pass the output to pymystic.Reader.process().

Returns:

A tuple containing:

  • The message id (int)

  • The message type (string)

  • The message (bytes)

scan_iter()

Yields an iterator over the messages in the AER file. In order to parse the data into a dictionary, pass the output to pymystic.Reader.process().

Yields:

a tuple containing:

  • The message id (int)

  • The message type (string)

  • The message (bytes)

class pymystic.Schema(aSchemaStr)

The Schema class consumes a schema string and generates local definitions of the schema.

__init__(aSchemaStr)

The schema constructor takes a schema string and builds up a definition representation of the schema, and a map from message id to structure name

Parameters

aSchemaStr (str) – The schema definition string

example_message_list.py

This example script will output a list of times and message types, and when an entity state message is encountered it will also write the name of the relevant platform.

Output will look like this:

28797.0 MsgEntityState platformA
28798.0 MsgEntityState platformB
28798.0 MsgEntityState platformA
28799.0 MsgEntityState platformB
28800.001953125 :  MsgPlatformStatus
28800.001953125 :  MsgPlatformStatus

example_graph.py

This example requires graphviz and the graphviz python modules. It will query command-chain relationships from the MsgPlatformInfo messages and use them to build the entire scenario’s command-chain graph. It will then render this graph into a PDF.

Output will look like this:

../_images/pymystic_graph.png

example_bigreport.py

This example will read from a local aerlist.txt file containing a list of AER filenames (users will need to generate this). It will read the execution data message from each file and report the version of AFSIM that is was executed in, and the time-stamp of the execution.

Output will look like this:

TESTING  /AFSIM/test_scenarios/scen1/scen1.aer
   ***unversioned***
TESTING  /AFSIM/training/developer/labs/solution/comm/data/comm_exercise.aer
   version:   mission 2.4.0.190626
   executed:  2019-06-28 09:09:48
TESTING  /AFSIM/training/developer/labs/solution/comm/data/comm_exercise2.aer
   version:   mission 2.4.0.190626
   executed:  2019-06-28 09:09:52
TESTING  /AFSIM/training/user/basic/scenarios/solutions/11/Floridistan/output/jacksonabad.aer
   version:   Warlock 2.5.0.191029
   executed:  2019-10-31 11:50:59

example_print_message_data.py

The purpose of this example is to demonstrate recursive processing of messages represented by nested dictionaries.

The script takes an AER file as a parameter, and reads each message from the input file, printing the data from each message to the console. The FormatMessage function recursively formats messages containing nested dictionaries.

Output will look like this:

id:                                                1
msgtype:                                           MsgEntityState
simTime:                                           0.0
simIndex:                                          0
state:
      platformIndex:                             38
      damageFactor:                              0.0
      locationWCS:
               x:                                 -2356075.8866955335
               y:                                 -3743698.25337908
               z:                                 4579620.857159804
      velocityWCSValid:                          False
      accelerationWCSValid:                      False
      orientationWCSValid:                       True
      orientationWCS:
               x:                                 1.0090789794921875
               y:                                 -0.7646905779838562
               z:                                 3.1415927410125732
      fuelCurrentValid:                          True
      fuelCurrent:                               0.0