<jupyter_start><jupyter_text>READMEThe goal in this script is to simplify generating eoir synthetic data.  An interval of time is specified and the data is generated over that  period. The same period of time is analyzed with different EOIR cloud  and atmospheric properties.  Before running or if using a different scenario, the user needs to  make the below changes.  * Open the STK scenario * Update the file path* Set the animation time & time step Connect Command ReferenceData is generated using connect commands, this information is provided   as refernce. Atmosphere Key* 0 - off.* 1 - Simple atmosphere.* 2 - MODTRAN atmosphere.Atmosphere Simple Parameters* Aerosol Models: Rural* Visibility: 25.00 km* Humidity: 45.8 %    Cloud Key* On - turns on clouds.* Off - turns off clouds.Cloud Parameters* Altitude: 12 km* Forward Scatter: 10%* Back Scatter: 80%* Constant Coverage: 75%* Constant Emissivity and Temperature* Emissivity: 50%* Temperature: 233K<jupyter_code># Open the STK scenario and run this section 
# make any necessary changes 

import os 
import csv
import time
import itertools
from datetime import timedelta
from datetime import datetime
from agi.stk12.stkdesktop import STKDesktop
from agi.stk12.stkobjects import *

# Open EOIR_Clouds_AirToAir.sc
# Connect to the scenario
# Get the IAgStkObjectRoot interface 

stk      = STKDesktop.AttachToApplication()  
root     = stk.Root                           
scenario = root.CurrentScenario 


# set the scenario time 
scenario.StartTime     = '5 May 2020 11:41:30.000'
scenario.StopTime      = '5 May 2020 11:46:30.000'

