def findSimDefinitionFile(providedPath): # It is already a path, just return it if os.path.isfile(providedPath): return providedPath # Track if it is a relative path, relative to a different location than the current terminal (example/default cases) installationLocation = Path(__file__).parent.parent alternateLocations = [ installationLocation / "MAPLEAF/Examples/Simulations/", installationLocation / "MAPLEAF/Examples/BatchSims/" ] possibleRelativePaths = [providedPath] if len(providedPath) < 8 or providedPath[-8:] != ".mapleaf": # If it's just the case name (ex: 'Staging') try also adding the file extension possibleRelativePaths = [providedPath, providedPath + ".mapleaf"] for path in possibleRelativePaths: for alternateLocation in alternateLocations: absPath = getAbsoluteFilePath(path, alternateLocation, silent=True) if os.path.isfile(absPath): # We've located the file! return absPath print( "ERROR: Unable to locate simulation definition file: {}! Checked whether the path was relative to the current command line location, the MAPLEAF installation directory, or one of the example cases. To be sure that your file will be found, try using an absolute path." .format(providedPath)) sys.exit()
def __init__(self): # Read gravity coefficients from table # Columns are: Degree Order C S (Where C and S are the coefficients) coeffPath = getAbsoluteFilePath( './MAPLEAF/ENV/sphericalHarmonicGravityCoeffs.txt') gravityCoeffs = np.loadtxt(coeffPath, skiprows=2) # Convert that table into nested dictionary form, to make C and S coefficients easily accessible by degree and order Ccoeffs = {} Scoeffs = {} for row in gravityCoeffs: degree, order, C, S, = row if degree not in Ccoeffs: # Create subdictionary for each degree if this is the first time we're encountering that degree Ccoeffs[degree] = {} Scoeffs[degree] = {} # Save coefficient from this row Ccoeffs[degree][order] = C Scoeffs[degree][order] = S # Save results # Now C_{2,3} is accessible as self.C[2][3], same for self.S self.C = Ccoeffs self.S = Scoeffs
def plot_Earth_Mayavi( earthTexture='MAPLEAF/IO/blue_marble_spherical_splitFlipped.jpg'): from mayavi import mlab from tvtk.api import tvtk # python wrappers for the C++ vtk ecosystem # create a figure window (and scene) fig = mlab.figure(size=(600, 600)) # load and map the texture img = tvtk.JPEGReader() img.file_name = getAbsoluteFilePath(earthTexture) texture = tvtk.Texture(input_connection=img.output_port, interpolate=1) # (interpolate for a less raster appearance when zoomed in) # use a TexturedSphereSource, a.k.a. getting our hands dirty R = 6371007.1809 Nrad = 180 # create the sphere source with a given radius and angular resolution sphere = tvtk.TexturedSphereSource(radius=R, theta_resolution=Nrad, phi_resolution=Nrad) # assemble rest of the pipeline, assign texture sphere_mapper = tvtk.PolyDataMapper(input_connection=sphere.output_port) sphere_actor = tvtk.Actor(mapper=sphere_mapper, texture=texture) fig.scene.add_actor(sphere_actor)
def _getAveragedWindRose(self, Months=["May"], MonthWeights=[1.0], locations=["MedecineHat"], locationWeights=[1.0]): windRose = self._readWindRose( getAbsoluteFilePath( "MAPLEAF/Examples/Wind/WindroseAprMedecineHat.txt") ) * 0.0 # Initialize as zero for i in range(len(Months)): for a in range(len(locations)): windRoseFilePath = "MAPLEAF/Examples/Wind/Windrose{}{}.txt".format( Months[i], locations[a]) windRoseFilePath = getAbsoluteFilePath(windRoseFilePath) windRose += self._readWindRose( windRoseFilePath) * MonthWeights[i] * locationWeights[a] return windRose.copy()
def atmosphericModelFactory(envDictReader=None) -> AtmosphericModel: ''' Provide either an atmosphericModel name ('USStandardAtmosphere' is only option right now that doesn't require additional info, or provide an envDictReader (`MAPLEAF.IO.SubDictReader`) ''' if envDictReader == None: modelType = defaultConfigValues["Environment.AtmosphericPropertiesModel"] else: modelType = envDictReader.getString("AtmosphericPropertiesModel") if modelType == "Constant": if envDictReader == None: raise ValueError("envDictReader required to initialize Constant atm properties model") # Get values from ConstantAtmosphere subDictionary envDictReader.simDefDictPathToReadFrom = "Environment.ConstantAtmosphere" constTemp = envDictReader.getFloat("temp") + 273.15 # Convert to Kelvin (Expecting Celsius input) constPressure = envDictReader.getFloat("pressure") constDensity = envDictReader.getFloat("density") constViscosity = envDictReader.getFloat("viscosity") # Return to reading from Environment for any subsequent parsing envDictReader.simDefDictPathToReadFrom = "Environment" return ConstantAtmosphere(constTemp, constPressure, constDensity, constViscosity) elif modelType == "TabulatedAtmosphere": try: tableFilePath = envDictReader.getString("TabulatedAtmosphere.filePath") except AttributeError: tableFilePath = defaultConfigValues["Environment.TabulatedAtmosphere.filePath"] tableFilePath = getAbsoluteFilePath(tableFilePath) return TabulatedAtmosphere(tableFilePath) elif modelType == "USStandardAtmosphere": return USStandardAtmosphere() else: raise ValueError("Atmospheric model: {} not implemented, try using 'USStandardAtmosphere'".format(modelType))
def getRadioSondeWindProfile(self, locations=["Edmonton", "Glasgow"], locationWeights=[0.48, 0.52], locationASLAltitudes=[710, 638], launchMonth=None, randomSeed=None): ''' Arguments: locations: list of location names. Names must match those in radio sonde data file names (ex. "Edmonton" -> "RadioSondeEdmonton_filtered.txt") locationWeights: list of numeric values, must add to one. Order should match list of locations. locationASLAltitudes: list of ASL altitudes (m). Order should match list of locations. launchMonth: 3-letter string ("Jan", "Feb", "Mar", etc...) indicating month from which data is desired. Otherwise "Yearly" or None to select randomly from all months randomSeed: Pass in the same random seed to pick the same radio sonde profile Returns: altitudes: List of numeric altitudes (meters AGL) windVectors: Corresponding list of wind vectors (m/s) ''' # Set random seed if provided random.seed(randomSeed) # Pick a location selectedLocation = random.choices(locations, locationWeights, k=1)[0] locationASLAltitude = locationASLAltitudes[locations.index( selectedLocation)] # Load radiosonde data for that location radioSondeFilePath = "MAPLEAF/Examples/Wind/RadioSonde{}_filtered.txt".format( selectedLocation) # Convert to absolute file path radioSondeFilePath = getAbsoluteFilePath(radioSondeFilePath) # Read datasets from fille if launchMonth != "Yearly": datasetStartLines, data = self._readRadioSondeDataFile( radioSondeFilePath, filterByMonth=launchMonth) else: datasetStartLines, data = self._readRadioSondeDataFile( radioSondeFilePath) # Pick one of it's datasets selectedDataset = random.randint(0, len(datasetStartLines) - 1) # selectedDataset is an array of strings, header is a string # Example header: #CAM00071119 2000 01 01 12 1117 75 ncdc-gts ncdc-gts 535475 -1141083 header, radioSondeData = self._extractRadioSondeDataSet( datasetStartLines, data, selectedDataset) stationID, year, month, day, hour = self._parseRadioSondeHeader(header) if not self.silent: if self.monteCarloDataLogger != None: self.monteCarloDataLogger.log( "Wind data from radio sonde dataset: {}, stationID: {}, {}, {}, {}, {}" .format(selectedLocation, stationID, year, month, day, hour)) else: print( "Wind data from radio sonde dataset: {}, stationID: {}, {}, {}, {}, {}" .format(selectedLocation, stationID, year, month, day, hour)) # Turn data from strings into a numpy array altitudes, windVectors = self._parseRadioSondeData( radioSondeData, locationASLAltitude) return altitudes, windVectors