# Set the scenario animation properties
animation               = scenario.Animation
animation.EnableAnimCycleTime = True
animation.AnimCycleType = AgEScEndLoopType.eLoopAtTime
animation.AnimStepValue = 0.5<jupyter_output><empty_output><jupyter_text>_findObjects()_Look through aircraft objects in the scenario and find the  child (sensor objects). This information will be used in  the connect commands in eoirdata(). This function specifically looks at aircraft objects. Change  AgESTKObjectType.eAircraft if looking at different parent objects.<jupyter_code>def findObjects():

    parentObj = scenario.Children.GetElements(AgESTKObjectType.eAircraft)

    parClass = []
    parName  = []
    chlClass = []
    chlName  = []

    # the scenario has multiple aircraft, sweep through them all
    for i in range(parentObj.Count): 
        if parentObj.Item(i).HasChildren == True:
            # capture the identity of the parent object that has children
            parClass.append(parentObj.Item(i).ClassName)
            parName.append(parentObj.Item(i).InstanceName)
            for j in range(parentObj.Item(i).Children.Count):
                # find number of child objects
                # capture relevant properties 
                chlClass.append(parentObj.Item(i).Children
                    .GetElements(AgESTKObjectType.eSensor).Item(j).ClassName)
                chlName.append(parentObj.Item(i).Children
                    .GetElements(AgESTKObjectType.eSensor).Item(j).InstanceName)
        else:
            continue

    return parClass,parName,chlClass,chlName<jupyter_output><empty_output><jupyter_text>_createfolders()_  Create the folders that eoirdata() will save to. It will first check  if the directories exist and decide if they need to be generated.  Please Note: the scenario will crash if the directories do not exist.<jupyter_code>def createfolders(filepath,data,sensor,ftype,cld,atm):

    # Generate folders for the data to go 
    newdir = os.mkdir("{}output/".format(filepath))

    # Directory structure based on generated data
    for (a,b,c) in itertools.product(data,ftype,sensor): 
        for (x,y) in itertools.zip_longest(cld,atm):
            name = "{}_{}_{}_Cld{}_Atm{}".format(a, b, c, x, y)
            # print("{}output/{}".format(filepath,name))
            os.mkdir("{}output/{}".format(filepath,name))<jupyter_output><empty_output><jupyter_text>_eoirdata()_  eoirdata() uses connect commands to generate the bitmap and the  raw data. In the same line, the data is stored into it's respective  folder, see createfolders(). This function then steps forward in time  and does the whole thing again. The range, or number of iterations is   set by the number of frames. Once it reaches the end time the function  jumps out.<jupyter_code>def eoirdata(parClass,parName,chlClass,sensor,filepath,x,y,z):

    # Use connect commands to generate the EOIR Syn Scene & Txt file 
    for k in range(z):
        for i in range(len(parClass)):
            for j in range(len(chlClass)):
                # print("EOIRDetails */{}/{}/{}/{} SaveSceneImage "\
                #      "\"{}output/raw_bitmap_{}_Cld{}_Atm{}/{}.bmp\""
                #     .format(parClass[i],parName[i],chlClass[j],
                #      sensor[j],filepath,sensor[j],x,y,k))
                # print("EOIRDetails */{}/{}/{}/{} SaveSceneRawData "\
                #      "\"{}output/raw_txt_{}_Cld{}_Atm{}/{}.txt\""
                #     .format(parClass[i],parName[i],chlClass[j],
                #      sensor[j],filepath,sensor[j],x,y,k))
                root.ExecuteCommand("EOIRDetails */{}/{}/{}/{} SaveSceneImage "\
                    "\"{}output/raw_bitmap_{}_Cld{}_Atm{}/{}.bmp\""
                    .format(parClass[i],parName[i],chlClass[j],
                    sensor[j],filepath,sensor[j],x,y,k))
                root.ExecuteCommand("EOIRDetails */{}/{}/{}/{} SaveSceneRawData "\
                    "\"{}output/raw_txt_{}_Cld{}_Atm{}/{}.txt\""
                    .format(parClass[i],parName[i],chlClass[j],
                    sensor[j],filepath,sensor[j],x,y,k))
            root.StepForward()<jupyter_output><empty_output><jupyter_text>_main()_main() kicks everything off. Using the scenario time, it calculates the  number of total frames between start and stop. This will be the number  of times eoirdata() steps through the scenario. findObjects() finds the  parent and child objects, these will be used in the directory names as  well as in the connect commands in eoirdata(). createfolders() is next  and creates the files that data is saved to. Then we start generating data.  The loop jumps to the beginning of the scenario then cycles through the   following cloud and atmospheric parameters.   |Clouds| . |Atmosphere||:-----|:-:|---------:||Off   | . |Off (0)       ||On    | . |Off (0)      ||On    | . |Simple (1)      ||On    | . |MODTRAN (2)  |Once the parameters are set, it dives into eoirdata()<jupyter_code>def main():

    # Measure elapsed time for data generation
    start = time.time() 
    
    # Total frames (k) generated based on scenario animation time/timestep
    d1 = datetime.strptime(animation.StartTime,     "%d %b %Y %H:%M:%S.%f")
    d2 = datetime.strptime(animation.AnimCycleTime, "%d %b %Y %H:%M:%S.%f")
    k  = int(timedelta.total_seconds(d2 - d1)/animation.AnimStepValue)

    parClass,parName,chlClass,sensor  = findObjects()

    ########
    # USER DEFINED 
    # File path for the output data 
    filepath = 'C:/Users/nkazmi/Documents/STK 12/EOIR_Clouds_AirToAir/'

    #k       = 4 # number of frames, used for testing, commment for full run
    data    = ['raw','processed'] # the state of the data
    ftype   = ['bitmap','txt']    # exported data format

    cld     = ['Off','On','On']
    atm     = [0,0,1]
    ########

    # Check if the save to directories exist 
    # Create them before generating data
    isExist = os.path.exists("{}output/".format(filepath))

    if isExist == False:
        print('Creating Directories...')
        createfolders(filepath,data,sensor,ftype,cld,atm)
    else:
        print('Directories Exist')

    # Jump to the beginning of the animation time
    # Set EOIR Cloud and Atmosphere properties
    # Animate and generate data for each timestep 
    for (i,j) in itertools.zip_longest(cld,atm):
        root.Rewind()
        root.ExecuteCommand("EOIR */ SetAtmosphere Clouds {}".format(i))
        root.ExecuteCommand("EOIR */ SetAtmosphere Mode {}".format(j))
        eoirdata(parClass,parName,chlClass,sensor,filepath,i,j,k)
    

    end = time.time()
    print("Elapsed Time (hr): " + str((end - start)/(3600)))

if __name__ == '__main__':
    main()<jupyter_output>Directories Exist
Elapsed Time (hr): 0.04570387853516473
{'fraction_non_alphanumeric': 0.11163503477543323, 'fraction_numerical': 0.010963102675940115, 'mean_word_length': 2.902483900643974, 'pattern_counts': {'":': 0, '<': 20, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '226220', 'license': 'Adobe-2006', 'n_tokens_mistral': 2706, 'n_tokens_neox': 2519, 'n_words': 740, 'path': 'StkAutomation/Python/Scenario_Analysis/EOIR_Synthetic_Scene_and_Data_Generation/EOIR_Image_Generation.ipynb', 'repo_name': 'jpthompson212/STKCodeExamples', 'size': '8483'}