From 3c02d7b3203b49cafcb86b29c6fde759c8d06e8d Mon Sep 17 00:00:00 2001 From: Brad Schrag Date: Fri, 5 Oct 2018 12:19:32 -0500 Subject: [PATCH 01/43] updated vs number and created dev branch --- pyradUtilities.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyradUtilities.py b/pyradUtilities.py index 25b0ffe..267ebc3 100644 --- a/pyradUtilities.py +++ b/pyradUtilities.py @@ -394,7 +394,7 @@ def displayAllMolecules(): 'regularCyan': '\x1b[0;36;48m', 'colorEnd': '\x1b[0m'} -VERSION = '1.71' +VERSION = '2.0' titleLine = "%s*********************** PyRad v%s ***********************%s" \ % (TEXT_COLORS['underlineCyan'], VERSION, TEXT_COLORS['colorEnd']) messageGap = int((len(titleLine) - len(VERSION) - 1) / 2) From 023b7344bc7c2f8d4c383849e9c155ec167bd678 Mon Sep 17 00:00:00 2001 From: Brad Schrag Date: Fri, 12 Oct 2018 14:04:17 -0500 Subject: [PATCH 02/43] getting close to planet transmission --- .idea/dictionaries/brad.xml | 11 + .idea/inspectionProfiles/Project_Default.xml | 15 + data/901/params.pyr | 4 + earthtransmission.py | 87 ++++ main.py | 10 +- pyrad.py | 414 +++++++++++++++++-- pyradUtilities.py | 1 + 7 files changed, 504 insertions(+), 38 deletions(-) create mode 100644 .idea/dictionaries/brad.xml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 data/901/params.pyr create mode 100644 earthtransmission.py diff --git a/.idea/dictionaries/brad.xml b/.idea/dictionaries/brad.xml new file mode 100644 index 0000000..1c180f3 --- /dev/null +++ b/.idea/dictionaries/brad.xml @@ -0,0 +1,11 @@ + + + + absorbance + coef + linewidth + wavenumber + xkcd + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..3b58b6c --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,15 @@ + + + + \ No newline at end of file diff --git a/data/901/params.pyr b/data/901/params.pyr new file mode 100644 index 0000000..f53890c --- /dev/null +++ b/data/901/params.pyr @@ -0,0 +1,4 @@ +# # # +# Molecule params for pyrad +# # # +129,h2o,1,262,2.4197e-08,1027.8,1,20.022915 diff --git a/earthtransmission.py b/earthtransmission.py new file mode 100644 index 0000000..eca6c1a --- /dev/null +++ b/earthtransmission.py @@ -0,0 +1,87 @@ +import pyrad +import numpy as np + + +initialThickness = 100 * 100 +tropopause = 11000 * 100 +strat1 = 20000 * 100 +strat2 = 32000 * 100 +stratopause = 47000 * 100 +meso1 = 51000 * 100 +meso2 = 71000 * 100 +mesopause = 80000 * 100 +top = 90000 * 100 +profileName = 'earth123' + + +earth = pyrad.Planet(profileName, 1013.25, 300, rangeMin=500, rangeMax=900, initialThickness=initialThickness) + +earth.addLapseRate('troposphere dry LR', 0, earth.surfaceTemperature, tropopause, 216, earth.surfacePressure) +earth.addLapseRate('tropopause', tropopause, earth.temperatureAtHeight(tropopause), strat1, 216, earth.pressureAtHeight(tropopause)) +earth.addLapseRate('stratosphere1', strat1, earth.temperatureAtHeight(strat1), strat2, 228, earth.pressureAtHeight(strat1)) +earth.addLapseRate('stratosphere2', strat2, earth.temperatureAtHeight(strat2), stratopause, 270, earth.pressureAtHeight(strat2)) +earth.addLapseRate('stratopause', stratopause, earth.temperatureAtHeight(stratopause), meso1, 270, earth.pressureAtHeight(stratopause)) +earth.addLapseRate('mesosphere1', meso1, earth.temperatureAtHeight(meso1), meso2, 214, earth.pressureAtHeight(meso1)) +earth.addLapseRate('mesosphere2', meso2, earth.temperatureAtHeight(meso2), mesopause, 190, earth.pressureAtHeight(meso2)) +earth.addLapseRate('mesopause', mesopause, earth.temperatureAtHeight(mesopause), top, 190, earth.pressureAtHeight(mesopause)) + +co2 = earth.addMolecule('co2', ppm=350) +h2o = earth.addMolecule('h2o', ppm=20000) +n2 = earth.addMolecule('n2', percentage=76.9) +o2 = earth.addMolecule('o2', percentage=19.9) +#o3 = earth.addMolecule('o3', ppb=0) +# ar = earth.addMolecule('ar', percentage=.9) + +# earth.addCompositionRate('co2 troposphere', 0, co2.concentration, 11000, -.000000001, co2) +# earth.addCompositionRate('co2 stratosphere and up', 0, earth.compositionAtHeight(11000, co2), 90000, 0, co2) + +wvCP1 = 2500 * 100 +wvCP2 = 8000 * 100 +wvCP3 = 9000 * 100 +wvCP4 = 10000 * 100 +wvCP5 = 20000 * 100 + +earth.addCompositionRate('WV boundary layer', 0, h2o.concentration, wvCP1, 10000e-6, h2o) +earth.addCompositionRate('WV troposphere1', wvCP1, earth.compositionAtHeight(wvCP1, h2o), wvCP2, 200e-6, h2o) +earth.addCompositionRate('WV troposphere2', wvCP2, earth.compositionAtHeight(wvCP2, h2o), wvCP3, 400e-6, h2o) +earth.addCompositionRate('WV troposphere2', wvCP3, earth.compositionAtHeight(wvCP3, h2o), wvCP4, 400e-6, h2o) +earth.addCompositionRate('WV tropopause', wvCP4, earth.compositionAtHeight(wvCP4, h2o), wvCP5, 2e-6, h2o) +earth.addCompositionRate('WV stratosphere and up', wvCP5, earth.compositionAtHeight(wvCP5, h2o), top, 0, h2o) + +# ozone rules +ozCP0 = 3000 * 100 +ozCP1 = 16000 * 100 +ozCP2 = 32000 * 100 +ozCP3 = 60000 * 100 +#earth.addCompositionRate('troposphere ozone', ozCP0, 30E-9, ozCP1, 60E-9, o3) +#earth.addCompositionRate('tropopause ozone', ozCP1, earth.compositionAtHeight(ozCP1, o3), ozCP2, 5E-6, o3) +#earth.addCompositionRate('upper strat ozone', ozCP2, earth.compositionAtHeight(ozCP2, o3), ozCP3, 0, o3) +#earth.addCompositionRate('strat on up ozone', ozCP3, earth.compositionAtHeight(ozCP3, o3), top, 0, o3) + +yAxis = np.arange(1, 90000, 1) +xAxis = [] +earth.sliceAtm() + + + +#plt.plot(xAxis, yAxis) +#plt.show() + + + + +""" +height = 0 +nextLayerThickness = initialThickness +initalMass = earth.densityAtHeight(height) * initialThickness / 100 +while height < 11000: + previousLayer = earth.atmosphere[-1] + newHeight = previousLayer.height + previousLayer.depth + newTemp = earth.temperatureAtHeight(newHeight) + newDensity = earth.densityAtHeight(newHeight) + newPressure = earth.pressureAtHeight(newHeight) + newDepth = initalMass / newDensity + earth.atmosphere.addLayer(nextLayerThickness, earth.temperatureAtHeight(height)) + + +""" diff --git a/main.py b/main.py index 363c651..d9fff66 100644 --- a/main.py +++ b/main.py @@ -35,14 +35,14 @@ co2 = layer1.addMolecule(2, percentage=10, isotopeDepth=1) -#layer2 = pyrad.Layer(1000, 300, 1013.25, 500, 800, name='h2o: 1%') -#h2o = layer2.addMolecule('h2o', percentage=1) +# layer2 = pyrad.Layer(1000, 300, 1013.25, 500, 800, name='h2o: 1%') +# h2o = layer2.addMolecule('h2o', percentage=1) layer3 = pyrad.Layer(1000, 300, 1013.25, 500, 700, name='layer3') -#n2o = layer1.addMolecule('n2o', ppb=350) +# n2o = layer1.addMolecule('n2o', ppb=350) -#pyrad.plot('optical depth', layer3.title, [layer1, co2, n2o]) -pyrad.plotSpectrum(layer=layer1, spectrumList=[layer1.transmission(320)], planckTemperatureList=[280, 320]) +# pyrad.plot('optical depth', layer3.title, [layer1, co2, n2o]) +pyrad.plotSpectrum(layer=layer1, objList=[layer1], planckTemperatureList=[280, 320]) """ MOLECULE_ID = {'h2o': 1, 'co2': 2, 'o3': 3, 'n2o': 4, 'co': 5, diff --git a/pyrad.py b/pyrad.py index 5a7cf0e..8054ac3 100644 --- a/pyrad.py +++ b/pyrad.py @@ -5,20 +5,71 @@ import pyradPlanck import numpy as np import matplotlib.pyplot as plt -import pyradInteractive +# import pyradInteractive c = 299792458.0 k = 1.38064852E-23 -c = 299792458.0 h = 6.62607004e-34 pi = 3.141592653589793 +R = 8.3144598 t0 = 296 p0 = 1013.25 -t0 = 296 avo = 6.022140857E23 +def wvPressure(temperature, RH): + wvP = RH * wvSaturationVaporPressure(temperature) / 100 + return wvP + + +def wvRH2AH(temperature, pressure, RH): + wvP = wvPressure(temperature, RH) + + absHum = wvP / 461.5 * temperature + print(wvP, absHum) + return absHum + + +def wvMixingRatio(temperature, pressure, RH): + e = wvPressure(temperature, RH) + r = .622 * e / (pressure - e) + return r + + +def smooth(y, box_pts): + box = np.ones(box_pts)/box_pts + y_smooth = np.convolve(y, box, mode='same') + return y_smooth + + +def wvSaturationVaporPressure(temperature): + temperature -= 273 + tC = 647.096 + pC = 220640 + a1 = -7.85951783 + a2 = 1.84408259 + a3 = -11.7866497 + a4 = 22.6807411 + a5 = -15.9618719 + a6 = 1.80122502 + # v = 1 - temperature / tC + # satVP = pC * np.exp(tC / temperature * (a1 * v + a2 * v**1.5 + a3 * v**3 + a4 * v**3.5 + a5 * v**4 + a6 * v**7.5)) + satVP = 6.11 * np.exp(17.3 * temperature / (temperature + 237.3)) + return satVP + + +def wvConcentrationFromRH(layer, RH): + temperature = layer.T + pressure = layer.P + concentration = wvMixingRatio(temperature, pressure, RH) + return concentration + +def linear(baseValue, baseHeight, rate, height): + newValue = baseValue + rate * (height - baseHeight) + return newValue + + def integrateSpectrum(spectrum, unitAngle=pi, res=utils.BASE_RESOLUTION): value = np.sum(np.nan_to_num(spectrum)) value = value * unitAngle * res @@ -32,6 +83,8 @@ def getCrossSection(obj): def resetCrossSection(obj): + if not obj.progressCrossSection: + return obj.crossSection = np.zeros(int((obj.rangeMax - obj.rangeMin) / utils.BASE_RESOLUTION)) obj.progressCrossSection = False for child in obj: @@ -264,16 +317,19 @@ def yAxis(self): def xAxis(self): return np.copy(self.layer.xAxis) - def getData(self): - print('Getting data for %s, isotope %s' % (self.molecule.name, self.globalIsoNumber)) + def getData(self, lineSurvey=False, verbose=True): + if verbose: + print('Getting data for %s, %s, isotope %s' % (self.layer.name, self.molecule.name, self.globalIsoNumber), end='\r', flush=True) lineDict = utils.gatherData(self.globalIsoNumber, self.layer.effectiveRangeMin, self.layer.effectiveRangeMax) self.q = utils.getQData(self.globalIsoNumber) for line in lineDict: - self.append(Line(line, lineDict[line]['intensity'], lineDict[line]['einsteinA'], + # need to soft code the intensity value, depending on resolution setting + if lineDict[line]['intensity'] > 1E-22: + self.append(Line(line, lineDict[line]['intensity'], lineDict[line]['einsteinA'], lineDict[line]['airHalfWidth'], lineDict[line]['selfHalfWidth'], lineDict[line]['lowerEnergy'], lineDict[line]['tempExponent'], lineDict[line]['pressureShift'], self)) - self.createLineSurvey() + # self.createLineSurvey() def createCrossSection(self): molecule = self.molecule @@ -285,9 +341,12 @@ def createCrossSection(self): trackGauss = 0 trackLorentz = 0 trackVoigt = 0 + if len(self) == 0: + self.progressCrossSection = True + return for line in self: if progress > i * alertInterval: - print('Progress for %s <%s%s>' % (molecule.name, '*' * i, '-' * (20 - i)), end='\r') + print('Progress for %s: %s, temperature: %s, pressure: %s <%s%s>' % (layer.name, molecule.name, layer.T, layer.P, '*' * i, '-' * (20 - i)), end='\r') os.sys.stdout.flush() i += 1 progress += 1 @@ -358,6 +417,9 @@ def transmission(self, surfaceSpectrum): emitted = self.emittance * self.planck(self.T) return transmitted + emitted + def returnCopy(self): + return self.linelist() + class Molecule(list): def __init__(self, shortNameOrMolNum, layer, isotopeDepth=1, **abundance): @@ -402,7 +464,7 @@ def returnCopy(self): valueUnit = self.concText.split() tempDict = {valueUnit[1]: float(valueUnit[0])} newMolecule = Molecule(self.name, self.layer, isotopeDepth=int(self.isotopeDepth), **tempDict) - newMolecule.getData() + newMolecule.getData(verbose=False) return newMolecule def setPercentage(self, percentage): @@ -424,9 +486,9 @@ def setConcentration(self, concentration): self.setPPM(concentration * 1E6) resetCrossSection(self) - def getData(self): + def getData(self, verbose=True): for isotope in self: - isotope.getData() + isotope.getData(verbose) def createCrossSection(self): tempAxis = np.zeros(int((self.rangeMax - self.rangeMin) / utils.BASE_RESOLUTION)) @@ -506,11 +568,15 @@ def resolution(self): def distanceFromCenter(self): return self.layer.distanceFromCenter + @property + def molarMass(self): + return self[0].molmass + class Layer(list): hasAtmosphere = False - def __init__(self, depth, T, P, rangeMin, rangeMax, atmosphere=None, name='', dynamicResolution=True): + def __init__(self, depth, T, P, rangeMin, rangeMax, height=0.0, atmosphere=None, name='', dynamicResolution=True): super(Layer, self).__init__(self) self.rangeMin = rangeMin self.rangeMax = rangeMax @@ -521,6 +587,8 @@ def __init__(self, depth, T, P, rangeMin, rangeMax, atmosphere=None, name='', dy self.effectiveRangeMin = max(self.rangeMin - self.distanceFromCenter, 0) self.effectiveRangeMax = self.rangeMax + self.distanceFromCenter self.dynamicResolution = dynamicResolution + self.surfaceSpectrum = None + self.height = height if not dynamicResolution: self.resolution = utils.BASE_RESOLUTION else: @@ -537,7 +605,8 @@ def __init__(self, depth, T, P, rangeMin, rangeMax, atmosphere=None, name='', dy self.crossSection = np.zeros(int((rangeMax - rangeMin) / utils.BASE_RESOLUTION)) self.progressCrossSection = False if not name: - name = 'layer %s' % self.atmosphere.nextLayerName() + name = '%s' % self.atmosphere.nextLayerName() + self.atmosphere.append(self) self.name = name def __str__(self): @@ -553,6 +622,16 @@ def createCrossSection(self): self.progressCrossSection = True self.crossSection = tempAxis + def returnMolecule(self, name): + for m in self: + if m.name == name: + return m + return False + + @property + def meanHeight(self): + return self.height + .5 * self.depth + @property def lineSurvey(self): tempAxis = np.zeros(int((self.rangeMax - self.rangeMin) / utils.BASE_RESOLUTION)) @@ -596,6 +675,37 @@ def emissivity(self): def emittance(self): return self.emissivity + @property + def molarMass(self): + mass = 0 + for mol in self: + mass += mol.molarMass * mol.concentration + return mass + + @property + def density(self): + return self.P * 100 / self.T / self.specGasConstant + + @property + def mass(self): + return self.density * self.depth / 100 + + @property + def specGasConstant(self): + return R * 1000 / self.molarMass + + @property + def temperatureAtHeight(self): + return int(self.atmosphere.temperatureAtHeight(self.meanHeight)) + + @property + def pressureAtHeight(self): + return self.atmosphere.pressureAtHeight(self.meanHeight) + + @property + def densityAtHeight(self): + return self.atmosphere.densityAtHeight(self.temperatureAtHeight, self.specGasConstant) + def changeRange(self, rangeMin, rangeMax): self.rangeMin = rangeMin self.rangeMax = rangeMax @@ -627,12 +737,14 @@ def addMolecule(self, name, isotopeDepth=1, **abundance): molecule.getData() return molecule - def returnCopy(self): - newCopy = Layer(self.depth, self.T, self.P, self.rangeMin, self.rangeMax, - self.atmosphere, name=self.atmosphere.nextLayerName(), dynamicResolution=self.dynamicResolution) + def returnCopy(self, name=None): + if not name: + name = self.atmosphere.nextLayerName() + newCopy = Layer(self.depth, self.T, self.P, self.rangeMin, self.rangeMax, height=self.height, + atmosphere=self.atmosphere, name=name, dynamicResolution=self.dynamicResolution) for molecule in self: - newMolecule = molecule.returnCopy() - newCopy.append(newMolecule) + newCopy.addMolecule(molecule.name, molecule.isotopeDepth, concentration=molecule.concentration) + print('%s copied to %s' % (self.name, newCopy.name)) return newCopy def returnMoleculeObjects(self): @@ -651,9 +763,12 @@ def transmission(self, surfaceSpectrum): class Atmosphere(list): - def __init__(self, name): + def __init__(self, name, rangeMin=0, rangeMax=0, planet=None): super().__init__(self) self.name = name + self.rangeMin = rangeMin + self.rangeMax = rangeMax + self.planet = planet def __str__(self): return self.name @@ -661,11 +776,11 @@ def __str__(self): def __bool__(self): return True - def addLayer(self, depth, T, P, rangeMin, rangeMax, name=None, dynamicResolution=True): + def addLayer(self, depth, T, P, rangeMin, rangeMax, name=None, dynamicResolution=True, height=0.0): if not name: name = self.nextLayerName() - newLayer = Layer(depth, T, P, rangeMin, rangeMax, atmosphere=self, name=name, dynamicResolution=dynamicResolution) - self.append(newLayer) + newLayer = Layer(depth, T, P, rangeMin, rangeMax, atmosphere=self, name=name, + dynamicResolution=dynamicResolution, height=height) return newLayer def nextLayerName(self): @@ -678,11 +793,241 @@ def returnLayerNames(self): return tempList def returnLayerObjects(self): + if len(self) == 0: + return False tempList = [] for layer in self: tempList.append(layer) return tempList + def temperatureAtHeight(self, height): + ruleList = self.planet.returnApplicableRules(height, 'temperature') + if len(ruleList) > 1: + print('Multiple rules found for height %s: %s' % (height, ruleList)) + rule = ruleList[0] + temperature = rule.rateFunction(rule.baseValue, rule.baseHeight, rule.rate, height) + return temperature + + def pressureAtHeight(self, height): + height = height / 100 + ruleList = self.planet.returnApplicableRules(height, 'temperature') + if len(ruleList) > 1: + print('Multiple rules found for height %s: %s' % (height, ruleList)) + rule = ruleList[0] + temperature = self.temperatureAtHeight(height) + if rule.rate != 0: + pressure = rule.basePressure * (rule.baseValue / temperature) ** \ + (self.planet.gravity * self.planet.molarMass / R / rule.rate) + else: + pressure = rule.basePressure * \ + np.exp(-self.planet.gravity * self.planet.molarMass * + (height - rule.baseHeight) / R / rule.baseValue) + return pressure + + def compositionAtHeight(self, height, molecule): + ruleList = self.planet.returnApplicableRules(height, 'composition') + if not ruleList: + return molecule.concentration + for rule in ruleList: + if rule.molecule.name == molecule.name: + concentration = rule.rateFunction(rule.baseValue, rule.baseHeight, rule.rate, height) + return concentration + return molecule.concentration + + def densityAtHeight(self, height, gasConstant): + temperature = self.temperatureAtHeight(height) + pressure = self.pressureAtHeight(height) + density = pressure * 100 / gasConstant / temperature + return density + + +class Planet: + def __init__(self, name, pressure, temperature, molarMass=0.0289644, + gravity=9.80665, rangeMin=0, rangeMax=2000, initialThickness=100): + self.name = name + self.mass = 0 + self.gravity = gravity + self.molarMass = molarMass + self.radius = 0 + self.surfacePressure = pressure + self.surfaceTemperature = temperature + self.atmosphereRules = [] + self.rangeMin = rangeMin + self.rangeMax = rangeMax + self.atmosphere = Atmosphere("%s's atmosphere" % self.name, planet=self) + self.initialLayer = \ + self.atmosphere.addLayer(initialThickness, temperature, pressure, rangeMin, rangeMax, height=0) + + def setMass(self, mass): + self.mass = mass + + def addLapseRate(self, name, baseHeight, baseTemperature, finalHeight, finalValue, basePressure, rateFunction=linear): + self.atmosphereRules.append(AtmosphereRule( + name, baseHeight, baseTemperature, finalHeight, finalValue, 'temperature', + basePressure, rateFunction=rateFunction)) + + def addCompositionRate(self, name, baseHeight, baseValue, finalHeight, rate, molecule, rateFunction=linear): + self.atmosphereRules.append(AtmosphereRule( + name, baseHeight, baseValue, finalHeight, rate, ruleType='composition', + molecule=molecule, rateFunction=rateFunction)) + + def setRadius(self, radius): + self.radius = radius + + def setGravity(self, gravity): + self.gravity = gravity + + def setSurfacePressure(self, pressure): + self.surfacePressure = pressure + + def setSurfaceTemperature(self, temperature): + self.surfaceTemperature = temperature + + def setSurfaceComposition(self): + pass + + def returnApplicableRules(self, height, ruleType): + ruleList = [] + for rule in self.atmosphereRules: + if rule.isInRange(height, ruleType): + ruleList.append(rule) + if not ruleList: + return False + return ruleList + + def temperatureAtHeight(self, height): + return self.atmosphere.temperatureAtHeight(height) + + def pressureAtHeight(self, height): + return self.atmosphere.pressureAtHeight(height) + + def densityAtHeight(self, height): + return self.atmosphere.densityAtHeight(height) + + def compositionAtHeight(self, height, molecule): + return self.atmosphere.compositionAtHeight(height, molecule) + + def addMolecule(self, name, isotopeDepth=1, **abundance): + molecule = self.initialLayer.addMolecule(name, isotopeDepth, **abundance) + return molecule + + def sliceAtm(self): + acceptSetup = False + height = 0 + while not acceptSetup: + mass = self.initialLayer.mass + layer = self.initialLayer.returnCopy(name='temp layer') + print('p %s, T %s, depth %s, height %s' % (layer.P, layer.T, layer.depth, layer.height)) + heightList = [height] + tempList = [layer.T] + pressureList = [layer.P] + depthList = [layer.depth] + changePoints = self.atmChangePoints + while layer.height + layer.depth < 9000000: + print('temp: %s, press: %s, baseHeight: %skm, meanHeight: %s, depth: %s, tarMass: %s, layMass: %s' % ( + int(layer.T), layer.P, layer.height / 100000, layer.meanHeight, layer.depth, mass, layer.mass)) + newHeight = heightList[-1] + depthList[-1] + heightList.append(newHeight) + tempList.append(self.temperatureAtHeight(newHeight)) + pressureList.append(self.pressureAtHeight(newHeight)) + layer.P = pressureList[-1] + layer.T = tempList[-1] + layer.height = heightList[-1] + layer.depth = (mass / layer.density * 100) + '''if layer.height + layer.depth > changePoints[0]: + tempHeight = changePoints.pop(0) + layer.depth = tempHeight - layer.height + while changePoints: + if changePoints[0] == tempHeight: + changePoints.pop(0) + else: + break''' + if layer.depth != 0: + depthList.append(layer.depth) + print('Total # of layers: %s' % len(heightList)) + isValid = False + while not isValid: + self.atmosphere.pop() + userInput = input('Accept the current slicing (y/n): ') + if userInput.lower()[0] == 'n': + isValid = True + validNumber = False + while not validNumber: + print('Enter the new initial depth. Larger depth will decrease number of layers, smaller will increase') + userNumber = input('Current depth is %scm:' % utils.limeText(self.initialLayer.depth)) + try: + newDepth = float(userNumber) + self.initialLayer.depth = newDepth + validNumber = True + except ValueError: + print('Invalid number.') + elif userInput.lower()[0] == 'y': + isValid = True + acceptSetup = True + # print(len(self.atmosphere), self.atmosphere[0].name) + heightList.pop(0) + depthList.pop(0) + for i in range(0, len(heightList) - 1): + height = heightList[i] + depth = depthList[i] + newLayer = self.initialLayer.returnCopy() + newLayer.height = height + newLayer.depth = depth + newLayer.T = int(self.temperatureAtHeight(newLayer.meanHeight)) + newLayer.P = self.pressureAtHeight(newLayer.meanHeight) + for molecule in newLayer: + molecule.concentration = self.compositionAtHeight(newLayer.meanHeight, molecule) + surfaceSpectrum = pyradPlanck.planckWavenumber(self.initialLayer.xAxis, self.surfaceTemperature) + + for layer in self.atmosphere: + layer.createCrossSection() + transmission = layer.transmission(surfaceSpectrum) + surfaceSpectrum = transmission + plt.plot(self.initialLayer.xAxis, smooth(surfaceSpectrum, 100), linewidth=.5) + plt.plot(self.initialLayer.xAxis, pyradPlanck.planckWavenumber(self.initialLayer.xAxis, self.surfaceTemperature), linewidth=.5) + plt.plot(self.initialLayer.xAxis, + pyradPlanck.planckWavenumber(self.initialLayer.xAxis, 280), linewidth=.5) + plt.plot(self.initialLayer.xAxis, + pyradPlanck.planckWavenumber(self.initialLayer.xAxis, 260), linewidth=.5) + plt.plot(self.initialLayer.xAxis, + pyradPlanck.planckWavenumber(self.initialLayer.xAxis, 240), linewidth=.5) + plt.show() + + @property + def yAxis(self): + return np.zeros(int((self.rangeMax - self.rangeMin) / utils.BASE_RESOLUTION)) + + @property + def xAxis(self): + return np.linspace(self.rangeMin, self.rangeMax, (self.rangeMax - self.rangeMin) / utils.BASE_RESOLUTION, + endpoint=True) + + @property + def atmChangePoints(self): + changePointList = [] + for rule in self.atmosphereRules: + changePointList.append(rule.finalHeight) + return sorted(changePointList) + + +class AtmosphereRule: + def __init__(self, name, baseHeight, baseValue, finalHeight, finalValue, ruleType, basePressure=0, + molecule=None, rateFunction=linear): + self.name = name + self.baseHeight = baseHeight + self.baseValue = baseValue + self.finalHeight = finalHeight + self.finalValue = finalValue + if rateFunction == linear: + self.rate = (self.finalValue - self.baseValue) / (self.finalHeight - self.baseHeight) + self.ruleType = ruleType + self.molecule = molecule + self.basePressure = basePressure + self.rateFunction = rateFunction + + def isInRange(self, height, ruleType): + return self.baseHeight < height <= self.finalHeight and self.ruleType == ruleType + def returnPlot(obj, propertyToPlot): if propertyToPlot == "transmittance": @@ -722,10 +1067,11 @@ def plot(propertyToPlot, title, plotList, fill=False): plt.title('%s' % title) handles = [] linewidth = 1.2 - alpha =.7 + alpha = .7 for singlePlot, color in zip(plotList, COLOR_LIST): yAxis, fillAxis = returnPlot(singlePlot, propertyToPlot) - fig, = plt.plot(singlePlot.xAxis, yAxis, linewidth=linewidth, alpha=alpha, color=color, label='%s' % singlePlot.name) + fig, = plt.plot(singlePlot.xAxis, smooth(yAxis, 50), linewidth=linewidth, alpha=alpha, color=color, + label='%s' % singlePlot.name) handles.append(fig) plt.fill_between(singlePlot.xAxis, fillAxis, yAxis, color=color, alpha=.3 * fill) linewidth = .7 @@ -737,7 +1083,7 @@ def plot(propertyToPlot, title, plotList, fill=False): def plotSpectrum(layer=None, title=None, rangeMin=None, rangeMax=None, objList=None, surfaceSpectrum=None, - planckTemperatureList=None, planckType='wavenumber', fill=False): + planckTemperatureList=None, planckType='wavenumber'): plt.figure(figsize=(10, 6), dpi=80) plt.subplot(111, facecolor='xkcd:dark grey') plt.margins(0.01) @@ -756,7 +1102,7 @@ def plotSpectrum(layer=None, title=None, rangeMin=None, rangeMax=None, objList=N plt.ylabel('Radiance Wm-2sr-1Hz-1') planckFunction = pyradPlanck.planckHz xAxis = np.linspace(rangeMin, rangeMax, 1000) - elif planckType == 'wavelength': + else: plt.xlabel('wavelength um') plt.ylabel('Radiance Wm-2sr-1um-1') planckFunction = pyradPlanck.planckWavelength @@ -774,7 +1120,8 @@ def plotSpectrum(layer=None, title=None, rangeMin=None, rangeMax=None, objList=N for temperature in planckTemperatureList: yAxis = planckFunction(xAxis, float(temperature)) fig, = plt.plot(xAxis, yAxis, linewidth=.75, color=(red, green, blue), - linestyle=':', label='%sK : %sWm-2' % (temperature, round(integrateSpectrum(yAxis, res=(rangeMax - rangeMin) / len(yAxis)), 2))) + linestyle=':', label='%sK : %sWm-2' % + (temperature, round(integrateSpectrum(yAxis, res=(rangeMax - rangeMin) / len(yAxis)), 2))) handles.append(fig) if red + dr < 0 or red + dr > 1: dr *= -1 @@ -793,11 +1140,11 @@ def plotSpectrum(layer=None, title=None, rangeMin=None, rangeMax=None, objList=N if objList: alpha = .7 linewidth = 1.2 - surfacePower = integrateSpectrum(surfaceSpectrum, pi) for obj, color in zip(objList, COLOR_LIST): yAxis = obj.transmission(surfaceSpectrum) - fig, = plt.plot(layer.xAxis, yAxis, linewidth=linewidth, alpha=alpha, color=color, label='%s : %sWm-2' - % (obj.name, round(integrateSpectrum(yAxis, pi), 2))) + fig, = plt.plot(layer.xAxis, yAxis, linewidth=linewidth, + alpha=alpha, color=color, + label='%s : %sWm-2' % (obj.name, round(integrateSpectrum(yAxis, pi), 2))) handles.append(fig) alpha = .5 linewidth = 1 @@ -859,7 +1206,8 @@ def cacheCurves(): 46: {1: 97, 2: 98, 3: 99, 4: 100}, 47: {1: 114}, 48: {1: 123}, - 49: {1: 124, 2: 125}} + 49: {1: 124, 2: 125}, + 901: {1: 901}} COLOR_LIST = ['xkcd:white', 'xkcd:bright orange', @@ -882,8 +1230,8 @@ def cacheCurves(): 'o': 34, 'clono2': 35, 'no+': 36, 'hobr': 37, 'c2h4': 38, 'ch3oh': 39, 'ch3br': 40, 'ch3cn': 41, 'cf4': 42, 'c4h2': 43, 'hc3n': 44, 'h2': 45, - 'cs': 46, 'so3': 47, 'c2n2': 48, 'cocl2': 49} - + 'cs': 46, 'so3': 47, 'c2n2': 48, 'cocl2': 49, + 'ar': 901} if __name__ == 'main': diff --git a/pyradUtilities.py b/pyradUtilities.py index 267ebc3..3fad480 100644 --- a/pyradUtilities.py +++ b/pyradUtilities.py @@ -11,6 +11,7 @@ dataDir = '%s/data' % cwd curvesDir = '%s/curves' % dataDir molParamsFile = '%s/molparams.txt' % dataDir +profileDir = '/%s/profiles' % cwd debuggerFilePath = '%s/logger.txt' % cwd now = datetime.datetime.now() debuggerFile = open(debuggerFilePath, 'wb') From 2ad9a388c7eb0bcb72dac40652e6ab1c0dbb909b Mon Sep 17 00:00:00 2001 From: Brad Schrag Date: Sat, 13 Oct 2018 11:54:30 -0500 Subject: [PATCH 03/43] things are working well. Profile are created from scratch, or if existing loaded quickly. Next is to try a full spectrum processing, which has previously locked up the machine. Next function to implement will be the ability to continue where the app left off, in case it does crash. --- .idea/dictionaries/brad.xml | 11 -- .idea/inspectionProfiles/Project_Default.xml | 15 -- data/901/params.pyr | 4 - earth2.py | 61 ++++++ earthtransmission.py | 14 +- pyrad.py | 189 ++++++++++++------- pyradLineshape.py | 36 ++-- pyradUtilities.py | 82 +++++++- 8 files changed, 288 insertions(+), 124 deletions(-) delete mode 100644 .idea/dictionaries/brad.xml delete mode 100644 .idea/inspectionProfiles/Project_Default.xml delete mode 100644 data/901/params.pyr create mode 100644 earth2.py diff --git a/.idea/dictionaries/brad.xml b/.idea/dictionaries/brad.xml deleted file mode 100644 index 1c180f3..0000000 --- a/.idea/dictionaries/brad.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - absorbance - coef - linewidth - wavenumber - xkcd - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 3b58b6c..0000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - \ No newline at end of file diff --git a/data/901/params.pyr b/data/901/params.pyr deleted file mode 100644 index f53890c..0000000 --- a/data/901/params.pyr +++ /dev/null @@ -1,4 +0,0 @@ -# # # -# Molecule params for pyrad -# # # -129,h2o,1,262,2.4197e-08,1027.8,1,20.022915 diff --git a/earth2.py b/earth2.py new file mode 100644 index 0000000..00b9e60 --- /dev/null +++ b/earth2.py @@ -0,0 +1,61 @@ +import pyrad +import numpy as np + + +initialThickness = 100 * 100 +tropopause = 11000 * 100 +strat1 = 20000 * 100 +strat2 = 32000 * 100 +stratopause = 47000 * 100 +meso1 = 51000 * 100 +meso2 = 71000 * 100 +mesopause = 80000 * 100 +maxHeight = 90000 * 100 +profileName = 'earth345' + + +earth = pyrad.Planet(profileName, 1013.25, 300, maxHeight, rangeMin=00, rangeMax=2000, initialThickness=initialThickness) + +earth.addLapseRate('troposphere dry LR', 0, earth.surfaceTemperature, tropopause, 216, earth.surfacePressure) +earth.addLapseRate('tropopause', tropopause, earth.temperatureAtHeight(tropopause), strat1, 216, earth.pressureAtHeight(tropopause)) +earth.addLapseRate('stratosphere1', strat1, earth.temperatureAtHeight(strat1), strat2, 228, earth.pressureAtHeight(strat1)) +earth.addLapseRate('stratosphere2', strat2, earth.temperatureAtHeight(strat2), stratopause, 270, earth.pressureAtHeight(strat2)) +earth.addLapseRate('stratopause', stratopause, earth.temperatureAtHeight(stratopause), meso1, 270, earth.pressureAtHeight(stratopause)) +earth.addLapseRate('mesosphere1', meso1, earth.temperatureAtHeight(meso1), meso2, 214, earth.pressureAtHeight(meso1)) +earth.addLapseRate('mesosphere2', meso2, earth.temperatureAtHeight(meso2), mesopause, 190, earth.pressureAtHeight(meso2)) +earth.addLapseRate('mesopause', mesopause, earth.temperatureAtHeight(mesopause), maxHeight, 190, earth.pressureAtHeight(mesopause)) + +co2 = earth.addMolecule('co2', ppm=350) +h2o = earth.addMolecule('h2o', ppm=20000) +n2 = earth.addMolecule('n2', percentage=76.9) +o2 = earth.addMolecule('o2', percentage=19.9) +o3 = earth.addMoleculeo3('o3', ppb=0) +# ar = earth.addMolecule('ar', percentage=.9) + +# earth.addCompositionRate('co2 troposphere', 0, co2.concentration, 11000, -.000000001, co2) +# earth.addCompositionRate('co2 stratosphere and up', 0, earth.compositionAtHeight(11000, co2), 90000, 0, co2) + +wvCP1 = 2500 * 100 +wvCP2 = 8000 * 100 +wvCP3 = 9000 * 100 +wvCP4 = 10000 * 100 +wvCP5 = 20000 * 100 + +earth.addCompositionRate('WV boundary layer', 0, h2o.concentration, wvCP1, 10000e-6, h2o) +earth.addCompositionRate('WV troposphere1', wvCP1, earth.compositionAtHeight(wvCP1, h2o), wvCP2, 200e-6, h2o) +earth.addCompositionRate('WV troposphere2', wvCP2, earth.compositionAtHeight(wvCP2, h2o), wvCP3, 400e-6, h2o) +earth.addCompositionRate('WV troposphere2', wvCP3, earth.compositionAtHeight(wvCP3, h2o), wvCP4, 400e-6, h2o) +earth.addCompositionRate('WV tropopause', wvCP4, earth.compositionAtHeight(wvCP4, h2o), wvCP5, 2e-6, h2o) +earth.addCompositionRate('WV stratosphere and up', wvCP5, earth.compositionAtHeight(wvCP5, h2o), maxHeight, 0, h2o) + +# ozone rules +ozCP0 = 3000 * 100 +ozCP1 = 16000 * 100 +ozCP2 = 32000 * 100 +ozCP3 = 60000 * 100 +earth.addCompositionRate('troposphere ozone', ozCP0, 30E-9, ozCP1, 60E-9, o3) +earth.addCompositionRate('tropopause ozone', ozCP1, earth.compositionAtHeight(ozCP1, o3), ozCP2, 5E-6, o3) +earth.addCompositionRate('upper strat ozone', ozCP2, earth.compositionAtHeight(ozCP2, o3), ozCP3, 0, o3) +earth.addCompositionRate('strat on up ozone', ozCP3, earth.compositionAtHeight(ozCP3, o3), top, 0, o3) + +earth.processTransmission(90E5) diff --git a/earthtransmission.py b/earthtransmission.py index eca6c1a..8fc64aa 100644 --- a/earthtransmission.py +++ b/earthtransmission.py @@ -10,11 +10,11 @@ meso1 = 51000 * 100 meso2 = 71000 * 100 mesopause = 80000 * 100 -top = 90000 * 100 +maxHeight = 90000 * 100 profileName = 'earth123' -earth = pyrad.Planet(profileName, 1013.25, 300, rangeMin=500, rangeMax=900, initialThickness=initialThickness) +earth = pyrad.Planet(profileName, 1013.25, 300, maxHeight, rangeMin=500, rangeMax=900, initialThickness=initialThickness) earth.addLapseRate('troposphere dry LR', 0, earth.surfaceTemperature, tropopause, 216, earth.surfacePressure) earth.addLapseRate('tropopause', tropopause, earth.temperatureAtHeight(tropopause), strat1, 216, earth.pressureAtHeight(tropopause)) @@ -23,7 +23,7 @@ earth.addLapseRate('stratopause', stratopause, earth.temperatureAtHeight(stratopause), meso1, 270, earth.pressureAtHeight(stratopause)) earth.addLapseRate('mesosphere1', meso1, earth.temperatureAtHeight(meso1), meso2, 214, earth.pressureAtHeight(meso1)) earth.addLapseRate('mesosphere2', meso2, earth.temperatureAtHeight(meso2), mesopause, 190, earth.pressureAtHeight(meso2)) -earth.addLapseRate('mesopause', mesopause, earth.temperatureAtHeight(mesopause), top, 190, earth.pressureAtHeight(mesopause)) +earth.addLapseRate('mesopause', mesopause, earth.temperatureAtHeight(mesopause), maxHeight, 190, earth.pressureAtHeight(mesopause)) co2 = earth.addMolecule('co2', ppm=350) h2o = earth.addMolecule('h2o', ppm=20000) @@ -46,7 +46,7 @@ earth.addCompositionRate('WV troposphere2', wvCP2, earth.compositionAtHeight(wvCP2, h2o), wvCP3, 400e-6, h2o) earth.addCompositionRate('WV troposphere2', wvCP3, earth.compositionAtHeight(wvCP3, h2o), wvCP4, 400e-6, h2o) earth.addCompositionRate('WV tropopause', wvCP4, earth.compositionAtHeight(wvCP4, h2o), wvCP5, 2e-6, h2o) -earth.addCompositionRate('WV stratosphere and up', wvCP5, earth.compositionAtHeight(wvCP5, h2o), top, 0, h2o) +earth.addCompositionRate('WV stratosphere and up', wvCP5, earth.compositionAtHeight(wvCP5, h2o), maxHeight, 0, h2o) # ozone rules ozCP0 = 3000 * 100 @@ -58,11 +58,7 @@ #earth.addCompositionRate('upper strat ozone', ozCP2, earth.compositionAtHeight(ozCP2, o3), ozCP3, 0, o3) #earth.addCompositionRate('strat on up ozone', ozCP3, earth.compositionAtHeight(ozCP3, o3), top, 0, o3) -yAxis = np.arange(1, 90000, 1) -xAxis = [] -earth.sliceAtm() - - +earth.processTransmission(90E5) #plt.plot(xAxis, yAxis) #plt.show() diff --git a/pyrad.py b/pyrad.py index 8054ac3..e17723a 100644 --- a/pyrad.py +++ b/pyrad.py @@ -18,6 +18,20 @@ avo = 6.022140857E23 +def yesOrNo(promptText): + validInput = False + while not validInput: + userSelection = input(promptText) + if not userSelection: + pass + elif userSelection.lower()[0] == 'y': + return True + elif userSelection.lower()[0] == 'n': + return False + else: + print('Invalid choice.') + + def wvPressure(temperature, RH): wvP = RH * wvSaturationVaporPressure(temperature) / 100 return wvP @@ -346,8 +360,9 @@ def createCrossSection(self): return for line in self: if progress > i * alertInterval: - print('Progress for %s: %s, temperature: %s, pressure: %s <%s%s>' % (layer.name, molecule.name, layer.T, layer.P, '*' * i, '-' * (20 - i)), end='\r') - os.sys.stdout.flush() + print('Progress for %s: %s, K: %s, mBar: %s, km: %s <%s%s>' + % (layer.name, molecule.name, layer.T, round(layer.P, 2), + round(layer.height / 100000, 2), '*' * i, '-' * (20 - i)), end='\r', flush=True) i += 1 progress += 1 xValues = np.arange(0, layer.distanceFromCenter, layer.resolution) @@ -379,7 +394,7 @@ def createCrossSection(self): (self.rangeMax - self.rangeMin) / self.resolution, endpoint=True), crossSection) - print('\ngaussian only: %s\t lorentz only: %s\t voigt: %s\n' % (trackGauss, trackLorentz, trackVoigt), end='\r') + # print('\ngaussian only: %s\t lorentz only: %s\t voigt: %s\n' % (trackGauss, trackLorentz, trackVoigt), end='\r') self.progressCrossSection = True def createLineSurvey(self): @@ -603,7 +618,9 @@ def __init__(self, depth, T, P, rangeMin, rangeMax, height=0.0, atmosphere=None, self.atmosphere = atmosphere self.hasAtmosphere = atmosphere self.crossSection = np.zeros(int((rangeMax - rangeMin) / utils.BASE_RESOLUTION)) + self.absorptionCoefficient = np.zeros(int((rangeMax - rangeMin) / utils.BASE_RESOLUTION)) self.progressCrossSection = False + self.progressAbsCoef = False if not name: name = '%s' % self.atmosphere.nextLayerName() self.atmosphere.append(self) @@ -650,10 +667,11 @@ def xAxis(self): @property def absCoef(self): - tempAxis = np.zeros(int((self.rangeMax - self.rangeMin) / utils.BASE_RESOLUTION)) - for molecule in self: - tempAxis += getAbsCoef(molecule) - return tempAxis + if not self.progressAbsCoef: + for molecule in self: + self.absorptionCoefficient += getAbsCoef(molecule) + self.progressAbsCoef = True + return self.absorptionCoefficient @property def transmittance(self): @@ -842,21 +860,25 @@ def densityAtHeight(self, height, gasConstant): class Planet: - def __init__(self, name, pressure, temperature, molarMass=0.0289644, + def __init__(self, name, pressure, temperature, maxHeight, molarMass=0.0289644, gravity=9.80665, rangeMin=0, rangeMax=2000, initialThickness=100): self.name = name self.mass = 0 self.gravity = gravity + self.maxHeight = maxHeight self.molarMass = molarMass self.radius = 0 self.surfacePressure = pressure self.surfaceTemperature = temperature self.atmosphereRules = [] + self.heightList = [] + self.depthList = [] self.rangeMin = rangeMin self.rangeMax = rangeMax self.atmosphere = Atmosphere("%s's atmosphere" % self.name, planet=self) self.initialLayer = \ self.atmosphere.addLayer(initialThickness, temperature, pressure, rangeMin, rangeMax, height=0) + self.progressProfileLoaded = False def setMass(self, mass): self.mass = mass @@ -918,73 +940,111 @@ def sliceAtm(self): mass = self.initialLayer.mass layer = self.initialLayer.returnCopy(name='temp layer') print('p %s, T %s, depth %s, height %s' % (layer.P, layer.T, layer.depth, layer.height)) - heightList = [height] + self.heightList = [height] tempList = [layer.T] pressureList = [layer.P] - depthList = [layer.depth] - changePoints = self.atmChangePoints - while layer.height + layer.depth < 9000000: - print('temp: %s, press: %s, baseHeight: %skm, meanHeight: %s, depth: %s, tarMass: %s, layMass: %s' % ( - int(layer.T), layer.P, layer.height / 100000, layer.meanHeight, layer.depth, mass, layer.mass)) - newHeight = heightList[-1] + depthList[-1] - heightList.append(newHeight) + self.depthList = [layer.depth] + while layer.height + layer.depth < self.maxHeight: + print('K: %s, mBar: %s, baseHeight: %skm, depth : %skm, layMass: %s' % ( + int(layer.T), round(layer.P, 2), round(layer.height / 100000, 2), round(layer.depth / 100000, 2), round(layer.mass, 2))) + newHeight = self.heightList[-1] + self.depthList[-1] + self.heightList.append(newHeight) tempList.append(self.temperatureAtHeight(newHeight)) pressureList.append(self.pressureAtHeight(newHeight)) layer.P = pressureList[-1] layer.T = tempList[-1] - layer.height = heightList[-1] + layer.height = self.heightList[-1] layer.depth = (mass / layer.density * 100) - '''if layer.height + layer.depth > changePoints[0]: - tempHeight = changePoints.pop(0) - layer.depth = tempHeight - layer.height - while changePoints: - if changePoints[0] == tempHeight: - changePoints.pop(0) - else: - break''' if layer.depth != 0: - depthList.append(layer.depth) - print('Total # of layers: %s' % len(heightList)) - isValid = False - while not isValid: - self.atmosphere.pop() - userInput = input('Accept the current slicing (y/n): ') - if userInput.lower()[0] == 'n': - isValid = True - validNumber = False - while not validNumber: - print('Enter the new initial depth. Larger depth will decrease number of layers, smaller will increase') - userNumber = input('Current depth is %scm:' % utils.limeText(self.initialLayer.depth)) - try: - newDepth = float(userNumber) - self.initialLayer.depth = newDepth - validNumber = True - except ValueError: - print('Invalid number.') - elif userInput.lower()[0] == 'y': - isValid = True - acceptSetup = True - # print(len(self.atmosphere), self.atmosphere[0].name) - heightList.pop(0) - depthList.pop(0) - for i in range(0, len(heightList) - 1): - height = heightList[i] - depth = depthList[i] - newLayer = self.initialLayer.returnCopy() - newLayer.height = height - newLayer.depth = depth - newLayer.T = int(self.temperatureAtHeight(newLayer.meanHeight)) - newLayer.P = self.pressureAtHeight(newLayer.meanHeight) - for molecule in newLayer: - molecule.concentration = self.compositionAtHeight(newLayer.meanHeight, molecule) - surfaceSpectrum = pyradPlanck.planckWavenumber(self.initialLayer.xAxis, self.surfaceTemperature) + self.depthList.append(layer.depth) + if self.heightList[-1] + .5 * self.depthList[-1] > self.maxHeight: + self.heightList.pop() + self.depthList.pop() + print('Total # of layers: %s' % len(self.heightList)) + self.atmosphere.pop() + if yesOrNo('Accept the current slicing (y/n): '): + acceptSetup = True + else: + validNumber = False + while not validNumber: + print( + 'Enter the new initial depth. Larger depth will decrease number of layers, smaller will increase') + userNumber = input('Current depth is %scm:' % utils.limeText(self.initialLayer.depth)) + try: + newDepth = float(userNumber) + self.initialLayer.depth = newDepth + validNumber = True + except ValueError: + print('Invalid number.') + return - for layer in self.atmosphere: + def processLayers(self): + if not self.heightList: + self.sliceAtm() + '''if utils.checkPlanetProfile(self.name, len(self.heightList)): + print('Files found, loading profile %s' % self.name) + self.loadProfile() + return''' + #surfaceSpectrum = pyradPlanck.planckWavenumber(self.initialLayer.xAxis, self.surfaceTemperature) + layer = self.initialLayer + i = 1 + for height, depth in zip(self.heightList, self.depthList): + layer.name = 'Layer %s:%s' % (i, len(self.heightList)) + layer.height = height + layer.depth = depth + layer.T = int(self.temperatureAtHeight(layer.meanHeight)) + layer.P = self.pressureAtHeight(layer.meanHeight) + for molecule in layer: + molecule.concentration = self.compositionAtHeight(layer.meanHeight, molecule) layer.createCrossSection() - transmission = layer.transmission(surfaceSpectrum) - surfaceSpectrum = transmission - plt.plot(self.initialLayer.xAxis, smooth(surfaceSpectrum, 100), linewidth=.5) + utils.writePlanetProfile(self.name, layer) + #surfaceSpectrum = layer.transmission(surfaceSpectrum) + resetCrossSection(layer) + layer.absorptionCoefficient = np.zeros(len(layer.crossSection)) + layer.progressAbsCoef = False + i += 1 + '''plt.plot(self.initialLayer.xAxis, smooth(surfaceSpectrum, 50), linewidth=.5) plt.plot(self.initialLayer.xAxis, pyradPlanck.planckWavenumber(self.initialLayer.xAxis, self.surfaceTemperature), linewidth=.5) + plt.plot(self.initialLayer.xAxis, + pyradPlanck.planckWavenumber(self.initialLayer.xAxis, 280), linewidth=.5) + plt.plot(self.initialLayer.xAxis, + pyradPlanck.planckWavenumber(self.initialLayer.xAxis, 260), linewidth=.5) + plt.plot(self.initialLayer.xAxis, + pyradPlanck.planckWavenumber(self.initialLayer.xAxis, 240), linewidth=.5) + plt.show()''' + + def loadProfile(self): + if not utils.checkPlanetProfile(self.name, len(self.heightList)): + self.processLayers() + else: + fileLength = utils.profileLength(self.name) + if not yesOrNo('%s layers found for profile %s. Load profile (y/n):' % (fileLength, self.name)): + if yesOrNo('Are you sure, selecting yes will delete all previous profile data (y/n): '): + utils.emptyProfileDirectory(self.name) + self.processLayers() + fileLength = utils.profileLength(self.name) + while len(self.atmosphere) > 0: + self.atmosphere.pop() + for i in range(1, fileLength + 1): + lP = utils.readPlanetProfile(self.name, i, fileLength) + layer = Layer(lP['depth'], lP['T'], lP['P'], lP['rangeMin'], lP['rangeMax'], name=lP['name']) + self.atmosphere.append(layer) + layer.absorptionCoefficient = np.asarray(lP['absCoef']) + layer.progressAbsCoef = True + self.progressProfileLoaded = True + return + + def processTransmission(self, height, direction='down'): + if not self.progressProfileLoaded: + self.loadProfile() + surfaceSpectrum = pyradPlanck.planckWavenumber(self.initialLayer.xAxis, self.surfaceTemperature) + for layer in self.atmosphere: + if layer.meanHeight < height: + surfaceSpectrum = layer.transmission(surfaceSpectrum) + print('maxHeight: %s, processed %s, layerMeanHeight: %s' % (height / 100000, layer.name, layer.meanHeight)) + plt.plot(self.initialLayer.xAxis, smooth(surfaceSpectrum, 50), linewidth=.5) + plt.plot(self.initialLayer.xAxis, + pyradPlanck.planckWavenumber(self.initialLayer.xAxis, self.surfaceTemperature), linewidth=.5) plt.plot(self.initialLayer.xAxis, pyradPlanck.planckWavenumber(self.initialLayer.xAxis, 280), linewidth=.5) plt.plot(self.initialLayer.xAxis, @@ -993,6 +1053,7 @@ def sliceAtm(self): pyradPlanck.planckWavenumber(self.initialLayer.xAxis, 240), linewidth=.5) plt.show() + @property def yAxis(self): return np.zeros(int((self.rangeMax - self.rangeMin) / utils.BASE_RESOLUTION)) diff --git a/pyradLineshape.py b/pyradLineshape.py index 5523e13..58cf0de 100644 --- a/pyradLineshape.py +++ b/pyradLineshape.py @@ -5,10 +5,10 @@ #cachedVoigt = utils.getCurves('voigt', utils.BASE_RESOLUTION) #cachedLorentz = utils.getCurves('lorentz', utils.BASE_RESOLUTION) #cachedGaussian = utils.getCurves('gaussian', utils.BASE_RESOLUTION) -cachedLorentz = {} -cachedGaussian = {} -newLorentz = {} -newGaussian = {} +#cachedLorentz = {} +#cachedGaussian = {} +#newLorentz = {} +#newGaussian = {} print('\n', end='\r') h = 6.62607004e-34 @@ -30,28 +30,28 @@ def lorentzHW(airHalfWidth, selfHalfWidth, P, T, q, tExponent): def gaussianLineShape(halfWidth, xValue): - if isinstance(xValue, np.ndarray) and str(halfWidth) in cachedGaussian: - length = len(xValue) - cachedCurve = cachedGaussian[str(halfWidth)] - if len(cachedCurve) >= length: - return cachedCurve[:length] +# if isinstance(xValue, np.ndarray) and str(halfWidth) in cachedGaussian: +# length = len(xValue) +# cachedCurve = cachedGaussian[str(halfWidth)] +# if len(cachedCurve) >= length: +# return cachedCurve[:length] """Returns the right half of a gaussian curve, used for temp broadening in low pressure scenarios""" lineShape = np.exp(-xValue**2 / halfWidth**2) / halfWidth / np.sqrt(pi) - cachedGaussian[halfWidth] = lineShape - newGaussian[halfWidth] = lineShape + #cachedGaussian[halfWidth] = lineShape + #newGaussian[halfWidth] = lineShape return lineShape def lorentzLineShape(halfWidth, xValue): - if isinstance(xValue, np.ndarray) and str(halfWidth) in cachedLorentz: - length = len(xValue) - cachedCurve = cachedLorentz[str(halfWidth)] - if len(cachedCurve) >= length: - return cachedCurve[:length] +# if isinstance(xValue, np.ndarray) and str(halfWidth) in cachedLorentz: +# length = len(xValue) +# cachedCurve = cachedLorentz[str(halfWidth)] +# if len(cachedCurve) >= length: +# return cachedCurve[:length] """Returns the right half of a lorentzian curve.""" lineShape = halfWidth / pi / (xValue**2 + halfWidth**2) - cachedLorentz[halfWidth] = lineShape - newLorentz[halfWidth] = lineShape + #cachedLorentz[halfWidth] = lineShape + #newLorentz[halfWidth] = lineShape return lineShape diff --git a/pyradUtilities.py b/pyradUtilities.py index 3fad480..13ed5c2 100644 --- a/pyradUtilities.py +++ b/pyradUtilities.py @@ -11,7 +11,7 @@ dataDir = '%s/data' % cwd curvesDir = '%s/curves' % dataDir molParamsFile = '%s/molparams.txt' % dataDir -profileDir = '/%s/profiles' % cwd +profileDir = '/%s/profiles' % dataDir debuggerFilePath = '%s/logger.txt' % cwd now = datetime.datetime.now() debuggerFile = open(debuggerFilePath, 'wb') @@ -56,7 +56,7 @@ def logToFile(text): def setupDir(): print('Verifying data structure...', end='') sys.stdout.flush() - directoryList = [dataDir, curvesDir] + directoryList = [dataDir, curvesDir, profileDir] fileList = [] directoryCheck = True fileCheck = True @@ -92,7 +92,83 @@ def openReturnLines(fullPath): lineList.pop(0) return lineList - + +def writePlanetProfile(name, layer): + folderPath = '%s/%s' % (profileDir, name) + if not os.path.isdir(folderPath): + os.mkdir(folderPath) + filePath = '%s/%s.pyr' % (folderPath, layer.name) + openFile = open(filePath, 'wb') + text = ('depth: %s\n' + 'T: %s\n' + 'P: %s\n' + 'rangeMin: %s\n' + 'rangeMax: %s\n' + 'height: %s\n' + 'name: %s\n' + '##\t\tlayer absorption coefficient\t\t##\n' + 'absCoef: %s' + % (layer.depth, int(layer.T), layer.P, layer.rangeMin, layer.rangeMax, layer.height, layer.name, + ','.join(map(str, layer.absCoef.tolist())))) + openFile.write(text.encode('utf-8')) + openFile.close() + print('absCoef written to profiles/%s.pyr' % layer.name) + return + + +def checkPlanetProfile(name, length): + folderPath = '%s/%s' % (profileDir, name) + if not os.path.isdir(folderPath): + os.mkdir(folderPath) + return False + else: + for i in range(1, length + 1): + fileName = 'Layer %s:%s' % (i, length) + filePath = '%s/%s.pyr' % (folderPath, fileName) + if not os.path.isfile(filePath): + print('%s missing' % fileName) + return False + return True + + +def profileLength(name): + folderPath = '%s/%s' % (profileDir, name) + return len(os.listdir(folderPath)) + +def emptyProfileDirectory(name): + folderPath = '%s/%s' % (profileDir, name) + fileList = os.listdir(folderPath) + for file in fileList: + filePath = '%s/%s' % (folderPath, file) + os.remove(filePath) + os.removedirs(folderPath) + return + +def readPlanetProfile(name, layerNumber, length): + folderPath = '%s/%s' % (profileDir, name) + fileName = 'Layer %s:%s' % (layerNumber, length) + filePath = '%s/%s.pyr' % (folderPath, fileName) + lines = openReturnLines(filePath) + layerDict = {} + for line in lines: + keyValue = line.split(':') + if line[0] == '#': + pass + elif keyValue[0] == 'name': + layerDict[keyValue[0]] = keyValue[1] + elif keyValue[0] == 'absCoef': + absList = keyValue[1].split(',') + absCoefList = [] + for value in absList: + absCoefList.append(float(value)) + layerDict[keyValue[0]] = absCoefList + elif keyValue[0] == 'T' or keyValue[0] == 'rangeMin' or keyValue[0] == 'rangeMax': + layerDict[keyValue[0]] = int(keyValue[1]) + else: + layerDict[keyValue[0]] = float(keyValue[1]) + return layerDict + + def writeDictListToFile(dictionary, fullPath, comments=None, mode='wb'): openFile = open(fullPath, mode) if comments: From afb6582c4a02ddee669dd2de4f4c5c3cac1b0006 Mon Sep 17 00:00:00 2001 From: Brad Schrag Date: Sat, 13 Oct 2018 13:17:47 -0500 Subject: [PATCH 04/43] things are flying. processing earth.py takes about 30minutes and looks great./pithos.in --- earth2.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/earth2.py b/earth2.py index 00b9e60..82f28a0 100644 --- a/earth2.py +++ b/earth2.py @@ -29,7 +29,8 @@ h2o = earth.addMolecule('h2o', ppm=20000) n2 = earth.addMolecule('n2', percentage=76.9) o2 = earth.addMolecule('o2', percentage=19.9) -o3 = earth.addMoleculeo3('o3', ppb=0) +o3 = earth.addMolecule('o3', ppb=0) +ch4 = earth.addMolecule('ch4', ppm=1.5) # ar = earth.addMolecule('ar', percentage=.9) # earth.addCompositionRate('co2 troposphere', 0, co2.concentration, 11000, -.000000001, co2) @@ -56,6 +57,11 @@ earth.addCompositionRate('troposphere ozone', ozCP0, 30E-9, ozCP1, 60E-9, o3) earth.addCompositionRate('tropopause ozone', ozCP1, earth.compositionAtHeight(ozCP1, o3), ozCP2, 5E-6, o3) earth.addCompositionRate('upper strat ozone', ozCP2, earth.compositionAtHeight(ozCP2, o3), ozCP3, 0, o3) -earth.addCompositionRate('strat on up ozone', ozCP3, earth.compositionAtHeight(ozCP3, o3), top, 0, o3) +earth.addCompositionRate('strat on up ozone', ozCP3, earth.compositionAtHeight(ozCP3, o3), maxHeight, 0, o3) + +#ch4 rules +earth.addCompositionRate('troposphere methane', 0, ch4.concentration, strat1, ch4.concentration, ch4) +earth.addCompositionRate('taper ch4 strat', strat1, ch4.concentration, stratopause, 0, ch4) +earth.addCompositionRate('ch4 0 to max height', stratopause, 0, maxHeight, 0, ch4) earth.processTransmission(90E5) From 2a476284abcf8f8617f774827102993128187aa5 Mon Sep 17 00:00:00 2001 From: Brad Schrag Date: Tue, 16 Oct 2018 09:08:04 -0500 Subject: [PATCH 05/43] more details getting sorted --- earth low simple.pyr | 21 +++++ earth2.py | 2 +- earth3.py | 67 ++++++++++++++ earthtransmission.py | 91 +++++++++---------- pyrad.py | 204 ++++++++++++++++++++----------------------- pyradUtilities.py | 132 +++++++++++++++++++++++++--- 6 files changed, 350 insertions(+), 167 deletions(-) create mode 100644 earth low simple.pyr create mode 100644 earth3.py diff --git a/earth low simple.pyr b/earth low simple.pyr new file mode 100644 index 0000000..444a548 --- /dev/null +++ b/earth low simple.pyr @@ -0,0 +1,21 @@ +# A demo file for pyrad + +setting: low + +# mBar , K , km,cm-1,cm-1, m +surface: 1013.25, 288, 90, 500, 900, 100 + +molecule: co2, .000400 +molecule: h2o, .018000 +molecule: o3, 0 +molecule: o2, .21 +molecule: n2, .79 + +lapse rate: troposphere, 11, 216 +lapse rate: tropopause, 20, 216 +lapse rate: stratosphere 1, 32, 228 +lapse rate: stratosphere 2, 47, 270 +lapse rate: stratopause, 51, 270 +lapse rate: mesosphere 1, 71, 214 +lapse rate: mesosphere2, 80, 190 +lapse rate: mesopause, 90, 190 \ No newline at end of file diff --git a/earth2.py b/earth2.py index 82f28a0..bee412d 100644 --- a/earth2.py +++ b/earth2.py @@ -14,7 +14,7 @@ profileName = 'earth345' -earth = pyrad.Planet(profileName, 1013.25, 300, maxHeight, rangeMin=00, rangeMax=2000, initialThickness=initialThickness) +earth = pyrad.Planet(profileName, 1013.25, 288, maxHeight, rangeMin=00, rangeMax=2000, initialThickness=initialThickness) earth.addLapseRate('troposphere dry LR', 0, earth.surfaceTemperature, tropopause, 216, earth.surfacePressure) earth.addLapseRate('tropopause', tropopause, earth.temperatureAtHeight(tropopause), strat1, 216, earth.pressureAtHeight(tropopause)) diff --git a/earth3.py b/earth3.py new file mode 100644 index 0000000..79d7633 --- /dev/null +++ b/earth3.py @@ -0,0 +1,67 @@ +import pyrad +import numpy as np + + +initialThickness = 100 * 100 +tropopause = 11000 * 100 +strat1 = 20000 * 100 +strat2 = 32000 * 100 +stratopause = 47000 * 100 +meso1 = 51000 * 100 +meso2 = 71000 * 100 +mesopause = 80000 * 100 +maxHeight = 90000 * 100 +profileName = 'earth678' + + +earth = pyrad.Planet(profileName, 1013.25, 300, maxHeight, rangeMin=00, rangeMax=2000, initialThickness=initialThickness) + +earth.addLapseRate('troposphere dry LR', 0, earth.surfaceTemperature, tropopause, 216, earth.surfacePressure) +earth.addLapseRate('tropopause', tropopause, earth.temperatureAtHeight(tropopause), strat1, 216, earth.pressureAtHeight(tropopause)) +earth.addLapseRate('stratosphere1', strat1, earth.temperatureAtHeight(strat1), strat2, 228, earth.pressureAtHeight(strat1)) +earth.addLapseRate('stratosphere2', strat2, earth.temperatureAtHeight(strat2), stratopause, 270, earth.pressureAtHeight(strat2)) +earth.addLapseRate('stratopause', stratopause, earth.temperatureAtHeight(stratopause), meso1, 270, earth.pressureAtHeight(stratopause)) +earth.addLapseRate('mesosphere1', meso1, earth.temperatureAtHeight(meso1), meso2, 214, earth.pressureAtHeight(meso1)) +earth.addLapseRate('mesosphere2', meso2, earth.temperatureAtHeight(meso2), mesopause, 190, earth.pressureAtHeight(meso2)) +earth.addLapseRate('mesopause', mesopause, earth.temperatureAtHeight(mesopause), maxHeight, 190, earth.pressureAtHeight(mesopause)) + +co2 = earth.addMolecule('co2', ppm=350) +h2o = earth.addMolecule('h2o', ppm=20000) +n2 = earth.addMolecule('n2', percentage=76.9) +o2 = earth.addMolecule('o2', percentage=19.9) +o3 = earth.addMolecule('o3', ppb=0) +ch4 = earth.addMolecule('ch4', ppm=1.5) +# ar = earth.addMolecule('ar', percentage=.9) + +# earth.addCompositionRate('co2 troposphere', 0, co2.concentration, 11000, -.000000001, co2) +# earth.addCompositionRate('co2 stratosphere and up', 0, earth.compositionAtHeight(11000, co2), 90000, 0, co2) + +wvCP1 = 2500 * 100 +wvCP2 = 8000 * 100 +wvCP3 = 9000 * 100 +wvCP4 = 10000 * 100 +wvCP5 = 20000 * 100 + +earth.addCompositionRate('WV boundary layer', 0, h2o.concentration, wvCP1, 10000e-6, h2o) +earth.addCompositionRate('WV troposphere1', wvCP1, earth.compositionAtHeight(wvCP1, h2o), wvCP2, 200e-6, h2o) +earth.addCompositionRate('WV troposphere2', wvCP2, earth.compositionAtHeight(wvCP2, h2o), wvCP3, 400e-6, h2o) +earth.addCompositionRate('WV troposphere2', wvCP3, earth.compositionAtHeight(wvCP3, h2o), wvCP4, 400e-6, h2o) +earth.addCompositionRate('WV tropopause', wvCP4, earth.compositionAtHeight(wvCP4, h2o), wvCP5, 2e-6, h2o) +earth.addCompositionRate('WV stratosphere and up', wvCP5, earth.compositionAtHeight(wvCP5, h2o), maxHeight, 0, h2o) + +# ozone rules +ozCP0 = 3000 * 100 +ozCP1 = 16000 * 100 +ozCP2 = 32000 * 100 +ozCP3 = 60000 * 100 +earth.addCompositionRate('troposphere ozone', ozCP0, 30E-9, ozCP1, 60E-9, o3) +earth.addCompositionRate('tropopause ozone', ozCP1, earth.compositionAtHeight(ozCP1, o3), ozCP2, 5E-6, o3) +earth.addCompositionRate('upper strat ozone', ozCP2, earth.compositionAtHeight(ozCP2, o3), ozCP3, 0, o3) +earth.addCompositionRate('strat on up ozone', ozCP3, earth.compositionAtHeight(ozCP3, o3), maxHeight, 0, o3) + +#ch4 rules +earth.addCompositionRate('troposphere methane', 0, ch4.concentration, strat1, ch4.concentration, ch4) +earth.addCompositionRate('taper ch4 strat', strat1, ch4.concentration, stratopause, 0, ch4) +earth.addCompositionRate('ch4 0 to max height', stratopause, 0, maxHeight, 0, ch4) + +earth.processTransmission(90E5) diff --git a/earthtransmission.py b/earthtransmission.py index 8fc64aa..6e8081c 100644 --- a/earthtransmission.py +++ b/earthtransmission.py @@ -1,69 +1,70 @@ import pyrad import numpy as np - - -initialThickness = 100 * 100 -tropopause = 11000 * 100 -strat1 = 20000 * 100 -strat2 = 32000 * 100 -stratopause = 47000 * 100 -meso1 = 51000 * 100 -meso2 = 71000 * 100 -mesopause = 80000 * 100 -maxHeight = 90000 * 100 +from matplotlib import pyplot as plt + + +initialThickness = 100 #meter +tropopause = 11 #km +strat1 = 20 #km +strat2 = 32 #km +stratopause = 47 +meso1 = 51 +meso2 = 71 +mesopause = 80 +maxHeight = 90 profileName = 'earth123' earth = pyrad.Planet(profileName, 1013.25, 300, maxHeight, rangeMin=500, rangeMax=900, initialThickness=initialThickness) -earth.addLapseRate('troposphere dry LR', 0, earth.surfaceTemperature, tropopause, 216, earth.surfacePressure) -earth.addLapseRate('tropopause', tropopause, earth.temperatureAtHeight(tropopause), strat1, 216, earth.pressureAtHeight(tropopause)) -earth.addLapseRate('stratosphere1', strat1, earth.temperatureAtHeight(strat1), strat2, 228, earth.pressureAtHeight(strat1)) -earth.addLapseRate('stratosphere2', strat2, earth.temperatureAtHeight(strat2), stratopause, 270, earth.pressureAtHeight(strat2)) -earth.addLapseRate('stratopause', stratopause, earth.temperatureAtHeight(stratopause), meso1, 270, earth.pressureAtHeight(stratopause)) -earth.addLapseRate('mesosphere1', meso1, earth.temperatureAtHeight(meso1), meso2, 214, earth.pressureAtHeight(meso1)) -earth.addLapseRate('mesosphere2', meso2, earth.temperatureAtHeight(meso2), mesopause, 190, earth.pressureAtHeight(meso2)) -earth.addLapseRate('mesopause', mesopause, earth.temperatureAtHeight(mesopause), maxHeight, 190, earth.pressureAtHeight(mesopause)) +earth.addLapseRate('troposphere dry LR', tropopause, 216) +earth.addLapseRate('tropopause', strat1, 216) +earth.addLapseRate('stratosphere1', strat2, 228) +earth.addLapseRate('stratosphere2', stratopause, 270) +earth.addLapseRate('stratopause', meso1, 270) +earth.addLapseRate('mesosphere1', meso2, 214) +earth.addLapseRate('mesosphere2', mesopause, 190) +earth.addLapseRate('mesopause', maxHeight, 190) co2 = earth.addMolecule('co2', ppm=350) h2o = earth.addMolecule('h2o', ppm=20000) n2 = earth.addMolecule('n2', percentage=76.9) o2 = earth.addMolecule('o2', percentage=19.9) #o3 = earth.addMolecule('o3', ppb=0) -# ar = earth.addMolecule('ar', percentage=.9) - -# earth.addCompositionRate('co2 troposphere', 0, co2.concentration, 11000, -.000000001, co2) -# earth.addCompositionRate('co2 stratosphere and up', 0, earth.compositionAtHeight(11000, co2), 90000, 0, co2) -wvCP1 = 2500 * 100 -wvCP2 = 8000 * 100 -wvCP3 = 9000 * 100 -wvCP4 = 10000 * 100 -wvCP5 = 20000 * 100 +wvCP1 = 2.5 +wvCP2 = 8 +wvCP3 = 9 +wvCP4 = 10 +wvCP5 = 20 -earth.addCompositionRate('WV boundary layer', 0, h2o.concentration, wvCP1, 10000e-6, h2o) -earth.addCompositionRate('WV troposphere1', wvCP1, earth.compositionAtHeight(wvCP1, h2o), wvCP2, 200e-6, h2o) -earth.addCompositionRate('WV troposphere2', wvCP2, earth.compositionAtHeight(wvCP2, h2o), wvCP3, 400e-6, h2o) -earth.addCompositionRate('WV troposphere2', wvCP3, earth.compositionAtHeight(wvCP3, h2o), wvCP4, 400e-6, h2o) -earth.addCompositionRate('WV tropopause', wvCP4, earth.compositionAtHeight(wvCP4, h2o), wvCP5, 2e-6, h2o) -earth.addCompositionRate('WV stratosphere and up', wvCP5, earth.compositionAtHeight(wvCP5, h2o), maxHeight, 0, h2o) +earth.addCompositionRate('WV boundary layer', wvCP1, 18000e-6, h2o) +earth.addCompositionRate('WV troposphere1', wvCP2, 200e-6, h2o) +earth.addCompositionRate('WV troposphere2', wvCP3, 400e-6, h2o) +earth.addCompositionRate('WV troposphere2', wvCP4, 400e-6, h2o) +earth.addCompositionRate('WV tropopause', wvCP5, 2e-6, h2o) +earth.addCompositionRate('WV stratosphere and up',maxHeight, 0, h2o) # ozone rules -ozCP0 = 3000 * 100 -ozCP1 = 16000 * 100 -ozCP2 = 32000 * 100 -ozCP3 = 60000 * 100 -#earth.addCompositionRate('troposphere ozone', ozCP0, 30E-9, ozCP1, 60E-9, o3) -#earth.addCompositionRate('tropopause ozone', ozCP1, earth.compositionAtHeight(ozCP1, o3), ozCP2, 5E-6, o3) -#earth.addCompositionRate('upper strat ozone', ozCP2, earth.compositionAtHeight(ozCP2, o3), ozCP3, 0, o3) -#earth.addCompositionRate('strat on up ozone', ozCP3, earth.compositionAtHeight(ozCP3, o3), top, 0, o3) +ozCP0 = 3 +ozCP1 = 16 +ozCP2 = 32 +ozCP3 = 60 +#earth.addCompositionRate('troposphere ozone', ozCP1, 60E-9, o3) +#earth.addCompositionRate('tropopause ozone', ozCP2, 5E-6, o3) +#earth.addCompositionRate('upper strat ozone', ozCP3, 0, o3) +#earth.addCompositionRate('strat on up ozone', maxHeight, 0, o3) -earth.processTransmission(90E5) +'''yAxis = np.arange(1, 90000, 1) +xAxis = [] +for height in yAxis: + xAxis.append(earth.compositionAtHeight(height*100, o3)) -#plt.plot(xAxis, yAxis) -#plt.show() +plt.plot(xAxis, yAxis) +plt.show()''' +earth.processTransmission(90E5) """ diff --git a/pyrad.py b/pyrad.py index e17723a..1fb2944 100644 --- a/pyrad.py +++ b/pyrad.py @@ -32,53 +32,12 @@ def yesOrNo(promptText): print('Invalid choice.') -def wvPressure(temperature, RH): - wvP = RH * wvSaturationVaporPressure(temperature) / 100 - return wvP - - -def wvRH2AH(temperature, pressure, RH): - wvP = wvPressure(temperature, RH) - - absHum = wvP / 461.5 * temperature - print(wvP, absHum) - return absHum - - -def wvMixingRatio(temperature, pressure, RH): - e = wvPressure(temperature, RH) - r = .622 * e / (pressure - e) - return r - - def smooth(y, box_pts): box = np.ones(box_pts)/box_pts y_smooth = np.convolve(y, box, mode='same') return y_smooth -def wvSaturationVaporPressure(temperature): - temperature -= 273 - tC = 647.096 - pC = 220640 - a1 = -7.85951783 - a2 = 1.84408259 - a3 = -11.7866497 - a4 = 22.6807411 - a5 = -15.9618719 - a6 = 1.80122502 - # v = 1 - temperature / tC - # satVP = pC * np.exp(tC / temperature * (a1 * v + a2 * v**1.5 + a3 * v**3 + a4 * v**3.5 + a5 * v**4 + a6 * v**7.5)) - satVP = 6.11 * np.exp(17.3 * temperature / (temperature + 237.3)) - return satVP - - -def wvConcentrationFromRH(layer, RH): - temperature = layer.T - pressure = layer.P - concentration = wvMixingRatio(temperature, pressure, RH) - return concentration - def linear(baseValue, baseHeight, rate, height): newValue = baseValue + rate * (height - baseHeight) return newValue @@ -156,13 +115,6 @@ def getGlobalIsotope(ID, isotopeDepth): return globalIsoList -def printProgress(text, obj): - layerName = obj.layer.name - molName = obj.molecule.name - isoName = obj.name - print('Processing %s: %s; %s; isotope %s' % (text, layerName, molName, isoName)) - - def totalConcentration(layer): total = 0 for molecule in layer: @@ -359,10 +311,10 @@ def createCrossSection(self): self.progressCrossSection = True return for line in self: - if progress > i * alertInterval: - print('Progress for %s: %s, K: %s, mBar: %s, km: %s <%s%s>' - % (layer.name, molecule.name, layer.T, round(layer.P, 2), - round(layer.height / 100000, 2), '*' * i, '-' * (20 - i)), end='\r', flush=True) + if progress > i * alertInterval and len(self) > 50: + text = 'Processing %s, height %skm, molecule %s: <%s%s>' % (layer.name, round(layer.height / 100000, 2), + molecule.name, '*' * i, '-' * (20 - i)) + print(text, end='\r', flush=True) i += 1 progress += 1 xValues = np.arange(0, layer.distanceFromCenter, layer.resolution) @@ -394,7 +346,6 @@ def createCrossSection(self): (self.rangeMax - self.rangeMin) / self.resolution, endpoint=True), crossSection) - # print('\ngaussian only: %s\t lorentz only: %s\t voigt: %s\n' % (trackGauss, trackLorentz, trackVoigt), end='\r') self.progressCrossSection = True def createLineSurvey(self): @@ -865,7 +816,7 @@ def __init__(self, name, pressure, temperature, maxHeight, molarMass=0.0289644, self.name = name self.mass = 0 self.gravity = gravity - self.maxHeight = maxHeight + self.maxHeight = maxHeight * 100000 self.molarMass = molarMass self.radius = 0 self.surfacePressure = pressure @@ -877,20 +828,19 @@ def __init__(self, name, pressure, temperature, maxHeight, molarMass=0.0289644, self.rangeMax = rangeMax self.atmosphere = Atmosphere("%s's atmosphere" % self.name, planet=self) self.initialLayer = \ - self.atmosphere.addLayer(initialThickness, temperature, pressure, rangeMin, rangeMax, height=0) + self.atmosphere.addLayer(initialThickness * 100, temperature, pressure, rangeMin, rangeMax, + name='initial layer', height=0) self.progressProfileLoaded = False def setMass(self, mass): self.mass = mass - def addLapseRate(self, name, baseHeight, baseTemperature, finalHeight, finalValue, basePressure, rateFunction=linear): - self.atmosphereRules.append(AtmosphereRule( - name, baseHeight, baseTemperature, finalHeight, finalValue, 'temperature', - basePressure, rateFunction=rateFunction)) + def addLapseRate(self, name, finalHeight, finalValue, rateFunction=linear): + self.atmosphereRules.append(AtmosphereRule(name, finalHeight * 100000, + finalValue, 'temperature', self, rateFunction=rateFunction)) - def addCompositionRate(self, name, baseHeight, baseValue, finalHeight, rate, molecule, rateFunction=linear): - self.atmosphereRules.append(AtmosphereRule( - name, baseHeight, baseValue, finalHeight, rate, ruleType='composition', + def addCompositionRate(self, name, finalHeight, finalValue, molecule, rateFunction=linear): + self.atmosphereRules.append(AtmosphereRule(name, finalHeight * 100000, finalValue, 'composition', self, molecule=molecule, rateFunction=rateFunction)) def setRadius(self, radius): @@ -917,6 +867,13 @@ def returnApplicableRules(self, height, ruleType): return False return ruleList + def returnAllRulesOfType(self, ruleType): + ruleList = [] + for rule in self.atmosphereRules: + if rule.ruleType == ruleType: + ruleList.append(rule) + return ruleList + def temperatureAtHeight(self, height): return self.atmosphere.temperatureAtHeight(height) @@ -933,20 +890,20 @@ def addMolecule(self, name, isotopeDepth=1, **abundance): molecule = self.initialLayer.addMolecule(name, isotopeDepth, **abundance) return molecule - def sliceAtm(self): + def sliceAtm(self, verify=True): acceptSetup = False height = 0 while not acceptSetup: mass = self.initialLayer.mass - layer = self.initialLayer.returnCopy(name='temp layer') - print('p %s, T %s, depth %s, height %s' % (layer.P, layer.T, layer.depth, layer.height)) + layer = self.initialLayer + print('%s, p %s, T %s, depth %s, height %s' % (layer.name, layer.P, layer.T, layer.depth, layer.height)) self.heightList = [height] tempList = [layer.T] pressureList = [layer.P] self.depthList = [layer.depth] while layer.height + layer.depth < self.maxHeight: - print('K: %s, mBar: %s, baseHeight: %skm, depth : %skm, layMass: %s' % ( - int(layer.T), round(layer.P, 2), round(layer.height / 100000, 2), round(layer.depth / 100000, 2), round(layer.mass, 2))) + print('%s: K: %s, mBar: %s, baseHeight: %skm, depth : %skm, layMass: %s' % ( + 'Layer %s' %len(self.heightList), int(layer.T), round(layer.P, 2), round(layer.height / 100000, 2), round(layer.depth / 100000, 2), round(layer.mass, 2))) newHeight = self.heightList[-1] + self.depthList[-1] self.heightList.append(newHeight) tempList.append(self.temperatureAtHeight(newHeight)) @@ -961,34 +918,35 @@ def sliceAtm(self): self.heightList.pop() self.depthList.pop() print('Total # of layers: %s' % len(self.heightList)) - self.atmosphere.pop() - if yesOrNo('Accept the current slicing (y/n): '): - acceptSetup = True + if verify: + if yesOrNo('Accept the current slicing (y/n): '): + acceptSetup = True + else: + validNumber = False + while not validNumber: + print( + 'Enter the new initial depth. Larger depth will decrease number of layers, smaller will increase') + userNumber = input('Current depth is %scm:' % utils.limeText(self.initialLayer.depth)) + try: + newDepth = float(userNumber) + self.initialLayer.depth = newDepth + validNumber = True + except ValueError: + print('Invalid number.') else: - validNumber = False - while not validNumber: - print( - 'Enter the new initial depth. Larger depth will decrease number of layers, smaller will increase') - userNumber = input('Current depth is %scm:' % utils.limeText(self.initialLayer.depth)) - try: - newDepth = float(userNumber) - self.initialLayer.depth = newDepth - validNumber = True - except ValueError: - print('Invalid number.') + acceptSetup = True return def processLayers(self): + if utils.profileProgress(self.name): + self.sliceAtm(verify=False) if not self.heightList: self.sliceAtm() - '''if utils.checkPlanetProfile(self.name, len(self.heightList)): - print('Files found, loading profile %s' % self.name) - self.loadProfile() - return''' - #surfaceSpectrum = pyradPlanck.planckWavenumber(self.initialLayer.xAxis, self.surfaceTemperature) layer = self.initialLayer - i = 1 - for height, depth in zip(self.heightList, self.depthList): + startPoint = utils.profileProgress(self.name) + i = startPoint + 1 + print('Incomplete profile found, resuming...') + for height, depth in zip(self.heightList[startPoint:], self.depthList[startPoint:]): layer.name = 'Layer %s:%s' % (i, len(self.heightList)) layer.height = height layer.depth = depth @@ -998,30 +956,23 @@ def processLayers(self): molecule.concentration = self.compositionAtHeight(layer.meanHeight, molecule) layer.createCrossSection() utils.writePlanetProfile(self.name, layer) - #surfaceSpectrum = layer.transmission(surfaceSpectrum) + utils.profileWriteProgress(self.name, i, len(self.heightList)) resetCrossSection(layer) layer.absorptionCoefficient = np.zeros(len(layer.crossSection)) layer.progressAbsCoef = False i += 1 - '''plt.plot(self.initialLayer.xAxis, smooth(surfaceSpectrum, 50), linewidth=.5) - plt.plot(self.initialLayer.xAxis, pyradPlanck.planckWavenumber(self.initialLayer.xAxis, self.surfaceTemperature), linewidth=.5) - plt.plot(self.initialLayer.xAxis, - pyradPlanck.planckWavenumber(self.initialLayer.xAxis, 280), linewidth=.5) - plt.plot(self.initialLayer.xAxis, - pyradPlanck.planckWavenumber(self.initialLayer.xAxis, 260), linewidth=.5) - plt.plot(self.initialLayer.xAxis, - pyradPlanck.planckWavenumber(self.initialLayer.xAxis, 240), linewidth=.5) - plt.show()''' + utils.profileWriteComplete(self.name, i, len(self.heightList)) + return def loadProfile(self): - if not utils.checkPlanetProfile(self.name, len(self.heightList)): - self.processLayers() - else: + if utils.profileComplete(self.name): fileLength = utils.profileLength(self.name) if not yesOrNo('%s layers found for profile %s. Load profile (y/n):' % (fileLength, self.name)): if yesOrNo('Are you sure, selecting yes will delete all previous profile data (y/n): '): utils.emptyProfileDirectory(self.name) self.processLayers() + else: + self.processLayers() fileLength = utils.profileLength(self.name) while len(self.atmosphere) > 0: self.atmosphere.pop() @@ -1031,6 +982,7 @@ def loadProfile(self): self.atmosphere.append(layer) layer.absorptionCoefficient = np.asarray(lP['absCoef']) layer.progressAbsCoef = True + print('') self.progressProfileLoaded = True return @@ -1038,10 +990,13 @@ def processTransmission(self, height, direction='down'): if not self.progressProfileLoaded: self.loadProfile() surfaceSpectrum = pyradPlanck.planckWavenumber(self.initialLayer.xAxis, self.surfaceTemperature) + print('Processing atmosphere spectrum from %s looking %s...' % (height / 100000, direction)) for layer in self.atmosphere: if layer.meanHeight < height: surfaceSpectrum = layer.transmission(surfaceSpectrum) - print('maxHeight: %s, processed %s, layerMeanHeight: %s' % (height / 100000, layer.name, layer.meanHeight)) + print('Processing %s...' % layer.name, end='\r', flush=True) + print('') + print('total power of spectrum: %sWm-2' % int((integrateSpectrum(surfaceSpectrum) / 5.67E-8)**.25)) plt.plot(self.initialLayer.xAxis, smooth(surfaceSpectrum, 50), linewidth=.5) plt.plot(self.initialLayer.xAxis, pyradPlanck.planckWavenumber(self.initialLayer.xAxis, self.surfaceTemperature), linewidth=.5) @@ -1052,7 +1007,7 @@ def processTransmission(self, height, direction='down'): plt.plot(self.initialLayer.xAxis, pyradPlanck.planckWavenumber(self.initialLayer.xAxis, 240), linewidth=.5) plt.show() - + return surfaceSpectrum @property def yAxis(self): @@ -1070,25 +1025,56 @@ def atmChangePoints(self): changePointList.append(rule.finalHeight) return sorted(changePointList) + @property + def transmission(self): + return self.processTransmission(self.maxHeight) + class AtmosphereRule: - def __init__(self, name, baseHeight, baseValue, finalHeight, finalValue, ruleType, basePressure=0, - molecule=None, rateFunction=linear): + def __init__(self, name, finalHeight, finalValue, ruleType, planetClass, molecule=None, rateFunction=linear): self.name = name - self.baseHeight = baseHeight - self.baseValue = baseValue + self.ruleType = ruleType + self.parent = planetClass + self.baseHeight, self.baseValue, self.basePressure = self.setBaseValues(self.ruleType, molecule) self.finalHeight = finalHeight self.finalValue = finalValue if rateFunction == linear: self.rate = (self.finalValue - self.baseValue) / (self.finalHeight - self.baseHeight) - self.ruleType = ruleType self.molecule = molecule - self.basePressure = basePressure self.rateFunction = rateFunction def isInRange(self, height, ruleType): return self.baseHeight < height <= self.finalHeight and self.ruleType == ruleType + def baseHeightTemperatureRule(self): + height = 0 + temperature = self.parent.surfaceTemperature + pressure = self.parent.surfacePressure + tempRules = self.parent.returnAllRulesOfType(self.ruleType) + for rule in tempRules: + if rule.finalHeight > height: + height = rule.finalHeight + temperature = rule.finalValue + pressure = self.parent.pressureAtHeight(height) + return height, temperature, pressure + + def baseHeightCompositionRule(self, molecule): + height = 0 + pressure = self.parent.surfacePressure + concentration = molecule.concentration + compRules = self.parent.returnAllRulesOfType(self.ruleType) + for rule in compRules: + if rule.finalHeight > height and rule.molecule == molecule: + height = rule.finalHeight + concentration = rule.finalValue + return height, concentration, pressure + + def setBaseValues(self, ruleType, molecule): + if ruleType == 'temperature': + return self.baseHeightTemperatureRule() + elif ruleType == 'composition': + return self.baseHeightCompositionRule(molecule) + def returnPlot(obj, propertyToPlot): if propertyToPlot == "transmittance": diff --git a/pyradUtilities.py b/pyradUtilities.py index 13ed5c2..3da17a0 100644 --- a/pyradUtilities.py +++ b/pyradUtilities.py @@ -2,7 +2,7 @@ import sys import urllib.request as urlrequest import urllib.error as urlexception -import datetime +from datetime import datetime import numpy as np @@ -13,12 +13,48 @@ molParamsFile = '%s/molparams.txt' % dataDir profileDir = '/%s/profiles' % dataDir debuggerFilePath = '%s/logger.txt' % cwd -now = datetime.datetime.now() +now = datetime.now() debuggerFile = open(debuggerFilePath, 'wb') debuggerFile.write(bytes('%s\n' % now.strftime("%Y-%m-%d %H:%M:%S"), 'utf-8')) debuggerFile.close() +class Settings: + def __init__(self, setting='mid'): + self.setting = setting + + @property + def baseRes(self): + if self.setting == 'low': + return .1 + elif self.setting == 'mid': + return .01 + elif self.setting == 'hi': + return .01 + + @property + def lineIntensityCutoff(self): + if self.setting == 'low': + return 1E-30 + elif self.setting == 'mid': + return 1E-20 + elif self.setting == 'hi': + return 0.0 + + @property + def smoothing(self): + if self.setting == 'low': + return 1 + elif self.setting == 'mid': + return 50 + elif self.setting == 'hi': + return 100 + + +settings = Settings('mid') + + + def magentaText(text): return '%s%s%s' % (TEXT_COLORS['regularMagenta'], text, TEXT_COLORS['colorEnd']) @@ -112,28 +148,71 @@ def writePlanetProfile(name, layer): ','.join(map(str, layer.absCoef.tolist())))) openFile.write(text.encode('utf-8')) openFile.close() - print('absCoef written to profiles/%s.pyr' % layer.name) + print('\n\tprofile written to %s.pyr' % layer.name) return -def checkPlanetProfile(name, length): +def getProfileList(): + fileList = os.listdir(cwd) + profileFiles = [] + for file in profileFiles: + if '.pyr' in file: + profileFiles.append(file) + return fileList + + +def checkPlanetProfile(name): folderPath = '%s/%s' % (profileDir, name) if not os.path.isdir(folderPath): os.mkdir(folderPath) return False else: - for i in range(1, length + 1): - fileName = 'Layer %s:%s' % (i, length) - filePath = '%s/%s.pyr' % (folderPath, fileName) - if not os.path.isfile(filePath): - print('%s missing' % fileName) - return False - return True + fileName = 'completeProfile.pyr' + filePath = '%s/%s' % (folderPath, fileName) + if os.path.isfile(filePath): + return True + else: + return False def profileLength(name): folderPath = '%s/%s' % (profileDir, name) - return len(os.listdir(folderPath)) + fileList = os.listdir(folderPath) + count = 0 + for file in fileList: + if 'Layer' in file: + count += 1 + return count + + +def profileWriteProgress(name, completed, expected): + folderPath = '%s/%s' % (profileDir, name) + fileName = 'profileProgress.pyr' + filePath = '%s/%s' % (folderPath, fileName) + openFile = open(filePath, 'wb') + text = '# profile progess for %s\n' \ + 'completed: %s\n' \ + 'expected: %s' % (name, completed, expected) + openFile.write(text.encode('utf-8')) + openFile.close() + return + + +def profileProgress(name): + folderPath = '%s/%s' % (profileDir, name) + fileName = 'profileProgress' + filePath = '%s/%s.pyr' % (folderPath, fileName) + if not os.path.isfile(filePath): + return False + lines = openReturnLines(filePath) + for line in lines: + if line[0] == '#': + pass + else: + cells = line.split(':') + if cells[0] == 'completed': + return int(cells[1]) + def emptyProfileDirectory(name): folderPath = '%s/%s' % (profileDir, name) @@ -144,11 +223,40 @@ def emptyProfileDirectory(name): os.removedirs(folderPath) return + +def profileComplete(name): + folderPath = '%s/%s' % (profileDir, name) + fileName = 'profileComplete' + filePath = '%s/%s.pyr' % (folderPath, fileName) + if os.path.isfile(filePath): + return True + return False + + +def profileWriteComplete(name, completed, expected): + folderPath = '%s/%s' % (profileDir, name) + fileName = 'profileComplete' + filePath = '%s/%s.pyr' % (folderPath, fileName) + time = datetime.now() + text = '# profile for %s completed on %s\n' \ + '# PyRad v%s\n' \ + 'expected: %s\n' \ + 'completed: %s' % (name, time.strftime("%Y-%m-%d %H:%M:%S"), VERSION, expected, completed) + openFile = open(filePath, 'wb') + openFile.write(text.encode('utf-8')) + openFile.close() + fileName = 'profileProgress' + filePath = '%s/%s.pyr' % (folderPath, fileName) + os.remove(filePath) + return + + def readPlanetProfile(name, layerNumber, length): folderPath = '%s/%s' % (profileDir, name) fileName = 'Layer %s:%s' % (layerNumber, length) filePath = '%s/%s.pyr' % (folderPath, fileName) lines = openReturnLines(filePath) + print('Reading profile from %s...' % fileName, end='\r', flush=True) layerDict = {} for line in lines: keyValue = line.split(':') From 0633b0bf9d2fb4c1beec20d0f45e12b2ab0fe796 Mon Sep 17 00:00:00 2001 From: Brad Schrag Date: Tue, 16 Oct 2018 23:49:23 -0500 Subject: [PATCH 06/43] few steps closer --- earth low simple.pyr | 21 ---------- earthlowsimple.pyr | 37 +++++++++++++++++ earthtransmission.py | 3 +- mars simple.pyr | 12 ++++++ pyrad.py | 99 ++++++++++++++++++++++++++++++++++---------- pyradUtilities.py | 72 +++++++++++++++++++++++++++----- test.py | 4 ++ 7 files changed, 192 insertions(+), 56 deletions(-) delete mode 100644 earth low simple.pyr create mode 100644 earthlowsimple.pyr create mode 100644 mars simple.pyr create mode 100644 test.py diff --git a/earth low simple.pyr b/earth low simple.pyr deleted file mode 100644 index 444a548..0000000 --- a/earth low simple.pyr +++ /dev/null @@ -1,21 +0,0 @@ -# A demo file for pyrad - -setting: low - -# mBar , K , km,cm-1,cm-1, m -surface: 1013.25, 288, 90, 500, 900, 100 - -molecule: co2, .000400 -molecule: h2o, .018000 -molecule: o3, 0 -molecule: o2, .21 -molecule: n2, .79 - -lapse rate: troposphere, 11, 216 -lapse rate: tropopause, 20, 216 -lapse rate: stratosphere 1, 32, 228 -lapse rate: stratosphere 2, 47, 270 -lapse rate: stratopause, 51, 270 -lapse rate: mesosphere 1, 71, 214 -lapse rate: mesosphere2, 80, 190 -lapse rate: mesopause, 90, 190 \ No newline at end of file diff --git a/earthlowsimple.pyr b/earthlowsimple.pyr new file mode 100644 index 0000000..f8c2e46 --- /dev/null +++ b/earthlowsimple.pyr @@ -0,0 +1,37 @@ +# A demo file for pyrad + +setting: low + +# mBar , K , km,cm-1,cm-1, m , g +surface: 1013.25, 300, 90, 500, 900, 100, 9.8 + +# mol text name, concentration +molecule: co2, .000400 +molecule: h2o, .018000 +#molecule: o3, 0 +molecule: o2, .20 +molecule: n2, .79 + +# name, endHeight, endTemp +lapse rate: troposphere, 11, 216 +lapse rate: tropopause, 20, 216 +lapse rate: stratosphere, 32, 228 +lapse rate: stratosphere, 47, 270 +lapse rate: stratopause, 51, 270 +lapse rate: mesosphere, 71, 214 +lapse rate: mesosphere2, 80, 190 +lapse rate: mesopause, 90, 190 + +# name, endHeight, endValue, moleculeName +composition rate: WV boundary layer, 2.5, 18000e-6, h2o +compostiion rate: WV troposphere1, 8, 200e-6, h2o +compostiion rate: WV troposphere2, 9, 400e-6, h2o +compostiion rate: WV troposphere2, 10, 400e-6, h2o +compostiion rate: WV tropopause', 20, 2e-6, h2o +compostiion rate: WV stratosphere to top',90, 0, h2o + +#composition rate: troposphere ozone, 16, 60E-9, o3 +#composition rate: tropopause ozone, 32, 5E-6, o3 +#composition rate: upper strat ozone, 60, 0, o3 +#composition rate: strat on up ozone, 90, 0, o3 + diff --git a/earthtransmission.py b/earthtransmission.py index 6e8081c..622f450 100644 --- a/earthtransmission.py +++ b/earthtransmission.py @@ -30,7 +30,8 @@ h2o = earth.addMolecule('h2o', ppm=20000) n2 = earth.addMolecule('n2', percentage=76.9) o2 = earth.addMolecule('o2', percentage=19.9) -#o3 = earth.addMolecule('o3', ppb=0) +o3 = earth.addMolecule('o3', ppb=0) +ch4 = earth.addMolecule('ch4', ppb=1800) wvCP1 = 2.5 wvCP2 = 8 diff --git a/mars simple.pyr b/mars simple.pyr new file mode 100644 index 0000000..2a29fff --- /dev/null +++ b/mars simple.pyr @@ -0,0 +1,12 @@ +# mars simple + +setting: hi + +surface: 6, 220, 90, 100, 1500, 200, 3.711 + +molecule: co2, .9532 +molecule: n2, .027 +molecule: o2, .0013 + +lapse rate: first layer, 45, 100 +lapse rate: final layer, 90, 100 \ No newline at end of file diff --git a/pyrad.py b/pyrad.py index 1fb2944..f0c2339 100644 --- a/pyrad.py +++ b/pyrad.py @@ -17,6 +17,39 @@ p0 = 1013.25 avo = 6.022140857E23 +settings = utils.Settings('low') + +def createCustomPlanet(name): + + initialParameters = utils.parseCustomProfile(name) + initialValues = initialParameters['initialValues'] + moleculeList = initialParameters['molecules'] + temperatureRuleList = initialParameters['temperatureRules'] + compositionRuleList = initialParameters['compositionRules'] + + try: + value = initialParameters['setting'] + except KeyError: + value = 'low' + + settings.changeSetting(value) + planet = Planet(initialParameters['name'], initialValues['surfacePressure'], initialValues['surfaceTemperature'], + initialValues['maxHeight'], rangeMin=initialValues['rangeMin'], + rangeMax=initialValues['rangeMax'], initialThickness=initialValues['initialDepth'], gravity=initialValues['gravity']) + + for molecule in moleculeList: + planet.addMolecule(molecule['name'], concentration=molecule['concentration']) + + for rule in temperatureRuleList: + planet.addLapseRate(rule['name'], rule['finalHeight'], rule['finalValue']) + + for rule in compositionRuleList: + initalLayer = planet.initialLayer + molecule = initalLayer.returnMolecule(rule['moleculeName']) + planet.addCompositionRate(rule['name'], rule['finalHeight'], rule['finalValue'], molecule) + return planet + + def yesOrNo(promptText): validInput = False @@ -289,8 +322,7 @@ def getData(self, lineSurvey=False, verbose=True): lineDict = utils.gatherData(self.globalIsoNumber, self.layer.effectiveRangeMin, self.layer.effectiveRangeMax) self.q = utils.getQData(self.globalIsoNumber) for line in lineDict: - # need to soft code the intensity value, depending on resolution setting - if lineDict[line]['intensity'] > 1E-22: + if lineDict[line]['intensity'] > settings.lineIntensityCutoff: self.append(Line(line, lineDict[line]['intensity'], lineDict[line]['einsteinA'], lineDict[line]['airHalfWidth'], lineDict[line]['selfHalfWidth'], lineDict[line]['lowerEnergy'], lineDict[line]['tempExponent'], @@ -312,7 +344,7 @@ def createCrossSection(self): return for line in self: if progress > i * alertInterval and len(self) > 50: - text = 'Processing %s, height %skm, molecule %s: <%s%s>' % (layer.name, round(layer.height / 100000, 2), + text = 'Processing %s, height %skm, mean height %skm, molecule %s: <%s%s>' % (layer.name, round(layer.height / 100000, 2), round(layer.meanHeight / 100000, 2), molecule.name, '*' * i, '-' * (20 - i)) print(text, end='\r', flush=True) i += 1 @@ -653,7 +685,8 @@ def molarMass(self): @property def density(self): - return self.P * 100 / self.T / self.specGasConstant + d = self.P * 100 / self.T / self.specGasConstant + return d @property def mass(self): @@ -661,7 +694,8 @@ def mass(self): @property def specGasConstant(self): - return R * 1000 / self.molarMass + con = R * 1000 / self.molarMass + return con @property def temperatureAtHeight(self): @@ -892,32 +926,47 @@ def addMolecule(self, name, isotopeDepth=1, **abundance): def sliceAtm(self, verify=True): acceptSetup = False - height = 0 + layer = self.initialLayer + initialTemp = layer.T + initialPressure = layer.P + initialHeight = layer.height + initialDepth = layer.depth while not acceptSetup: mass = self.initialLayer.mass - layer = self.initialLayer - print('%s, p %s, T %s, depth %s, height %s' % (layer.name, layer.P, layer.T, layer.depth, layer.height)) - self.heightList = [height] + print('%s, p %s, T %s, depth %s, height %s' % (layer.name, initialPressure, initialTemp, initialDepth, initialHeight)) + self.heightList = [layer.height] tempList = [layer.T] pressureList = [layer.P] self.depthList = [layer.depth] while layer.height + layer.depth < self.maxHeight: - print('%s: K: %s, mBar: %s, baseHeight: %skm, depth : %skm, layMass: %s' % ( + print('%s: K: %s, mBar: %s, baseHeight: %skm, depth: %skm, mass: %skg' % ( 'Layer %s' %len(self.heightList), int(layer.T), round(layer.P, 2), round(layer.height / 100000, 2), round(layer.depth / 100000, 2), round(layer.mass, 2))) newHeight = self.heightList[-1] + self.depthList[-1] - self.heightList.append(newHeight) tempList.append(self.temperatureAtHeight(newHeight)) pressureList.append(self.pressureAtHeight(newHeight)) layer.P = pressureList[-1] layer.T = tempList[-1] - layer.height = self.heightList[-1] - layer.depth = (mass / layer.density * 100) - if layer.depth != 0: - self.depthList.append(layer.depth) + newDepth = (mass / layer.density * 100) + if newHeight + newDepth > self.maxHeight: + newDepth = self.maxHeight - newHeight + self.heightList.append(newHeight) + self.depthList.append(newDepth) + print('%s: K: %s, mBar: %s, baseHeight: %skm, depth: %skm, mass: %skg' % ( + 'Layer %s' % len(self.heightList), int(layer.T), round(layer.P, 2), + round(newHeight / 100000, 2), round(newDepth / 100000, 2), round(layer.mass, 2))) + print(self.heightList) + input('') + break + else: + self.heightList.append(newHeight) + self.depthList.append(newDepth) + layer.height = newHeight + layer.depth = newDepth if self.heightList[-1] + .5 * self.depthList[-1] > self.maxHeight: self.heightList.pop() self.depthList.pop() print('Total # of layers: %s' % len(self.heightList)) + print('Total # of absorption lines per layer: %s' % len(totalLineList(layer))) if verify: if yesOrNo('Accept the current slicing (y/n): '): acceptSetup = True @@ -926,10 +975,13 @@ def sliceAtm(self, verify=True): while not validNumber: print( 'Enter the new initial depth. Larger depth will decrease number of layers, smaller will increase') - userNumber = input('Current depth is %scm:' % utils.limeText(self.initialLayer.depth)) + userNumber = input('Current depth is %s:' % utils.limeText('%sm' % (int(self.depthList[0]) / 100))) try: newDepth = float(userNumber) - self.initialLayer.depth = newDepth + self.initialLayer.depth = newDepth * 100 + self.initialLayer.P = initialPressure + self.initialLayer.T = initialTemp + self.initialLayer.height = initialHeight validNumber = True except ValueError: print('Invalid number.') @@ -978,7 +1030,7 @@ def loadProfile(self): self.atmosphere.pop() for i in range(1, fileLength + 1): lP = utils.readPlanetProfile(self.name, i, fileLength) - layer = Layer(lP['depth'], lP['T'], lP['P'], lP['rangeMin'], lP['rangeMax'], name=lP['name']) + layer = Layer(lP['depth'], lP['T'], lP['P'], lP['rangeMin'], lP['rangeMax'], height=lP['height'], name=lP['name']) self.atmosphere.append(layer) layer.absorptionCoefficient = np.asarray(lP['absCoef']) layer.progressAbsCoef = True @@ -989,23 +1041,24 @@ def loadProfile(self): def processTransmission(self, height, direction='down'): if not self.progressProfileLoaded: self.loadProfile() + height = height * 100000 surfaceSpectrum = pyradPlanck.planckWavenumber(self.initialLayer.xAxis, self.surfaceTemperature) print('Processing atmosphere spectrum from %s looking %s...' % (height / 100000, direction)) for layer in self.atmosphere: if layer.meanHeight < height: surfaceSpectrum = layer.transmission(surfaceSpectrum) - print('Processing %s...' % layer.name, end='\r', flush=True) + print('Processing %s...%s, %s' % (layer.name, layer.meanHeight, layer.height), end='\n', flush=True) print('') print('total power of spectrum: %sWm-2' % int((integrateSpectrum(surfaceSpectrum) / 5.67E-8)**.25)) plt.plot(self.initialLayer.xAxis, smooth(surfaceSpectrum, 50), linewidth=.5) plt.plot(self.initialLayer.xAxis, - pyradPlanck.planckWavenumber(self.initialLayer.xAxis, self.surfaceTemperature), linewidth=.5) + pyradPlanck.planckWavenumber(self.initialLayer.xAxis, self.surfaceTemperature + 5), linewidth=.5) plt.plot(self.initialLayer.xAxis, - pyradPlanck.planckWavenumber(self.initialLayer.xAxis, 280), linewidth=.5) + pyradPlanck.planckWavenumber(self.initialLayer.xAxis, self.surfaceTemperature - 20), linewidth=.5) plt.plot(self.initialLayer.xAxis, - pyradPlanck.planckWavenumber(self.initialLayer.xAxis, 260), linewidth=.5) + pyradPlanck.planckWavenumber(self.initialLayer.xAxis, self.surfaceTemperature - 30), linewidth=.5) plt.plot(self.initialLayer.xAxis, - pyradPlanck.planckWavenumber(self.initialLayer.xAxis, 240), linewidth=.5) + pyradPlanck.planckWavenumber(self.initialLayer.xAxis, self.surfaceTemperature - 40), linewidth=.5) plt.show() return surfaceSpectrum diff --git a/pyradUtilities.py b/pyradUtilities.py index 3da17a0..50e3bbd 100644 --- a/pyradUtilities.py +++ b/pyradUtilities.py @@ -20,9 +20,12 @@ class Settings: - def __init__(self, setting='mid'): + def __init__(self, setting): self.setting = setting + def changeSetting(self, value): + self.setting = value + @property def baseRes(self): if self.setting == 'low': @@ -35,9 +38,9 @@ def baseRes(self): @property def lineIntensityCutoff(self): if self.setting == 'low': - return 1E-30 + return 1E-22 elif self.setting == 'mid': - return 1E-20 + return 1E-25 elif self.setting == 'hi': return 0.0 @@ -51,10 +54,6 @@ def smoothing(self): return 100 -settings = Settings('mid') - - - def magentaText(text): return '%s%s%s' % (TEXT_COLORS['regularMagenta'], text, TEXT_COLORS['colorEnd']) @@ -148,7 +147,7 @@ def writePlanetProfile(name, layer): ','.join(map(str, layer.absCoef.tolist())))) openFile.write(text.encode('utf-8')) openFile.close() - print('\n\tprofile written to %s.pyr' % layer.name) + print('\n\t\t\tprofile written to %s.pyr' % layer.name) return @@ -175,6 +174,55 @@ def checkPlanetProfile(name): return False +def parseCustomProfile(name): + filePath = '%s/%s.pyr' % (cwd, name) + lines = openReturnLines(filePath) + params = {'compositionRules': [], + 'temperatureRules': [], + 'molecules': [], + 'name': name} + for line in lines: + if line[0] == '#' or line == '': + pass + elif 'composition' in line.lower() or 'lapse' in line.lower(): + tempDict = {} + values = line.split(':')[1].split(',') + tempDict['name'] = values[0] + tempDict['finalHeight'] = float(values[1]) + tempDict['finalValue'] = float(values[2]) + if len(values) > 3: + tempDict['moleculeName'] = values[3].strip() + if 'composition' in line.lower(): + params['compositionRules'].append(tempDict) + elif 'lapse' in line.lower(): + params['temperatureRules'].append(tempDict) + elif 'surface' in line.lower(): + tempDict = {} + values = line.split(':')[1].split(',') + tempDict['surfacePressure'] = float(values[0]) + tempDict['surfaceTemperature'] = int(values[1]) + tempDict['maxHeight'] = float(values[2]) + tempDict['rangeMin'] = int(values[3]) + tempDict['rangeMax'] = int(values[4]) + tempDict['initialDepth'] = float(values[5]) + tempDict['gravity'] = float(values[6]) + params['initialValues'] = tempDict + elif 'setting' in line.lower(): + value = line.split(':')[1].lower() + params['setting'] = value.lower().strip() + elif 'molecule' in line.lower(): + values = line.split(':')[1].split(',') + try: + concentration = float(values[1]) + except ValueError: + print('invalid concentration %s in %s' % (values[1], filePath)) + exit() + tempDict = {'name': values[0].lower().strip(), + 'concentration': concentration} + params['molecules'].append(tempDict) + return params + + def profileLength(name): folderPath = '%s/%s' % (profileDir, name) fileList = os.listdir(folderPath) @@ -262,16 +310,18 @@ def readPlanetProfile(name, layerNumber, length): keyValue = line.split(':') if line[0] == '#': pass - elif keyValue[0] == 'name': + elif keyValue[0].strip() == 'name': layerDict[keyValue[0]] = keyValue[1] - elif keyValue[0] == 'absCoef': + elif keyValue[0].strip() == 'absCoef': absList = keyValue[1].split(',') absCoefList = [] for value in absList: absCoefList.append(float(value)) layerDict[keyValue[0]] = absCoefList - elif keyValue[0] == 'T' or keyValue[0] == 'rangeMin' or keyValue[0] == 'rangeMax': + elif keyValue[0].strip() == 'T' or keyValue[0] == 'rangeMin' or keyValue[0] == 'rangeMax': layerDict[keyValue[0]] = int(keyValue[1]) + elif keyValue[0].strip() == 'height': + layerDict[keyValue[0]] = float(keyValue[1]) else: layerDict[keyValue[0]] = float(keyValue[1]) return layerDict diff --git a/test.py b/test.py new file mode 100644 index 0000000..7e86531 --- /dev/null +++ b/test.py @@ -0,0 +1,4 @@ +import pyrad + +planet = pyrad.createCustomPlanet('mars simple') +planet.processTransmission(65) \ No newline at end of file From e3f7c42e4abc3b863e5382c77822310335cdf06e Mon Sep 17 00:00:00 2001 From: Brad Schrag Date: Tue, 16 Oct 2018 23:57:12 -0500 Subject: [PATCH 07/43] removed print statement --- earthmidfull.pyr | 0 pyrad.py | 1 - 2 files changed, 1 deletion(-) create mode 100644 earthmidfull.pyr diff --git a/earthmidfull.pyr b/earthmidfull.pyr new file mode 100644 index 0000000..e69de29 diff --git a/pyrad.py b/pyrad.py index f0c2339..52cc5d9 100644 --- a/pyrad.py +++ b/pyrad.py @@ -954,7 +954,6 @@ def sliceAtm(self, verify=True): print('%s: K: %s, mBar: %s, baseHeight: %skm, depth: %skm, mass: %skg' % ( 'Layer %s' % len(self.heightList), int(layer.T), round(layer.P, 2), round(newHeight / 100000, 2), round(newDepth / 100000, 2), round(layer.mass, 2))) - print(self.heightList) input('') break else: From 772de7d2472ce5de276705b9dd46c5ea262ac040 Mon Sep 17 00:00:00 2001 From: Brad Schrag Date: Tue, 16 Oct 2018 23:58:12 -0500 Subject: [PATCH 08/43] removed input statement --- pyrad.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pyrad.py b/pyrad.py index 52cc5d9..4b04e42 100644 --- a/pyrad.py +++ b/pyrad.py @@ -954,7 +954,6 @@ def sliceAtm(self, verify=True): print('%s: K: %s, mBar: %s, baseHeight: %skm, depth: %skm, mass: %skg' % ( 'Layer %s' % len(self.heightList), int(layer.T), round(layer.P, 2), round(newHeight / 100000, 2), round(newDepth / 100000, 2), round(layer.mass, 2))) - input('') break else: self.heightList.append(newHeight) From b1fb7c634c451b667b3b91eb70723cf5344fc573 Mon Sep 17 00:00:00 2001 From: Brad Schrag Date: Wed, 17 Oct 2018 11:39:47 -0500 Subject: [PATCH 09/43] backing up, seem to have found a bug and need to revert to check --- earthmidfull.pyr => earth lo 500-1000.pyr | 0 earthlowsimple.pyr => earth low simple.pyr | 13 +++--- earth mid simple.pyr | 37 +++++++++++++++++ earthtransmission.py | 2 +- pyrad.py | 47 +++++++++++++++++++--- test.py | 13 +++++- 6 files changed, 97 insertions(+), 15 deletions(-) rename earthmidfull.pyr => earth lo 500-1000.pyr (100%) rename earthlowsimple.pyr => earth low simple.pyr (75%) create mode 100644 earth mid simple.pyr diff --git a/earthmidfull.pyr b/earth lo 500-1000.pyr similarity index 100% rename from earthmidfull.pyr rename to earth lo 500-1000.pyr diff --git a/earthlowsimple.pyr b/earth low simple.pyr similarity index 75% rename from earthlowsimple.pyr rename to earth low simple.pyr index f8c2e46..b05b8f8 100644 --- a/earthlowsimple.pyr +++ b/earth low simple.pyr @@ -8,9 +8,10 @@ surface: 1013.25, 300, 90, 500, 900, 100, 9.8 # mol text name, concentration molecule: co2, .000400 molecule: h2o, .018000 -#molecule: o3, 0 +molecule: o3, 0 molecule: o2, .20 molecule: n2, .79 +molecule: ch4, .0000018 # name, endHeight, endTemp lapse rate: troposphere, 11, 216 @@ -24,11 +25,11 @@ lapse rate: mesopause, 90, 190 # name, endHeight, endValue, moleculeName composition rate: WV boundary layer, 2.5, 18000e-6, h2o -compostiion rate: WV troposphere1, 8, 200e-6, h2o -compostiion rate: WV troposphere2, 9, 400e-6, h2o -compostiion rate: WV troposphere2, 10, 400e-6, h2o -compostiion rate: WV tropopause', 20, 2e-6, h2o -compostiion rate: WV stratosphere to top',90, 0, h2o +composition rate: WV troposphere1, 8, 200e-6, h2o +composition rate: WV troposphere2, 9, 400e-6, h2o +composition rate: WV troposphere2, 10, 400e-6, h2o +composition rate: WV tropopause', 20, 2e-6, h2o +composition rate: WV stratosphere to top',90, 0, h2o #composition rate: troposphere ozone, 16, 60E-9, o3 #composition rate: tropopause ozone, 32, 5E-6, o3 diff --git a/earth mid simple.pyr b/earth mid simple.pyr new file mode 100644 index 0000000..3b215a5 --- /dev/null +++ b/earth mid simple.pyr @@ -0,0 +1,37 @@ +# A demo file for pyrad + +setting: mid + +# mBar , K , km,cm-1,cm-1, m , g +surface: 1013.25, 300, 90, 0, 2000, 100, 9.8 + +# mol text name, concentration +molecule: co2, .000400 +molecule: h2o, .018000 +molecule: o3, 0 +molecule: o2, .20 +molecule: n2, .78 +molecule: ch4, .0000018 + +# name, endHeight, endTemp +lapse rate: troposphere, 11, 216 +lapse rate: tropopause, 20, 216 +lapse rate: stratosphere, 32, 228 +lapse rate: stratosphere, 47, 270 +lapse rate: stratopause, 51, 270 +lapse rate: mesosphere, 71, 214 +lapse rate: mesosphere2, 80, 190 +lapse rate: mesopause, 90, 190 + +# name, endHeight, endValue, moleculeName +composition rate: WV boundary layer, 2.5, 18000e-6, h2o +composition rate: WV troposphere1, 8, 200e-6, h2o +composition rate: WV troposphere2, 9, 400e-6, h2o +composition rate: WV troposphere2, 10, 400e-6, h2o +composition rate: WV tropopause', 20, 2e-6, h2o +composition rate: WV stratosphere to top',90, 0, h2o + +#composition rate: troposphere ozone, 16, 60E-9, o3 +#composition rate: tropopause ozone, 32, 5E-6, o3 +#composition rate: upper strat ozone, 60, 0, o3 +#composition rate: strat on up ozone, 90, 0, o3 diff --git a/earthtransmission.py b/earthtransmission.py index 622f450..b1bab49 100644 --- a/earthtransmission.py +++ b/earthtransmission.py @@ -65,7 +65,7 @@ plt.plot(xAxis, yAxis) plt.show()''' -earth.processTransmission(90E5) +earth.processTransmission(90) """ diff --git a/pyrad.py b/pyrad.py index 4b04e42..a14a029 100644 --- a/pyrad.py +++ b/pyrad.py @@ -50,7 +50,6 @@ def createCustomPlanet(name): return planet - def yesOrNo(promptText): validInput = False while not validInput: @@ -851,6 +850,7 @@ def __init__(self, name, pressure, temperature, maxHeight, molarMass=0.0289644, self.mass = 0 self.gravity = gravity self.maxHeight = maxHeight * 100000 + print('maxHeight in cm: %s' % self.maxHeight) self.molarMass = molarMass self.radius = 0 self.surfacePressure = pressure @@ -953,16 +953,16 @@ def sliceAtm(self, verify=True): self.depthList.append(newDepth) print('%s: K: %s, mBar: %s, baseHeight: %skm, depth: %skm, mass: %skg' % ( 'Layer %s' % len(self.heightList), int(layer.T), round(layer.P, 2), - round(newHeight / 100000, 2), round(newDepth / 100000, 2), round(layer.mass, 2))) + round(newHeight, 2), round(newDepth, 2), round(layer.mass, 2))) break else: self.heightList.append(newHeight) self.depthList.append(newDepth) layer.height = newHeight layer.depth = newDepth - if self.heightList[-1] + .5 * self.depthList[-1] > self.maxHeight: + '''if self.heightList[-1] + .5 * self.depthList[-1] > self.maxHeight: self.heightList.pop() - self.depthList.pop() + self.depthList.pop()''' print('Total # of layers: %s' % len(self.heightList)) print('Total # of absorption lines per layer: %s' % len(totalLineList(layer))) if verify: @@ -1041,11 +1041,11 @@ def processTransmission(self, height, direction='down'): self.loadProfile() height = height * 100000 surfaceSpectrum = pyradPlanck.planckWavenumber(self.initialLayer.xAxis, self.surfaceTemperature) - print('Processing atmosphere spectrum from %s looking %s...' % (height / 100000, direction)) + print('Processing atmosphere spectrum from %skm looking %s...' % (height / 100000, direction)) for layer in self.atmosphere: if layer.meanHeight < height: surfaceSpectrum = layer.transmission(surfaceSpectrum) - print('Processing %s...%s, %s' % (layer.name, layer.meanHeight, layer.height), end='\n', flush=True) + print('Processing %s...%s, %s, %s' % (layer.name, round(layer.height / 100000, 4), round(layer.meanHeight / 100000, 4), round(layer.depth / 100000, 4)), end='\n', flush=True) print('') print('total power of spectrum: %sWm-2' % int((integrateSpectrum(surfaceSpectrum) / 5.67E-8)**.25)) plt.plot(self.initialLayer.xAxis, smooth(surfaceSpectrum, 50), linewidth=.5) @@ -1252,6 +1252,41 @@ def plotSpectrum(layer=None, title=None, rangeMin=None, rangeMax=None, objList=N plt.show() +def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=[300, 270, 240, 210]): + linewidth = .5 + alpha = .8 + plt.figure(figsize=(10, 6), dpi=80) + plt.subplot(111, facecolor='xkcd:dark grey') + plt.margins(0.01) + plt.subplots_adjust(left=.07, bottom=.08, right=.97, top=.90) + plt.ylabel('Radiance Wm-2sr-1(cm-1)-1') + handles = [] + heightFlag = True + if not height: + heightFlag = False + for planet, color in zip(planets, COLOR_LIST[1:]): + if not heightFlag: + height = planet.maxHeight + print('plot height is: %s' % height) + xAxis = planet.xAxis + yAxis = planet.processTransmission(height, direction) + fig, = plt.plot(xAxis, smooth(yAxis, 50), linewidth=linewidth, + alpha=alpha, color=color, + label='%s : %sWm-2' % (planet.name, round(integrateSpectrum(yAxis, pi), 2))) + handles.append(fig) + for temperature in temperatureList: + yAxis = pyradPlanck.planckWavenumber(xAxis, float(temperature)) + fig, = plt.plot(xAxis, yAxis, linewidth=.75, color='grey', + linestyle=':', label='%sK : %sWm-2' % + (temperature, + round(integrateSpectrum(yAxis, pi), 2))) + handles.append(fig) + legend = plt.legend(handles=handles, frameon=False) + text = legend.get_texts() + plt.setp(text, color='w') + plt.show() + + def cacheCurves(): ls.writeCacheToFile() diff --git a/test.py b/test.py index 7e86531..139dbd7 100644 --- a/test.py +++ b/test.py @@ -1,4 +1,13 @@ +import numpy as np import pyrad +from matplotlib import pyplot as plt -planet = pyrad.createCustomPlanet('mars simple') -planet.processTransmission(65) \ No newline at end of file +planet = pyrad.createCustomPlanet('earth lo 500-1000') +yAxis = np.arange(1, 90000, 1) +xAxis = [] +'''for height in yAxis: + xAxis.append(planet.temperatureAtHeight(height*100)) +plt.plot(xAxis, yAxis) +plt.show()''' +#planet2 = pyrad.createCustomPlanet('mars simple') +pyrad.plotPlanetSpectrum([planet], 90) \ No newline at end of file From a9133db8a4ad69ea03b854f0ed531916621d7f75 Mon Sep 17 00:00:00 2001 From: Brad Schrag Date: Fri, 19 Oct 2018 11:19:52 -0500 Subject: [PATCH 10/43] touched up some ui issues --- pyrad.py | 75 +++++++++++++++++++++++------------------------ pyradPlanck.py | 2 +- pyradUtilities.py | 10 +++---- test.py | 12 ++++---- 4 files changed, 49 insertions(+), 50 deletions(-) diff --git a/pyrad.py b/pyrad.py index a14a029..c5a434b 100644 --- a/pyrad.py +++ b/pyrad.py @@ -16,6 +16,7 @@ t0 = 296 p0 = 1013.25 avo = 6.022140857E23 +sb = 5.67E-8 settings = utils.Settings('low') @@ -850,7 +851,6 @@ def __init__(self, name, pressure, temperature, maxHeight, molarMass=0.0289644, self.mass = 0 self.gravity = gravity self.maxHeight = maxHeight * 100000 - print('maxHeight in cm: %s' % self.maxHeight) self.molarMass = molarMass self.radius = 0 self.surfacePressure = pressure @@ -987,11 +987,11 @@ def sliceAtm(self, verify=True): acceptSetup = True return - def processLayers(self): + def processLayers(self, verify=True): if utils.profileProgress(self.name): self.sliceAtm(verify=False) if not self.heightList: - self.sliceAtm() + self.sliceAtm(verify=verify) layer = self.initialLayer startPoint = utils.profileProgress(self.name) i = startPoint + 1 @@ -1014,13 +1014,14 @@ def processLayers(self): utils.profileWriteComplete(self.name, i, len(self.heightList)) return - def loadProfile(self): + def loadProfile(self, verify=True): if utils.profileComplete(self.name): fileLength = utils.profileLength(self.name) - if not yesOrNo('%s layers found for profile %s. Load profile (y/n):' % (fileLength, self.name)): - if yesOrNo('Are you sure, selecting yes will delete all previous profile data (y/n): '): - utils.emptyProfileDirectory(self.name) - self.processLayers() + if verify: + if not yesOrNo('%s layers found for profile %s. Load profile (y/n):' % (fileLength, self.name)): + if yesOrNo('Are you sure, selecting yes will delete all previous profile data (y/n): '): + utils.emptyProfileDirectory(self.name) + self.processLayers() else: self.processLayers() fileLength = utils.profileLength(self.name) @@ -1036,28 +1037,25 @@ def loadProfile(self): self.progressProfileLoaded = True return - def processTransmission(self, height, direction='down'): + def processTransmission(self, height, direction='down', verify=True): if not self.progressProfileLoaded: - self.loadProfile() + self.loadProfile(verify=verify) height = height * 100000 - surfaceSpectrum = pyradPlanck.planckWavenumber(self.initialLayer.xAxis, self.surfaceTemperature) print('Processing atmosphere spectrum from %skm looking %s...' % (height / 100000, direction)) - for layer in self.atmosphere: - if layer.meanHeight < height: - surfaceSpectrum = layer.transmission(surfaceSpectrum) - print('Processing %s...%s, %s, %s' % (layer.name, round(layer.height / 100000, 4), round(layer.meanHeight / 100000, 4), round(layer.depth / 100000, 4)), end='\n', flush=True) + if direction == 'down': + surfaceSpectrum = pyradPlanck.planckWavenumber(self.initialLayer.xAxis, self.surfaceTemperature) + for layer in self.atmosphere: + if layer.meanHeight < height: + surfaceSpectrum = layer.transmission(surfaceSpectrum) + print('Processing %s...' % (layer.name), end='\r', flush=True) + elif direction == 'up': + surfaceSpectrum = pyradPlanck.planckWavenumber(self.initialLayer.xAxis, 3) + for layer in reversed(self.atmosphere): + if layer.meanHeight > height: + surfaceSpectrum = layer.transmission(surfaceSpectrum) + print('Processing %s...\n' % (layer.name), layer.T, end='\r', flush=True) print('') print('total power of spectrum: %sWm-2' % int((integrateSpectrum(surfaceSpectrum) / 5.67E-8)**.25)) - plt.plot(self.initialLayer.xAxis, smooth(surfaceSpectrum, 50), linewidth=.5) - plt.plot(self.initialLayer.xAxis, - pyradPlanck.planckWavenumber(self.initialLayer.xAxis, self.surfaceTemperature + 5), linewidth=.5) - plt.plot(self.initialLayer.xAxis, - pyradPlanck.planckWavenumber(self.initialLayer.xAxis, self.surfaceTemperature - 20), linewidth=.5) - plt.plot(self.initialLayer.xAxis, - pyradPlanck.planckWavenumber(self.initialLayer.xAxis, self.surfaceTemperature - 30), linewidth=.5) - plt.plot(self.initialLayer.xAxis, - pyradPlanck.planckWavenumber(self.initialLayer.xAxis, self.surfaceTemperature - 40), linewidth=.5) - plt.show() return surfaceSpectrum @property @@ -1081,6 +1079,10 @@ def transmission(self): return self.processTransmission(self.maxHeight) +def stefanB(power): + return (power / sb) ^ .25 + + class AtmosphereRule: def __init__(self, name, finalHeight, finalValue, ruleType, planetClass, molecule=None, rateFunction=linear): self.name = name @@ -1252,45 +1254,42 @@ def plotSpectrum(layer=None, title=None, rangeMin=None, rangeMax=None, objList=N plt.show() -def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=[300, 270, 240, 210]): +def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=[300, 280, 250, 210, 170], verify=True, integrateRange=[]): linewidth = .5 - alpha = .8 + alpha = .7 plt.figure(figsize=(10, 6), dpi=80) - plt.subplot(111, facecolor='xkcd:dark grey') + plt.subplot(111, facecolor='xkcd:almost black') plt.margins(0.01) plt.subplots_adjust(left=.07, bottom=.08, right=.97, top=.90) plt.ylabel('Radiance Wm-2sr-1(cm-1)-1') handles = [] heightFlag = True - if not height: + if height is None: heightFlag = False for planet, color in zip(planets, COLOR_LIST[1:]): if not heightFlag: - height = planet.maxHeight - print('plot height is: %s' % height) + height = planet.maxHeight / 100000 xAxis = planet.xAxis - yAxis = planet.processTransmission(height, direction) - fig, = plt.plot(xAxis, smooth(yAxis, 50), linewidth=linewidth, + yAxis = planet.processTransmission(height, direction=direction, verify=verify) + fig, = plt.plot(xAxis, smooth(yAxis, 75), linewidth=linewidth, alpha=alpha, color=color, label='%s : %sWm-2' % (planet.name, round(integrateSpectrum(yAxis, pi), 2))) handles.append(fig) + color = 1 for temperature in temperatureList: yAxis = pyradPlanck.planckWavenumber(xAxis, float(temperature)) - fig, = plt.plot(xAxis, yAxis, linewidth=.75, color='grey', + fig, = plt.plot(xAxis, yAxis, linewidth=.75, color=(color, color, color), alpha=alpha, linestyle=':', label='%sK : %sWm-2' % (temperature, round(integrateSpectrum(yAxis, pi), 2))) handles.append(fig) + color -= .15 legend = plt.legend(handles=handles, frameon=False) text = legend.get_texts() plt.setp(text, color='w') plt.show() -def cacheCurves(): - ls.writeCacheToFile() - - HITRAN_GLOBAL_ISO = {1: {1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 129}, 2: {1: 7, 2: 8, 3: 9, 4: 10, 5: 11, 6: 12, 7: 13, 8: 14, 9: 121, 10: 15, 11: 120, 12: 122}, 3: {1: 16, 2: 17, 3: 18, 4: 19, 5: 20}, diff --git a/pyradPlanck.py b/pyradPlanck.py index d534a52..81391fa 100644 --- a/pyradPlanck.py +++ b/pyradPlanck.py @@ -1,5 +1,5 @@ import numpy as np -np.seterr(divide='ignore', invalid='ignore') +np.seterr(divide='ignore', invalid='ignore', over='ignore') k = 1.38064852E-23 c = 299792458.0 diff --git a/pyradUtilities.py b/pyradUtilities.py index 50e3bbd..ff8c936 100644 --- a/pyradUtilities.py +++ b/pyradUtilities.py @@ -38,9 +38,9 @@ def baseRes(self): @property def lineIntensityCutoff(self): if self.setting == 'low': - return 1E-22 + return 1E-21 elif self.setting == 'mid': - return 1E-25 + return 1E-28 elif self.setting == 'hi': return 0.0 @@ -187,7 +187,7 @@ def parseCustomProfile(name): elif 'composition' in line.lower() or 'lapse' in line.lower(): tempDict = {} values = line.split(':')[1].split(',') - tempDict['name'] = values[0] + tempDict['name'] = values[0].strip() tempDict['finalHeight'] = float(values[1]) tempDict['finalValue'] = float(values[2]) if len(values) > 3: @@ -304,14 +304,14 @@ def readPlanetProfile(name, layerNumber, length): fileName = 'Layer %s:%s' % (layerNumber, length) filePath = '%s/%s.pyr' % (folderPath, fileName) lines = openReturnLines(filePath) - print('Reading profile from %s...' % fileName, end='\r', flush=True) + print('Reading profile from %s... ' % fileName, end='\r', flush=True) layerDict = {} for line in lines: keyValue = line.split(':') if line[0] == '#': pass elif keyValue[0].strip() == 'name': - layerDict[keyValue[0]] = keyValue[1] + layerDict[keyValue[0]] = keyValue[1].strip() elif keyValue[0].strip() == 'absCoef': absList = keyValue[1].split(',') absCoefList = [] diff --git a/test.py b/test.py index 139dbd7..f2929fb 100644 --- a/test.py +++ b/test.py @@ -2,12 +2,12 @@ import pyrad from matplotlib import pyplot as plt -planet = pyrad.createCustomPlanet('earth lo 500-1000') -yAxis = np.arange(1, 90000, 1) +planet = pyrad.createCustomPlanet('earth low simple') +'''yAxis = np.arange(1, 90E5, 10000) xAxis = [] -'''for height in yAxis: - xAxis.append(planet.temperatureAtHeight(height*100)) +for height in yAxis: + xAxis.append(planet.pressureAtHeight(height)) plt.plot(xAxis, yAxis) plt.show()''' -#planet2 = pyrad.createCustomPlanet('mars simple') -pyrad.plotPlanetSpectrum([planet], 90) \ No newline at end of file +planet2 = pyrad.createCustomPlanet('mars simple') +pyrad.plotPlanetSpectrum([planet], verify=False) \ No newline at end of file From 3f2a77c68171816b6c7d2f7d444de091f6b7917c Mon Sep 17 00:00:00 2001 From: Brad Schrag Date: Sat, 20 Oct 2018 11:12:54 -0500 Subject: [PATCH 11/43] time to add menu integration --- pyrad.py | 17 +++++++++++++++++ pyradUtilities.py | 23 +++++++++++++++-------- test.py | 2 +- 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/pyrad.py b/pyrad.py index c5a434b..30fbb07 100644 --- a/pyrad.py +++ b/pyrad.py @@ -20,6 +20,18 @@ settings = utils.Settings('low') + +def reduceRes(array, lumpTo=1): + n = int(lumpTo / settings.baseRes) + length = int(len(array) * settings.baseRes) + newArray = np.zeros(length) + for m in range(0, length): + for i in range(0, n): + newArray[m] += array[m * n + i] / n + return newArray + + + def createCustomPlanet(name): initialParameters = utils.parseCustomProfile(name) @@ -1270,10 +1282,15 @@ def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=[ if not heightFlag: height = planet.maxHeight / 100000 xAxis = planet.xAxis + #xAxis = np.linspace(planet.rangeMin, planet.rangeMax, planet.rangeMax - planet.rangeMin) yAxis = planet.processTransmission(height, direction=direction, verify=verify) + #yAxis = reduceRes(planet.processTransmission(height, direction=direction, verify=verify)) fig, = plt.plot(xAxis, smooth(yAxis, 75), linewidth=linewidth, alpha=alpha, color=color, label='%s : %sWm-2' % (planet.name, round(integrateSpectrum(yAxis, pi), 2))) + #fig, = plt.plot(xAxis, yAxis, linewidth=linewidth, + # alpha=alpha, color=color, + # label='%s : %sWm-2' % (planet.name, round(integrateSpectrum(yAxis, pi), 2))) handles.append(fig) color = 1 for temperature in temperatureList: diff --git a/pyradUtilities.py b/pyradUtilities.py index ff8c936..7098709 100644 --- a/pyradUtilities.py +++ b/pyradUtilities.py @@ -22,14 +22,18 @@ class Settings: def __init__(self, setting): self.setting = setting + self.reduceRes = True def changeSetting(self, value): self.setting = value + def changeResReduce(self, bool): + self.reduceRes = bool + @property def baseRes(self): if self.setting == 'low': - return .1 + return .01 elif self.setting == 'mid': return .01 elif self.setting == 'hi': @@ -117,7 +121,8 @@ def setupDir(): def openReturnLines(fullPath): if not os.path.isfile(fullPath): - return False + print('file not found %s' % fullPath) + exit() openFile = open(fullPath) lineList = openFile.readlines() openFile.close() @@ -225,12 +230,14 @@ def parseCustomProfile(name): def profileLength(name): folderPath = '%s/%s' % (profileDir, name) - fileList = os.listdir(folderPath) - count = 0 - for file in fileList: - if 'Layer' in file: - count += 1 - return count + filePath = '%s/profileComplete.pyr' % folderPath + lines = openReturnLines(filePath) + for line in lines: + if line[0] == '#': + pass + else: + values = line.split(':') + return int(values[1]) def profileWriteProgress(name, completed, expected): diff --git a/test.py b/test.py index f2929fb..ff53fce 100644 --- a/test.py +++ b/test.py @@ -10,4 +10,4 @@ plt.plot(xAxis, yAxis) plt.show()''' planet2 = pyrad.createCustomPlanet('mars simple') -pyrad.plotPlanetSpectrum([planet], verify=False) \ No newline at end of file +pyrad.plotPlanetSpectrum([planet], verify=True) \ No newline at end of file From 35a825e5f4b0c8ebe1a83bf209307af3f513759d Mon Sep 17 00:00:00 2001 From: Brad Schrag Date: Sun, 21 Oct 2018 15:10:31 -0500 Subject: [PATCH 12/43] atm transfer added to pyrad menus --- earth lo 500-1000.pyr | 0 earth low simple.pyr | 38 - earth2.py | 67 - earth3.py | 67 - earth mid simple.pyr => earthsimple.pyr | 14 +- earthtransmission.py | 85 - mars simple.pyr | 12 - marssimple.pyr | 12 + pyrad.py | 2032 ++++++++--------------- pyradClasses.py | 1385 +++++++++++++++ pyradInteractive.py | 625 ------- pyradUtilities.py | 9 +- sample.py | 5 + test.py | 13 - 14 files changed, 2095 insertions(+), 2269 deletions(-) delete mode 100644 earth lo 500-1000.pyr delete mode 100644 earth low simple.pyr delete mode 100644 earth2.py delete mode 100644 earth3.py rename earth mid simple.pyr => earthsimple.pyr (75%) delete mode 100644 earthtransmission.py delete mode 100644 mars simple.pyr create mode 100644 marssimple.pyr create mode 100644 pyradClasses.py delete mode 100644 pyradInteractive.py create mode 100644 sample.py delete mode 100644 test.py diff --git a/earth lo 500-1000.pyr b/earth lo 500-1000.pyr deleted file mode 100644 index e69de29..0000000 diff --git a/earth low simple.pyr b/earth low simple.pyr deleted file mode 100644 index b05b8f8..0000000 --- a/earth low simple.pyr +++ /dev/null @@ -1,38 +0,0 @@ -# A demo file for pyrad - -setting: low - -# mBar , K , km,cm-1,cm-1, m , g -surface: 1013.25, 300, 90, 500, 900, 100, 9.8 - -# mol text name, concentration -molecule: co2, .000400 -molecule: h2o, .018000 -molecule: o3, 0 -molecule: o2, .20 -molecule: n2, .79 -molecule: ch4, .0000018 - -# name, endHeight, endTemp -lapse rate: troposphere, 11, 216 -lapse rate: tropopause, 20, 216 -lapse rate: stratosphere, 32, 228 -lapse rate: stratosphere, 47, 270 -lapse rate: stratopause, 51, 270 -lapse rate: mesosphere, 71, 214 -lapse rate: mesosphere2, 80, 190 -lapse rate: mesopause, 90, 190 - -# name, endHeight, endValue, moleculeName -composition rate: WV boundary layer, 2.5, 18000e-6, h2o -composition rate: WV troposphere1, 8, 200e-6, h2o -composition rate: WV troposphere2, 9, 400e-6, h2o -composition rate: WV troposphere2, 10, 400e-6, h2o -composition rate: WV tropopause', 20, 2e-6, h2o -composition rate: WV stratosphere to top',90, 0, h2o - -#composition rate: troposphere ozone, 16, 60E-9, o3 -#composition rate: tropopause ozone, 32, 5E-6, o3 -#composition rate: upper strat ozone, 60, 0, o3 -#composition rate: strat on up ozone, 90, 0, o3 - diff --git a/earth2.py b/earth2.py deleted file mode 100644 index bee412d..0000000 --- a/earth2.py +++ /dev/null @@ -1,67 +0,0 @@ -import pyrad -import numpy as np - - -initialThickness = 100 * 100 -tropopause = 11000 * 100 -strat1 = 20000 * 100 -strat2 = 32000 * 100 -stratopause = 47000 * 100 -meso1 = 51000 * 100 -meso2 = 71000 * 100 -mesopause = 80000 * 100 -maxHeight = 90000 * 100 -profileName = 'earth345' - - -earth = pyrad.Planet(profileName, 1013.25, 288, maxHeight, rangeMin=00, rangeMax=2000, initialThickness=initialThickness) - -earth.addLapseRate('troposphere dry LR', 0, earth.surfaceTemperature, tropopause, 216, earth.surfacePressure) -earth.addLapseRate('tropopause', tropopause, earth.temperatureAtHeight(tropopause), strat1, 216, earth.pressureAtHeight(tropopause)) -earth.addLapseRate('stratosphere1', strat1, earth.temperatureAtHeight(strat1), strat2, 228, earth.pressureAtHeight(strat1)) -earth.addLapseRate('stratosphere2', strat2, earth.temperatureAtHeight(strat2), stratopause, 270, earth.pressureAtHeight(strat2)) -earth.addLapseRate('stratopause', stratopause, earth.temperatureAtHeight(stratopause), meso1, 270, earth.pressureAtHeight(stratopause)) -earth.addLapseRate('mesosphere1', meso1, earth.temperatureAtHeight(meso1), meso2, 214, earth.pressureAtHeight(meso1)) -earth.addLapseRate('mesosphere2', meso2, earth.temperatureAtHeight(meso2), mesopause, 190, earth.pressureAtHeight(meso2)) -earth.addLapseRate('mesopause', mesopause, earth.temperatureAtHeight(mesopause), maxHeight, 190, earth.pressureAtHeight(mesopause)) - -co2 = earth.addMolecule('co2', ppm=350) -h2o = earth.addMolecule('h2o', ppm=20000) -n2 = earth.addMolecule('n2', percentage=76.9) -o2 = earth.addMolecule('o2', percentage=19.9) -o3 = earth.addMolecule('o3', ppb=0) -ch4 = earth.addMolecule('ch4', ppm=1.5) -# ar = earth.addMolecule('ar', percentage=.9) - -# earth.addCompositionRate('co2 troposphere', 0, co2.concentration, 11000, -.000000001, co2) -# earth.addCompositionRate('co2 stratosphere and up', 0, earth.compositionAtHeight(11000, co2), 90000, 0, co2) - -wvCP1 = 2500 * 100 -wvCP2 = 8000 * 100 -wvCP3 = 9000 * 100 -wvCP4 = 10000 * 100 -wvCP5 = 20000 * 100 - -earth.addCompositionRate('WV boundary layer', 0, h2o.concentration, wvCP1, 10000e-6, h2o) -earth.addCompositionRate('WV troposphere1', wvCP1, earth.compositionAtHeight(wvCP1, h2o), wvCP2, 200e-6, h2o) -earth.addCompositionRate('WV troposphere2', wvCP2, earth.compositionAtHeight(wvCP2, h2o), wvCP3, 400e-6, h2o) -earth.addCompositionRate('WV troposphere2', wvCP3, earth.compositionAtHeight(wvCP3, h2o), wvCP4, 400e-6, h2o) -earth.addCompositionRate('WV tropopause', wvCP4, earth.compositionAtHeight(wvCP4, h2o), wvCP5, 2e-6, h2o) -earth.addCompositionRate('WV stratosphere and up', wvCP5, earth.compositionAtHeight(wvCP5, h2o), maxHeight, 0, h2o) - -# ozone rules -ozCP0 = 3000 * 100 -ozCP1 = 16000 * 100 -ozCP2 = 32000 * 100 -ozCP3 = 60000 * 100 -earth.addCompositionRate('troposphere ozone', ozCP0, 30E-9, ozCP1, 60E-9, o3) -earth.addCompositionRate('tropopause ozone', ozCP1, earth.compositionAtHeight(ozCP1, o3), ozCP2, 5E-6, o3) -earth.addCompositionRate('upper strat ozone', ozCP2, earth.compositionAtHeight(ozCP2, o3), ozCP3, 0, o3) -earth.addCompositionRate('strat on up ozone', ozCP3, earth.compositionAtHeight(ozCP3, o3), maxHeight, 0, o3) - -#ch4 rules -earth.addCompositionRate('troposphere methane', 0, ch4.concentration, strat1, ch4.concentration, ch4) -earth.addCompositionRate('taper ch4 strat', strat1, ch4.concentration, stratopause, 0, ch4) -earth.addCompositionRate('ch4 0 to max height', stratopause, 0, maxHeight, 0, ch4) - -earth.processTransmission(90E5) diff --git a/earth3.py b/earth3.py deleted file mode 100644 index 79d7633..0000000 --- a/earth3.py +++ /dev/null @@ -1,67 +0,0 @@ -import pyrad -import numpy as np - - -initialThickness = 100 * 100 -tropopause = 11000 * 100 -strat1 = 20000 * 100 -strat2 = 32000 * 100 -stratopause = 47000 * 100 -meso1 = 51000 * 100 -meso2 = 71000 * 100 -mesopause = 80000 * 100 -maxHeight = 90000 * 100 -profileName = 'earth678' - - -earth = pyrad.Planet(profileName, 1013.25, 300, maxHeight, rangeMin=00, rangeMax=2000, initialThickness=initialThickness) - -earth.addLapseRate('troposphere dry LR', 0, earth.surfaceTemperature, tropopause, 216, earth.surfacePressure) -earth.addLapseRate('tropopause', tropopause, earth.temperatureAtHeight(tropopause), strat1, 216, earth.pressureAtHeight(tropopause)) -earth.addLapseRate('stratosphere1', strat1, earth.temperatureAtHeight(strat1), strat2, 228, earth.pressureAtHeight(strat1)) -earth.addLapseRate('stratosphere2', strat2, earth.temperatureAtHeight(strat2), stratopause, 270, earth.pressureAtHeight(strat2)) -earth.addLapseRate('stratopause', stratopause, earth.temperatureAtHeight(stratopause), meso1, 270, earth.pressureAtHeight(stratopause)) -earth.addLapseRate('mesosphere1', meso1, earth.temperatureAtHeight(meso1), meso2, 214, earth.pressureAtHeight(meso1)) -earth.addLapseRate('mesosphere2', meso2, earth.temperatureAtHeight(meso2), mesopause, 190, earth.pressureAtHeight(meso2)) -earth.addLapseRate('mesopause', mesopause, earth.temperatureAtHeight(mesopause), maxHeight, 190, earth.pressureAtHeight(mesopause)) - -co2 = earth.addMolecule('co2', ppm=350) -h2o = earth.addMolecule('h2o', ppm=20000) -n2 = earth.addMolecule('n2', percentage=76.9) -o2 = earth.addMolecule('o2', percentage=19.9) -o3 = earth.addMolecule('o3', ppb=0) -ch4 = earth.addMolecule('ch4', ppm=1.5) -# ar = earth.addMolecule('ar', percentage=.9) - -# earth.addCompositionRate('co2 troposphere', 0, co2.concentration, 11000, -.000000001, co2) -# earth.addCompositionRate('co2 stratosphere and up', 0, earth.compositionAtHeight(11000, co2), 90000, 0, co2) - -wvCP1 = 2500 * 100 -wvCP2 = 8000 * 100 -wvCP3 = 9000 * 100 -wvCP4 = 10000 * 100 -wvCP5 = 20000 * 100 - -earth.addCompositionRate('WV boundary layer', 0, h2o.concentration, wvCP1, 10000e-6, h2o) -earth.addCompositionRate('WV troposphere1', wvCP1, earth.compositionAtHeight(wvCP1, h2o), wvCP2, 200e-6, h2o) -earth.addCompositionRate('WV troposphere2', wvCP2, earth.compositionAtHeight(wvCP2, h2o), wvCP3, 400e-6, h2o) -earth.addCompositionRate('WV troposphere2', wvCP3, earth.compositionAtHeight(wvCP3, h2o), wvCP4, 400e-6, h2o) -earth.addCompositionRate('WV tropopause', wvCP4, earth.compositionAtHeight(wvCP4, h2o), wvCP5, 2e-6, h2o) -earth.addCompositionRate('WV stratosphere and up', wvCP5, earth.compositionAtHeight(wvCP5, h2o), maxHeight, 0, h2o) - -# ozone rules -ozCP0 = 3000 * 100 -ozCP1 = 16000 * 100 -ozCP2 = 32000 * 100 -ozCP3 = 60000 * 100 -earth.addCompositionRate('troposphere ozone', ozCP0, 30E-9, ozCP1, 60E-9, o3) -earth.addCompositionRate('tropopause ozone', ozCP1, earth.compositionAtHeight(ozCP1, o3), ozCP2, 5E-6, o3) -earth.addCompositionRate('upper strat ozone', ozCP2, earth.compositionAtHeight(ozCP2, o3), ozCP3, 0, o3) -earth.addCompositionRate('strat on up ozone', ozCP3, earth.compositionAtHeight(ozCP3, o3), maxHeight, 0, o3) - -#ch4 rules -earth.addCompositionRate('troposphere methane', 0, ch4.concentration, strat1, ch4.concentration, ch4) -earth.addCompositionRate('taper ch4 strat', strat1, ch4.concentration, stratopause, 0, ch4) -earth.addCompositionRate('ch4 0 to max height', stratopause, 0, maxHeight, 0, ch4) - -earth.processTransmission(90E5) diff --git a/earth mid simple.pyr b/earthsimple.pyr similarity index 75% rename from earth mid simple.pyr rename to earthsimple.pyr index 3b215a5..2820686 100644 --- a/earth mid simple.pyr +++ b/earthsimple.pyr @@ -1,9 +1,9 @@ # A demo file for pyrad -setting: mid +setting: low # mBar , K , km,cm-1,cm-1, m , g -surface: 1013.25, 300, 90, 0, 2000, 100, 9.8 +surface: 1013.25, 300, 120, 100, 1500, 100, 9.8 # mol text name, concentration molecule: co2, .000400 @@ -22,6 +22,7 @@ lapse rate: stratopause, 51, 270 lapse rate: mesosphere, 71, 214 lapse rate: mesosphere2, 80, 190 lapse rate: mesopause, 90, 190 +lapse rate: thermosphere, 100, 228 # name, endHeight, endValue, moleculeName composition rate: WV boundary layer, 2.5, 18000e-6, h2o @@ -31,7 +32,8 @@ composition rate: WV troposphere2, 10, 400e-6, h2o composition rate: WV tropopause', 20, 2e-6, h2o composition rate: WV stratosphere to top',90, 0, h2o -#composition rate: troposphere ozone, 16, 60E-9, o3 -#composition rate: tropopause ozone, 32, 5E-6, o3 -#composition rate: upper strat ozone, 60, 0, o3 -#composition rate: strat on up ozone, 90, 0, o3 +composition rate: troposphere ozone, 16, 60E-9, o3 +composition rate: tropopause ozone, 32, 5E-6, o3 +composition rate: upper strat ozone, 60, 0, o3 +composition rate: strat on up ozone, 90, 0, o3 + diff --git a/earthtransmission.py b/earthtransmission.py deleted file mode 100644 index b1bab49..0000000 --- a/earthtransmission.py +++ /dev/null @@ -1,85 +0,0 @@ -import pyrad -import numpy as np -from matplotlib import pyplot as plt - - -initialThickness = 100 #meter -tropopause = 11 #km -strat1 = 20 #km -strat2 = 32 #km -stratopause = 47 -meso1 = 51 -meso2 = 71 -mesopause = 80 -maxHeight = 90 -profileName = 'earth123' - - -earth = pyrad.Planet(profileName, 1013.25, 300, maxHeight, rangeMin=500, rangeMax=900, initialThickness=initialThickness) - -earth.addLapseRate('troposphere dry LR', tropopause, 216) -earth.addLapseRate('tropopause', strat1, 216) -earth.addLapseRate('stratosphere1', strat2, 228) -earth.addLapseRate('stratosphere2', stratopause, 270) -earth.addLapseRate('stratopause', meso1, 270) -earth.addLapseRate('mesosphere1', meso2, 214) -earth.addLapseRate('mesosphere2', mesopause, 190) -earth.addLapseRate('mesopause', maxHeight, 190) - -co2 = earth.addMolecule('co2', ppm=350) -h2o = earth.addMolecule('h2o', ppm=20000) -n2 = earth.addMolecule('n2', percentage=76.9) -o2 = earth.addMolecule('o2', percentage=19.9) -o3 = earth.addMolecule('o3', ppb=0) -ch4 = earth.addMolecule('ch4', ppb=1800) - -wvCP1 = 2.5 -wvCP2 = 8 -wvCP3 = 9 -wvCP4 = 10 -wvCP5 = 20 - -earth.addCompositionRate('WV boundary layer', wvCP1, 18000e-6, h2o) -earth.addCompositionRate('WV troposphere1', wvCP2, 200e-6, h2o) -earth.addCompositionRate('WV troposphere2', wvCP3, 400e-6, h2o) -earth.addCompositionRate('WV troposphere2', wvCP4, 400e-6, h2o) -earth.addCompositionRate('WV tropopause', wvCP5, 2e-6, h2o) -earth.addCompositionRate('WV stratosphere and up',maxHeight, 0, h2o) - -# ozone rules -ozCP0 = 3 -ozCP1 = 16 -ozCP2 = 32 -ozCP3 = 60 -#earth.addCompositionRate('troposphere ozone', ozCP1, 60E-9, o3) -#earth.addCompositionRate('tropopause ozone', ozCP2, 5E-6, o3) -#earth.addCompositionRate('upper strat ozone', ozCP3, 0, o3) -#earth.addCompositionRate('strat on up ozone', maxHeight, 0, o3) - -'''yAxis = np.arange(1, 90000, 1) -xAxis = [] -for height in yAxis: - xAxis.append(earth.compositionAtHeight(height*100, o3)) - - -plt.plot(xAxis, yAxis) -plt.show()''' - -earth.processTransmission(90) - - -""" -height = 0 -nextLayerThickness = initialThickness -initalMass = earth.densityAtHeight(height) * initialThickness / 100 -while height < 11000: - previousLayer = earth.atmosphere[-1] - newHeight = previousLayer.height + previousLayer.depth - newTemp = earth.temperatureAtHeight(newHeight) - newDensity = earth.densityAtHeight(newHeight) - newPressure = earth.pressureAtHeight(newHeight) - newDepth = initalMass / newDensity - earth.atmosphere.addLayer(nextLayerThickness, earth.temperatureAtHeight(height)) - - -""" diff --git a/mars simple.pyr b/mars simple.pyr deleted file mode 100644 index 2a29fff..0000000 --- a/mars simple.pyr +++ /dev/null @@ -1,12 +0,0 @@ -# mars simple - -setting: hi - -surface: 6, 220, 90, 100, 1500, 200, 3.711 - -molecule: co2, .9532 -molecule: n2, .027 -molecule: o2, .0013 - -lapse rate: first layer, 45, 100 -lapse rate: final layer, 90, 100 \ No newline at end of file diff --git a/marssimple.pyr b/marssimple.pyr new file mode 100644 index 0000000..bc41dce --- /dev/null +++ b/marssimple.pyr @@ -0,0 +1,12 @@ +# mars simple + +setting: hi + +surface: 6, 220, 100, 100, 1500, 200, 3.711 + +molecule: co2, .9532 +molecule: n2, .027 +molecule: o2, .0013 + +lapse rate: first layer, 45, 120 +lapse rate: final layer, 100, 120 \ No newline at end of file diff --git a/pyrad.py b/pyrad.py index 30fbb07..589a5fd 100644 --- a/pyrad.py +++ b/pyrad.py @@ -1,1387 +1,715 @@ -import os -import pyradUtilities as utils -import pyradLineshape as ls -import pyradIntensity +import pyradClasses +import pyradUtilities as util +import re import pyradPlanck -import numpy as np -import matplotlib.pyplot as plt -# import pyradInteractive +existingAtmosphere = False +validValueAndUnits = re.compile('([-])?(\d+)?([.])?(\d+)?(\S+)?') +genericAtmosphere = pyradClasses.Atmosphere('holding atm for pyrad interactive') +pyradClasses.settings.changeSetting('hi') -c = 299792458.0 -k = 1.38064852E-23 -h = 6.62607004e-34 -pi = 3.141592653589793 -R = 8.3144598 -t0 = 296 -p0 = 1013.25 -avo = 6.022140857E23 -sb = 5.67E-8 -settings = utils.Settings('low') +class Menu: + def __init__(self, title, entries, previousMenu=None, menuParams=None): + self.title = title + self.entries = entries + self.previousMenu = previousMenu + self.menuParams = menuParams + def displayMenu(self): + titleStr = '\t' + self.title + while len(titleStr) < 60: + titleStr += ' ' + print('\n%s' % util.underlineCyan(titleStr)) + i = 1 + validEntry = ['x'] + for entry in self.entries: + validEntry.append(str(i)) + print(' %s) %s' % (util.magentaText(i), entry.name)) + i += 1 + if 'Main' not in self.title: + print(' %s Previous menu' % util.magentaText('B)')) + validEntry.append('b') + print(' %s Exit' % util.magentaText('X)')) + validChoice = False + while not validChoice: + userInput = input('Choose an option: ') + if userInput.lower() == 'x': + print('Goodbye') + exit(1) + elif userInput.lower() == 'b' and 'Main' not in self.title: + self.previousMenu() + elif userInput in validEntry: + userChoice = self.entries[int(userInput) - 1] + if userChoice.nextFunction: + userChoice.nextFunction(userChoice.functionParams) + validChoice = True + elif userChoice.nextMenu: + userChoice.nextMenu.displayMenu() + validChoice = True + else: + print('Invalid entry. Try again.') -def reduceRes(array, lumpTo=1): - n = int(lumpTo / settings.baseRes) - length = int(len(array) * settings.baseRes) - newArray = np.zeros(length) - for m in range(0, length): - for i in range(0, n): - newArray[m] += array[m * n + i] / n - return newArray - - - -def createCustomPlanet(name): - - initialParameters = utils.parseCustomProfile(name) - initialValues = initialParameters['initialValues'] - moleculeList = initialParameters['molecules'] - temperatureRuleList = initialParameters['temperatureRules'] - compositionRuleList = initialParameters['compositionRules'] - - try: - value = initialParameters['setting'] - except KeyError: - value = 'low' + def displayMultiChoiceMenu(self): + titleStr = '\t' + self.title + while len(titleStr) < 60: + titleStr += ' ' + print('\n%s' % util.underlineCyan(titleStr)) + i = 1 + validEntry = ['x'] + for entry in self.entries: + validEntry.append(str(i)) + print(' %s) %s' % (util.magentaText(i), entry.name)) + i += 1 + if 'Main' not in self.title: + print(' %s Previous menu' % util.magentaText('B)')) + validEntry.append('b') + print(' %s Exit' % util.magentaText('X)')) + validChoice = False + while not validChoice: + userInput = input('Choose an option: ') + if userInput.lower() == 'x': + print('Goodbye') + exit(1) + elif userInput.lower() == 'b' and 'Main' not in self.title: + return + else: + inputs = userInput.split(',') + allValid = True + userChoices = [] + for i in inputs: + print('i: %s' % i) + if i.strip() not in validEntry: + allValid = False + else: + userChoices.append(self.entries[int(i) - 1]) + if allValid: + nextFunction = userChoices[0].nextFunction + nextFunction(userChoices) + validChoice = True + else: + print('Invalid entry. Try again.') - settings.changeSetting(value) - planet = Planet(initialParameters['name'], initialValues['surfacePressure'], initialValues['surfaceTemperature'], - initialValues['maxHeight'], rangeMin=initialValues['rangeMin'], - rangeMax=initialValues['rangeMax'], initialThickness=initialValues['initialDepth'], gravity=initialValues['gravity']) - for molecule in moleculeList: - planet.addMolecule(molecule['name'], concentration=molecule['concentration']) +class Entry: + def __init__(self, text, nextMenu=None, nextFunction=None, functionParams=None, previousMenu=None): + self.name = text + self.nextMenu = nextMenu + self.nextFunction = nextFunction + self.functionParams = functionParams + self.previousMenu = previousMenu - for rule in temperatureRuleList: - planet.addLapseRate(rule['name'], rule['finalHeight'], rule['finalValue']) - for rule in compositionRuleList: - initalLayer = planet.initialLayer - molecule = initalLayer.returnMolecule(rule['moleculeName']) - planet.addCompositionRate(rule['name'], rule['finalHeight'], rule['finalValue'], molecule) - return planet +def createPlot(params): + plotList = params['plots'] + plotType = params['plotType'] + plotTitle = params['title'] + pyradClasses.plot(plotType, plotTitle, plotList) + menuChoosePlotType() -def yesOrNo(promptText): - validInput = False - while not validInput: - userSelection = input(promptText) - if not userSelection: - pass - elif userSelection.lower()[0] == 'y': - return True - elif userSelection.lower()[0] == 'n': - return False +def plotPlanetSpectrum(values): + pList = [] + for p in values['profiles']: + planet = pyradClasses.createCustomPlanet(p.name) + pList.append(planet) + if values['height'] == -2.71828: + pyradClasses.plotPlanetSpectrum(pList, direction=values['direction'], verify=False) + else: + pyradClasses.plotPlanetSpectrum(pList, direction=values['direction'], height=values['height'], verify=False) + atmosphereTransferMenu() + + +def createLayer(atmosphere): + defaultLayerName = atmosphere.nextLayerName() + getLayerName = '\n%s\n' \ + 'If no value given, default will be %s : ' \ + % (util.underlineCyan('Enter the name of the layer.\t\t'), + util.limeText(defaultLayerName)) + depth = inputLayerDepth() + pressure = inputLayerPressure() + temperature = inputLayerTemperature() + rangeMin, rangeMax = inputLayerRange() + validName = False + while not validName: + layerName = input(getLayerName) + if layerName not in genericAtmosphere: + validName = True else: - print('Invalid choice.') - - -def smooth(y, box_pts): - box = np.ones(box_pts)/box_pts - y_smooth = np.convolve(y, box, mode='same') - return y_smooth - - -def linear(baseValue, baseHeight, rate, height): - newValue = baseValue + rate * (height - baseHeight) - return newValue - - -def integrateSpectrum(spectrum, unitAngle=pi, res=utils.BASE_RESOLUTION): - value = np.sum(np.nan_to_num(spectrum)) - value = value * unitAngle * res - return value - - -def getCrossSection(obj): - if not obj.progressCrossSection: - obj.createCrossSection() - return obj.crossSection + print('Name already taken. Please try again.') + layer = atmosphere.addLayer(depth, temperature, pressure, rangeMin, rangeMax, name=layerName) + createMolecule(layer) + return + + +def createMolecule(layer): + addMoleculeLoop = True + while addMoleculeLoop: + moleculeName = inputMoleculeName() + concentration, units = inputMoleculeComposition() + tempdict = {units: concentration} + molecule = layer.addMolecule(moleculeName, **tempdict) + while pyradClasses.totalConcentration(layer) > 1: + print("%s total concentration exceeds 100%%" % util.magentaText('***\tWARNING\t***')) + menuEditComposition(layer) + validInput = False + while not validInput: + ask = input("Add another molecule to the layer %s " % util.magentaText('(y/n) :')) + if ask.strip().lower() == 'y': + validInput = True + elif ask.strip().lower() == 'n': + gasCellMenu() + + +def menuEditLayerParam(layer): + editDepth = Entry('Depth', nextFunction=editLayerDepth, functionParams=layer) + editRange = Entry('Min or max range', nextFunction=editLayerRange, functionParams=layer) + editTemperature = Entry('Temperature',nextFunction=editLayerTemperature, functionParams=layer) + editPressure = Entry('Pressure', nextFunction=editLayerPressure, functionParams=layer) + entryList = [editDepth, editRange, editTemperature, editPressure] + menu = Menu('Choose the parameter to edit for %s' % layer.name, entryList, + previousMenu=menuEditParamsOrComp, menuParams=layer) + menu.displayMenu() + return + + +def editLayerDepth(layer): + print('Current %s for %s is : %s\n' + % (util.limeText('depth'), util.limeText(layer.name), util.cyanText('%scm' % layer.depth))) + depth = inputLayerDepth(default=layer.depth) + layer.changeDepth(depth) + menuEditLayerParam(layer) + + +def editLayerTemperature(layer): + print('Current %s for %s is : %s\n' + % (util.limeText('temperature'), util.limeText(layer.name), util.cyanText('%sK' % layer.T))) + temperature = inputLayerTemperature(default=layer.T) + layer.changeTemperature(temperature) + menuEditLayerParam(layer) + + +def editLayerPressure(layer): + print('Current %s for %s is : %s\n' + % (util.limeText('pressure'), util.limeText(layer.name), util.cyanText('%smbar' % layer.P))) + pressure = inputLayerPressure(default=layer.P) + layer.changePressure(pressure) + menuEditLayerParam(layer) + + +def editLayerRange(layer): + print('Current %s for %s is %s\n' + % (util.limeText('range'), util.limeText(layer.name), + util.cyanText('%s-%scm-1' % (layer.rangeMin, layer.rangeMax)))) + rangeMin, rangeMax = inputLayerRange(defaultMin=layer.rangeMin, defaultMax=layer.rangeMax) + layer.changeRange(rangeMin, rangeMax) + menuEditLayerParam(layer) + + +def editComposition(molecule): + print('Current concentration for %s is %s\n' % (util.limeText(molecule.name), util.limeText(molecule.concText))) + return inputMoleculeComposition(molecule, default=molecule.concText) + + +def inputLayerDepth(default=None): + if not default: + default = 10 + text = 'Enter the thickness of the layer.\t\t\t' + getDepth = '%s\n' \ + 'If no units are specified, %s will be assumed.\n' \ + 'Other valid units are %s . If no value given, default will be %s: ' % \ + (util.underlineCyan(text), + util.limeText('cm'), + util.limeText('m, in, ft.'), + util.limeText('%scm' % default)) + depth = receiveInput(getDepth, validDepth, default=default) + return depth + + +def inputLayerTemperature(default=None): + if not default: + default = 300 + text = 'Enter the temperature of the layer.\t\t\t' + getTemperature = '%s\n' \ + 'If no units are specified, %s will be assumed.\n' \ + 'Other valid units are %s . If no value given, default will be %s: ' % \ + (util.underlineCyan(text), + util.limeText('K'), + util.limeText('C or F'), + util.limeText('%sK' % default)) + temperature = receiveInput(getTemperature, validTemperature, default=default) + return temperature + + +def inputLayerPressure(default=None): + if not default: + default = 1013.25 + text = 'Enter the pressure of the layer.\t\t\t' + getPressure = '%s\n' \ + 'If no units are specified, %s will be assumed.\n' \ + 'Other valid units are %s . If no value given, default will be %s: ' % \ + (util.underlineCyan(text), + util.limeText('mBar'), + util.limeText('pa, bar, and atm.'), + util.limeText('%smbar' % default)) + pressure = receiveInput(getPressure, validPressure, default=default) + return pressure + + +def inputLayerRange(defaultMin=None, defaultMax=None): + if not defaultMin: + defaultMin = 600 + if not defaultMax: + defaultMax = 700 + rangeMin = -1 + rangeMax = -1 + text = 'Enter the minimum range of the layer.\t\t\t' + getRangeMin = '%s\n' \ + 'If no units are specified, %s will be assumed.\n' \ + 'Other valid units are %s . If no value given, default will be %s: ' % \ + (util.underlineCyan(text), + util.limeText('cm-1'), + util.limeText('um'), + util.limeText('%scm' % defaultMin)) + while rangeMin < 0: + rangeMin = receiveInput(getRangeMin, validRange, default=defaultMin) + if rangeMin < 0: + print('Range min must be %s than zero' % util.magentaText('greater')) + text = 'Enter the maximum range of the layer.\t\t\t' + getRangeMax = '%s\n' \ + 'If no units are specified, %s will be assumed.\n' \ + 'Other valid units are %s . If no value given, default will be %s: ' % \ + (util.underlineCyan(text), + util.limeText('cm-1'), + util.limeText('um'), + util.limeText('%scm' % defaultMax)) + while rangeMax <= rangeMin: + rangeMax = receiveInput(getRangeMax, validRange, default=defaultMax) + if rangeMax <= rangeMin: + print('Range min must be %s than range min of %s' % (util.magentaText('greater'), util.cyanText(rangeMin))) + return rangeMin, rangeMax + + +def validNumber(userInput): + try: + return float(userInput) + except ValueError: + return False -def resetCrossSection(obj): - if not obj.progressCrossSection: - return - obj.crossSection = np.zeros(int((obj.rangeMax - obj.rangeMin) / utils.BASE_RESOLUTION)) - obj.progressCrossSection = False - for child in obj: - if not isinstance(child, Line): - resetCrossSection(child) - - -def resetData(obj): - # clears the existing line data from parent object down to isotope, and then reloads the data using getData - # use this if layer ranges get changed. Will also clear the cross section data of the obj. - for child in obj: - if isinstance(child, Isotope): - while len(child) > 0: - child.pop() - child.getData() +def inputPlanckRange(units): + rangeMin = -1 + rangeMax = -1 + text = '%s\nUnits are %s. Scientific notation is accepted (1e14):' \ + % (util.underlineCyan('Enter the minimum range of the planck spectrum.'),util.limeText(units)) + while rangeMin < 0: + rangeMin = receiveInput(text, validNumber) + if rangeMin < 0: + print('Range min must be %s than zero' % util.magentaText('greater')) + text = '%s\nUnits are %s. Scientific notation is accepted (1e14):' \ + % (util.underlineCyan('Enter the maximum range of the planck spectrum.'), util.limeText(units)) + while rangeMax <= rangeMin: + rangeMax = receiveInput(text, validNumber) + if rangeMax <= rangeMin: + print('Range min must be %s than range min of %s' % (util.magentaText('greater'), util.cyanText(rangeMin))) + return rangeMin, rangeMax + + +def inputMoleculeName(default=None): + if not default: + default = 'co2' + text = 'Enter the short molecule name.\t\t\t' + moleculeName = receiveInput('%s\n' + 'For a full list of options, type %s . If no value given, %s will be used: ' + % (util.underlineCyan(text), + util.magentaText('help'), + util.limeText(default)), validMoleculeName, default=default) + return moleculeName + + +def inputMoleculeComposition(obj=None, default=None): + if not default: + default = '400ppm' + text = 'Enter the molecule composition.\t\t\t' + composition, units = receiveInput('%s\n' + 'If no units entered, composition will be assumed %s.\n' + 'Other valid units are %s . If no value given, %s will be used: ' + % (util.underlineCyan(text), + util.limeText('parts per 1'), + util.limeText('ppm, ppb, or percentage'), + util.limeText(default)), validComposition, default=default) + if obj: + if units == 'ppm': + obj.setPPM(composition) + elif units == 'ppb': + obj.setPPB(composition) + elif 'perc' in units or units == '%': + obj.setPercentage(composition) else: - resetData(child) - resetCrossSection(obj) - - -def getAbsCoef(obj): - if not obj.progressCrossSection: - obj.createCrossSection() - return obj.absCoef - + obj.setConcentrationPercentage(composition) + return + else: + return composition, units + + +def inputPlanckTemps(): + text = 'Enter the temperature of the planck curves.\t\t\t' + tempList = receiveMultiInput('%s\n' + 'If no units entered, temperature will be assumed %s.\n' + 'Other valid units are %s .Multiple temperatures can be separated with a comma: ' + % (util.underlineCyan(text), + util.limeText('K'), + util.limeText('C and F')), validTemperature) + return tempList + + +def inputHeight(values): + text = 'Enter the height to view transmission from.\t\t\t' + height = receiveInput('%s\n' + 'Units should be in %s. If no value entered, maximum atm height will be used: ' % (util.underlineCyan(text), util.limeText('km')), validNumber, default=-2.71828) + values['height'] = height + plotPlanetSpectrum(values) + return + + +def menuChooseLayerToEdit(empty=None): + entryList = [] + for layer in genericAtmosphere: + nextEntry = Entry(layer.name, nextFunction=menuEditParamsOrComp, functionParams=layer) + entryList.append(nextEntry) + editLayerMenu = Menu('Edit layer', entryList) + editLayerMenu.displayMenu() + return + + +def menuChooseTransmission(plotType): + entryList = [] + for layer in genericAtmosphere: + params = {'plots': [layer], 'plotType': plotType, 'title': layer.title} + nextEntry = Entry(layer.name, nextFunction=createTransmission, functionParams=params) + entryList.append(nextEntry) + plotList, title = createObjAndComponents(layer) + params = {'plots': plotList, 'plotType': plotType, 'title': title} + nextEntry = Entry('%s and components' % layer.name, nextFunction=createTransmission, functionParams=params) + entryList.append(nextEntry) + transmissionMenu = Menu('Choose which layers to plot transmission', entryList) + transmissionMenu.displayMenu() + return + + +def createPlanckCurves(plotType): + plotList = inputPlanckTemps() + rangeMin, rangeMax = inputPlanckRange(plotType) + pyradClasses.plotSpectrum(title='Planck spectrums', rangeMin=rangeMin, rangeMax=rangeMax, planckTemperatureList=plotList, planckType=plotType) + return + + +def menuPlanckType(empty=None): + entryList = [] + wavenumber = 'wavenumber' + hertz = 'Hz' + wavelength = 'wavelength' + entryList.append(Entry('By %s (cm-1)' % wavenumber, nextFunction=createPlanckCurves, functionParams=wavenumber)) + entryList.append(Entry('By %s (um)' % wavelength, nextFunction=createPlanckCurves, functionParams=wavelength)) + entryList.append(Entry('By %s (s-1)' % hertz, nextFunction=createPlanckCurves, functionParams=hertz)) + planckTypeMenu = Menu('Choose planck type', entryList) + planckTypeMenu.displayMenu() + return + + +def createTransmission(params): + layer = params['plots'][0] + text = 'A plot for transmission requires an initial surface temperature.\n'\ + 'Please choose a temperature different from the layer temperature of %sK:' % util.limeText(layer.T) + temperature = receiveMultiInput(text, validTemperature) + objList = [] + for item in params['plots']: + objList.append(item) + temperature.append(layer.T) + pyradClasses.plotSpectrum(layer, objList=objList, + surfaceSpectrum=pyradPlanck.planckWavenumber(layer.xAxis, temperature[0]), + planckTemperatureList=temperature) + return + + +def menuChoosePlotType(empty=None): + entryList = [] + entryList.append(Entry('transmittance', nextFunction=menuChooseLayerToPlot, functionParams='transmittance')) + entryList.append(Entry('absorption coefficient', nextFunction=menuChooseLayerToPlot, functionParams='absorption coefficient')) + entryList.append(Entry('cross section', nextFunction=menuChooseLayerToPlot, functionParams='cross section')) + entryList.append(Entry('absorbance', nextFunction=menuChooseLayerToPlot, functionParams='absorbance')) + entryList.append(Entry('optical depth', nextFunction=menuChooseLayerToPlot, functionParams='optical depth')) + entryList.append(Entry('line survey', nextFunction=menuChooseLayerToPlot, functionParams='line survey')) + entryList.append(Entry('transmission', nextFunction=menuChooseTransmission, functionParams='transmission')) + choosePlotTypeMenu = Menu('Choose plot type', entryList, previousMenu=gasCellMenu) + choosePlotTypeMenu.displayMenu() + return + + +def menuChooseLayerToPlot(plotType): + entryList = [] + for layer in genericAtmosphere: + params = {'plots': [layer], 'plotType': plotType, 'title': layer.title} + nextEntry = Entry(layer.name, nextFunction=createPlot, functionParams=params) + entryList.append(nextEntry) + plotList, title = createObjAndComponents(layer) + params = {'plots': plotList, 'plotType': plotType, 'title': title} + nextEntry = Entry('%s and components' % layer.name, nextFunction=createPlot, functionParams=params) + entryList.append(nextEntry) + plotLayerMenu = Menu('Plot layer', entryList, previousMenu=menuChoosePlotType) + plotLayerMenu.displayMenu() + return + + +def createObjAndComponents(obj): + plotList = [obj] + for item in obj: + plotList.append(item) + return plotList, obj.title -def getTransmittance(obj): - if not obj.progressCrossSection: - obj.createCrossSection() - return obj.transmittance +def menuEditComposition(layer): + moleculeList = layer.returnMoleculeObjects() + entryList = [] + for molecule in moleculeList: + newEntry = Entry('%s : %s' % (molecule.name, molecule.concText), + functionParams=molecule, nextFunction=inputMoleculeComposition) + entryList.append(newEntry) + entryList.append(Entry('Add a new molecule(s)', nextFunction=createMolecule, functionParams=layer)) + editCompMenu = Menu('Choose a molecule to edit', entryList, previousMenu=menuEditParamsOrComp) + editCompMenu.displayMenu() + return + + +def menuEditParamsOrComp(layer): + entryList = [] + editLayerParamsEntry = Entry('Edit layer parameters', nextFunction=menuEditLayerParam, functionParams=layer) + entryList.append(editLayerParamsEntry) + duplicateLayerEntry = Entry('Duplicate layer', nextFunction=duplicateObj, functionParams=layer) + entryList.append(duplicateLayerEntry) + editCompositionEntry = Entry('Edit composition', nextFunction=menuEditComposition, functionParams=layer) + entryList.append(editCompositionEntry) + chooseParamsMenu = Menu('Edit or duplicate', entryList, previousMenu=menuChooseLayerToEdit) + chooseParamsMenu.displayMenu() + return + + +def gasCellMenu(param=None): + createLayerEntry = Entry("Create new gas cell", nextFunction=createLayer, functionParams=genericAtmosphere) + editLayerEntry = Entry("Edit/duplicate gas cell", nextFunction=menuChooseLayerToEdit) + plotLayerEntry = Entry("Plot gas cell", nextFunction=menuChoosePlotType) + planckPlotEntry = (Entry('Plot planck curves', nextFunction=menuPlanckType)) + menuGasCell = Menu('Gas cell simulator', [createLayerEntry, editLayerEntry, plotLayerEntry, planckPlotEntry], previousMenu=menuMain) + menuGasCell.displayMenu() + return + + +def chooseDirection(profileList): + lookUpEntry = Entry('Looking up', nextFunction=inputHeight, functionParams={'profiles': profileList, + 'direction': 'up'}) + lookDownEntry = Entry('Looking down', nextFunction=inputHeight, functionParams={'profiles': profileList, + 'direction': 'down'}) + menuChooseDirection = Menu('Choose direction to look', [lookUpEntry, lookDownEntry], previousMenu=atmosphereTransferMenu) + menuChooseDirection.displayMenu() + return + + +def atmosphereTransferMenu(param=None): + profileList = util.getProfileList() + entryList = [] + for profile in profileList: + entryList.append(Entry('%s' % profile[:-4], nextFunction=chooseDirection, functionParams=profile)) + menuAtmTransfer = Menu('Choose atmosphere', entryList, previousMenu=menuMain) + menuAtmTransfer.displayMultiChoiceMenu() + return + + +def menuMain(): + gasCellEntry = Entry('Gas cell simulator', nextFunction=gasCellMenu) + atmosphereTransferEntry = Entry('Atmosphere transmission', nextFunction=atmosphereTransferMenu) + mainMenu = Menu('Main menu', [gasCellEntry, atmosphereTransferEntry]) + mainMenu.displayMenu() + return + + +def duplicateObj(obj): + newObj = obj.returnCopy() + if isinstance(newObj, pyradClasses.Layer): + genericAtmosphere.append(newObj) + else: + print('Unknown object %s, type %s' % (obj.name, type(obj))) + return -def getOpticalDepth(obj): - if not obj.progressCrossSection: - obj.createCrossSection() - return -np.log(obj.transmittance) +def receiveInput(inputText, validInputFunction, default=None): + validInput = False + while validInput is False: + userInput = input('\n%s' % inputText) + if userInput == '': + return validInputFunction(str(default)) + validInput = validInputFunction(userInput) + return validInput -def getAbsorbance(obj): - if not obj.progressCrossSection: - obj.createCrossSection() - return obj.absorbance +def receiveMultiInput(inputText, validInputFunction, default=None): + validInput = False + while not validInput: + userInput = input(inputText) + inputList = userInput.replace(' ', '').split(',') + testInput = True + for item in inputList: + if not validInputFunction(item): + print('%s not recognized as valid. Please try again.') + testInput = False + if testInput: + return inputList + + +def validMoleculeName(userInput): + if not userInput: + return False + if userInput.strip().lower() == 'help': + util.displayAllMolecules() + return False + elif userInput in pyradClasses.MOLECULE_ID: + return userInput + else: + print('Invalid molecule name. %s' % (util.underlineMagenta('Please try again.'))) + return False -def getEmissivity(obj): - if not obj.progressCrossSection: - obj.createCrossSection() - return obj.emissivity +def validPressure(userInput): + if not userInput: + return False + try: + splitInput = validValueAndUnits.match(userInput) + except AttributeError: + print('Invalid input for pressure. Example: %s. %s' + % (util.limeText('1.35atm'), util.underlineMagenta('Please try again.'))) + return False + unit = splitInput.group(5) + if not unit: + unit = 'mbar' + unit = unit.lower() + if unit not in PRESSURE_UNITS: + print('Invalid units. Accepted units are %s.' % ', '.join(PRESSURE_UNITS)) + return False + textNumber = '' + for i in range(1, 5): + if splitInput.group(i): + textNumber += splitInput.group(i) -def getGlobalIsotope(ID, isotopeDepth): - globalIsoList = [] - for i in range(1, isotopeDepth + 1): - globalIsoList.append(HITRAN_GLOBAL_ISO[ID][i]) - return globalIsoList + value = float(textNumber) + return pyradClasses.convertPressure(value, unit) -def totalConcentration(layer): - total = 0 - for molecule in layer: - total += molecule.concentration - return total +def validComposition(userInput): + if not userInput: + return False + try: + splitInput = validValueAndUnits.match(userInput) + except AttributeError: + print('Invalid input for concentration. Example: %s. %s' + % (util.limeText('15ppb'), util.underlineMagenta('Please try again.'))) + return False + unit = splitInput.group(5) + if not unit: + unit = 'concentration' + if unit not in COMPOSITION_UNITS: + print('Invalid units. Accepted units are %s.' + % (util.limeText(', '.join(COMPOSITION_UNITS)))) + return False + textNumber = '' + for i in range(1, 5): + if splitInput.group(i): + textNumber += splitInput.group(i) + value = float(textNumber) + if value <= 0: + print('Concentration must be greater than 0') + return False + return value, unit -def totalLineList(obj): - fullList = [] - if isinstance(obj, Isotope): - return obj.linelist() - for item in obj: - fullList += totalLineList(item) - return fullList - - -def convertLength(value, units): - if units == 'cm': - return value - elif units in ['m', 'meter']: - return value * 100 - elif units in ['ft', 'feet']: - return value * 30.48 - elif units in ['in', 'inch']: - return value * 2.54 - - -def convertPressure(value, units): - if units == 'mbar': - return value - elif units in ['atm', 'atmospheres', 'atmosphere']: - return value * 1013.25 - elif units in ['b', 'bar']: - return value * 1000 - elif units in ['pa', 'pascal', 'pascals']: - return value / 100 - - -def convertRange(value, units): - if units == 'cm-1': - return value - elif units in ['um', 'micrometers', 'micrometer']: - return 10000 / value - - -def convertTemperature(value, units): - if units[0].upper() == 'K': - return value - elif units[0].upper() == 'C': - return value + 273 - elif units[0].upper() == 'F': - return (value - 32) * 5 / 9 + 273 - - -def interpolateArray(hiResXAxis, loResXAxis, loResYValues): - hiResY = np.interp(hiResXAxis, loResXAxis, loResYValues) - return hiResY - - -class Line: - def __init__(self, wavenumber, intensity, einsteinA, airHalfWidth, - selfHalfWidth, lowerEnergy, tempExponent, pressureShift, parent): - self.isotope = parent - self.molecule = self.isotope.molecule - self.layer = self.molecule.layer - self.wavenumber = wavenumber - self.intensity = intensity - self.einsteinA = einsteinA - self.airHalfWidth = airHalfWidth - self.selfHalfWidth = selfHalfWidth - self.lowerEnergy = lowerEnergy - self.tempExponent = tempExponent - self.pressureShift = pressureShift - - @property - def broadenedLine(self): - return self.wavenumber + self.pressureShift * self.layer.P / p0 - - @property - def lorentzHW(self): - return (float((1 - self.molecule.concentration) * self.airHalfWidth + self.molecule.concentration - * self.selfHalfWidth) * (self.layer.P / p0) * (t0 / self.layer.T) ** self.tempExponent) - - @property - def gaussianHW(self): - return self.broadenedLine * np.sqrt(2 * k * self.layer.T / self.isotope.molMass / c ** 2) - - -class Isotope(list): - def __init__(self, number, molecule): - super(Isotope, self).__init__(self) - params = utils.readMolParams(number) - self.globalIsoNumber = params[0] - self.shortName = params[1] - self.name = 'Isotope %s' % self.globalIsoNumber - self.molNum = params[2] - self.isoN = params[3] - self.abundance = params[4] - self.q296 = params[5] - self.gj = params[6] - self.molmass = params[7] - self.molecule = molecule - self.layer = self.molecule.layer - self.q = {} - self.crossSection = np.copy(self.layer.crossSection) - self.lineSurvey = np.zeros(int((self.layer.rangeMax - self.layer.rangeMin) / utils.BASE_RESOLUTION)) - self.progressCrossSection = False - - @property - def P(self): - return self.layer.P - - @property - def molMass(self): - return self.molmass / 1000 / avo - - @property - def T(self): - return self.layer.T - - @property - def depth(self): - return self.layer.depth - - @property - def rangeMin(self): - return self.layer.rangeMin - - @property - def rangeMax(self): - return self.layer.rangeMax - - @property - def resolution(self): - return self.layer.resolution - - @property - def distanceFromCenter(self): - return self.layer.distanceFromCenter - - @property - def absCoef(self): - return self.crossSection * self.molecule.concentration * self.layer.P / 1E4 / k / self.layer.T - - @property - def transmittance(self): - return np.exp(-self.absCoef * self.layer.depth) - - @property - def emissivity(self): - return 1 - self.transmittance - - @property - def emittance(self): - return self.emissivity - - @property - def absorbance(self): - return np.log10(1 / self.transmittance) - - @property - def yAxis(self): - return np.copy(self.layer.yAxis) - - @property - def xAxis(self): - return np.copy(self.layer.xAxis) - - def getData(self, lineSurvey=False, verbose=True): - if verbose: - print('Getting data for %s, %s, isotope %s' % (self.layer.name, self.molecule.name, self.globalIsoNumber), end='\r', flush=True) - lineDict = utils.gatherData(self.globalIsoNumber, self.layer.effectiveRangeMin, self.layer.effectiveRangeMax) - self.q = utils.getQData(self.globalIsoNumber) - for line in lineDict: - if lineDict[line]['intensity'] > settings.lineIntensityCutoff: - self.append(Line(line, lineDict[line]['intensity'], lineDict[line]['einsteinA'], - lineDict[line]['airHalfWidth'], lineDict[line]['selfHalfWidth'], - lineDict[line]['lowerEnergy'], lineDict[line]['tempExponent'], - lineDict[line]['pressureShift'], self)) - # self.createLineSurvey() - - def createCrossSection(self): - molecule = self.molecule - layer = molecule.layer - progress = 0 - i = 1 - alertInterval = int(len(self) / 20) - crossSection = np.copy(self.yAxis) - trackGauss = 0 - trackLorentz = 0 - trackVoigt = 0 - if len(self) == 0: - self.progressCrossSection = True - return - for line in self: - if progress > i * alertInterval and len(self) > 50: - text = 'Processing %s, height %skm, mean height %skm, molecule %s: <%s%s>' % (layer.name, round(layer.height / 100000, 2), round(layer.meanHeight / 100000, 2), - molecule.name, '*' * i, '-' * (20 - i)) - print(text, end='\r', flush=True) - i += 1 - progress += 1 - xValues = np.arange(0, layer.distanceFromCenter, layer.resolution) - hwRatio = line.lorentzHW / line.gaussianHW - if hwRatio < .01: - rightCurve = ls.gaussianLineShape(line.gaussianHW, xValues) - trackGauss += 1 - elif hwRatio > 100: - rightCurve = ls.lorentzLineShape(line.lorentzHW, xValues) - trackLorentz += 1 - else: - rightCurve = ls.pseudoVoigtShape(line.gaussianHW, line.lorentzHW, xValues) - trackVoigt += 1 - intensity = pyradIntensity.intensityFactor(line.intensity, line.broadenedLine, - layer.T, line.lowerEnergy, self.q[layer.T], self.q296) - arrayIndex = int((line.wavenumber - layer.rangeMin) / layer.resolution) - arrayLength = len(crossSection) - 1 - if isBetween(arrayIndex, 0, arrayLength): - crossSection[arrayIndex] = crossSection[arrayIndex] + rightCurve[0] * intensity - for dx in range(1, len(rightCurve) - 1): - rightIndex = arrayIndex + dx - leftIndex = arrayIndex - dx - if isBetween(rightIndex, 0, arrayLength): - crossSection[rightIndex] += rightCurve[dx] * intensity - if isBetween(leftIndex, 0, arrayLength): - crossSection[leftIndex] += rightCurve[dx] * intensity - self.crossSection = interpolateArray(self.xAxis, - np.linspace(self.rangeMin, self.rangeMax, - (self.rangeMax - self.rangeMin) / self.resolution, - endpoint=True), - crossSection) - self.progressCrossSection = True - - def createLineSurvey(self): - print('Creating line survey for %s' % self.name) - molecule = self.molecule - layer = molecule.layer - progress = 0 - i = 1 - alertInterval = int(len(self) / 20) - lineSurvey = np.zeros(int((self.rangeMax - self.rangeMin) / utils.BASE_RESOLUTION)) - for line in self: - if progress > i * alertInterval: - print('Progress for %s <%s%s>' % (molecule.name, '*' * i, '-' * (20 - i)), end='\r', flush=True) - i += 1 - progress += 1 - intensity = line.intensity - arrayIndex = int((line.wavenumber - layer.rangeMin) / layer.resolution) - arrayLength = len(lineSurvey) - 1 - if isBetween(arrayIndex, 0, arrayLength): - lineSurvey[arrayIndex] = lineSurvey[arrayIndex] + intensity - self.lineSurvey = lineSurvey - return self.lineSurvey - - def linelist(self): - lines = [] - for line in self: - lines.append(line) - return lines - - def planck(self, temperature): - return self.layer.planck(temperature) - - def transmission(self, surfaceSpectrum): - transmitted = self.transmittance * surfaceSpectrum - emitted = self.emittance * self.planck(self.T) - return transmitted + emitted - - def returnCopy(self): - return self.linelist() - - -class Molecule(list): - def __init__(self, shortNameOrMolNum, layer, isotopeDepth=1, **abundance): - super(Molecule, self).__init__(self) - self.layer = layer - self.crossSection = np.copy(layer.crossSection) - self.isotopeDepth = isotopeDepth - self.concText = '' - self.concentration = 0 - try: - int(shortNameOrMolNum) - self.ID = int(shortNameOrMolNum) - self.name = False - except ValueError: - self.name = shortNameOrMolNum - self.ID = MOLECULE_ID[self.name] - for isotope in getGlobalIsotope(self.ID, isotopeDepth): - isoClass = Isotope(isotope, self) - self.append(isoClass) - if not self.name: - self.name = isoClass.shortName - self.progressCrossSection = False - for key in abundance: - if key == 'ppm': - self.setPPM(abundance[key]) - elif key == 'ppb': - self.setPPB(abundance[key]) - elif key == 'percentage' or key == 'perc' or key == '%': - self.setPercentage(abundance[key]) - elif key == 'concentration': - self.setConcentration(abundance[key]) - else: - print('Invalid concentration type. Use ppm, ppb, percentage, or concentration.') - - def __str__(self): - return '%s: %s' % (self.name, self.concText) - - def __bool__(self): - return True - - def returnCopy(self): - valueUnit = self.concText.split() - tempDict = {valueUnit[1]: float(valueUnit[0])} - newMolecule = Molecule(self.name, self.layer, isotopeDepth=int(self.isotopeDepth), **tempDict) - newMolecule.getData(verbose=False) - return newMolecule - - def setPercentage(self, percentage): - self.concentration = percentage / 100 - self.concText = '%s %%' % percentage - resetCrossSection(self) - - def setPPM(self, ppm): - self.concentration = ppm * 10**-6 - self.concText = '%s ppm' % ppm - resetCrossSection(self) - - def setPPB(self, ppb): - self.concentration = ppb * 10**-8 - self.concText = '%s ppb' % ppb - resetCrossSection(self) - - def setConcentration(self, concentration): - self.setPPM(concentration * 1E6) - resetCrossSection(self) - - def getData(self, verbose=True): - for isotope in self: - isotope.getData(verbose) - - def createCrossSection(self): - tempAxis = np.zeros(int((self.rangeMax - self.rangeMin) / utils.BASE_RESOLUTION)) - for isotope in self: - tempAxis += getCrossSection(isotope) - self.progressCrossSection = True - self.crossSection = tempAxis - - def planck(self, temperature): - return self.layer.planck(temperature) - - def transmission(self, surfaceSpectrum): - transmitted = self.transmittance * surfaceSpectrum - emitted = self.emittance * self.planck(self.T) - return transmitted + emitted - - @property - def absCoef(self): - return self.crossSection * self.concentration * self.layer.P / 1E4 / k / self.layer.T - - @property - def transmittance(self): - return np.exp(-self.absCoef * self.layer.depth) - - @property - def lineSurvey(self): - tempAxis = np.zeros(int((self.rangeMax - self.rangeMin) / utils.BASE_RESOLUTION)) - for isotope in self: - tempAxis += isotope.lineSurvey - return tempAxis - - @property - def absorbance(self): - return np.log10(1 / self.transmittance) - - @property - def emissivity(self): - return 1 - self.transmittance - - @property - def emittance(self): - return self.emissivity - - @property - def P(self): - return self.layer.P - - @property - def yAxis(self): - return np.copy(self.layer.yAxis) - - @property - def xAxis(self): - return np.copy(self.layer.xAxis) - - @property - def T(self): - return self.layer.T - - @property - def depth(self): - return self.layer.depth - - @property - def rangeMin(self): - return self.layer.rangeMin - - @property - def rangeMax(self): - return self.layer.rangeMax - - @property - def resolution(self): - return self.layer.resolution - - @property - def distanceFromCenter(self): - return self.layer.distanceFromCenter - - @property - def molarMass(self): - return self[0].molmass - - -class Layer(list): - hasAtmosphere = False - - def __init__(self, depth, T, P, rangeMin, rangeMax, height=0.0, atmosphere=None, name='', dynamicResolution=True): - super(Layer, self).__init__(self) - self.rangeMin = rangeMin - self.rangeMax = rangeMax - self.T = T - self.P = P - self.depth = depth - self.distanceFromCenter = self.P / 1013.25 * 5 - self.effectiveRangeMin = max(self.rangeMin - self.distanceFromCenter, 0) - self.effectiveRangeMax = self.rangeMax + self.distanceFromCenter - self.dynamicResolution = dynamicResolution - self.surfaceSpectrum = None - self.height = height - if not dynamicResolution: - self.resolution = utils.BASE_RESOLUTION - else: - self.resolution = max(10**int(np.log10((self.P / 1013.25))) * .01, utils.BASE_RESOLUTION) - if not atmosphere: - if not Layer.hasAtmosphere: - self.atmosphere = Atmosphere('generic') - Layer.hasAtmosphere = self.atmosphere - else: - self.atmosphere = Layer.hasAtmosphere - else: - self.atmosphere = atmosphere - self.hasAtmosphere = atmosphere - self.crossSection = np.zeros(int((rangeMax - rangeMin) / utils.BASE_RESOLUTION)) - self.absorptionCoefficient = np.zeros(int((rangeMax - rangeMin) / utils.BASE_RESOLUTION)) - self.progressCrossSection = False - self.progressAbsCoef = False - if not name: - name = '%s' % self.atmosphere.nextLayerName() - self.atmosphere.append(self) - self.name = name - - def __str__(self): - return '%s; %s' % (self.name, '; '.join(str(m) for m in self)) - - def __bool__(self): - return True - - def createCrossSection(self): - tempAxis = np.zeros(int((self.rangeMax - self.rangeMin) / utils.BASE_RESOLUTION)) - for molecule in self: - tempAxis += getCrossSection(molecule) - self.progressCrossSection = True - self.crossSection = tempAxis - - def returnMolecule(self, name): - for m in self: - if m.name == name: - return m +def validTemperature(userInput): + if not userInput: + return False + try: + splitInput = validValueAndUnits.match(userInput) + except AttributeError: + print('Invalid input for temperature. Example: %s. %s' + % (util.limeText('20C'), util.underlineMagenta('Please try again.'))) return False + unit = splitInput.group(5) + if not unit: + unit = 'K' + unit = unit.upper()[0] + if unit not in TEMPERATURE_UNITS: + print('Invalid units. Accepted units are %s.' + % (util.limeText(', '.join(TEMPERATURE_UNITS)))) + return False + textNumber = '' + for i in range(1, 5): + if splitInput.group(i): + textNumber += splitInput.group(i) + value = float(textNumber) + return pyradClasses.convertTemperature(value, unit) - @property - def meanHeight(self): - return self.height + .5 * self.depth - - @property - def lineSurvey(self): - tempAxis = np.zeros(int((self.rangeMax - self.rangeMin) / utils.BASE_RESOLUTION)) - for molecule in self: - tempAxis += molecule.lineSurvey - return tempAxis - - @property - def yAxis(self): - return np.zeros(int((self.rangeMax - self.rangeMin) / self.resolution)) - - @property - def xAxis(self): - return np.linspace(self.rangeMin, self.rangeMax, (self.rangeMax - self.rangeMin) / utils.BASE_RESOLUTION, - endpoint=True) - - @property - def absCoef(self): - if not self.progressAbsCoef: - for molecule in self: - self.absorptionCoefficient += getAbsCoef(molecule) - self.progressAbsCoef = True - return self.absorptionCoefficient - - @property - def transmittance(self): - return np.exp(-self.absCoef * self.depth) - - @property - def absorbance(self): - return np.log10(1 / self.transmittance) - - @property - def title(self): - return '%s\nP: %smBars; T: %sK; depth: %scm' % (str(self), self.P, self.T, self.depth) - - @property - def emissivity(self): - return 1 - self.transmittance - - @property - def emittance(self): - return self.emissivity - - @property - def molarMass(self): - mass = 0 - for mol in self: - mass += mol.molarMass * mol.concentration - return mass - - @property - def density(self): - d = self.P * 100 / self.T / self.specGasConstant - return d - - @property - def mass(self): - return self.density * self.depth / 100 - - @property - def specGasConstant(self): - con = R * 1000 / self.molarMass - return con - - @property - def temperatureAtHeight(self): - return int(self.atmosphere.temperatureAtHeight(self.meanHeight)) - - @property - def pressureAtHeight(self): - return self.atmosphere.pressureAtHeight(self.meanHeight) - - @property - def densityAtHeight(self): - return self.atmosphere.densityAtHeight(self.temperatureAtHeight, self.specGasConstant) - - def changeRange(self, rangeMin, rangeMax): - self.rangeMin = rangeMin - self.rangeMax = rangeMax - self.effectiveRangeMax = self.rangeMax + self.distanceFromCenter - self.effectiveRangeMin = max(self.rangeMin - self.distanceFromCenter, 0) - resetData(self) - - def changeTemperature(self, temperature): - self.T = temperature - resetCrossSection(self) - - def changePressure(self, pressure): - self.P = pressure - self.distanceFromCenter = self.P / 1013.25 * 5 - if not self.dynamicResolution: - self.resolution = utils.BASE_RESOLUTION - else: - self.resolution = max(10**int(np.log10((self.P / 1013.25))) * .01, utils.BASE_RESOLUTION) - resetData(self) - - def changeDepth(self, depth): - self.depth = depth - - def addMolecule(self, name, isotopeDepth=1, **abundance): - molecule = Molecule(name, self, isotopeDepth, **abundance) - self.append(molecule) - if totalConcentration(self) > 1: - print('**Warning : Concentrations exceed 1.') - molecule.getData() - return molecule - - def returnCopy(self, name=None): - if not name: - name = self.atmosphere.nextLayerName() - newCopy = Layer(self.depth, self.T, self.P, self.rangeMin, self.rangeMax, height=self.height, - atmosphere=self.atmosphere, name=name, dynamicResolution=self.dynamicResolution) - for molecule in self: - newCopy.addMolecule(molecule.name, molecule.isotopeDepth, concentration=molecule.concentration) - print('%s copied to %s' % (self.name, newCopy.name)) - return newCopy - - def returnMoleculeObjects(self): - moleculeList = [] - for m in self: - moleculeList.append(m) - return moleculeList - - def planck(self, temperature): - return pyradPlanck.planckWavenumber(self.xAxis, temperature) - - def transmission(self, surfaceSpectrum): - transmitted = self.transmittance * surfaceSpectrum - emitted = self.emittance * self.planck(self.T) - return transmitted + emitted - - -class Atmosphere(list): - def __init__(self, name, rangeMin=0, rangeMax=0, planet=None): - super().__init__(self) - self.name = name - self.rangeMin = rangeMin - self.rangeMax = rangeMax - self.planet = planet - - def __str__(self): - return self.name - - def __bool__(self): - return True - - def addLayer(self, depth, T, P, rangeMin, rangeMax, name=None, dynamicResolution=True, height=0.0): - if not name: - name = self.nextLayerName() - newLayer = Layer(depth, T, P, rangeMin, rangeMax, atmosphere=self, name=name, - dynamicResolution=dynamicResolution, height=height) - return newLayer - - def nextLayerName(self): - return 'Layer %s' % (len(self) + 1) - - def returnLayerNames(self): - tempList = [] - for layer in self: - tempList.append(layer.name) - return tempList - - def returnLayerObjects(self): - if len(self) == 0: - return False - tempList = [] - for layer in self: - tempList.append(layer) - return tempList - - def temperatureAtHeight(self, height): - ruleList = self.planet.returnApplicableRules(height, 'temperature') - if len(ruleList) > 1: - print('Multiple rules found for height %s: %s' % (height, ruleList)) - rule = ruleList[0] - temperature = rule.rateFunction(rule.baseValue, rule.baseHeight, rule.rate, height) - return temperature - - def pressureAtHeight(self, height): - height = height / 100 - ruleList = self.planet.returnApplicableRules(height, 'temperature') - if len(ruleList) > 1: - print('Multiple rules found for height %s: %s' % (height, ruleList)) - rule = ruleList[0] - temperature = self.temperatureAtHeight(height) - if rule.rate != 0: - pressure = rule.basePressure * (rule.baseValue / temperature) ** \ - (self.planet.gravity * self.planet.molarMass / R / rule.rate) - else: - pressure = rule.basePressure * \ - np.exp(-self.planet.gravity * self.planet.molarMass * - (height - rule.baseHeight) / R / rule.baseValue) - return pressure - - def compositionAtHeight(self, height, molecule): - ruleList = self.planet.returnApplicableRules(height, 'composition') - if not ruleList: - return molecule.concentration - for rule in ruleList: - if rule.molecule.name == molecule.name: - concentration = rule.rateFunction(rule.baseValue, rule.baseHeight, rule.rate, height) - return concentration - return molecule.concentration - - def densityAtHeight(self, height, gasConstant): - temperature = self.temperatureAtHeight(height) - pressure = self.pressureAtHeight(height) - density = pressure * 100 / gasConstant / temperature - return density - - -class Planet: - def __init__(self, name, pressure, temperature, maxHeight, molarMass=0.0289644, - gravity=9.80665, rangeMin=0, rangeMax=2000, initialThickness=100): - self.name = name - self.mass = 0 - self.gravity = gravity - self.maxHeight = maxHeight * 100000 - self.molarMass = molarMass - self.radius = 0 - self.surfacePressure = pressure - self.surfaceTemperature = temperature - self.atmosphereRules = [] - self.heightList = [] - self.depthList = [] - self.rangeMin = rangeMin - self.rangeMax = rangeMax - self.atmosphere = Atmosphere("%s's atmosphere" % self.name, planet=self) - self.initialLayer = \ - self.atmosphere.addLayer(initialThickness * 100, temperature, pressure, rangeMin, rangeMax, - name='initial layer', height=0) - self.progressProfileLoaded = False - - def setMass(self, mass): - self.mass = mass - - def addLapseRate(self, name, finalHeight, finalValue, rateFunction=linear): - self.atmosphereRules.append(AtmosphereRule(name, finalHeight * 100000, - finalValue, 'temperature', self, rateFunction=rateFunction)) - - def addCompositionRate(self, name, finalHeight, finalValue, molecule, rateFunction=linear): - self.atmosphereRules.append(AtmosphereRule(name, finalHeight * 100000, finalValue, 'composition', self, - molecule=molecule, rateFunction=rateFunction)) - - def setRadius(self, radius): - self.radius = radius - - def setGravity(self, gravity): - self.gravity = gravity - - def setSurfacePressure(self, pressure): - self.surfacePressure = pressure - - def setSurfaceTemperature(self, temperature): - self.surfaceTemperature = temperature - - def setSurfaceComposition(self): - pass - - def returnApplicableRules(self, height, ruleType): - ruleList = [] - for rule in self.atmosphereRules: - if rule.isInRange(height, ruleType): - ruleList.append(rule) - if not ruleList: - return False - return ruleList - - def returnAllRulesOfType(self, ruleType): - ruleList = [] - for rule in self.atmosphereRules: - if rule.ruleType == ruleType: - ruleList.append(rule) - return ruleList - - def temperatureAtHeight(self, height): - return self.atmosphere.temperatureAtHeight(height) - - def pressureAtHeight(self, height): - return self.atmosphere.pressureAtHeight(height) - - def densityAtHeight(self, height): - return self.atmosphere.densityAtHeight(height) - - def compositionAtHeight(self, height, molecule): - return self.atmosphere.compositionAtHeight(height, molecule) - - def addMolecule(self, name, isotopeDepth=1, **abundance): - molecule = self.initialLayer.addMolecule(name, isotopeDepth, **abundance) - return molecule - - def sliceAtm(self, verify=True): - acceptSetup = False - layer = self.initialLayer - initialTemp = layer.T - initialPressure = layer.P - initialHeight = layer.height - initialDepth = layer.depth - while not acceptSetup: - mass = self.initialLayer.mass - print('%s, p %s, T %s, depth %s, height %s' % (layer.name, initialPressure, initialTemp, initialDepth, initialHeight)) - self.heightList = [layer.height] - tempList = [layer.T] - pressureList = [layer.P] - self.depthList = [layer.depth] - while layer.height + layer.depth < self.maxHeight: - print('%s: K: %s, mBar: %s, baseHeight: %skm, depth: %skm, mass: %skg' % ( - 'Layer %s' %len(self.heightList), int(layer.T), round(layer.P, 2), round(layer.height / 100000, 2), round(layer.depth / 100000, 2), round(layer.mass, 2))) - newHeight = self.heightList[-1] + self.depthList[-1] - tempList.append(self.temperatureAtHeight(newHeight)) - pressureList.append(self.pressureAtHeight(newHeight)) - layer.P = pressureList[-1] - layer.T = tempList[-1] - newDepth = (mass / layer.density * 100) - if newHeight + newDepth > self.maxHeight: - newDepth = self.maxHeight - newHeight - self.heightList.append(newHeight) - self.depthList.append(newDepth) - print('%s: K: %s, mBar: %s, baseHeight: %skm, depth: %skm, mass: %skg' % ( - 'Layer %s' % len(self.heightList), int(layer.T), round(layer.P, 2), - round(newHeight, 2), round(newDepth, 2), round(layer.mass, 2))) - break - else: - self.heightList.append(newHeight) - self.depthList.append(newDepth) - layer.height = newHeight - layer.depth = newDepth - '''if self.heightList[-1] + .5 * self.depthList[-1] > self.maxHeight: - self.heightList.pop() - self.depthList.pop()''' - print('Total # of layers: %s' % len(self.heightList)) - print('Total # of absorption lines per layer: %s' % len(totalLineList(layer))) - if verify: - if yesOrNo('Accept the current slicing (y/n): '): - acceptSetup = True - else: - validNumber = False - while not validNumber: - print( - 'Enter the new initial depth. Larger depth will decrease number of layers, smaller will increase') - userNumber = input('Current depth is %s:' % utils.limeText('%sm' % (int(self.depthList[0]) / 100))) - try: - newDepth = float(userNumber) - self.initialLayer.depth = newDepth * 100 - self.initialLayer.P = initialPressure - self.initialLayer.T = initialTemp - self.initialLayer.height = initialHeight - validNumber = True - except ValueError: - print('Invalid number.') - else: - acceptSetup = True - return - def processLayers(self, verify=True): - if utils.profileProgress(self.name): - self.sliceAtm(verify=False) - if not self.heightList: - self.sliceAtm(verify=verify) - layer = self.initialLayer - startPoint = utils.profileProgress(self.name) - i = startPoint + 1 - print('Incomplete profile found, resuming...') - for height, depth in zip(self.heightList[startPoint:], self.depthList[startPoint:]): - layer.name = 'Layer %s:%s' % (i, len(self.heightList)) - layer.height = height - layer.depth = depth - layer.T = int(self.temperatureAtHeight(layer.meanHeight)) - layer.P = self.pressureAtHeight(layer.meanHeight) - for molecule in layer: - molecule.concentration = self.compositionAtHeight(layer.meanHeight, molecule) - layer.createCrossSection() - utils.writePlanetProfile(self.name, layer) - utils.profileWriteProgress(self.name, i, len(self.heightList)) - resetCrossSection(layer) - layer.absorptionCoefficient = np.zeros(len(layer.crossSection)) - layer.progressAbsCoef = False - i += 1 - utils.profileWriteComplete(self.name, i, len(self.heightList)) - return +def validRange(userInput): + if not userInput: + return False + try: + splitInput = validValueAndUnits.match(userInput) + except AttributeError: + print('Invalid input for range. Example: %s. %s' + % (util.limeText('150cm-1'), util.underlineMagenta('Please try again.'))) + return False + unit = splitInput.group(5) + if not unit: + unit = 'cm-1' + unit = unit.lower() + if unit not in RANGE_UNITS: + print('Invalid units. Accepted units are %s' + % (util.limeText(', '.join(RANGE_UNITS)))) + return False + textNumber = '' + for i in range(1, 5): + if splitInput.group(i): + textNumber += splitInput.group(i) + value = float(textNumber) + return pyradClasses.convertRange(value, unit) - def loadProfile(self, verify=True): - if utils.profileComplete(self.name): - fileLength = utils.profileLength(self.name) - if verify: - if not yesOrNo('%s layers found for profile %s. Load profile (y/n):' % (fileLength, self.name)): - if yesOrNo('Are you sure, selecting yes will delete all previous profile data (y/n): '): - utils.emptyProfileDirectory(self.name) - self.processLayers() - else: - self.processLayers() - fileLength = utils.profileLength(self.name) - while len(self.atmosphere) > 0: - self.atmosphere.pop() - for i in range(1, fileLength + 1): - lP = utils.readPlanetProfile(self.name, i, fileLength) - layer = Layer(lP['depth'], lP['T'], lP['P'], lP['rangeMin'], lP['rangeMax'], height=lP['height'], name=lP['name']) - self.atmosphere.append(layer) - layer.absorptionCoefficient = np.asarray(lP['absCoef']) - layer.progressAbsCoef = True - print('') - self.progressProfileLoaded = True - return - def processTransmission(self, height, direction='down', verify=True): - if not self.progressProfileLoaded: - self.loadProfile(verify=verify) - height = height * 100000 - print('Processing atmosphere spectrum from %skm looking %s...' % (height / 100000, direction)) - if direction == 'down': - surfaceSpectrum = pyradPlanck.planckWavenumber(self.initialLayer.xAxis, self.surfaceTemperature) - for layer in self.atmosphere: - if layer.meanHeight < height: - surfaceSpectrum = layer.transmission(surfaceSpectrum) - print('Processing %s...' % (layer.name), end='\r', flush=True) - elif direction == 'up': - surfaceSpectrum = pyradPlanck.planckWavenumber(self.initialLayer.xAxis, 3) - for layer in reversed(self.atmosphere): - if layer.meanHeight > height: - surfaceSpectrum = layer.transmission(surfaceSpectrum) - print('Processing %s...\n' % (layer.name), layer.T, end='\r', flush=True) - print('') - print('total power of spectrum: %sWm-2' % int((integrateSpectrum(surfaceSpectrum) / 5.67E-8)**.25)) - return surfaceSpectrum - - @property - def yAxis(self): - return np.zeros(int((self.rangeMax - self.rangeMin) / utils.BASE_RESOLUTION)) - - @property - def xAxis(self): - return np.linspace(self.rangeMin, self.rangeMax, (self.rangeMax - self.rangeMin) / utils.BASE_RESOLUTION, - endpoint=True) - - @property - def atmChangePoints(self): - changePointList = [] - for rule in self.atmosphereRules: - changePointList.append(rule.finalHeight) - return sorted(changePointList) - - @property - def transmission(self): - return self.processTransmission(self.maxHeight) - - -def stefanB(power): - return (power / sb) ^ .25 - - -class AtmosphereRule: - def __init__(self, name, finalHeight, finalValue, ruleType, planetClass, molecule=None, rateFunction=linear): - self.name = name - self.ruleType = ruleType - self.parent = planetClass - self.baseHeight, self.baseValue, self.basePressure = self.setBaseValues(self.ruleType, molecule) - self.finalHeight = finalHeight - self.finalValue = finalValue - if rateFunction == linear: - self.rate = (self.finalValue - self.baseValue) / (self.finalHeight - self.baseHeight) - self.molecule = molecule - self.rateFunction = rateFunction - - def isInRange(self, height, ruleType): - return self.baseHeight < height <= self.finalHeight and self.ruleType == ruleType - - def baseHeightTemperatureRule(self): - height = 0 - temperature = self.parent.surfaceTemperature - pressure = self.parent.surfacePressure - tempRules = self.parent.returnAllRulesOfType(self.ruleType) - for rule in tempRules: - if rule.finalHeight > height: - height = rule.finalHeight - temperature = rule.finalValue - pressure = self.parent.pressureAtHeight(height) - return height, temperature, pressure - - def baseHeightCompositionRule(self, molecule): - height = 0 - pressure = self.parent.surfacePressure - concentration = molecule.concentration - compRules = self.parent.returnAllRulesOfType(self.ruleType) - for rule in compRules: - if rule.finalHeight > height and rule.molecule == molecule: - height = rule.finalHeight - concentration = rule.finalValue - return height, concentration, pressure - - def setBaseValues(self, ruleType, molecule): - if ruleType == 'temperature': - return self.baseHeightTemperatureRule() - elif ruleType == 'composition': - return self.baseHeightCompositionRule(molecule) - - -def returnPlot(obj, propertyToPlot): - if propertyToPlot == "transmittance": - yAxis = getTransmittance(obj), 1 - elif propertyToPlot == 'absorption coefficient': - yAxis = getAbsCoef(obj), 0 - elif propertyToPlot == 'cross section': - yAxis = getCrossSection(obj), 0 - elif propertyToPlot == 'absorbance': - yAxis = getAbsorbance(obj), 0 - elif propertyToPlot == 'optical depth': - yAxis = getOpticalDepth(obj), 0 - elif propertyToPlot == 'line survey': - yAxis = obj.lineSurvey, 0 - else: +def validDepth(userInput): + if not userInput: return False - return yAxis - - -def isBetween(test, minValue, maxValue): - if test >= minValue: - if test <= maxValue: - return True - return False - - -def plot(propertyToPlot, title, plotList, fill=False): - plt.figure(figsize=(10, 6), dpi=80) - plt.subplot(111, facecolor='xkcd:dark grey') - plt.xlabel('wavenumber cm-1') - plt.margins(0.01) - plt.subplots_adjust(left=.07, bottom=.08, right=.97, top=.90) - plt.ylabel(propertyToPlot) - if propertyToPlot == 'line survey': - plt.yscale('log') - plt.grid('grey', linewidth=.5, linestyle=':') - plt.title('%s' % title) - handles = [] - linewidth = 1.2 - alpha = .7 - for singlePlot, color in zip(plotList, COLOR_LIST): - yAxis, fillAxis = returnPlot(singlePlot, propertyToPlot) - fig, = plt.plot(singlePlot.xAxis, smooth(yAxis, 50), linewidth=linewidth, alpha=alpha, color=color, - label='%s' % singlePlot.name) - handles.append(fig) - plt.fill_between(singlePlot.xAxis, fillAxis, yAxis, color=color, alpha=.3 * fill) - linewidth = .7 - alpha = .5 - legend = plt.legend(handles=handles, frameon=False) - text = legend.get_texts() - plt.setp(text, color='w') - plt.show() - - -def plotSpectrum(layer=None, title=None, rangeMin=None, rangeMax=None, objList=None, surfaceSpectrum=None, - planckTemperatureList=None, planckType='wavenumber'): - plt.figure(figsize=(10, 6), dpi=80) - plt.subplot(111, facecolor='xkcd:dark grey') - plt.margins(0.01) - plt.subplots_adjust(left=.07, bottom=.08, right=.97, top=.90) - if layer: - rangeMin = layer.rangeMin - rangeMax = layer.rangeMax - title = layer.title - if planckType == 'wavenumber': - plt.xlabel('wavenumber cm-1') - plt.ylabel('Radiance Wm-2sr-1(cm-1)-1') - planckFunction = pyradPlanck.planckWavenumber - xAxis = np.linspace(rangeMin, rangeMax, (rangeMax - rangeMin) / utils.BASE_RESOLUTION) - elif planckType == 'Hz': - plt.xlabel('Hertz') - plt.ylabel('Radiance Wm-2sr-1Hz-1') - planckFunction = pyradPlanck.planckHz - xAxis = np.linspace(rangeMin, rangeMax, 1000) - else: - plt.xlabel('wavelength um') - plt.ylabel('Radiance Wm-2sr-1um-1') - planckFunction = pyradPlanck.planckWavelength - xAxis = np.linspace(rangeMin, rangeMax, (rangeMax - rangeMin) / utils.BASE_RESOLUTION) - plt.title('%s' % title) - handles = [] - blue = .3 - red = 1 - green = .6 - dr = -.15 - db = .15 - dg = .15 - if not rangeMax: - xAxis = layer.xAxis - for temperature in planckTemperatureList: - yAxis = planckFunction(xAxis, float(temperature)) - fig, = plt.plot(xAxis, yAxis, linewidth=.75, color=(red, green, blue), - linestyle=':', label='%sK : %sWm-2' % - (temperature, round(integrateSpectrum(yAxis, res=(rangeMax - rangeMin) / len(yAxis)), 2))) - handles.append(fig) - if red + dr < 0 or red + dr > 1: - dr *= -1 - if green + dg > 1 or green + dg < 0: - dg *= -1 - if blue + db > 1 or blue + db < 0: - db *= -1 - red += dr - green += dg - blue += db - if red < .3 and green < .3 and blue < .3: - green += .5 - blue += .2 - if red < .3 and green < .3: - green += .4 - if objList: - alpha = .7 - linewidth = 1.2 - for obj, color in zip(objList, COLOR_LIST): - yAxis = obj.transmission(surfaceSpectrum) - fig, = plt.plot(layer.xAxis, yAxis, linewidth=linewidth, - alpha=alpha, color=color, - label='%s : %sWm-2' % (obj.name, round(integrateSpectrum(yAxis, pi), 2))) - handles.append(fig) - alpha = .5 - linewidth = 1 - legend = plt.legend(handles=handles, frameon=False) - text = legend.get_texts() - plt.setp(text, color='w') - plt.show() - - -def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=[300, 280, 250, 210, 170], verify=True, integrateRange=[]): - linewidth = .5 - alpha = .7 - plt.figure(figsize=(10, 6), dpi=80) - plt.subplot(111, facecolor='xkcd:almost black') - plt.margins(0.01) - plt.subplots_adjust(left=.07, bottom=.08, right=.97, top=.90) - plt.ylabel('Radiance Wm-2sr-1(cm-1)-1') - handles = [] - heightFlag = True - if height is None: - heightFlag = False - for planet, color in zip(planets, COLOR_LIST[1:]): - if not heightFlag: - height = planet.maxHeight / 100000 - xAxis = planet.xAxis - #xAxis = np.linspace(planet.rangeMin, planet.rangeMax, planet.rangeMax - planet.rangeMin) - yAxis = planet.processTransmission(height, direction=direction, verify=verify) - #yAxis = reduceRes(planet.processTransmission(height, direction=direction, verify=verify)) - fig, = plt.plot(xAxis, smooth(yAxis, 75), linewidth=linewidth, - alpha=alpha, color=color, - label='%s : %sWm-2' % (planet.name, round(integrateSpectrum(yAxis, pi), 2))) - #fig, = plt.plot(xAxis, yAxis, linewidth=linewidth, - # alpha=alpha, color=color, - # label='%s : %sWm-2' % (planet.name, round(integrateSpectrum(yAxis, pi), 2))) - handles.append(fig) - color = 1 - for temperature in temperatureList: - yAxis = pyradPlanck.planckWavenumber(xAxis, float(temperature)) - fig, = plt.plot(xAxis, yAxis, linewidth=.75, color=(color, color, color), alpha=alpha, - linestyle=':', label='%sK : %sWm-2' % - (temperature, - round(integrateSpectrum(yAxis, pi), 2))) - handles.append(fig) - color -= .15 - legend = plt.legend(handles=handles, frameon=False) - text = legend.get_texts() - plt.setp(text, color='w') - plt.show() - - -HITRAN_GLOBAL_ISO = {1: {1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 129}, - 2: {1: 7, 2: 8, 3: 9, 4: 10, 5: 11, 6: 12, 7: 13, 8: 14, 9: 121, 10: 15, 11: 120, 12: 122}, - 3: {1: 16, 2: 17, 3: 18, 4: 19, 5: 20}, - 4: {1: 21, 2: 22, 3: 23, 4: 24, 5: 25, }, - 5: {1: 26, 2: 27, 3: 28, 4: 29, 5: 30, 6: 31}, - 6: {1: 32, 2: 33, 3: 34, 4: 35}, - 7: {1: 36, 2: 37, 3: 38}, - 8: {1: 39, 2: 40, 3: 41}, - 9: {1: 42, 2: 43}, - 10: {1: 44}, - 11: {1: 45, 2: 46}, - 12: {1: 47, 2: 117}, - 13: {1: 48, 2: 49, 3: 50}, - 14: {1: 51, 2: 110}, - 15: {1: 52, 2: 53, 3: 107, 4: 108}, - 16: {1: 19, 2: 11, 3: 111, 4: 112}, - 17: {1: 56, 2: 113}, - 18: {1: 57, 2: 58}, - 19: {1: 59, 2: 60, 3: 61, 4: 62, 5: 63}, - 20: {1: 64, 2: 65, 3: 66}, - 21: {1: 67, 2: 68}, - 22: {1: 69, 2: 118}, - 23: {1: 70, 2: 71, 3: 72}, - 24: {1: 73, 2: 74}, - 25: {1: 75}, - 26: {1: 76, 2: 77, 3: 105}, - 27: {1: 78, 2: 106}, - 28: {1: 79}, - 29: {1: 80, 2: 119}, - 30: {1: 126}, - 31: {1: 81, 2: 82, 3: 83}, - 32: {1: 84}, - 33: {1: 85}, - 34: {1: 86}, - 35: {1: 127, 2: 128}, - 36: {1: 87}, - 37: {1: 88, 2: 89}, - 38: {1: 90, 2: 91}, - 39: {1: 92}, - 40: {1: 93, 2: 94}, - 41: {1: 95}, - 42: {1: 96}, - 43: {1: 116}, - 44: {1: 109}, - 45: {1: 103, 2: 115}, - 46: {1: 97, 2: 98, 3: 99, 4: 100}, - 47: {1: 114}, - 48: {1: 123}, - 49: {1: 124, 2: 125}, - 901: {1: 901}} - -COLOR_LIST = ['xkcd:white', - 'xkcd:bright orange', - 'xkcd:seafoam green', - 'xkcd:bright blue', - 'xkcd:salmon', - 'xkcd:light violet', - 'xkcd:green yellow'] - -VERSION = utils.VERSION - -MOLECULE_ID = {'h2o': 1, 'co2': 2, 'o3': 3, 'n2o': 4, 'co': 5, - 'ch4': 6, 'o2': 7, 'no': 8, 'so2': 9, - 'no2': 10, 'nh3': 11, 'hno3': 12, 'oh': 13, - 'hf': 14, 'hcl': 15, 'hbr': 16, 'hi': 17, - 'clo': 18, 'ocs': 19, 'h2co': 20, 'hocl': 21, - 'n2': 22, 'hcn': 23, 'ch3cl': 24, 'h2o2': 25, - 'c2h2': 26, 'c2h6': 27, 'ph3': 28, 'cof2': 29, - 'sf6': 30, 'h2s': 31, 'hcooh': 32, 'ho2': 33, - 'o': 34, 'clono2': 35, 'no+': 36, 'hobr': 37, - 'c2h4': 38, 'ch3oh': 39, 'ch3br': 40, 'ch3cn': 41, - 'cf4': 42, 'c4h2': 43, 'hc3n': 44, 'h2': 45, - 'cs': 46, 'so3': 47, 'c2n2': 48, 'cocl2': 49, - 'ar': 901} - - -if __name__ == 'main': - pyradInteractive.menuMain() + try: + splitInput = validValueAndUnits.match(userInput) + except AttributeError: + print('Invalid input for depth. Example: %s. %s' + % (util.limeText('10cm'), util.underlineMagenta('Please try again.'))) + return False + unit = splitInput.group(5) + if not unit: + unit = 'cm' + unit = unit.lower() + if unit not in DEPTH_UNITS: + print('Invalid units. Accepted units are %s' + % (util.limeText(', '.join(DEPTH_UNITS)))) + return False + textNumber = '' + for i in range(1, 5): + if splitInput.group(i): + textNumber += splitInput.group(i) + value = float(textNumber) + return pyradClasses.convertLength(value, unit) + + +DEPTH_UNITS = ['cm', 'in', 'inches', 'ft', 'feet', 'meter', 'm'] +PRESSURE_UNITS = ['atm', 'bar', 'mbar', 'pa'] +TEMPERATURE_UNITS = ['K', 'C', 'F'] +RANGE_UNITS = ['um', 'cm-1'] +COMPOSITION_UNITS = ['ppm', 'ppb', '%', 'percentage', 'perc', 'concentration'] + +while True: + menuMain() diff --git a/pyradClasses.py b/pyradClasses.py new file mode 100644 index 0000000..e532fa4 --- /dev/null +++ b/pyradClasses.py @@ -0,0 +1,1385 @@ +import pyradUtilities as utils +import pyradLineshape as ls +import pyradIntensity +import pyradPlanck +import numpy as np +import matplotlib.pyplot as plt + + +c = 299792458.0 +k = 1.38064852E-23 +h = 6.62607004e-34 +pi = 3.141592653589793 +R = 8.3144598 +t0 = 296 +p0 = 1013.25 +avo = 6.022140857E23 +sb = 5.67E-8 + +settings = utils.Settings('low') + + +def reduceRes(array, lumpTo=1): + n = int(lumpTo / settings.baseRes) + length = int(len(array) * settings.baseRes) + newArray = np.zeros(length) + for m in range(0, length): + for i in range(0, n): + newArray[m] += array[m * n + i] / n + return newArray + + + +def createCustomPlanet(name): + + initialParameters = utils.parseCustomProfile(name) + initialValues = initialParameters['initialValues'] + moleculeList = initialParameters['molecules'] + temperatureRuleList = initialParameters['temperatureRules'] + compositionRuleList = initialParameters['compositionRules'] + + try: + value = initialParameters['setting'] + except KeyError: + value = 'low' + + settings.changeSetting(value) + planet = Planet(initialParameters['name'], initialValues['surfacePressure'], initialValues['surfaceTemperature'], + initialValues['maxHeight'], rangeMin=initialValues['rangeMin'], + rangeMax=initialValues['rangeMax'], initialThickness=initialValues['initialDepth'], gravity=initialValues['gravity']) + + for molecule in moleculeList: + planet.addMolecule(molecule['name'], concentration=molecule['concentration']) + + for rule in temperatureRuleList: + planet.addLapseRate(rule['name'], rule['finalHeight'], rule['finalValue']) + + for rule in compositionRuleList: + initalLayer = planet.initialLayer + molecule = initalLayer.returnMolecule(rule['moleculeName']) + planet.addCompositionRate(rule['name'], rule['finalHeight'], rule['finalValue'], molecule) + return planet + + +def yesOrNo(promptText): + validInput = False + while not validInput: + userSelection = input(promptText) + if not userSelection: + pass + elif userSelection.lower()[0] == 'y': + return True + elif userSelection.lower()[0] == 'n': + return False + else: + print('Invalid choice.') + + +def smooth(y, box_pts): + box = np.ones(box_pts)/box_pts + y_smooth = np.convolve(y, box, mode='same') + return y_smooth + + +def linear(baseValue, baseHeight, rate, height): + newValue = baseValue + rate * (height - baseHeight) + return newValue + + +def integrateSpectrum(spectrum, unitAngle=pi, res=utils.BASE_RESOLUTION): + value = np.sum(np.nan_to_num(spectrum)) + value = value * unitAngle * res + return value + + +def getCrossSection(obj): + if not obj.progressCrossSection: + obj.createCrossSection() + return obj.crossSection + + +def resetCrossSection(obj): + if not obj.progressCrossSection: + return + obj.crossSection = np.zeros(int((obj.rangeMax - obj.rangeMin) / utils.BASE_RESOLUTION)) + obj.progressCrossSection = False + for child in obj: + if not isinstance(child, Line): + resetCrossSection(child) + + +def resetData(obj): + # clears the existing line data from parent object down to isotope, and then reloads the data using getData + # use this if layer ranges get changed. Will also clear the cross section data of the obj. + for child in obj: + if isinstance(child, Isotope): + while len(child) > 0: + child.pop() + child.getData() + else: + resetData(child) + resetCrossSection(obj) + + +def getAbsCoef(obj): + if not obj.progressCrossSection: + obj.createCrossSection() + return obj.absCoef + + +def getTransmittance(obj): + if not obj.progressCrossSection: + obj.createCrossSection() + return obj.transmittance + + +def getOpticalDepth(obj): + if not obj.progressCrossSection: + obj.createCrossSection() + return -np.log(obj.transmittance) + + +def getAbsorbance(obj): + if not obj.progressCrossSection: + obj.createCrossSection() + return obj.absorbance + + +def getEmissivity(obj): + if not obj.progressCrossSection: + obj.createCrossSection() + return obj.emissivity + + +def getGlobalIsotope(ID, isotopeDepth): + globalIsoList = [] + for i in range(1, isotopeDepth + 1): + globalIsoList.append(HITRAN_GLOBAL_ISO[ID][i]) + return globalIsoList + + +def totalConcentration(layer): + total = 0 + for molecule in layer: + total += molecule.concentration + return total + + +def totalLineList(obj): + fullList = [] + if isinstance(obj, Isotope): + return obj.linelist() + for item in obj: + fullList += totalLineList(item) + return fullList + + +def convertLength(value, units): + if units == 'cm': + return value + elif units in ['m', 'meter']: + return value * 100 + elif units in ['ft', 'feet']: + return value * 30.48 + elif units in ['in', 'inch']: + return value * 2.54 + + +def convertPressure(value, units): + if units == 'mbar': + return value + elif units in ['atm', 'atmospheres', 'atmosphere']: + return value * 1013.25 + elif units in ['b', 'bar']: + return value * 1000 + elif units in ['pa', 'pascal', 'pascals']: + return value / 100 + + +def convertRange(value, units): + if units == 'cm-1': + return value + elif units in ['um', 'micrometers', 'micrometer']: + return 10000 / value + + +def convertTemperature(value, units): + if units[0].upper() == 'K': + return value + elif units[0].upper() == 'C': + return value + 273 + elif units[0].upper() == 'F': + return (value - 32) * 5 / 9 + 273 + + +def interpolateArray(hiResXAxis, loResXAxis, loResYValues): + hiResY = np.interp(hiResXAxis, loResXAxis, loResYValues) + return hiResY + + +class Line: + def __init__(self, wavenumber, intensity, einsteinA, airHalfWidth, + selfHalfWidth, lowerEnergy, tempExponent, pressureShift, parent): + self.isotope = parent + self.molecule = self.isotope.molecule + self.layer = self.molecule.layer + self.wavenumber = wavenumber + self.intensity = intensity + self.einsteinA = einsteinA + self.airHalfWidth = airHalfWidth + self.selfHalfWidth = selfHalfWidth + self.lowerEnergy = lowerEnergy + self.tempExponent = tempExponent + self.pressureShift = pressureShift + + @property + def broadenedLine(self): + return self.wavenumber + self.pressureShift * self.layer.P / p0 + + @property + def lorentzHW(self): + return (float((1 - self.molecule.concentration) * self.airHalfWidth + self.molecule.concentration + * self.selfHalfWidth) * (self.layer.P / p0) * (t0 / self.layer.T) ** self.tempExponent) + + @property + def gaussianHW(self): + return self.broadenedLine * np.sqrt(2 * k * self.layer.T / self.isotope.molMass / c ** 2) + + +class Isotope(list): + def __init__(self, number, molecule): + super(Isotope, self).__init__(self) + params = utils.readMolParams(number) + self.globalIsoNumber = params[0] + self.shortName = params[1] + self.name = 'Isotope %s' % self.globalIsoNumber + self.molNum = params[2] + self.isoN = params[3] + self.abundance = params[4] + self.q296 = params[5] + self.gj = params[6] + self.molmass = params[7] + self.molecule = molecule + self.layer = self.molecule.layer + self.q = {} + self.crossSection = np.copy(self.layer.crossSection) + self.lineSurvey = np.zeros(int((self.layer.rangeMax - self.layer.rangeMin) / utils.BASE_RESOLUTION)) + self.progressCrossSection = False + + @property + def P(self): + return self.layer.P + + @property + def molMass(self): + return self.molmass / 1000 / avo + + @property + def T(self): + return self.layer.T + + @property + def depth(self): + return self.layer.depth + + @property + def rangeMin(self): + return self.layer.rangeMin + + @property + def rangeMax(self): + return self.layer.rangeMax + + @property + def resolution(self): + return self.layer.resolution + + @property + def distanceFromCenter(self): + return self.layer.distanceFromCenter + + @property + def absCoef(self): + return self.crossSection * self.molecule.concentration * self.layer.P / 1E4 / k / self.layer.T + + @property + def transmittance(self): + return np.exp(-self.absCoef * self.layer.depth) + + @property + def emissivity(self): + return 1 - self.transmittance + + @property + def emittance(self): + return self.emissivity + + @property + def absorbance(self): + return np.log10(1 / self.transmittance) + + @property + def yAxis(self): + return np.copy(self.layer.yAxis) + + @property + def xAxis(self): + return np.copy(self.layer.xAxis) + + def getData(self, lineSurvey=False, verbose=True): + if verbose: + print('Getting data for %s, %s, isotope %s' % (self.layer.name, self.molecule.name, self.globalIsoNumber), end='\r', flush=True) + lineDict = utils.gatherData(self.globalIsoNumber, self.layer.effectiveRangeMin, self.layer.effectiveRangeMax) + self.q = utils.getQData(self.globalIsoNumber) + for line in lineDict: + if lineDict[line]['intensity'] > settings.lineIntensityCutoff: + self.append(Line(line, lineDict[line]['intensity'], lineDict[line]['einsteinA'], + lineDict[line]['airHalfWidth'], lineDict[line]['selfHalfWidth'], + lineDict[line]['lowerEnergy'], lineDict[line]['tempExponent'], + lineDict[line]['pressureShift'], self)) + # self.createLineSurvey() + + def createCrossSection(self): + molecule = self.molecule + layer = molecule.layer + progress = 0 + i = 1 + alertInterval = int(len(self) / 20) + crossSection = np.copy(self.yAxis) + trackGauss = 0 + trackLorentz = 0 + trackVoigt = 0 + if len(self) == 0: + self.progressCrossSection = True + return + for line in self: + if progress > i * alertInterval and len(self) > 50: + text = 'Processing %s, height %skm, mean height %skm, molecule %s: <%s%s>' % (layer.name, round(layer.height / 100000, 2), round(layer.meanHeight / 100000, 2), + molecule.name, '*' * i, '-' * (20 - i)) + print(text, end='\r', flush=True) + i += 1 + progress += 1 + xValues = np.arange(0, layer.distanceFromCenter, layer.resolution) + hwRatio = line.lorentzHW / line.gaussianHW + if hwRatio < .01: + rightCurve = ls.gaussianLineShape(line.gaussianHW, xValues) + trackGauss += 1 + elif hwRatio > 100: + rightCurve = ls.lorentzLineShape(line.lorentzHW, xValues) + trackLorentz += 1 + else: + rightCurve = ls.pseudoVoigtShape(line.gaussianHW, line.lorentzHW, xValues) + trackVoigt += 1 + intensity = pyradIntensity.intensityFactor(line.intensity, line.broadenedLine, + layer.T, line.lowerEnergy, self.q[layer.T], self.q296) + arrayIndex = int((line.wavenumber - layer.rangeMin) / layer.resolution) + arrayLength = len(crossSection) - 1 + if isBetween(arrayIndex, 0, arrayLength): + crossSection[arrayIndex] = crossSection[arrayIndex] + rightCurve[0] * intensity + for dx in range(1, len(rightCurve) - 1): + rightIndex = arrayIndex + dx + leftIndex = arrayIndex - dx + if isBetween(rightIndex, 0, arrayLength): + crossSection[rightIndex] += rightCurve[dx] * intensity + if isBetween(leftIndex, 0, arrayLength): + crossSection[leftIndex] += rightCurve[dx] * intensity + self.crossSection = interpolateArray(self.xAxis, + np.linspace(self.rangeMin, self.rangeMax, + (self.rangeMax - self.rangeMin) / self.resolution, + endpoint=True), + crossSection) + self.progressCrossSection = True + + def createLineSurvey(self): + print('Creating line survey for %s' % self.name) + molecule = self.molecule + layer = molecule.layer + progress = 0 + i = 1 + alertInterval = int(len(self) / 20) + lineSurvey = np.zeros(int((self.rangeMax - self.rangeMin) / utils.BASE_RESOLUTION)) + for line in self: + if progress > i * alertInterval: + print('Progress for %s <%s%s>' % (molecule.name, '*' * i, '-' * (20 - i)), end='\r', flush=True) + i += 1 + progress += 1 + intensity = line.intensity + arrayIndex = int((line.wavenumber - layer.rangeMin) / layer.resolution) + arrayLength = len(lineSurvey) - 1 + if isBetween(arrayIndex, 0, arrayLength): + lineSurvey[arrayIndex] = lineSurvey[arrayIndex] + intensity + self.lineSurvey = lineSurvey + return self.lineSurvey + + def linelist(self): + lines = [] + for line in self: + lines.append(line) + return lines + + def planck(self, temperature): + return self.layer.planck(temperature) + + def transmission(self, surfaceSpectrum): + transmitted = self.transmittance * surfaceSpectrum + emitted = self.emittance * self.planck(self.T) + return transmitted + emitted + + def returnCopy(self): + return self.linelist() + + +class Molecule(list): + def __init__(self, shortNameOrMolNum, layer, isotopeDepth=1, **abundance): + super(Molecule, self).__init__(self) + self.layer = layer + self.crossSection = np.copy(layer.crossSection) + self.isotopeDepth = isotopeDepth + self.concText = '' + self.concentration = 0 + try: + int(shortNameOrMolNum) + self.ID = int(shortNameOrMolNum) + self.name = False + except ValueError: + self.name = shortNameOrMolNum + self.ID = MOLECULE_ID[self.name] + for isotope in getGlobalIsotope(self.ID, isotopeDepth): + isoClass = Isotope(isotope, self) + self.append(isoClass) + if not self.name: + self.name = isoClass.shortName + self.progressCrossSection = False + for key in abundance: + if key == 'ppm': + self.setPPM(abundance[key]) + elif key == 'ppb': + self.setPPB(abundance[key]) + elif key == 'percentage' or key == 'perc' or key == '%': + self.setPercentage(abundance[key]) + elif key == 'concentration': + self.setConcentration(abundance[key]) + else: + print('Invalid concentration type. Use ppm, ppb, percentage, or concentration.') + + def __str__(self): + return '%s: %s' % (self.name, self.concText) + + def __bool__(self): + return True + + def returnCopy(self): + valueUnit = self.concText.split() + tempDict = {valueUnit[1]: float(valueUnit[0])} + newMolecule = Molecule(self.name, self.layer, isotopeDepth=int(self.isotopeDepth), **tempDict) + newMolecule.getData(verbose=False) + return newMolecule + + def setPercentage(self, percentage): + self.concentration = percentage / 100 + self.concText = '%s %%' % percentage + resetCrossSection(self) + + def setPPM(self, ppm): + self.concentration = ppm * 10**-6 + self.concText = '%s ppm' % ppm + resetCrossSection(self) + + def setPPB(self, ppb): + self.concentration = ppb * 10**-8 + self.concText = '%s ppb' % ppb + resetCrossSection(self) + + def setConcentration(self, concentration): + self.setPPM(concentration * 1E6) + resetCrossSection(self) + + def getData(self, verbose=True): + for isotope in self: + isotope.getData(verbose) + + def createCrossSection(self): + tempAxis = np.zeros(int((self.rangeMax - self.rangeMin) / utils.BASE_RESOLUTION)) + for isotope in self: + tempAxis += getCrossSection(isotope) + self.progressCrossSection = True + self.crossSection = tempAxis + + def planck(self, temperature): + return self.layer.planck(temperature) + + def transmission(self, surfaceSpectrum): + transmitted = self.transmittance * surfaceSpectrum + emitted = self.emittance * self.planck(self.T) + return transmitted + emitted + + @property + def absCoef(self): + return self.crossSection * self.concentration * self.layer.P / 1E4 / k / self.layer.T + + @property + def transmittance(self): + return np.exp(-self.absCoef * self.layer.depth) + + @property + def lineSurvey(self): + tempAxis = np.zeros(int((self.rangeMax - self.rangeMin) / utils.BASE_RESOLUTION)) + for isotope in self: + tempAxis += isotope.lineSurvey + return tempAxis + + @property + def absorbance(self): + return np.log10(1 / self.transmittance) + + @property + def emissivity(self): + return 1 - self.transmittance + + @property + def emittance(self): + return self.emissivity + + @property + def P(self): + return self.layer.P + + @property + def yAxis(self): + return np.copy(self.layer.yAxis) + + @property + def xAxis(self): + return np.copy(self.layer.xAxis) + + @property + def T(self): + return self.layer.T + + @property + def depth(self): + return self.layer.depth + + @property + def rangeMin(self): + return self.layer.rangeMin + + @property + def rangeMax(self): + return self.layer.rangeMax + + @property + def resolution(self): + return self.layer.resolution + + @property + def distanceFromCenter(self): + return self.layer.distanceFromCenter + + @property + def molarMass(self): + return self[0].molmass + + +class Layer(list): + hasAtmosphere = False + + def __init__(self, depth, T, P, rangeMin, rangeMax, height=0.0, atmosphere=None, name='', dynamicResolution=True): + super(Layer, self).__init__(self) + self.rangeMin = rangeMin + self.rangeMax = rangeMax + self.T = T + self.P = P + self.depth = depth + self.distanceFromCenter = self.P / 1013.25 * 5 + self.effectiveRangeMin = max(self.rangeMin - self.distanceFromCenter, 0) + self.effectiveRangeMax = self.rangeMax + self.distanceFromCenter + self.dynamicResolution = dynamicResolution + self.surfaceSpectrum = None + self.height = height + if not dynamicResolution: + self.resolution = utils.BASE_RESOLUTION + else: + self.resolution = max(10**int(np.log10((self.P / 1013.25))) * .01, utils.BASE_RESOLUTION) + if not atmosphere: + if not Layer.hasAtmosphere: + self.atmosphere = Atmosphere('generic') + Layer.hasAtmosphere = self.atmosphere + else: + self.atmosphere = Layer.hasAtmosphere + else: + self.atmosphere = atmosphere + self.hasAtmosphere = atmosphere + self.crossSection = np.zeros(int((rangeMax - rangeMin) / utils.BASE_RESOLUTION)) + self.absorptionCoefficient = np.zeros(int((rangeMax - rangeMin) / utils.BASE_RESOLUTION)) + self.progressCrossSection = False + self.progressAbsCoef = False + if not name: + name = '%s' % self.atmosphere.nextLayerName() + self.atmosphere.append(self) + self.name = name + + def __str__(self): + return '%s; %s' % (self.name, '; '.join(str(m) for m in self)) + + def __bool__(self): + return True + + def createCrossSection(self): + tempAxis = np.zeros(int((self.rangeMax - self.rangeMin) / utils.BASE_RESOLUTION)) + for molecule in self: + tempAxis += getCrossSection(molecule) + self.progressCrossSection = True + self.crossSection = tempAxis + + def returnMolecule(self, name): + for m in self: + if m.name == name: + return m + return False + + @property + def meanHeight(self): + return self.height + .5 * self.depth + + @property + def lineSurvey(self): + tempAxis = np.zeros(int((self.rangeMax - self.rangeMin) / utils.BASE_RESOLUTION)) + for molecule in self: + tempAxis += molecule.lineSurvey + return tempAxis + + @property + def yAxis(self): + return np.zeros(int((self.rangeMax - self.rangeMin) / self.resolution)) + + @property + def xAxis(self): + return np.linspace(self.rangeMin, self.rangeMax, (self.rangeMax - self.rangeMin) / utils.BASE_RESOLUTION, + endpoint=True) + + @property + def absCoef(self): + if not self.progressAbsCoef: + for molecule in self: + self.absorptionCoefficient += getAbsCoef(molecule) + self.progressAbsCoef = True + return self.absorptionCoefficient + + @property + def transmittance(self): + return np.exp(-self.absCoef * self.depth) + + @property + def absorbance(self): + return np.log10(1 / self.transmittance) + + @property + def title(self): + return '%s\nP: %smBars; T: %sK; depth: %scm' % (str(self), self.P, self.T, self.depth) + + @property + def emissivity(self): + return 1 - self.transmittance + + @property + def emittance(self): + return self.emissivity + + @property + def molarMass(self): + mass = 0 + for mol in self: + mass += mol.molarMass * mol.concentration + return mass + + @property + def density(self): + d = self.P * 100 / self.T / self.specGasConstant + return d + + @property + def mass(self): + return self.density * self.depth / 100 + + @property + def specGasConstant(self): + con = R * 1000 / self.molarMass + return con + + @property + def temperatureAtHeight(self): + return int(self.atmosphere.temperatureAtHeight(self.meanHeight)) + + @property + def pressureAtHeight(self): + return self.atmosphere.pressureAtHeight(self.meanHeight) + + @property + def densityAtHeight(self): + return self.atmosphere.densityAtHeight(self.temperatureAtHeight, self.specGasConstant) + + def changeRange(self, rangeMin, rangeMax): + self.rangeMin = rangeMin + self.rangeMax = rangeMax + self.effectiveRangeMax = self.rangeMax + self.distanceFromCenter + self.effectiveRangeMin = max(self.rangeMin - self.distanceFromCenter, 0) + resetData(self) + + def changeTemperature(self, temperature): + self.T = temperature + resetCrossSection(self) + + def changePressure(self, pressure): + self.P = pressure + self.distanceFromCenter = self.P / 1013.25 * 5 + if not self.dynamicResolution: + self.resolution = utils.BASE_RESOLUTION + else: + self.resolution = max(10**int(np.log10((self.P / 1013.25))) * .01, utils.BASE_RESOLUTION) + resetData(self) + + def changeDepth(self, depth): + self.depth = depth + + def addMolecule(self, name, isotopeDepth=1, **abundance): + molecule = Molecule(name, self, isotopeDepth, **abundance) + self.append(molecule) + if totalConcentration(self) > 1: + print('**Warning : Concentrations exceed 1.') + molecule.getData() + return molecule + + def returnCopy(self, name=None): + if not name: + name = self.atmosphere.nextLayerName() + newCopy = Layer(self.depth, self.T, self.P, self.rangeMin, self.rangeMax, height=self.height, + atmosphere=self.atmosphere, name=name, dynamicResolution=self.dynamicResolution) + for molecule in self: + newCopy.addMolecule(molecule.name, molecule.isotopeDepth, concentration=molecule.concentration) + print('%s copied to %s' % (self.name, newCopy.name)) + return newCopy + + def returnMoleculeObjects(self): + moleculeList = [] + for m in self: + moleculeList.append(m) + return moleculeList + + def planck(self, temperature): + return pyradPlanck.planckWavenumber(self.xAxis, temperature) + + def transmission(self, surfaceSpectrum): + transmitted = self.transmittance * surfaceSpectrum + emitted = self.emittance * self.planck(self.T) + return transmitted + emitted + + +class Atmosphere(list): + def __init__(self, name, rangeMin=0, rangeMax=0, planet=None): + super().__init__(self) + self.name = name + self.rangeMin = rangeMin + self.rangeMax = rangeMax + self.planet = planet + + def __str__(self): + return self.name + + def __bool__(self): + return True + + def addLayer(self, depth, T, P, rangeMin, rangeMax, name=None, dynamicResolution=True, height=0.0): + if not name: + name = self.nextLayerName() + newLayer = Layer(depth, T, P, rangeMin, rangeMax, atmosphere=self, name=name, + dynamicResolution=dynamicResolution, height=height) + return newLayer + + def nextLayerName(self): + return 'Layer %s' % (len(self) + 1) + + def returnLayerNames(self): + tempList = [] + for layer in self: + tempList.append(layer.name) + return tempList + + def returnLayerObjects(self): + if len(self) == 0: + return False + tempList = [] + for layer in self: + tempList.append(layer) + return tempList + + def temperatureAtHeight(self, height): + ruleList = self.planet.returnApplicableRules(height, 'temperature') + if len(ruleList) > 1: + print('Multiple rules found for height %s: %s' % (height, ruleList)) + rule = ruleList[0] + temperature = rule.rateFunction(rule.baseValue, rule.baseHeight, rule.rate, height) + return temperature + + def pressureAtHeight(self, height): + height = height / 100 + ruleList = self.planet.returnApplicableRules(height, 'temperature') + if len(ruleList) > 1: + print('Multiple rules found for height %s: %s' % (height, ruleList)) + rule = ruleList[0] + temperature = self.temperatureAtHeight(height) + if rule.rate != 0: + pressure = rule.basePressure * (rule.baseValue / temperature) ** \ + (self.planet.gravity * self.planet.molarMass / R / rule.rate) + else: + pressure = rule.basePressure * \ + np.exp(-self.planet.gravity * self.planet.molarMass * + (height - rule.baseHeight) / R / rule.baseValue) + return pressure + + def compositionAtHeight(self, height, molecule): + ruleList = self.planet.returnApplicableRules(height, 'composition') + if not ruleList: + return molecule.concentration + for rule in ruleList: + if rule.molecule.name == molecule.name: + concentration = rule.rateFunction(rule.baseValue, rule.baseHeight, rule.rate, height) + return concentration + return molecule.concentration + + def densityAtHeight(self, height, gasConstant): + temperature = self.temperatureAtHeight(height) + pressure = self.pressureAtHeight(height) + density = pressure * 100 / gasConstant / temperature + return density + + +class Planet: + def __init__(self, name, pressure, temperature, maxHeight, molarMass=0.0289644, + gravity=9.80665, rangeMin=0, rangeMax=2000, initialThickness=100): + self.name = name + self.mass = 0 + self.gravity = gravity + self.maxHeight = maxHeight * 100000 + self.molarMass = molarMass + self.radius = 0 + self.surfacePressure = pressure + self.surfaceTemperature = temperature + self.atmosphereRules = [] + self.heightList = [] + self.depthList = [] + self.rangeMin = rangeMin + self.rangeMax = rangeMax + self.setting = settings.setting + self.atmosphere = Atmosphere("%s's atmosphere" % self.name, planet=self) + self.initialLayer = \ + self.atmosphere.addLayer(initialThickness * 100, temperature, pressure, rangeMin, rangeMax, + name='initial layer', height=0) + self.progressProfileLoaded = False + + def setMass(self, mass): + self.mass = mass + + def addLapseRate(self, name, finalHeight, finalValue, rateFunction=linear): + self.atmosphereRules.append(AtmosphereRule(name, finalHeight * 100000, + finalValue, 'temperature', self, rateFunction=rateFunction)) + + def addCompositionRate(self, name, finalHeight, finalValue, molecule, rateFunction=linear): + self.atmosphereRules.append(AtmosphereRule(name, finalHeight * 100000, finalValue, 'composition', self, + molecule=molecule, rateFunction=rateFunction)) + + def setRadius(self, radius): + self.radius = radius + + def setGravity(self, gravity): + self.gravity = gravity + + def setSurfacePressure(self, pressure): + self.surfacePressure = pressure + + def setSurfaceTemperature(self, temperature): + self.surfaceTemperature = temperature + + def setSurfaceComposition(self): + pass + + def returnApplicableRules(self, height, ruleType): + ruleList = [] + for rule in self.atmosphereRules: + if rule.isInRange(height, ruleType): + ruleList.append(rule) + if not ruleList: + return False + return ruleList + + def returnAllRulesOfType(self, ruleType): + ruleList = [] + for rule in self.atmosphereRules: + if rule.ruleType == ruleType: + ruleList.append(rule) + return ruleList + + def temperatureAtHeight(self, height): + return self.atmosphere.temperatureAtHeight(height) + + def pressureAtHeight(self, height): + return self.atmosphere.pressureAtHeight(height) + + def densityAtHeight(self, height): + return self.atmosphere.densityAtHeight(height) + + def compositionAtHeight(self, height, molecule): + return self.atmosphere.compositionAtHeight(height, molecule) + + def addMolecule(self, name, isotopeDepth=1, **abundance): + molecule = self.initialLayer.addMolecule(name, isotopeDepth, **abundance) + return molecule + + def sliceAtm(self, verify=True): + acceptSetup = False + layer = self.initialLayer + initialTemp = layer.T + initialPressure = layer.P + initialHeight = layer.height + initialDepth = layer.depth + while not acceptSetup: + mass = self.initialLayer.mass + print('%s, p %s, T %s, depth %s, height %s' % (layer.name, initialPressure, initialTemp, initialDepth, initialHeight)) + self.heightList = [layer.height] + tempList = [layer.T] + pressureList = [layer.P] + self.depthList = [layer.depth] + while layer.height + layer.depth < self.maxHeight: + print('%s: K: %s, mBar: %s, baseHeight: %skm, depth: %skm, mass: %skg' % ( + 'Layer %s' %len(self.heightList), int(layer.T), round(layer.P, 2), round(layer.height / 100000, 2), round(layer.depth / 100000, 2), round(layer.mass, 2))) + newHeight = self.heightList[-1] + self.depthList[-1] + tempList.append(self.temperatureAtHeight(newHeight)) + pressureList.append(self.pressureAtHeight(newHeight)) + layer.P = pressureList[-1] + layer.T = tempList[-1] + newDepth = (mass / layer.density * 100) + if newHeight + newDepth > self.maxHeight: + newDepth = self.maxHeight - newHeight + self.heightList.append(newHeight) + self.depthList.append(newDepth) + print('%s: K: %s, mBar: %s, baseHeight: %skm, depth: %skm, mass: %skg' % ( + 'Layer %s' % len(self.heightList), int(layer.T), round(layer.P, 2), + round(newHeight, 2), round(newDepth, 2), round(layer.mass, 2))) + break + else: + self.heightList.append(newHeight) + self.depthList.append(newDepth) + layer.height = newHeight + layer.depth = newDepth + '''if self.heightList[-1] + .5 * self.depthList[-1] > self.maxHeight: + self.heightList.pop() + self.depthList.pop()''' + print('Total # of layers: %s' % len(self.heightList)) + print('Total # of absorption lines per layer: %s' % len(totalLineList(layer))) + if verify: + if yesOrNo('Accept the current slicing (y/n): '): + acceptSetup = True + else: + validNumber = False + while not validNumber: + print( + 'Enter the new initial depth. Larger depth will decrease number of layers, smaller will increase') + userNumber = input('Current depth is %s:' % utils.limeText('%sm' % (int(self.depthList[0]) / 100))) + try: + newDepth = float(userNumber) + self.initialLayer.depth = newDepth * 100 + self.initialLayer.P = initialPressure + self.initialLayer.T = initialTemp + self.initialLayer.height = initialHeight + validNumber = True + except ValueError: + print('Invalid number.') + else: + acceptSetup = True + return + + def processLayers(self, verify=True): + if utils.profileProgress(self.folderPath): + self.sliceAtm(verify=False) + if not self.heightList: + self.sliceAtm(verify=verify) + layer = self.initialLayer + startPoint = utils.profileProgress(self.folderPath) + i = startPoint + 1 + for height, depth in zip(self.heightList[startPoint:], self.depthList[startPoint:]): + layer.name = 'Layer %s:%s' % (i, len(self.heightList)) + layer.height = height + layer.depth = depth + layer.T = int(self.temperatureAtHeight(layer.meanHeight)) + layer.P = self.pressureAtHeight(layer.meanHeight) + for molecule in layer: + molecule.concentration = self.compositionAtHeight(layer.meanHeight, molecule) + layer.createCrossSection() + utils.writePlanetProfile(self.folderPath, layer) + utils.profileWriteProgress(self.folderPath, i, len(self.heightList)) + resetCrossSection(layer) + layer.absorptionCoefficient = np.zeros(len(layer.crossSection)) + layer.progressAbsCoef = False + i += 1 + utils.profileWriteComplete(self.folderPath, i - 1, len(self.heightList)) + return + + def loadProfile(self, verify=True): + if utils.profileComplete(self.folderPath): + fileLength = utils.profileLength(self.folderPath) + if verify: + if not yesOrNo('%s layers found for profile %s. Load profile (y/n):' % (fileLength, self.name)): + if yesOrNo('Are you sure, selecting yes will delete all previous profile data (y/n): '): + utils.emptyProfileDirectory(self.folderPath) + self.processLayers() + else: + self.processLayers() + fileLength = utils.profileLength(self.folderPath) + while len(self.atmosphere) > 0: + self.atmosphere.pop() + for i in range(1, fileLength + 1): + lP = utils.readPlanetProfile(self.folderPath, i, fileLength) + layer = Layer(lP['depth'], lP['T'], lP['P'], lP['rangeMin'], lP['rangeMax'], height=lP['height'], name=lP['name']) + self.atmosphere.append(layer) + layer.absorptionCoefficient = np.asarray(lP['absCoef']) + layer.progressAbsCoef = True + print('') + self.progressProfileLoaded = True + return + + def processTransmission(self, height, direction='down', verify=True): + if not self.progressProfileLoaded: + self.loadProfile(verify=verify) + height = height * 100000 + print('Processing atmosphere spectrum from %skm looking %s...' % (height / 100000, direction)) + if direction == 'down': + surfaceSpectrum = pyradPlanck.planckWavenumber(self.initialLayer.xAxis, self.surfaceTemperature) + for layer in self.atmosphere: + if layer.meanHeight < height: + surfaceSpectrum = layer.transmission(surfaceSpectrum) + print('Processing %s...' % (layer.name), end='\r', flush=True) + elif direction == 'up': + surfaceSpectrum = pyradPlanck.planckWavenumber(self.initialLayer.xAxis, 3) + for layer in reversed(self.atmosphere): + if layer.meanHeight > height: + surfaceSpectrum = layer.transmission(surfaceSpectrum) + print('Processing %s...' % (layer.name), layer.T, end='\r', flush=True) + print('') + print('total power of spectrum: %sWm-2' % int((integrateSpectrum(surfaceSpectrum) / 5.67E-8)**.25)) + return surfaceSpectrum + + @property + def yAxis(self): + return np.zeros(int((self.rangeMax - self.rangeMin) / utils.BASE_RESOLUTION)) + + @property + def folderPath(self): + return '%s %s' % (self.name, self.setting) + + @property + def xAxis(self): + return np.linspace(self.rangeMin, self.rangeMax, (self.rangeMax - self.rangeMin) / utils.BASE_RESOLUTION, + endpoint=True) + + @property + def atmChangePoints(self): + changePointList = [] + for rule in self.atmosphereRules: + changePointList.append(rule.finalHeight) + return sorted(changePointList) + + @property + def transmission(self): + return self.processTransmission(self.maxHeight) + + +def stefanB(power): + return (power / sb) ^ .25 + + +class AtmosphereRule: + def __init__(self, name, finalHeight, finalValue, ruleType, planetClass, molecule=None, rateFunction=linear): + self.name = name + self.ruleType = ruleType + self.parent = planetClass + self.baseHeight, self.baseValue, self.basePressure = self.setBaseValues(self.ruleType, molecule) + self.finalHeight = finalHeight + self.finalValue = finalValue + if rateFunction == linear: + self.rate = (self.finalValue - self.baseValue) / (self.finalHeight - self.baseHeight) + self.molecule = molecule + self.rateFunction = rateFunction + + def isInRange(self, height, ruleType): + return self.baseHeight < height <= self.finalHeight and self.ruleType == ruleType + + def baseHeightTemperatureRule(self): + height = 0 + temperature = self.parent.surfaceTemperature + pressure = self.parent.surfacePressure + tempRules = self.parent.returnAllRulesOfType(self.ruleType) + for rule in tempRules: + if rule.finalHeight > height: + height = rule.finalHeight + temperature = rule.finalValue + pressure = self.parent.pressureAtHeight(height) + return height, temperature, pressure + + def baseHeightCompositionRule(self, molecule): + height = 0 + pressure = self.parent.surfacePressure + concentration = molecule.concentration + compRules = self.parent.returnAllRulesOfType(self.ruleType) + for rule in compRules: + if rule.finalHeight > height and rule.molecule == molecule: + height = rule.finalHeight + concentration = rule.finalValue + return height, concentration, pressure + + def setBaseValues(self, ruleType, molecule): + if ruleType == 'temperature': + return self.baseHeightTemperatureRule() + elif ruleType == 'composition': + return self.baseHeightCompositionRule(molecule) + + +def returnPlot(obj, propertyToPlot): + if propertyToPlot == "transmittance": + yAxis = getTransmittance(obj), 1 + elif propertyToPlot == 'absorption coefficient': + yAxis = getAbsCoef(obj), 0 + elif propertyToPlot == 'cross section': + yAxis = getCrossSection(obj), 0 + elif propertyToPlot == 'absorbance': + yAxis = getAbsorbance(obj), 0 + elif propertyToPlot == 'optical depth': + yAxis = getOpticalDepth(obj), 0 + elif propertyToPlot == 'line survey': + yAxis = obj.lineSurvey, 0 + else: + return False + return yAxis + + +def isBetween(test, minValue, maxValue): + if test >= minValue: + if test <= maxValue: + return True + return False + + +def plot(propertyToPlot, title, plotList, fill=False): + plt.figure(figsize=(10, 6), dpi=80) + plt.subplot(111, facecolor='xkcd:dark grey') + plt.xlabel('wavenumber cm-1') + plt.margins(0.01) + plt.subplots_adjust(left=.07, bottom=.08, right=.97, top=.90) + plt.ylabel(propertyToPlot) + if propertyToPlot == 'line survey': + plt.yscale('log') + plt.grid('grey', linewidth=.5, linestyle=':') + plt.title('%s' % title) + handles = [] + linewidth = .7 + alpha = .7 + for singlePlot, color in zip(plotList, COLOR_LIST): + yAxis, fillAxis = returnPlot(singlePlot, propertyToPlot) + fig, = plt.plot(singlePlot.xAxis, yAxis, linewidth=linewidth, alpha=alpha, color=color, + label='%s' % singlePlot.name) + handles.append(fig) + plt.fill_between(singlePlot.xAxis, fillAxis, yAxis, color=color, alpha=.3 * fill) + linewidth = .7 + alpha = .5 + legend = plt.legend(handles=handles, frameon=False) + text = legend.get_texts() + plt.setp(text, color='w') + plt.show() + + +def plotSpectrum(layer=None, title=None, rangeMin=None, rangeMax=None, objList=None, surfaceSpectrum=None, + planckTemperatureList=None, planckType='wavenumber'): + plt.figure(figsize=(10, 6), dpi=80) + plt.subplot(111, facecolor='xkcd:dark grey') + plt.margins(0.01) + plt.subplots_adjust(left=.07, bottom=.08, right=.97, top=.90) + if layer: + rangeMin = layer.rangeMin + rangeMax = layer.rangeMax + title = layer.title + if planckType == 'wavenumber': + plt.xlabel('wavenumber cm-1') + plt.ylabel('Radiance Wm-2sr-1(cm-1)-1') + planckFunction = pyradPlanck.planckWavenumber + xAxis = np.linspace(rangeMin, rangeMax, (rangeMax - rangeMin) / utils.BASE_RESOLUTION) + elif planckType == 'Hz': + plt.xlabel('Hertz') + plt.ylabel('Radiance Wm-2sr-1Hz-1') + planckFunction = pyradPlanck.planckHz + xAxis = np.linspace(rangeMin, rangeMax, 1000) + else: + plt.xlabel('wavelength um') + plt.ylabel('Radiance Wm-2sr-1um-1') + planckFunction = pyradPlanck.planckWavelength + xAxis = np.linspace(rangeMin, rangeMax, (rangeMax - rangeMin) / utils.BASE_RESOLUTION) + plt.title('%s' % title) + handles = [] + blue = .3 + red = 1 + green = .6 + dr = -.15 + db = .15 + dg = .15 + if not rangeMax: + xAxis = layer.xAxis + for temperature in planckTemperatureList: + yAxis = planckFunction(xAxis, float(temperature)) + fig, = plt.plot(xAxis, yAxis, linewidth=.75, color=(red, green, blue), + linestyle=':', label='%sK : %sWm-2' % + (temperature, round(integrateSpectrum(yAxis, res=(rangeMax - rangeMin) / len(yAxis)), 2))) + handles.append(fig) + if red + dr < 0 or red + dr > 1: + dr *= -1 + if green + dg > 1 or green + dg < 0: + dg *= -1 + if blue + db > 1 or blue + db < 0: + db *= -1 + red += dr + green += dg + blue += db + if red < .3 and green < .3 and blue < .3: + green += .5 + blue += .2 + if red < .3 and green < .3: + green += .4 + if objList: + alpha = .7 + linewidth = .7 + for obj, color in zip(objList, COLOR_LIST): + yAxis = obj.transmission(surfaceSpectrum) + fig, = plt.plot(layer.xAxis, yAxis, linewidth=linewidth, + alpha=alpha, color=color, + label='%s : %sWm-2' % (obj.name, round(integrateSpectrum(yAxis, pi), 2))) + handles.append(fig) + alpha = .5 + linewidth = .7 + legend = plt.legend(handles=handles, frameon=False) + text = legend.get_texts() + plt.setp(text, color='w') + plt.show() + + +def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=[300, 280, 250, 210, 170], verify=True, integrateRange=[]): + linewidth = .5 + alpha = .7 + plt.figure(figsize=(10, 6), dpi=80) + plt.subplot(111, facecolor='xkcd:almost black') + plt.margins(0.01) + plt.subplots_adjust(left=.07, bottom=.08, right=.97, top=.90) + plt.ylabel('Radiance Wm-2sr-1(cm-1)-1') + handles = [] + heightFlag = True + if height is None: + heightFlag = False + for planet, color in zip(planets, COLOR_LIST[1:]): + if not heightFlag: + height = planet.maxHeight / 100000 + xAxis = planet.xAxis + #xAxis = np.linspace(planet.rangeMin, planet.rangeMax, planet.rangeMax - planet.rangeMin) + yAxis = planet.processTransmission(height, direction=direction, verify=verify) + #yAxis = reduceRes(planet.processTransmission(height, direction=direction, verify=verify)) + fig, = plt.plot(xAxis, smooth(yAxis, 75), linewidth=linewidth, + alpha=alpha, color=color, + label='%s : %sWm-2' % (planet.name, round(integrateSpectrum(yAxis, pi), 2))) + #fig, = plt.plot(xAxis, yAxis, linewidth=linewidth, + # alpha=alpha, color=color, + # label='%s : %sWm-2' % (planet.name, round(integrateSpectrum(yAxis, pi), 2))) + handles.append(fig) + color = 1 + for temperature in temperatureList: + yAxis = pyradPlanck.planckWavenumber(xAxis, float(temperature)) + fig, = plt.plot(xAxis, yAxis, linewidth=.75, color=(color, color, color), alpha=alpha, + linestyle=':', label='%sK : %sWm-2' % + (temperature, + round(integrateSpectrum(yAxis, pi), 2))) + handles.append(fig) + color -= .15 + legend = plt.legend(handles=handles, frameon=False) + text = legend.get_texts() + plt.setp(text, color='w') + plt.show() + + +HITRAN_GLOBAL_ISO = {1: {1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 129}, + 2: {1: 7, 2: 8, 3: 9, 4: 10, 5: 11, 6: 12, 7: 13, 8: 14, 9: 121, 10: 15, 11: 120, 12: 122}, + 3: {1: 16, 2: 17, 3: 18, 4: 19, 5: 20}, + 4: {1: 21, 2: 22, 3: 23, 4: 24, 5: 25, }, + 5: {1: 26, 2: 27, 3: 28, 4: 29, 5: 30, 6: 31}, + 6: {1: 32, 2: 33, 3: 34, 4: 35}, + 7: {1: 36, 2: 37, 3: 38}, + 8: {1: 39, 2: 40, 3: 41}, + 9: {1: 42, 2: 43}, + 10: {1: 44}, + 11: {1: 45, 2: 46}, + 12: {1: 47, 2: 117}, + 13: {1: 48, 2: 49, 3: 50}, + 14: {1: 51, 2: 110}, + 15: {1: 52, 2: 53, 3: 107, 4: 108}, + 16: {1: 19, 2: 11, 3: 111, 4: 112}, + 17: {1: 56, 2: 113}, + 18: {1: 57, 2: 58}, + 19: {1: 59, 2: 60, 3: 61, 4: 62, 5: 63}, + 20: {1: 64, 2: 65, 3: 66}, + 21: {1: 67, 2: 68}, + 22: {1: 69, 2: 118}, + 23: {1: 70, 2: 71, 3: 72}, + 24: {1: 73, 2: 74}, + 25: {1: 75}, + 26: {1: 76, 2: 77, 3: 105}, + 27: {1: 78, 2: 106}, + 28: {1: 79}, + 29: {1: 80, 2: 119}, + 30: {1: 126}, + 31: {1: 81, 2: 82, 3: 83}, + 32: {1: 84}, + 33: {1: 85}, + 34: {1: 86}, + 35: {1: 127, 2: 128}, + 36: {1: 87}, + 37: {1: 88, 2: 89}, + 38: {1: 90, 2: 91}, + 39: {1: 92}, + 40: {1: 93, 2: 94}, + 41: {1: 95}, + 42: {1: 96}, + 43: {1: 116}, + 44: {1: 109}, + 45: {1: 103, 2: 115}, + 46: {1: 97, 2: 98, 3: 99, 4: 100}, + 47: {1: 114}, + 48: {1: 123}, + 49: {1: 124, 2: 125}, + 901: {1: 901}} + +COLOR_LIST = ['xkcd:white', + 'xkcd:bright orange', + 'xkcd:seafoam green', + 'xkcd:bright blue', + 'xkcd:salmon', + 'xkcd:light violet', + 'xkcd:green yellow'] + +VERSION = utils.VERSION + +MOLECULE_ID = {'h2o': 1, 'co2': 2, 'o3': 3, 'n2o': 4, 'co': 5, + 'ch4': 6, 'o2': 7, 'no': 8, 'so2': 9, + 'no2': 10, 'nh3': 11, 'hno3': 12, 'oh': 13, + 'hf': 14, 'hcl': 15, 'hbr': 16, 'hi': 17, + 'clo': 18, 'ocs': 19, 'h2co': 20, 'hocl': 21, + 'n2': 22, 'hcn': 23, 'ch3cl': 24, 'h2o2': 25, + 'c2h2': 26, 'c2h6': 27, 'ph3': 28, 'cof2': 29, + 'sf6': 30, 'h2s': 31, 'hcooh': 32, 'ho2': 33, + 'o': 34, 'clono2': 35, 'no+': 36, 'hobr': 37, + 'c2h4': 38, 'ch3oh': 39, 'ch3br': 40, 'ch3cn': 41, + 'cf4': 42, 'c4h2': 43, 'hc3n': 44, 'h2': 45, + 'cs': 46, 'so3': 47, 'c2n2': 48, 'cocl2': 49, + 'ar': 901} diff --git a/pyradInteractive.py b/pyradInteractive.py deleted file mode 100644 index 1ca18ab..0000000 --- a/pyradInteractive.py +++ /dev/null @@ -1,625 +0,0 @@ -import pyrad -import pyradUtilities as util -import re -import pyradPlanck - -existingAtmosphere = False -validValueAndUnits = re.compile('([-])?(\d+)?([.])?(\d+)?(\S+)?') -genericAtmosphere = pyrad.Atmosphere('holding atm for pyrad interactive') - - -class Menu: - def __init__(self, title, entries, previousMenu=None, menuParams=None): - self.title = title - self.entries = entries - self.previousMenu = previousMenu - self.menuParams = menuParams - - def displayMenu(self): - titleStr = '\t' + self.title - while len(titleStr) < 60: - titleStr += ' ' - print('\n%s' % util.underlineCyan(titleStr)) - i = 1 - validEntry = ['x'] - for entry in self.entries: - validEntry.append(str(i)) - print(' %s) %s' % (util.magentaText(i), entry.name)) - i += 1 - if 'Main' not in self.title: - print(' %s Previous menu' % util.magentaText('B)')) - validEntry.append('b') - print(' %s Exit' % util.magentaText('X)')) - validChoice = False - while not validChoice: - userInput = input('Choose an option: ') - if userInput.lower() == 'x': - print('Goodbye') - exit(1) - elif userInput.lower() == 'b' and 'Main' not in self.title: - return - elif userInput in validEntry: - userChoice = self.entries[int(userInput) - 1] - if userChoice.nextFunction: - userChoice.nextFunction(userChoice.functionParams) - validChoice = True - elif userChoice.nextMenu: - userChoice.nextMenu.displayMenu() - validChoice = True - else: - print('Invalid entry. Try again.') - - -class Entry: - def __init__(self, text, nextMenu=None, nextFunction=None, functionParams=None, previousMenu=None): - self.name = text - self.nextMenu = nextMenu - self.nextFunction = nextFunction - self.functionParams = functionParams - self.previousMenu = previousMenu - - -def createPlot(params): - plotList = params['plots'] - plotType = params['plotType'] - plotTitle = params['title'] - pyrad.plot(plotType, plotTitle, plotList) - return - - -def createLayer(atmosphere): - defaultLayerName = atmosphere.nextLayerName() - getLayerName = '\n%s\n' \ - 'If no value given, default will be %s : ' \ - % (util.underlineCyan('Enter the name of the layer.\t\t'), - util.limeText(defaultLayerName)) - depth = inputLayerDepth() - pressure = inputLayerPressure() - temperature = inputLayerTemperature() - rangeMin, rangeMax = inputLayerRange() - validName = False - while not validName: - layerName = input(getLayerName) - if layerName not in genericAtmosphere: - validName = True - else: - print('Name already taken. Please try again.') - layer = atmosphere.addLayer(depth, temperature, pressure, rangeMin, rangeMax, name=layerName) - createMolecule(layer) - return - - -def createMolecule(layer): - addMoleculeLoop = True - while addMoleculeLoop: - moleculeName = inputMoleculeName() - concentration, units = inputMoleculeComposition() - tempdict = {units: concentration} - molecule = layer.addMolecule(moleculeName, **tempdict) - while pyrad.totalConcentration(layer) > 1: - print("%s total concentration exceeds 100%%" % util.magentaText('***\tWARNING\t***')) - menuEditComposition(layer) - validInput = False - while not validInput: - ask = input("Add another molecule to the layer %s " % util.magentaText('(y/n) :')) - if ask.strip().lower() == 'y': - validInput = True - elif ask.strip().lower() == 'n': - return - - -def menuEditLayerParam(layer): - editDepth = Entry('Depth', nextFunction=editLayerDepth, functionParams=layer) - editRange = Entry('Min or max range', nextFunction=editLayerRange, functionParams=layer) - editTemperature = Entry('Temperature',nextFunction=editLayerTemperature, functionParams=layer) - editPressure = Entry('Pressure', nextFunction=editLayerPressure, functionParams=layer) - entryList = [editDepth, editRange, editTemperature, editPressure] - menu = Menu('Choose the parameter to edit for %s' % layer.name, entryList, - previousMenu=menuEditParamsOrComp, menuParams=layer) - menu.displayMenu() - return - - -def editLayerDepth(layer): - print('Current %s for %s is : %s\n' - % (util.limeText('depth'), util.limeText(layer.name), util.cyanText('%scm' % layer.depth))) - depth = inputLayerDepth(default=layer.depth) - layer.changeDepth(depth) - menuEditLayerParam(layer) - - -def editLayerTemperature(layer): - print('Current %s for %s is : %s\n' - % (util.limeText('temperature'), util.limeText(layer.name), util.cyanText('%sK' % layer.T))) - temperature = inputLayerTemperature(default=layer.T) - layer.changeTemperature(temperature) - menuEditLayerParam(layer) - - -def editLayerPressure(layer): - print('Current %s for %s is : %s\n' - % (util.limeText('pressure'), util.limeText(layer.name), util.cyanText('%smbar' % layer.P))) - pressure = inputLayerPressure(default=layer.P) - layer.changePressure(pressure) - menuEditLayerParam(layer) - - -def editLayerRange(layer): - print('Current %s for %s is %s\n' - % (util.limeText('range'), util.limeText(layer.name), - util.cyanText('%s-%scm-1' % (layer.rangeMin, layer.rangeMax)))) - rangeMin, rangeMax = inputLayerRange(defaultMin=layer.rangeMin, defaultMax=layer.rangeMax) - layer.changeRange(rangeMin, rangeMax) - menuEditLayerParam(layer) - - -def editComposition(molecule): - print('Current concentration for %s is %s\n' % (util.limeText(molecule.name), util.limeText(molecule.concText))) - return inputMoleculeComposition(molecule, default=molecule.concText) - - -def inputLayerDepth(default=None): - if not default: - default = 10 - text = 'Enter the thickness of the layer.\t\t\t' - getDepth = '%s\n' \ - 'If no units are specified, %s will be assumed.\n' \ - 'Other valid units are %s . If no value given, default will be %s: ' % \ - (util.underlineCyan(text), - util.limeText('cm'), - util.limeText('m, in, ft.'), - util.limeText('%scm' % default)) - depth = receiveInput(getDepth, validDepth, default=default) - return depth - - -def inputLayerTemperature(default=None): - if not default: - default = 300 - text = 'Enter the temperature of the layer.\t\t\t' - getTemperature = '%s\n' \ - 'If no units are specified, %s will be assumed.\n' \ - 'Other valid units are %s . If no value given, default will be %s: ' % \ - (util.underlineCyan(text), - util.limeText('K'), - util.limeText('C or F'), - util.limeText('%sK' % default)) - temperature = receiveInput(getTemperature, validTemperature, default=default) - return temperature - - -def inputLayerPressure(default=None): - if not default: - default = 1013.25 - text = 'Enter the pressure of the layer.\t\t\t' - getPressure = '%s\n' \ - 'If no units are specified, %s will be assumed.\n' \ - 'Other valid units are %s . If no value given, default will be %s: ' % \ - (util.underlineCyan(text), - util.limeText('mBar'), - util.limeText('pa, bar, and atm.'), - util.limeText('%smbar' % default)) - pressure = receiveInput(getPressure, validPressure, default=default) - return pressure - - -def inputLayerRange(defaultMin=None, defaultMax=None): - if not defaultMin: - defaultMin = 600 - if not defaultMax: - defaultMax = 700 - rangeMin = -1 - rangeMax = -1 - text = 'Enter the minimum range of the layer.\t\t\t' - getRangeMin = '%s\n' \ - 'If no units are specified, %s will be assumed.\n' \ - 'Other valid units are %s . If no value given, default will be %s: ' % \ - (util.underlineCyan(text), - util.limeText('cm-1'), - util.limeText('um'), - util.limeText('%scm' % defaultMin)) - while rangeMin < 0: - rangeMin = receiveInput(getRangeMin, validRange, default=defaultMin) - if rangeMin < 0: - print('Range min must be %s than zero' % util.magentaText('greater')) - text = 'Enter the maximum range of the layer.\t\t\t' - getRangeMax = '%s\n' \ - 'If no units are specified, %s will be assumed.\n' \ - 'Other valid units are %s . If no value given, default will be %s: ' % \ - (util.underlineCyan(text), - util.limeText('cm-1'), - util.limeText('um'), - util.limeText('%scm' % defaultMax)) - while rangeMax <= rangeMin: - rangeMax = receiveInput(getRangeMax, validRange, default=defaultMax) - if rangeMax <= rangeMin: - print('Range min must be %s than range min of %s' % (util.magentaText('greater'), util.cyanText(rangeMin))) - return rangeMin, rangeMax - - -def validNumber(userInput): - try: - return float(userInput) - except ValueError: - return False - - -def inputPlanckRange(units): - rangeMin = -1 - rangeMax = -1 - text = '%s\nUnits are %s. Scientific notation is accepted (1e14):' \ - % (util.underlineCyan('Enter the minimum range of the planck spectrum.'),util.limeText(units)) - while rangeMin < 0: - rangeMin = receiveInput(text, validNumber) - if rangeMin < 0: - print('Range min must be %s than zero' % util.magentaText('greater')) - text = '%s\nUnits are %s. Scientific notation is accepted (1e14):' \ - % (util.underlineCyan('Enter the maximum range of the planck spectrum.'), util.limeText(units)) - while rangeMax <= rangeMin: - rangeMax = receiveInput(text, validNumber) - if rangeMax <= rangeMin: - print('Range min must be %s than range min of %s' % (util.magentaText('greater'), util.cyanText(rangeMin))) - return rangeMin, rangeMax - - -def inputMoleculeName(default=None): - if not default: - default = 'co2' - text = 'Enter the short molecule name.\t\t\t' - moleculeName = receiveInput('%s\n' - 'For a full list of options, type %s . If no value given, %s will be used: ' - % (util.underlineCyan(text), - util.magentaText('help'), - util.limeText(default)), validMoleculeName, default=default) - return moleculeName - - -def inputMoleculeComposition(obj=None, default=None): - if not default: - default = '400ppm' - text = 'Enter the molecule composition.\t\t\t' - composition, units = receiveInput('%s\n' - 'If no units entered, composition will be assumed %s.\n' - 'Other valid units are %s . If no value given, %s will be used: ' - % (util.underlineCyan(text), - util.limeText('parts per 1'), - util.limeText('ppm, ppb, or percentage'), - util.limeText(default)), validComposition, default=default) - if obj: - if units == 'ppm': - obj.setPPM(composition) - elif units == 'ppb': - obj.setPPB(composition) - elif 'perc' in units or units == '%': - obj.setPercentage(composition) - else: - obj.setConcentrationPercentage(composition) - return - else: - return composition, units - - -def inputPlanckTemps(): - text = 'Enter the temperature of the planck curves.\t\t\t' - tempList = receiveMultiInput('%s\n' - 'If no units entered, temperature will be assumed %s.\n' - 'Other valid units are %s .Multiple temperatures can be separated with a comma: ' - % (util.underlineCyan(text), - util.limeText('K'), - util.limeText('C and F')), validTemperature) - return tempList - - -def menuChooseLayerToEdit(empty=None): - entryList = [] - for layer in genericAtmosphere: - nextEntry = Entry(layer.name, nextFunction=menuEditParamsOrComp, functionParams=layer) - entryList.append(nextEntry) - editLayerMenu = Menu('Edit layer', entryList) - editLayerMenu.displayMenu() - return - - -def menuChooseTransmission(plotType): - entryList = [] - for layer in genericAtmosphere: - params = {'plots': [layer], 'plotType': plotType, 'title': layer.title} - nextEntry = Entry(layer.name, nextFunction=createTransmission, functionParams=params) - entryList.append(nextEntry) - plotList, title = createObjAndComponents(layer) - params = {'plots': plotList, 'plotType': plotType, 'title': title} - nextEntry = Entry('%s and components' % layer.name, nextFunction=createTransmission, functionParams=params) - entryList.append(nextEntry) - transmissionMenu = Menu('Choose which layers to plot transmission', entryList) - transmissionMenu.displayMenu() - return - - -def createPlanckCurves(plotType): - plotList = inputPlanckTemps() - rangeMin, rangeMax = inputPlanckRange(plotType) - pyrad.plotSpectrum(title='Planck spectrums', rangeMin=rangeMin, rangeMax=rangeMax, planckTemperatureList=plotList, planckType=plotType) - return - - -def menuPlanckType(empty=None): - entryList = [] - wavenumber = 'wavenumber' - hertz = 'Hz' - wavelength = 'wavelength' - entryList.append(Entry('By %s (cm-1)' % wavenumber, nextFunction=createPlanckCurves, functionParams=wavenumber)) - entryList.append(Entry('By %s (um)' % wavelength, nextFunction=createPlanckCurves, functionParams=wavelength)) - entryList.append(Entry('By %s (s-1)' % hertz, nextFunction=createPlanckCurves, functionParams=hertz)) - planckTypeMenu = Menu('Choose planck type', entryList) - planckTypeMenu.displayMenu() - return - - -def createTransmission(params): - layer = params['plots'][0] - text = 'A plot for transmission requires an initial surface temperature.\n'\ - 'Please choose a temperature different from the layer temperature of %sK:' % util.limeText(layer.T) - temperature = receiveMultiInput(text, validTemperature) - objList = [] - for item in params['plots']: - objList.append(item) - temperature.append(layer.T) - pyrad.plotSpectrum(layer, objList=objList, - surfaceSpectrum=pyradPlanck.planckWavenumber(layer.xAxis, temperature[0]), - planckTemperatureList=temperature) - return - - -def menuChoosePlotType(empty=None): - entryList = [] - entryList.append(Entry('transmittance', nextFunction=menuChooseLayerToPlot, functionParams='transmittance')) - entryList.append(Entry('absorption coefficient', nextFunction=menuChooseLayerToPlot, functionParams='absorption coefficient')) - entryList.append(Entry('cross section', nextFunction=menuChooseLayerToPlot, functionParams='cross section')) - entryList.append(Entry('absorbance', nextFunction=menuChooseLayerToPlot, functionParams='absorbance')) - entryList.append(Entry('optical depth', nextFunction=menuChooseLayerToPlot, functionParams='optical depth')) - entryList.append(Entry('line survey', nextFunction=menuChooseLayerToPlot, functionParams='line survey')) - entryList.append(Entry('transmission', nextFunction=menuChooseTransmission, functionParams='transmission')) - choosePlotTypeMenu = Menu('Choose plot type', entryList) - choosePlotTypeMenu.displayMenu() - return - - -def menuChooseLayerToPlot(plotType): - entryList = [] - for layer in genericAtmosphere: - params = {'plots': [layer], 'plotType': plotType, 'title': layer.title} - nextEntry = Entry(layer.name, nextFunction=createPlot, functionParams=params) - entryList.append(nextEntry) - plotList, title = createObjAndComponents(layer) - params = {'plots': plotList, 'plotType': plotType, 'title': title} - nextEntry = Entry('%s and components' % layer.name, nextFunction=createPlot, functionParams=params) - entryList.append(nextEntry) - plotLayerMenu = Menu('Plot layer', entryList) - plotLayerMenu.displayMenu() - return - - -def createObjAndComponents(obj): - plotList = [obj] - for item in obj: - plotList.append(item) - return plotList, obj.title - - -def menuEditComposition(layer): - moleculeList = layer.returnMoleculeObjects() - entryList = [] - for molecule in moleculeList: - newEntry = Entry('%s : %s' % (molecule.name, molecule.concText), - functionParams=molecule, nextFunction=inputMoleculeComposition) - entryList.append(newEntry) - entryList.append(Entry('Add a new molecule(s)', nextFunction=createMolecule, functionParams=layer)) - editCompMenu = Menu('Choose a molecule to edit', entryList, previousMenu=menuEditParamsOrComp) - editCompMenu.displayMenu() - return - - -def menuEditParamsOrComp(layer): - entryList = [] - editLayerParamsEntry = Entry('Edit layer parameters', nextFunction=menuEditLayerParam, functionParams=layer) - entryList.append(editLayerParamsEntry) - duplicateLayerEntry = Entry('Duplicate layer', nextFunction=duplicateObj, functionParams=layer) - entryList.append(duplicateLayerEntry) - editCompositionEntry = Entry('Edit composition', nextFunction=menuEditComposition, functionParams=layer) - entryList.append(editCompositionEntry) - chooseParamsMenu = Menu('Edit or duplicate', entryList, previousMenu=menuChooseLayerToEdit) - chooseParamsMenu.displayMenu() - return - - -def menuMain(): - createLayerEntry = Entry("Create new gas cell", nextFunction=createLayer, functionParams=genericAtmosphere) - editLayerEntry = Entry("Edit/duplicate gas cell", nextFunction=menuChooseLayerToEdit) - plotLayerEntry = Entry("Plot gas cell", nextFunction=menuChoosePlotType) - planckPlotEntry = (Entry('Plot planck curves', nextFunction=menuPlanckType)) - mainMenu = Menu('Main menu', [createLayerEntry, editLayerEntry, plotLayerEntry, planckPlotEntry]) - mainMenu.displayMenu() - return - - -def duplicateObj(obj): - newObj = obj.returnCopy() - if isinstance(newObj, pyrad.Layer): - genericAtmosphere.append(newObj) - else: - print('Unknown object %s, type %s' % (obj.name, type(obj))) - return - - -def receiveInput(inputText, validInputFunction, default=None): - validInput = False - while validInput is False: - userInput = input('\n%s' % inputText) - if userInput == '': - return validInputFunction(str(default)) - validInput = validInputFunction(userInput) - return validInput - - -def receiveMultiInput(inputText, validInputFunction, default=None): - validInput = False - while not validInput: - userInput = input(inputText) - inputList = userInput.replace(' ', '').split(',') - testInput = True - for item in inputList: - if not validInputFunction(item): - print('%s not recognized as valid. Please try again.') - testInput = False - if testInput: - return inputList - - -def validMoleculeName(userInput): - if not userInput: - return False - if userInput.strip().lower() == 'help': - util.displayAllMolecules() - return False - elif userInput in pyrad.MOLECULE_ID: - return userInput - else: - print('Invalid molecule name. %s' % (util.underlineMagenta('Please try again.'))) - return False - - -def validPressure(userInput): - if not userInput: - return False - try: - splitInput = validValueAndUnits.match(userInput) - except AttributeError: - print('Invalid input for pressure. Example: %s. %s' - % (util.limeText('1.35atm'), util.underlineMagenta('Please try again.'))) - return False - unit = splitInput.group(5) - if not unit: - unit = 'mbar' - unit = unit.lower() - if unit not in PRESSURE_UNITS: - print('Invalid units. Accepted units are %s.' % ', '.join(PRESSURE_UNITS)) - return False - textNumber = '' - for i in range(1, 5): - if splitInput.group(i): - textNumber += splitInput.group(i) - - value = float(textNumber) - return pyrad.convertPressure(value, unit) - - -def validComposition(userInput): - if not userInput: - return False - try: - splitInput = validValueAndUnits.match(userInput) - except AttributeError: - print('Invalid input for concentration. Example: %s. %s' - % (util.limeText('15ppb'), util.underlineMagenta('Please try again.'))) - return False - unit = splitInput.group(5) - if not unit: - unit = 'concentration' - if unit not in COMPOSITION_UNITS: - print('Invalid units. Accepted units are %s.' - % (util.limeText(', '.join(COMPOSITION_UNITS)))) - return False - textNumber = '' - for i in range(1, 5): - if splitInput.group(i): - textNumber += splitInput.group(i) - value = float(textNumber) - if value <= 0: - print('Concentration must be greater than 0') - return False - return value, unit - - -def validTemperature(userInput): - if not userInput: - return False - try: - splitInput = validValueAndUnits.match(userInput) - except AttributeError: - print('Invalid input for temperature. Example: %s. %s' - % (util.limeText('20C'), util.underlineMagenta('Please try again.'))) - return False - unit = splitInput.group(5) - if not unit: - unit = 'K' - unit = unit.upper()[0] - if unit not in TEMPERATURE_UNITS: - print('Invalid units. Accepted units are %s.' - % (util.limeText(', '.join(TEMPERATURE_UNITS)))) - return False - textNumber = '' - for i in range(1, 5): - if splitInput.group(i): - textNumber += splitInput.group(i) - value = float(textNumber) - return pyrad.convertTemperature(value, unit) - - -def validRange(userInput): - if not userInput: - return False - try: - splitInput = validValueAndUnits.match(userInput) - except AttributeError: - print('Invalid input for range. Example: %s. %s' - % (util.limeText('150cm-1'), util.underlineMagenta('Please try again.'))) - return False - unit = splitInput.group(5) - if not unit: - unit = 'cm-1' - unit = unit.lower() - if unit not in RANGE_UNITS: - print('Invalid units. Accepted units are %s' - % (util.limeText(', '.join(RANGE_UNITS)))) - return False - textNumber = '' - for i in range(1, 5): - if splitInput.group(i): - textNumber += splitInput.group(i) - value = float(textNumber) - return pyrad.convertRange(value, unit) - - -def validDepth(userInput): - if not userInput: - return False - try: - splitInput = validValueAndUnits.match(userInput) - except AttributeError: - print('Invalid input for depth. Example: %s. %s' - % (util.limeText('10cm'), util.underlineMagenta('Please try again.'))) - return False - unit = splitInput.group(5) - if not unit: - unit = 'cm' - unit = unit.lower() - if unit not in DEPTH_UNITS: - print('Invalid units. Accepted units are %s' - % (util.limeText(', '.join(DEPTH_UNITS)))) - return False - textNumber = '' - for i in range(1, 5): - if splitInput.group(i): - textNumber += splitInput.group(i) - value = float(textNumber) - return pyrad.convertLength(value, unit) - - -DEPTH_UNITS = ['cm', 'in', 'inches', 'ft', 'feet', 'meter', 'm'] -PRESSURE_UNITS = ['atm', 'bar', 'mbar', 'pa'] -TEMPERATURE_UNITS = ['K', 'C', 'F'] -RANGE_UNITS = ['um', 'cm-1'] -COMPOSITION_UNITS = ['ppm', 'ppb', '%', 'percentage', 'perc', 'concentration'] - -while True: - menuMain() diff --git a/pyradUtilities.py b/pyradUtilities.py index 7098709..678844a 100644 --- a/pyradUtilities.py +++ b/pyradUtilities.py @@ -159,10 +159,11 @@ def writePlanetProfile(name, layer): def getProfileList(): fileList = os.listdir(cwd) profileFiles = [] - for file in profileFiles: + for file in fileList: if '.pyr' in file: profileFiles.append(file) - return fileList + print(file) + return profileFiles def checkPlanetProfile(name): @@ -245,7 +246,7 @@ def profileWriteProgress(name, completed, expected): fileName = 'profileProgress.pyr' filePath = '%s/%s' % (folderPath, fileName) openFile = open(filePath, 'wb') - text = '# profile progess for %s\n' \ + text = '# profile progress for %s\n' \ 'completed: %s\n' \ 'expected: %s' % (name, completed, expected) openFile.write(text.encode('utf-8')) @@ -270,7 +271,7 @@ def profileProgress(name): def emptyProfileDirectory(name): - folderPath = '%s/%s' % (profileDir, name) + folderPath = name fileList = os.listdir(folderPath) for file in fileList: filePath = '%s/%s' % (folderPath, file) diff --git a/sample.py b/sample.py new file mode 100644 index 0000000..3b7b5d6 --- /dev/null +++ b/sample.py @@ -0,0 +1,5 @@ +import pyradClasses + +planet = pyradClasses.createCustomPlanet('earthsimple') +planet2 = pyradClasses.createCustomPlanet('marssimple') +pyradClasses.plotPlanetSpectrum([planet, planet2], verify=True) diff --git a/test.py b/test.py deleted file mode 100644 index ff53fce..0000000 --- a/test.py +++ /dev/null @@ -1,13 +0,0 @@ -import numpy as np -import pyrad -from matplotlib import pyplot as plt - -planet = pyrad.createCustomPlanet('earth low simple') -'''yAxis = np.arange(1, 90E5, 10000) -xAxis = [] -for height in yAxis: - xAxis.append(planet.pressureAtHeight(height)) -plt.plot(xAxis, yAxis) -plt.show()''' -planet2 = pyrad.createCustomPlanet('mars simple') -pyrad.plotPlanetSpectrum([planet], verify=True) \ No newline at end of file From b3f1dc1da18fd12eaefb928b105f74868dd2673e Mon Sep 17 00:00:00 2001 From: Brad Schrag Date: Fri, 26 Oct 2018 23:31:42 -0500 Subject: [PATCH 13/43] finally almost finished.... for now --- earthsimple.pyr | 17 ++- marssimple.pyr | 4 +- pyrad.py | 118 +++++++++++++++++-- pyradClasses.py | 289 +++++++++++++++++++++++++++++----------------- pyradUtilities.py | 210 ++++++++++++++++++++++++--------- 5 files changed, 457 insertions(+), 181 deletions(-) diff --git a/earthsimple.pyr b/earthsimple.pyr index 2820686..610a80a 100644 --- a/earthsimple.pyr +++ b/earthsimple.pyr @@ -1,17 +1,16 @@ # A demo file for pyrad -setting: low - -# mBar , K , km,cm-1,cm-1, m , g -surface: 1013.25, 300, 120, 100, 1500, 100, 9.8 +# mBar , K , km, m , g, cm-1,cm-1 +surface: 1013.25, 288, 120, 100, 9.8, 00, 2000 # mol text name, concentration molecule: co2, .000400 molecule: h2o, .018000 molecule: o3, 0 molecule: o2, .20 -molecule: n2, .78 +molecule: n2, .77 molecule: ch4, .0000018 +molecule: ar, .009 # name, endHeight, endTemp lapse rate: troposphere, 11, 216 @@ -22,18 +21,18 @@ lapse rate: stratopause, 51, 270 lapse rate: mesosphere, 71, 214 lapse rate: mesosphere2, 80, 190 lapse rate: mesopause, 90, 190 -lapse rate: thermosphere, 100, 228 +lapse rate: thermosphere, 120, 228 # name, endHeight, endValue, moleculeName composition rate: WV boundary layer, 2.5, 18000e-6, h2o composition rate: WV troposphere1, 8, 200e-6, h2o composition rate: WV troposphere2, 9, 400e-6, h2o composition rate: WV troposphere2, 10, 400e-6, h2o -composition rate: WV tropopause', 20, 2e-6, h2o -composition rate: WV stratosphere to top',90, 0, h2o +composition rate: WV tropopause, 20, 2e-6, h2o +composition rate: WV stratosphere to top,120, 0, h2o composition rate: troposphere ozone, 16, 60E-9, o3 composition rate: tropopause ozone, 32, 5E-6, o3 composition rate: upper strat ozone, 60, 0, o3 -composition rate: strat on up ozone, 90, 0, o3 +composition rate: strat on up ozone, 120, 0, o3 diff --git a/marssimple.pyr b/marssimple.pyr index bc41dce..ed0274a 100644 --- a/marssimple.pyr +++ b/marssimple.pyr @@ -1,8 +1,6 @@ # mars simple -setting: hi - -surface: 6, 220, 100, 100, 1500, 200, 3.711 +surface: 6, 220, 100, 200, 3.711 molecule: co2, .9532 molecule: n2, .027 diff --git a/pyrad.py b/pyrad.py index 589a5fd..363fc26 100644 --- a/pyrad.py +++ b/pyrad.py @@ -17,7 +17,7 @@ def __init__(self, title, entries, previousMenu=None, menuParams=None): self.menuParams = menuParams def displayMenu(self): - titleStr = '\t' + self.title + titleStr = '\t%s\tdetail: %s' % (self.title, pyradClasses.settings.setting) while len(titleStr) < 60: titleStr += ' ' print('\n%s' % util.underlineCyan(titleStr)) @@ -30,6 +30,9 @@ def displayMenu(self): if 'Main' not in self.title: print(' %s Previous menu' % util.magentaText('B)')) validEntry.append('b') + if 'settings' not in self.title: + print(' %s Settings' % util.magentaText('S)')) + validEntry.append('s') print(' %s Exit' % util.magentaText('X)')) validChoice = False while not validChoice: @@ -37,8 +40,10 @@ def displayMenu(self): if userInput.lower() == 'x': print('Goodbye') exit(1) - elif userInput.lower() == 'b' and 'Main' not in self.title: + elif userInput.lower() == 'b' and 'main' not in self.title.lower(): self.previousMenu() + elif userInput.lower() == 's' and 'settings' not in self.title.lower(): + settingsMenu(self) elif userInput in validEntry: userChoice = self.entries[int(userInput) - 1] if userChoice.nextFunction: @@ -51,7 +56,7 @@ def displayMenu(self): print('Invalid entry. Try again.') def displayMultiChoiceMenu(self): - titleStr = '\t' + self.title + titleStr = '\t%s\tdetail: %s' % (self.title, pyradClasses.settings.setting) while len(titleStr) < 60: titleStr += ' ' print('\n%s' % util.underlineCyan(titleStr)) @@ -64,6 +69,9 @@ def displayMultiChoiceMenu(self): if 'Main' not in self.title: print(' %s Previous menu' % util.magentaText('B)')) validEntry.append('b') + if 'settings' not in self.title: + print(' %s Settings' % util.magentaText('S)')) + validEntry.append('s') print(' %s Exit' % util.magentaText('X)')) validChoice = False while not validChoice: @@ -73,6 +81,8 @@ def displayMultiChoiceMenu(self): exit(1) elif userInput.lower() == 'b' and 'Main' not in self.title: return + elif userInput.lower() == 's' and 'settings' not in self.title.lower(): + settingsMenu(self) else: inputs = userInput.split(',') allValid = True @@ -111,13 +121,22 @@ def createPlot(params): def plotPlanetSpectrum(values): pList = [] for p in values['profiles']: - planet = pyradClasses.createCustomPlanet(p.name) + planet = pyradClasses.loadEmptyPlanet(p.name) pList.append(planet) if values['height'] == -2.71828: pyradClasses.plotPlanetSpectrum(pList, direction=values['direction'], verify=False) else: pyradClasses.plotPlanetSpectrum(pList, direction=values['direction'], height=values['height'], verify=False) - atmosphereTransferMenu() + chooseAtmTransferBuildProfile() + + +def plotPlanetSpectrumComponents(values): + planet = pyradClasses.createCustomPlanet(values['profiles'].name) + if values['height'] == -2.71828: + pyradClasses.plotPlanetAndComponents(planet, direction=values['direction'], verify=False) + else: + pyradClasses.plotPlanetAndComponents(planet, direction=values['direction'], height=values['height'], verify=False) + chooseAtmTransferBuildProfile() def createLayer(atmosphere): @@ -372,6 +391,15 @@ def inputHeight(values): return +def inputHeightComponents(values): + text = 'Enter the height to view transmission from.\t\t\t' + height = receiveInput('%s\n' + 'Units should be in %s. If no value entered, maximum atm height will be used: ' % (util.underlineCyan(text), util.limeText('km')), validNumber, default=-2.71828) + values['height'] = height + plotPlanetSpectrumComponents(values) + return + + def menuChooseLayerToEdit(empty=None): entryList = [] for layer in genericAtmosphere: @@ -509,27 +537,92 @@ def chooseDirection(profileList): 'direction': 'up'}) lookDownEntry = Entry('Looking down', nextFunction=inputHeight, functionParams={'profiles': profileList, 'direction': 'down'}) - menuChooseDirection = Menu('Choose direction to look', [lookUpEntry, lookDownEntry], previousMenu=atmosphereTransferMenu) + menuChooseDirection = Menu('Choose direction to look', [lookUpEntry, lookDownEntry], previousMenu=plotAtmTransferMenu) menuChooseDirection.displayMenu() return -def atmosphereTransferMenu(param=None): +def chooseDirectionComponents(profile): + lookUpEntry = Entry('Looking up', nextFunction=inputHeightComponents, functionParams={'profiles': profile, + 'direction': 'up'}) + lookDownEntry = Entry('Looking down', nextFunction=inputHeightComponents, functionParams={'profiles': profile, + 'direction': 'down'}) + menuChooseDirection = Menu('Choose direction to look', [lookUpEntry, lookDownEntry], + previousMenu=plotProfileComponentsMenu) + menuChooseDirection.displayMenu() + return + + +def plotProfileComponentsMenu(param=None): + entryList = [] + profileList = util.getProfileList() + for profile in profileList: + if util.profileComplete('%s %s' % (profile, pyradClasses.settings.setting)) and \ + util.molSpecProfile(profile, pyradClasses.settings.setting): + entryList.append(Entry('%s' % profile[:-4], nextFunction=chooseDirectionComponents, functionParams=profile)) + menuAtmTransfer = Menu('Choose atmosphere', entryList, previousMenu=chooseAtmTransferBuildProfile) + menuAtmTransfer.displayMenu() + return + + +def buildProfile(profileList): + for profile in profileList: + print('Building %s on setting %s' % (profile.name, pyradClasses.settings.setting)) + planet = pyradClasses.createCustomPlanet(profile.name) + moleculeSpecific = pyradClasses.yesOrNo("Store data by individual molecule? Doesn't require more time, " + "just hard drive space %s:" % util.limeText('(y/n)')) + overwrite = True + if util.profileComplete(planet.folderPath): + overwrite = pyradClasses.yesOrNo("Data for this profile and setting seems to exist.\n" + "Do you wish to overwrite it? %s" % util.limeText('(y/n)')) + if overwrite: + planet.processLayers(verify=False, moleculeSpecific=moleculeSpecific) + chooseAtmTransferBuildProfile() + + +def buildProfilesMenu(param=None): + entryList = [] profileList = util.getProfileList() + for profile in profileList: + entryList.append(Entry('%s' % profile[:-4], nextFunction=buildProfile, functionParams=profile)) + menuBuildProfile = Menu('Which profile(s) do you want to build', entryList, previousMenu=chooseAtmTransferBuildProfile) + menuBuildProfile.displayMultiChoiceMenu() + return + + +def chooseAtmTransferBuildProfile(param=None): + plotProfilesEntry = Entry('Plot profile(s)', nextFunction=plotAtmTransferMenu) + plotProfileAndComponents = Entry('Plot single atm and components', nextFunction=plotProfileComponentsMenu) + buildProfilesEntry = Entry('Build profile(s)', nextFunction=buildProfilesMenu) + menuChooseProfileBuild = Menu('Plot or build profiles', [plotProfilesEntry, plotProfileAndComponents, buildProfilesEntry], previousMenu=menuMain) + menuChooseProfileBuild.displayMenu() + return + + +def plotAtmTransferMenu(param=None): + profileList = util.getCompletedProfileList(pyradClasses.settings.setting) entryList = [] for profile in profileList: - entryList.append(Entry('%s' % profile[:-4], nextFunction=chooseDirection, functionParams=profile)) + entryList.append(Entry('%s' % profile, nextFunction=chooseDirection, functionParams=profile)) menuAtmTransfer = Menu('Choose atmosphere', entryList, previousMenu=menuMain) menuAtmTransfer.displayMultiChoiceMenu() return +def settingsMenu(previousMenu): + lowSetting = Entry('low (intensity > 1E-21)', nextFunction=pyradClasses.settings.changeSetting, functionParams='low') + midSetting = Entry('mid (intensity > 1E-28)', nextFunction=pyradClasses.settings.changeSetting, functionParams='mid') + hiSetting = Entry('hi (all absorption lines)', nextFunction=pyradClasses.settings.changeSetting, functionParams='hi') + menuSettings = Menu('Choose level of detail', [lowSetting, midSetting, hiSetting], previousMenu=menuMain) + return menuSettings + + def menuMain(): gasCellEntry = Entry('Gas cell simulator', nextFunction=gasCellMenu) - atmosphereTransferEntry = Entry('Atmosphere transmission', nextFunction=atmosphereTransferMenu) + atmosphereTransferEntry = Entry('Atmosphere transmission', nextFunction=chooseAtmTransferBuildProfile) mainMenu = Menu('Main menu', [gasCellEntry, atmosphereTransferEntry]) - mainMenu.displayMenu() - return + return mainMenu + def duplicateObj(obj): @@ -711,5 +804,6 @@ def validDepth(userInput): RANGE_UNITS = ['um', 'cm-1'] COMPOSITION_UNITS = ['ppm', 'ppb', '%', 'percentage', 'perc', 'concentration'] +menu = menuMain() while True: - menuMain() + menu = menu.displayMenu() \ No newline at end of file diff --git a/pyradClasses.py b/pyradClasses.py index e532fa4..28f4c22 100644 --- a/pyradClasses.py +++ b/pyradClasses.py @@ -4,6 +4,7 @@ import pyradPlanck import numpy as np import matplotlib.pyplot as plt +import time c = 299792458.0 @@ -19,9 +20,9 @@ settings = utils.Settings('low') -def reduceRes(array, lumpTo=1): +def reduceRes(array, lumpTo=1.0): n = int(lumpTo / settings.baseRes) - length = int(len(array) * settings.baseRes) + length = int(len(array) * settings.baseRes / lumpTo) newArray = np.zeros(length) for m in range(0, length): for i in range(0, n): @@ -29,6 +30,41 @@ def reduceRes(array, lumpTo=1): return newArray +def strToBool(v): + return 'true' in v.lower() + + +def returnHMS(time): + hours = int(time / 3600) + minutes = int((time - hours * 3600) / 60) + seconds = time - hours * 3600 - minutes * 60 + return hours, minutes, seconds + + +def loadEmptyPlanet(folderPath, planet=None, moleculeSpecific=False, verify=False): + values = utils.readCompleteProfile(folderPath) + if planet is None: + planet = Planet(values['name'], float(values['surfacePressure']), int(values['surfaceTemperature']), float(values['maxHeight']), + rangeMin=int(values['rangeMin']), rangeMax=int(values['rangeMax']), initialThickness=float(values['initialDepth']), + gravity=float(values['gravity']), moleculeSpecific=strToBool(values['molSpecific'])) + if utils.profileComplete(folderPath): + fileLength = utils.profileLength(folderPath) + else: + planet.processLayers(verify=verify) + fileLength = utils.profileLength(folderPath) + while len(planet.atmosphere) > 0: + planet.atmosphere.pop() + for i in range(1, fileLength + 1): + lP = utils.readPlanetProfile(folderPath, i, fileLength, moleculeSpecific) + layer = Layer(lP['depth'], lP['T'], lP['P'], lP['rangeMin'], lP['rangeMax'], height=lP['height'], + name=lP['name']) + layer.absorptionCoefficient = np.asarray(lP['absCoef']) + layer.progressAbsCoef = True + planet.atmosphere.append(layer) + print('') + planet.progressProfileLoaded = True + return planet + def createCustomPlanet(name): @@ -38,15 +74,16 @@ def createCustomPlanet(name): temperatureRuleList = initialParameters['temperatureRules'] compositionRuleList = initialParameters['compositionRules'] - try: - value = initialParameters['setting'] - except KeyError: - value = 'low' + #try: + # value = initialParameters['setting'] + #except KeyError: + # value = 'low' + #settings.changeSetting(value) - settings.changeSetting(value) planet = Planet(initialParameters['name'], initialValues['surfacePressure'], initialValues['surfaceTemperature'], initialValues['maxHeight'], rangeMin=initialValues['rangeMin'], - rangeMax=initialValues['rangeMax'], initialThickness=initialValues['initialDepth'], gravity=initialValues['gravity']) + rangeMax=initialValues['rangeMax'], initialThickness=initialValues['initialDepth'], + gravity=initialValues['gravity']) for molecule in moleculeList: planet.addMolecule(molecule['name'], concentration=molecule['concentration']) @@ -249,16 +286,22 @@ def gaussianHW(self): class Isotope(list): def __init__(self, number, molecule): super(Isotope, self).__init__(self) - params = utils.readMolParams(number) - self.globalIsoNumber = params[0] - self.shortName = params[1] - self.name = 'Isotope %s' % self.globalIsoNumber - self.molNum = params[2] - self.isoN = params[3] - self.abundance = params[4] - self.q296 = params[5] - self.gj = params[6] - self.molmass = params[7] + if number in INERT_MOL_DATA: + self.globalIsoNumber = MOLECULE_ID[molecule.name] + self.shortName = molecule.name + self.name = 'Inert molecule %s' % molecule.name + self.molmass = INERT_MOL_DATA[self.globalIsoNumber]['mass'] + else: + params = utils.readMolParams(number) + self.globalIsoNumber = params[0] + self.shortName = params[1] + self.name = 'Isotope %s' % self.globalIsoNumber + self.molNum = params[2] + self.isoN = params[3] + self.abundance = params[4] + self.q296 = params[5] + self.gj = params[6] + self.molmass = params[7] self.molecule = molecule self.layer = self.molecule.layer self.q = {} @@ -327,6 +370,9 @@ def xAxis(self): return np.copy(self.layer.xAxis) def getData(self, lineSurvey=False, verbose=True): + if 'Inert' in self.name: + print('Inert molecule, no data.') + return if verbose: print('Getting data for %s, %s, isotope %s' % (self.layer.name, self.molecule.name, self.globalIsoNumber), end='\r', flush=True) lineDict = utils.gatherData(self.globalIsoNumber, self.layer.effectiveRangeMin, self.layer.effectiveRangeMax) @@ -354,8 +400,7 @@ def createCrossSection(self): return for line in self: if progress > i * alertInterval and len(self) > 50: - text = 'Processing %s, height %skm, mean height %skm, molecule %s: <%s%s>' % (layer.name, round(layer.height / 100000, 2), round(layer.meanHeight / 100000, 2), - molecule.name, '*' * i, '-' * (20 - i)) + text = 'Progress %s: %s: <%s%s>' % (layer.name, molecule.name, '*' * i, '-' * (20 - i)) print(text, end='\r', flush=True) i += 1 progress += 1 @@ -388,6 +433,7 @@ def createCrossSection(self): (self.rangeMax - self.rangeMin) / self.resolution, endpoint=True), crossSection) + self.progressCrossSection = True def createLineSurvey(self): @@ -655,7 +701,7 @@ def yAxis(self): @property def xAxis(self): - return np.linspace(self.rangeMin, self.rangeMax, (self.rangeMax - self.rangeMin) / utils.BASE_RESOLUTION, + return np.linspace(self.rangeMin, self.rangeMax, len(self.absorptionCoefficient), endpoint=True) @property @@ -746,7 +792,10 @@ def addMolecule(self, name, isotopeDepth=1, **abundance): molecule = Molecule(name, self, isotopeDepth, **abundance) self.append(molecule) if totalConcentration(self) > 1: - print('**Warning : Concentrations exceed 1.') + print('**Warning : Concentrations exceed 1: total=%s' % totalConcentration(self)) + for molecule in self: + print('concentration %s: %s' % (molecule.name, molecule.concentration)) + exit(1) molecule.getData() return molecule @@ -766,6 +815,12 @@ def returnMoleculeObjects(self): moleculeList.append(m) return moleculeList + def returnMoleculeNameList(self): + nameList = [] + for m in self: + nameList.append(m.name) + return nameList + def planck(self, temperature): return pyradPlanck.planckWavenumber(self.xAxis, temperature) @@ -855,31 +910,28 @@ def densityAtHeight(self, height, gasConstant): class Planet: - def __init__(self, name, pressure, temperature, maxHeight, molarMass=0.0289644, - gravity=9.80665, rangeMin=0, rangeMax=2000, initialThickness=100): + def __init__(self, name, pressure, temperature, maxHeight, + gravity=9.80665, rangeMin=0, rangeMax=2000, initialThickness=100, moleculeSpecific=False): self.name = name - self.mass = 0 self.gravity = gravity self.maxHeight = maxHeight * 100000 - self.molarMass = molarMass self.radius = 0 self.surfacePressure = pressure self.surfaceTemperature = temperature self.atmosphereRules = [] self.heightList = [] self.depthList = [] + self.moleculeList = [] self.rangeMin = rangeMin self.rangeMax = rangeMax self.setting = settings.setting + self.moleculeSpecific = moleculeSpecific self.atmosphere = Atmosphere("%s's atmosphere" % self.name, planet=self) self.initialLayer = \ self.atmosphere.addLayer(initialThickness * 100, temperature, pressure, rangeMin, rangeMax, name='initial layer', height=0) self.progressProfileLoaded = False - def setMass(self, mass): - self.mass = mass - def addLapseRate(self, name, finalHeight, finalValue, rateFunction=linear): self.atmosphereRules.append(AtmosphereRule(name, finalHeight * 100000, finalValue, 'temperature', self, rateFunction=rateFunction)) @@ -888,21 +940,6 @@ def addCompositionRate(self, name, finalHeight, finalValue, molecule, rateFuncti self.atmosphereRules.append(AtmosphereRule(name, finalHeight * 100000, finalValue, 'composition', self, molecule=molecule, rateFunction=rateFunction)) - def setRadius(self, radius): - self.radius = radius - - def setGravity(self, gravity): - self.gravity = gravity - - def setSurfacePressure(self, pressure): - self.surfacePressure = pressure - - def setSurfaceTemperature(self, temperature): - self.surfaceTemperature = temperature - - def setSurfaceComposition(self): - pass - def returnApplicableRules(self, height, ruleType): ruleList = [] for rule in self.atmosphereRules: @@ -933,6 +970,7 @@ def compositionAtHeight(self, height, molecule): def addMolecule(self, name, isotopeDepth=1, **abundance): molecule = self.initialLayer.addMolecule(name, isotopeDepth, **abundance) + self.moleculeList = self.initialLayer.returnMoleculeNameList() return molecule def sliceAtm(self, verify=True): @@ -950,8 +988,8 @@ def sliceAtm(self, verify=True): pressureList = [layer.P] self.depthList = [layer.depth] while layer.height + layer.depth < self.maxHeight: - print('%s: K: %s, mBar: %s, baseHeight: %skm, depth: %skm, mass: %skg' % ( - 'Layer %s' %len(self.heightList), int(layer.T), round(layer.P, 2), round(layer.height / 100000, 2), round(layer.depth / 100000, 2), round(layer.mass, 2))) + print('%s: K: %s, mBar: %s, height: %skm, depth: %skm' % ( + 'Layer %s' % len(self.heightList), int(layer.T), round(layer.P, 2), round(layer.height / 100000, 2), round(layer.depth / 100000, 2))) newHeight = self.heightList[-1] + self.depthList[-1] tempList.append(self.temperatureAtHeight(newHeight)) pressureList.append(self.pressureAtHeight(newHeight)) @@ -962,18 +1000,15 @@ def sliceAtm(self, verify=True): newDepth = self.maxHeight - newHeight self.heightList.append(newHeight) self.depthList.append(newDepth) - print('%s: K: %s, mBar: %s, baseHeight: %skm, depth: %skm, mass: %skg' % ( + print('%s: K: %s, mBar: %s, height: %skm, depth: %skm' % ( 'Layer %s' % len(self.heightList), int(layer.T), round(layer.P, 2), - round(newHeight, 2), round(newDepth, 2), round(layer.mass, 2))) + round(newHeight / 100000, 2), round(newDepth / 100000, 2))) break else: self.heightList.append(newHeight) self.depthList.append(newDepth) layer.height = newHeight layer.depth = newDepth - '''if self.heightList[-1] + .5 * self.depthList[-1] > self.maxHeight: - self.heightList.pop() - self.depthList.pop()''' print('Total # of layers: %s' % len(self.heightList)) print('Total # of absorption lines per layer: %s' % len(totalLineList(layer))) if verify: @@ -998,15 +1033,17 @@ def sliceAtm(self, verify=True): acceptSetup = True return - def processLayers(self, verify=True): + def processLayers(self, verify=True, moleculeSpecific=False): if utils.profileProgress(self.folderPath): self.sliceAtm(verify=False) if not self.heightList: self.sliceAtm(verify=verify) layer = self.initialLayer - startPoint = utils.profileProgress(self.folderPath) + startPoint, timeStart = utils.profileProgress(self.folderPath) i = startPoint + 1 + totalProcessTime = timeStart for height, depth in zip(self.heightList[startPoint:], self.depthList[startPoint:]): + layerProcessTimeStart = time.time() layer.name = 'Layer %s:%s' % (i, len(self.heightList)) layer.height = height layer.depth = depth @@ -1015,57 +1052,42 @@ def processLayers(self, verify=True): for molecule in layer: molecule.concentration = self.compositionAtHeight(layer.meanHeight, molecule) layer.createCrossSection() - utils.writePlanetProfile(self.folderPath, layer) - utils.profileWriteProgress(self.folderPath, i, len(self.heightList)) + processTime = time.time() - layerProcessTimeStart + utils.writePlanetProfile(self.folderPath, layer, processTime, self.moleculeList, moleculeSpecific=moleculeSpecific) + totalProcessTime += processTime + utils.profileWriteProgress(self.folderPath, i, len(self.heightList), totalProcessTime, + self.moleculeSpecific, self.moleculeList) resetCrossSection(layer) layer.absorptionCoefficient = np.zeros(len(layer.crossSection)) layer.progressAbsCoef = False i += 1 - utils.profileWriteComplete(self.folderPath, i - 1, len(self.heightList)) + utils.profileWriteComplete(self, i - 1, len(self.heightList), totalProcessTime) return - def loadProfile(self, verify=True): - if utils.profileComplete(self.folderPath): - fileLength = utils.profileLength(self.folderPath) - if verify: - if not yesOrNo('%s layers found for profile %s. Load profile (y/n):' % (fileLength, self.name)): - if yesOrNo('Are you sure, selecting yes will delete all previous profile data (y/n): '): - utils.emptyProfileDirectory(self.folderPath) - self.processLayers() - else: - self.processLayers() - fileLength = utils.profileLength(self.folderPath) - while len(self.atmosphere) > 0: - self.atmosphere.pop() - for i in range(1, fileLength + 1): - lP = utils.readPlanetProfile(self.folderPath, i, fileLength) - layer = Layer(lP['depth'], lP['T'], lP['P'], lP['rangeMin'], lP['rangeMax'], height=lP['height'], name=lP['name']) - self.atmosphere.append(layer) - layer.absorptionCoefficient = np.asarray(lP['absCoef']) - layer.progressAbsCoef = True - print('') - self.progressProfileLoaded = True - return + def loadProfile(self, verify=True, moleculeSpecific=False): + if not utils.profileComplete(self.folderPath): + self.processLayers(verify=verify, moleculeSpecific=moleculeSpecific) + loadEmptyPlanet(self.folderPath, self, moleculeSpecific=moleculeSpecific, verify=verify) - def processTransmission(self, height, direction='down', verify=True): + def processTransmission(self, height, direction='down', verify=True, moleculeSpecific=False): if not self.progressProfileLoaded: - self.loadProfile(verify=verify) + self.loadProfile(verify=verify, moleculeSpecific=moleculeSpecific) height = height * 100000 print('Processing atmosphere spectrum from %skm looking %s...' % (height / 100000, direction)) if direction == 'down': - surfaceSpectrum = pyradPlanck.planckWavenumber(self.initialLayer.xAxis, self.surfaceTemperature) + xAxis = np.linspace(self.rangeMin, self.rangeMax, len(self.atmosphere[0].absCoef)) + surfaceSpectrum = pyradPlanck.planckWavenumber(xAxis, self.surfaceTemperature) for layer in self.atmosphere: if layer.meanHeight < height: surfaceSpectrum = layer.transmission(surfaceSpectrum) - print('Processing %s...' % (layer.name), end='\r', flush=True) + print('Processing %s...' % layer.name, end='\r', flush=True) elif direction == 'up': surfaceSpectrum = pyradPlanck.planckWavenumber(self.initialLayer.xAxis, 3) for layer in reversed(self.atmosphere): if layer.meanHeight > height: surfaceSpectrum = layer.transmission(surfaceSpectrum) - print('Processing %s...' % (layer.name), layer.T, end='\r', flush=True) + print('Processing %s...' % layer.name, end='\r', flush=True) print('') - print('total power of spectrum: %sWm-2' % int((integrateSpectrum(surfaceSpectrum) / 5.67E-8)**.25)) return surfaceSpectrum @property @@ -1076,6 +1098,10 @@ def yAxis(self): def folderPath(self): return '%s %s' % (self.name, self.setting) + @property + def molarMass(self): + return self.initialLayer.molarMass / 1000 + @property def xAxis(self): return np.linspace(self.rangeMin, self.rangeMax, (self.rangeMax - self.rangeMin) / utils.BASE_RESOLUTION, @@ -1094,7 +1120,7 @@ def transmission(self): def stefanB(power): - return (power / sb) ^ .25 + return (power / sb) ** .25 class AtmosphereRule: @@ -1137,6 +1163,7 @@ def baseHeightCompositionRule(self, molecule): return height, concentration, pressure def setBaseValues(self, ruleType, molecule): + print(molecule) if ruleType == 'temperature': return self.baseHeightTemperatureRule() elif ruleType == 'composition': @@ -1269,7 +1296,7 @@ def plotSpectrum(layer=None, title=None, rangeMin=None, rangeMax=None, objList=N def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=[300, 280, 250, 210, 170], verify=True, integrateRange=[]): - linewidth = .5 + linewidth = .7 alpha = .7 plt.figure(figsize=(10, 6), dpi=80) plt.subplot(111, facecolor='xkcd:almost black') @@ -1283,24 +1310,21 @@ def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=[ for planet, color in zip(planets, COLOR_LIST[1:]): if not heightFlag: height = planet.maxHeight / 100000 - xAxis = planet.xAxis - #xAxis = np.linspace(planet.rangeMin, planet.rangeMax, planet.rangeMax - planet.rangeMin) - yAxis = planet.processTransmission(height, direction=direction, verify=verify) - #yAxis = reduceRes(planet.processTransmission(height, direction=direction, verify=verify)) - fig, = plt.plot(xAxis, smooth(yAxis, 75), linewidth=linewidth, + yAxis = reduceRes(planet.processTransmission(height, direction=direction, verify=verify)) + xAxis = np.linspace(planet.rangeMin, planet.rangeMax, len(yAxis)) + powerSpectrum = int(integrateSpectrum(yAxis, pi, res=1)) + effTemp = int(stefanB(powerSpectrum)) + fig, = plt.plot(xAxis, yAxis, linewidth=linewidth, alpha=alpha, color=color, - label='%s : %sWm-2' % (planet.name, round(integrateSpectrum(yAxis, pi), 2))) - #fig, = plt.plot(xAxis, yAxis, linewidth=linewidth, - # alpha=alpha, color=color, - # label='%s : %sWm-2' % (planet.name, round(integrateSpectrum(yAxis, pi), 2))) + label='%s : %sWm-2, eff : %sK' % (planet.name, powerSpectrum, effTemp)) handles.append(fig) color = 1 for temperature in temperatureList: yAxis = pyradPlanck.planckWavenumber(xAxis, float(temperature)) - fig, = plt.plot(xAxis, yAxis, linewidth=.75, color=(color, color, color), alpha=alpha, + fig, = plt.plot(xAxis, yAxis, linewidth=.5, color=(color, color, color), alpha=alpha, linestyle=':', label='%sK : %sWm-2' % (temperature, - round(integrateSpectrum(yAxis, pi), 2))) + int(integrateSpectrum(yAxis, pi, res=1)))) handles.append(fig) color -= .15 legend = plt.legend(handles=handles, frameon=False) @@ -1309,6 +1333,56 @@ def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=[ plt.show() +def plotPlanetAndComponents(planet, height=None, direction='down', temperatureList=[300, 280, 250, 210, 170], verify=True): + linewidth = .8 + alpha = .8 + plt.figure(figsize=(10, 6), dpi=80) + plt.subplot(111, facecolor=(.8, .8, .8)) + plt.margins(0.01) + plt.subplots_adjust(left=.05, bottom=.05, right=.97, top=.95) + plt.ylabel('radiance Wm-2sr-1(cm-1)-1') + plt.xlabel('wavenumber cm-1') + handles = [] + if height is None: + height = planet.maxHeight / 100000 + yAxis = reduceRes(planet.processTransmission(height, direction=direction, verify=verify, moleculeSpecific=True)) + xAxis = np.linspace(planet.rangeMin, planet.rangeMax, len(yAxis)) + planckAxis = pyradPlanck.planckWavenumber(xAxis, float(planet.surfaceTemperature)) + surfacePower = int(integrateSpectrum(planckAxis, pi, res=1)) + powerSpectrum = int(integrateSpectrum(yAxis, pi, res=1)) + plt.title('Surface temp: %sK Surface flux: %sWm-2 Effec temp: %sK' + % (planet.surfaceTemperature, surfacePower, int(stefanB(powerSpectrum)))) + fig, = plt.plot(xAxis, yAxis, linewidth=.7, + alpha=1, color='black', + label='net flux: %sWm-2 netGHE: %sWm-2' % (powerSpectrum, surfacePower - powerSpectrum)) + handles.append(fig) + + tempName = planet.name + tempFolder = planet.folderPath + length = len(planet.atmosphere) + for molecule, color in zip(planet.moleculeList, COLOR_LIST[1:]): + print('processing %s in atmosphere' % molecule) + planet.name = molecule + i = 1 + for layer in planet.atmosphere: + layer.absorptionCoefficient = np.asarray(utils.readPlanetProfileMolecule(tempFolder, i, length, molecule)) + i += 1 + yAxis = reduceRes(planet.processTransmission(height, direction=direction, verify=False)) + tempPowerSpectrum = int(integrateSpectrum(yAxis, pi, res=1)) + fig, = plt.plot(xAxis, yAxis, linewidth=linewidth, + alpha=alpha, color=color, + label='%s effect : %sWm-2' % (planet.name, surfacePower - tempPowerSpectrum)) + handles.append(fig) + legend = plt.legend(handles=handles, frameon=False) + text = legend.get_texts() + #plt.setp(text, color='w') + plt.show() + planet.name = tempName + print('Reloading original planet data...') + planet.loadProfile(verify=False) + + + HITRAN_GLOBAL_ISO = {1: {1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 129}, 2: {1: 7, 2: 8, 3: 9, 4: 10, 5: 11, 6: 12, 7: 13, 8: 14, 9: 121, 10: 15, 11: 120, 12: 122}, 3: {1: 16, 2: 17, 3: 18, 4: 19, 5: 20}, @@ -1360,13 +1434,14 @@ def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=[ 49: {1: 124, 2: 125}, 901: {1: 901}} -COLOR_LIST = ['xkcd:white', - 'xkcd:bright orange', - 'xkcd:seafoam green', - 'xkcd:bright blue', - 'xkcd:salmon', - 'xkcd:light violet', - 'xkcd:green yellow'] +COLOR_LIST = [(1, 1, 1), + (160/255, 60/255, 60/255), + (1, 127/255, 42/255), + (.67, .78, .21), + (85/255, 1, 153/255), + (85/255, 153/255, 1), + (153/255, 85/255, 1), + (0, 212/255, 0)] VERSION = utils.VERSION @@ -1383,3 +1458,9 @@ def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=[ 'cf4': 42, 'c4h2': 43, 'hc3n': 44, 'h2': 45, 'cs': 46, 'so3': 47, 'c2n2': 48, 'cocl2': 49, 'ar': 901} + +INERT_MOL_DATA = {901: {'mass': 39.948}} + +THEME = {'dark': {'facecolor': (29/255, 29/255, 29/255), + 'color0': (239/255, 244/255, 1), + 'colorList': [(153/255,180/255,51/255)]}} \ No newline at end of file diff --git a/pyradUtilities.py b/pyradUtilities.py index 678844a..3a823f2 100644 --- a/pyradUtilities.py +++ b/pyradUtilities.py @@ -133,26 +133,37 @@ def openReturnLines(fullPath): return lineList -def writePlanetProfile(name, layer): +def writePlanetProfile(name, layer, processingTime, moleculeList, moleculeSpecific=False): folderPath = '%s/%s' % (profileDir, name) if not os.path.isdir(folderPath): os.mkdir(folderPath) filePath = '%s/%s.pyr' % (folderPath, layer.name) + now = datetime.now() openFile = open(filePath, 'wb') - text = ('depth: %s\n' + text = '# created by PyRad v%s on %s.\n' % (VERSION, now.strftime("%Y-%m-%d %H:%M:%S")) + openFile.write(text.encode('utf-8')) + text = ('time: %ssecs\n' + 'depth: %s\n' 'T: %s\n' 'P: %s\n' 'rangeMin: %s\n' 'rangeMax: %s\n' 'height: %s\n' 'name: %s\n' - '##\t\tlayer absorption coefficient\t\t##\n' - 'absCoef: %s' - % (layer.depth, int(layer.T), layer.P, layer.rangeMin, layer.rangeMax, layer.height, layer.name, - ','.join(map(str, layer.absCoef.tolist())))) + 'molecule list: %s\n' + '# layer abs coef\n' + 'layer absCoef: %s\n' + % (int(processingTime), layer.depth, int(layer.T), layer.P, layer.rangeMin, layer.rangeMax, layer.height, + layer.name, ','.join(moleculeList), ','.join(map(str, layer.absCoef.tolist())))) openFile.write(text.encode('utf-8')) + if moleculeSpecific: + for molecule in layer: + text1 = '# %s abs coef\n' % molecule.name + text2 = '%s absCoef: %s\n' % (molecule.name, ','.join(map(str, molecule.absCoef.tolist()))) + openFile.write(text1.encode('utf-8')) + openFile.write(text2.encode('utf-8')) openFile.close() - print('\n\t\t\tprofile written to %s.pyr' % layer.name) + print(' |--> %s.pyr' % layer.name) return @@ -162,19 +173,64 @@ def getProfileList(): for file in fileList: if '.pyr' in file: profileFiles.append(file) - print(file) return profileFiles +def getCompletedProfileList(settings): + fileList = os.listdir(profileDir) + dirList = [] + completedList = [] + for file in fileList: + if os.path.isdir('%s/%s' % (profileDir, file)): + dirList.append('%s/%s' % (profileDir, file)) + for dir in dirList: + if os.path.isfile('%s/profileComplete.pyr' % dir): + print(dir.split('/')[-1]) + completedList.append(dir.split('/')[-1]) + return completedList + + +def readCompleteProfile(folderPath): + fullPath = '%s/%s/profileComplete.pyr' % (profileDir, folderPath) + lines = openReturnLines(fullPath) + values = {} + for line in lines: + if line[0] == '#': + pass + else: + cells = line.split(':') + values[cells[0].strip()] = cells[1].strip() + return values + + +def molSpecProfile(name, settings): + folder = name[:-4] + folderPath = '%s/%s %s' % (profileDir, folder, settings) + fileName = 'profileComplete.pyr' + filePath = '%s/%s' % (folderPath, fileName) + lines = openReturnLines(filePath) + for line in lines: + if line[0] == '#': + pass + elif line.split(':')[0] == 'molSpecific': + if 'true' in line.split(':')[1].lower(): + return True + else: + return False + + def checkPlanetProfile(name): folderPath = '%s/%s' % (profileDir, name) + print('fullpath=%s' % folderPath) if not os.path.isdir(folderPath): os.mkdir(folderPath) return False else: - fileName = 'completeProfile.pyr' + fileName = 'profileComplete.pyr' filePath = '%s/%s' % (folderPath, fileName) + print('filePath=%s' % filePath) if os.path.isfile(filePath): + print('found file') return True else: return False @@ -186,7 +242,8 @@ def parseCustomProfile(name): params = {'compositionRules': [], 'temperatureRules': [], 'molecules': [], - 'name': name} + 'name': name, + 'molSpecific': False} for line in lines: if line[0] == '#' or line == '': pass @@ -203,29 +260,35 @@ def parseCustomProfile(name): elif 'lapse' in line.lower(): params['temperatureRules'].append(tempDict) elif 'surface' in line.lower(): - tempDict = {} + tempDict = {'rangeMin': 0, + 'rangeMax': 2000} values = line.split(':')[1].split(',') tempDict['surfacePressure'] = float(values[0]) tempDict['surfaceTemperature'] = int(values[1]) tempDict['maxHeight'] = float(values[2]) - tempDict['rangeMin'] = int(values[3]) - tempDict['rangeMax'] = int(values[4]) - tempDict['initialDepth'] = float(values[5]) - tempDict['gravity'] = float(values[6]) + tempDict['initialDepth'] = float(values[3]) + tempDict['gravity'] = float(values[4]) + if len(values) > 5: + tempDict['rangeMin'] = int(values[5]) + if len(values) > 6: + tempDict['rangeMax'] = int(values[6]) params['initialValues'] = tempDict - elif 'setting' in line.lower(): - value = line.split(':')[1].lower() - params['setting'] = value.lower().strip() elif 'molecule' in line.lower(): values = line.split(':')[1].split(',') try: concentration = float(values[1]) + tempDict = {'name': values[0].lower().strip(), + 'concentration': concentration} except ValueError: print('invalid concentration %s in %s' % (values[1], filePath)) exit() - tempDict = {'name': values[0].lower().strip(), - 'concentration': concentration} params['molecules'].append(tempDict) + elif 'molspecific' in line.lower(): + if line.split(':')[1].lower().strip() == 'true': + value = True + else: + value = False + params['molSpecific'] = value return params @@ -238,17 +301,23 @@ def profileLength(name): pass else: values = line.split(':') - return int(values[1]) + if values[0].lower().strip() == 'completed': + return int(values[1]) -def profileWriteProgress(name, completed, expected): +def profileWriteProgress(name, completed, expected, processingTime, moleculeSpecific, moleculeList): folderPath = '%s/%s' % (profileDir, name) - fileName = 'profileProgress.pyr' - filePath = '%s/%s' % (folderPath, fileName) + fileName = 'profileProgress' + filePath = '%s/%s.pyr' % (folderPath, fileName) + text = '# profile for %s\n' \ + '# PyRad v%s\n' \ + '# total processing time: %ssecs\n' \ + 'molSpecific: %s\n' \ + 'molList: %s\n' \ + 'expected: %s\n' \ + 'completed: %s' % (name, VERSION, int(processingTime), + moleculeSpecific, ','.join(moleculeList), expected, completed) openFile = open(filePath, 'wb') - text = '# profile progress for %s\n' \ - 'completed: %s\n' \ - 'expected: %s' % (name, completed, expected) openFile.write(text.encode('utf-8')) openFile.close() return @@ -258,8 +327,9 @@ def profileProgress(name): folderPath = '%s/%s' % (profileDir, name) fileName = 'profileProgress' filePath = '%s/%s.pyr' % (folderPath, fileName) + startTime = 0 if not os.path.isfile(filePath): - return False + return False, startTime lines = openReturnLines(filePath) for line in lines: if line[0] == '#': @@ -267,11 +337,14 @@ def profileProgress(name): else: cells = line.split(':') if cells[0] == 'completed': - return int(cells[1]) + completed = int(cells[1]) + elif cells[0] == 'time': + startTime = int(cells[1].strip()) + return completed, startTime def emptyProfileDirectory(name): - folderPath = name + folderPath = '%s/%s' % (profileDir, name) fileList = os.listdir(folderPath) for file in fileList: filePath = '%s/%s' % (folderPath, file) @@ -289,15 +362,29 @@ def profileComplete(name): return False -def profileWriteComplete(name, completed, expected): - folderPath = '%s/%s' % (profileDir, name) +def profileWriteComplete(planet, completed, expected, processingTime): + folderPath = '%s/%s' % (profileDir, planet.folderPath) fileName = 'profileComplete' filePath = '%s/%s.pyr' % (folderPath, fileName) time = datetime.now() text = '# profile for %s completed on %s\n' \ '# PyRad v%s\n' \ + '# total processing time: %ssecs\n' \ + 'name: %s\n' \ + 'molSpecific: %s\n' \ + 'surfacePressure: %s\n' \ + 'surfaceTemperature: %s\n' \ + 'maxHeight: %s\n' \ + 'initialDepth: %s\n' \ + 'gravity: %s\n' \ + 'rangeMin: %s\n' \ + 'rangeMax: %s\n' \ + 'molList: %s\n' \ 'expected: %s\n' \ - 'completed: %s' % (name, time.strftime("%Y-%m-%d %H:%M:%S"), VERSION, expected, completed) + 'completed: %s' % (planet.folderPath, time.strftime("%Y-%m-%d %H:%M:%S"), VERSION, int(processingTime), + planet.folderPath, planet.moleculeSpecific, planet.surfacePressure, planet.surfaceTemperature, + int(planet.maxHeight / 100000), planet.heightList[1], planet.gravity, + planet.rangeMin, planet.rangeMax, ','.join(planet.moleculeList), expected, completed) openFile = open(filePath, 'wb') openFile.write(text.encode('utf-8')) openFile.close() @@ -307,31 +394,51 @@ def profileWriteComplete(name, completed, expected): return -def readPlanetProfile(name, layerNumber, length): +def readPlanetProfileMolecule(name, layerNumber, length, moleculeName): + folderPath = '%s/%s' % (profileDir, name) + fileName = 'Layer %s:%s' % (layerNumber, length) + filePath = '%s/%s.pyr' % (folderPath, fileName) + print('Reading %s profile from %s... ' % (moleculeName, fileName), end='\r', flush=True) + lines = openReturnLines(filePath) + for line in lines: + keyValue = line.split(':') + if line[0] == '#': + pass + elif keyValue[0].strip() == '%s absCoef' % moleculeName: + absList = keyValue[1].split(',') + absCoefList = [] + for value in absList: + absCoefList.append(float(value)) + return absCoefList + print('missing absCoef for %s in %s' % (moleculeName, filePath)) + exit() + + +def readPlanetProfile(name, layerNumber, length, moleculeSpecific=False): folderPath = '%s/%s' % (profileDir, name) fileName = 'Layer %s:%s' % (layerNumber, length) filePath = '%s/%s.pyr' % (folderPath, fileName) lines = openReturnLines(filePath) print('Reading profile from %s... ' % fileName, end='\r', flush=True) - layerDict = {} + layerDict = {'molecule list': []} for line in lines: keyValue = line.split(':') if line[0] == '#': pass elif keyValue[0].strip() == 'name': layerDict[keyValue[0]] = keyValue[1].strip() - elif keyValue[0].strip() == 'absCoef': + elif keyValue[0].strip() == 'layer absCoef': absList = keyValue[1].split(',') absCoefList = [] for value in absList: absCoefList.append(float(value)) - layerDict[keyValue[0]] = absCoefList + layerDict['absCoef'] = absCoefList elif keyValue[0].strip() == 'T' or keyValue[0] == 'rangeMin' or keyValue[0] == 'rangeMax': layerDict[keyValue[0]] = int(keyValue[1]) - elif keyValue[0].strip() == 'height': + elif keyValue[0].strip() == 'P' or keyValue[0].strip() == 'height' or keyValue[0].strip() == 'depth': layerDict[keyValue[0]] = float(keyValue[1]) else: - layerDict[keyValue[0]] = float(keyValue[1]) + pass return layerDict @@ -476,18 +583,7 @@ def downloadHitran(path, globalID, waveMin, waveMax): '&request_params=%s' % params try: request = urlrequest.urlopen(url) - except urlexception.HTTPError: - print('Can not retrieve data for given parameters.') - openFile = open(path, 'wb') - openFile.write(bytes('%s no data available for %s, range %s-%s' % - (NULL_TAG, globalID, waveMin, waveMax), 'utf-8')) - openFile.close() - request = False - except urlexception.URLError: - print('Can not connect to %s' % str(url)) - request = False - dirLength = len(cwd) - if request: + dirLength = len(cwd) i = 0 openFile = open(path, 'wb') chunkSize = 1024 * 64 @@ -502,6 +598,14 @@ def downloadHitran(path, globalID, waveMin, waveMax): print(outputText, end='\r', flush=True) print('%s%s downloaded.\n' % (outputText, i * chunkSize), end='\r') openFile.close() + except urlexception.HTTPError: + print('Can not retrieve data for given parameters.') + openFile = open(path, 'wb') + openFile.write(bytes('%s no data available for %s, range %s-%s' % + (NULL_TAG, globalID, waveMin, waveMax), 'utf-8')) + openFile.close() + except urlexception.URLError: + print('Can not connect to %s' % str(url)) def readQ(ID, isotopeDepth): @@ -637,8 +741,8 @@ def displayAllMolecules(): 'regularCyan': '\x1b[0;36;48m', 'colorEnd': '\x1b[0m'} -VERSION = '2.0' -titleLine = "%s*********************** PyRad v%s ***********************%s" \ +VERSION = '3.0' +titleLine = "%s****************** PyRad v%s ******************%s" \ % (TEXT_COLORS['underlineCyan'], VERSION, TEXT_COLORS['colorEnd']) messageGap = int((len(titleLine) - len(VERSION) - 1) / 2) GREETING = "%s\n\n" \ From 34600066d4efffee58db18f9b28e7b3f52843ca9 Mon Sep 17 00:00:00 2001 From: Brad Schrag Date: Sat, 27 Oct 2018 09:56:57 -0500 Subject: [PATCH 14/43] theme added. thanks @brandonrgates.... --- pyrad.py | 17 +++++---- pyradClasses.py | 94 +++++++++++++++++++---------------------------- pyradUtilities.py | 67 ++++++++++++++++++++++++++++++++- 3 files changed, 112 insertions(+), 66 deletions(-) diff --git a/pyrad.py b/pyrad.py index 363fc26..549ccf6 100644 --- a/pyrad.py +++ b/pyrad.py @@ -17,7 +17,7 @@ def __init__(self, title, entries, previousMenu=None, menuParams=None): self.menuParams = menuParams def displayMenu(self): - titleStr = '\t%s\tdetail: %s' % (self.title, pyradClasses.settings.setting) + titleStr = '\t%s detail: %s' % (self.title, pyradClasses.settings.setting) while len(titleStr) < 60: titleStr += ' ' print('\n%s' % util.underlineCyan(titleStr)) @@ -88,7 +88,7 @@ def displayMultiChoiceMenu(self): allValid = True userChoices = [] for i in inputs: - print('i: %s' % i) + if i.strip() not in validEntry: allValid = False else: @@ -559,7 +559,7 @@ def plotProfileComponentsMenu(param=None): for profile in profileList: if util.profileComplete('%s %s' % (profile, pyradClasses.settings.setting)) and \ util.molSpecProfile(profile, pyradClasses.settings.setting): - entryList.append(Entry('%s' % profile[:-4], nextFunction=chooseDirectionComponents, functionParams=profile)) + entryList.append(Entry('%s' % profile[:-4], nextFunction=chooseDirectionComponents, functionParams=profile)) menuAtmTransfer = Menu('Choose atmosphere', entryList, previousMenu=chooseAtmTransferBuildProfile) menuAtmTransfer.displayMenu() return @@ -614,15 +614,17 @@ def settingsMenu(previousMenu): midSetting = Entry('mid (intensity > 1E-28)', nextFunction=pyradClasses.settings.changeSetting, functionParams='mid') hiSetting = Entry('hi (all absorption lines)', nextFunction=pyradClasses.settings.changeSetting, functionParams='hi') menuSettings = Menu('Choose level of detail', [lowSetting, midSetting, hiSetting], previousMenu=menuMain) - return menuSettings + menuSettings.displayMenu() + previousMenu.displayMenu() + return def menuMain(): gasCellEntry = Entry('Gas cell simulator', nextFunction=gasCellMenu) atmosphereTransferEntry = Entry('Atmosphere transmission', nextFunction=chooseAtmTransferBuildProfile) mainMenu = Menu('Main menu', [gasCellEntry, atmosphereTransferEntry]) - return mainMenu - + mainMenu.displayMenu() + return def duplicateObj(obj): @@ -804,6 +806,5 @@ def validDepth(userInput): RANGE_UNITS = ['um', 'cm-1'] COMPOSITION_UNITS = ['ppm', 'ppb', '%', 'percentage', 'perc', 'concentration'] -menu = menuMain() while True: - menu = menu.displayMenu() \ No newline at end of file + menuMain() diff --git a/pyradClasses.py b/pyradClasses.py index 28f4c22..d9bf44b 100644 --- a/pyradClasses.py +++ b/pyradClasses.py @@ -17,7 +17,9 @@ avo = 6.022140857E23 sb = 5.67E-8 + settings = utils.Settings('low') +theme = utils.Theme() def reduceRes(array, lumpTo=1.0): @@ -306,7 +308,6 @@ def __init__(self, number, molecule): self.layer = self.molecule.layer self.q = {} self.crossSection = np.copy(self.layer.crossSection) - self.lineSurvey = np.zeros(int((self.layer.rangeMax - self.layer.rangeMin) / utils.BASE_RESOLUTION)) self.progressCrossSection = False @property @@ -450,12 +451,12 @@ def createLineSurvey(self): i += 1 progress += 1 intensity = line.intensity - arrayIndex = int((line.wavenumber - layer.rangeMin) / layer.resolution) - arrayLength = len(lineSurvey) - 1 - if isBetween(arrayIndex, 0, arrayLength): - lineSurvey[arrayIndex] = lineSurvey[arrayIndex] + intensity - self.lineSurvey = lineSurvey - return self.lineSurvey + if intensity > settings.lineIntensityCutoff: + arrayIndex = int((line.wavenumber - layer.rangeMin) / layer.resolution) + arrayLength = len(lineSurvey) - 1 + if isBetween(arrayIndex, 0, arrayLength): + lineSurvey[arrayIndex] = lineSurvey[arrayIndex] + intensity + return lineSurvey def linelist(self): lines = [] @@ -474,6 +475,10 @@ def transmission(self, surfaceSpectrum): def returnCopy(self): return self.linelist() + @property + def lineSurvey(self): + return self.createLineSurvey() + class Molecule(list): def __init__(self, shortNameOrMolNum, layer, isotopeDepth=1, **abundance): @@ -1197,19 +1202,19 @@ def isBetween(test, minValue, maxValue): def plot(propertyToPlot, title, plotList, fill=False): plt.figure(figsize=(10, 6), dpi=80) - plt.subplot(111, facecolor='xkcd:dark grey') + plt.subplot(111, facecolor=theme.faceColor) plt.xlabel('wavenumber cm-1') plt.margins(0.01) plt.subplots_adjust(left=.07, bottom=.08, right=.97, top=.90) plt.ylabel(propertyToPlot) if propertyToPlot == 'line survey': plt.yscale('log') - plt.grid('grey', linewidth=.5, linestyle=':') + plt.grid(theme.gridColor, linewidth=.5, linestyle=':') plt.title('%s' % title) handles = [] linewidth = .7 alpha = .7 - for singlePlot, color in zip(plotList, COLOR_LIST): + for singlePlot, color in zip(plotList, theme.colorList): yAxis, fillAxis = returnPlot(singlePlot, propertyToPlot) fig, = plt.plot(singlePlot.xAxis, yAxis, linewidth=linewidth, alpha=alpha, color=color, label='%s' % singlePlot.name) @@ -1219,14 +1224,14 @@ def plot(propertyToPlot, title, plotList, fill=False): alpha = .5 legend = plt.legend(handles=handles, frameon=False) text = legend.get_texts() - plt.setp(text, color='w') + plt.setp(text, color=theme.textColor) plt.show() def plotSpectrum(layer=None, title=None, rangeMin=None, rangeMax=None, objList=None, surfaceSpectrum=None, planckTemperatureList=None, planckType='wavenumber'): plt.figure(figsize=(10, 6), dpi=80) - plt.subplot(111, facecolor='xkcd:dark grey') + plt.subplot(111, facecolor=theme.faceColor) plt.margins(0.01) plt.subplots_adjust(left=.07, bottom=.08, right=.97, top=.90) if layer: @@ -1250,52 +1255,32 @@ def plotSpectrum(layer=None, title=None, rangeMin=None, rangeMax=None, objList=N xAxis = np.linspace(rangeMin, rangeMax, (rangeMax - rangeMin) / utils.BASE_RESOLUTION) plt.title('%s' % title) handles = [] - blue = .3 - red = 1 - green = .6 - dr = -.15 - db = .15 - dg = .15 if not rangeMax: xAxis = layer.xAxis - for temperature in planckTemperatureList: + for temperature, color in zip(planckTemperatureList, theme.colorList): yAxis = planckFunction(xAxis, float(temperature)) - fig, = plt.plot(xAxis, yAxis, linewidth=.75, color=(red, green, blue), + fig, = plt.plot(xAxis, yAxis, linewidth=.75, color=color, linestyle=':', label='%sK : %sWm-2' % (temperature, round(integrateSpectrum(yAxis, res=(rangeMax - rangeMin) / len(yAxis)), 2))) handles.append(fig) - if red + dr < 0 or red + dr > 1: - dr *= -1 - if green + dg > 1 or green + dg < 0: - dg *= -1 - if blue + db > 1 or blue + db < 0: - db *= -1 - red += dr - green += dg - blue += db - if red < .3 and green < .3 and blue < .3: - green += .5 - blue += .2 - if red < .3 and green < .3: - green += .4 if objList: - alpha = .7 - linewidth = .7 - for obj, color in zip(objList, COLOR_LIST): + alpha = 1 + linewidth = 1 + for obj, color in zip(objList, theme.colorList): yAxis = obj.transmission(surfaceSpectrum) fig, = plt.plot(layer.xAxis, yAxis, linewidth=linewidth, alpha=alpha, color=color, label='%s : %sWm-2' % (obj.name, round(integrateSpectrum(yAxis, pi), 2))) handles.append(fig) - alpha = .5 - linewidth = .7 + alpha = 1 + linewidth = 1 legend = plt.legend(handles=handles, frameon=False) text = legend.get_texts() - plt.setp(text, color='w') + plt.setp(text, color=theme.textColor) plt.show() -def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=[300, 280, 250, 210, 170], verify=True, integrateRange=[]): +def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=[300, 280, 250, 210, 170], verify=True, integrateRange=[], res=1): linewidth = .7 alpha = .7 plt.figure(figsize=(10, 6), dpi=80) @@ -1307,33 +1292,31 @@ def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=[ heightFlag = True if height is None: heightFlag = False - for planet, color in zip(planets, COLOR_LIST[1:]): + for planet, color in zip(planets, theme.colorList): if not heightFlag: height = planet.maxHeight / 100000 yAxis = reduceRes(planet.processTransmission(height, direction=direction, verify=verify)) xAxis = np.linspace(planet.rangeMin, planet.rangeMax, len(yAxis)) - powerSpectrum = int(integrateSpectrum(yAxis, pi, res=1)) + powerSpectrum = int(integrateSpectrum(yAxis, pi, res=res)) effTemp = int(stefanB(powerSpectrum)) fig, = plt.plot(xAxis, yAxis, linewidth=linewidth, alpha=alpha, color=color, label='%s : %sWm-2, eff : %sK' % (planet.name, powerSpectrum, effTemp)) handles.append(fig) - color = 1 - for temperature in temperatureList: + for temperature, color in zip(temperatureList, theme.colorList): yAxis = pyradPlanck.planckWavenumber(xAxis, float(temperature)) - fig, = plt.plot(xAxis, yAxis, linewidth=.5, color=(color, color, color), alpha=alpha, + fig, = plt.plot(xAxis, yAxis, linewidth=.5, color=color, alpha=alpha, linestyle=':', label='%sK : %sWm-2' % (temperature, - int(integrateSpectrum(yAxis, pi, res=1)))) + int(integrateSpectrum(yAxis, pi, res=res)))) handles.append(fig) - color -= .15 legend = plt.legend(handles=handles, frameon=False) text = legend.get_texts() - plt.setp(text, color='w') + plt.setp(text, color=theme.textColor) plt.show() -def plotPlanetAndComponents(planet, height=None, direction='down', temperatureList=[300, 280, 250, 210, 170], verify=True): +def plotPlanetAndComponents(planet, height=None, direction='down', temperatureList=[300, 280, 250, 210, 170], verify=True, res=1): linewidth = .8 alpha = .8 plt.figure(figsize=(10, 6), dpi=80) @@ -1348,8 +1331,8 @@ def plotPlanetAndComponents(planet, height=None, direction='down', temperatureLi yAxis = reduceRes(planet.processTransmission(height, direction=direction, verify=verify, moleculeSpecific=True)) xAxis = np.linspace(planet.rangeMin, planet.rangeMax, len(yAxis)) planckAxis = pyradPlanck.planckWavenumber(xAxis, float(planet.surfaceTemperature)) - surfacePower = int(integrateSpectrum(planckAxis, pi, res=1)) - powerSpectrum = int(integrateSpectrum(yAxis, pi, res=1)) + surfacePower = int(integrateSpectrum(planckAxis, pi, res=res)) + powerSpectrum = int(integrateSpectrum(yAxis, pi, res=res)) plt.title('Surface temp: %sK Surface flux: %sWm-2 Effec temp: %sK' % (planet.surfaceTemperature, surfacePower, int(stefanB(powerSpectrum)))) fig, = plt.plot(xAxis, yAxis, linewidth=.7, @@ -1368,14 +1351,14 @@ def plotPlanetAndComponents(planet, height=None, direction='down', temperatureLi layer.absorptionCoefficient = np.asarray(utils.readPlanetProfileMolecule(tempFolder, i, length, molecule)) i += 1 yAxis = reduceRes(planet.processTransmission(height, direction=direction, verify=False)) - tempPowerSpectrum = int(integrateSpectrum(yAxis, pi, res=1)) + tempPowerSpectrum = int(integrateSpectrum(yAxis, pi, res=res)) fig, = plt.plot(xAxis, yAxis, linewidth=linewidth, alpha=alpha, color=color, label='%s effect : %sWm-2' % (planet.name, surfacePower - tempPowerSpectrum)) handles.append(fig) legend = plt.legend(handles=handles, frameon=False) text = legend.get_texts() - #plt.setp(text, color='w') + plt.setp(text, color=theme.textColor) plt.show() planet.name = tempName print('Reloading original planet data...') @@ -1461,6 +1444,3 @@ def plotPlanetAndComponents(planet, height=None, direction='down', temperatureLi INERT_MOL_DATA = {901: {'mass': 39.948}} -THEME = {'dark': {'facecolor': (29/255, 29/255, 29/255), - 'color0': (239/255, 244/255, 1), - 'colorList': [(153/255,180/255,51/255)]}} \ No newline at end of file diff --git a/pyradUtilities.py b/pyradUtilities.py index 3a823f2..a73e9aa 100644 --- a/pyradUtilities.py +++ b/pyradUtilities.py @@ -12,6 +12,7 @@ curvesDir = '%s/curves' % dataDir molParamsFile = '%s/molparams.txt' % dataDir profileDir = '/%s/profiles' % dataDir +themeDir = '%s/themes' % dataDir debuggerFilePath = '%s/logger.txt' % cwd now = datetime.now() debuggerFile = open(debuggerFilePath, 'wb') @@ -19,6 +20,34 @@ debuggerFile.close() +class Theme: + def __init__(self, value='dark'): + self.theme = value + self.faceColor = None + self.textColor = None + self.gridColor = None + self.colorList = [] + self.loadTheme(self.theme) + + def rgbTuple(self, value): + rgb = value.split(',') + return (float(rgb[0]) / 255, float(rgb[1]) / 255, float(rgb[2]) / 255) + + def loadTheme(self, value): + fullPath = '%s/%s.pyr' % (themeDir, value) + lines = openReturnLines(fullPath) + for line in lines: + cells = line.split(':') + if cells[0] == 'colorList': + self.colorList.append(self.rgbTuple(cells[1])) + elif cells[0] == 'textColor': + self.textColor = self.rgbTuple(cells[1]) + elif cells[0] == 'faceColor': + self.faceColor = self.rgbTuple(cells[1]) + elif cells[0] == 'gridColor': + self.gridColor = self.rgbTuple(cells[1]) + + class Settings: def __init__(self, setting): self.setting = setting @@ -95,7 +124,7 @@ def logToFile(text): def setupDir(): print('Verifying data structure...', end='') sys.stdout.flush() - directoryList = [dataDir, curvesDir, profileDir] + directoryList = [dataDir, curvesDir, profileDir, themeDir] fileList = [] directoryCheck = True fileCheck = True @@ -115,10 +144,36 @@ def setupDir(): if not os.path.isfile(molParamsFile): downloadMolParam() getMolParamsFromHitranFile() + # check theme + filePath = '%s/dark.pyr' % themeDir + if not os.path.isfile(filePath): + writeTheme(filePath) print('files checked.') return directoryCheck and fileCheck +def writeTheme(fullPath): + openFile = open(fullPath, 'wb') + text = '# created by PyRad v%s on %s.\n' \ + '# values are (r, g, b) [0-255]\n' % (VERSION, now.strftime("%Y-%m-%d %H:%M:%S")) + properties = THEME['dark'] + value = 'faceColor' + r,g,b = properties[value] + text += '%s: %s, %s, %s\n' % (value, r, g, b) + value = 'gridColor' + r, g, b = properties[value] + text += '%s: %s, %s, %s\n' % (value, r, g, b) + value = 'textColor' + r, g, b = properties[value] + text += '%s: %s, %s, %s\n' % (value, r, g, b) + for color in properties['colorList']: + r,g,b = color + text += '%s: %s, %s, %s\n' % ('colorList', r,g,b) + openFile.write(text.encode('utf-8')) + openFile.close() + return + + def openReturnLines(fullPath): if not os.path.isfile(fullPath): print('file not found %s' % fullPath) @@ -903,6 +958,16 @@ def displayAllMolecules(): 'cf4': 42, 'c4h2': 43, 'hc3n': 44, 'h2': 45, 'cs': 46, 'so3': 47, 'c2n2': 48, 'cocl2': 49} +THEME = {'dark': {'faceColor': (29, 29, 29), + 'colorList': [(239, 244, 255), + (0, 163, 0), + (126,56, 120), + (0, 171, 169), + (185, 29,171), + (30, 113, 69), + (227, 162, 26)], + 'textColor': (239, 244, 255), + 'gridColor': (204, 204, 204)}} print(GREETING) setupDir() From 097ea61cdbd52a8b071497d63296c0e6d0689974 Mon Sep 17 00:00:00 2001 From: Brad Schrag Date: Sun, 28 Oct 2018 02:02:47 -0500 Subject: [PATCH 15/43] themes added, menu system fixed. It's created a handful of minor bugs but think they are almost cleared up. --- pyrad.py | 282 ++++++++++++++++++++++++---------------------- pyradClasses.py | 72 ++++++------ pyradUtilities.py | 58 +++++----- themes/dark.pyr | 34 ++++++ themes/light.pyr | 32 ++++++ 5 files changed, 279 insertions(+), 199 deletions(-) create mode 100644 themes/dark.pyr create mode 100644 themes/light.pyr diff --git a/pyrad.py b/pyrad.py index 549ccf6..ff76110 100644 --- a/pyrad.py +++ b/pyrad.py @@ -10,50 +10,55 @@ class Menu: - def __init__(self, title, entries, previousMenu=None, menuParams=None): + def __init__(self, title, entries, previousMenu=None, menuParams=None, multiChoice=False): self.title = title self.entries = entries self.previousMenu = previousMenu self.menuParams = menuParams + self.multiChoice = multiChoice def displayMenu(self): - titleStr = '\t%s detail: %s' % (self.title, pyradClasses.settings.setting) - while len(titleStr) < 60: - titleStr += ' ' - print('\n%s' % util.underlineCyan(titleStr)) - i = 1 - validEntry = ['x'] - for entry in self.entries: - validEntry.append(str(i)) - print(' %s) %s' % (util.magentaText(i), entry.name)) - i += 1 - if 'Main' not in self.title: - print(' %s Previous menu' % util.magentaText('B)')) - validEntry.append('b') - if 'settings' not in self.title: - print(' %s Settings' % util.magentaText('S)')) - validEntry.append('s') - print(' %s Exit' % util.magentaText('X)')) - validChoice = False - while not validChoice: - userInput = input('Choose an option: ') - if userInput.lower() == 'x': - print('Goodbye') - exit(1) - elif userInput.lower() == 'b' and 'main' not in self.title.lower(): - self.previousMenu() - elif userInput.lower() == 's' and 'settings' not in self.title.lower(): - settingsMenu(self) - elif userInput in validEntry: - userChoice = self.entries[int(userInput) - 1] - if userChoice.nextFunction: - userChoice.nextFunction(userChoice.functionParams) - validChoice = True - elif userChoice.nextMenu: - userChoice.nextMenu.displayMenu() - validChoice = True - else: - print('Invalid entry. Try again.') + if self.multiChoice: + return self.displayMultiChoiceMenu() + else: + titleStr = ' %s detail: %s' % (self.title, pyradClasses.settings.setting) + while len(titleStr) < 60: + titleStr += ' ' + print('\n%s' % util.underlineCyan(titleStr)) + i = 1 + validEntry = ['x'] + for entry in self.entries: + validEntry.append(str(i)) + print(' %s) %s' % (util.magentaText(i), entry.name)) + i += 1 + text = ' %s) Exit' % util.magentaText('X') + if 'Main' not in self.title: + text += '\t%s) Back' % util.magentaText('B') + validEntry.append('b') + if self.title != 'Choose level of detail': + text += '\t%s) Settings' % util.magentaText('S') + validEntry.append('s') + print(text) + validChoice = False + while not validChoice: + userInput = input('Choose an option: ') + if userInput.lower() == 'x': + print('Goodbye') + exit(1) + elif userInput.lower() == 'b' and 'main' not in self.title.lower(): + if type(self.previousMenu) == Menu: + return self.previousMenu + return self.previousMenu() + elif userInput.lower() == 's' and 'settings' not in self.title.lower(): + return settingsMenu(previousMenu=self) + elif userInput in validEntry: + userChoice = self.entries[int(userInput) - 1] + if userChoice.nextFunction: + return userChoice.nextFunction(userChoice.functionParams) + elif userChoice.nextMenu: + return userChoice.nextMenu(userChoice.functionParams) + else: + print('Invalid entry. Try again.') def displayMultiChoiceMenu(self): titleStr = '\t%s\tdetail: %s' % (self.title, pyradClasses.settings.setting) @@ -75,14 +80,14 @@ def displayMultiChoiceMenu(self): print(' %s Exit' % util.magentaText('X)')) validChoice = False while not validChoice: - userInput = input('Choose an option: ') + userInput = input('Choose an option(s). Separate multiple choices with a comma: ') if userInput.lower() == 'x': print('Goodbye') exit(1) - elif userInput.lower() == 'b' and 'Main' not in self.title: - return + elif userInput.lower() == 'b' and 'main' not in self.title.lower(): + return self.previousMenu() elif userInput.lower() == 's' and 'settings' not in self.title.lower(): - settingsMenu(self) + return settingsMenu(previousMenu=self) else: inputs = userInput.split(',') allValid = True @@ -94,9 +99,13 @@ def displayMultiChoiceMenu(self): else: userChoices.append(self.entries[int(i) - 1]) if allValid: - nextFunction = userChoices[0].nextFunction - nextFunction(userChoices) - validChoice = True + if userChoices[0].nextFunction: + nextFunction = userChoices[0].nextFunction + return nextFunction(userChoices) + else: + nextMenu = userChoices[0].nextMenu + tempMenu = nextMenu(userChoices) + return tempMenu else: print('Invalid entry. Try again.') @@ -107,7 +116,22 @@ def __init__(self, text, nextMenu=None, nextFunction=None, functionParams=None, self.nextMenu = nextMenu self.nextFunction = nextFunction self.functionParams = functionParams - self.previousMenu = previousMenu + if previousMenu: + self.previousMenu = previousMenu() + + +def changeSettings(params): + value = params[0] + previousMenu = params[1] + pyradClasses.settings.changeSetting(value) + return previousMenu + + +def loadTheme(params): + value = params[0] + previousMenu = params[1] + pyradClasses.theme.loadTheme(value) + return settingsMenu(previousMenu) def createPlot(params): @@ -115,7 +139,7 @@ def createPlot(params): plotType = params['plotType'] plotTitle = params['title'] pyradClasses.plot(plotType, plotTitle, plotList) - menuChoosePlotType() + return menuChoosePlotType() def plotPlanetSpectrum(values): @@ -127,16 +151,16 @@ def plotPlanetSpectrum(values): pyradClasses.plotPlanetSpectrum(pList, direction=values['direction'], verify=False) else: pyradClasses.plotPlanetSpectrum(pList, direction=values['direction'], height=values['height'], verify=False) - chooseAtmTransferBuildProfile() + return chooseAtmTransferBuildProfile() def plotPlanetSpectrumComponents(values): - planet = pyradClasses.createCustomPlanet(values['profiles'].name) + planet = pyradClasses.loadEmptyPlanet(values['profiles'][0].name) if values['height'] == -2.71828: pyradClasses.plotPlanetAndComponents(planet, direction=values['direction'], verify=False) else: pyradClasses.plotPlanetAndComponents(planet, direction=values['direction'], height=values['height'], verify=False) - chooseAtmTransferBuildProfile() + return chooseAtmTransferBuildProfile() def createLayer(atmosphere): @@ -157,8 +181,7 @@ def createLayer(atmosphere): else: print('Name already taken. Please try again.') layer = atmosphere.addLayer(depth, temperature, pressure, rangeMin, rangeMax, name=layerName) - createMolecule(layer) - return + return createMolecule(layer) def createMolecule(layer): @@ -177,19 +200,18 @@ def createMolecule(layer): if ask.strip().lower() == 'y': validInput = True elif ask.strip().lower() == 'n': - gasCellMenu() + return gasCellMenu() def menuEditLayerParam(layer): editDepth = Entry('Depth', nextFunction=editLayerDepth, functionParams=layer) editRange = Entry('Min or max range', nextFunction=editLayerRange, functionParams=layer) - editTemperature = Entry('Temperature',nextFunction=editLayerTemperature, functionParams=layer) + editTemperature = Entry('Temp erature',nextFunction=editLayerTemperature, functionParams=layer) editPressure = Entry('Pressure', nextFunction=editLayerPressure, functionParams=layer) entryList = [editDepth, editRange, editTemperature, editPressure] menu = Menu('Choose the parameter to edit for %s' % layer.name, entryList, previousMenu=menuEditParamsOrComp, menuParams=layer) - menu.displayMenu() - return + return menu def editLayerDepth(layer): @@ -197,7 +219,7 @@ def editLayerDepth(layer): % (util.limeText('depth'), util.limeText(layer.name), util.cyanText('%scm' % layer.depth))) depth = inputLayerDepth(default=layer.depth) layer.changeDepth(depth) - menuEditLayerParam(layer) + return menuEditLayerParam(layer) def editLayerTemperature(layer): @@ -205,7 +227,7 @@ def editLayerTemperature(layer): % (util.limeText('temperature'), util.limeText(layer.name), util.cyanText('%sK' % layer.T))) temperature = inputLayerTemperature(default=layer.T) layer.changeTemperature(temperature) - menuEditLayerParam(layer) + return menuEditLayerParam(layer) def editLayerPressure(layer): @@ -213,7 +235,7 @@ def editLayerPressure(layer): % (util.limeText('pressure'), util.limeText(layer.name), util.cyanText('%smbar' % layer.P))) pressure = inputLayerPressure(default=layer.P) layer.changePressure(pressure) - menuEditLayerParam(layer) + return menuEditLayerParam(layer) def editLayerRange(layer): @@ -222,7 +244,7 @@ def editLayerRange(layer): util.cyanText('%s-%scm-1' % (layer.rangeMin, layer.rangeMax)))) rangeMin, rangeMax = inputLayerRange(defaultMin=layer.rangeMin, defaultMax=layer.rangeMax) layer.changeRange(rangeMin, rangeMax) - menuEditLayerParam(layer) + return menuEditLayerParam(layer) def editComposition(molecule): @@ -387,8 +409,7 @@ def inputHeight(values): height = receiveInput('%s\n' 'Units should be in %s. If no value entered, maximum atm height will be used: ' % (util.underlineCyan(text), util.limeText('km')), validNumber, default=-2.71828) values['height'] = height - plotPlanetSpectrum(values) - return + return plotPlanetSpectrum(values) def inputHeightComponents(values): @@ -396,8 +417,7 @@ def inputHeightComponents(values): height = receiveInput('%s\n' 'Units should be in %s. If no value entered, maximum atm height will be used: ' % (util.underlineCyan(text), util.limeText('km')), validNumber, default=-2.71828) values['height'] = height - plotPlanetSpectrumComponents(values) - return + return plotPlanetSpectrumComponents(values) def menuChooseLayerToEdit(empty=None): @@ -406,8 +426,7 @@ def menuChooseLayerToEdit(empty=None): nextEntry = Entry(layer.name, nextFunction=menuEditParamsOrComp, functionParams=layer) entryList.append(nextEntry) editLayerMenu = Menu('Edit layer', entryList) - editLayerMenu.displayMenu() - return + return editLayerMenu def menuChooseTransmission(plotType): @@ -421,15 +440,14 @@ def menuChooseTransmission(plotType): nextEntry = Entry('%s and components' % layer.name, nextFunction=createTransmission, functionParams=params) entryList.append(nextEntry) transmissionMenu = Menu('Choose which layers to plot transmission', entryList) - transmissionMenu.displayMenu() - return + return transmissionMenu def createPlanckCurves(plotType): plotList = inputPlanckTemps() rangeMin, rangeMax = inputPlanckRange(plotType) pyradClasses.plotSpectrum(title='Planck spectrums', rangeMin=rangeMin, rangeMax=rangeMax, planckTemperatureList=plotList, planckType=plotType) - return + return menuMain() def menuPlanckType(empty=None): @@ -440,9 +458,8 @@ def menuPlanckType(empty=None): entryList.append(Entry('By %s (cm-1)' % wavenumber, nextFunction=createPlanckCurves, functionParams=wavenumber)) entryList.append(Entry('By %s (um)' % wavelength, nextFunction=createPlanckCurves, functionParams=wavelength)) entryList.append(Entry('By %s (s-1)' % hertz, nextFunction=createPlanckCurves, functionParams=hertz)) - planckTypeMenu = Menu('Choose planck type', entryList) - planckTypeMenu.displayMenu() - return + planckTypeMenu = Menu('Choose planck type', entryList, previousMenu=menuMain) + return planckTypeMenu def createTransmission(params): @@ -457,21 +474,20 @@ def createTransmission(params): pyradClasses.plotSpectrum(layer, objList=objList, surfaceSpectrum=pyradPlanck.planckWavenumber(layer.xAxis, temperature[0]), planckTemperatureList=temperature) - return + return menuChoosePlotType() def menuChoosePlotType(empty=None): entryList = [] - entryList.append(Entry('transmittance', nextFunction=menuChooseLayerToPlot, functionParams='transmittance')) - entryList.append(Entry('absorption coefficient', nextFunction=menuChooseLayerToPlot, functionParams='absorption coefficient')) - entryList.append(Entry('cross section', nextFunction=menuChooseLayerToPlot, functionParams='cross section')) - entryList.append(Entry('absorbance', nextFunction=menuChooseLayerToPlot, functionParams='absorbance')) - entryList.append(Entry('optical depth', nextFunction=menuChooseLayerToPlot, functionParams='optical depth')) - entryList.append(Entry('line survey', nextFunction=menuChooseLayerToPlot, functionParams='line survey')) - entryList.append(Entry('transmission', nextFunction=menuChooseTransmission, functionParams='transmission')) + entryList.append(Entry('transmittance', nextMenu=menuChooseLayerToPlot, functionParams='transmittance')) + entryList.append(Entry('absorption coefficient', nextMenu=menuChooseLayerToPlot, functionParams='absorption coefficient')) + entryList.append(Entry('cross section', nextMenu=menuChooseLayerToPlot, functionParams='cross section')) + entryList.append(Entry('absorbance', nextMenu=menuChooseLayerToPlot, functionParams='absorbance')) + entryList.append(Entry('optical depth', nextMenu=menuChooseLayerToPlot, functionParams='optical depth')) + entryList.append(Entry('line survey', nextMenu=menuChooseLayerToPlot, functionParams='line survey')) + entryList.append(Entry('transmission', nextMenu=menuChooseTransmission, functionParams='transmission')) choosePlotTypeMenu = Menu('Choose plot type', entryList, previousMenu=gasCellMenu) - choosePlotTypeMenu.displayMenu() - return + return choosePlotTypeMenu def menuChooseLayerToPlot(plotType): @@ -485,8 +501,7 @@ def menuChooseLayerToPlot(plotType): nextEntry = Entry('%s and components' % layer.name, nextFunction=createPlot, functionParams=params) entryList.append(nextEntry) plotLayerMenu = Menu('Plot layer', entryList, previousMenu=menuChoosePlotType) - plotLayerMenu.displayMenu() - return + return plotLayerMenu def createObjAndComponents(obj): @@ -505,8 +520,7 @@ def menuEditComposition(layer): entryList.append(newEntry) entryList.append(Entry('Add a new molecule(s)', nextFunction=createMolecule, functionParams=layer)) editCompMenu = Menu('Choose a molecule to edit', entryList, previousMenu=menuEditParamsOrComp) - editCompMenu.displayMenu() - return + return editCompMenu def menuEditParamsOrComp(layer): @@ -518,28 +532,24 @@ def menuEditParamsOrComp(layer): editCompositionEntry = Entry('Edit composition', nextFunction=menuEditComposition, functionParams=layer) entryList.append(editCompositionEntry) chooseParamsMenu = Menu('Edit or duplicate', entryList, previousMenu=menuChooseLayerToEdit) - chooseParamsMenu.displayMenu() - return + return chooseParamsMenu def gasCellMenu(param=None): createLayerEntry = Entry("Create new gas cell", nextFunction=createLayer, functionParams=genericAtmosphere) - editLayerEntry = Entry("Edit/duplicate gas cell", nextFunction=menuChooseLayerToEdit) - plotLayerEntry = Entry("Plot gas cell", nextFunction=menuChoosePlotType) - planckPlotEntry = (Entry('Plot planck curves', nextFunction=menuPlanckType)) - menuGasCell = Menu('Gas cell simulator', [createLayerEntry, editLayerEntry, plotLayerEntry, planckPlotEntry], previousMenu=menuMain) - menuGasCell.displayMenu() - return + editLayerEntry = Entry("Edit/duplicate gas cell", nextMenu=menuChooseLayerToEdit) + plotLayerEntry = Entry("Plot gas cell", nextMenu=menuChoosePlotType) + menuGasCell = Menu('Gas cell simulator', [createLayerEntry, editLayerEntry, plotLayerEntry], previousMenu=menuMain) + return menuGasCell def chooseDirection(profileList): lookUpEntry = Entry('Looking up', nextFunction=inputHeight, functionParams={'profiles': profileList, 'direction': 'up'}) lookDownEntry = Entry('Looking down', nextFunction=inputHeight, functionParams={'profiles': profileList, - 'direction': 'down'}) + 'direction': 'down'}) menuChooseDirection = Menu('Choose direction to look', [lookUpEntry, lookDownEntry], previousMenu=plotAtmTransferMenu) - menuChooseDirection.displayMenu() - return + return menuChooseDirection def chooseDirectionComponents(profile): @@ -549,20 +559,16 @@ def chooseDirectionComponents(profile): 'direction': 'down'}) menuChooseDirection = Menu('Choose direction to look', [lookUpEntry, lookDownEntry], previousMenu=plotProfileComponentsMenu) - menuChooseDirection.displayMenu() - return + return menuChooseDirection def plotProfileComponentsMenu(param=None): entryList = [] - profileList = util.getProfileList() + profileList = util.molSpecProfileList() for profile in profileList: - if util.profileComplete('%s %s' % (profile, pyradClasses.settings.setting)) and \ - util.molSpecProfile(profile, pyradClasses.settings.setting): - entryList.append(Entry('%s' % profile[:-4], nextFunction=chooseDirectionComponents, functionParams=profile)) - menuAtmTransfer = Menu('Choose atmosphere', entryList, previousMenu=chooseAtmTransferBuildProfile) - menuAtmTransfer.displayMenu() - return + entryList.append(Entry('%s' % profile, nextMenu=chooseDirectionComponents, functionParams=profile)) + menuAtmTransfer = Menu('Choose atmosphere', entryList, previousMenu=chooseAtmTransferBuildProfile, multiChoice=True) + return menuAtmTransfer def buildProfile(profileList): @@ -576,55 +582,61 @@ def buildProfile(profileList): overwrite = pyradClasses.yesOrNo("Data for this profile and setting seems to exist.\n" "Do you wish to overwrite it? %s" % util.limeText('(y/n)')) if overwrite: + util.emptyProfileDirectory(planet.folderPath) planet.processLayers(verify=False, moleculeSpecific=moleculeSpecific) - chooseAtmTransferBuildProfile() + return chooseAtmTransferBuildProfile() def buildProfilesMenu(param=None): entryList = [] - profileList = util.getProfileList() + profileList = util.getPyrFileList() for profile in profileList: entryList.append(Entry('%s' % profile[:-4], nextFunction=buildProfile, functionParams=profile)) - menuBuildProfile = Menu('Which profile(s) do you want to build', entryList, previousMenu=chooseAtmTransferBuildProfile) - menuBuildProfile.displayMultiChoiceMenu() - return + menuBuildProfile = Menu('Which profile(s) do you want to build', entryList, previousMenu=chooseAtmTransferBuildProfile, multiChoice=True) + return menuBuildProfile def chooseAtmTransferBuildProfile(param=None): - plotProfilesEntry = Entry('Plot profile(s)', nextFunction=plotAtmTransferMenu) - plotProfileAndComponents = Entry('Plot single atm and components', nextFunction=plotProfileComponentsMenu) - buildProfilesEntry = Entry('Build profile(s)', nextFunction=buildProfilesMenu) + plotProfilesEntry = Entry('Plot profile(s)', nextMenu=plotAtmTransferMenu) + plotProfileAndComponents = Entry('Plot single atm and components', nextMenu=plotProfileComponentsMenu) + buildProfilesEntry = Entry('Build profile(s)', nextMenu=buildProfilesMenu) menuChooseProfileBuild = Menu('Plot or build profiles', [plotProfilesEntry, plotProfileAndComponents, buildProfilesEntry], previousMenu=menuMain) - menuChooseProfileBuild.displayMenu() - return + return menuChooseProfileBuild def plotAtmTransferMenu(param=None): - profileList = util.getCompletedProfileList(pyradClasses.settings.setting) + profileList = util.getCompletedProfileList() entryList = [] for profile in profileList: - entryList.append(Entry('%s' % profile, nextFunction=chooseDirection, functionParams=profile)) - menuAtmTransfer = Menu('Choose atmosphere', entryList, previousMenu=menuMain) - menuAtmTransfer.displayMultiChoiceMenu() - return + entryList.append(Entry('%s' % profile, nextMenu=chooseDirection, functionParams=profile)) + menuAtmTransfer = Menu('Choose atmosphere', entryList, previousMenu=menuMain, multiChoice=True) + return menuAtmTransfer + + +def chooseThemeMenu(originalMenu): + themeList = pyradClasses.theme.listOfThemes + entryList = [] + for theme in themeList: + entryList.append(Entry('%s' % theme, nextFunction=loadTheme, functionParams=(theme, originalMenu))) + menuChooseTheme = Menu('Choose theme', entryList, previousMenu=settingsMenu) + return menuChooseTheme def settingsMenu(previousMenu): - lowSetting = Entry('low (intensity > 1E-21)', nextFunction=pyradClasses.settings.changeSetting, functionParams='low') - midSetting = Entry('mid (intensity > 1E-28)', nextFunction=pyradClasses.settings.changeSetting, functionParams='mid') - hiSetting = Entry('hi (all absorption lines)', nextFunction=pyradClasses.settings.changeSetting, functionParams='hi') - menuSettings = Menu('Choose level of detail', [lowSetting, midSetting, hiSetting], previousMenu=menuMain) - menuSettings.displayMenu() - previousMenu.displayMenu() - return + lowSetting = Entry('low (intensity > 1E-21)', nextFunction=changeSettings, functionParams=('low', previousMenu)) + midSetting = Entry('mid (intensity > 1E-28)', nextFunction=changeSettings, functionParams=('mid', previousMenu)) + hiSetting = Entry('hi (all absorption lines)', nextFunction=changeSettings, functionParams=('hi', previousMenu)) + loadTheme = Entry('Change theme', nextMenu=chooseThemeMenu, functionParams=previousMenu) + menuSettings = Menu('Choose level of detail', [lowSetting, midSetting, hiSetting, loadTheme], previousMenu=previousMenu) + return menuSettings def menuMain(): - gasCellEntry = Entry('Gas cell simulator', nextFunction=gasCellMenu) - atmosphereTransferEntry = Entry('Atmosphere transmission', nextFunction=chooseAtmTransferBuildProfile) - mainMenu = Menu('Main menu', [gasCellEntry, atmosphereTransferEntry]) - mainMenu.displayMenu() - return + gasCellEntry = Entry('Gas cell simulator', nextMenu=gasCellMenu) + atmosphereTransferEntry = Entry('Atmosphere transmission', nextMenu=chooseAtmTransferBuildProfile) + planckPlotEntry = (Entry('Plot planck curves', nextMenu=menuPlanckType)) + mainMenu = Menu('Main menu', [gasCellEntry, atmosphereTransferEntry, planckPlotEntry]) + return mainMenu def duplicateObj(obj): @@ -806,5 +818,7 @@ def validDepth(userInput): RANGE_UNITS = ['um', 'cm-1'] COMPOSITION_UNITS = ['ppm', 'ppb', '%', 'percentage', 'perc', 'concentration'] +menu = menuMain() while True: - menuMain() + menu = menu.displayMenu() + diff --git a/pyradClasses.py b/pyradClasses.py index d9bf44b..574e202 100644 --- a/pyradClasses.py +++ b/pyradClasses.py @@ -43,12 +43,14 @@ def returnHMS(time): return hours, minutes, seconds -def loadEmptyPlanet(folderPath, planet=None, moleculeSpecific=False, verify=False): +def loadEmptyPlanet(folderPath, planet=None, verify=False): values = utils.readCompleteProfile(folderPath) if planet is None: planet = Planet(values['name'], float(values['surfacePressure']), int(values['surfaceTemperature']), float(values['maxHeight']), - rangeMin=int(values['rangeMin']), rangeMax=int(values['rangeMax']), initialThickness=float(values['initialDepth']), - gravity=float(values['gravity']), moleculeSpecific=strToBool(values['molSpecific'])) + rangeMin=int(values['rangeMin']), rangeMax=int(values['rangeMax']), initialThickness=int(float(values['initialDepth'])), + gravity=float(values['gravity'])) + for mol in values['molList'].split(','): + planet.moleculeList.append(mol) if utils.profileComplete(folderPath): fileLength = utils.profileLength(folderPath) else: @@ -57,7 +59,7 @@ def loadEmptyPlanet(folderPath, planet=None, moleculeSpecific=False, verify=Fals while len(planet.atmosphere) > 0: planet.atmosphere.pop() for i in range(1, fileLength + 1): - lP = utils.readPlanetProfile(folderPath, i, fileLength, moleculeSpecific) + lP = utils.readPlanetProfile(folderPath, i, fileLength) layer = Layer(lP['depth'], lP['T'], lP['P'], lP['rangeMin'], lP['rangeMax'], height=lP['height'], name=lP['name']) layer.absorptionCoefficient = np.asarray(lP['absCoef']) @@ -76,12 +78,6 @@ def createCustomPlanet(name): temperatureRuleList = initialParameters['temperatureRules'] compositionRuleList = initialParameters['compositionRules'] - #try: - # value = initialParameters['setting'] - #except KeyError: - # value = 'low' - #settings.changeSetting(value) - planet = Planet(initialParameters['name'], initialValues['surfacePressure'], initialValues['surfaceTemperature'], initialValues['maxHeight'], rangeMin=initialValues['rangeMin'], rangeMax=initialValues['rangeMax'], initialThickness=initialValues['initialDepth'], @@ -434,7 +430,6 @@ def createCrossSection(self): (self.rangeMax - self.rangeMin) / self.resolution, endpoint=True), crossSection) - self.progressCrossSection = True def createLineSurvey(self): @@ -916,7 +911,7 @@ def densityAtHeight(self, height, gasConstant): class Planet: def __init__(self, name, pressure, temperature, maxHeight, - gravity=9.80665, rangeMin=0, rangeMax=2000, initialThickness=100, moleculeSpecific=False): + gravity=9.80665, rangeMin=0, rangeMax=2000, initialThickness=100): self.name = name self.gravity = gravity self.maxHeight = maxHeight * 100000 @@ -930,7 +925,6 @@ def __init__(self, name, pressure, temperature, maxHeight, self.rangeMin = rangeMin self.rangeMax = rangeMax self.setting = settings.setting - self.moleculeSpecific = moleculeSpecific self.atmosphere = Atmosphere("%s's atmosphere" % self.name, planet=self) self.initialLayer = \ self.atmosphere.addLayer(initialThickness * 100, temperature, pressure, rangeMin, rangeMax, @@ -1022,8 +1016,7 @@ def sliceAtm(self, verify=True): else: validNumber = False while not validNumber: - print( - 'Enter the new initial depth. Larger depth will decrease number of layers, smaller will increase') + print('Enter the new initial depth. Larger depth will decrease number of layers, smaller will increase') userNumber = input('Current depth is %s:' % utils.limeText('%sm' % (int(self.depthList[0]) / 100))) try: newDepth = float(userNumber) @@ -1061,12 +1054,12 @@ def processLayers(self, verify=True, moleculeSpecific=False): utils.writePlanetProfile(self.folderPath, layer, processTime, self.moleculeList, moleculeSpecific=moleculeSpecific) totalProcessTime += processTime utils.profileWriteProgress(self.folderPath, i, len(self.heightList), totalProcessTime, - self.moleculeSpecific, self.moleculeList) + moleculeSpecific, self.moleculeList) resetCrossSection(layer) layer.absorptionCoefficient = np.zeros(len(layer.crossSection)) layer.progressAbsCoef = False i += 1 - utils.profileWriteComplete(self, i - 1, len(self.heightList), totalProcessTime) + utils.profileWriteComplete(self, i - 1, len(self.heightList), totalProcessTime, moleculeSpecific=moleculeSpecific) return def loadProfile(self, verify=True, moleculeSpecific=False): @@ -1168,7 +1161,6 @@ def baseHeightCompositionRule(self, molecule): return height, concentration, pressure def setBaseValues(self, ruleType, molecule): - print(molecule) if ruleType == 'temperature': return self.baseHeightTemperatureRule() elif ruleType == 'composition': @@ -1280,11 +1272,10 @@ def plotSpectrum(layer=None, title=None, rangeMin=None, rangeMax=None, objList=N plt.show() -def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=[300, 280, 250, 210, 170], verify=True, integrateRange=[], res=1): - linewidth = .7 - alpha = .7 +def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=(290, 260, 230, 200), verify=True, integrateRange=[], res=1): + linewidth = 1 plt.figure(figsize=(10, 6), dpi=80) - plt.subplot(111, facecolor='xkcd:almost black') + plt.subplot(111, facecolor=theme.faceColor) plt.margins(0.01) plt.subplots_adjust(left=.07, bottom=.08, right=.97, top=.90) plt.ylabel('Radiance Wm-2sr-1(cm-1)-1') @@ -1299,13 +1290,12 @@ def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=[ xAxis = np.linspace(planet.rangeMin, planet.rangeMax, len(yAxis)) powerSpectrum = int(integrateSpectrum(yAxis, pi, res=res)) effTemp = int(stefanB(powerSpectrum)) - fig, = plt.plot(xAxis, yAxis, linewidth=linewidth, - alpha=alpha, color=color, + fig, = plt.plot(xAxis, yAxis, linewidth=linewidth, color=color, label='%s : %sWm-2, eff : %sK' % (planet.name, powerSpectrum, effTemp)) handles.append(fig) for temperature, color in zip(temperatureList, theme.colorList): yAxis = pyradPlanck.planckWavenumber(xAxis, float(temperature)) - fig, = plt.plot(xAxis, yAxis, linewidth=.5, color=color, alpha=alpha, + fig, = plt.plot(xAxis, yAxis, linewidth=1, color=color, linestyle=':', label='%sK : %sWm-2' % (temperature, int(integrateSpectrum(yAxis, pi, res=res)))) @@ -1316,11 +1306,10 @@ def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=[ plt.show() -def plotPlanetAndComponents(planet, height=None, direction='down', temperatureList=[300, 280, 250, 210, 170], verify=True, res=1): - linewidth = .8 - alpha = .8 +def plotPlanetAndComponents(planet, height=None, direction='down', temperatureList=(290, 260, 230, 200),verify=True, res=1): + linewidth = 1 plt.figure(figsize=(10, 6), dpi=80) - plt.subplot(111, facecolor=(.8, .8, .8)) + plt.subplot(111, facecolor=theme.faceColor) plt.margins(0.01) plt.subplots_adjust(left=.05, bottom=.05, right=.97, top=.95) plt.ylabel('radiance Wm-2sr-1(cm-1)-1') @@ -1335,34 +1324,39 @@ def plotPlanetAndComponents(planet, height=None, direction='down', temperatureLi powerSpectrum = int(integrateSpectrum(yAxis, pi, res=res)) plt.title('Surface temp: %sK Surface flux: %sWm-2 Effec temp: %sK' % (planet.surfaceTemperature, surfacePower, int(stefanB(powerSpectrum)))) - fig, = plt.plot(xAxis, yAxis, linewidth=.7, - alpha=1, color='black', + fig, = plt.plot(xAxis, yAxis, linewidth=1, color=theme.colorList[0], label='net flux: %sWm-2 netGHE: %sWm-2' % (powerSpectrum, surfacePower - powerSpectrum)) handles.append(fig) - tempName = planet.name - tempFolder = planet.folderPath length = len(planet.atmosphere) - for molecule, color in zip(planet.moleculeList, COLOR_LIST[1:]): + for molecule, color in zip(planet.moleculeList, theme.colorList[1:]): print('processing %s in atmosphere' % molecule) planet.name = molecule i = 1 for layer in planet.atmosphere: - layer.absorptionCoefficient = np.asarray(utils.readPlanetProfileMolecule(tempFolder, i, length, molecule)) + layer.absorptionCoefficient = np.asarray(utils.readPlanetProfileMolecule(tempName, i, length, molecule)) i += 1 yAxis = reduceRes(planet.processTransmission(height, direction=direction, verify=False)) tempPowerSpectrum = int(integrateSpectrum(yAxis, pi, res=res)) - fig, = plt.plot(xAxis, yAxis, linewidth=linewidth, - alpha=alpha, color=color, + fig, = plt.plot(xAxis, yAxis, linewidth=linewidth, color=color, label='%s effect : %sWm-2' % (planet.name, surfacePower - tempPowerSpectrum)) handles.append(fig) + for temperature, color in zip(temperatureList, theme.colorList): + yAxis = pyradPlanck.planckWavenumber(xAxis, float(temperature)) + fig, = plt.plot(xAxis, yAxis, linewidth=linewidth, color=color, + linestyle=':', label='%sK : %sWm-2' % + (temperature, + int(integrateSpectrum(yAxis, pi, res=res)))) + handles.append(fig) legend = plt.legend(handles=handles, frameon=False) text = legend.get_texts() plt.setp(text, color=theme.textColor) plt.show() planet.name = tempName - print('Reloading original planet data...') - planet.loadProfile(verify=False) + #print('Reloading original planet data...') + #return loadEmptyPlanet(planet.name, verify=False) + return + diff --git a/pyradUtilities.py b/pyradUtilities.py index a73e9aa..7fae48e 100644 --- a/pyradUtilities.py +++ b/pyradUtilities.py @@ -12,7 +12,7 @@ curvesDir = '%s/curves' % dataDir molParamsFile = '%s/molparams.txt' % dataDir profileDir = '/%s/profiles' % dataDir -themeDir = '%s/themes' % dataDir +themeDir = '%s/themes' % cwd debuggerFilePath = '%s/logger.txt' % cwd now = datetime.now() debuggerFile = open(debuggerFilePath, 'wb') @@ -47,6 +47,14 @@ def loadTheme(self, value): elif cells[0] == 'gridColor': self.gridColor = self.rgbTuple(cells[1]) + @property + def listOfThemes(self): + themeList = [] + fileList = getPyrFileList(themeDir) + for file in fileList: + themeList.append(file.split('.')[0]) + return themeList + class Settings: def __init__(self, setting): @@ -218,12 +226,12 @@ def writePlanetProfile(name, layer, processingTime, moleculeList, moleculeSpecif openFile.write(text1.encode('utf-8')) openFile.write(text2.encode('utf-8')) openFile.close() - print(' |--> %s.pyr' % layer.name) + print('\t\t\t\t\t\t ||> %s.pyr' % layer.name, end='\r', flush=True) return -def getProfileList(): - fileList = os.listdir(cwd) +def getPyrFileList(folder=cwd): + fileList = os.listdir(folder) profileFiles = [] for file in fileList: if '.pyr' in file: @@ -231,7 +239,7 @@ def getProfileList(): return profileFiles -def getCompletedProfileList(settings): +def getCompletedProfileList(): fileList = os.listdir(profileDir) dirList = [] completedList = [] @@ -240,7 +248,6 @@ def getCompletedProfileList(settings): dirList.append('%s/%s' % (profileDir, file)) for dir in dirList: if os.path.isfile('%s/profileComplete.pyr' % dir): - print(dir.split('/')[-1]) completedList.append(dir.split('/')[-1]) return completedList @@ -258,34 +265,31 @@ def readCompleteProfile(folderPath): return values -def molSpecProfile(name, settings): - folder = name[:-4] - folderPath = '%s/%s %s' % (profileDir, folder, settings) - fileName = 'profileComplete.pyr' - filePath = '%s/%s' % (folderPath, fileName) - lines = openReturnLines(filePath) - for line in lines: - if line[0] == '#': - pass - elif line.split(':')[0] == 'molSpecific': - if 'true' in line.split(':')[1].lower(): - return True - else: - return False +def molSpecProfileList(): + completedProfileDirList = getCompletedProfileList() + completeList = [] + for completeDir in completedProfileDirList: + folderPath = '%s/%s' % (profileDir, completeDir) + fullPath = '%s/profileComplete.pyr' % folderPath + lines = openReturnLines(fullPath) + for line in lines: + if line[0] == '#': + pass + elif line.split(':')[0] == 'molSpecific': + if 'true' in line.split(':')[1].lower(): + completeList.append(completeDir) + return completeList def checkPlanetProfile(name): folderPath = '%s/%s' % (profileDir, name) - print('fullpath=%s' % folderPath) if not os.path.isdir(folderPath): os.mkdir(folderPath) return False else: fileName = 'profileComplete.pyr' filePath = '%s/%s' % (folderPath, fileName) - print('filePath=%s' % filePath) if os.path.isfile(filePath): - print('found file') return True else: return False @@ -400,6 +404,8 @@ def profileProgress(name): def emptyProfileDirectory(name): folderPath = '%s/%s' % (profileDir, name) + if not os.path.isdir(folderPath): + return fileList = os.listdir(folderPath) for file in fileList: filePath = '%s/%s' % (folderPath, file) @@ -417,7 +423,7 @@ def profileComplete(name): return False -def profileWriteComplete(planet, completed, expected, processingTime): +def profileWriteComplete(planet, completed, expected, processingTime, moleculeSpecific=False): folderPath = '%s/%s' % (profileDir, planet.folderPath) fileName = 'profileComplete' filePath = '%s/%s.pyr' % (folderPath, fileName) @@ -437,7 +443,7 @@ def profileWriteComplete(planet, completed, expected, processingTime): 'molList: %s\n' \ 'expected: %s\n' \ 'completed: %s' % (planet.folderPath, time.strftime("%Y-%m-%d %H:%M:%S"), VERSION, int(processingTime), - planet.folderPath, planet.moleculeSpecific, planet.surfacePressure, planet.surfaceTemperature, + planet.folderPath, moleculeSpecific, planet.surfacePressure, planet.surfaceTemperature, int(planet.maxHeight / 100000), planet.heightList[1], planet.gravity, planet.rangeMin, planet.rangeMax, ','.join(planet.moleculeList), expected, completed) openFile = open(filePath, 'wb') @@ -469,7 +475,7 @@ def readPlanetProfileMolecule(name, layerNumber, length, moleculeName): exit() -def readPlanetProfile(name, layerNumber, length, moleculeSpecific=False): +def readPlanetProfile(name, layerNumber, length): folderPath = '%s/%s' % (profileDir, name) fileName = 'Layer %s:%s' % (layerNumber, length) filePath = '%s/%s.pyr' % (folderPath, fileName) diff --git a/themes/dark.pyr b/themes/dark.pyr new file mode 100644 index 0000000..44dced5 --- /dev/null +++ b/themes/dark.pyr @@ -0,0 +1,34 @@ +# created by PyRad v3.0 on 2018-10-27 09:53:17. +# values are (r, g, b) [0-255] +# placing color names next to them isn't necessary, just helps correct a color if you don't like it later +# don't put comments after the color values + +# dark grey +faceColor: 29, 29, 29 + +# light grey +gridColor: 204, 204, 204 + +# pale blue +textColor: 239, 244, 255 + +# pale blue +colorList: 239, 244, 255 + +# light purple +colorList: 159, 0, 167 + +# teal +colorList: 0, 171, 169 + +# dark red +colorList: 185, 29, 171 + +# dark green +colorList: 30, 113, 69 + +# orange +colorList: 227, 162, 26 + +# light green +colorList: 0, 163, 0 diff --git a/themes/light.pyr b/themes/light.pyr new file mode 100644 index 0000000..08be515 --- /dev/null +++ b/themes/light.pyr @@ -0,0 +1,32 @@ +# created by PyRad v3.0 on 2018-10-27 09:53:17. +# values are (r, g, b) [0-255] + +# dark grey +textColor: 29, 29, 29 + +# light grey +gridColor: 204, 204, 204 + +# pale blue +faceColor: 239, 244, 255 + +# dark purple +colorList: 96, 60, 186 + +# light green +colorList: 0, 163, 0 + +# light purple +colorList: 159, 0, 167 + +# teal +colorList: 0, 171, 169 + +# dark red +colorList: 185, 29, 171 + +# dark green +colorList: 30, 113, 69 + +# orange +colorList: 227, 162, 26 From 9fcf7298af4e428783f7a6ba648457d076cd035f Mon Sep 17 00:00:00 2001 From: Brad Schrag Date: Mon, 29 Oct 2018 14:47:19 -0500 Subject: [PATCH 16/43] cleaning up presentation --- pyrad.py | 18 ++++++++-------- pyradClasses.py | 24 ++++++++++----------- pyradUtilities.py | 53 ++++++----------------------------------------- sample.py | 10 ++++++--- themes/dark.pyr | 37 +++++++++++++++++++-------------- themes/light.pyr | 41 +++++++++++++++++++++--------------- 6 files changed, 79 insertions(+), 104 deletions(-) diff --git a/pyrad.py b/pyrad.py index ff76110..1f19b9e 100644 --- a/pyrad.py +++ b/pyrad.py @@ -622,15 +622,6 @@ def chooseThemeMenu(originalMenu): return menuChooseTheme -def settingsMenu(previousMenu): - lowSetting = Entry('low (intensity > 1E-21)', nextFunction=changeSettings, functionParams=('low', previousMenu)) - midSetting = Entry('mid (intensity > 1E-28)', nextFunction=changeSettings, functionParams=('mid', previousMenu)) - hiSetting = Entry('hi (all absorption lines)', nextFunction=changeSettings, functionParams=('hi', previousMenu)) - loadTheme = Entry('Change theme', nextMenu=chooseThemeMenu, functionParams=previousMenu) - menuSettings = Menu('Choose level of detail', [lowSetting, midSetting, hiSetting, loadTheme], previousMenu=previousMenu) - return menuSettings - - def menuMain(): gasCellEntry = Entry('Gas cell simulator', nextMenu=gasCellMenu) atmosphereTransferEntry = Entry('Atmosphere transmission', nextMenu=chooseAtmTransferBuildProfile) @@ -639,6 +630,15 @@ def menuMain(): return mainMenu +def settingsMenu(previousMenu=menuMain): + lowSetting = Entry('low (intensity > 1E-21)', nextFunction=changeSettings, functionParams=('low', previousMenu)) + midSetting = Entry('mid (intensity > 1E-28)', nextFunction=changeSettings, functionParams=('mid', previousMenu)) + hiSetting = Entry('hi (all absorption lines)', nextFunction=changeSettings, functionParams=('hi', previousMenu)) + loadTheme = Entry('Change theme', nextMenu=chooseThemeMenu, functionParams=previousMenu) + menuSettings = Menu('Choose level of detail', [lowSetting, midSetting, hiSetting, loadTheme], previousMenu=previousMenu) + return menuSettings + + def duplicateObj(obj): newObj = obj.returnCopy() if isinstance(newObj, pyradClasses.Layer): diff --git a/pyradClasses.py b/pyradClasses.py index 574e202..88b449f 100644 --- a/pyradClasses.py +++ b/pyradClasses.py @@ -1317,14 +1317,21 @@ def plotPlanetAndComponents(planet, height=None, direction='down', temperatureLi handles = [] if height is None: height = planet.maxHeight / 100000 - yAxis = reduceRes(planet.processTransmission(height, direction=direction, verify=verify, moleculeSpecific=True)) - xAxis = np.linspace(planet.rangeMin, planet.rangeMax, len(yAxis)) + yTotal = reduceRes(planet.processTransmission(height, direction=direction, verify=verify, moleculeSpecific=True)) + xAxis = np.linspace(planet.rangeMin, planet.rangeMax, len(yTotal)) + for temperature, color in zip(temperatureList, theme.gridList): + yAxis = pyradPlanck.planckWavenumber(xAxis, float(temperature)) + fig, = plt.plot(xAxis, yAxis, linewidth=linewidth / 2, color=color, + linestyle='--', label='%sK : %sWm-2' % + (temperature, + int(integrateSpectrum(yAxis, pi, res=res)))) + handles.append(fig) planckAxis = pyradPlanck.planckWavenumber(xAxis, float(planet.surfaceTemperature)) surfacePower = int(integrateSpectrum(planckAxis, pi, res=res)) - powerSpectrum = int(integrateSpectrum(yAxis, pi, res=res)) + powerSpectrum = int(integrateSpectrum(yTotal, pi, res=res)) plt.title('Surface temp: %sK Surface flux: %sWm-2 Effec temp: %sK' % (planet.surfaceTemperature, surfacePower, int(stefanB(powerSpectrum)))) - fig, = plt.plot(xAxis, yAxis, linewidth=1, color=theme.colorList[0], + fig, = plt.plot(xAxis, yTotal, linewidth=linewidth, color=theme.colorList[0], label='net flux: %sWm-2 netGHE: %sWm-2' % (powerSpectrum, surfacePower - powerSpectrum)) handles.append(fig) tempName = planet.name @@ -1338,16 +1345,9 @@ def plotPlanetAndComponents(planet, height=None, direction='down', temperatureLi i += 1 yAxis = reduceRes(planet.processTransmission(height, direction=direction, verify=False)) tempPowerSpectrum = int(integrateSpectrum(yAxis, pi, res=res)) - fig, = plt.plot(xAxis, yAxis, linewidth=linewidth, color=color, + fig, = plt.plot(xAxis, yAxis, linewidth=linewidth, color=color, alpha=.6, label='%s effect : %sWm-2' % (planet.name, surfacePower - tempPowerSpectrum)) handles.append(fig) - for temperature, color in zip(temperatureList, theme.colorList): - yAxis = pyradPlanck.planckWavenumber(xAxis, float(temperature)) - fig, = plt.plot(xAxis, yAxis, linewidth=linewidth, color=color, - linestyle=':', label='%sK : %sWm-2' % - (temperature, - int(integrateSpectrum(yAxis, pi, res=res)))) - handles.append(fig) legend = plt.legend(handles=handles, frameon=False) text = legend.get_texts() plt.setp(text, color=theme.textColor) diff --git a/pyradUtilities.py b/pyradUtilities.py index 7fae48e..e7bb74b 100644 --- a/pyradUtilities.py +++ b/pyradUtilities.py @@ -3,13 +3,11 @@ import urllib.request as urlrequest import urllib.error as urlexception from datetime import datetime -import numpy as np cwd = os.getcwd() lineSep = os.linesep dataDir = '%s/data' % cwd -curvesDir = '%s/curves' % dataDir molParamsFile = '%s/molparams.txt' % dataDir profileDir = '/%s/profiles' % dataDir themeDir = '%s/themes' % cwd @@ -25,7 +23,7 @@ def __init__(self, value='dark'): self.theme = value self.faceColor = None self.textColor = None - self.gridColor = None + self.gridList = [] self.colorList = [] self.loadTheme(self.theme) @@ -36,6 +34,8 @@ def rgbTuple(self, value): def loadTheme(self, value): fullPath = '%s/%s.pyr' % (themeDir, value) lines = openReturnLines(fullPath) + self.colorList = [] + self.gridList = [] for line in lines: cells = line.split(':') if cells[0] == 'colorList': @@ -44,8 +44,8 @@ def loadTheme(self, value): self.textColor = self.rgbTuple(cells[1]) elif cells[0] == 'faceColor': self.faceColor = self.rgbTuple(cells[1]) - elif cells[0] == 'gridColor': - self.gridColor = self.rgbTuple(cells[1]) + elif cells[0] == 'gridList': + self.gridList.append(self.rgbTuple(cells[1])) @property def listOfThemes(self): @@ -132,7 +132,7 @@ def logToFile(text): def setupDir(): print('Verifying data structure...', end='') sys.stdout.flush() - directoryList = [dataDir, curvesDir, profileDir, themeDir] + directoryList = [dataDir, profileDir, themeDir] fileList = [] directoryCheck = True fileCheck = True @@ -513,35 +513,6 @@ def writeDictListToFile(dictionary, fullPath, comments=None, mode='wb'): openFile.close() -def getCurves(curveType, res): - curveDict = {} - resDirectory = '%s/res%s' % (curvesDir, res) - print('Retrieving %s curves...' % curveType, end='', flush=True) - if not os.path.isdir(resDirectory): - os.mkdir(resDirectory) - if curveType == 'voigt': - curveFilePath = '%s/voigt.pyr' % resDirectory - elif curveType == 'lorentz': - curveFilePath = '%s/lorentz.pyr' % resDirectory - elif curveType == 'gaussian': - curveFilePath = '%s/gaussian.pyr' % resDirectory - rows = openReturnLines(curveFilePath) - if rows: - for row in rows: - cells = row.strip().split(',') - key = cells.pop(0) - for i in range(0, len(cells) - 1): - if cells[i]: - try: - cells[i] = float(cells[i]) - except ValueError: - print(cells[i]) - cells.pop() - curveDict[key] = np.asarray(cells) - print('%s built from cache.' % len(curveDict)) - return curveDict - - def getMolParamsFromHitranFile(): rows = openReturnLines(molParamsFile) isotopeInfo = {} @@ -744,18 +715,6 @@ def readMolParams(globalIso): return [globalIso, shortName, moleculeNum, isoN, abundance, q296, gj, molMass] -def writeCurveToFile(curveDict, curveName, res): - resDirectory = '%s/res%s' % (curvesDir, res) - resFile = '%s/%s.pyr' % (resDirectory, curveName) - openFile = open(resFile, 'ab') - for key in curveDict: - openFile.write(bytes('%s,' % key, 'utf-8')) - for value in curveDict[key]: - openFile.write(bytes('%s,' % value, 'utf-8')) - openFile.write(bytes('\n', 'utf-8')) - openFile.close() - - def displayAllMolecules(): newLineIter = 0 for molecule in MOLECULE_ID.keys(): diff --git a/sample.py b/sample.py index 3b7b5d6..5d6769a 100644 --- a/sample.py +++ b/sample.py @@ -1,5 +1,9 @@ import pyradClasses -planet = pyradClasses.createCustomPlanet('earthsimple') -planet2 = pyradClasses.createCustomPlanet('marssimple') -pyradClasses.plotPlanetSpectrum([planet, planet2], verify=True) +planet = pyradClasses.createCustomPlanet('earthsimplemolspec narrow') + + +#planet2 = pyradClasses.createCustomPlanet('marssimple') + +pyradClasses.plotPlanetAndComponents(planet, verify=True) +#pyradClasses.plotPlanetSpectrum([planet], verify=True) \ No newline at end of file diff --git a/themes/dark.pyr b/themes/dark.pyr index 44dced5..1830841 100644 --- a/themes/dark.pyr +++ b/themes/dark.pyr @@ -7,28 +7,33 @@ faceColor: 29, 29, 29 # light grey -gridColor: 204, 204, 204 +gridList: 240, 240, 240 +gridList: 210, 210, 210 +gridList: 170, 170, 170 +gridList: 130, 130, 130 +gridList: 90, 90, 90 -# pale blue -textColor: 239, 244, 255 +# light grey +textColor: 240, 240, 240 +colorList: 240, 240, 240 -# pale blue -colorList: 239, 244, 255 +# dark green +colorList: 30, 100, 30 -# light purple -colorList: 159, 0, 167 +# dark blue +colorList: 0, 20, 110 -# teal -colorList: 0, 171, 169 +# dark purple +colorList: 70, 30, 70 # dark red -colorList: 185, 29, 171 +colorList: 100, 20, 20 -# dark green -colorList: 30, 113, 69 +# dark teal +colorList: 0, 80, 80 -# orange -colorList: 227, 162, 26 +# dark orange +colorList: 130, 50, 0 -# light green -colorList: 0, 163, 0 +# light blue +colorList: 0, 160, 160 diff --git a/themes/light.pyr b/themes/light.pyr index 08be515..ccb7ddb 100644 --- a/themes/light.pyr +++ b/themes/light.pyr @@ -2,31 +2,38 @@ # values are (r, g, b) [0-255] # dark grey -textColor: 29, 29, 29 +textColor: 50, 50, 50 -# light grey -gridColor: 204, 204, 204 +# greys +gridList: 30, 30, 30 +gridList: 70, 70, 70 +gridList: 110, 110, 110 +gridList: 150, 150, 150 +gridList: 190, 190, 190 -# pale blue -faceColor: 239, 244, 255 +# lighter gray +faceColor: 215, 215, 215 -# dark purple -colorList: 96, 60, 186 +# mid gray +colorList: 140, 140, 140 # light green -colorList: 0, 163, 0 +colorList: 60, 255, 130 -# light purple -colorList: 159, 0, 167 +# orange +colorList: 227, 162, 26 + +# light blue +colorList: 120, 120, 255 # teal -colorList: 0, 171, 169 +colorList: 50, 170, 170 -# dark red -colorList: 185, 29, 171 +# light red/pink +colorList: 255, 100, 100 -# dark green -colorList: 30, 113, 69 +# light purple +colorList: 190, 160, 190 -# orange -colorList: 227, 162, 26 +# yellow +colorList: 255, 255, 100 From ef6f7514045e377e04ecbd872763ad0b394eab1f Mon Sep 17 00:00:00 2001 From: Brad Schrag Date: Tue, 30 Oct 2018 19:43:38 -0500 Subject: [PATCH 17/43] worth chasing the rabbit down the hole. Now a by molecule transmission takes up about 30megs for earth, vs 2.2gigs prior.Needless to say, loading time is a bit quicker as well. --- pyrad.py | 13 +++++- pyradClasses.py | 102 ++++++++++++++++++++++++++++++++++++++-------- pyradUtilities.py | 72 ++++++++++++++++++++++++++++++-- sample.py | 2 +- themes/dark.pyr | 27 +++++++----- 5 files changed, 182 insertions(+), 34 deletions(-) diff --git a/pyrad.py b/pyrad.py index 1f19b9e..2f332d3 100644 --- a/pyrad.py +++ b/pyrad.py @@ -145,7 +145,7 @@ def createPlot(params): def plotPlanetSpectrum(values): pList = [] for p in values['profiles']: - planet = pyradClasses.loadEmptyPlanet(p.name) + planet = pyradClasses.loadEmptyPlanet2(p.name) pList.append(planet) if values['height'] == -2.71828: pyradClasses.plotPlanetSpectrum(pList, direction=values['direction'], verify=False) @@ -155,7 +155,7 @@ def plotPlanetSpectrum(values): def plotPlanetSpectrumComponents(values): - planet = pyradClasses.loadEmptyPlanet(values['profiles'][0].name) + planet = pyradClasses.loadEmptyPlanet2(values['profiles'][0].name) if values['height'] == -2.71828: pyradClasses.plotPlanetAndComponents(planet, direction=values['direction'], verify=False) else: @@ -578,9 +578,18 @@ def buildProfile(profileList): moleculeSpecific = pyradClasses.yesOrNo("Store data by individual molecule? Doesn't require more time, " "just hard drive space %s:" % util.limeText('(y/n)')) overwrite = True + progress, time = util.profileProgress(planet.folderPath) + print('progress: %s' % progress) if util.profileComplete(planet.folderPath): overwrite = pyradClasses.yesOrNo("Data for this profile and setting seems to exist.\n" "Do you wish to overwrite it? %s" % util.limeText('(y/n)')) + elif progress: + resume = pyradClasses.yesOrNo('Partial data exists for this setting, do you wish to resume? %s' % util.limeText('(y/n)')) + if not resume: + overwrite = pyradClasses.yesOrNo("Are you sure, choosing yes will erase all previous data.\n" + "Do you wish to overwrite it? %s" % util.limeText('(y/n)')) + else: + planet.processLayers(verify=False, moleculeSpecific=moleculeSpecific) if overwrite: util.emptyProfileDirectory(planet.folderPath) planet.processLayers(verify=False, moleculeSpecific=moleculeSpecific) diff --git a/pyradClasses.py b/pyradClasses.py index 88b449f..c5e5a73 100644 --- a/pyradClasses.py +++ b/pyradClasses.py @@ -43,17 +43,77 @@ def returnHMS(time): return hours, minutes, seconds +def loadEmptyPlanet2(folderPath, verify=False): + values = utils.readCompleteProfile(folderPath) + planet = Planet(values['name'], float(values['surfacePressure']), int(values['surfaceTemperature']), + float(values['maxHeight']), + rangeMin=int(values['rangeMin']), rangeMax=int(values['rangeMax']), + initialThickness=int(float(values['initialDepth'])), + gravity=float(values['gravity'])) + for mol in values['molList'].split(','): + planet.moleculeList.append(mol) + #if utils.profileComplete(folderPath): + # fileLength = utils.profileLength(folderPath) + #else: + # planet.processLayers(verify=verify) + return planet + + +def readTransmittance(planet, height, direction): + height = height * 100000 + fileLength = utils.profileLength(planet.name) + moleculeList = planet.moleculeList + values = {} + xAxis = np.linspace(planet.rangeMin, planet.rangeMax, int(planet.rangeMax - planet.rangeMin) / planet.res) + if direction == 'down': + values['layer'] = pyradPlanck.planckWavenumber(xAxis, planet.surfaceTemperature) + fileArray = list(range(1, fileLength + 1)) + print(fileArray) + else: + values['layer'] = pyradPlanck.planckWavenumber(xAxis, 2.7) + fileArray = list(reversed(range(1, fileLength + 1))) + for molecule in moleculeList: + values[molecule] = np.copy(values['layer']) + i = 0 + layer = utils.readPlanetProfileTransmittance(planet.name, fileArray[i], fileLength) + meanHeight = layer['height'] + .5 * layer['depth'] + if direction == 'down': + while meanHeight < height and i < len(fileArray) - 1: + transmittance = np.asarray(layer['layer']) + transmitted = values['layer'] * transmittance + emittance = 1 - transmittance + emitted = emittance * pyradPlanck.planckWavenumber(xAxis, layer['T']) + values['layer'] = transmitted + emitted + for molecule in moleculeList: + transmittance = np.asarray(layer[molecule]) + transmitted = values[molecule] * transmittance + emittance = 1 - transmittance + emitted = emittance * pyradPlanck.planckWavenumber(xAxis, layer['T']) + values[molecule] = transmitted + emitted + i += 1 + layer = utils.readPlanetProfileTransmittance(planet.name, fileArray[i], fileLength) + meanHeight = layer['height'] + .5 * layer['depth'] + else: + while meanHeight > height and i < fileLength + 1: + transmittance = np.asarray(layer['layer']) + values['layer'] = values['layer'] * transmittance + for molecule in moleculeList: + values[molecule] = values[molecule] * transmittance + i += 1 + layer = utils.readPlanetProfileTransmittance(planet.name, fileArray[i], fileLength) + meanHeight = layer['height'] + .5 * layer['depth'] + return values + + def loadEmptyPlanet(folderPath, planet=None, verify=False): values = utils.readCompleteProfile(folderPath) if planet is None: planet = Planet(values['name'], float(values['surfacePressure']), int(values['surfaceTemperature']), float(values['maxHeight']), rangeMin=int(values['rangeMin']), rangeMax=int(values['rangeMax']), initialThickness=int(float(values['initialDepth'])), - gravity=float(values['gravity'])) + gravity=float(values['gravity']), res=int(float(values['res']))) for mol in values['molList'].split(','): planet.moleculeList.append(mol) - if utils.profileComplete(folderPath): - fileLength = utils.profileLength(folderPath) - else: + if not utils.profileComplete(folderPath): planet.processLayers(verify=verify) fileLength = utils.profileLength(folderPath) while len(planet.atmosphere) > 0: @@ -911,7 +971,7 @@ def densityAtHeight(self, height, gasConstant): class Planet: def __init__(self, name, pressure, temperature, maxHeight, - gravity=9.80665, rangeMin=0, rangeMax=2000, initialThickness=100): + gravity=9.80665, rangeMin=0, rangeMax=2000, initialThickness=100, res=1): self.name = name self.gravity = gravity self.maxHeight = maxHeight * 100000 @@ -926,6 +986,7 @@ def __init__(self, name, pressure, temperature, maxHeight, self.rangeMax = rangeMax self.setting = settings.setting self.atmosphere = Atmosphere("%s's atmosphere" % self.name, planet=self) + self.res = res self.initialLayer = \ self.atmosphere.addLayer(initialThickness * 100, temperature, pressure, rangeMin, rangeMax, name='initial layer', height=0) @@ -1031,7 +1092,7 @@ def sliceAtm(self, verify=True): acceptSetup = True return - def processLayers(self, verify=True, moleculeSpecific=False): + def processLayers(self, verify=True, moleculeSpecific=False, res=1): if utils.profileProgress(self.folderPath): self.sliceAtm(verify=False) if not self.heightList: @@ -1051,15 +1112,20 @@ def processLayers(self, verify=True, moleculeSpecific=False): molecule.concentration = self.compositionAtHeight(layer.meanHeight, molecule) layer.createCrossSection() processTime = time.time() - layerProcessTimeStart - utils.writePlanetProfile(self.folderPath, layer, processTime, self.moleculeList, moleculeSpecific=moleculeSpecific) + #utils.writePlanetProfile(self.folderPath, layer, processTime, self.moleculeList, moleculeSpecific=moleculeSpecific) + params = {'layer transmittance': reduceRes(layer.transmittance, res)} + for molecule in layer: + key = '%s transmittance' % molecule.name + params[key] = reduceRes(molecule.transmittance,res) + utils.writePlanetProfileTransmittance(self.folderPath, layer, processTime, self.moleculeList, params) totalProcessTime += processTime utils.profileWriteProgress(self.folderPath, i, len(self.heightList), totalProcessTime, - moleculeSpecific, self.moleculeList) + moleculeSpecific, self.moleculeList, res) resetCrossSection(layer) layer.absorptionCoefficient = np.zeros(len(layer.crossSection)) layer.progressAbsCoef = False i += 1 - utils.profileWriteComplete(self, i - 1, len(self.heightList), totalProcessTime, moleculeSpecific=moleculeSpecific) + utils.profileWriteComplete(self, i - 1, len(self.heightList), totalProcessTime, res, moleculeSpecific=moleculeSpecific) return def loadProfile(self, verify=True, moleculeSpecific=False): @@ -1306,7 +1372,7 @@ def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=( plt.show() -def plotPlanetAndComponents(planet, height=None, direction='down', temperatureList=(290, 260, 230, 200),verify=True, res=1): +def plotPlanetAndComponents(planet, height=None, direction='down', temperatureList=(290, 260, 230, 200), verify=True, res=1): linewidth = 1 plt.figure(figsize=(10, 6), dpi=80) plt.subplot(111, facecolor=theme.faceColor) @@ -1317,7 +1383,9 @@ def plotPlanetAndComponents(planet, height=None, direction='down', temperatureLi handles = [] if height is None: height = planet.maxHeight / 100000 - yTotal = reduceRes(planet.processTransmission(height, direction=direction, verify=verify, moleculeSpecific=True)) + transmittanceValues = readTransmittance(planet, height, direction=direction) + yTotal = transmittanceValues['layer'] + #yTotal = reduceRes(planet.processTransmission(height, direction=direction, verify=verify, moleculeSpecific=True)) xAxis = np.linspace(planet.rangeMin, planet.rangeMax, len(yTotal)) for temperature, color in zip(temperatureList, theme.gridList): yAxis = pyradPlanck.planckWavenumber(xAxis, float(temperature)) @@ -1331,22 +1399,24 @@ def plotPlanetAndComponents(planet, height=None, direction='down', temperatureLi powerSpectrum = int(integrateSpectrum(yTotal, pi, res=res)) plt.title('Surface temp: %sK Surface flux: %sWm-2 Effec temp: %sK' % (planet.surfaceTemperature, surfacePower, int(stefanB(powerSpectrum)))) - fig, = plt.plot(xAxis, yTotal, linewidth=linewidth, color=theme.colorList[0], + fig, = plt.plot(xAxis, yTotal, linewidth=linewidth, color=theme.backingColor, label='net flux: %sWm-2 netGHE: %sWm-2' % (powerSpectrum, surfacePower - powerSpectrum)) handles.append(fig) tempName = planet.name length = len(planet.atmosphere) - for molecule, color in zip(planet.moleculeList, theme.colorList[1:]): + for molecule, color in zip(planet.moleculeList, theme.colorList): print('processing %s in atmosphere' % molecule) - planet.name = molecule + + '''planet.name = molecule i = 1 for layer in planet.atmosphere: layer.absorptionCoefficient = np.asarray(utils.readPlanetProfileMolecule(tempName, i, length, molecule)) i += 1 - yAxis = reduceRes(planet.processTransmission(height, direction=direction, verify=False)) + yAxis = reduceRes(planet.processTransmission(height, direction=direction, verify=False))''' + yAxis = transmittanceValues[molecule] tempPowerSpectrum = int(integrateSpectrum(yAxis, pi, res=res)) fig, = plt.plot(xAxis, yAxis, linewidth=linewidth, color=color, alpha=.6, - label='%s effect : %sWm-2' % (planet.name, surfacePower - tempPowerSpectrum)) + label='%s effect : %sWm-2' % (molecule, surfacePower - tempPowerSpectrum)) handles.append(fig) legend = plt.legend(handles=handles, frameon=False) text = legend.get_texts() diff --git a/pyradUtilities.py b/pyradUtilities.py index e7bb74b..649543f 100644 --- a/pyradUtilities.py +++ b/pyradUtilities.py @@ -23,6 +23,7 @@ def __init__(self, value='dark'): self.theme = value self.faceColor = None self.textColor = None + self.backingColor = None self.gridList = [] self.colorList = [] self.loadTheme(self.theme) @@ -46,6 +47,8 @@ def loadTheme(self, value): self.faceColor = self.rgbTuple(cells[1]) elif cells[0] == 'gridList': self.gridList.append(self.rgbTuple(cells[1])) + elif cells[0] == 'backingColor': + self.backingColor = self.rgbTuple(cells[1]) @property def listOfThemes(self): @@ -196,6 +199,36 @@ def openReturnLines(fullPath): return lineList +def writePlanetProfileTransmittance(name, layer, processingTime, moleculeList, params): + folderPath = '%s/%s' % (profileDir, name) + if not os.path.isdir(folderPath): + os.mkdir(folderPath) + filePath = '%s/%s.pyr' % (folderPath, layer.name) + now = datetime.now() + openFile = open(filePath, 'wb') + text = '# created by PyRad v%s on %s.\n' % (VERSION, now.strftime("%Y-%m-%d %H:%M:%S")) + openFile.write(text.encode('utf-8')) + text = 'time: %ssecs\n'\ + 'depth: %s\n'\ + 'T: %s\n'\ + 'P: %s\n'\ + 'rangeMin: %s\n'\ + 'rangeMax: %s\n'\ + 'height: %s\n'\ + 'name: %s\n'\ + 'molecule list: %s\n'\ + '# layer transmittance\n'\ + % (int(processingTime), layer.depth, int(layer.T), layer.P, layer.rangeMin, layer.rangeMax, layer.height, + layer.name, ','.join(moleculeList)) + openFile.write(text.encode('utf-8')) + for key in params: + text = '%s: %s\n' % (key, ','.join(map(str, params[key].tolist()))) + openFile.write(text.encode('utf-8')) + openFile.close() + print('\t\t\t\t\t\t ||> %s.pyr' % layer.name, end='\r', flush=True) + return + + def writePlanetProfile(name, layer, processingTime, moleculeList, moleculeSpecific=False): folderPath = '%s/%s' % (profileDir, name) if not os.path.isdir(folderPath): @@ -364,7 +397,7 @@ def profileLength(name): return int(values[1]) -def profileWriteProgress(name, completed, expected, processingTime, moleculeSpecific, moleculeList): +def profileWriteProgress(name, completed, expected, processingTime, moleculeSpecific, moleculeList, res): folderPath = '%s/%s' % (profileDir, name) fileName = 'profileProgress' filePath = '%s/%s.pyr' % (folderPath, fileName) @@ -373,9 +406,10 @@ def profileWriteProgress(name, completed, expected, processingTime, moleculeSpec '# total processing time: %ssecs\n' \ 'molSpecific: %s\n' \ 'molList: %s\n' \ + 'res: %s\n' \ 'expected: %s\n' \ 'completed: %s' % (name, VERSION, int(processingTime), - moleculeSpecific, ','.join(moleculeList), expected, completed) + moleculeSpecific, ','.join(moleculeList), res, expected, completed) openFile = open(filePath, 'wb') openFile.write(text.encode('utf-8')) openFile.close() @@ -423,7 +457,7 @@ def profileComplete(name): return False -def profileWriteComplete(planet, completed, expected, processingTime, moleculeSpecific=False): +def profileWriteComplete(planet, completed, expected, processingTime, res, moleculeSpecific=False): folderPath = '%s/%s' % (profileDir, planet.folderPath) fileName = 'profileComplete' filePath = '%s/%s.pyr' % (folderPath, fileName) @@ -441,11 +475,12 @@ def profileWriteComplete(planet, completed, expected, processingTime, moleculeSp 'rangeMin: %s\n' \ 'rangeMax: %s\n' \ 'molList: %s\n' \ + 'res: %s\n' \ 'expected: %s\n' \ 'completed: %s' % (planet.folderPath, time.strftime("%Y-%m-%d %H:%M:%S"), VERSION, int(processingTime), planet.folderPath, moleculeSpecific, planet.surfacePressure, planet.surfaceTemperature, int(planet.maxHeight / 100000), planet.heightList[1], planet.gravity, - planet.rangeMin, planet.rangeMax, ','.join(planet.moleculeList), expected, completed) + planet.rangeMin, planet.rangeMax, ','.join(planet.moleculeList), res, expected, completed) openFile = open(filePath, 'wb') openFile.write(text.encode('utf-8')) openFile.close() @@ -503,6 +538,35 @@ def readPlanetProfile(name, layerNumber, length): return layerDict +def readPlanetProfileTransmittance(name, layerNumber, length): + folderPath = '%s/%s' % (profileDir, name) + fileName = 'Layer %s:%s' % (layerNumber, length) + filePath = '%s/%s.pyr' % (folderPath, fileName) + lines = openReturnLines(filePath) + print('Reading profile from %s... ' % fileName, end='\r', flush=True) + layerDict = {'molecule list': []} + for line in lines: + keyValue = line.split(':') + if line[0] == '#': + pass + elif keyValue[0].strip() == 'name': + layerDict[keyValue[0]] = keyValue[1].strip() + elif 'transmittance' in keyValue[0]: + trans = keyValue[1].split(',') + transList = [] + for value in trans: + transList.append(float(value)) + key = keyValue[0].split(' ')[0] + layerDict[key] = transList + elif keyValue[0].strip() == 'T' or keyValue[0] == 'rangeMin' or keyValue[0] == 'rangeMax': + layerDict[keyValue[0]] = int(keyValue[1]) + elif keyValue[0].strip() == 'P' or keyValue[0].strip() == 'height' or keyValue[0].strip() == 'depth': + layerDict[keyValue[0]] = float(keyValue[1]) + else: + pass + return layerDict + + def writeDictListToFile(dictionary, fullPath, comments=None, mode='wb'): openFile = open(fullPath, mode) if comments: diff --git a/sample.py b/sample.py index 5d6769a..b762bbf 100644 --- a/sample.py +++ b/sample.py @@ -1,6 +1,6 @@ import pyradClasses -planet = pyradClasses.createCustomPlanet('earthsimplemolspec narrow') +planet = pyradClasses.loadEmptyPlanet2('earthsimplemolspec narrow low') #planet2 = pyradClasses.createCustomPlanet('marssimple') diff --git a/themes/dark.pyr b/themes/dark.pyr index 1830841..8bca091 100644 --- a/themes/dark.pyr +++ b/themes/dark.pyr @@ -13,27 +13,32 @@ gridList: 170, 170, 170 gridList: 130, 130, 130 gridList: 90, 90, 90 +# backingcolor used for backing the composite plots. For composite plots, the other colors alphas will be adjusted down, +# so they will become a tint of the backingcolor. backingColor should be an grayscale/white/black that will stand out +# on the faceColor well. + +backingColor: 200, 200, 200 + # light grey textColor: 240, 240, 240 -colorList: 240, 240, 240 -# dark green -colorList: 30, 100, 30 +# mint green +colorList: 120, 255, 120 # dark blue -colorList: 0, 20, 110 +colorList: 0, 125, 255 # dark purple -colorList: 70, 30, 70 +colorList: 180, 65, 180 # dark red -colorList: 100, 20, 20 +colorList: 255, 50, 50 # dark teal -colorList: 0, 80, 80 +colorList: 60, 170, 170 -# dark orange -colorList: 130, 50, 0 +# orange +colorList: 255, 95, 0 -# light blue -colorList: 0, 160, 160 +# yellow +colorList: 255, 255, 0 From a959f77280350018f5ab36d92d8a036a71fcb39e Mon Sep 17 00:00:00 2001 From: Brad Schrag Date: Fri, 2 Nov 2018 10:42:56 -0500 Subject: [PATCH 18/43] quick rollback to not processing transmittance before storing data --- pyradClasses.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/pyradClasses.py b/pyradClasses.py index c5e5a73..de29677 100644 --- a/pyradClasses.py +++ b/pyradClasses.py @@ -1112,12 +1112,12 @@ def processLayers(self, verify=True, moleculeSpecific=False, res=1): molecule.concentration = self.compositionAtHeight(layer.meanHeight, molecule) layer.createCrossSection() processTime = time.time() - layerProcessTimeStart - #utils.writePlanetProfile(self.folderPath, layer, processTime, self.moleculeList, moleculeSpecific=moleculeSpecific) - params = {'layer transmittance': reduceRes(layer.transmittance, res)} - for molecule in layer: - key = '%s transmittance' % molecule.name - params[key] = reduceRes(molecule.transmittance,res) - utils.writePlanetProfileTransmittance(self.folderPath, layer, processTime, self.moleculeList, params) + utils.writePlanetProfile(self.folderPath, layer, processTime, self.moleculeList, moleculeSpecific=moleculeSpecific) + #params = {'layer transmittance': reduceRes(layer.transmittance, res)} + #for molecule in layer: + # key = '%s transmittance' % molecule.name + # params[key] = reduceRes(molecule.transmittance,res) + #utils.writePlanetProfileTransmittance(self.folderPath, layer, processTime, self.moleculeList, params) totalProcessTime += processTime utils.profileWriteProgress(self.folderPath, i, len(self.heightList), totalProcessTime, moleculeSpecific, self.moleculeList, res) @@ -1383,9 +1383,9 @@ def plotPlanetAndComponents(planet, height=None, direction='down', temperatureLi handles = [] if height is None: height = planet.maxHeight / 100000 - transmittanceValues = readTransmittance(planet, height, direction=direction) - yTotal = transmittanceValues['layer'] - #yTotal = reduceRes(planet.processTransmission(height, direction=direction, verify=verify, moleculeSpecific=True)) + #transmittanceValues = readTransmittance(planet, height, direction=direction) + #yTotal = transmittanceValues['layer'] + yTotal = reduceRes(planet.processTransmission(height, direction=direction, verify=verify, moleculeSpecific=True)) xAxis = np.linspace(planet.rangeMin, planet.rangeMax, len(yTotal)) for temperature, color in zip(temperatureList, theme.gridList): yAxis = pyradPlanck.planckWavenumber(xAxis, float(temperature)) @@ -1407,13 +1407,13 @@ def plotPlanetAndComponents(planet, height=None, direction='down', temperatureLi for molecule, color in zip(planet.moleculeList, theme.colorList): print('processing %s in atmosphere' % molecule) - '''planet.name = molecule + planet.name = molecule i = 1 for layer in planet.atmosphere: layer.absorptionCoefficient = np.asarray(utils.readPlanetProfileMolecule(tempName, i, length, molecule)) i += 1 - yAxis = reduceRes(planet.processTransmission(height, direction=direction, verify=False))''' - yAxis = transmittanceValues[molecule] + yAxis = reduceRes(planet.processTransmission(height, direction=direction, verify=False)) + #yAxis = transmittanceValues[molecule] tempPowerSpectrum = int(integrateSpectrum(yAxis, pi, res=res)) fig, = plt.plot(xAxis, yAxis, linewidth=linewidth, color=color, alpha=.6, label='%s effect : %sWm-2' % (molecule, surfacePower - tempPowerSpectrum)) From 1d3c3c1a6400c35af152763e9f6c791c2bee1bb9 Mon Sep 17 00:00:00 2001 From: Brad Schrag Date: Fri, 2 Nov 2018 10:50:52 -0500 Subject: [PATCH 19/43] couple other reversions --- pyrad.py | 2 +- pyradClasses.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyrad.py b/pyrad.py index 2f332d3..367172d 100644 --- a/pyrad.py +++ b/pyrad.py @@ -145,7 +145,7 @@ def createPlot(params): def plotPlanetSpectrum(values): pList = [] for p in values['profiles']: - planet = pyradClasses.loadEmptyPlanet2(p.name) + planet = pyradClasses.loadEmptyPlanet(p.name) pList.append(planet) if values['height'] == -2.71828: pyradClasses.plotPlanetSpectrum(pList, direction=values['direction'], verify=False) diff --git a/pyradClasses.py b/pyradClasses.py index de29677..8b02552 100644 --- a/pyradClasses.py +++ b/pyradClasses.py @@ -1131,7 +1131,7 @@ def processLayers(self, verify=True, moleculeSpecific=False, res=1): def loadProfile(self, verify=True, moleculeSpecific=False): if not utils.profileComplete(self.folderPath): self.processLayers(verify=verify, moleculeSpecific=moleculeSpecific) - loadEmptyPlanet(self.folderPath, self, moleculeSpecific=moleculeSpecific, verify=verify) + loadEmptyPlanet(self.folderPath, self, verify=verify) def processTransmission(self, height, direction='down', verify=True, moleculeSpecific=False): if not self.progressProfileLoaded: From aa62ec98a6d7d8817ce9cd14fb139b9d5f52da52 Mon Sep 17 00:00:00 2001 From: Brad Schrag Date: Fri, 2 Nov 2018 10:52:45 -0500 Subject: [PATCH 20/43] why didn't I push these fixes before my laptop crashed? --- pyrad.py | 2 +- pyradClasses.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyrad.py b/pyrad.py index 367172d..24be1ed 100644 --- a/pyrad.py +++ b/pyrad.py @@ -155,7 +155,7 @@ def plotPlanetSpectrum(values): def plotPlanetSpectrumComponents(values): - planet = pyradClasses.loadEmptyPlanet2(values['profiles'][0].name) + planet = pyradClasses.loadEmptyPlanet(values['profiles'][0].name) if values['height'] == -2.71828: pyradClasses.plotPlanetAndComponents(planet, direction=values['direction'], verify=False) else: diff --git a/pyradClasses.py b/pyradClasses.py index 8b02552..463d2e9 100644 --- a/pyradClasses.py +++ b/pyradClasses.py @@ -1315,7 +1315,7 @@ def plotSpectrum(layer=None, title=None, rangeMin=None, rangeMax=None, objList=N handles = [] if not rangeMax: xAxis = layer.xAxis - for temperature, color in zip(planckTemperatureList, theme.colorList): + for temperature, color in zip(planckTemperatureList, theme.gridList): yAxis = planckFunction(xAxis, float(temperature)) fig, = plt.plot(xAxis, yAxis, linewidth=.75, color=color, linestyle=':', label='%sK : %sWm-2' % @@ -1359,7 +1359,7 @@ def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=( fig, = plt.plot(xAxis, yAxis, linewidth=linewidth, color=color, label='%s : %sWm-2, eff : %sK' % (planet.name, powerSpectrum, effTemp)) handles.append(fig) - for temperature, color in zip(temperatureList, theme.colorList): + for temperature, color in zip(temperatureList, theme.gridList): yAxis = pyradPlanck.planckWavenumber(xAxis, float(temperature)) fig, = plt.plot(xAxis, yAxis, linewidth=1, color=color, linestyle=':', label='%sK : %sWm-2' % From 02a00c9206f5b4a2a1fcb2c701756e6bcf17b6b1 Mon Sep 17 00:00:00 2001 From: bschrag620 Date: Fri, 2 Nov 2018 13:33:56 -0500 Subject: [PATCH 21/43] Update README.md updating readme with new info and guide --- README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 398f714..21b6e11 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,15 @@ On Mac: https://penandpants.com/2012/02/24/install-python/ All absorption lines, intensities, and relevant info are downloaded from hitran.org and stored locally. -For a more comprehensive (ie professional package), be sure to check out HAPI (Hitran API) http://hitran.org/hapi. It is free and open source as well. This project has been more personal opportunity to test and improve my own understanding of radiative transfer through gases. The final version of this project should support modeling radiative transfer through any atmospheric composition. Currently, it serves as a gas cell simulator, similar to http://www.spectralcalc.com/calc/spectralcalc.php +For a more comprehensive (ie professional package), be sure to check out HAPI (Hitran API) http://hitran.org/hapi. It is free and open source as well. This project has been more personal opportunity to test and improve my own understanding of radiative transfer through gases. +The final version of this project should support modeling radiative transfer through any atmospheric composition. Currently, it serves as a gas cell simulator, similar to http://www.spectralcalc.com/calc/spectralcalc.php + +Version 3: +Big jump happening all at once here, but 3.0 is live now. PyRad is officially a line-by-line, radiatvie transfer model for an atmosphere. +-Interactive mode allows access to gas cell simulator, plotting of planck curves (by wavelength, wavenumber, or Hz), and processing and plotting of radiative transfer through an atmosphere +-profiles can be created for custom atmospheres and saved in the PyRad folder. Be sure to use a .pyr extension +-theme files for changing plot colors can be created and added to the theme folder. Again, use a .pyr extension so they are seen +-see below for details on how to create a custom atmosphere Version 1.5: -Release of interactive mode. Simply run the pyrad.py file to access the menu. @@ -26,3 +34,6 @@ HAPI Interface - R.V. Kochanov, I.E. Gordon, L.S. Rothman, P. Wcislo, C. Hill, J Tom Marshall of GATS-Inc.com, for providing guidance in resolving personal ignorances of units. Eli Rabett, for his patience in helping me understand concepts that I have not received an education on previously. + + +Creating a custom atmosphere profile/planet: From 0e1b39617a12b42982678bb1cbba734eec8b713d Mon Sep 17 00:00:00 2001 From: Brad Schrag Date: Thu, 8 Nov 2018 21:28:23 -0600 Subject: [PATCH 22/43] pushing to dev before updating laptop.... just in case. --- earthsimple.pyr => earthsimple2.pyr | 0 pyrad.py | 100 ++++++++------- pyradClasses.py | 184 ++++++++++++++-------------- pyradUtilities.py | 83 ++++--------- venussimple.pyr | 21 ++++ 5 files changed, 190 insertions(+), 198 deletions(-) rename earthsimple.pyr => earthsimple2.pyr (100%) create mode 100644 venussimple.pyr diff --git a/earthsimple.pyr b/earthsimple2.pyr similarity index 100% rename from earthsimple.pyr rename to earthsimple2.pyr diff --git a/pyrad.py b/pyrad.py index 24be1ed..cf2da4d 100644 --- a/pyrad.py +++ b/pyrad.py @@ -18,50 +18,66 @@ def __init__(self, title, entries, previousMenu=None, menuParams=None, multiChoi self.multiChoice = multiChoice def displayMenu(self): - if self.multiChoice: - return self.displayMultiChoiceMenu() - else: - titleStr = ' %s detail: %s' % (self.title, pyradClasses.settings.setting) - while len(titleStr) < 60: - titleStr += ' ' - print('\n%s' % util.underlineCyan(titleStr)) - i = 1 - validEntry = ['x'] - for entry in self.entries: - validEntry.append(str(i)) - print(' %s) %s' % (util.magentaText(i), entry.name)) - i += 1 - text = ' %s) Exit' % util.magentaText('X') - if 'Main' not in self.title: - text += '\t%s) Back' % util.magentaText('B') - validEntry.append('b') - if self.title != 'Choose level of detail': - text += '\t%s) Settings' % util.magentaText('S') - validEntry.append('s') - print(text) - validChoice = False - while not validChoice: - userInput = input('Choose an option: ') - if userInput.lower() == 'x': - print('Goodbye') - exit(1) - elif userInput.lower() == 'b' and 'main' not in self.title.lower(): - if type(self.previousMenu) == Menu: - return self.previousMenu - return self.previousMenu() - elif userInput.lower() == 's' and 'settings' not in self.title.lower(): - return settingsMenu(previousMenu=self) - elif userInput in validEntry: - userChoice = self.entries[int(userInput) - 1] - if userChoice.nextFunction: - return userChoice.nextFunction(userChoice.functionParams) - elif userChoice.nextMenu: - return userChoice.nextMenu(userChoice.functionParams) + titleStr = ' %s detail: %s' % (self.title, pyradClasses.settings.setting) + while len(titleStr) < 60: + titleStr += ' ' + print('\n%s' % util.underlineCyan(titleStr)) + i = 1 + validEntry = ['x'] + for entry in self.entries: + validEntry.append(str(i)) + print(' %s) %s' % (util.magentaText(i), entry.name)) + i += 1 + text = ' %s) Exit' % util.magentaText('X') + if 'Main' not in self.title: + text += '\t%s) Back' % util.magentaText('B') + validEntry.append('b') + if self.title != 'Choose level of detail': + text += '\t%s) Settings' % util.magentaText('S') + validEntry.append('s') + print(text) + validChoice = False + while not validChoice: + userInput = input('Choose an option: ') + if userInput.lower() == 'x': + print('Goodbye') + exit(1) + elif userInput.lower() == 'b' and 'main' not in self.title.lower(): + if type(self.previousMenu) == Menu: + return self.previousMenu + return self.previousMenu() + elif userInput.lower() == 's' and 'settings' not in self.title.lower(): + return settingsMenu(previousMenu=self) + elif not self.multiChoice and userInput in validEntry: + userChoice = self.entries[int(userInput) - 1] + if userChoice.nextFunction: + return userChoice.nextFunction(userChoice.functionParams) + elif userChoice.nextMenu: + return userChoice.nextMenu(userChoice.functionParams) + elif self.multiChoice: + inputs = userInput.split(',') + allValid = True + userChoices = [] + for i in inputs: + if i.strip() not in validEntry: + allValid = False + else: + userChoices.append(self.entries[int(i) - 1]) + if allValid: + if userChoices[0].nextFunction: + nextFunction = userChoices[0].nextFunction + return nextFunction(userChoices) + else: + nextMenu = userChoices[0].nextMenu + tempMenu = nextMenu(userChoices) + return tempMenu else: print('Invalid entry. Try again.') + else: + print('Invalid entry. Try again.') def displayMultiChoiceMenu(self): - titleStr = '\t%s\tdetail: %s' % (self.title, pyradClasses.settings.setting) + titleStr = '%sdetail: %s' % (self.title, pyradClasses.settings.setting) while len(titleStr) < 60: titleStr += ' ' print('\n%s' % util.underlineCyan(titleStr)) @@ -145,8 +161,7 @@ def createPlot(params): def plotPlanetSpectrum(values): pList = [] for p in values['profiles']: - planet = pyradClasses.loadEmptyPlanet(p.name) - pList.append(planet) + pList.append(p.name) if values['height'] == -2.71828: pyradClasses.plotPlanetSpectrum(pList, direction=values['direction'], verify=False) else: @@ -590,6 +605,7 @@ def buildProfile(profileList): "Do you wish to overwrite it? %s" % util.limeText('(y/n)')) else: planet.processLayers(verify=False, moleculeSpecific=moleculeSpecific) + overwrite = False if overwrite: util.emptyProfileDirectory(planet.folderPath) planet.processLayers(verify=False, moleculeSpecific=moleculeSpecific) diff --git a/pyradClasses.py b/pyradClasses.py index 463d2e9..838daa8 100644 --- a/pyradClasses.py +++ b/pyradClasses.py @@ -22,9 +22,9 @@ theme = utils.Theme() -def reduceRes(array, lumpTo=1.0): - n = int(lumpTo / settings.baseRes) - length = int(len(array) * settings.baseRes / lumpTo) +def reduceRes(array, finalRes=1.0): + n = int(finalRes / settings.baseRes) + length = int(len(array) * settings.baseRes / finalRes) newArray = np.zeros(length) for m in range(0, length): for i in range(0, n): @@ -43,68 +43,6 @@ def returnHMS(time): return hours, minutes, seconds -def loadEmptyPlanet2(folderPath, verify=False): - values = utils.readCompleteProfile(folderPath) - planet = Planet(values['name'], float(values['surfacePressure']), int(values['surfaceTemperature']), - float(values['maxHeight']), - rangeMin=int(values['rangeMin']), rangeMax=int(values['rangeMax']), - initialThickness=int(float(values['initialDepth'])), - gravity=float(values['gravity'])) - for mol in values['molList'].split(','): - planet.moleculeList.append(mol) - #if utils.profileComplete(folderPath): - # fileLength = utils.profileLength(folderPath) - #else: - # planet.processLayers(verify=verify) - return planet - - -def readTransmittance(planet, height, direction): - height = height * 100000 - fileLength = utils.profileLength(planet.name) - moleculeList = planet.moleculeList - values = {} - xAxis = np.linspace(planet.rangeMin, planet.rangeMax, int(planet.rangeMax - planet.rangeMin) / planet.res) - if direction == 'down': - values['layer'] = pyradPlanck.planckWavenumber(xAxis, planet.surfaceTemperature) - fileArray = list(range(1, fileLength + 1)) - print(fileArray) - else: - values['layer'] = pyradPlanck.planckWavenumber(xAxis, 2.7) - fileArray = list(reversed(range(1, fileLength + 1))) - for molecule in moleculeList: - values[molecule] = np.copy(values['layer']) - i = 0 - layer = utils.readPlanetProfileTransmittance(planet.name, fileArray[i], fileLength) - meanHeight = layer['height'] + .5 * layer['depth'] - if direction == 'down': - while meanHeight < height and i < len(fileArray) - 1: - transmittance = np.asarray(layer['layer']) - transmitted = values['layer'] * transmittance - emittance = 1 - transmittance - emitted = emittance * pyradPlanck.planckWavenumber(xAxis, layer['T']) - values['layer'] = transmitted + emitted - for molecule in moleculeList: - transmittance = np.asarray(layer[molecule]) - transmitted = values[molecule] * transmittance - emittance = 1 - transmittance - emitted = emittance * pyradPlanck.planckWavenumber(xAxis, layer['T']) - values[molecule] = transmitted + emitted - i += 1 - layer = utils.readPlanetProfileTransmittance(planet.name, fileArray[i], fileLength) - meanHeight = layer['height'] + .5 * layer['depth'] - else: - while meanHeight > height and i < fileLength + 1: - transmittance = np.asarray(layer['layer']) - values['layer'] = values['layer'] * transmittance - for molecule in moleculeList: - values[molecule] = values[molecule] * transmittance - i += 1 - layer = utils.readPlanetProfileTransmittance(planet.name, fileArray[i], fileLength) - meanHeight = layer['height'] + .5 * layer['depth'] - return values - - def loadEmptyPlanet(folderPath, planet=None, verify=False): values = utils.readCompleteProfile(folderPath) if planet is None: @@ -130,6 +68,54 @@ def loadEmptyPlanet(folderPath, planet=None, verify=False): return planet +def processTransmissionBySingleLayer(folderPath, res=1): + #first process transmission upward. Need to get initial values, mostly just for surface temp + values = utils.readCompleteProfile(folderPath) + planet = Planet(values['name'], float(values['surfacePressure']), int(values['surfaceTemperature']), + float(values['maxHeight']), + rangeMin=int(values['rangeMin']), rangeMax=int(values['rangeMax']), + initialThickness=int(float(values['initialDepth'])), + gravity=float(values['gravity']), res=int(float(values['res']))) + for mol in values['molList'].split(','): + planet.moleculeList.append(mol) + + # now, 1 file at a time, open it, read values, write the transmission at a reduced res, to save space. It will be + # written in key: value style, with the key being the mean height of the layer. This will allow for easy lookup + # for values. + # Start by process the transmission, looking down, ie process surface transmission 1 --> top + xAxis = None + fileLength = utils.profileLength(folderPath) + for i in range(1, fileLength + 1): + lP = utils.readPlanetProfile(folderPath, i, fileLength) + layer = Layer(lP['depth'], lP['T'], lP['P'], lP['rangeMin'], lP['rangeMax'], height=lP['height'], + name=lP['name']) + layer.absorptionCoefficient = np.asarray(lP['absCoef']) + layer.progressAbsCoef = True + + # if this is the first time through the loop, create an xAxis with range and steps the same as the absCoef + # and intitiate the surfaceSpectrum + if xAxis is None: + xAxis = np.linspace(planet.rangeMin, planet.rangeMax, len(layer.absorptionCoefficient)) + surfaceSpectrum = pyradPlanck.planckWavenumber(xAxis, planet.surfaceTemperature) + spectrumDict = {'layer': reduceRes(surfaceSpectrum, finalRes=res)} + for molecule in planet.moleculeList: + spectrumDict[molecule] = reduceRes(surfaceSpectrum, finalRes=res) + utils.writePlanetTransmission(folderPath, 0, spectrumDict, 'up') + + nextSpectrum = layer.transmission(surfaceSpectrum) + spectrumDict = {'layer': reduceRes(nextSpectrum, finalRes=res)} + #for molecule in planet.moleculeList: + # molAbsCoef = utils.readPlanetProfileMolecule(folderPath, i, fileLength, molecule) + # layer.absorptionCoefficient = np.asarray(molAbsCoef) + # spectrumDict[molecule] = reduceRes(layer.transmission(surfaceSpectrum), finalRes=res) + utils.writePlanetTransmission(folderPath, layer.meanHeight, spectrumDict, 'up') + surfaceSpectrum = nextSpectrum + + # with transmission from surface upward processed, do the same in reverse to get the transmission toward the surface + # initial spetrum will be 2.7K for CMB + + + def createCustomPlanet(name): initialParameters = utils.parseCustomProfile(name) @@ -706,7 +692,7 @@ def __init__(self, depth, T, P, rangeMin, rangeMax, height=0.0, atmosphere=None, if not dynamicResolution: self.resolution = utils.BASE_RESOLUTION else: - self.resolution = max(10**int(np.log10((self.P / 1013.25))) * .01, utils.BASE_RESOLUTION) + self.resolution = max(self.P / 1013.25 * .01, utils.BASE_RESOLUTION) if not atmosphere: if not Layer.hasAtmosphere: self.atmosphere = Atmosphere('generic') @@ -796,7 +782,10 @@ def emittance(self): def molarMass(self): mass = 0 for mol in self: - mass += mol.molarMass * mol.concentration + if mol.name == 'h2o': + pass + else: + mass += mol.molarMass * mol.concentration return mass @property @@ -842,7 +831,7 @@ def changePressure(self, pressure): if not self.dynamicResolution: self.resolution = utils.BASE_RESOLUTION else: - self.resolution = max(10**int(np.log10((self.P / 1013.25))) * .01, utils.BASE_RESOLUTION) + self.resolution = max(self.P / 1013.25 * .01, utils.BASE_RESOLUTION) resetData(self) def changeDepth(self, depth): @@ -937,20 +926,20 @@ def temperatureAtHeight(self, height): return temperature def pressureAtHeight(self, height): - height = height / 100 ruleList = self.planet.returnApplicableRules(height, 'temperature') if len(ruleList) > 1: print('Multiple rules found for height %s: %s' % (height, ruleList)) rule = ruleList[0] temperature = self.temperatureAtHeight(height) + pressurePa = rule.basePressure * 100 + rateInMeters = rule.rate * 100 if rule.rate != 0: - pressure = rule.basePressure * (rule.baseValue / temperature) ** \ - (self.planet.gravity * self.planet.molarMass / R / rule.rate) + pressure = pressurePa * (rule.baseValue / temperature) ** \ + (self.planet.gravity * self.planet.molarMass / R / rateInMeters) else: - pressure = rule.basePressure * \ - np.exp(-self.planet.gravity * self.planet.molarMass * - (height - rule.baseHeight) / R / rule.baseValue) - return pressure + changeInHeightMeters = (height - rule.baseHeight) / 100 + pressure = pressurePa * np.exp(-self.planet.gravity * self.planet.molarMass * changeInHeightMeters / R / rule.baseValue) + return pressure / 100 def compositionAtHeight(self, height, molecule): ruleList = self.planet.returnApplicableRules(height, 'composition') @@ -1113,11 +1102,6 @@ def processLayers(self, verify=True, moleculeSpecific=False, res=1): layer.createCrossSection() processTime = time.time() - layerProcessTimeStart utils.writePlanetProfile(self.folderPath, layer, processTime, self.moleculeList, moleculeSpecific=moleculeSpecific) - #params = {'layer transmittance': reduceRes(layer.transmittance, res)} - #for molecule in layer: - # key = '%s transmittance' % molecule.name - # params[key] = reduceRes(molecule.transmittance,res) - #utils.writePlanetProfileTransmittance(self.folderPath, layer, processTime, self.moleculeList, params) totalProcessTime += processTime utils.profileWriteProgress(self.folderPath, i, len(self.heightList), totalProcessTime, moleculeSpecific, self.moleculeList, res) @@ -1224,6 +1208,7 @@ def baseHeightCompositionRule(self, molecule): if rule.finalHeight > height and rule.molecule == molecule: height = rule.finalHeight concentration = rule.finalValue + pressure = self.parent.pressureAtHeight(height) return height, concentration, pressure def setBaseValues(self, ruleType, molecule): @@ -1347,25 +1332,36 @@ def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=( plt.ylabel('Radiance Wm-2sr-1(cm-1)-1') handles = [] heightFlag = True + if height is None: heightFlag = False - for planet, color in zip(planets, theme.colorList): - if not heightFlag: - height = planet.maxHeight / 100000 - yAxis = reduceRes(planet.processTransmission(height, direction=direction, verify=verify)) - xAxis = np.linspace(planet.rangeMin, planet.rangeMax, len(yAxis)) - powerSpectrum = int(integrateSpectrum(yAxis, pi, res=res)) - effTemp = int(stefanB(powerSpectrum)) - fig, = plt.plot(xAxis, yAxis, linewidth=linewidth, color=color, - label='%s : %sWm-2, eff : %sK' % (planet.name, powerSpectrum, effTemp)) - handles.append(fig) + p = loadEmptyPlanet(planets[0]) + if not heightFlag: + height = p.maxHeight / 100000 + + totalY = reduceRes(p.processTransmission(height, direction=direction, verify=verify)) + xAxis = np.linspace(p.rangeMin, p.rangeMax, len(totalY)) + for temperature, color in zip(temperatureList, theme.gridList): yAxis = pyradPlanck.planckWavenumber(xAxis, float(temperature)) - fig, = plt.plot(xAxis, yAxis, linewidth=1, color=color, - linestyle=':', label='%sK : %sWm-2' % - (temperature, - int(integrateSpectrum(yAxis, pi, res=res)))) + fig, = plt.plot(xAxis, yAxis, linewidth=1, color=color, linestyle=':', label='%sK : %sWm-2' % (temperature, round(integrateSpectrum(yAxis, pi, res=res), 2))) handles.append(fig) + + powerSpectrum = round(integrateSpectrum(totalY, pi, res=res), 2) + effTemp = int(stefanB(powerSpectrum)) + fig, = plt.plot(xAxis, totalY, linewidth=linewidth, color=theme.colorList[0], label='%s : %sWm-2, eff : %sK' % (p.name, powerSpectrum, effTemp)) + handles.append(fig) + + for planet, color in zip(planets[1:], theme.colorList[1:]): + p = loadEmptyPlanet(planet) + if not heightFlag: + height = p.maxHeight / 100000 + totalY = reduceRes(p.processTransmission(height, direction=direction, verify=verify)) + powerSpectrum = round(integrateSpectrum(totalY, pi, res=res), 2) + effTemp = int(stefanB(powerSpectrum)) + fig, = plt.plot(xAxis, totalY, linewidth=linewidth, color=color, label='%s : %sWm-2, eff : %sK' % (p.name, powerSpectrum, effTemp)) + handles.append(fig) + legend = plt.legend(handles=handles, frameon=False) text = legend.get_texts() plt.setp(text, color=theme.textColor) diff --git a/pyradUtilities.py b/pyradUtilities.py index 649543f..a8e49d0 100644 --- a/pyradUtilities.py +++ b/pyradUtilities.py @@ -84,7 +84,7 @@ def lineIntensityCutoff(self): if self.setting == 'low': return 1E-21 elif self.setting == 'mid': - return 1E-28 + return 1E-24 elif self.setting == 'hi': return 0.0 @@ -187,8 +187,7 @@ def writeTheme(fullPath): def openReturnLines(fullPath): if not os.path.isfile(fullPath): - print('file not found %s' % fullPath) - exit() + return False openFile = open(fullPath) lineList = openFile.readlines() openFile.close() @@ -199,36 +198,6 @@ def openReturnLines(fullPath): return lineList -def writePlanetProfileTransmittance(name, layer, processingTime, moleculeList, params): - folderPath = '%s/%s' % (profileDir, name) - if not os.path.isdir(folderPath): - os.mkdir(folderPath) - filePath = '%s/%s.pyr' % (folderPath, layer.name) - now = datetime.now() - openFile = open(filePath, 'wb') - text = '# created by PyRad v%s on %s.\n' % (VERSION, now.strftime("%Y-%m-%d %H:%M:%S")) - openFile.write(text.encode('utf-8')) - text = 'time: %ssecs\n'\ - 'depth: %s\n'\ - 'T: %s\n'\ - 'P: %s\n'\ - 'rangeMin: %s\n'\ - 'rangeMax: %s\n'\ - 'height: %s\n'\ - 'name: %s\n'\ - 'molecule list: %s\n'\ - '# layer transmittance\n'\ - % (int(processingTime), layer.depth, int(layer.T), layer.P, layer.rangeMin, layer.rangeMax, layer.height, - layer.name, ','.join(moleculeList)) - openFile.write(text.encode('utf-8')) - for key in params: - text = '%s: %s\n' % (key, ','.join(map(str, params[key].tolist()))) - openFile.write(text.encode('utf-8')) - openFile.close() - print('\t\t\t\t\t\t ||> %s.pyr' % layer.name, end='\r', flush=True) - return - - def writePlanetProfile(name, layer, processingTime, moleculeList, moleculeSpecific=False): folderPath = '%s/%s' % (profileDir, name) if not os.path.isdir(folderPath): @@ -263,6 +232,18 @@ def writePlanetProfile(name, layer, processingTime, moleculeList, moleculeSpecif return +def writePlanetTransmission(name, height, values, direction): + folderPath = '%s/%s' % (profileDir, name) + filePath = '%s/%s.pyr' % (folderPath, 'transmission %s' % direction) + openfile = open(filePath, 'ab') + print('test: writing to %s' % filePath) + for item in values: + text = '%s: %s: %s\n' % (height, item, ','.join(map(str, values[item]))) + openfile.write(text.encode('utf-8')) + openfile.close() + return + + def getPyrFileList(folder=cwd): fileList = os.listdir(folder) profileFiles = [] @@ -515,6 +496,13 @@ def readPlanetProfile(name, layerNumber, length): fileName = 'Layer %s:%s' % (layerNumber, length) filePath = '%s/%s.pyr' % (folderPath, fileName) lines = openReturnLines(filePath) + if not lines: + fileName = 'Layer %s_%s' % (layerNumber, length) + filePath = '%s/%s.pyr' % (folderPath, fileName) + lines = openReturnLines(filePath) + if not lines: + print('cant find layer file %s' % filePath) + exit() print('Reading profile from %s... ' % fileName, end='\r', flush=True) layerDict = {'molecule list': []} for line in lines: @@ -538,35 +526,6 @@ def readPlanetProfile(name, layerNumber, length): return layerDict -def readPlanetProfileTransmittance(name, layerNumber, length): - folderPath = '%s/%s' % (profileDir, name) - fileName = 'Layer %s:%s' % (layerNumber, length) - filePath = '%s/%s.pyr' % (folderPath, fileName) - lines = openReturnLines(filePath) - print('Reading profile from %s... ' % fileName, end='\r', flush=True) - layerDict = {'molecule list': []} - for line in lines: - keyValue = line.split(':') - if line[0] == '#': - pass - elif keyValue[0].strip() == 'name': - layerDict[keyValue[0]] = keyValue[1].strip() - elif 'transmittance' in keyValue[0]: - trans = keyValue[1].split(',') - transList = [] - for value in trans: - transList.append(float(value)) - key = keyValue[0].split(' ')[0] - layerDict[key] = transList - elif keyValue[0].strip() == 'T' or keyValue[0] == 'rangeMin' or keyValue[0] == 'rangeMax': - layerDict[keyValue[0]] = int(keyValue[1]) - elif keyValue[0].strip() == 'P' or keyValue[0].strip() == 'height' or keyValue[0].strip() == 'depth': - layerDict[keyValue[0]] = float(keyValue[1]) - else: - pass - return layerDict - - def writeDictListToFile(dictionary, fullPath, comments=None, mode='wb'): openFile = open(fullPath, mode) if comments: diff --git a/venussimple.pyr b/venussimple.pyr new file mode 100644 index 0000000..49cee48 --- /dev/null +++ b/venussimple.pyr @@ -0,0 +1,21 @@ +# A demo file for pyrad + +# mBar , K , km, m , g, cm-1,cm-1 +surface: 93000, 735, 200, 50, 8.87 + +# mol text name, concentration +molecule: co2, .965 +molecule: h2o, .000020 +molecule: so2, .000150 +molecule: co, .000017 +molecule: n2, .03 +molecule: hcl, .0000003 +molecule: hf, .000000003 + +# name, endHeight, endTemp +lapse rate: atm rate 1, 55, 300 +lapse rate: atm rate 2, 100, 150 +lapse rate: atm rate 3, 200, 300 + + + From 60bc8279b567aabce5cf466753378078a474f6b1 Mon Sep 17 00:00:00 2001 From: Brad Schrag Date: Mon, 12 Nov 2018 15:10:06 -0600 Subject: [PATCH 23/43] added in creating transmission files. --- pyradClasses.py | 48 +++++++++++++++++++++++++++++++++++++---------- pyradUtilities.py | 34 ++++++++++++++++++++++++++++----- 2 files changed, 67 insertions(+), 15 deletions(-) diff --git a/pyradClasses.py b/pyradClasses.py index 838daa8..73c079f 100644 --- a/pyradClasses.py +++ b/pyradClasses.py @@ -85,6 +85,7 @@ def processTransmissionBySingleLayer(folderPath, res=1): # Start by process the transmission, looking down, ie process surface transmission 1 --> top xAxis = None fileLength = utils.profileLength(folderPath) + heightList = [0] for i in range(1, fileLength + 1): lP = utils.readPlanetProfile(folderPath, i, fileLength) layer = Layer(lP['depth'], lP['T'], lP['P'], lP['rangeMin'], lP['rangeMax'], height=lP['height'], @@ -93,27 +94,54 @@ def processTransmissionBySingleLayer(folderPath, res=1): layer.progressAbsCoef = True # if this is the first time through the loop, create an xAxis with range and steps the same as the absCoef - # and intitiate the surfaceSpectrum + # and initiate the surfaceSpectrum if xAxis is None: xAxis = np.linspace(planet.rangeMin, planet.rangeMax, len(layer.absorptionCoefficient)) surfaceSpectrum = pyradPlanck.planckWavenumber(xAxis, planet.surfaceTemperature) spectrumDict = {'layer': reduceRes(surfaceSpectrum, finalRes=res)} for molecule in planet.moleculeList: spectrumDict[molecule] = reduceRes(surfaceSpectrum, finalRes=res) - utils.writePlanetTransmission(folderPath, 0, spectrumDict, 'up') + utils.writePlanetTransmission(folderPath, 0, spectrumDict, 'down', 0) nextSpectrum = layer.transmission(surfaceSpectrum) - spectrumDict = {'layer': reduceRes(nextSpectrum, finalRes=res)} - #for molecule in planet.moleculeList: - # molAbsCoef = utils.readPlanetProfileMolecule(folderPath, i, fileLength, molecule) - # layer.absorptionCoefficient = np.asarray(molAbsCoef) - # spectrumDict[molecule] = reduceRes(layer.transmission(surfaceSpectrum), finalRes=res) - utils.writePlanetTransmission(folderPath, layer.meanHeight, spectrumDict, 'up') + spectrumDict = {folderPath: reduceRes(nextSpectrum, finalRes=res)} + + for molecule in planet.moleculeList: + molAbsCoef = utils.readPlanetProfileMolecule(folderPath, i, fileLength, molecule) + layer.absorptionCoefficient = np.asarray(molAbsCoef) + spectrumDict[molecule] = reduceRes(layer.transmission(surfaceSpectrum), finalRes=res) + utils.writePlanetTransmission(folderPath, layer.meanHeight, spectrumDict, 'down', i) + heightList.append(layer.meanHeight) surfaceSpectrum = nextSpectrum + #insert a line(s) into the top of the file of the heightList and other pyrad data + utils.profileWriteTransmissionComplete(folderPath, heightList) + # with transmission from surface upward processed, do the same in reverse to get the transmission toward the surface # initial spetrum will be 2.7K for CMB - + surfaceSpectrum = pyradPlanck.planckWavenumber(xAxis, 2.7) + heightList = [planet.maxHeight] + for i in range(1, fileLength + 1): + fileNumber = fileLength + 1 - i + lP = utils.readPlanetProfile(folderPath, fileNumber, fileLength) + layer = Layer(lP['depth'], lP['T'], lP['P'], lP['rangeMin'], lP['rangeMax'], height=lP['height'], + name=lP['name']) + layer.absorptionCoefficient = np.asarray(lP['absCoef']) + layer.progressAbsCoef = True + spectrumDict = {folderPath: reduceRes(surfaceSpectrum, finalRes=res)} + for molecule in planet.moleculeList: + spectrumDict[molecule] = reduceRes(surfaceSpectrum, finalRes=res) + utils.writePlanetTransmission(folderPath, planet.maxHeight, spectrumDict, 'up', 0) + nextSpectrum = layer.transmission(surfaceSpectrum) + spectrumDict = {'layer': reduceRes(nextSpectrum, finalRes=res)} + for molecule in planet.moleculeList: + molAbsCoef = utils.readPlanetProfileMolecule(folderPath, fileNumber, fileLength, molecule) + layer.absorptionCoefficient = np.asarray(molAbsCoef) + spectrumDict[molecule] = reduceRes(layer.transmission(surfaceSpectrum), finalRes=res) + utils.writePlanetTransmission(folderPath, layer.meanHeight, spectrumDict, 'up', i) + heightList.append(layer.meanHeight) + surfaceSpectrum = nextSpectrum + return def createCustomPlanet(name): @@ -1252,7 +1280,7 @@ def plot(propertyToPlot, title, plotList, fill=False): plt.ylabel(propertyToPlot) if propertyToPlot == 'line survey': plt.yscale('log') - plt.grid(theme.gridColor, linewidth=.5, linestyle=':') + plt.grid(theme.gridList, linewidth=.5, linestyle=':') plt.title('%s' % title) handles = [] linewidth = .7 diff --git a/pyradUtilities.py b/pyradUtilities.py index a8e49d0..b10f0b0 100644 --- a/pyradUtilities.py +++ b/pyradUtilities.py @@ -232,14 +232,23 @@ def writePlanetProfile(name, layer, processingTime, moleculeList, moleculeSpecif return -def writePlanetTransmission(name, height, values, direction): +def writePlanetTransmission(name, height, values, direction, number): folderPath = '%s/%s' % (profileDir, name) - filePath = '%s/%s.pyr' % (folderPath, 'transmission %s' % direction) - openfile = open(filePath, 'ab') - print('test: writing to %s' % filePath) + filePath = '%s/%s.pyr' % (folderPath, 'trans looking %s-%s ' % (direction, number)) + openfile = open(filePath, 'wb') for item in values: - text = '%s: %s: %s\n' % (height, item, ','.join(map(str, values[item]))) + text = '# PyRad v%s transmission file\n' \ + '# layer height for this file is %s\n' % (VERSION, height) openfile.write(text.encode('utf-8')) + text = '%s: %s\n' % (item, ','.join(map(str, values[item]))) + openfile.write(text.encode('utf-8')) + openfile.close() + return + + +def emptyFile(filePath): + fullPath = '%s/%s' % (cwd, filePath) + openfile = open(fullPath, 'wb') openfile.close() return @@ -438,6 +447,21 @@ def profileComplete(name): return False +def profileWriteTransmissionComplete(folderPath, heightList): + folderPath = '%s/%s' % (profileDir, folderPath) + fileName = 'profileComplete' + filePath = '%s/%s.pyr' % (folderPath, fileName) + completeProfileData = openReturnLines(filePath) + transmissionPath = '%s/transmissionComplete.pyr' % folderPath + openFile = open(transmissionPath, 'wb') + for line in completeProfileData: + openFile.write(line.encode('utf-8')) + text = '\nheightList: %s' % (','.join(str(n) for n in heightList)) + openFile.write(text.encode('utf-8')) + openFile.close() + return + + def profileWriteComplete(planet, completed, expected, processingTime, res, moleculeSpecific=False): folderPath = '%s/%s' % (profileDir, planet.folderPath) fileName = 'profileComplete' From 915688941f38f6ad49d599cfdc95423d778f0cda Mon Sep 17 00:00:00 2001 From: Brad Schrag Date: Tue, 13 Nov 2018 14:55:54 -0600 Subject: [PATCH 24/43] worst. bugs. ever. --- earthsimple2.pyr => earthsimple narrow.pyr | 2 +- pyradClasses.py | 174 +++++++++++++-------- pyradUtilities.py | 42 ++++- 3 files changed, 145 insertions(+), 73 deletions(-) rename earthsimple2.pyr => earthsimple narrow.pyr (96%) diff --git a/earthsimple2.pyr b/earthsimple narrow.pyr similarity index 96% rename from earthsimple2.pyr rename to earthsimple narrow.pyr index 610a80a..d4b0b61 100644 --- a/earthsimple2.pyr +++ b/earthsimple narrow.pyr @@ -1,7 +1,7 @@ # A demo file for pyrad # mBar , K , km, m , g, cm-1,cm-1 -surface: 1013.25, 288, 120, 100, 9.8, 00, 2000 +surface: 1013.25, 288, 120, 100, 9.8, 500, 1000 # mol text name, concentration molecule: co2, .000400 diff --git a/pyradClasses.py b/pyradClasses.py index 73c079f..bc0d28c 100644 --- a/pyradClasses.py +++ b/pyradClasses.py @@ -68,8 +68,40 @@ def loadEmptyPlanet(folderPath, planet=None, verify=False): return planet +def readTransmissionFromFile(requestedHeight, folderPath, direction): + completedValues = utils.readCompleteTransmission(folderPath) + stringHeightList = completedValues['heightList'].split(',') + maxHeight = float(completedValues['maxHeight']) * 100000 + i = 0 + heightList = [] + for h in stringHeightList: + heightList.append(float(h)) + if direction == 'down': + height = 0 + while height < requestedHeight and i < len(heightList) - 1: + height = float(heightList[i]) + i += 1 + else: + height = maxHeight + heightList.reverse() + requestedHeight = min(requestedHeight, maxHeight) + while height > requestedHeight and i < len(heightList) - 1: + height = float(heightList[i]) + i += 1 + targetIndex = heightList.index(height) + fileName = 'trans looking %s-%s.pyr' % (direction, targetIndex) + transmissionValues = utils.readTransmissionValues(fileName, folderPath) + for key in transmissionValues: + transmissionValues[key] = np.asarray(transmissionValues[key]) + transmissionValues['rangeMin'] = float(completedValues['rangeMin']) + transmissionValues['rangeMax'] = float(completedValues['rangeMax']) + transmissionValues['surfaceTemperature'] = float(completedValues['surfaceTemperature']) + transmissionValues['molList'] = completedValues['molList'] + return transmissionValues + + def processTransmissionBySingleLayer(folderPath, res=1): - #first process transmission upward. Need to get initial values, mostly just for surface temp + # first process transmission upward. Need to get initial values, mostly just for surface temp values = utils.readCompleteProfile(folderPath) planet = Planet(values['name'], float(values['surfacePressure']), int(values['surfaceTemperature']), float(values['maxHeight']), @@ -79,13 +111,10 @@ def processTransmissionBySingleLayer(folderPath, res=1): for mol in values['molList'].split(','): planet.moleculeList.append(mol) - # now, 1 file at a time, open it, read values, write the transmission at a reduced res, to save space. It will be - # written in key: value style, with the key being the mean height of the layer. This will allow for easy lookup - # for values. - # Start by process the transmission, looking down, ie process surface transmission 1 --> top xAxis = None fileLength = utils.profileLength(folderPath) heightList = [0] + for i in range(1, fileLength + 1): lP = utils.readPlanetProfile(folderPath, i, fileLength) layer = Layer(lP['depth'], lP['T'], lP['P'], lP['rangeMin'], lP['rangeMax'], height=lP['height'], @@ -93,34 +122,42 @@ def processTransmissionBySingleLayer(folderPath, res=1): layer.absorptionCoefficient = np.asarray(lP['absCoef']) layer.progressAbsCoef = True - # if this is the first time through the loop, create an xAxis with range and steps the same as the absCoef - # and initiate the surfaceSpectrum if xAxis is None: xAxis = np.linspace(planet.rangeMin, planet.rangeMax, len(layer.absorptionCoefficient)) surfaceSpectrum = pyradPlanck.planckWavenumber(xAxis, planet.surfaceTemperature) - spectrumDict = {'layer': reduceRes(surfaceSpectrum, finalRes=res)} + spectrumDict = {folderPath: reduceRes(surfaceSpectrum, finalRes=res)} for molecule in planet.moleculeList: spectrumDict[molecule] = reduceRes(surfaceSpectrum, finalRes=res) utils.writePlanetTransmission(folderPath, 0, spectrumDict, 'down', 0) - - nextSpectrum = layer.transmission(surfaceSpectrum) - spectrumDict = {folderPath: reduceRes(nextSpectrum, finalRes=res)} - - for molecule in planet.moleculeList: - molAbsCoef = utils.readPlanetProfileMolecule(folderPath, i, fileLength, molecule) - layer.absorptionCoefficient = np.asarray(molAbsCoef) - spectrumDict[molecule] = reduceRes(layer.transmission(surfaceSpectrum), finalRes=res) + surfaceSpectrum = layer.transmission(surfaceSpectrum) + spectrumDict = {folderPath: reduceRes(surfaceSpectrum, finalRes=res)} utils.writePlanetTransmission(folderPath, layer.meanHeight, spectrumDict, 'down', i) heightList.append(layer.meanHeight) - surfaceSpectrum = nextSpectrum - #insert a line(s) into the top of the file of the heightList and other pyrad data - utils.profileWriteTransmissionComplete(folderPath, heightList) + heightList.append(planet.maxHeight) + for molecule in planet.moleculeList: + surfaceSpectrum = pyradPlanck.planckWavenumber(xAxis, planet.surfaceTemperature) + spectrumDict = {} + for i in range(1, fileLength + 1): + lP = utils.readPlanetProfile(folderPath, i, fileLength) + molAbsCoef = utils.readPlanetProfileMolecule(folderPath, i, fileLength, molecule) + + molLayer = Layer(lP['depth'], lP['T'], lP['P'], lP['rangeMin'], lP['rangeMax'], height=lP['height'], + name=lP['name']) + molLayer.absorptionCoefficient = np.asarray(molAbsCoef) + molLayer.progressAbsCoef = True + spectrumDict[molecule] = reduceRes(molLayer.transmission(surfaceSpectrum)) + surfaceSpectrum = molLayer.transmission(surfaceSpectrum) + utils.writePlanetTransmission(folderPath, molLayer.meanHeight, spectrumDict, 'down', i, mode='ab') # with transmission from surface upward processed, do the same in reverse to get the transmission toward the surface - # initial spetrum will be 2.7K for CMB + # initial spectrum will be 2.7K for CMB surfaceSpectrum = pyradPlanck.planckWavenumber(xAxis, 2.7) - heightList = [planet.maxHeight] + spectrumDict = {folderPath: reduceRes(surfaceSpectrum, finalRes=res)} + for molecule in planet.moleculeList: + spectrumDict[molecule] = reduceRes(surfaceSpectrum, finalRes=res) + utils.writePlanetTransmission(folderPath, planet.maxHeight, spectrumDict, 'up', 0) + for i in range(1, fileLength + 1): fileNumber = fileLength + 1 - i lP = utils.readPlanetProfile(folderPath, fileNumber, fileLength) @@ -128,19 +165,24 @@ def processTransmissionBySingleLayer(folderPath, res=1): name=lP['name']) layer.absorptionCoefficient = np.asarray(lP['absCoef']) layer.progressAbsCoef = True + surfaceSpectrum = layer.transmission(surfaceSpectrum) spectrumDict = {folderPath: reduceRes(surfaceSpectrum, finalRes=res)} - for molecule in planet.moleculeList: - spectrumDict[molecule] = reduceRes(surfaceSpectrum, finalRes=res) - utils.writePlanetTransmission(folderPath, planet.maxHeight, spectrumDict, 'up', 0) - nextSpectrum = layer.transmission(surfaceSpectrum) - spectrumDict = {'layer': reduceRes(nextSpectrum, finalRes=res)} - for molecule in planet.moleculeList: - molAbsCoef = utils.readPlanetProfileMolecule(folderPath, fileNumber, fileLength, molecule) - layer.absorptionCoefficient = np.asarray(molAbsCoef) - spectrumDict[molecule] = reduceRes(layer.transmission(surfaceSpectrum), finalRes=res) utils.writePlanetTransmission(folderPath, layer.meanHeight, spectrumDict, 'up', i) - heightList.append(layer.meanHeight) - surfaceSpectrum = nextSpectrum + + for molecule in planet.moleculeList: + surfaceSpectrum = pyradPlanck.planckWavenumber(xAxis, 2.7) + spectrumDict = {} + for i in range(1, fileLength + 1): + fileNumber = fileLength + 1 - i + molAbsCoef = utils.readPlanetProfileMolecule(folderPath, fileNumber, fileLength, molecule) + molLayer = Layer(lP['depth'], lP['T'], lP['P'], lP['rangeMin'], lP['rangeMax'], height=lP['height'], + name=lP['name']) + molLayer.absorptionCoefficient = np.asarray(molAbsCoef) + molLayer.progressAbsCoef = True + spectrumDict[molecule] = reduceRes(molLayer.transmission(surfaceSpectrum), finalRes=res) + utils.writePlanetTransmission(folderPath, molLayer.meanHeight, spectrumDict, 'up', i, mode='ab') + surfaceSpectrum = molLayer.transmission(surfaceSpectrum) + utils.profileWriteTransmissionComplete(folderPath, heightList) return @@ -1280,7 +1322,7 @@ def plot(propertyToPlot, title, plotList, fill=False): plt.ylabel(propertyToPlot) if propertyToPlot == 'line survey': plt.yscale('log') - plt.grid(theme.gridList, linewidth=.5, linestyle=':') + plt.grid(theme.gridList[0], linewidth=.5, linestyle=':') plt.title('%s' % title) handles = [] linewidth = .7 @@ -1305,6 +1347,7 @@ def plotSpectrum(layer=None, title=None, rangeMin=None, rangeMax=None, objList=N plt.subplot(111, facecolor=theme.faceColor) plt.margins(0.01) plt.subplots_adjust(left=.07, bottom=.08, right=.97, top=.90) + plt.grid(theme.gridList[0], linewidth=.5, linestyle=':') if layer: rangeMin = layer.rangeMin rangeMax = layer.rangeMax @@ -1358,17 +1401,19 @@ def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=( plt.margins(0.01) plt.subplots_adjust(left=.07, bottom=.08, right=.97, top=.90) plt.ylabel('Radiance Wm-2sr-1(cm-1)-1') + plt.grid(theme.gridList[0], linewidth=.5, linestyle=':') handles = [] heightFlag = True if height is None: heightFlag = False - p = loadEmptyPlanet(planets[0]) - if not heightFlag: - height = p.maxHeight / 100000 - - totalY = reduceRes(p.processTransmission(height, direction=direction, verify=verify)) - xAxis = np.linspace(p.rangeMin, p.rangeMax, len(totalY)) + if not heightFlag and direction == 'down': + height = 999999999999 + elif not heightFlag and direction == 'up': + height = 0 + transmissionValues = readTransmissionFromFile(height, planets[0], direction=direction) + totalY = transmissionValues[planets[0]] + xAxis = np.linspace(transmissionValues['rangeMin'], transmissionValues['rangeMax'], len(totalY)) for temperature, color in zip(temperatureList, theme.gridList): yAxis = pyradPlanck.planckWavenumber(xAxis, float(temperature)) @@ -1377,17 +1422,19 @@ def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=( powerSpectrum = round(integrateSpectrum(totalY, pi, res=res), 2) effTemp = int(stefanB(powerSpectrum)) - fig, = plt.plot(xAxis, totalY, linewidth=linewidth, color=theme.colorList[0], label='%s : %sWm-2, eff : %sK' % (p.name, powerSpectrum, effTemp)) + fig, = plt.plot(xAxis, totalY, linewidth=linewidth, color=theme.colorList[0], label='%s : %sWm-2, eff : %sK' % (planets[0], powerSpectrum, effTemp)) handles.append(fig) for planet, color in zip(planets[1:], theme.colorList[1:]): - p = loadEmptyPlanet(planet) - if not heightFlag: - height = p.maxHeight / 100000 - totalY = reduceRes(p.processTransmission(height, direction=direction, verify=verify)) + if not heightFlag and direction == 'down': + height = 999999999999 + elif not heightFlag and direction == 'up': + height = 0 + transmissionValues = readTransmissionFromFile(height, planet, direction) + totalY = transmissionValues[planet] powerSpectrum = round(integrateSpectrum(totalY, pi, res=res), 2) effTemp = int(stefanB(powerSpectrum)) - fig, = plt.plot(xAxis, totalY, linewidth=linewidth, color=color, label='%s : %sWm-2, eff : %sK' % (p.name, powerSpectrum, effTemp)) + fig, = plt.plot(xAxis, totalY, linewidth=linewidth, color=color, label='%s : %sWm-2, eff : %sK' % (planet, powerSpectrum, effTemp)) handles.append(fig) legend = plt.legend(handles=handles, frameon=False) @@ -1402,15 +1449,20 @@ def plotPlanetAndComponents(planet, height=None, direction='down', temperatureLi plt.subplot(111, facecolor=theme.faceColor) plt.margins(0.01) plt.subplots_adjust(left=.05, bottom=.05, right=.97, top=.95) + plt.grid(theme.gridList[0], linewidth=.5, linestyle=':') plt.ylabel('radiance Wm-2sr-1(cm-1)-1') plt.xlabel('wavenumber cm-1') handles = [] + heightFlag = True if height is None: - height = planet.maxHeight / 100000 - #transmittanceValues = readTransmittance(planet, height, direction=direction) - #yTotal = transmittanceValues['layer'] - yTotal = reduceRes(planet.processTransmission(height, direction=direction, verify=verify, moleculeSpecific=True)) - xAxis = np.linspace(planet.rangeMin, planet.rangeMax, len(yTotal)) + heightFlag = False + if not heightFlag and direction == 'down': + height = 999999999999 + elif not heightFlag and direction == 'up': + height = 0 + transmittanceValues = readTransmissionFromFile(height, planet, direction=direction) + yTotal = transmittanceValues[planet] + xAxis = np.linspace(transmittanceValues['rangeMin'], transmittanceValues['rangeMax'], len(yTotal)) for temperature, color in zip(temperatureList, theme.gridList): yAxis = pyradPlanck.planckWavenumber(xAxis, float(temperature)) fig, = plt.plot(xAxis, yAxis, linewidth=linewidth / 2, color=color, @@ -1418,26 +1470,17 @@ def plotPlanetAndComponents(planet, height=None, direction='down', temperatureLi (temperature, int(integrateSpectrum(yAxis, pi, res=res)))) handles.append(fig) - planckAxis = pyradPlanck.planckWavenumber(xAxis, float(planet.surfaceTemperature)) + planckAxis = pyradPlanck.planckWavenumber(xAxis, float(transmittanceValues['surfaceTemperature'])) surfacePower = int(integrateSpectrum(planckAxis, pi, res=res)) powerSpectrum = int(integrateSpectrum(yTotal, pi, res=res)) plt.title('Surface temp: %sK Surface flux: %sWm-2 Effec temp: %sK' - % (planet.surfaceTemperature, surfacePower, int(stefanB(powerSpectrum)))) + % (transmittanceValues['surfaceTemperature'], surfacePower, int(stefanB(powerSpectrum)))) fig, = plt.plot(xAxis, yTotal, linewidth=linewidth, color=theme.backingColor, label='net flux: %sWm-2 netGHE: %sWm-2' % (powerSpectrum, surfacePower - powerSpectrum)) handles.append(fig) - tempName = planet.name - length = len(planet.atmosphere) - for molecule, color in zip(planet.moleculeList, theme.colorList): - print('processing %s in atmosphere' % molecule) - - planet.name = molecule - i = 1 - for layer in planet.atmosphere: - layer.absorptionCoefficient = np.asarray(utils.readPlanetProfileMolecule(tempName, i, length, molecule)) - i += 1 - yAxis = reduceRes(planet.processTransmission(height, direction=direction, verify=False)) - #yAxis = transmittanceValues[molecule] + moleculeList = transmittanceValues['molList'].split(',') + for molecule, color in zip(moleculeList, theme.colorList): + yAxis = transmittanceValues[molecule] tempPowerSpectrum = int(integrateSpectrum(yAxis, pi, res=res)) fig, = plt.plot(xAxis, yAxis, linewidth=linewidth, color=color, alpha=.6, label='%s effect : %sWm-2' % (molecule, surfacePower - tempPowerSpectrum)) @@ -1446,9 +1489,6 @@ def plotPlanetAndComponents(planet, height=None, direction='down', temperatureLi text = legend.get_texts() plt.setp(text, color=theme.textColor) plt.show() - planet.name = tempName - #print('Reloading original planet data...') - #return loadEmptyPlanet(planet.name, verify=False) return diff --git a/pyradUtilities.py b/pyradUtilities.py index b10f0b0..a033742 100644 --- a/pyradUtilities.py +++ b/pyradUtilities.py @@ -187,11 +187,13 @@ def writeTheme(fullPath): def openReturnLines(fullPath): if not os.path.isfile(fullPath): + print('could not find file %s to open.' % fullPath) return False openFile = open(fullPath) lineList = openFile.readlines() openFile.close() if not lineList or NULL_TAG in lineList[0]: + print('file %s seems to not have any info.' % fullPath) return False while lineList[0][0] == '#' and len(lineList) > 1: lineList.pop(0) @@ -232,14 +234,15 @@ def writePlanetProfile(name, layer, processingTime, moleculeList, moleculeSpecif return -def writePlanetTransmission(name, height, values, direction, number): +def writePlanetTransmission(name, height, values, direction, number, mode='wb'): folderPath = '%s/%s' % (profileDir, name) - filePath = '%s/%s.pyr' % (folderPath, 'trans looking %s-%s ' % (direction, number)) - openfile = open(filePath, 'wb') - for item in values: + filePath = '%s/%s.pyr' % (folderPath, 'trans looking %s-%s' % (direction, number)) + openfile = open(filePath, mode) + if mode == 'wb': text = '# PyRad v%s transmission file\n' \ - '# layer height for this file is %s\n' % (VERSION, height) + '# layer height for this file is %s\n' % (VERSION, height) openfile.write(text.encode('utf-8')) + for item in values: text = '%s: %s\n' % (item, ','.join(map(str, values[item]))) openfile.write(text.encode('utf-8')) openfile.close() @@ -288,6 +291,35 @@ def readCompleteProfile(folderPath): return values +def readCompleteTransmission(folderPath): + fullPath = '%s/%s/transmissionComplete.pyr' % (profileDir, folderPath) + lines = openReturnLines(fullPath) + values = {} + for line in lines: + if line[0] == '#': + pass + else: + cells = line.split(':') + values[cells[0].strip()] = cells[1].strip() + return values + + +def readTransmissionValues(fileName, folderPath): + fullPath = '%s/%s/%s' % (profileDir, folderPath, fileName) + lines = openReturnLines(fullPath) + values = {} + for line in lines: + if line[0] == '#': + pass + else: + cells = line.split(':') + transmission = [] + for t in cells[1].split(','): + transmission.append(float(t)) + values[cells[0]] = transmission + return values + + def molSpecProfileList(): completedProfileDirList = getCompletedProfileList() completeList = [] From 7fb17b8c9d5bc1494ed40784b49a77a8cec09e93 Mon Sep 17 00:00:00 2001 From: Brad Schrag Date: Wed, 14 Nov 2018 00:35:21 -0600 Subject: [PATCH 25/43] feeling like this is wrapping up. Running some hi detail models now --- earthsimple.pyr | 38 ++++++++++++++++++++++++++++++++ logger.txt | 1 + pyrad.py | 25 +++++++++++++-------- pyradClasses.py | 56 +++++++++++++++++++++++++++-------------------- pyradUtilities.py | 46 ++++++++++++++++++++++++++++++++++---- venussimple.pyr | 2 +- 6 files changed, 130 insertions(+), 38 deletions(-) create mode 100644 earthsimple.pyr create mode 100644 logger.txt diff --git a/earthsimple.pyr b/earthsimple.pyr new file mode 100644 index 0000000..610a80a --- /dev/null +++ b/earthsimple.pyr @@ -0,0 +1,38 @@ +# A demo file for pyrad + +# mBar , K , km, m , g, cm-1,cm-1 +surface: 1013.25, 288, 120, 100, 9.8, 00, 2000 + +# mol text name, concentration +molecule: co2, .000400 +molecule: h2o, .018000 +molecule: o3, 0 +molecule: o2, .20 +molecule: n2, .77 +molecule: ch4, .0000018 +molecule: ar, .009 + +# name, endHeight, endTemp +lapse rate: troposphere, 11, 216 +lapse rate: tropopause, 20, 216 +lapse rate: stratosphere, 32, 228 +lapse rate: stratosphere, 47, 270 +lapse rate: stratopause, 51, 270 +lapse rate: mesosphere, 71, 214 +lapse rate: mesosphere2, 80, 190 +lapse rate: mesopause, 90, 190 +lapse rate: thermosphere, 120, 228 + +# name, endHeight, endValue, moleculeName +composition rate: WV boundary layer, 2.5, 18000e-6, h2o +composition rate: WV troposphere1, 8, 200e-6, h2o +composition rate: WV troposphere2, 9, 400e-6, h2o +composition rate: WV troposphere2, 10, 400e-6, h2o +composition rate: WV tropopause, 20, 2e-6, h2o +composition rate: WV stratosphere to top,120, 0, h2o + +composition rate: troposphere ozone, 16, 60E-9, o3 +composition rate: tropopause ozone, 32, 5E-6, o3 +composition rate: upper strat ozone, 60, 0, o3 +composition rate: strat on up ozone, 120, 0, o3 + diff --git a/logger.txt b/logger.txt new file mode 100644 index 0000000..70f4f7b --- /dev/null +++ b/logger.txt @@ -0,0 +1 @@ +2018-11-14 00:20:21 diff --git a/pyrad.py b/pyrad.py index cf2da4d..21ea83b 100644 --- a/pyrad.py +++ b/pyrad.py @@ -170,11 +170,12 @@ def plotPlanetSpectrum(values): def plotPlanetSpectrumComponents(values): - planet = pyradClasses.loadEmptyPlanet(values['profiles'][0].name) + #planet = pyradClasses.loadEmptyPlanet(values['profiles'][0].name) if values['height'] == -2.71828: - pyradClasses.plotPlanetAndComponents(planet, direction=values['direction'], verify=False) + pyradClasses.plotPlanetAndComponents(values['profile'], direction=values['direction'], verify=False) + pyradClasses.plotPlanetAndComponents(values['profile'], direction=values['direction'], verify=False) else: - pyradClasses.plotPlanetAndComponents(planet, direction=values['direction'], height=values['height'], verify=False) + pyradClasses.plotPlanetAndComponents(values['profile'], direction=values['direction'], height=values['height'], verify=False) return chooseAtmTransferBuildProfile() @@ -579,7 +580,7 @@ def chooseDirectionComponents(profile): def plotProfileComponentsMenu(param=None): entryList = [] - profileList = util.molSpecProfileList() + profileList = util.getCompletedTransmissionList() for profile in profileList: entryList.append(Entry('%s' % profile, nextMenu=chooseDirectionComponents, functionParams=profile)) menuAtmTransfer = Menu('Choose atmosphere', entryList, previousMenu=chooseAtmTransferBuildProfile, multiChoice=True) @@ -590,8 +591,10 @@ def buildProfile(profileList): for profile in profileList: print('Building %s on setting %s' % (profile.name, pyradClasses.settings.setting)) planet = pyradClasses.createCustomPlanet(profile.name) - moleculeSpecific = pyradClasses.yesOrNo("Store data by individual molecule? Doesn't require more time, " - "just hard drive space %s:" % util.limeText('(y/n)')) + #moleculeSpecific = pyradClasses.yesOrNo("Store data by individual molecule? Doesn't require more time, " + # "just hard drive space %s:" % util.limeText('(y/n)')) + saveAbsData = pyradClasses.yesOrNo("Would you like to save abs coef data?\n" + "This takes up quite a bit of space and generally isn't needed. %s" % util.limeText('(y/n)')) overwrite = True progress, time = util.profileProgress(planet.folderPath) print('progress: %s' % progress) @@ -604,11 +607,15 @@ def buildProfile(profileList): overwrite = pyradClasses.yesOrNo("Are you sure, choosing yes will erase all previous data.\n" "Do you wish to overwrite it? %s" % util.limeText('(y/n)')) else: - planet.processLayers(verify=False, moleculeSpecific=moleculeSpecific) + planet.processLayers(verify=False, moleculeSpecific=True) overwrite = False if overwrite: util.emptyProfileDirectory(planet.folderPath) - planet.processLayers(verify=False, moleculeSpecific=moleculeSpecific) + planet.processLayers(verify=False, moleculeSpecific=True) + print('Creating transmission...') + pyradClasses.processTransmissionBySingleLayer(planet.folderPath) + if not saveAbsData: + util.clearAbsData(planet.folderPath) return chooseAtmTransferBuildProfile() @@ -630,7 +637,7 @@ def chooseAtmTransferBuildProfile(param=None): def plotAtmTransferMenu(param=None): - profileList = util.getCompletedProfileList() + profileList = util.getCompletedTransmissionList() entryList = [] for profile in profileList: entryList.append(Entry('%s' % profile, nextMenu=chooseDirection, functionParams=profile)) diff --git a/pyradClasses.py b/pyradClasses.py index bc0d28c..45f8f44 100644 --- a/pyradClasses.py +++ b/pyradClasses.py @@ -116,10 +116,10 @@ def processTransmissionBySingleLayer(folderPath, res=1): heightList = [0] for i in range(1, fileLength + 1): - lP = utils.readPlanetProfile(folderPath, i, fileLength) - layer = Layer(lP['depth'], lP['T'], lP['P'], lP['rangeMin'], lP['rangeMax'], height=lP['height'], - name=lP['name']) - layer.absorptionCoefficient = np.asarray(lP['absCoef']) + layerProfile = utils.readPlanetProfile(folderPath, i, fileLength) + layer = Layer(layerProfile['depth'], layerProfile['T'], layerProfile['P'], layerProfile['rangeMin'], layerProfile['rangeMax'], height=layerProfile['height'], + name=layerProfile['name']) + layer.absorptionCoefficient = np.asarray(layerProfile['absCoef']) layer.progressAbsCoef = True if xAxis is None: @@ -139,12 +139,11 @@ def processTransmissionBySingleLayer(folderPath, res=1): surfaceSpectrum = pyradPlanck.planckWavenumber(xAxis, planet.surfaceTemperature) spectrumDict = {} for i in range(1, fileLength + 1): - lP = utils.readPlanetProfile(folderPath, i, fileLength) - molAbsCoef = utils.readPlanetProfileMolecule(folderPath, i, fileLength, molecule) + moleculeProfile = utils.readPlanetProfileMolecule(folderPath, i, fileLength, molecule) - molLayer = Layer(lP['depth'], lP['T'], lP['P'], lP['rangeMin'], lP['rangeMax'], height=lP['height'], - name=lP['name']) - molLayer.absorptionCoefficient = np.asarray(molAbsCoef) + molLayer = Layer(moleculeProfile['depth'], moleculeProfile['T'], moleculeProfile['P'], moleculeProfile['rangeMin'], moleculeProfile['rangeMax'], height=moleculeProfile['height'], + name=moleculeProfile['name']) + molLayer.absorptionCoefficient = np.asarray(moleculeProfile['absCoef']) molLayer.progressAbsCoef = True spectrumDict[molecule] = reduceRes(molLayer.transmission(surfaceSpectrum)) surfaceSpectrum = molLayer.transmission(surfaceSpectrum) @@ -160,10 +159,10 @@ def processTransmissionBySingleLayer(folderPath, res=1): for i in range(1, fileLength + 1): fileNumber = fileLength + 1 - i - lP = utils.readPlanetProfile(folderPath, fileNumber, fileLength) - layer = Layer(lP['depth'], lP['T'], lP['P'], lP['rangeMin'], lP['rangeMax'], height=lP['height'], - name=lP['name']) - layer.absorptionCoefficient = np.asarray(lP['absCoef']) + layerProfile= utils.readPlanetProfile(folderPath, fileNumber, fileLength) + layer = Layer(layerProfile['depth'], layerProfile['T'], layerProfile['P'], layerProfile['rangeMin'], layerProfile['rangeMax'], height=layerProfile['height'], + name=layerProfile['name']) + layer.absorptionCoefficient = np.asarray(layerProfile['absCoef']) layer.progressAbsCoef = True surfaceSpectrum = layer.transmission(surfaceSpectrum) spectrumDict = {folderPath: reduceRes(surfaceSpectrum, finalRes=res)} @@ -174,10 +173,10 @@ def processTransmissionBySingleLayer(folderPath, res=1): spectrumDict = {} for i in range(1, fileLength + 1): fileNumber = fileLength + 1 - i - molAbsCoef = utils.readPlanetProfileMolecule(folderPath, fileNumber, fileLength, molecule) - molLayer = Layer(lP['depth'], lP['T'], lP['P'], lP['rangeMin'], lP['rangeMax'], height=lP['height'], - name=lP['name']) - molLayer.absorptionCoefficient = np.asarray(molAbsCoef) + moleculeProfile = utils.readPlanetProfileMolecule(folderPath, fileNumber, fileLength, molecule) + molLayer = Layer(moleculeProfile['depth'], moleculeProfile['T'], moleculeProfile['P'], moleculeProfile['rangeMin'], moleculeProfile['rangeMax'], height=moleculeProfile['height'], + name=moleculeProfile['name']) + molLayer.absorptionCoefficient = np.asarray(moleculeProfile['absCoef']) molLayer.progressAbsCoef = True spectrumDict[molecule] = reduceRes(molLayer.transmission(surfaceSpectrum), finalRes=res) utils.writePlanetTransmission(folderPath, molLayer.meanHeight, spectrumDict, 'up', i, mode='ab') @@ -1408,14 +1407,14 @@ def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=( if height is None: heightFlag = False if not heightFlag and direction == 'down': - height = 999999999999 + height = 9999999999999999999 elif not heightFlag and direction == 'up': height = 0 transmissionValues = readTransmissionFromFile(height, planets[0], direction=direction) totalY = transmissionValues[planets[0]] xAxis = np.linspace(transmissionValues['rangeMin'], transmissionValues['rangeMax'], len(totalY)) - for temperature, color in zip(temperatureList, theme.gridList): + for temperature, color in zip(temperatureList, theme.colorList[1:]): yAxis = pyradPlanck.planckWavenumber(xAxis, float(temperature)) fig, = plt.plot(xAxis, yAxis, linewidth=1, color=color, linestyle=':', label='%sK : %sWm-2' % (temperature, round(integrateSpectrum(yAxis, pi, res=res), 2))) handles.append(fig) @@ -1427,7 +1426,7 @@ def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=( for planet, color in zip(planets[1:], theme.colorList[1:]): if not heightFlag and direction == 'down': - height = 999999999999 + height = 9999999999999999999 elif not heightFlag and direction == 'up': height = 0 transmissionValues = readTransmissionFromFile(height, planet, direction) @@ -1457,13 +1456,13 @@ def plotPlanetAndComponents(planet, height=None, direction='down', temperatureLi if height is None: heightFlag = False if not heightFlag and direction == 'down': - height = 999999999999 + height = 9999999999999999999 elif not heightFlag and direction == 'up': height = 0 transmittanceValues = readTransmissionFromFile(height, planet, direction=direction) yTotal = transmittanceValues[planet] xAxis = np.linspace(transmittanceValues['rangeMin'], transmittanceValues['rangeMax'], len(yTotal)) - for temperature, color in zip(temperatureList, theme.gridList): + for temperature, color in zip(temperatureList, theme.colorList[1:]): yAxis = pyradPlanck.planckWavenumber(xAxis, float(temperature)) fig, = plt.plot(xAxis, yAxis, linewidth=linewidth / 2, color=color, linestyle='--', label='%sK : %sWm-2' % @@ -1475,15 +1474,24 @@ def plotPlanetAndComponents(planet, height=None, direction='down', temperatureLi powerSpectrum = int(integrateSpectrum(yTotal, pi, res=res)) plt.title('Surface temp: %sK Surface flux: %sWm-2 Effec temp: %sK' % (transmittanceValues['surfaceTemperature'], surfacePower, int(stefanB(powerSpectrum)))) + if direction == 'up': + effect = surfacePower - powerSpectrum + else: + effect = powerSpectrum fig, = plt.plot(xAxis, yTotal, linewidth=linewidth, color=theme.backingColor, - label='net flux: %sWm-2 netGHE: %sWm-2' % (powerSpectrum, surfacePower - powerSpectrum)) + label='net flux: %sWm-2 netGHE: %sWm-2' % (powerSpectrum, effect)) handles.append(fig) moleculeList = transmittanceValues['molList'].split(',') for molecule, color in zip(moleculeList, theme.colorList): yAxis = transmittanceValues[molecule] tempPowerSpectrum = int(integrateSpectrum(yAxis, pi, res=res)) + if direction == 'up': + effect = surfacePower - tempPowerSpectrum + else: + effect = tempPowerSpectrum + fig, = plt.plot(xAxis, yAxis, linewidth=linewidth, color=color, alpha=.6, - label='%s effect : %sWm-2' % (molecule, surfacePower - tempPowerSpectrum)) + label='%s effect : %sWm-2' % (molecule, effect)) handles.append(fig) legend = plt.legend(handles=handles, frameon=False) text = legend.get_texts() diff --git a/pyradUtilities.py b/pyradUtilities.py index a033742..870d452 100644 --- a/pyradUtilities.py +++ b/pyradUtilities.py @@ -193,7 +193,6 @@ def openReturnLines(fullPath): lineList = openFile.readlines() openFile.close() if not lineList or NULL_TAG in lineList[0]: - print('file %s seems to not have any info.' % fullPath) return False while lineList[0][0] == '#' and len(lineList) > 1: lineList.pop(0) @@ -249,6 +248,10 @@ def writePlanetTransmission(name, height, values, direction, number, mode='wb'): return +def clearAbsData(folderPath): + pass + + def emptyFile(filePath): fullPath = '%s/%s' % (cwd, filePath) openfile = open(fullPath, 'wb') @@ -278,6 +281,19 @@ def getCompletedProfileList(): return completedList +def getCompletedTransmissionList(): + fileList = os.listdir(profileDir) + dirList = [] + completedList = [] + for file in fileList: + if os.path.isdir('%s/%s' % (profileDir, file)): + dirList.append('%s/%s' % (profileDir, file)) + for dir in dirList: + if os.path.isfile('%s/transmissionComplete.pyr' % dir): + completedList.append(dir.split('/')[-1]) + return completedList + + def readCompleteProfile(folderPath): fullPath = '%s/%s/profileComplete.pyr' % (profileDir, folderPath) lines = openReturnLines(fullPath) @@ -350,6 +366,20 @@ def checkPlanetProfile(name): return False +def checkPlanetTransmission(name): + folderPath = '%s/%s' % (profileDir, name) + if not os.path.isdir(folderPath): + os.mkdir(folderPath) + return False + else: + fileName = 'transmissionComplete.pyr' + filePath = '%s/%s' % (folderPath, fileName) + if os.path.isfile(filePath): + return True + else: + return False + + def parseCustomProfile(name): filePath = '%s/%s.pyr' % (cwd, name) lines = openReturnLines(filePath) @@ -532,19 +562,27 @@ def readPlanetProfileMolecule(name, layerNumber, length, moleculeName): fileName = 'Layer %s:%s' % (layerNumber, length) filePath = '%s/%s.pyr' % (folderPath, fileName) print('Reading %s profile from %s... ' % (moleculeName, fileName), end='\r', flush=True) + layerDict = {'molecule list': []} lines = openReturnLines(filePath) for line in lines: keyValue = line.split(':') if line[0] == '#': pass + elif keyValue[0].strip() == 'name': + layerDict[keyValue[0]] = keyValue[1].strip() elif keyValue[0].strip() == '%s absCoef' % moleculeName: absList = keyValue[1].split(',') absCoefList = [] for value in absList: absCoefList.append(float(value)) - return absCoefList - print('missing absCoef for %s in %s' % (moleculeName, filePath)) - exit() + layerDict['absCoef'] = absCoefList + elif keyValue[0].strip() == 'T' or keyValue[0] == 'rangeMin' or keyValue[0] == 'rangeMax': + layerDict[keyValue[0]] = int(keyValue[1]) + elif keyValue[0].strip() == 'P' or keyValue[0].strip() == 'height' or keyValue[0].strip() == 'depth': + layerDict[keyValue[0]] = float(keyValue[1]) + else: + pass + return layerDict def readPlanetProfile(name, layerNumber, length): diff --git a/venussimple.pyr b/venussimple.pyr index 49cee48..01ab162 100644 --- a/venussimple.pyr +++ b/venussimple.pyr @@ -1,7 +1,7 @@ # A demo file for pyrad # mBar , K , km, m , g, cm-1,cm-1 -surface: 93000, 735, 200, 50, 8.87 +surface: 93000, 735, 200, 2, 8.87 # mol text name, concentration molecule: co2, .965 From e9085f236847982c0282179d800a4f7f638ad9d4 Mon Sep 17 00:00:00 2001 From: Brad Schrag Date: Wed, 14 Nov 2018 09:30:35 -0600 Subject: [PATCH 26/43] fixed bug in loading plots in menu system --- logger.txt | 1 - pyrad.py | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) delete mode 100644 logger.txt diff --git a/logger.txt b/logger.txt deleted file mode 100644 index 70f4f7b..0000000 --- a/logger.txt +++ /dev/null @@ -1 +0,0 @@ -2018-11-14 00:20:21 diff --git a/pyrad.py b/pyrad.py index 21ea83b..204f14a 100644 --- a/pyrad.py +++ b/pyrad.py @@ -172,10 +172,10 @@ def plotPlanetSpectrum(values): def plotPlanetSpectrumComponents(values): #planet = pyradClasses.loadEmptyPlanet(values['profiles'][0].name) if values['height'] == -2.71828: - pyradClasses.plotPlanetAndComponents(values['profile'], direction=values['direction'], verify=False) - pyradClasses.plotPlanetAndComponents(values['profile'], direction=values['direction'], verify=False) + pyradClasses.plotPlanetAndComponents(values['profiles'][0].name, direction=values['direction'], verify=False) +# pyradClasses.plotPlanetAndComponents(values['profiles'], direction=values['direction'], verify=False) else: - pyradClasses.plotPlanetAndComponents(values['profile'], direction=values['direction'], height=values['height'], verify=False) + pyradClasses.plotPlanetAndComponents(values['profiles'][0].name, direction=values['direction'], height=values['height'], verify=False) return chooseAtmTransferBuildProfile() From f9336cc9b21240e14c652b2edf025806e08abe6c Mon Sep 17 00:00:00 2001 From: brad schrag Date: Thu, 15 Nov 2018 01:51:06 -0600 Subject: [PATCH 27/43] updated filename for layers --- pyradClasses.py | 5 +++-- pyradUtilities.py | 13 ++++++++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/pyradClasses.py b/pyradClasses.py index 45f8f44..b3a5a53 100644 --- a/pyradClasses.py +++ b/pyradClasses.py @@ -160,7 +160,8 @@ def processTransmissionBySingleLayer(folderPath, res=1): for i in range(1, fileLength + 1): fileNumber = fileLength + 1 - i layerProfile= utils.readPlanetProfile(folderPath, fileNumber, fileLength) - layer = Layer(layerProfile['depth'], layerProfile['T'], layerProfile['P'], layerProfile['rangeMin'], layerProfile['rangeMax'], height=layerProfile['height'], + layer = Layer(layerProfile['depth'], layerProfile['T'], layerProfile['P'], layerProfile['rangeMin'], + layerProfile['rangeMax'], height=layerProfile['height'], name=layerProfile['name']) layer.absorptionCoefficient = np.asarray(layerProfile['absCoef']) layer.progressAbsCoef = True @@ -1161,7 +1162,7 @@ def processLayers(self, verify=True, moleculeSpecific=False, res=1): totalProcessTime = timeStart for height, depth in zip(self.heightList[startPoint:], self.depthList[startPoint:]): layerProcessTimeStart = time.time() - layer.name = 'Layer %s:%s' % (i, len(self.heightList)) + layer.name = 'layer %s_%s' % (i, len(self.heightList)) layer.height = height layer.depth = depth layer.T = int(self.temperatureAtHeight(layer.meanHeight)) diff --git a/pyradUtilities.py b/pyradUtilities.py index 311846c..cd92e4f 100644 --- a/pyradUtilities.py +++ b/pyradUtilities.py @@ -187,7 +187,6 @@ def writeTheme(fullPath): def openReturnLines(fullPath): if not os.path.isfile(fullPath): - print('could not find file %s to open.' % fullPath) return False openFile = open(fullPath) lineList = openFile.readlines() @@ -561,9 +560,17 @@ def readPlanetProfileMolecule(name, layerNumber, length, moleculeName): folderPath = '%s/%s' % (profileDir, name) fileName = 'Layer %s:%s' % (layerNumber, length) filePath = '%s/%s.pyr' % (folderPath, fileName) - print('Reading %s profile from %s... ' % (moleculeName, fileName), end='\r', flush=True) layerDict = {'molecule list': []} lines = openReturnLines(filePath) + if not lines: + fileName = 'layer %s_%s' % (layerNumber, length) + filePath = '%s/%s.pyr' % (folderPath, fileName) + lines = openReturnLines(filePath) + if not lines: + print('cant find layer file %s' % filePath) + exit() + print('Reading %s profile from %s... ' % (moleculeName, fileName), end='\r', + flush=True) for line in lines: keyValue = line.split(':') if line[0] == '#': @@ -591,7 +598,7 @@ def readPlanetProfile(name, layerNumber, length): filePath = '%s/%s.pyr' % (folderPath, fileName) lines = openReturnLines(filePath) if not lines: - fileName = 'Layer %s_%s' % (layerNumber, length) + fileName = 'layer %s_%s' % (layerNumber, length) filePath = '%s/%s.pyr' % (folderPath, fileName) lines = openReturnLines(filePath) if not lines: From 42434fea0e94180e4ff4173e40e9a896ed8797b6 Mon Sep 17 00:00:00 2001 From: brad schrag Date: Thu, 15 Nov 2018 09:03:11 -0600 Subject: [PATCH 28/43] fixed settings menu --- pyrad.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyrad.py b/pyrad.py index 204f14a..3eb3f4e 100644 --- a/pyrad.py +++ b/pyrad.py @@ -663,8 +663,8 @@ def menuMain(): def settingsMenu(previousMenu=menuMain): - lowSetting = Entry('low (intensity > 1E-21)', nextFunction=changeSettings, functionParams=('low', previousMenu)) - midSetting = Entry('mid (intensity > 1E-28)', nextFunction=changeSettings, functionParams=('mid', previousMenu)) + lowSetting = Entry('low (intensity > 1e-21)', nextFunction=changeSettings, functionParams=('low', previousMenu)) + midSetting = Entry('mid (intensity > 1e-24)', nextFunction=changeSettings, functionParams=('mid', previousMenu)) hiSetting = Entry('hi (all absorption lines)', nextFunction=changeSettings, functionParams=('hi', previousMenu)) loadTheme = Entry('Change theme', nextMenu=chooseThemeMenu, functionParams=previousMenu) menuSettings = Menu('Choose level of detail', [lowSetting, midSetting, hiSetting, loadTheme], previousMenu=previousMenu) From 012d58062df2dcb2e920441d15cf90f588f26fd3 Mon Sep 17 00:00:00 2001 From: brad schrag Date: Thu, 15 Nov 2018 11:59:38 -0600 Subject: [PATCH 29/43] added the method to dump the abs coef data after the transmission up & down is processed. --- pyrad.py | 2 -- pyradUtilities.py | 9 ++++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/pyrad.py b/pyrad.py index 3eb3f4e..71dabe1 100644 --- a/pyrad.py +++ b/pyrad.py @@ -591,8 +591,6 @@ def buildProfile(profileList): for profile in profileList: print('Building %s on setting %s' % (profile.name, pyradClasses.settings.setting)) planet = pyradClasses.createCustomPlanet(profile.name) - #moleculeSpecific = pyradClasses.yesOrNo("Store data by individual molecule? Doesn't require more time, " - # "just hard drive space %s:" % util.limeText('(y/n)')) saveAbsData = pyradClasses.yesOrNo("Would you like to save abs coef data?\n" "This takes up quite a bit of space and generally isn't needed. %s" % util.limeText('(y/n)')) overwrite = True diff --git a/pyradUtilities.py b/pyradUtilities.py index cd92e4f..e91738b 100644 --- a/pyradUtilities.py +++ b/pyradUtilities.py @@ -248,7 +248,14 @@ def writePlanetTransmission(name, height, values, direction, number, mode='wb'): def clearAbsData(folderPath): - pass + fullPath = '%s/%s' % (profileDir, folderPath) + fileList = os.listdir(fullPath) + for file in fileList: + if 'layer' in file: + filePath = '%s/%s' % (fullPath, file) + print('removing %s' % file, end='\r', flush=True) + os.remove(filePath) + return def emptyFile(filePath): From 13ed915e09c0cdfe49398012d981b7fa2405febf Mon Sep 17 00:00:00 2001 From: brad schrag Date: Fri, 16 Nov 2018 10:21:16 -0600 Subject: [PATCH 30/43] changed how the effect gets reported on the plot for each molecule so it reads correctly when looking up. --- pyradClasses.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pyradClasses.py b/pyradClasses.py index b3a5a53..5cc67a5 100644 --- a/pyradClasses.py +++ b/pyradClasses.py @@ -1470,15 +1470,17 @@ def plotPlanetAndComponents(planet, height=None, direction='down', temperatureLi (temperature, int(integrateSpectrum(yAxis, pi, res=res)))) handles.append(fig) - planckAxis = pyradPlanck.planckWavenumber(xAxis, float(transmittanceValues['surfaceTemperature'])) + if direction == 'down': + surfaceTemp = float(transmittanceValues['surfaceTemperature']) + else: + surfaceTemp = 2.7 + planckAxis = pyradPlanck.planckWavenumber(xAxis, surfaceTemp) surfacePower = int(integrateSpectrum(planckAxis, pi, res=res)) powerSpectrum = int(integrateSpectrum(yTotal, pi, res=res)) plt.title('Surface temp: %sK Surface flux: %sWm-2 Effec temp: %sK' % (transmittanceValues['surfaceTemperature'], surfacePower, int(stefanB(powerSpectrum)))) - if direction == 'up': - effect = surfacePower - powerSpectrum - else: - effect = powerSpectrum + effect = surfacePower - powerSpectrum + fig, = plt.plot(xAxis, yTotal, linewidth=linewidth, color=theme.backingColor, label='net flux: %sWm-2 netGHE: %sWm-2' % (powerSpectrum, effect)) handles.append(fig) @@ -1486,13 +1488,11 @@ def plotPlanetAndComponents(planet, height=None, direction='down', temperatureLi for molecule, color in zip(moleculeList, theme.colorList): yAxis = transmittanceValues[molecule] tempPowerSpectrum = int(integrateSpectrum(yAxis, pi, res=res)) - if direction == 'up': - effect = surfacePower - tempPowerSpectrum - else: - effect = tempPowerSpectrum + + effect = surfacePower - tempPowerSpectrum fig, = plt.plot(xAxis, yAxis, linewidth=linewidth, color=color, alpha=.6, - label='%s effect : %sWm-2' % (molecule, effect)) + label='%s effect: %sWm-2' % (molecule, effect)) handles.append(fig) legend = plt.legend(handles=handles, frameon=False) text = legend.get_texts() From 2a856bbcf7e735374474ec270d35b5bdaa3a0c43 Mon Sep 17 00:00:00 2001 From: brad schrag Date: Fri, 16 Nov 2018 15:49:19 -0600 Subject: [PATCH 31/43] added effective emissivity. Going to add this into saved transmission data later --- pyradClasses.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pyradClasses.py b/pyradClasses.py index 5cc67a5..a884748 100644 --- a/pyradClasses.py +++ b/pyradClasses.py @@ -702,6 +702,10 @@ def emissivity(self): def emittance(self): return self.emissivity + @property + def effectiveEmissivity(self): + return np.average(self.emissivity) + @property def P(self): return self.layer.P @@ -848,6 +852,10 @@ def emissivity(self): def emittance(self): return self.emissivity + @property + def effectiveEmissivity(self): + return np.average(self.emissivity) + @property def molarMass(self): mass = 0 From 93ddfd10c5f844f0cb98440f4abb495b9c988188 Mon Sep 17 00:00:00 2001 From: brad schrag Date: Mon, 19 Nov 2018 23:15:50 -0600 Subject: [PATCH 32/43] updated the saved data to include a few more items. Molecule concentration, emissivity, and a normalized emissivity for each layer and moelcule --- pyrad.py | 1 - pyradClasses.py | 70 +++++++++++++++++++++++++++++++---------------- pyradUtilities.py | 21 ++++++++++++-- 3 files changed, 65 insertions(+), 27 deletions(-) diff --git a/pyrad.py b/pyrad.py index 71dabe1..b51b4fa 100644 --- a/pyrad.py +++ b/pyrad.py @@ -595,7 +595,6 @@ def buildProfile(profileList): "This takes up quite a bit of space and generally isn't needed. %s" % util.limeText('(y/n)')) overwrite = True progress, time = util.profileProgress(planet.folderPath) - print('progress: %s' % progress) if util.profileComplete(planet.folderPath): overwrite = pyradClasses.yesOrNo("Data for this profile and setting seems to exist.\n" "Do you wish to overwrite it? %s" % util.limeText('(y/n)')) diff --git a/pyradClasses.py b/pyradClasses.py index a884748..5f42795 100644 --- a/pyradClasses.py +++ b/pyradClasses.py @@ -125,12 +125,19 @@ def processTransmissionBySingleLayer(folderPath, res=1): if xAxis is None: xAxis = np.linspace(planet.rangeMin, planet.rangeMax, len(layer.absorptionCoefficient)) surfaceSpectrum = pyradPlanck.planckWavenumber(xAxis, planet.surfaceTemperature) - spectrumDict = {folderPath: reduceRes(surfaceSpectrum, finalRes=res)} + spectrumDict = {folderPath: reduceRes(surfaceSpectrum, finalRes=res), + 'temperature': layer.T, + 'pressure': layer.P, + 'depth': layer.depth, + 'meanHeight': layer.meanHeight} for molecule in planet.moleculeList: - spectrumDict[molecule] = reduceRes(surfaceSpectrum, finalRes=res) + spectrumDict['%s transmission' % molecule] = reduceRes(surfaceSpectrum, finalRes=res) + spectrumDict['%s concentration' % molecule] = layerProfile['%s concentration' % molecule] utils.writePlanetTransmission(folderPath, 0, spectrumDict, 'down', 0) surfaceSpectrum = layer.transmission(surfaceSpectrum) - spectrumDict = {folderPath: reduceRes(surfaceSpectrum, finalRes=res)} + spectrumDict = {'%s transmission' % folderPath: reduceRes(surfaceSpectrum, finalRes=res), + '%s layer effective emissivity' % folderPath: layer.effectiveEmissivity, + '%s layer normalized emissivity' % folderPath: layer.normalizedEmissivity} utils.writePlanetTransmission(folderPath, layer.meanHeight, spectrumDict, 'down', i) heightList.append(layer.meanHeight) @@ -141,13 +148,16 @@ def processTransmissionBySingleLayer(folderPath, res=1): for i in range(1, fileLength + 1): moleculeProfile = utils.readPlanetProfileMolecule(folderPath, i, fileLength, molecule) - molLayer = Layer(moleculeProfile['depth'], moleculeProfile['T'], moleculeProfile['P'], moleculeProfile['rangeMin'], moleculeProfile['rangeMax'], height=moleculeProfile['height'], + layer = Layer(moleculeProfile['depth'], moleculeProfile['T'], moleculeProfile['P'], moleculeProfile['rangeMin'], moleculeProfile['rangeMax'], height=moleculeProfile['height'], name=moleculeProfile['name']) - molLayer.absorptionCoefficient = np.asarray(moleculeProfile['absCoef']) - molLayer.progressAbsCoef = True - spectrumDict[molecule] = reduceRes(molLayer.transmission(surfaceSpectrum)) - surfaceSpectrum = molLayer.transmission(surfaceSpectrum) - utils.writePlanetTransmission(folderPath, molLayer.meanHeight, spectrumDict, 'down', i, mode='ab') + layer.absorptionCoefficient = np.asarray(moleculeProfile['absCoef']) + layer.progressAbsCoef = True + spectrumDict['%s transmission' % molecule] = reduceRes(layer.transmission(surfaceSpectrum)) + spectrumDict['%s effective emissivity' % molecule] = layer.effectiveEmissivity + spectrumDict['%s normalized emissivity' % molecule] = layer.normalizedEmissivity + spectrumDict['%s concentration' % molecule] = moleculeProfile['%s concentration' % molecule] + surfaceSpectrum = layer.transmission(surfaceSpectrum) + utils.writePlanetTransmission(folderPath, layer.meanHeight, spectrumDict, 'down', i, mode='ab') # with transmission from surface upward processed, do the same in reverse to get the transmission toward the surface # initial spectrum will be 2.7K for CMB @@ -159,14 +169,16 @@ def processTransmissionBySingleLayer(folderPath, res=1): for i in range(1, fileLength + 1): fileNumber = fileLength + 1 - i - layerProfile= utils.readPlanetProfile(folderPath, fileNumber, fileLength) + layerProfile = utils.readPlanetProfile(folderPath, fileNumber, fileLength) layer = Layer(layerProfile['depth'], layerProfile['T'], layerProfile['P'], layerProfile['rangeMin'], layerProfile['rangeMax'], height=layerProfile['height'], name=layerProfile['name']) layer.absorptionCoefficient = np.asarray(layerProfile['absCoef']) layer.progressAbsCoef = True surfaceSpectrum = layer.transmission(surfaceSpectrum) - spectrumDict = {folderPath: reduceRes(surfaceSpectrum, finalRes=res)} + spectrumDict = {'%s transmission' % folderPath: reduceRes(surfaceSpectrum, finalRes=res), + '%s layer effective emissivity' % folderPath: layer.effectiveEmissivity, + '%s layer nomrmalized emissivity' % folderPath: layer.normalizedEmissivity} utils.writePlanetTransmission(folderPath, layer.meanHeight, spectrumDict, 'up', i) for molecule in planet.moleculeList: @@ -175,13 +187,16 @@ def processTransmissionBySingleLayer(folderPath, res=1): for i in range(1, fileLength + 1): fileNumber = fileLength + 1 - i moleculeProfile = utils.readPlanetProfileMolecule(folderPath, fileNumber, fileLength, molecule) - molLayer = Layer(moleculeProfile['depth'], moleculeProfile['T'], moleculeProfile['P'], moleculeProfile['rangeMin'], moleculeProfile['rangeMax'], height=moleculeProfile['height'], + layer = Layer(moleculeProfile['depth'], moleculeProfile['T'], moleculeProfile['P'], moleculeProfile['rangeMin'], moleculeProfile['rangeMax'], height=moleculeProfile['height'], name=moleculeProfile['name']) - molLayer.absorptionCoefficient = np.asarray(moleculeProfile['absCoef']) - molLayer.progressAbsCoef = True - spectrumDict[molecule] = reduceRes(molLayer.transmission(surfaceSpectrum), finalRes=res) - utils.writePlanetTransmission(folderPath, molLayer.meanHeight, spectrumDict, 'up', i, mode='ab') - surfaceSpectrum = molLayer.transmission(surfaceSpectrum) + layer.absorptionCoefficient = np.asarray(moleculeProfile['absCoef']) + layer.progressAbsCoef = True + spectrumDict['%s transmission' % molecule] = reduceRes(layer.transmission(surfaceSpectrum), finalRes=res) + spectrumDict['%s effective emissivity' % molecule] = layer.effectiveEmissivity + spectrumDict['%s normalized emissivity' % molecule] = layer.normalizedEmissivity + spectrumDict['%s concentration' % molecule] = moleculeProfile['%s concentration' % molecule] + utils.writePlanetTransmission(folderPath, layer.meanHeight, spectrumDict, 'up', i, mode='ab') + surfaceSpectrum = layer.transmission(surfaceSpectrum) utils.profileWriteTransmissionComplete(folderPath, heightList) return @@ -856,6 +871,17 @@ def emittance(self): def effectiveEmissivity(self): return np.average(self.emissivity) + @property + def normalizedEmissivity(self): + normalized = np.array([]) + emissivity = self.emissivity + nonzeroIndex = np.nonzero(emissivity) + if np.size(nonzeroIndex) == 0: + return 0 + for i in nonzeroIndex: + normalized = np.append(normalized, emissivity[i]) + return np.average(normalized) + @property def molarMass(self): mass = 0 @@ -1420,7 +1446,7 @@ def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=( elif not heightFlag and direction == 'up': height = 0 transmissionValues = readTransmissionFromFile(height, planets[0], direction=direction) - totalY = transmissionValues[planets[0]] + totalY = transmissionValues[planets[0] + ' transmission'] xAxis = np.linspace(transmissionValues['rangeMin'], transmissionValues['rangeMax'], len(totalY)) for temperature, color in zip(temperatureList, theme.colorList[1:]): @@ -1439,7 +1465,7 @@ def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=( elif not heightFlag and direction == 'up': height = 0 transmissionValues = readTransmissionFromFile(height, planet, direction) - totalY = transmissionValues[planet] + totalY = transmissionValues[planet + ' transmission'] powerSpectrum = round(integrateSpectrum(totalY, pi, res=res), 2) effTemp = int(stefanB(powerSpectrum)) fig, = plt.plot(xAxis, totalY, linewidth=linewidth, color=color, label='%s : %sWm-2, eff : %sK' % (planet, powerSpectrum, effTemp)) @@ -1469,7 +1495,7 @@ def plotPlanetAndComponents(planet, height=None, direction='down', temperatureLi elif not heightFlag and direction == 'up': height = 0 transmittanceValues = readTransmissionFromFile(height, planet, direction=direction) - yTotal = transmittanceValues[planet] + yTotal = transmittanceValues[planet + ' transmission'] xAxis = np.linspace(transmittanceValues['rangeMin'], transmittanceValues['rangeMax'], len(yTotal)) for temperature, color in zip(temperatureList, theme.colorList[1:]): yAxis = pyradPlanck.planckWavenumber(xAxis, float(temperature)) @@ -1494,7 +1520,7 @@ def plotPlanetAndComponents(planet, height=None, direction='down', temperatureLi handles.append(fig) moleculeList = transmittanceValues['molList'].split(',') for molecule, color in zip(moleculeList, theme.colorList): - yAxis = transmittanceValues[molecule] + yAxis = transmittanceValues[molecule + ' transmission'] tempPowerSpectrum = int(integrateSpectrum(yAxis, pi, res=res)) effect = surfacePower - tempPowerSpectrum @@ -1509,8 +1535,6 @@ def plotPlanetAndComponents(planet, height=None, direction='down', temperatureLi return - - HITRAN_GLOBAL_ISO = {1: {1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 129}, 2: {1: 7, 2: 8, 3: 9, 4: 10, 5: 11, 6: 12, 7: 13, 8: 14, 9: 121, 10: 15, 11: 120, 12: 122}, 3: {1: 16, 2: 17, 3: 18, 4: 19, 5: 20}, diff --git a/pyradUtilities.py b/pyradUtilities.py index e91738b..810f1f0 100644 --- a/pyradUtilities.py +++ b/pyradUtilities.py @@ -225,8 +225,10 @@ def writePlanetProfile(name, layer, processingTime, moleculeList, moleculeSpecif for molecule in layer: text1 = '# %s abs coef\n' % molecule.name text2 = '%s absCoef: %s\n' % (molecule.name, ','.join(map(str, molecule.absCoef.tolist()))) + text3 = '%s concentration: %s\n' % (molecule.name, molecule.concentration) openFile.write(text1.encode('utf-8')) openFile.write(text2.encode('utf-8')) + openFile.write(text3.encode('utf-8')) openFile.close() print('\t\t\t\t\t\t ||> %s.pyr' % layer.name, end='\r', flush=True) return @@ -240,9 +242,19 @@ def writePlanetTransmission(name, height, values, direction, number, mode='wb'): text = '# PyRad v%s transmission file\n' \ '# layer height for this file is %s\n' % (VERSION, height) openfile.write(text.encode('utf-8')) + text = '# general layer data is listed below this line. Other data contained within this file is\n' \ + '# the reduced transmission for the layer and each molecule that is part of the atmosphere.\n' \ + '# Effective emissivity for is the avg emissivity, normalized is the avg with zeroes removed.\n#\n' + openfile.write(text.encode('utf-8')) for item in values: - text = '%s: %s\n' % (item, ','.join(map(str, values[item]))) + try: + iter(values[item]) + value = ','.join(map(str, values[item])) + except TypeError: + value = values[item] + text = '%s: %s\n' % (item, value) openfile.write(text.encode('utf-8')) + openfile.write('#\n'.encode('utf-8')) openfile.close() return @@ -592,7 +604,8 @@ def readPlanetProfileMolecule(name, layerNumber, length, moleculeName): layerDict['absCoef'] = absCoefList elif keyValue[0].strip() == 'T' or keyValue[0] == 'rangeMin' or keyValue[0] == 'rangeMax': layerDict[keyValue[0]] = int(keyValue[1]) - elif keyValue[0].strip() == 'P' or keyValue[0].strip() == 'height' or keyValue[0].strip() == 'depth': + elif keyValue[0].strip() == 'P' or keyValue[0].strip() == 'height' or keyValue[0].strip() == 'depth' \ + or keyValue[0].strip() == '%s concentration' % moleculeName: layerDict[keyValue[0]] = float(keyValue[1]) else: pass @@ -627,7 +640,8 @@ def readPlanetProfile(name, layerNumber, length): layerDict['absCoef'] = absCoefList elif keyValue[0].strip() == 'T' or keyValue[0] == 'rangeMin' or keyValue[0] == 'rangeMax': layerDict[keyValue[0]] = int(keyValue[1]) - elif keyValue[0].strip() == 'P' or keyValue[0].strip() == 'height' or keyValue[0].strip() == 'depth': + elif keyValue[0].strip() == 'P' or keyValue[0].strip() == 'height' or keyValue[0].strip() == 'depth' \ + or 'concentration' in keyValue[0]: layerDict[keyValue[0]] = float(keyValue[1]) else: pass @@ -699,6 +713,7 @@ def getQData(isotope): downloadQData(isotope) return readQFile(isotope) + # downloads a table of isotopes and data from hitran def downloadMolParam(): print('Missing molecule parameters file. Downloading from http://hitran.org') From 47719a9c9d2490d8aef047ec94b3b44bf28b9b3f Mon Sep 17 00:00:00 2001 From: brad schrag Date: Tue, 20 Nov 2018 15:31:47 -0600 Subject: [PATCH 33/43] added attribution to PyRad and the user that created the plot. Currently the username can't be overridden. Need to add a config file to store some on launch default values. username will be one of these. --- pyradClasses.py | 23 +++++++++++++++++------ pyradUtilities.py | 4 +++- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/pyradClasses.py b/pyradClasses.py index 5f42795..e707f46 100644 --- a/pyradClasses.py +++ b/pyradClasses.py @@ -3,6 +3,7 @@ import pyradIntensity import pyradPlanck import numpy as np +import matplotlib.patches as mpatches import matplotlib.pyplot as plt import time @@ -1354,6 +1355,7 @@ def plot(propertyToPlot, title, plotList, fill=False): plt.margins(0.01) plt.subplots_adjust(left=.07, bottom=.08, right=.97, top=.90) plt.ylabel(propertyToPlot) + plt.text(650, .5, '%s' % settings.userName, verticalalignment='bottom', horizontalalignment='right', color=theme.textColor, fontsize=8) if propertyToPlot == 'line survey': plt.yscale('log') plt.grid(theme.gridList[0], linewidth=.5, linestyle=':') @@ -1369,7 +1371,9 @@ def plot(propertyToPlot, title, plotList, fill=False): plt.fill_between(singlePlot.xAxis, fillAxis, yAxis, color=color, alpha=.3 * fill) linewidth = .7 alpha = .5 - legend = plt.legend(handles=handles, frameon=False) + credit = 'PyRad v%s\n%s' % (utils.VERSION, settings.userName) + handles.append(mpatches.Patch(color='none', label=credit)) + legend = plt.legend(handles=handles, frameon=False, loc=4, ncol=4) text = legend.get_texts() plt.setp(text, color=theme.textColor) plt.show() @@ -1422,7 +1426,9 @@ def plotSpectrum(layer=None, title=None, rangeMin=None, rangeMax=None, objList=N handles.append(fig) alpha = 1 linewidth = 1 - legend = plt.legend(handles=handles, frameon=False) + credit = 'PyRad v%s\n%s' % (utils.VERSION, settings.userName) + handles.append(mpatches.Patch(color='none', label=credit)) + legend = plt.legend(handles=handles, frameon=False, loc=4, ncol=4) text = legend.get_texts() plt.setp(text, color=theme.textColor) plt.show() @@ -1436,6 +1442,8 @@ def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=( plt.subplots_adjust(left=.07, bottom=.08, right=.97, top=.90) plt.ylabel('Radiance Wm-2sr-1(cm-1)-1') plt.grid(theme.gridList[0], linewidth=.5, linestyle=':') + plt.text(0.95, 0.01, '%s' % settings.userName, verticalalignment='bottom', horizontalalignment='right', + transform=plt.transAxes, color=theme.textColor, fontsize=8) handles = [] heightFlag = True @@ -1470,8 +1478,9 @@ def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=( effTemp = int(stefanB(powerSpectrum)) fig, = plt.plot(xAxis, totalY, linewidth=linewidth, color=color, label='%s : %sWm-2, eff : %sK' % (planet, powerSpectrum, effTemp)) handles.append(fig) - - legend = plt.legend(handles=handles, frameon=False) + credit = 'PyRad v%s\n%s' % (utils.VERSION, settings.userName) + handles.append(mpatches.Patch(color='none', label=credit)) + legend = plt.legend(handles=handles, frameon=False, loc=4, ncol=4) text = legend.get_texts() plt.setp(text, color=theme.textColor) plt.show() @@ -1516,7 +1525,7 @@ def plotPlanetAndComponents(planet, height=None, direction='down', temperatureLi effect = surfacePower - powerSpectrum fig, = plt.plot(xAxis, yTotal, linewidth=linewidth, color=theme.backingColor, - label='net flux: %sWm-2 netGHE: %sWm-2' % (powerSpectrum, effect)) + label='net flux: %sWm-2' % powerSpectrum) handles.append(fig) moleculeList = transmittanceValues['molList'].split(',') for molecule, color in zip(moleculeList, theme.colorList): @@ -1528,7 +1537,9 @@ def plotPlanetAndComponents(planet, height=None, direction='down', temperatureLi fig, = plt.plot(xAxis, yAxis, linewidth=linewidth, color=color, alpha=.6, label='%s effect: %sWm-2' % (molecule, effect)) handles.append(fig) - legend = plt.legend(handles=handles, frameon=False) + credit = 'PyRad v%s\n%s' % (utils.VERSION, settings.userName) + handles.append(mpatches.Patch(color='none', label=credit)) + legend = plt.legend(handles=handles, frameon=False, loc=4, ncol=4) text = legend.get_texts() plt.setp(text, color=theme.textColor) plt.show() diff --git a/pyradUtilities.py b/pyradUtilities.py index 810f1f0..396c4f2 100644 --- a/pyradUtilities.py +++ b/pyradUtilities.py @@ -60,9 +60,10 @@ def listOfThemes(self): class Settings: - def __init__(self, setting): + def __init__(self, setting, userName='@bradschrag'): self.setting = setting self.reduceRes = True + self.userName = userName def changeSetting(self, value): self.setting = value @@ -70,6 +71,7 @@ def changeSetting(self, value): def changeResReduce(self, bool): self.reduceRes = bool + @property def baseRes(self): if self.setting == 'low': From 9a5b09487d77ee27adef6112394fbcaf06b622a1 Mon Sep 17 00:00:00 2001 From: brad schrag Date: Tue, 27 Nov 2018 18:08:24 -0600 Subject: [PATCH 34/43] found and fixed a memory leak that was occurring when transmission files were being processed and created. --- earthsimple.pyr | 4 +-- pyradClasses.py | 72 ++++++++++++++++++++++++++-------------- pyradUtilities.py | 84 ++++++++++++++++++++++++++--------------------- 3 files changed, 97 insertions(+), 63 deletions(-) diff --git a/earthsimple.pyr b/earthsimple.pyr index 610a80a..5ab3971 100644 --- a/earthsimple.pyr +++ b/earthsimple.pyr @@ -1,7 +1,7 @@ # A demo file for pyrad -# mBar , K , km, m , g, cm-1,cm-1 -surface: 1013.25, 288, 120, 100, 9.8, 00, 2000 +# mBar , K , km, m , g, +surface: 1013.25, 288, 120, 100, 9.8 # mol text name, concentration molecule: co2, .000400 diff --git a/pyradClasses.py b/pyradClasses.py index e707f46..0ab1973 100644 --- a/pyradClasses.py +++ b/pyradClasses.py @@ -6,6 +6,8 @@ import matplotlib.patches as mpatches import matplotlib.pyplot as plt import time +from pympler import tracker +import gc c = 299792458.0 @@ -23,6 +25,7 @@ theme = utils.Theme() + def reduceRes(array, finalRes=1.0): n = int(finalRes / settings.baseRes) length = int(len(array) * settings.baseRes / finalRes) @@ -102,6 +105,7 @@ def readTransmissionFromFile(requestedHeight, folderPath, direction): def processTransmissionBySingleLayer(folderPath, res=1): + memoryTracker = tracker.SummaryTracker() # first process transmission upward. Need to get initial values, mostly just for surface temp values = utils.readCompleteProfile(folderPath) planet = Planet(values['name'], float(values['surfacePressure']), int(values['surfaceTemperature']), @@ -115,11 +119,16 @@ def processTransmissionBySingleLayer(folderPath, res=1): xAxis = None fileLength = utils.profileLength(folderPath) heightList = [0] - + layer = Layer(0, 0, 0, 0, 0) for i in range(1, fileLength + 1): layerProfile = utils.readPlanetProfile(folderPath, i, fileLength) - layer = Layer(layerProfile['depth'], layerProfile['T'], layerProfile['P'], layerProfile['rangeMin'], layerProfile['rangeMax'], height=layerProfile['height'], - name=layerProfile['name']) + layer.depth = layerProfile['depth'] + layer.P = layerProfile['P'] + layer.T = layerProfile['T'] + layer.rangeMin = layerProfile['rangeMin'] + layer.rangeMax = layerProfile['rangeMax'] + layer.height = layerProfile['height'] + layer.name = layerProfile['name'] layer.absorptionCoefficient = np.asarray(layerProfile['absCoef']) layer.progressAbsCoef = True @@ -141,24 +150,29 @@ def processTransmissionBySingleLayer(folderPath, res=1): '%s layer normalized emissivity' % folderPath: layer.normalizedEmissivity} utils.writePlanetTransmission(folderPath, layer.meanHeight, spectrumDict, 'down', i) heightList.append(layer.meanHeight) + gc.collect() heightList.append(planet.maxHeight) for molecule in planet.moleculeList: surfaceSpectrum = pyradPlanck.planckWavenumber(xAxis, planet.surfaceTemperature) - spectrumDict = {} for i in range(1, fileLength + 1): moleculeProfile = utils.readPlanetProfileMolecule(folderPath, i, fileLength, molecule) - - layer = Layer(moleculeProfile['depth'], moleculeProfile['T'], moleculeProfile['P'], moleculeProfile['rangeMin'], moleculeProfile['rangeMax'], height=moleculeProfile['height'], - name=moleculeProfile['name']) + layer.depth = layerProfile['depth'] + layer.P = moleculeProfile['P'] + layer.T = moleculeProfile['T'] + layer.rangeMin = moleculeProfile['rangeMin'] + layer.rangeMax = moleculeProfile['rangeMax'] + layer.height = moleculeProfile['height'] + layer.name = moleculeProfile['name'] layer.absorptionCoefficient = np.asarray(moleculeProfile['absCoef']) layer.progressAbsCoef = True - spectrumDict['%s transmission' % molecule] = reduceRes(layer.transmission(surfaceSpectrum)) - spectrumDict['%s effective emissivity' % molecule] = layer.effectiveEmissivity - spectrumDict['%s normalized emissivity' % molecule] = layer.normalizedEmissivity - spectrumDict['%s concentration' % molecule] = moleculeProfile['%s concentration' % molecule] + spectrumDict = {'%s transmission' % molecule: reduceRes(layer.transmission(surfaceSpectrum)), + '%s effective emissivity' % molecule: layer.effectiveEmissivity, + '%s normalized emissivity' % molecule: layer.normalizedEmissivity, + '%s concentration' % molecule: moleculeProfile['%s concentration' % molecule]} surfaceSpectrum = layer.transmission(surfaceSpectrum) utils.writePlanetTransmission(folderPath, layer.meanHeight, spectrumDict, 'down', i, mode='ab') + gc.collect() # with transmission from surface upward processed, do the same in reverse to get the transmission toward the surface # initial spectrum will be 2.7K for CMB @@ -171,33 +185,45 @@ def processTransmissionBySingleLayer(folderPath, res=1): for i in range(1, fileLength + 1): fileNumber = fileLength + 1 - i layerProfile = utils.readPlanetProfile(folderPath, fileNumber, fileLength) - layer = Layer(layerProfile['depth'], layerProfile['T'], layerProfile['P'], layerProfile['rangeMin'], - layerProfile['rangeMax'], height=layerProfile['height'], - name=layerProfile['name']) + layer.depth = layerProfile['depth'] + layer.P = layerProfile['P'] + layer.T = layerProfile['T'] + layer.rangeMin = layerProfile['rangeMin'] + layer.rangeMax = layerProfile['rangeMax'] + layer.height = layerProfile['height'] + layer.name = layerProfile['name'] layer.absorptionCoefficient = np.asarray(layerProfile['absCoef']) layer.progressAbsCoef = True surfaceSpectrum = layer.transmission(surfaceSpectrum) spectrumDict = {'%s transmission' % folderPath: reduceRes(surfaceSpectrum, finalRes=res), '%s layer effective emissivity' % folderPath: layer.effectiveEmissivity, - '%s layer nomrmalized emissivity' % folderPath: layer.normalizedEmissivity} + '%s layer normalized emissivity' % folderPath: layer.normalizedEmissivity} utils.writePlanetTransmission(folderPath, layer.meanHeight, spectrumDict, 'up', i) + gc.collect() for molecule in planet.moleculeList: surfaceSpectrum = pyradPlanck.planckWavenumber(xAxis, 2.7) - spectrumDict = {} + for i in range(1, fileLength + 1): fileNumber = fileLength + 1 - i moleculeProfile = utils.readPlanetProfileMolecule(folderPath, fileNumber, fileLength, molecule) - layer = Layer(moleculeProfile['depth'], moleculeProfile['T'], moleculeProfile['P'], moleculeProfile['rangeMin'], moleculeProfile['rangeMax'], height=moleculeProfile['height'], - name=moleculeProfile['name']) + layer.depth = layerProfile['depth'] + layer.P = moleculeProfile['P'] + layer.T = moleculeProfile['T'] + layer.rangeMin = moleculeProfile['rangeMin'] + layer.rangeMax = moleculeProfile['rangeMax'] + layer.height = moleculeProfile['height'] + layer.name = moleculeProfile['name'] layer.absorptionCoefficient = np.asarray(moleculeProfile['absCoef']) layer.progressAbsCoef = True - spectrumDict['%s transmission' % molecule] = reduceRes(layer.transmission(surfaceSpectrum), finalRes=res) - spectrumDict['%s effective emissivity' % molecule] = layer.effectiveEmissivity - spectrumDict['%s normalized emissivity' % molecule] = layer.normalizedEmissivity - spectrumDict['%s concentration' % molecule] = moleculeProfile['%s concentration' % molecule] + spectrumDict = {'%s transmission' % molecule: reduceRes(layer.transmission(surfaceSpectrum), finalRes=res), + '%s effective emissivity' % molecule: layer.effectiveEmissivity, + '%s normalized emissivity' % molecule: layer.normalizedEmissivity, + '%s concentration' % molecule: moleculeProfile['%s concentration' % molecule]} utils.writePlanetTransmission(folderPath, layer.meanHeight, spectrumDict, 'up', i, mode='ab') surfaceSpectrum = layer.transmission(surfaceSpectrum) + gc.collect() + utils.profileWriteTransmissionComplete(folderPath, heightList) return @@ -1442,8 +1468,6 @@ def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=( plt.subplots_adjust(left=.07, bottom=.08, right=.97, top=.90) plt.ylabel('Radiance Wm-2sr-1(cm-1)-1') plt.grid(theme.gridList[0], linewidth=.5, linestyle=':') - plt.text(0.95, 0.01, '%s' % settings.userName, verticalalignment='bottom', horizontalalignment='right', - transform=plt.transAxes, color=theme.textColor, fontsize=8) handles = [] heightFlag = True diff --git a/pyradUtilities.py b/pyradUtilities.py index 396c4f2..ee91e1d 100644 --- a/pyradUtilities.py +++ b/pyradUtilities.py @@ -2,6 +2,8 @@ import sys import urllib.request as urlrequest import urllib.error as urlexception +import gc +from pympler import tracker from datetime import datetime @@ -17,6 +19,8 @@ debuggerFile.write(bytes('%s\n' % now.strftime("%Y-%m-%d %H:%M:%S"), 'utf-8')) debuggerFile.close() +mytracker = tracker.SummaryTracker() + class Theme: def __init__(self, value='dark'): @@ -60,10 +64,14 @@ def listOfThemes(self): class Settings: + + userName = "@bradschrag" + def __init__(self, setting, userName='@bradschrag'): self.setting = setting self.reduceRes = True self.userName = userName + Settings.userName = userName def changeSetting(self, value): self.setting = value @@ -190,13 +198,14 @@ def writeTheme(fullPath): def openReturnLines(fullPath): if not os.path.isfile(fullPath): return False - openFile = open(fullPath) - lineList = openFile.readlines() - openFile.close() + with open(fullPath, 'r') as data: + lineList = data.readlines() + if not lineList or NULL_TAG in lineList[0]: return False while lineList[0][0] == '#' and len(lineList) > 1: lineList.pop(0) + gc.collect() return lineList @@ -206,10 +215,10 @@ def writePlanetProfile(name, layer, processingTime, moleculeList, moleculeSpecif os.mkdir(folderPath) filePath = '%s/%s.pyr' % (folderPath, layer.name) now = datetime.now() - openFile = open(filePath, 'wb') - text = '# created by PyRad v%s on %s.\n' % (VERSION, now.strftime("%Y-%m-%d %H:%M:%S")) - openFile.write(text.encode('utf-8')) - text = ('time: %ssecs\n' + with open(filePath, 'wb') as openFile: + text = '# created by PyRad v%s on %s.\n' % (VERSION, now.strftime("%Y-%m-%d %H:%M:%S")) + openFile.write(text.encode('utf-8')) + text = ('time: %ssecs\n' 'depth: %s\n' 'T: %s\n' 'P: %s\n' @@ -222,16 +231,15 @@ def writePlanetProfile(name, layer, processingTime, moleculeList, moleculeSpecif 'layer absCoef: %s\n' % (int(processingTime), layer.depth, int(layer.T), layer.P, layer.rangeMin, layer.rangeMax, layer.height, layer.name, ','.join(moleculeList), ','.join(map(str, layer.absCoef.tolist())))) - openFile.write(text.encode('utf-8')) - if moleculeSpecific: - for molecule in layer: - text1 = '# %s abs coef\n' % molecule.name - text2 = '%s absCoef: %s\n' % (molecule.name, ','.join(map(str, molecule.absCoef.tolist()))) - text3 = '%s concentration: %s\n' % (molecule.name, molecule.concentration) - openFile.write(text1.encode('utf-8')) - openFile.write(text2.encode('utf-8')) - openFile.write(text3.encode('utf-8')) - openFile.close() + openFile.write(text.encode('utf-8')) + if moleculeSpecific: + for molecule in layer: + text1 = '# %s abs coef\n' % molecule.name + text2 = '%s absCoef: %s\n' % (molecule.name, ','.join(map(str, molecule.absCoef.tolist()))) + text3 = '%s concentration: %s\n' % (molecule.name, molecule.concentration) + openFile.write(text1.encode('utf-8')) + openFile.write(text2.encode('utf-8')) + openFile.write(text3.encode('utf-8')) print('\t\t\t\t\t\t ||> %s.pyr' % layer.name, end='\r', flush=True) return @@ -239,25 +247,25 @@ def writePlanetProfile(name, layer, processingTime, moleculeList, moleculeSpecif def writePlanetTransmission(name, height, values, direction, number, mode='wb'): folderPath = '%s/%s' % (profileDir, name) filePath = '%s/%s.pyr' % (folderPath, 'trans looking %s-%s' % (direction, number)) - openfile = open(filePath, mode) - if mode == 'wb': - text = '# PyRad v%s transmission file\n' \ - '# layer height for this file is %s\n' % (VERSION, height) - openfile.write(text.encode('utf-8')) - text = '# general layer data is listed below this line. Other data contained within this file is\n' \ - '# the reduced transmission for the layer and each molecule that is part of the atmosphere.\n' \ - '# Effective emissivity for is the avg emissivity, normalized is the avg with zeroes removed.\n#\n' - openfile.write(text.encode('utf-8')) - for item in values: - try: - iter(values[item]) - value = ','.join(map(str, values[item])) - except TypeError: - value = values[item] - text = '%s: %s\n' % (item, value) - openfile.write(text.encode('utf-8')) - openfile.write('#\n'.encode('utf-8')) - openfile.close() + with open(filePath, mode) as openFile: + if mode == 'wb': + text = '# PyRad v%s transmission file\n' \ + '# layer height for this file is %s\n' % (VERSION, height) + openFile.write(text.encode('utf-8')) + text = '# general layer data is listed below this line. Other data contained within this file is\n' \ + '# the reduced transmission for the layer and each molecule that is part of the atmosphere.\n' \ + '# Effective emissivity for is the avg emissivity, normalized is the avg with zeroes removed.\n#\n' + openFile.write(text.encode('utf-8')) + for item in values: + try: + iter(values[item]) + value = ','.join(map(str, values[item])) + except TypeError: + value = values[item] + text = '%s: %s\n' % (item, value) + openFile.write(text.encode('utf-8')) + openFile.write('#\n'.encode('utf-8')) + gc.collect() return @@ -909,7 +917,7 @@ def displayAllMolecules(): 'regularCyan': '\x1b[0;36;48m', 'colorEnd': '\x1b[0m'} -VERSION = '3.0' +VERSION = '3.01' titleLine = "%s****************** PyRad v%s ******************%s" \ % (TEXT_COLORS['underlineCyan'], VERSION, TEXT_COLORS['colorEnd']) messageGap = int((len(titleLine) - len(VERSION) - 1) / 2) @@ -1082,5 +1090,7 @@ def displayAllMolecules(): 'textColor': (239, 244, 255), 'gridColor': (204, 204, 204)}} +CREDIT = credit = 'PyRad v%s\n%s' % (VERSION, Settings.userName) + print(GREETING) setupDir() From 9b798c3f7902d04e40ce68c2fa8911a9b1b007de Mon Sep 17 00:00:00 2001 From: brad schrag Date: Sun, 2 Dec 2018 13:55:21 -0600 Subject: [PATCH 35/43] few more updates. bug when saving the transmission by molecule. --- pyrad.py | 2 +- pyradClasses.py | 68 +++++++++++++++++++++++++++-------------------- pyradUtilities.py | 6 ++--- 3 files changed, 43 insertions(+), 33 deletions(-) diff --git a/pyrad.py b/pyrad.py index b51b4fa..18e0bab 100644 --- a/pyrad.py +++ b/pyrad.py @@ -662,7 +662,7 @@ def menuMain(): def settingsMenu(previousMenu=menuMain): lowSetting = Entry('low (intensity > 1e-21)', nextFunction=changeSettings, functionParams=('low', previousMenu)) midSetting = Entry('mid (intensity > 1e-24)', nextFunction=changeSettings, functionParams=('mid', previousMenu)) - hiSetting = Entry('hi (all absorption lines)', nextFunction=changeSettings, functionParams=('hi', previousMenu)) + hiSetting = Entry('high (all absorption lines)', nextFunction=changeSettings, functionParams=('high', previousMenu)) loadTheme = Entry('Change theme', nextMenu=chooseThemeMenu, functionParams=previousMenu) menuSettings = Menu('Choose level of detail', [lowSetting, midSetting, hiSetting, loadTheme], previousMenu=previousMenu) return menuSettings diff --git a/pyradClasses.py b/pyradClasses.py index 0ab1973..830b91e 100644 --- a/pyradClasses.py +++ b/pyradClasses.py @@ -6,7 +6,6 @@ import matplotlib.patches as mpatches import matplotlib.pyplot as plt import time -from pympler import tracker import gc @@ -21,10 +20,13 @@ sb = 5.67E-8 -settings = utils.Settings('low') +settings = utils.Settings('high') theme = utils.Theme() +def stefanB(power): + return (power / sb) ** .25 + def reduceRes(array, finalRes=1.0): n = int(finalRes / settings.baseRes) @@ -105,8 +107,7 @@ def readTransmissionFromFile(requestedHeight, folderPath, direction): def processTransmissionBySingleLayer(folderPath, res=1): - memoryTracker = tracker.SummaryTracker() - # first process transmission upward. Need to get initial values, mostly just for surface temp + values = utils.readCompleteProfile(folderPath) planet = Planet(values['name'], float(values['surfacePressure']), int(values['surfaceTemperature']), float(values['maxHeight']), @@ -156,20 +157,20 @@ def processTransmissionBySingleLayer(folderPath, res=1): for molecule in planet.moleculeList: surfaceSpectrum = pyradPlanck.planckWavenumber(xAxis, planet.surfaceTemperature) for i in range(1, fileLength + 1): - moleculeProfile = utils.readPlanetProfileMolecule(folderPath, i, fileLength, molecule) + layerProfile = utils.readPlanetProfileMolecule(folderPath, i, fileLength, molecule) layer.depth = layerProfile['depth'] - layer.P = moleculeProfile['P'] - layer.T = moleculeProfile['T'] - layer.rangeMin = moleculeProfile['rangeMin'] - layer.rangeMax = moleculeProfile['rangeMax'] - layer.height = moleculeProfile['height'] - layer.name = moleculeProfile['name'] - layer.absorptionCoefficient = np.asarray(moleculeProfile['absCoef']) + layer.P = layerProfile['P'] + layer.T = layerProfile['T'] + layer.rangeMin = layerProfile['rangeMin'] + layer.rangeMax = layerProfile['rangeMax'] + layer.height = layerProfile['height'] + layer.name = layerProfile['name'] + layer.absorptionCoefficient = np.asarray(layerProfile['absCoef']) layer.progressAbsCoef = True spectrumDict = {'%s transmission' % molecule: reduceRes(layer.transmission(surfaceSpectrum)), '%s effective emissivity' % molecule: layer.effectiveEmissivity, '%s normalized emissivity' % molecule: layer.normalizedEmissivity, - '%s concentration' % molecule: moleculeProfile['%s concentration' % molecule]} + '%s concentration' % molecule: layerProfile['%s concentration' % molecule]} surfaceSpectrum = layer.transmission(surfaceSpectrum) utils.writePlanetTransmission(folderPath, layer.meanHeight, spectrumDict, 'down', i, mode='ab') gc.collect() @@ -206,20 +207,20 @@ def processTransmissionBySingleLayer(folderPath, res=1): for i in range(1, fileLength + 1): fileNumber = fileLength + 1 - i - moleculeProfile = utils.readPlanetProfileMolecule(folderPath, fileNumber, fileLength, molecule) + layerProfile = utils.readPlanetProfileMolecule(folderPath, fileNumber, fileLength, molecule) layer.depth = layerProfile['depth'] - layer.P = moleculeProfile['P'] - layer.T = moleculeProfile['T'] - layer.rangeMin = moleculeProfile['rangeMin'] - layer.rangeMax = moleculeProfile['rangeMax'] - layer.height = moleculeProfile['height'] - layer.name = moleculeProfile['name'] - layer.absorptionCoefficient = np.asarray(moleculeProfile['absCoef']) + layer.P = layerProfile['P'] + layer.T = layerProfile['T'] + layer.rangeMin = layerProfile['rangeMin'] + layer.rangeMax = layerProfile['rangeMax'] + layer.height = layerProfile['height'] + layer.name = layerProfile['name'] + layer.absorptionCoefficient = np.asarray(layerProfile['absCoef']) layer.progressAbsCoef = True spectrumDict = {'%s transmission' % molecule: reduceRes(layer.transmission(surfaceSpectrum), finalRes=res), '%s effective emissivity' % molecule: layer.effectiveEmissivity, '%s normalized emissivity' % molecule: layer.normalizedEmissivity, - '%s concentration' % molecule: moleculeProfile['%s concentration' % molecule]} + '%s concentration' % molecule: layerProfile['%s concentration' % molecule]} utils.writePlanetTransmission(folderPath, layer.meanHeight, spectrumDict, 'up', i, mode='ab') surfaceSpectrum = layer.transmission(surfaceSpectrum) gc.collect() @@ -1082,12 +1083,17 @@ def compositionAtHeight(self, height, molecule): return concentration return molecule.concentration - def densityAtHeight(self, height, gasConstant): + def densityAtHeight(self, height): + gasConstant = self.planet.specGasConstant temperature = self.temperatureAtHeight(height) pressure = self.pressureAtHeight(height) density = pressure * 100 / gasConstant / temperature return density + def moleculesAtHeight(self, height): + density = self.densityAtHeight(height) + return density / self.planet.molarMass / 1000 * avo + class Planet: def __init__(self, name, pressure, temperature, maxHeight, @@ -1281,6 +1287,10 @@ def folderPath(self): def molarMass(self): return self.initialLayer.molarMass / 1000 + @property + def specGasConstant(self): + return R * 1000 / self.molarMass + @property def xAxis(self): return np.linspace(self.rangeMin, self.rangeMax, (self.rangeMax - self.rangeMin) / utils.BASE_RESOLUTION, @@ -1297,9 +1307,9 @@ def atmChangePoints(self): def transmission(self): return self.processTransmission(self.maxHeight) - -def stefanB(power): - return (power / sb) ** .25 + @property + def moleculesAtHeight(self, height): + return self.atmosphere.moleculesAtHeight(height) class AtmosphereRule: @@ -1378,7 +1388,7 @@ def plot(propertyToPlot, title, plotList, fill=False): plt.figure(figsize=(10, 6), dpi=80) plt.subplot(111, facecolor=theme.faceColor) plt.xlabel('wavenumber cm-1') - plt.margins(0.01) + plt.margins(0.1) plt.subplots_adjust(left=.07, bottom=.08, right=.97, top=.90) plt.ylabel(propertyToPlot) plt.text(650, .5, '%s' % settings.userName, verticalalignment='bottom', horizontalalignment='right', color=theme.textColor, fontsize=8) @@ -1464,7 +1474,7 @@ def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=( linewidth = 1 plt.figure(figsize=(10, 6), dpi=80) plt.subplot(111, facecolor=theme.faceColor) - plt.margins(0.01) + plt.margins(x=0.01, y=.2) plt.subplots_adjust(left=.07, bottom=.08, right=.97, top=.90) plt.ylabel('Radiance Wm-2sr-1(cm-1)-1') plt.grid(theme.gridList[0], linewidth=.5, linestyle=':') @@ -1514,7 +1524,7 @@ def plotPlanetAndComponents(planet, height=None, direction='down', temperatureLi linewidth = 1 plt.figure(figsize=(10, 6), dpi=80) plt.subplot(111, facecolor=theme.faceColor) - plt.margins(0.01) + plt.margins(x=0.01, y=.2) plt.subplots_adjust(left=.05, bottom=.05, right=.97, top=.95) plt.grid(theme.gridList[0], linewidth=.5, linestyle=':') plt.ylabel('radiance Wm-2sr-1(cm-1)-1') diff --git a/pyradUtilities.py b/pyradUtilities.py index ee91e1d..f7b56be 100644 --- a/pyradUtilities.py +++ b/pyradUtilities.py @@ -86,7 +86,7 @@ def baseRes(self): return .01 elif self.setting == 'mid': return .01 - elif self.setting == 'hi': + elif self.setting == 'high': return .01 @property @@ -95,7 +95,7 @@ def lineIntensityCutoff(self): return 1E-21 elif self.setting == 'mid': return 1E-24 - elif self.setting == 'hi': + elif self.setting == 'high': return 0.0 @property @@ -104,7 +104,7 @@ def smoothing(self): return 1 elif self.setting == 'mid': return 50 - elif self.setting == 'hi': + elif self.setting == 'high': return 100 From cd68b682ef4c01fc86ca15adfd4708440d922226 Mon Sep 17 00:00:00 2001 From: brad schrag Date: Thu, 6 Dec 2018 10:10:24 -0600 Subject: [PATCH 36/43] getting the profiles created for making a comparison to other LBL from Conner et al 2006 --- atmProfiles.py | 351 +++++++++++++++++++++++++++++++++++++++++++++ mls summer 286.pyr | 76 ++++++++++ mls summer 369.pyr | 76 ++++++++++ mls summer.pyr | 76 ++++++++++ pyrad.py | 5 +- pyradUtilities.py | 6 +- 6 files changed, 585 insertions(+), 5 deletions(-) create mode 100644 atmProfiles.py create mode 100644 mls summer 286.pyr create mode 100644 mls summer 369.pyr create mode 100644 mls summer.pyr diff --git a/atmProfiles.py b/atmProfiles.py new file mode 100644 index 0000000..c8828a6 --- /dev/null +++ b/atmProfiles.py @@ -0,0 +1,351 @@ +# the following atm profiles were pulled from Anderson et al 1986. While this file won't be directly utilized +# by PyRad, the data from these profiles will be used for testing and creating some .pyr profiles for users to build +# from. + +# original paper can be found at: +# https://www.researchgate.net/publication/235054307_AFGL_Atmospheric_Constituent_Profiles_0120km + +# Dictionary {'profile name': {surface temp: , +# list of heights: , +# list of pressures: , +# list of temperatures: , +# list of mol density: , +# list of h2o MR: , +# list of o3 MR: , +# list of n2o MR: , +# list of co MR: , +# list of ch4 MR: , + +from matplotlib import pyplot as plt + +ATM_PROFILES = {'tropical': {'surface temp': 299.7, + 'heights': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, + 23, 24, 25, 27.5, 30, 32.5, 35, 37.5, 40, 42.5, 45, 47.5, 50, 55, 60, 65, 70, + 75, 80, 85, 90, 95, 100, 105, 110, 115, 120], + 'pressure': [1.013e3, 9.040e2, 8.05e2, 7.15e2, 6.33e2, 5.59e2, 4.92e2, 4.32e2, 3.78e2, + 3.29e2, 2.86e2, 2.47e2, 2.13e2, 1.82e2, 1.56e2, 1.32e2, 1.11e2, 93.7, 78.9, + 66.6, 56.5, 48.0, 40.9, 35.0, 30, 25.7, 17.63, 12.2, 8.52, 6, 4.26, 3.05, 2.2, + 1.59, 1.16, .854, .456, .239, .121, 5.8e-2, 2.6e-2, 1.1e-2, 4.4e-3, 1.72e-3, + 6.88e-4, 2.89e-4, 1.3e-4, 6.47e-5, 3.6e-5, 2.25e-5], + 'temp': [299.7, 293.7, 287.7, 283.7, 277, 270.3, 263.6, 257.0, 250.3, 243.6, 237.0, 230.1, + 223.6, + 217.0, 210.3, 203.7, 197.0, 194.8, 198.8, 202.7, 206.7, 210.7, 214.6, 217.0, + 219.2, 221.4, 227.0, 232.3, 237.7, 243.1, 248.5, 254.0, 259.4, 264.8, 269.6, + 270.2, 263.4, 253.1, 236.0, 218.9, 201.8, 184.8, 177.1, 177.0, 184.3, 190.7, + 212.0, 241.6, 299.7, 380], + 'mol density': [2.45E19, 2.231E19, 2.028E19, 1.827E19, 1.656E19, 1.499E19, 1.353E19, + 1.218E19, 1.098E19, 9.789E18, 8.747E18, 7.780E18, 6.904E18, 6.079E18, + 5.377E18, 4.697E18, 4.084E18, 3.486E18, 2.877E18, 2.381E18, 1.981E18, + 1.651E18, 1.381E18, 1.169e18, 9.920E17, 8.413E17, 5.629E17, 3.807E17, + 2.598E17, 1.789E17, 1.243E17, 8.703E16, 6.147E16, 4.352E16, 3.119E16, + 2.291E16, 1.255E16, 6.844E15, 3.716E15, 1.920E15, 9.338E14, 4.314E14, + 1.801E14, 7.043E13, 2.706E13, 1.098E13, 4.445E12, 1941E12, 8.706E11, + 4.225E11], + 'h2o': [2.59E4, 1.95E4, 1.53E4, 8.60E3, 4.44E3, 3.35E3, 2.1E3, 1.29E3, 7.64E2, 4.1E2, + 1.91E2, 7.31E1, 2.91E1, 9.9E0, 6.22E0, 4E0, 3E0, 2.9E0, 2.75E0, 2.60E0, 2.6E0, + 2.65E0, 2.8E0, 2.9E0, 3.2E0, 3.25E0, 3.6E0, 4E0, 4.3, 4.6, 4.9, 5.2, 5.5, 5.7, 5.9, + 6, 6, 6, 5.4, 4.5, 3.3, 2.1, 1.3, 8.5E-1, 5.4E-1, 4.0E-1, 3.4E-1, 2.8E-1, 2.4E-1, + 2.0E-1], + 'o3': [2.87e-2, 3.15e-2, 3.34e-2, 3.5e-2, 3.55e-2, 3.77e-2, 3.99e-2, 4.22e-2, 4.47e-2, + 5.0e-2, 56e-2, 6.61e-2, 7.82e-2, 9.29e-2, 1.05e-1, 1.26e-1, 1.44e-1, 2.5e-1, 5.0e-1, + 9.5e-1, 1.4, 1.8, 2.4, 3.4, 4.3, 5.4, 7.8, 9.3, 9.85, 9.7, 8.8, 7.5, 5.9, 4.5, 3.45, + 2.8, 1.8, 1.1, 6.5e-1, 3.0e-1, 1.8e-1, 3.3e-1, 5e-1, 5.2e-1, 5e-1, 4e-1, 2e-1, 5e-2, + 5e-3, 5e-4], + 'n2o': [.32, .32, .32, .32, .32, .32, .32, .32, .32, .32, .318, .314, .310, .05, .3, .294, + .288, .28, .267, .253, .237, .219, .205, .197, .188, .176, .159, .142, .117, .0928, + .0698, .0451, .0275, .0159, 9.38e-3, 4.75e-3, 3e-3, 2.07e-3, 1.51e-3, 1.15e-3, + 8.89e-4, 7.046e-4, 5.72e-4, 4.71e-4, 3.93e-4, 3.32e-4, 2.84e-4, 2.44e-4, 2.12e-4, + 1.85e-4], + 'co': [.15, .145, .140, .135, .131, .130, .129, .125, .119, .109, 9.96e-2, 8.92e-2, + 7.81e-2, + 6.37e-2, 5.03e-2, 3.94e-2, 3.07e-2, 2.49e-2, 1.97e-2, 1.55e-2, 1.33e-2, 1.23e-2, + 1.23e-2, 1.31e-2, 1.4e-2, 1.52e-2, 1.72e-2, 2e-2, 2.27e-2, 2.49e-2, 2.74e-2, 3.1e-2, + 3.51e-2, 3.99e-2, 4.48e-2, 5.09e-2, 5.99e-2, 6.96e-2, 9.19e-2, .194, .569, 1.55, + 3.85, 6.59, 10.4, 17.1, 24.7, 33.6, 51.5, 50], + 'ch4': [.17, .17, .17, .17, .17, .17, .17, .17, .17, .169, .169, .168, .166, .165, .163, + .161, .158, .155, .152, .148, .142, .136, .12, .119, .112, .106, 9.87e-1, 9.14e-1, + 8.3e-1, 7.46e-1, 6.62e-1, 5.64e-1, 4.61e-1, 3.63e-1, 2.77e-1, 2.1e-1, 1.65e-1, + 1.5e-1, 1.5e-1, 1.5e-1, 1.5e-1, 1.5e-1, 1.5e-1, 1.4e-1, 1.3e-1, 1.2e-1, 1.1e-1, + 9.5e-2, 6e-2, 3e-2]}, + 'midlatitude summer': {'surface temp': 294.2, + 'heights': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 27.5, 30, 32.5, 35, 37.5, 40, 42.5, 45, 47.5, + 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120], + 'temp': [294.2, 289.7, 285.2, 279.2, 273.2, 267.2, 261.2, 254.7, 248.2, 241.7, + 235.3, 228.8, 222.3, 215.8, 215.7, 215.7, 215.7, 215.7, 216.8, 217.9, + 219.2, 220.4, 221.6, 222.8, 223.9, 225.1, 228.5, 233.7, 239.0, 245.2, + 251.3, 257.5, 263.7, 269.9, 275.2, 275.7, 269.3, 257.1, 240.1, 218.1, + 196.1, 174.1, 165.1, 165.0, 178.3, 190.5, 222.2, 262.4, 316.8, 380], + 'pressure': [1.013e3, 9.020e2, 8.020e2, 7.1e2, 6.28e2, 5.54e2, 4.87e2, 4.26e2, + 3.72e2, 3.24e2, 2.81e2, 2.43e2, 2.090e2, 1.79e2, 1.53e2, 1.3e2, + 1.11e2, 95, 81.2, 96.5, 59.5, 51.0, 43.7, 37.6, 32.2, 27.7, 19.07, + 13.2, 9.3, 6.52, 4.64, 3.33, 2.41, 1.76, 1.29, .951, .515, .272, + .139, 6.7e-2, 3e-2, 1.2e-2, 4.48e-3, 1.64e-3, 6.24e-4, 2.58e-4, + 1.17e-4, 6.11e-5, 3.56e-5, 2.27e-5], + 'mol density': [2.496e19, 2.257e19, 2.038e19, 1.843e19, 1.666e19, 1.503e19, + 1.351e19, 1.212e19, 1.806e19, 9.716e18, 8.656e18, 7.698e18, + 6.814e18, 6.012e18, 5.141e18, 4.368e18, 3.73e18, 3.192e18, + 2.715e18, 2.312e18, 1.967e18, 1.677e18, 1.429e18, 1.223e18, + 1.042e18, 8.919e17, 6.050e17, 4.094e17, 2.82e17, 1.927e17, + 1.338e17, 9.373e16, 6.624e16, 4.726e16, 3.398e16, 2.500e16, + 1.3868e16, 7.668e15, 4.2196e15, 2.227e15, 1.109e15, 4.996e14, + 1.967e14, 7.204e13, 2.541e13, 9.816e12, 3.816e12, 1.688e12, + 8.145e11, 4.330e11], + 'h2o': [1.88e4, 1.38e4, 9.68e3, 5.68e3, 3.81e3, 2.23e3, 1.51e3, 1.02e3, 6.46e2, + 4.13e2, 2.47e2, 95.6, 29.4, 8, 5, 3.4, 3.3, 3.2, 3.15, 3.2, 3.3, 3.45, + 3.6, 3.85, 4, 4.2, 4.45, 4.7, 4.85, 4.95, 5, 5.1, 5.3, 5.45, 5.5, 5.5, + 5.35, 5, 4.4, 3.7, 2.95, 2.1, 1.33, .85, .54, .4, .34, .28, .24, .2], + 'o3': [3.02e-2, 3.34e-2, 3.69e-2, 4.22e-2, 4.82e-2, 5.51e-2, 6.41e-2, 7.76e-2, + 9.13e-2, .111, .130, .179, .223, .300, .440, .500, .600, .700, 1, 1.5, 2, + 2.4, 2.9, 3.4, 4, 4.8, 6, 7, 8.1, 8.9, 8.7, 7.55, 5.90, 4.5, 3.5, 2.8, + 1.8, + 1.3, .8, .4, .19, .2, .57, .75, .7, .4, .2, .05, .005, .0005], + 'n2o': [.32, .32, .32, .32, .32, .32, .32, .32, .32, .316, .310, .299, .294, + .286, .280, .272, .261, .242, .217, .184, .161, .132, .115, .105, + 9.62e-2, 8.96e-2, 8.01e-2, 6.7e-2, 4.96e-2, 3.7e-2, 2.52e-2, 1.74e-2, + 1.16e-2, 7.67e-3, 5.32e-3, 3.22e-3, 2.03e-3, 1.4e-3, 1.02e-3, 7.77e-4, + 6.26e-4, 5.17e-4, 4.35e-4, 3.73e-4, 3.24e-4, 2.84e-4, 2.52e-4, 2.26e-4, + 2.04e-4, 1.85e-4], + 'co': [.15, .145, .14, .135, .131, .130, .129, .125, .119, .109, 9.96e-2, + 8.96e-2, + 7.81e-2, 6.3e-2, 5.03e-2, 3.94e-2, 3.07e-2, 2.49e-2, 1.97e-2, 1.55e-2, + 1.33e-2, 1.23e-2, 1.23e-2, 1.31e-2, 1.4e-2, 1.51e-2, 1.72e-2, 2e-2, + 2.27e-2, 2.49e-2, 2.72e-2, 2.96e-2, 3.14e-2, 3.31e-2, 3.49e-2, 3.65e-2, + 3.92e-2, 4.67e-2, 6.4e-2, .118, .294, .682, 1.47, 2.85, 5.14, 10.1, 18.7, + 28.6, 38.9, 50], + 'ch4': [1.7, 1.7, 1.7, 1.7, 1.7, 1.69, 1.57, 1.65, 1.63, 1.62, 1.58, 1.54, 1.51, + 1.48, 1.45, 1.42, 1.39, 1.36, 1.32, 1.28, 1.22, 1.15, 1.07, .973, .880, + .789, .705, .632, .559, .501, .445, .392, .339, .287, .238, .194, .157, + .150, .15, .15, .15, .15, .15, .14, .13, .12, .11, .095, .06, .03]}, + 'midlatitude winter': {'surface temp': 272.2, + 'heights': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 27.5, 30, 32.5, 35, 37.5, 40, 42.5, + 45, 47.5, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, + 110, 115, 120], + 'pressure': [1.18e3, 8.973e2, 7.897e2, 6.938e2, 6.081e2, 5.313e2, 4.627e2, + 4.016e2, 3.473e2, 2.993e2, 2.568e2, 2.199e2, 1.882e2, 1.611e2, + 1.378e2, 1.178e2, 1.002e2, 86.1, 73.6, 62.8, 53.7, 45.8, 39.1, 33.4, + 28.6, 24.4, 16.46, 11.1, 7.56, 5.18, 3.6, 2.53, 1.80, 1.29, .94, + .683, .362, .188, 9.5e-2, 4.7e-2, 2.22e-2, 1.03e-2, 4.56e-3, + 1.98e-3, + 8.77e-4, 4.074e-4, 2e-4, 1.057e-4, 5.98e-5, 3.6e-5], + 'temp': [272.2, 268., 265.2, 261.7, 255.7, 249.7, 243.7, 237.7, 231.7, 225.7, + 219.7, 219.2, 218.7, 218.2, 217.7, 217.2, 216.7, 216.2, 215.7, 215.2, + 215.2, 215.2, 215.2, 215.2, 215.2, 215.2, 215.5, 21.4, 220.4, 227.9, + 235.5, 243.2, 250.8, 258.5, 265.1, 265.7, 260.6, 250.8, 240.9, 230.7, + 220.4, 210.1, 199.8, 199.5, 208.3, 218.6, 237.1, 259.5, 293, 333], + 'mol density': [2.711e19, 2.42e19, 2.158e19, 1.922e19, 1.724e19, 1.542e19, + 1.376e19, 1.225e19, 1.086e19, 9.612e18, 8.472e18, 7.271e18, + 6.237e18, 5.351e18, 4.588e18, 3.931e18, 3.366e18, 2.886e18, + 2.473e18, 2.115e18, 1.809e18, 1.543e18, 1.317e18, 1.125e18, + 9.633e17, 8.218e17, 5.536e17, 3.701e17, 2.486e17, 1.647e1, + 1.108e17, 7.540e16, 5.202e16, 3.61e16, 2.570e16, 1.863e16, + 1.007e16, 5.433e15, 2.858e15, 1.477e15, 7.301e14, 3.553e14, + 1.654e14, 7.194e13, 3.052e13, 1.351e13, 6.114e12, 2.952e12, + 1.479e12, 7.836e11], + 'h2o': [4.32e3, 3.45e33, 2.9e3, 2.09e3, 1.28e3, 8.24e2, 5.1e2, 2.32e2, 1.08e2, + 55.7, 29.6, 10, 6, 5, 4.8, 4.7, 4.6, 4.5, 4.5, 4.5, 4.5, 4.5, 4.53, 4.55, + 4.60, 4.65, 4.7, 4.75, 4.8, 4.85, 4.9, 4.95, 5, 5, 5, 4.95, 4.85, 4.5, + 4.0, 3.3, 2.7, 2, 1.33, .85, .54, .4, .34, .28, .24, .2], + 'o3': [2.78e-2, 2.8e-2, 2.85e-2, 3.2e-2, 3.57e-2, 4.72e-2, 5.84e-2, 7.89e-2, + .104, + .15, .237, .362, .523, .04, .8, .9, 1.1, 1.4, 1.8, 2.3, 2.9, 3.5, 3.9, + 4.3, + 4.7, 5.1, 5.6, 6.1, 6.8, 7.1, 7.2, 6.9, 5.9, 4.6, 3.7, 2.75, 1.7, 1, .55, + .32, .25, .23, .55, .8, .8, .4, .2, .05, .005, .0005], + 'n2o': [.32, .32, .32, .32, .32, .32, .32, .32, .32, .316, .310, .299, .294, + .286, + .280, .22, .261, .242, .21, .184, .162, .136, .123, .112, .105, 9.66e-2, + 8.69e-2, 7.52e-2, 6.13e-2, 5.12e-2, 3.97e-2, 3.0e-2, 2.08e-2, 1.31e-2, + 8.07e-3, 4.16e-3, 2.63e-3, 1.81e-3, 1.32e-3, 1.01e-3, 7.88e-4, 6.33e-4, + 5.19e-4, 4.33e-4, 3.67e-4, 3.14e-4, 2.72e-4, 2.37e-4, 2.0e-4, 1.85e-4], + 'co': [.15, .145, .140, .135, .131, .130, .129, .125, .1119, .109, 9.96e-2, + 8.96e-2, 7.81e-2, 6.3e-2, 5.03e-2, 3.94e-2, 3.07e-2, 2.49e-2, 1.97e-2, + 1.55e-2, 1.33e-2, 1.23e-2, 1.23e-2, 1.31e-2, 1.4e-2, 1.5e-2, 1.6e-2, + 1.71e-2, 1.85e-2, 2.0e-2, 2.15e-2, 2.33e-2, 2.62e-2, 3.06e-2, 3.8e-2, + 6.25e-2, .148, .293, .559, 1.08, 1.9, 2.96, 4.53, 6.86, 10.5, 17.1, 24.7, + 33.6, 41.5, 50], + 'ch4': [1.7, 1.7, 1.7, 1.7, 1.7, 1.69, 1.67, 1.65, 1.32, 1.32, 1.58, 1.54, 1.51, + 1.48, 1.45, 1.42, 1.39, 1.36, 1.32, 1.28, 1.22, 1.15, 1.07, .973, .880, + .793, .713, .644, .575, .505, .448, .393, .340, .288, .239, .194, .157, + .15, .15, .15, .15, .15, .15, .14, .13, .12, .11, .095, .06, .03]}, + 'subarctic summer': {'surface temp': 287.2, + 'heights': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 27.5, 30, 32.5, 35, 37.5, 40, 42.5, + 45, 47.5, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, + 110, 115, 120], + 'pressure': [1.01e3, 8.96e2, 7.929e2, 7e2, 6.16e2, 5.41e2, 4.74e2, 4.13e2, 3.59e2, + 3.108e2, 2.677e2, 2.3e2, 1.977e2, 1.7e2, 1.46e2, 1.26e2, 1.08e2, 92.8, + 79.8, 68.6, 59.0, 50.7, 43.6, 37.5, 32.28, 27.80, 19.23, 13.4, 9.4, + 6.61, 4.72, 3.4, 2.48, 1.82, 1.34, .987, .537, .288, .147, 7.1e-2, + 3.2e-2, 1.25e-2, 4.51e-3, 1.61e-3, 6.06e-4, 2.48e-4, 1.13e-4, 6.0e-5, + 3.54e-5, 2.26e-5], + 'temp': [287.2, 281.7, 276.3, 270.9, 265.5, 260.1, 253.1, 246.1, 239.2, 232.2, + 225.5, 225.2, 225.2, 225.2, 225.2, 225.2, 225.2, 225.2, 225.2, 225.2, + 225.2, 225.2, 225.2, 225.2, 226.6, 228.1, 231.0, 235.1, 240, 24.2, 254.6, + 262.1, 269.5, 273.6, 276.2, 277.2, 274, 262.7, 239.7, 216.6, 193.6, 10.6, + 161., 161.6, 176.8, 194.4, 226, 270.1, 322.7, 380], + 'mol density': [2.459e19, 2.305e19, 2.080e19, 1.873e19, 1.682e19, 1.508e19, + 1.357e19, + 1.216e19, 1.088e19, 9.701e18, 8.616e18, 7.402e18, 6.363e18, + 5.471e18, + 4.699e18, 4.055e18, 3.476e18, 2.987e18, 2.568e18, 2.20e18, + 1.899e18, + 1.632e18, 1.403e18, 1.207e18, 1.033e18, 8.834e17, 6.034e17, + 4.131e17, + 2.839e17, 1.938e17, 1.344e17, 9.402e16, 6.670e16, 4.821e16, + 3.513e16, + 2.581e16, 1.421e16, 7.946e15, 4.445e15, 2.376e15, 1.1198e15, + 5.311e14, + 2.022e14, 7.221e13, 2.484e13, 9.441e12, 3.624e12, 1.610e12, + 7.951e11, + 4.311e11], + 'h2o': [1.19e4, 8.7e3, 6.75e3, 4.82e3, 3.38e3, 2.22e3, 1.33e3, 7.97e2, 4e2, 1.3e2, + 42.4, 13.3, 6, 4.45, 4, 4, 4, 4.05, 4.3, 4.5, 4.6, 4.7, 4.8, 4.83, 4.85, + 4.9, 4.95, 5, 5, 5, 5, 5, 5, 5, 5, 4.95, 4.85, 4.5, 4., 3.3, 2.7, 2, 1.33, + .85, .54, .4, .34, .28, .24, .2], + 'o3': [2.41e-2, 2.94e-2, 3.38e-2, 3.89e-2, 4.48e-2, 5.33e-2, 6.56e-2, 7.74e-2, + 9.11e-2, .142, .189, .305, .41, .5, .6, .7, .85, 1, 1.3, 1.7, 2.1, 2.7, 3.3, + 3.7, 4.2, 4.5, 5.3, 5.7, 6.9, 7.7, 7.8, 7, 5.4, 4.2, 3.2, 2.5, 1.7, 1.2, .8, + .4, .2, .18, .65, .9, .8, .4, .2, .05, .005, .0005], + 'n2o': [.31, .31, .31, .31, .308, .302, .291, .282, .276, .270, .265, .260, .255, + .249, .243, .236, .228, .218, .204, .182, .157, .135, .122, .110, 9.89e-2, + 8.78e-2, 7.33e-2, 5.94e-2, 4.15e-2, 3.03e-2, 1.95e-2, 1.27e-2, 9e-3, + 6.29e-3, 4.56e-3, 2.8e-3, 1.77e-3, 1.21e-3, 8.87e-4, 6.76e-4, 5.54e-4, + 4.65e-4, 3.68e-4, 3.46e-4, 3.05e-4, 2.71e-4, 2.44e-4, 2.21e-4, 2.02e-4, + 1.85e-4], + 'co': [.15, .145, .14, .135, .131, .130, .129, .125, .119, .109, 9.96e-2, 8.96e-2, + 7.81e-2, 6.37e-2, 5.03e-2, 3.94e-2, 3.07e-2, 2.49e-2, 1.97e-2, 1.55e-2, + 1.33e-2, 1.23e-2, 1.23e-2, 1.31e-2, 1.4e-2, 1.51e-2, 1.65e-2, 1.81e-2, 2e-2, + 2.18e-2, 2.34e-2, 2.5e-2, 2.65e-2, 2.81e-2, 3e-2, 3.22e-2, 3.65e-2, 4.59e-2, + 6.38e-2, .18, .303, .789, 1.82, 3.4, 5.92, 10.4, 18.8, 28.7, 38.9, 50], + 'ch4': [1.7, 1.7, 1.7, 1.7, 1.7, 1.69, 1.67, 1.65, 1.63, 1.32, 1.58, 1.54, 1.51, + 1.47, 1.43, 1.39, 1.34, 1.29, 1.23, 1.16, 1.08, .99, .917, .857, .801, + .748, + .696, .644, .589, .524, .451, .371, .299, .245, .2, .166, .15, .15, .15, + .15, .15, .15, .15, .14, .13, .12, .11, .095, .06, .03]}, + 'subarctic winter': {'surface temp': 257.2, + 'heights': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 27.5, 30, 32.5, 35, 37.5, 40, 42.5, + 45, 47.5, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, + 110, 115, 120], + 'pressure': [1.013e3, 8.878e2, 7.775e2, 6.798e2, 5.932e2, 5.158e2, 4.467e2, + 3.853e2, + 3.308e2, 2.829e2, 2.418e2, 2.067e2, 1.766e2, 1.510e2, 1.291e2, + 1.103e2, + 94.31, 80.58, 68.82, 58.75, 50.14, 42.77, 36.47, 31.09, 26.49, 22.56, + 15.13, 10.20, 6.91, 4.701, 3.23, 2.243, 1.570, 1.113, .79, .5719, + .299, + .155, 7.9e-2, 4e-2, 2e-2, 9.66e-3, 4.5e-3, 2.022e-3, 9.070e-4, + 4.23e-4, + 2.070e-4, 1.080e-4, 6e-5, 3.59e-5], + 'temp': [257.2, 239.1, 255.9, 252.7, 247.7, 240.9, 234.1, 227.3, 220.6, 217.2, + 217.2, 217.2, 217.2, 217.2, 217.2, 217.2, 216.6, 216.0, 215.4, 214.8, + 214.2, 213.6, 213.4, 212.4, 211.8, 211.2, 216.3, 216.0, 218.5, 222.3, + 228.5, 234.7, 240.8, 247.0, 253.2, 259.3, 259.1, 250.9, 248.4, 245.4, + 234.7, 223.9, 213.1, 202.3, 211, 218.5, 234.0, 252.6, 288.5, 333.0], + 'mol density': [2.855e19, 2.484e19, 2.202e19, 1.95e19, 1.736e19, 1.552e19, + 1.383e19, + 1.229e19, 1.087e19, 9.44e18, 8.069e18, 6.898e18, 5.893e18, + 5.039e18, + 4.308e18, 3.681e18, 3.156e18, 2.704e18, 2.316e18, 1.982e18, + 1.697e18, + 1.451e18, 1.241e18, 1.061e18, 9.065e17, 7.742e17, 5.134e17, + 3.423e17, + 2.292e17, 1.533e17, 1.025e17, 6.927e16, 4.726e16, 3.266e16, + 2.261e16, + 1.599e16, 8.364e15, 4.478e15, 2.305e15, 1.181e15, 6.176e14, + 3.127e14, + 1.531e14, 7.244e13, 3.116e13, 1.403e13, 6.412e12, 3.099e12, + 1.507e12, + 7.814e11], + 'h2o': [1.41e3, 1.52e3, 1.43e3, 1.17e3, 9.7e2, 4.31e2, 2.37e2, 1.47e2, 33.8, 29.8, + 20, 10, 6, 4.45, 4.5, 4.55, 4.6, 4.65, 4.7, 4.75, 4.8, 4.85, 4.9, 4.95, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4.95, 4.85, 4.5, 4, 3.3, 2.7, 2, 1.33, .85, + .54, .4, .34, .28, .24, .2], + 'o3': [1.8e-2, 2.07e-2, 2.34e-2, 2.77e-2, 3.25e-2, 3.8e-2, 4.45e-2, 7.25e-2, .104, + .210, .3, .35, .4, .65, .9, 1.2, 1.5, 1.9, 2.45, 3.1, 3.7, 4, 4, .2, 4.5, + 4.6, 4.7, 4.9, 5.4, 5.9, 6.2, 6.25, 5.9, 5.1, 4.1, 3, 2.6, 1.6, .95, .65, + .5, + .33, .13, .75, .8, .8, .8, .4, .2, .05, .005, .0005], + 'n2o': [.32, .32, .32, .32, .32, .32, .32, .32, .32, .316, .31, .299, .294, .286, + .28, .272, .261, .242, .217, .184, .162, .136, .123, .112, .104, 9.57e-2, + 8.6e-2, 7.31e-2, 5.71e-2, .467e-2, 3.44e-2, 2.47e-2, 1.53e-2, 1.07e-2, + 7.06e-3, 3.97e-3, 2.51e-3, 1.73e-3, 1.26e-3, 9.6e-4, 7.55e-4, 6.1e-4, + 5.02e-4, 4.21e-4, 3.58e-4, 3.08e-4, 2.68e-4, 2.35e-4, 2.08e-4, 1.85e-4], + 'co': [.15, .145, .14, .135, .131, .13, .129, .125, .119, .109, .0996, .0896, .078, + .0637, .0503, .0394, .0307, .0249, .0197, .0155, .0133, .0123, .0123, .0131, + .0140, .0152, .0172, .0204, .0249, .0317, .0443, .0647, .104, .151, .216, + .314, .484, .715, 1.07, 1.52, 2.17, 3.06, 4.56, 6.88, 10.6, 17.1, 24.7, + 33.6, + 41.5, 50], + 'ch4': [1.7, 1.7, 1.7, 1.7, 1.7, 1.69, 1.67, 1.65, 1.63, 1.62, 1.58, 1.54, 1.51, + 1.47, 1.43, 1.39, 1.34, 1.29, 1.23, 1.16, 1.05, 1.01, .956, .901, .848, + .796, .745, .694, .643, .588, .524, .451, .371, .3, .245, .198, .159, .15, + .15, .15, .15, .15, .15, .14, .13, .12, .11, .095, .06, .03] + }, + 'us standard atm': {'surface temp': 288.2, + 'heights': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 27.5, 30, 32.5, 35, 37.5, 40, 42.5, + 45, 47.5, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, + 110, 115, 120], + 'pressure': [1.013e3, 8.988e2, 7.95e2, 7.012e2, 6.166e2, 5.405e2, 4.722e2, 4.111e2, + 3.565e2, 3.080e2, 2.65e2, 2.27e2, 1.94e2, 1.658e2, 1.417e2, 1.211e2, + 1.035e2, 88.5, 75.65, 64.67, 55.29, 47.29, 40.47, 34.67, 29.72, 25.49, + 17.43, 11.97, 8.01, 5.746, 5.15, 2.871, 2.060, 1.491, 1.0990, .7975, + .4250, .219, .109, 5.022e-2, 2.4e-2, 1.05e-2, 4.46e-3, 1.84e-3, 7.6e-4, + 3.2e-4, 1.45e-4, 7.1e-5, 4.01e-5, 2.54e-4], + 'temp': [288.2, 281.7, 275.2, 268.7, 262.2, 255.7, 249.2, 242.7, 236.2, 229.7, + 223.3, 216.8, 216.7, 216.7, 216.7, 216.7, 216.7, 216.7, 216.7, 216.7, + 216.7, 217.6, 218.6, 219.6, 220.6, 221.6, 224, 226.5, 230, 236.5, 242.9, + 250.4, 257.3, 264.2, 270.6, 270.7, 260.8, 247, 233.3, 219.6, 208.4, 198.6, + 188.9, 186.9, 188.4, 195.1, 208.8, 240, 300, 360], + 'mol density': [2.548e19, 2.313e19, 2.094e19, 1.891e19, 1.704e19, 1.532e19, + 1.373e19, + 1.228e19, 1.094e19, 9.719e18, 8.602e18, 7.589e18, 6.489e18, + 5.546e18, + 4.739e18, 4.050e18, 3.462e18, 2.960e18, 2.530e18, 2.163e18, + 1.849e18, + 1.575e18, 1.342e18, 1.144e18, 9.765e17, 8.337e17, 5.640e17, 3.83e17, + 2.524e17, 1.761e17, 1.238e17, 8.310e16, 5.803e16, 4.090e16, + 2.920e16, + 2.136e16, 1.181e16, 6.426e15, 3.386e15, 1.723e15, 8.347e14, + 3.832e14, + 1.711e14, 7.136e13, 2.924e13, 1.189e13, 5.033e12, 2.144e12, + 9.688e11, + 5.114e11], + 'h2o': [7.75e3, 5.07e3, 4.63e3, 3.18e3, 2.16e3, 1.4e3, 9.25e2, 5.72e2, 3.67e2, + 1.58e2, 70, 36.1, 19.1, 10.9, 5.93, 5, 3.95, 3.85, 3.83, 3.85, 3.9, 3.98, + 4.07, 4.2, 4.3, 4.43, 4.58, 4.73, 4.83, 4.9, 4.95, 5.03, 5.15, 5.23, 5.25, + 5.23, 5.1, 4.75, 4.2, 3.5, 2.83, 2.05, 1.33, .85, .54, .4, .34, .28, .24, + .2], + 'o3': [.0266, .0293, .0324, .0332, .0339, .0377, .0411, .0501, .0597, .0917, .131, + .215, .310, .385, .503, .651, .870, 1.19, 1.59, 2.03, 2.58, 3.03, 3.65, 4.17, + 4.63, 5.12, 5.8, 6.55, 7.37, 7.84, 7.8, 7.3, 6.2, 5.25, 4.1, 3.1, 1.8, 1.1, + .7, .3, .25, .3, .5, .7, .7, .4, .2, .05, .005, .0005], + 'n2o': [.32, .32, .32, .32, .32, .32, .32, .32, .32, .32, .318, .314, .31, .305, .3, + .294, .288, .278, .267, .253, .237, .219, .205, .197, .188, .176, .159, + .142, .117, .0928, .0669, .0451, .0275, .0159, 9.38e-3, 4.75e-3, 3e-3, + 2.07e-3, 1.51e-3, 1.15e-3, 8.89e-4, 7.06e-4, 5.72e-4, 4.71e-4, 3.93e-4, + 3.32e-4, 2.84e-4, 2.44e-4, 2.12e-4, 1.85e-4], + 'co': [.15, .145, .14, .135, .131, .13, .129, .125, .119, .109, .0996, .0896, .0781, + .0637, .0503, .0394, .0307, .0249, .0197, .0155, .0133, .0123, .0123, .0131, + .0140, .0150, .0160, .0171, .0185, .0201, .0222, .0250, .0282, .0324, .0372, + .046, .0664, .107, .186, .306, .638, 1.5, 3.24, 5.84, 10.1, 16.9, 24.7, 33.6, + 41.5, 50], + 'ch4': [1.7, 1.7, 1.7, 1.7, 1.7, 1.7, 1.7, 1.7, 1.7, 1.69, 1.69, 1.68, 1.66, 1.65, + 1.63, 1.61, 1.58, 1.55, 1.52, 1.46, 1.42, 1.36, 1.27, 1.19, 1.12, 1.06, + .987, + .914, .830, .746, .662, .564, .461, .363, .277, .210, .165, .150, .15, .15, + .15, .15, .15, .14, .13, .12, .11, .095, .06, .03]}} + +properties = ['pressure', 'temp', 'mol density', 'h2o', 'co', 'ch4', 'n2o'] + +region = 'midlatitude summer' +profile = 'ch4' +yAxis = ATM_PROFILES[region]['heights'][20:50] +xAxis = ATM_PROFILES[region][profile][20:50] + +plt.plot(xAxis, yAxis) +plt.show() \ No newline at end of file diff --git a/mls summer 286.pyr b/mls summer 286.pyr new file mode 100644 index 0000000..145d7ef --- /dev/null +++ b/mls summer 286.pyr @@ -0,0 +1,76 @@ +# mid latitude summer from Anderson 1986 + +surface: 1013.25, 294, 120, 100, 9.8 + +molecule: co2, .000287 +molecule: h2o, .018800 +molecule: o3, .00000003 +molecule: n2o, .000000320 +molecule: co, .000000150 +molecule: ch4, .00000170 +molecule: o2, .20 +molecule: n2, .77 +molecule: ar, .009 + +lapse rate: boundary layer troposphere, 2, 285 +lapse rate: troposphere, 13, 216 +lapse rate: tropopause, 17, 215 +lapse rate: lower stratosphere, 27, 228 +lapse rate: stratosphere, 47.5, 275 +lapse rate: stratopause, 50, 276 +lapse rate: lower mesosphere, 55, 269 +lapse rate: mesosphere, 80, 174 +lapse rate: upper mesosphere, 85, 165 +lapse rate: mesopause, 90, 165 +lapse rate: thermosphere, 100, 190 +lapse rate: upper thermosphere, 120, 380 + +composition rate: WV boundary layer, 3, .005691, h2o +composition rate: WV troposphere, 5, .002266, h2o +composition rate: WV trop2, 6, .0015, h2o +composition rate: wv trop 3, 8, .000647, h2o +composition rate: wv tropopause, 11, .000099, h2o +composition rate: wv tropopause2, 12, .000030, h2o +composition rate: wv tropopause3, 13, .0000054, h2o +composition rate: wv stratosphere, 18, .000003, h2o +composition rate: wv strat2, 25, .0000045, h2o +composition rate: wv strat3, 50, .0000055, h2o +composition rate: wv strat3, 60, .000005, h2o +composition rate: wv meso, 90, .00000085, h2o +composition rate: wv thermo, 120, .0000002, h2o + +composition rate: ozone troposphere, 10, .00000013, o3 +composition rate: ozone tropopause, 17, .0000007, o3 +composition rate: ozone strat1, 35, .0000089, o3 +composition rate: ozone meso, 37, .0000087, o3 +composition rate: ozone meso2, 55, .0000017, o3 +composition rate: ozone meso3, 75, .00000018, o3 +composition rate: ozone meso4, 80, .00000018, o3 +composition rate: ozone meso5, 90, .00000076, o3 +composition rate: ozone thermo, 120, 0, o3 + +composition rate: n2o 1, 8, .00000032, n2o +composition rate: n2o 2, 16, .00000026, n2o +composition rate: n2o 3, 20, .00000013, n2o +composition rate: n2o 4, 25, .00000009, n2o +composition rate: n2o 5, 45, .000000008, n2o +composition rate: n2o 6, 120, 0, n2o + +composition rate: co 1, 4, .00000013, co +composition rate: co 2, 6, .000000128, co +composition rate: co 3, 15, .000000038, co +composition rate: co 4, 20, .00000012, co +composition rate: co 5, 60, .00000012, co +composition rate: co 6, 90, .0000029, co +composition rate: co 7, 120, .000050, co + +composition rate: ch4 1, 4, .00000017, ch4 +composition rate: ch4 2, 9, .000000162, ch4 +composition rate: ch4 3, 4, .00000017, ch4 +composition rate: ch4 4, 19, .0000018, ch4 +composition rate: ch4 5, 25, .00000078, ch4 +composition rate: ch4 6, 55, .00000015, ch4 +composition rate: ch4 7, 85, .00000015, ch4 +composition rate: ch4 8, 120,.00000003, ch4 + + diff --git a/mls summer 369.pyr b/mls summer 369.pyr new file mode 100644 index 0000000..6ef3a26 --- /dev/null +++ b/mls summer 369.pyr @@ -0,0 +1,76 @@ +# mid latitude summer from Anderson 1986 + +surface: 1013.25, 294, 120, 100, 9.8 + +molecule: co2, .000369 +molecule: h2o, .018800 +molecule: o3, .00000003 +molecule: n2o, .000000320 +molecule: co, .000000150 +molecule: ch4, .00000170 +molecule: o2, .20 +molecule: n2, .77 +molecule: ar, .009 + +lapse rate: boundary layer troposphere, 2, 285 +lapse rate: troposphere, 13, 216 +lapse rate: tropopause, 17, 215 +lapse rate: lower stratosphere, 27, 228 +lapse rate: stratosphere, 47.5, 275 +lapse rate: stratopause, 50, 276 +lapse rate: lower mesosphere, 55, 269 +lapse rate: mesosphere, 80, 174 +lapse rate: upper mesosphere, 85, 165 +lapse rate: mesopause, 90, 165 +lapse rate: thermosphere, 100, 190 +lapse rate: upper thermosphere, 120, 380 + +composition rate: WV boundary layer, 3, .005691, h2o +composition rate: WV troposphere, 5, .002266, h2o +composition rate: WV trop2, 6, .0015, h2o +composition rate: wv trop 3, 8, .000647, h2o +composition rate: wv tropopause, 11, .000099, h2o +composition rate: wv tropopause2, 12, .000030, h2o +composition rate: wv tropopause3, 13, .0000054, h2o +composition rate: wv stratosphere, 18, .000003, h2o +composition rate: wv strat2, 25, .0000045, h2o +composition rate: wv strat3, 50, .0000055, h2o +composition rate: wv strat3, 60, .000005, h2o +composition rate: wv meso, 90, .00000085, h2o +composition rate: wv thermo, 120, .0000002, h2o + +composition rate: ozone troposphere, 10, .00000013, o3 +composition rate: ozone tropopause, 17, .0000007, o3 +composition rate: ozone strat1, 35, .0000089, o3 +composition rate: ozone meso, 37, .0000087, o3 +composition rate: ozone meso2, 55, .0000017, o3 +composition rate: ozone meso3, 75, .00000018, o3 +composition rate: ozone meso4, 80, .00000018, o3 +composition rate: ozone meso5, 90, .00000076, o3 +composition rate: ozone thermo, 120, 0, o3 + +composition rate: n2o 1, 8, .00000032, n2o +composition rate: n2o 2, 16, .00000026, n2o +composition rate: n2o 3, 20, .00000013, n2o +composition rate: n2o 4, 25, .00000009, n2o +composition rate: n2o 5, 45, .000000008, n2o +composition rate: n2o 6, 120, 0, n2o + +composition rate: co 1, 4, .00000013, co +composition rate: co 2, 6, .000000128, co +composition rate: co 3, 15, .000000038, co +composition rate: co 4, 20, .00000012, co +composition rate: co 5, 60, .00000012, co +composition rate: co 6, 90, .0000029, co +composition rate: co 7, 120, .000050, co + +composition rate: ch4 1, 4, .00000017, ch4 +composition rate: ch4 2, 9, .000000162, ch4 +composition rate: ch4 3, 4, .00000017, ch4 +composition rate: ch4 4, 19, .0000018, ch4 +composition rate: ch4 5, 25, .00000078, ch4 +composition rate: ch4 6, 55, .00000015, ch4 +composition rate: ch4 7, 85, .00000015, ch4 +composition rate: ch4 8, 120,.00000003, ch4 + + diff --git a/mls summer.pyr b/mls summer.pyr new file mode 100644 index 0000000..391e170 --- /dev/null +++ b/mls summer.pyr @@ -0,0 +1,76 @@ +# mid latitude summer from Anderson 1986 + +surface: 1013.25, 294, 120, 100, 9.8 + +molecule: co2, .00033 +molecule: h2o, .018800 +molecule: o3, .00000003 +molecule: n2o, .000000320 +molecule: co, .000000150 +molecule: ch4, .00000170 +molecule: o2, .20 +molecule: n2, .77 +molecule: ar, .009 + +lapse rate: boundary layer troposphere, 2, 285 +lapse rate: troposphere, 13, 216 +lapse rate: tropopause, 17, 215 +lapse rate: lower stratosphere, 27, 228 +lapse rate: stratosphere, 47.5, 275 +lapse rate: stratopause, 50, 276 +lapse rate: lower mesosphere, 55, 269 +lapse rate: mesosphere, 80, 174 +lapse rate: upper mesosphere, 85, 165 +lapse rate: mesopause, 90, 165 +lapse rate: thermosphere, 100, 190 +lapse rate: upper thermosphere, 120, 380 + +composition rate: WV boundary layer, 3, .005691, h2o +composition rate: WV troposphere, 5, .002266, h2o +composition rate: WV trop2, 6, .0015, h2o +composition rate: wv trop 3, 8, .000647, h2o +composition rate: wv tropopause, 11, .000099, h2o +composition rate: wv tropopause2, 12, .000030, h2o +composition rate: wv tropopause3, 13, .0000054, h2o +composition rate: wv stratosphere, 18, .000003, h2o +composition rate: wv strat2, 25, .0000045, h2o +composition rate: wv strat3, 50, .0000055, h2o +composition rate: wv strat3, 60, .000005, h2o +composition rate: wv meso, 90, .00000085, h2o +composition rate: wv thermo, 120, .0000002, h2o + +composition rate: ozone troposphere, 10, .00000013, o3 +composition rate: ozone tropopause, 17, .0000007, o3 +composition rate: ozone strat1, 35, .0000089, o3 +composition rate: ozone meso, 37, .0000087, o3 +composition rate: ozone meso2, 55, .0000017, o3 +composition rate: ozone meso3, 75, .00000018, o3 +composition rate: ozone meso4, 80, .00000018, o3 +composition rate: ozone meso5, 90, .00000076, o3 +composition rate: ozone thermo, 120, 0, o3 + +composition rate: n2o 1, 8, .00000032, n2o +composition rate: n2o 2, 16, .00000026, n2o +composition rate: n2o 3, 20, .00000013, n2o +composition rate: n2o 4, 25, .00000009, n2o +composition rate: n2o 5, 45, .000000008, n2o +composition rate: n2o 6, 120, 0, n2o + +composition rate: co 1, 4, .00000013, co +composition rate: co 2, 6, .000000128, co +composition rate: co 3, 15, .000000038, co +composition rate: co 4, 20, .00000012, co +composition rate: co 5, 60, .00000012, co +composition rate: co 6, 90, .0000029, co +composition rate: co 7, 120, .000050, co + +composition rate: ch4 1, 4, .00000017, ch4 +composition rate: ch4 2, 9, .000000162, ch4 +composition rate: ch4 3, 4, .00000017, ch4 +composition rate: ch4 4, 19, .0000018, ch4 +composition rate: ch4 5, 25, .00000078, ch4 +composition rate: ch4 6, 55, .00000015, ch4 +composition rate: ch4 7, 85, .00000015, ch4 +composition rate: ch4 8, 120,.00000003, ch4 + + diff --git a/pyrad.py b/pyrad.py index 18e0bab..397be9b 100644 --- a/pyrad.py +++ b/pyrad.py @@ -588,11 +588,12 @@ def plotProfileComponentsMenu(param=None): def buildProfile(profileList): + saveAbsData = pyradClasses.yesOrNo("Would you like to save abs coef data?\n" + "This takes up quite a bit of space and generally isn't needed. %s" + % util.limeText('(y/n)')) for profile in profileList: print('Building %s on setting %s' % (profile.name, pyradClasses.settings.setting)) planet = pyradClasses.createCustomPlanet(profile.name) - saveAbsData = pyradClasses.yesOrNo("Would you like to save abs coef data?\n" - "This takes up quite a bit of space and generally isn't needed. %s" % util.limeText('(y/n)')) overwrite = True progress, time = util.profileProgress(planet.folderPath) if util.profileComplete(planet.folderPath): diff --git a/pyradUtilities.py b/pyradUtilities.py index f7b56be..5687564 100644 --- a/pyradUtilities.py +++ b/pyradUtilities.py @@ -86,7 +86,7 @@ def baseRes(self): return .01 elif self.setting == 'mid': return .01 - elif self.setting == 'high': + elif self.setting == 'high' or self.setting == 'hi': return .01 @property @@ -95,7 +95,7 @@ def lineIntensityCutoff(self): return 1E-21 elif self.setting == 'mid': return 1E-24 - elif self.setting == 'high': + elif self.setting == 'high' or self.setting == 'hi': return 0.0 @property @@ -104,7 +104,7 @@ def smoothing(self): return 1 elif self.setting == 'mid': return 50 - elif self.setting == 'high': + elif self.setting == 'high' or self.setting == 'hi': return 100 From 3cbf6471e24ac536a104272a95358cb17a0e3d9c Mon Sep 17 00:00:00 2001 From: brad schrag Date: Thu, 27 Dec 2018 10:39:11 -0600 Subject: [PATCH 37/43] lots of work refining how the data is written, to give better readaiblity and consistency --- atmProfiles.py | 8 +- collins - scenario 1a.pyr | 78 ++++++++++++++ collins - scenario 2a.pyr | 78 ++++++++++++++ collins - scenario 2b.pyr | 78 ++++++++++++++ pyrad.py | 8 +- pyradClasses.py | 213 ++++++++++++++++++++++---------------- pyradUtilities.py | 46 ++++++-- 7 files changed, 401 insertions(+), 108 deletions(-) create mode 100644 collins - scenario 1a.pyr create mode 100644 collins - scenario 2a.pyr create mode 100644 collins - scenario 2b.pyr diff --git a/atmProfiles.py b/atmProfiles.py index c8828a6..1e6587b 100644 --- a/atmProfiles.py +++ b/atmProfiles.py @@ -342,10 +342,10 @@ properties = ['pressure', 'temp', 'mol density', 'h2o', 'co', 'ch4', 'n2o'] -region = 'midlatitude summer' -profile = 'ch4' -yAxis = ATM_PROFILES[region]['heights'][20:50] -xAxis = ATM_PROFILES[region][profile][20:50] +region = 'midlatitude winter' +profile = 'h2o' +yAxis = ATM_PROFILES[region]['heights'] +xAxis = ATM_PROFILES[region][profile] plt.plot(xAxis, yAxis) plt.show() \ No newline at end of file diff --git a/collins - scenario 1a.pyr b/collins - scenario 1a.pyr new file mode 100644 index 0000000..2a8ec6a --- /dev/null +++ b/collins - scenario 1a.pyr @@ -0,0 +1,78 @@ +# mid latitude summer from Anderson 1986 +# these are duplciating scenarios from Collins et al 2006 as a means to validate, or not, PyRad against other LBL's. +# transmission is only processed up to the tropopause, rather than full height and atm constiuents is greatly reduced. + +surface: 1013.25, 294, 120, 100, 9.8 + +molecule: co2, .000287 +molecule: h2o, .018800 +molecule: o2, .20 +molecule: n2, .77 +molecule: ar, .009 +# molecule: ch4, .00000170 + molecule: o3, .00000003 +# molecule: n2o, .000000320 +# molecule: co, .000000150 + +lapse rate: boundary layer troposphere, 2, 285 +lapse rate: troposphere, 13, 216 +lapse rate: tropopause, 17, 215 +lapse rate: lower stratosphere, 27, 228 +lapse rate: stratosphere, 47.5, 275 +lapse rate: stratopause, 50, 276 +lapse rate: lower mesosphere, 55, 269 +lapse rate: mesosphere, 80, 174 +lapse rate: upper mesosphere, 85, 165 +lapse rate: mesopause, 90, 165 +lapse rate: thermosphere, 100, 190 +lapse rate: upper thermosphere, 120, 380 + +composition rate: WV boundary layer, 3, .005691, h2o +composition rate: WV troposphere, 5, .002266, h2o +composition rate: WV trop2, 6, .0015, h2o +composition rate: wv trop 3, 8, .000647, h2o +composition rate: wv tropopause, 11, .000099, h2o +composition rate: wv tropopause2, 12, .000030, h2o +composition rate: wv tropopause3, 13, .0000054, h2o +composition rate: wv stratosphere, 18, .000003, h2o +composition rate: wv strat2, 25, .0000045, h2o +composition rate: wv strat3, 50, .0000055, h2o +composition rate: wv strat3, 60, .000005, h2o +composition rate: wv meso, 90, .00000085, h2o +composition rate: wv thermo, 120, .0000002, h2o + +composition rate: ozone troposphere, 10, .00000013, o3 +composition rate: ozone tropopause, 17, .0000007, o3 +composition rate: ozone strat1, 35, .0000089, o3 +composition rate: ozone meso, 37, .0000087, o3 +composition rate: ozone meso2, 55, .0000017, o3 +composition rate: ozone meso3, 75, .00000018, o3 +composition rate: ozone meso4, 80, .00000018, o3 +composition rate: ozone meso5, 90, .00000076, o3 +composition rate: ozone thermo, 120, 0, o3 + +#composition rate: n2o 1, 8, .00000032, n2o +#composition rate: n2o 2, 16, .00000026, n2o +#composition rate: n2o 3, 20, .00000013, n2o +#composition rate: n2o 4, 25, .00000009, n2o +#composition rate: n2o 5, 45, .000000008, n2o +#composition rate: n2o 6, 120, 0, n2o + +#composition rate: co 1, 4, .00000013, co +#composition rate: co 2, 6, .000000128, co +#composition rate: co 3, 15, .000000038, co +#composition rate: co 4, 20, .00000012, co +#composition rate: co 5, 60, .00000012, co +#composition rate: co 6, 90, .0000029, co +#composition rate: co 7, 120, .000050, co + +#composition rate: ch4 1, 4, .00000017, ch4 +#composition rate: ch4 2, 9, .000000162, ch4 +#composition rate: ch4 3, 4, .00000017, ch4 +#composition rate: ch4 4, 19, .0000018, ch4 +#composition rate: ch4 5, 25, .00000078, ch4 +#composition rate: ch4 6, 55, .00000015, ch4 +#composition rate: ch4 7, 85, .00000015, ch4 +#composition rate: ch4 8, 120,.00000003, ch4 + + diff --git a/collins - scenario 2a.pyr b/collins - scenario 2a.pyr new file mode 100644 index 0000000..1717bab --- /dev/null +++ b/collins - scenario 2a.pyr @@ -0,0 +1,78 @@ +# mid latitude summer from Anderson 1986 +# these are duplciating scenarios from Collins et al 2006 as a means to validate, or not, PyRad against other LBL's. +# transmission is only processed up to the tropopause, rather than full height and atm constiuents is greatly reduced. + +surface: 1013.25, 294, 120, 100, 9.8 + +molecule: co2, .000369 +molecule: h2o, .018800 +molecule: o2, .20 +molecule: n2, .77 +molecule: ar, .009 +# molecule: ch4, .00000170 + molecule: o3, .00000003 +# molecule: n2o, .000000320 +# molecule: co, .000000150 + +lapse rate: boundary layer troposphere, 2, 285 +lapse rate: troposphere, 13, 216 +lapse rate: tropopause, 17, 215 +lapse rate: lower stratosphere, 27, 228 +lapse rate: stratosphere, 47.5, 275 +lapse rate: stratopause, 50, 276 +lapse rate: lower mesosphere, 55, 269 +lapse rate: mesosphere, 80, 174 +lapse rate: upper mesosphere, 85, 165 +lapse rate: mesopause, 90, 165 +lapse rate: thermosphere, 100, 190 +lapse rate: upper thermosphere, 120, 380 + +composition rate: WV boundary layer, 3, .005691, h2o +composition rate: WV troposphere, 5, .002266, h2o +composition rate: WV trop2, 6, .0015, h2o +composition rate: wv trop 3, 8, .000647, h2o +composition rate: wv tropopause, 11, .000099, h2o +composition rate: wv tropopause2, 12, .000030, h2o +composition rate: wv tropopause3, 13, .0000054, h2o +composition rate: wv stratosphere, 18, .000003, h2o +composition rate: wv strat2, 25, .0000045, h2o +composition rate: wv strat3, 50, .0000055, h2o +composition rate: wv strat3, 60, .000005, h2o +composition rate: wv meso, 90, .00000085, h2o +composition rate: wv thermo, 120, .0000002, h2o + +composition rate: ozone troposphere, 10, .00000013, o3 +composition rate: ozone tropopause, 17, .0000007, o3 +composition rate: ozone strat1, 35, .0000089, o3 +composition rate: ozone meso, 37, .0000087, o3 +composition rate: ozone meso2, 55, .0000017, o3 +composition rate: ozone meso3, 75, .00000018, o3 +composition rate: ozone meso4, 80, .00000018, o3 +composition rate: ozone meso5, 90, .00000076, o3 +composition rate: ozone thermo, 120, 0, o3 + +#composition rate: n2o 1, 8, .00000032, n2o +#composition rate: n2o 2, 16, .00000026, n2o +#composition rate: n2o 3, 20, .00000013, n2o +#composition rate: n2o 4, 25, .00000009, n2o +#composition rate: n2o 5, 45, .000000008, n2o +#composition rate: n2o 6, 120, 0, n2o + +#composition rate: co 1, 4, .00000013, co +#composition rate: co 2, 6, .000000128, co +#composition rate: co 3, 15, .000000038, co +#composition rate: co 4, 20, .00000012, co +#composition rate: co 5, 60, .00000012, co +#composition rate: co 6, 90, .0000029, co +#composition rate: co 7, 120, .000050, co + +#composition rate: ch4 1, 4, .00000017, ch4 +#composition rate: ch4 2, 9, .000000162, ch4 +#composition rate: ch4 3, 4, .00000017, ch4 +#composition rate: ch4 4, 19, .0000018, ch4 +#composition rate: ch4 5, 25, .00000078, ch4 +#composition rate: ch4 6, 55, .00000015, ch4 +#composition rate: ch4 7, 85, .00000015, ch4 +#composition rate: ch4 8, 120,.00000003, ch4 + + diff --git a/collins - scenario 2b.pyr b/collins - scenario 2b.pyr new file mode 100644 index 0000000..81dc913 --- /dev/null +++ b/collins - scenario 2b.pyr @@ -0,0 +1,78 @@ +# mid latitude summer from Anderson 1986 +# these are duplciating scenarios from Collins et al 2006 as a means to validate, or not, PyRad against other LBL's. +# transmission is only processed up to the tropopause, rather than full height and atm constiuents is greatly reduced. + +surface: 1013.25, 294, 120, 100, 9.8 + +molecule: co2, .000574 +molecule: h2o, .018800 +molecule: o2, .20 +molecule: n2, .77 +molecule: ar, .009 +# molecule: ch4, .00000170 + molecule: o3, .00000003 +# molecule: n2o, .000000320 +# molecule: co, .000000150 + +lapse rate: boundary layer troposphere, 2, 285 +lapse rate: troposphere, 13, 216 +lapse rate: tropopause, 17, 215 +lapse rate: lower stratosphere, 27, 228 +lapse rate: stratosphere, 47.5, 275 +lapse rate: stratopause, 50, 276 +lapse rate: lower mesosphere, 55, 269 +lapse rate: mesosphere, 80, 174 +lapse rate: upper mesosphere, 85, 165 +lapse rate: mesopause, 90, 165 +lapse rate: thermosphere, 100, 190 +lapse rate: upper thermosphere, 120, 380 + +composition rate: WV boundary layer, 3, .005691, h2o +composition rate: WV troposphere, 5, .002266, h2o +composition rate: WV trop2, 6, .0015, h2o +composition rate: wv trop 3, 8, .000647, h2o +composition rate: wv tropopause, 11, .000099, h2o +composition rate: wv tropopause2, 12, .000030, h2o +composition rate: wv tropopause3, 13, .0000054, h2o +composition rate: wv stratosphere, 18, .000003, h2o +composition rate: wv strat2, 25, .0000045, h2o +composition rate: wv strat3, 50, .0000055, h2o +composition rate: wv strat3, 60, .000005, h2o +composition rate: wv meso, 90, .00000085, h2o +composition rate: wv thermo, 120, .0000002, h2o + +composition rate: ozone troposphere, 10, .00000013, o3 +composition rate: ozone tropopause, 17, .0000007, o3 +composition rate: ozone strat1, 35, .0000089, o3 +composition rate: ozone meso, 37, .0000087, o3 +composition rate: ozone meso2, 55, .0000017, o3 +composition rate: ozone meso3, 75, .00000018, o3 +composition rate: ozone meso4, 80, .00000018, o3 +composition rate: ozone meso5, 90, .00000076, o3 +composition rate: ozone thermo, 120, 0, o3 + +#composition rate: n2o 1, 8, .00000032, n2o +#composition rate: n2o 2, 16, .00000026, n2o +#composition rate: n2o 3, 20, .00000013, n2o +#composition rate: n2o 4, 25, .00000009, n2o +#composition rate: n2o 5, 45, .000000008, n2o +#composition rate: n2o 6, 120, 0, n2o + +#composition rate: co 1, 4, .00000013, co +#composition rate: co 2, 6, .000000128, co +#composition rate: co 3, 15, .000000038, co +#composition rate: co 4, 20, .00000012, co +#composition rate: co 5, 60, .00000012, co +#composition rate: co 6, 90, .0000029, co +#composition rate: co 7, 120, .000050, co + +#composition rate: ch4 1, 4, .00000017, ch4 +#composition rate: ch4 2, 9, .000000162, ch4 +#composition rate: ch4 3, 4, .00000017, ch4 +#composition rate: ch4 4, 19, .0000018, ch4 +#composition rate: ch4 5, 25, .00000078, ch4 +#composition rate: ch4 6, 55, .00000015, ch4 +#composition rate: ch4 7, 85, .00000015, ch4 +#composition rate: ch4 8, 120,.00000003, ch4 + + diff --git a/pyrad.py b/pyrad.py index 397be9b..d6864a3 100644 --- a/pyrad.py +++ b/pyrad.py @@ -424,7 +424,7 @@ def inputHeight(values): text = 'Enter the height to view transmission from.\t\t\t' height = receiveInput('%s\n' 'Units should be in %s. If no value entered, maximum atm height will be used: ' % (util.underlineCyan(text), util.limeText('km')), validNumber, default=-2.71828) - values['height'] = height + values['height'] = height * 10**5 return plotPlanetSpectrum(values) @@ -432,7 +432,7 @@ def inputHeightComponents(values): text = 'Enter the height to view transmission from.\t\t\t' height = receiveInput('%s\n' 'Units should be in %s. If no value entered, maximum atm height will be used: ' % (util.underlineCyan(text), util.limeText('km')), validNumber, default=-2.71828) - values['height'] = height + values['height'] = height * 10**5 return plotPlanetSpectrumComponents(values) @@ -591,6 +591,9 @@ def buildProfile(profileList): saveAbsData = pyradClasses.yesOrNo("Would you like to save abs coef data?\n" "This takes up quite a bit of space and generally isn't needed. %s" % util.limeText('(y/n)')) + # initiate planet variable, in hopes of stopping memory leak + planet = None + for profile in profileList: print('Building %s on setting %s' % (profile.name, pyradClasses.settings.setting)) planet = pyradClasses.createCustomPlanet(profile.name) @@ -614,6 +617,7 @@ def buildProfile(profileList): pyradClasses.processTransmissionBySingleLayer(planet.folderPath) if not saveAbsData: util.clearAbsData(planet.folderPath) + planet.clearData() return chooseAtmTransferBuildProfile() diff --git a/pyradClasses.py b/pyradClasses.py index 830b91e..f4a81fe 100644 --- a/pyradClasses.py +++ b/pyradClasses.py @@ -76,12 +76,10 @@ def loadEmptyPlanet(folderPath, planet=None, verify=False): def readTransmissionFromFile(requestedHeight, folderPath, direction): completedValues = utils.readCompleteTransmission(folderPath) - stringHeightList = completedValues['heightList'].split(',') + heightList = completedValues['heightList'] maxHeight = float(completedValues['maxHeight']) * 100000 i = 0 - heightList = [] - for h in stringHeightList: - heightList.append(float(h)) + if direction == 'down': height = 0 while height < requestedHeight and i < len(heightList) - 1: @@ -96,6 +94,7 @@ def readTransmissionFromFile(requestedHeight, folderPath, direction): i += 1 targetIndex = heightList.index(height) fileName = 'trans looking %s-%s.pyr' % (direction, targetIndex) + print('retreiving transmission from: %s' % fileName) transmissionValues = utils.readTransmissionValues(fileName, folderPath) for key in transmissionValues: transmissionValues[key] = np.asarray(transmissionValues[key]) @@ -103,6 +102,9 @@ def readTransmissionFromFile(requestedHeight, folderPath, direction): transmissionValues['rangeMax'] = float(completedValues['rangeMax']) transmissionValues['surfaceTemperature'] = float(completedValues['surfaceTemperature']) transmissionValues['molList'] = completedValues['molList'] + transmissionValues['surfaceEffEmissivity'] = float(completedValues['surfaceEffEmissivity']), + transmissionValues['res'] = float(completedValues['res']) + transmissionValues['surfacePower'] = float(completedValues['surfacePower']) return transmissionValues @@ -113,14 +115,19 @@ def processTransmissionBySingleLayer(folderPath, res=1): float(values['maxHeight']), rangeMin=int(values['rangeMin']), rangeMax=int(values['rangeMax']), initialThickness=int(float(values['initialDepth'])), - gravity=float(values['gravity']), res=int(float(values['res']))) + gravity=float(values['gravity']), res=int(float(values['res'])), surfaceEffEmissivity=float(values['surfaceEffEmissivity'])) for mol in values['molList'].split(','): planet.moleculeList.append(mol) xAxis = None fileLength = utils.profileLength(folderPath) heightList = [0] + # making a generic layer and molecules layer = Layer(0, 0, 0, 0, 0) + + spectrumDict = {} + inputDict = {} + for i in range(1, fileLength + 1): layerProfile = utils.readPlanetProfile(folderPath, i, fileLength) layer.depth = layerProfile['depth'] @@ -130,57 +137,65 @@ def processTransmissionBySingleLayer(folderPath, res=1): layer.rangeMax = layerProfile['rangeMax'] layer.height = layerProfile['height'] layer.name = layerProfile['name'] - layer.absorptionCoefficient = np.asarray(layerProfile['absCoef']) + layer.absorptionCoefficient = np.asarray(layerProfile['layer absCoef']) layer.progressAbsCoef = True if xAxis is None: xAxis = np.linspace(planet.rangeMin, planet.rangeMax, len(layer.absorptionCoefficient)) - surfaceSpectrum = pyradPlanck.planckWavenumber(xAxis, planet.surfaceTemperature) - spectrumDict = {folderPath: reduceRes(surfaceSpectrum, finalRes=res), - 'temperature': layer.T, - 'pressure': layer.P, - 'depth': layer.depth, - 'meanHeight': layer.meanHeight} + spectrumDict['temperature'] = planet.surfaceTemperature, + spectrumDict['pressure'] = planet.surfacePressure, + spectrumDict['depth'] = 'surface', + spectrumDict['meanHeight'] = 0 + inputSpectrum = pyradPlanck.planckWavenumber(xAxis, planet.surfaceTemperature) * planet.effEmissivity + surfacePower = integrateSpectrum(inputSpectrum, pi,.01) + spectrumDict['layer transmission'] = reduceRes(inputSpectrum, finalRes=res) + spectrumDict['surfacePower'] = surfacePower + inputDict['layer'] = inputSpectrum for molecule in planet.moleculeList: - spectrumDict['%s transmission' % molecule] = reduceRes(surfaceSpectrum, finalRes=res) + spectrumDict['%s transmission' % molecule] = reduceRes(inputSpectrum, finalRes=res) spectrumDict['%s concentration' % molecule] = layerProfile['%s concentration' % molecule] + spectrumDict['%s power' % molecule] = integrateSpectrum(inputSpectrum, pi, .01) + inputDict[molecule] = inputSpectrum utils.writePlanetTransmission(folderPath, 0, spectrumDict, 'down', 0) - surfaceSpectrum = layer.transmission(surfaceSpectrum) - spectrumDict = {'%s transmission' % folderPath: reduceRes(surfaceSpectrum, finalRes=res), - '%s layer effective emissivity' % folderPath: layer.effectiveEmissivity, - '%s layer normalized emissivity' % folderPath: layer.normalizedEmissivity} + spectrumDict['temperature'] = layer.T, + spectrumDict['pressure'] = layer.P, + spectrumDict['depth'] = layer.depth, + spectrumDict['meanHeight'] = layer.meanHeight + inputSpectrum = inputDict['layer'] + transmittedSpectrum = layer.transmission(inputSpectrum) + spectrumDict.update({'layer transmission': reduceRes(transmittedSpectrum, finalRes=res), + 'layer effective emissivity': layer.effectiveEmissivity, + 'layer power': integrateSpectrum(transmittedSpectrum, pi, .01)}) + inputDict['layer'] = transmittedSpectrum + + for molecule in planet.moleculeList: + inputSpectrum = inputDict[molecule] + layer.absorptionCoefficient = np.asarray(layerProfile['%s absCoef' % molecule]) + transmittedSpectrum = layer.transmission(inputSpectrum) + spectrumDict.update({'%s transmission' % molecule: reduceRes(transmittedSpectrum), + '%s effective emissivity' % molecule: layer.effectiveEmissivity, + '%s power' % molecule: integrateSpectrum(transmittedSpectrum, pi, .01), + '%s concentration' % molecule: layerProfile['%s concentration' % molecule]}) + inputDict[molecule] = transmittedSpectrum + utils.writePlanetTransmission(folderPath, layer.meanHeight, spectrumDict, 'down', i) heightList.append(layer.meanHeight) gc.collect() heightList.append(planet.maxHeight) - for molecule in planet.moleculeList: - surfaceSpectrum = pyradPlanck.planckWavenumber(xAxis, planet.surfaceTemperature) - for i in range(1, fileLength + 1): - layerProfile = utils.readPlanetProfileMolecule(folderPath, i, fileLength, molecule) - layer.depth = layerProfile['depth'] - layer.P = layerProfile['P'] - layer.T = layerProfile['T'] - layer.rangeMin = layerProfile['rangeMin'] - layer.rangeMax = layerProfile['rangeMax'] - layer.height = layerProfile['height'] - layer.name = layerProfile['name'] - layer.absorptionCoefficient = np.asarray(layerProfile['absCoef']) - layer.progressAbsCoef = True - spectrumDict = {'%s transmission' % molecule: reduceRes(layer.transmission(surfaceSpectrum)), - '%s effective emissivity' % molecule: layer.effectiveEmissivity, - '%s normalized emissivity' % molecule: layer.normalizedEmissivity, - '%s concentration' % molecule: layerProfile['%s concentration' % molecule]} - surfaceSpectrum = layer.transmission(surfaceSpectrum) - utils.writePlanetTransmission(folderPath, layer.meanHeight, spectrumDict, 'down', i, mode='ab') - gc.collect() # with transmission from surface upward processed, do the same in reverse to get the transmission toward the surface # initial spectrum will be 2.7K for CMB - surfaceSpectrum = pyradPlanck.planckWavenumber(xAxis, 2.7) - spectrumDict = {folderPath: reduceRes(surfaceSpectrum, finalRes=res)} + inputDict = {} + + inputSpectrum = pyradPlanck.planckWavenumber(xAxis, 2.7) + spectrumDict = {'layer transmission': reduceRes(inputSpectrum, finalRes=res)} + surfacePower = integrateSpectrum(inputSpectrum, pi, .01) + spectrumDict['surfacePower'] = surfacePower + inputDict['layer'] = inputSpectrum for molecule in planet.moleculeList: - spectrumDict[molecule] = reduceRes(surfaceSpectrum, finalRes=res) + spectrumDict['%s transmission' % molecule] = reduceRes(inputSpectrum, finalRes=res) + inputDict[molecule] = inputSpectrum utils.writePlanetTransmission(folderPath, planet.maxHeight, spectrumDict, 'up', 0) for i in range(1, fileLength + 1): @@ -193,38 +208,28 @@ def processTransmissionBySingleLayer(folderPath, res=1): layer.rangeMax = layerProfile['rangeMax'] layer.height = layerProfile['height'] layer.name = layerProfile['name'] - layer.absorptionCoefficient = np.asarray(layerProfile['absCoef']) + layer.absorptionCoefficient = np.asarray(layerProfile['layer absCoef']) layer.progressAbsCoef = True - surfaceSpectrum = layer.transmission(surfaceSpectrum) - spectrumDict = {'%s transmission' % folderPath: reduceRes(surfaceSpectrum, finalRes=res), - '%s layer effective emissivity' % folderPath: layer.effectiveEmissivity, - '%s layer normalized emissivity' % folderPath: layer.normalizedEmissivity} + inputSpectrum = inputDict['layer'] + transmittedSpectrum = layer.transmission(inputSpectrum) + spectrumDict.update({'layer transmission': reduceRes(transmittedSpectrum, finalRes=res), + 'layer effective emissivity': layer.effectiveEmissivity, + 'layer power': integrateSpectrum(transmittedSpectrum, pi, .01)}) + inputDict['layer'] = transmittedSpectrum + + for molecule in planet.moleculeList: + inputSpectrum = inputDict[molecule] + layer.absorptionCoefficient = np.asarray(layerProfile['%s absCoef' % molecule]) + transmittedSpectrum = layer.transmission(inputSpectrum) + spectrumDict.update({'%s transmission' % molecule: reduceRes(transmittedSpectrum), + '%s effective emissivity' % molecule: layer.effectiveEmissivity, + '%s power' % molecule: integrateSpectrum(transmittedSpectrum, pi, .01), + '%s concentration' % molecule: layerProfile['%s concentration' % molecule]}) + inputDict[molecule] = transmittedSpectrum + utils.writePlanetTransmission(folderPath, layer.meanHeight, spectrumDict, 'up', i) gc.collect() - for molecule in planet.moleculeList: - surfaceSpectrum = pyradPlanck.planckWavenumber(xAxis, 2.7) - - for i in range(1, fileLength + 1): - fileNumber = fileLength + 1 - i - layerProfile = utils.readPlanetProfileMolecule(folderPath, fileNumber, fileLength, molecule) - layer.depth = layerProfile['depth'] - layer.P = layerProfile['P'] - layer.T = layerProfile['T'] - layer.rangeMin = layerProfile['rangeMin'] - layer.rangeMax = layerProfile['rangeMax'] - layer.height = layerProfile['height'] - layer.name = layerProfile['name'] - layer.absorptionCoefficient = np.asarray(layerProfile['absCoef']) - layer.progressAbsCoef = True - spectrumDict = {'%s transmission' % molecule: reduceRes(layer.transmission(surfaceSpectrum), finalRes=res), - '%s effective emissivity' % molecule: layer.effectiveEmissivity, - '%s normalized emissivity' % molecule: layer.normalizedEmissivity, - '%s concentration' % molecule: layerProfile['%s concentration' % molecule]} - utils.writePlanetTransmission(folderPath, layer.meanHeight, spectrumDict, 'up', i, mode='ab') - surfaceSpectrum = layer.transmission(surfaceSpectrum) - gc.collect() - utils.profileWriteTransmissionComplete(folderPath, heightList) return @@ -283,6 +288,7 @@ def linear(baseValue, baseHeight, rate, height): def integrateSpectrum(spectrum, unitAngle=pi, res=utils.BASE_RESOLUTION): value = np.sum(np.nan_to_num(spectrum)) value = value * unitAngle * res + return value @@ -426,6 +432,7 @@ def __init__(self, wavenumber, intensity, einsteinA, airHalfWidth, self.tempExponent = tempExponent self.pressureShift = pressureShift + @property def broadenedLine(self): return self.wavenumber + self.pressureShift * self.layer.P / p0 @@ -465,6 +472,11 @@ def __init__(self, number, molecule): self.crossSection = np.copy(self.layer.crossSection) self.progressCrossSection = False + def __del__(self): + for line in self: + line = None + + @property def P(self): return self.layer.P @@ -525,7 +537,7 @@ def yAxis(self): def xAxis(self): return np.copy(self.layer.xAxis) - def getData(self, lineSurvey=False, verbose=True): + def getData(self, verbose=True): if 'Inert' in self.name: print('Inert molecule, no data.') return @@ -539,7 +551,6 @@ def getData(self, lineSurvey=False, verbose=True): lineDict[line]['airHalfWidth'], lineDict[line]['selfHalfWidth'], lineDict[line]['lowerEnergy'], lineDict[line]['tempExponent'], lineDict[line]['pressureShift'], self)) - # self.createLineSurvey() def createCrossSection(self): molecule = self.molecule @@ -670,6 +681,10 @@ def __init__(self, shortNameOrMolNum, layer, isotopeDepth=1, **abundance): def __str__(self): return '%s: %s' % (self.name, self.concText) + def __del__(self): + for iso in self: + iso = None + def __bool__(self): return True @@ -834,6 +849,10 @@ def __str__(self): def __bool__(self): return True + def __del__(self): + for molecule in self: + molecule.__del__() + def createCrossSection(self): tempAxis = np.zeros(int((self.rangeMax - self.rangeMin) / utils.BASE_RESOLUTION)) for molecule in self: @@ -1025,6 +1044,10 @@ def __str__(self): def __bool__(self): return True + def __del__(self): + for layer in self: + layer.__del__() + def addLayer(self, depth, T, P, rangeMin, rangeMax, name=None, dynamicResolution=True, height=0.0): if not name: name = self.nextLayerName() @@ -1096,12 +1119,12 @@ def moleculesAtHeight(self, height): class Planet: - def __init__(self, name, pressure, temperature, maxHeight, + def __init__(self, name, pressure, temperature, maxHeight, surfaceEffEmissivity=.971, gravity=9.80665, rangeMin=0, rangeMax=2000, initialThickness=100, res=1): self.name = name self.gravity = gravity self.maxHeight = maxHeight * 100000 - self.radius = 0 + self.effEmissivity = surfaceEffEmissivity self.surfacePressure = pressure self.surfaceTemperature = temperature self.atmosphereRules = [] @@ -1118,6 +1141,12 @@ def __init__(self, name, pressure, temperature, maxHeight, name='initial layer', height=0) self.progressProfileLoaded = False + def __del__(self): + self.atmosphere.__del__() + + def clearData(self): + self.__del__() + def addLapseRate(self, name, finalHeight, finalValue, rateFunction=linear): self.atmosphereRules.append(AtmosphereRule(name, finalHeight * 100000, finalValue, 'temperature', self, rateFunction=rateFunction)) @@ -1261,7 +1290,7 @@ def processTransmission(self, height, direction='down', verify=True, moleculeSpe print('Processing atmosphere spectrum from %skm looking %s...' % (height / 100000, direction)) if direction == 'down': xAxis = np.linspace(self.rangeMin, self.rangeMax, len(self.atmosphere[0].absCoef)) - surfaceSpectrum = pyradPlanck.planckWavenumber(xAxis, self.surfaceTemperature) + surfaceSpectrum = pyradPlanck.planckWavenumber(xAxis, self.surfaceTemperature) * self.effEmissivity for layer in self.atmosphere: if layer.meanHeight < height: surfaceSpectrum = layer.transmission(surfaceSpectrum) @@ -1283,6 +1312,10 @@ def yAxis(self): def folderPath(self): return '%s %s' % (self.name, self.setting) + @property + def surfacePower(self): + return integrateSpectrum(pyradPlanck.planckWavenumber(self.xAxis, self.surfaceTemperature)) * self.effEmissivity + @property def molarMass(self): return self.initialLayer.molarMass / 1000 @@ -1488,7 +1521,7 @@ def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=( elif not heightFlag and direction == 'up': height = 0 transmissionValues = readTransmissionFromFile(height, planets[0], direction=direction) - totalY = transmissionValues[planets[0] + ' transmission'] + totalY = transmissionValues['layer transmission'] xAxis = np.linspace(transmissionValues['rangeMin'], transmissionValues['rangeMax'], len(totalY)) for temperature, color in zip(temperatureList, theme.colorList[1:]): @@ -1507,7 +1540,7 @@ def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=( elif not heightFlag and direction == 'up': height = 0 transmissionValues = readTransmissionFromFile(height, planet, direction) - totalY = transmissionValues[planet + ' transmission'] + totalY = transmissionValues['layer transmission'] powerSpectrum = round(integrateSpectrum(totalY, pi, res=res), 2) effTemp = int(stefanB(powerSpectrum)) fig, = plt.plot(xAxis, totalY, linewidth=linewidth, color=color, label='%s : %sWm-2, eff : %sK' % (planet, powerSpectrum, effTemp)) @@ -1520,7 +1553,7 @@ def plotPlanetSpectrum(planets, height=None, direction='down', temperatureList=( plt.show() -def plotPlanetAndComponents(planet, height=None, direction='down', temperatureList=(290, 260, 230, 200), verify=True, res=1): +def plotPlanetAndComponents(planet, height=None, direction='down', temperatureList=(300, 270, 240, 210, 180), verify=True, res=1): linewidth = 1 plt.figure(figsize=(10, 6), dpi=80) plt.subplot(111, facecolor=theme.faceColor) @@ -1538,8 +1571,8 @@ def plotPlanetAndComponents(planet, height=None, direction='down', temperatureLi elif not heightFlag and direction == 'up': height = 0 transmittanceValues = readTransmissionFromFile(height, planet, direction=direction) - yTotal = transmittanceValues[planet + ' transmission'] - xAxis = np.linspace(transmittanceValues['rangeMin'], transmittanceValues['rangeMax'], len(yTotal)) + yTotal = transmittanceValues['layer transmission'] + xAxis = np.arange(transmittanceValues['rangeMin'], transmittanceValues['rangeMax'], transmittanceValues['res']) for temperature, color in zip(temperatureList, theme.colorList[1:]): yAxis = pyradPlanck.planckWavenumber(xAxis, float(temperature)) fig, = plt.plot(xAxis, yAxis, linewidth=linewidth / 2, color=color, @@ -1547,29 +1580,25 @@ def plotPlanetAndComponents(planet, height=None, direction='down', temperatureLi (temperature, int(integrateSpectrum(yAxis, pi, res=res)))) handles.append(fig) - if direction == 'down': - surfaceTemp = float(transmittanceValues['surfaceTemperature']) - else: - surfaceTemp = 2.7 - planckAxis = pyradPlanck.planckWavenumber(xAxis, surfaceTemp) - surfacePower = int(integrateSpectrum(planckAxis, pi, res=res)) - powerSpectrum = int(integrateSpectrum(yTotal, pi, res=res)) - plt.title('Surface temp: %sK Surface flux: %sWm-2 Effec temp: %sK' - % (transmittanceValues['surfaceTemperature'], surfacePower, int(stefanB(powerSpectrum)))) - effect = surfacePower - powerSpectrum + + surfacePower = transmittanceValues['surfacePower'] + powerSpectrum = integrateSpectrum(yTotal, pi, res=res) + plt.title('Surface temp: %sK Surface flux: %sWm-2 Effect temp: %sK' + % (transmittanceValues['surfaceTemperature'], round(surfacePower, 2), round(stefanB(powerSpectrum), 2))) + fig, = plt.plot(xAxis, yTotal, linewidth=linewidth, color=theme.backingColor, - label='net flux: %sWm-2' % powerSpectrum) + label='net flux: %sWm-2' % round(powerSpectrum,2)) handles.append(fig) moleculeList = transmittanceValues['molList'].split(',') for molecule, color in zip(moleculeList, theme.colorList): yAxis = transmittanceValues[molecule + ' transmission'] - tempPowerSpectrum = int(integrateSpectrum(yAxis, pi, res=res)) - + tempPowerSpectrum = integrateSpectrum(yAxis, pi, res=res) + print('%s - %s' % (molecule, tempPowerSpectrum)) effect = surfacePower - tempPowerSpectrum fig, = plt.plot(xAxis, yAxis, linewidth=linewidth, color=color, alpha=.6, - label='%s effect: %sWm-2' % (molecule, effect)) + label='%s effect: %sWm-2' % (molecule, round(effect,2))) handles.append(fig) credit = 'PyRad v%s\n%s' % (utils.VERSION, settings.userName) handles.append(mpatches.Patch(color='none', label=credit)) diff --git a/pyradUtilities.py b/pyradUtilities.py index 5687564..d069a63 100644 --- a/pyradUtilities.py +++ b/pyradUtilities.py @@ -254,7 +254,7 @@ def writePlanetTransmission(name, height, values, direction, number, mode='wb'): openFile.write(text.encode('utf-8')) text = '# general layer data is listed below this line. Other data contained within this file is\n' \ '# the reduced transmission for the layer and each molecule that is part of the atmosphere.\n' \ - '# Effective emissivity for is the avg emissivity, normalized is the avg with zeroes removed.\n#\n' + '# Effective emissivity for is the avg emissivity\n#\n' openFile.write(text.encode('utf-8')) for item in values: try: @@ -335,6 +335,15 @@ def readCompleteProfile(folderPath): return values +def readHeightFile(folderPath): + fullPath = '%s/%s/profileHeights.pyr' % (profileDir, folderPath) + lines = openReturnLines(fullPath) + heights = [] + for line in lines: + heights.append(float(line)) + return heights + + def readCompleteTransmission(folderPath): fullPath = '%s/%s/transmissionComplete.pyr' % (profileDir, folderPath) lines = openReturnLines(fullPath) @@ -345,6 +354,7 @@ def readCompleteTransmission(folderPath): else: cells = line.split(':') values[cells[0].strip()] = cells[1].strip() + values['heightList'] = readHeightFile(folderPath) return values @@ -510,7 +520,7 @@ def profileProgress(name): else: cells = line.split(':') if cells[0] == 'completed': - completed = int(cells[1]) + completed = int(cells[1]) - 1 elif cells[0] == 'time': startTime = int(cells[1].strip()) return completed, startTime @@ -537,18 +547,28 @@ def profileComplete(name): return False +def writeHeightList(folderPath, heightList): + path = '%s/%s' % (profileDir, folderPath) + fileName = 'profileHeights' + filePath = '%s/%s.pyr' % (path, fileName) + openFile = open(filePath, 'wb') + for height in heightList: + text = "%s\n" % height + openFile.write(text.encode('utf-8')) + return + + def profileWriteTransmissionComplete(folderPath, heightList): - folderPath = '%s/%s' % (profileDir, folderPath) + path = '%s/%s' % (profileDir, folderPath) fileName = 'profileComplete' - filePath = '%s/%s.pyr' % (folderPath, fileName) + filePath = '%s/%s.pyr' % (path, fileName) completeProfileData = openReturnLines(filePath) - transmissionPath = '%s/transmissionComplete.pyr' % folderPath + transmissionPath = '%s/transmissionComplete.pyr' % path openFile = open(transmissionPath, 'wb') for line in completeProfileData: openFile.write(line.encode('utf-8')) - text = '\nheightList: %s' % (','.join(str(n) for n in heightList)) - openFile.write(text.encode('utf-8')) openFile.close() + writeHeightList(folderPath, heightList) return @@ -567,6 +587,8 @@ def profileWriteComplete(planet, completed, expected, processingTime, res, molec 'maxHeight: %s\n' \ 'initialDepth: %s\n' \ 'gravity: %s\n' \ + 'surfaceEffEmissivity: %s\n'\ + 'surfacePower: %s\n'\ 'rangeMin: %s\n' \ 'rangeMax: %s\n' \ 'molList: %s\n' \ @@ -575,7 +597,8 @@ def profileWriteComplete(planet, completed, expected, processingTime, res, molec 'completed: %s' % (planet.folderPath, time.strftime("%Y-%m-%d %H:%M:%S"), VERSION, int(processingTime), planet.folderPath, moleculeSpecific, planet.surfacePressure, planet.surfaceTemperature, int(planet.maxHeight / 100000), planet.heightList[1], planet.gravity, - planet.rangeMin, planet.rangeMax, ','.join(planet.moleculeList), res, expected, completed) + planet.effEmissivity, planet.surfacePower, planet.rangeMin, planet.rangeMax, + ','.join(planet.moleculeList), res, expected, completed) openFile = open(filePath, 'wb') openFile.write(text.encode('utf-8')) openFile.close() @@ -642,12 +665,12 @@ def readPlanetProfile(name, layerNumber, length): pass elif keyValue[0].strip() == 'name': layerDict[keyValue[0]] = keyValue[1].strip() - elif keyValue[0].strip() == 'layer absCoef': + elif 'absCoef' in keyValue[0].strip(): absList = keyValue[1].split(',') absCoefList = [] for value in absList: absCoefList.append(float(value)) - layerDict['absCoef'] = absCoefList + layerDict[keyValue[0].strip()] = absCoefList elif keyValue[0].strip() == 'T' or keyValue[0] == 'rangeMin' or keyValue[0] == 'rangeMax': layerDict[keyValue[0]] = int(keyValue[1]) elif keyValue[0].strip() == 'P' or keyValue[0].strip() == 'height' or keyValue[0].strip() == 'depth' \ @@ -746,6 +769,7 @@ def downloadMolParam(): openFile.write(chunk) openFile.close() + # downloads q table from hitran def downloadQData(isotope): url = 'http://hitran.org/data/Q/q%s.txt' % str(isotope) @@ -761,6 +785,7 @@ def downloadQData(isotope): openFile.write(chunk) openFile.close() + # downloads data from hitran using a function found in hapi that's been slightly modified def downloadHitran(path, globalID, waveMin, waveMax): params = 'molec_id,local_iso_id,nu,sw,a,elower,gamma_air,gamma_self,delta_air,n_air' @@ -880,6 +905,7 @@ def displayAllMolecules(): newLineIter = 0 print('\n') + RES_MULTIPLIER = 1 BASE_RESOLUTION = .01 * RES_MULTIPLIER From e05f80ce9d9d3fcd8de8a30ac18621fe9347dae2 Mon Sep 17 00:00:00 2001 From: brad schrag Date: Tue, 15 Jan 2019 11:38:45 -0600 Subject: [PATCH 38/43] adds many profiles, will clean these up later. Also changes how data is written to be a bit more consistent. --- afgl/midlatitude summer.csv | 52 ++++++ afgl/midlatitude summer.ods | Bin 0 -> 24121 bytes afgl/midlatitude winter.csv | 52 ++++++ afgl/midlatitude winter.ods | Bin 0 -> 23925 bytes afgl/subarctic summer.csv | 52 ++++++ afgl/subarctic summer.ods | Bin 0 -> 21815 bytes afgl/subarctic winter.csv | 52 ++++++ afgl/subarctic winter.ods | Bin 0 -> 23786 bytes afgl/tropical.csv | 52 ++++++ afgl/tropical.ods | Bin 0 -> 23990 bytes afgl/us standard.csv | 52 ++++++ afgl/us standard.ods | Bin 0 -> 23878 bytes collins - scenario 1a.pyr | 78 -------- collins - scenario 2a.pyr | 78 -------- collins - scenario 2b.pyr | 78 -------- collins 1a 25 slices.pyr | 174 +++++++++++++++++ collins 1a thick.pyr | 174 +++++++++++++++++ collins 1a.pyr | 174 +++++++++++++++++ collins 2a 25 slices.pyr | 174 +++++++++++++++++ collins 2a thick.pyr | 174 +++++++++++++++++ collins 2a.pyr | 174 +++++++++++++++++ collins 2b 25 slices.pyr | 174 +++++++++++++++++ collins 2b thick.pyr | 174 +++++++++++++++++ collins 2b.pyr | 174 +++++++++++++++++ collins 3a thick.pyr | 173 +++++++++++++++++ collins 3a.pyr | 173 +++++++++++++++++ earthsimple narrow.pyr | 38 ---- earthsimple.pyr | 38 ---- marssimple.pyr | 4 +- midlatitude summer.pyr | 329 +++++++++++++++++++++++++++++++++ midlatitude winter.pyr | 329 +++++++++++++++++++++++++++++++++ mls summer 286.pyr | 76 -------- mls summer 369.pyr | 76 -------- mls summer.pyr | 76 -------- pyradClasses.py | 2 +- pyradUtilities.py | 112 ++++++++++- subarctic summer.pyr | 329 +++++++++++++++++++++++++++++++++ subarctic winter.pyr | 329 +++++++++++++++++++++++++++++++++ themes/dark.pyr | 4 + tropical - narrow spectrum.pyr | 329 +++++++++++++++++++++++++++++++++ tropical.pyr | 329 +++++++++++++++++++++++++++++++++ us standard.pyr | 329 +++++++++++++++++++++++++++++++++ venussimple.pyr | 2 +- 43 files changed, 4646 insertions(+), 543 deletions(-) create mode 100644 afgl/midlatitude summer.csv create mode 100644 afgl/midlatitude summer.ods create mode 100644 afgl/midlatitude winter.csv create mode 100644 afgl/midlatitude winter.ods create mode 100644 afgl/subarctic summer.csv create mode 100644 afgl/subarctic summer.ods create mode 100644 afgl/subarctic winter.csv create mode 100644 afgl/subarctic winter.ods create mode 100644 afgl/tropical.csv create mode 100644 afgl/tropical.ods create mode 100644 afgl/us standard.csv create mode 100644 afgl/us standard.ods delete mode 100644 collins - scenario 1a.pyr delete mode 100644 collins - scenario 2a.pyr delete mode 100644 collins - scenario 2b.pyr create mode 100644 collins 1a 25 slices.pyr create mode 100644 collins 1a thick.pyr create mode 100644 collins 1a.pyr create mode 100644 collins 2a 25 slices.pyr create mode 100644 collins 2a thick.pyr create mode 100644 collins 2a.pyr create mode 100644 collins 2b 25 slices.pyr create mode 100644 collins 2b thick.pyr create mode 100644 collins 2b.pyr create mode 100644 collins 3a thick.pyr create mode 100644 collins 3a.pyr delete mode 100644 earthsimple narrow.pyr delete mode 100644 earthsimple.pyr create mode 100644 midlatitude summer.pyr create mode 100644 midlatitude winter.pyr delete mode 100644 mls summer 286.pyr delete mode 100644 mls summer 369.pyr delete mode 100644 mls summer.pyr create mode 100644 subarctic summer.pyr create mode 100644 subarctic winter.pyr create mode 100644 tropical - narrow spectrum.pyr create mode 100644 tropical.pyr create mode 100644 us standard.pyr diff --git a/afgl/midlatitude summer.csv b/afgl/midlatitude summer.csv new file mode 100644 index 0000000..b9fadf5 --- /dev/null +++ b/afgl/midlatitude summer.csv @@ -0,0 +1,52 @@ +midlatitude summer,,,,,,,, +altitude Km,pressure mB,temp K,mol*cm-3,h2o ppmv,o3 ppmv,n2o ppmv,co ppmv,ch4 ppmv +0,1.01E+03,294.2,2.50E+19,1.86E+04,3.02E-02,3.20E-01,1.50E-01,1.70E+00 +1,9.02E+02,289.7,2.26E+12,1.38E+04,3.34E-02,3.20E-01,1.45E-01,1.70E+00 +2,8.02E+02,295.2,2.04E+19,9.68E+03,3.69E-02,3.20E-01,1.40E-01,1.70E+00 +3,7.10E+02,279.2,1.84E+19,5.98E+03,4.22E-02,3.20E-01,1.35E-01,1.70E+00 +4,6.28E+02,273.2,1.67E+19,3.81E+03,4.82E-02,3.20E-01,1.31E-01,1.70E+00 +5,5.54E+02,287.2,1.50E+19,2.23E+03,5.51E-02,3.20E-01,1.30E-01,1.69E+00 +6,4.87E+02,261.2,1.35E+19,1.51E+03,6.41E-02,3.20E-01,1.29E-01,1.67E+00 +7,4.26E+02,254.7,1.21E+19,1.02E+03,7.76E-02,3.20E-01,1.26E-01,1.65E+00 +8,3.72E+02,248.2,1.09E+19,6.46E+02,9.13E-02,3.20E-01,1.20E-01,1.63E+00 +9,3.24E+02,241.7,9.72E+18,4.13E+02,1.11E-01,3.16E-01,1.09E-01,1.62E+00 +10,2.81E+02,235.3,8.66E+18,2.47E+02,1.30E-01,3.10E-01,9.96E-02,1.58E+00 +11,2.43E+02,228.8,7.70E+18,9.56E+01,1.79E-01,2.99E-01,8.96E-02,1.54E+00 +12,2.09E+02,222.3,6.81E+10,2.94E+01,2.23E-01,2.94E-01,7.81E-02,1.51E+00 +13,1.79E+02,215.8,6.01E+18,8.00E+00,3.00E-01,2.86E-01,6.37E-02,1.48E+00 +14,1.53E+02,215.7,5.14E+18,5.00E+00,4.40E-01,2.80E-01,5.03E-02,1.45E+00 +15,1.30E+02,215.7,4.37E+18,3.40E+00,5.00E-01,2.72E-01,3.94E-02,1.42E+00 +16,1.11E+02,215.7,3.73E+18,3.30E+00,6.00E-01,2.61E-01,3.07E-02,1.39E+00 +17,9.50E+01,215.7,3.19E+18,3.20E+00,7.00E-01,2.42E-01,2.49E-02,1.36E+00 +18,8.12E+01,216.8,2.72E+18,3.15E+00,1.00E+00,2.17E-01,1.97E-02,1.32E+00 +19,6.95E+01,217.9,2.31E+18,3.20E+00,1.50E+00,1.84E-01,1.66E-02,1.28E+00 +20,6.95E+01,219.2,1.97E+18,3.30E+00,2.00E+00,1.61E-01,1.33E-02,1.22E+00 +21,5.10E+01,220.4,1.68E+13,3.45E+00,2.40E+00,1.32E-01,1.23E-02,1.15E+00 +22,4.37E+01,221.6,1.43E+18,3.60E+00,2.90E+00,1.15E-01,1.23E-02,1.07E+00 +23,3.76E+01,222.8,1.22E+18,3.85E+00,3.40E+00,1.04E-01,1.31E-02,9.73E-01 +24,3.22E+01,223.9,1.04E+18,4.00E+00,4.00E+00,9.62E-02,1.40E-02,8.80E-01 +25,2.77E+01,225.1,8.92E+17,4.20E+00,4.80E+00,8.96E-02,1.52E-02,7.89E-01 +27.6,1.91E+01,228.5,6.05E+17,4.45E+00,6.00E+00,8.01E-02,1.72E-02,7.05E-01 +30,1.32E+01,233.7,4.09E+17,4.70E+00,7.00E+00,6.70E-02,2.00E-02,6.32E-01 +32.6,9.30E+00,239,2.82E+17,4.87E+00,8.10E+00,4.95E-02,2.27E-02,5.59E-01 +35,6.52E+00,245.2,1.93E+17,4.95E+00,8.90E+00,3.70E-02,2.49E-02,5.01E-01 +37.5,4.64E+00,251.3,1.34E+17,5.00E+00,8.70E+00,2.52E-02,2.72E-02,4.45E-01 +40,3.33E+00,257.5,9.37E+16,5.10E+00,7.55E+00,1.74E-02,2.96E-02,3.92E-01 +42.5,2.41E+00,263.7,6.62E+16,5.30E+00,5.90E+00,1.16E-02,3.14E-02,3.39E-01 +45,1.76E+00,269.9,4.73E+16,5.45E+00,4.50E+00,7.67E-03,3.31E-02,2.87E-01 +47.5,1.29E+00,275.2,3.40E+16,5.50E+00,3.50E+00,5.32E-03,3.49E-02,2.38E-01 +50,9.51E-01,275.7,2.50E+16,5.50E+00,2.80E+00,3.22E-30,3.65E-02,1.94E-01 +55,5.15E-01,269.3,1.39E+16,5.35E+00,1.80E+00,2.03E-03,3.92E-02,1.57E-01 +60,2.72E-01,257.1,7.67E+15,5.00E+00,1.30E+00,1.40E-03,4.67E-02,1.50E-01 +65,1.39E-01,240.1,4.20E+16,4.40E+00,8.00E-01,1.02E-03,6.40E-02,1.50E-01 +70,6.70E-02,218,2.27E+15,3.70E+00,4.00E-01,7.77E-04,1.18E-01,1.50E-01 +75,3.00E-02,196.1,1.11E+15,2.95E+00,1.90E-01,6.26E-04,2.94E-01,1.50E-01 +80,1.20E-02,174.1,5.00E+14,2.10E+00,2.00E-01,5.17E-04,6.82E-01,1.50E-01 +85,4.48E-03,165.1,1.97E+14,1.33E+00,5.70E-01,4.35E-04,1.47E+00,1.50E-01 +90,1.84E-03,165,7.20E+13,8.50E-01,7.50E-01,3.73E-04,2.85E+00,1.40E-01 +95,6.25E-04,178.3,2.54E+13,5.40E-01,7.00E-01,3.24E-04,5.17E+00,1.30E-01 +100,2.58E-04,190.5,9.82E+12,4.00E-01,4.03E-01,2.84E-04,1.01E+01,1.20E-01 +105,1.17E-04,222.2,3.82E+12,3.40E-01,2.00E-01,2.52E-04,1.87E+01,1.10E-01 +110,6.11E-05,262.4,1.69E+12,2.80E-01,5.00E-02,2.26E-04,2.86E+01,9.50E-02 +115,3.56E-05,316.8,8.15E+11,2.40E-01,5.00E-03,2.04E-04,3.89E+01,6.00E-02 +120,2.27E-05,380,4.33E+11,2.00E-01,5.00E-04,1.85E-04,5.00E+01,3.00E-02 diff --git a/afgl/midlatitude summer.ods b/afgl/midlatitude summer.ods new file mode 100644 index 0000000000000000000000000000000000000000..2be2188e751213409230b956d255a208a0ff64c1 GIT binary patch literal 24121 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 o*B18gp1)>~`^@~)q_zK$rQ!ZC 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 literal 0 HcmV?d00001 diff --git a/afgl/subarctic summer.csv b/afgl/subarctic summer.csv new file mode 100644 index 0000000..367ff57 --- /dev/null +++ b/afgl/subarctic summer.csv @@ -0,0 +1,52 @@ +subarctic summer,,,,,,,, +altitude Km,pressure mB,temp K,mol*cm-3,h2o ppmv,o3 ppmv,n2o ppmv,co ppmv,ch4 ppmv +0,1010,287.2,2.55E+19,1.19E+04,0.0241,0.31,0.15,1.7 +1,896,281.7,2.31E+19,8.70E+03,0.0294,0.31,0.145,1.7 +2,792,276.3,2.08E+19,6.75E+03,0.0338,0.31,0.14,1.7 +3,700,270.9,1.87E+19,4.82E+03,0.0389,0.31,0.135,1.7 +4,616,265.5,1.68E+19,3.38E+03,0.0448,0.308,0.131,1.7 +5,541,260.1,1.51E+19,2.22E+03,0.0533,0.302,0.13,1.69 +6,474,253.1,1.36E+19,1.33E+03,0.0656,0.291,0.129,1.67 +7,413,246.1,1.22E+19,7.97E+02,0.0774,0.282,0.125,1.65 +8,359,239.2,1.09E+19,4.00E+02,0.0911,0.276,0.119,1.63 +9,311,232.2,9.70E+18,1.30E+02,0.142,0.27,0.109,1.62 +10,267,225.2,8.62E+18,4.24E+01,0.189,0.265,0.0996,1.58 +11,230,225.2,7.40E+18,1.33E+01,0.305,0.26,0.0896,1.54 +12,198,225.2,6.36E+18,6.00E+00,0.41,0.255,0.0781,1.51 +13,170,225.2,5.47E+18,4.45E+00,0.5,0.249,0.0637,1.47 +14,146,225.2,4.70E+18,4.00E+00,0.6,0.243,0.0503,1.43 +15,126,225.2,4.06E+18,4.00E+00,0.7,0.236,0.0394,1.39 +16,108,225.2,3.48E+18,4.00E+00,0.8,0.228,0.0307,1.34 +17,2.8,225.2,2.99E+18,4.05E+00,1,0.218,0.0249,1.29 +18,79.8,225.2,2.57E+18,4.30E+00,1.3,0.204,0.0197,1.23 +19,68.6,225.2,2.21E+18,4.50E+00,1.7,0.182,0.0155,1.16 +20,59,225.2,1.90E+18,4.60E+00,2.1,0.157,0.0133,1.07 +21,50.7,225.2,1.63E+18,4.70E+00,2.7,0.135,0.0123,0.99 +22,43.6,225.2,1.40E+18,4.80E+00,3.3,0.122,0.0123,0.917 +23,37.5,225.2,1.21E+18,4.83E+00,3.7,0.11,0.0131,0.857 +24,32.3,226.6,1.03E+18,4.85E+00,4.2,0.0989,0.014,0.801 +25,27.8,228.1,8.83E+17,4.90E+00,4.5,0.0878,0.0151,0.748 +27.6,19.2,231,6.03E+17,4.95E+00,5.3,0.0733,0.0165,0.696 +30,13.4,235.1,4.13E+17,5.00E+00,5.7,0.0594,0.0181,0.644 +32.6,9.4,240,2.84E+17,5.00E+00,6.9,0.0415,0.02,0.589 +35,6.61,247.2,1.94E+17,5.00E+00,7.7,0.0303,0.0218,0.524 +37.5,4.72,254.6,1.34E+17,5.00E+00,7.8,0.0195,0.0234,0.451 +40,3.4,262.1,9.40E+16,5.00E+00,7,0.0127,0.025,0.371 +42.5,2.48,269.5,6.67E+16,5.00E+00,5.4,9.00E-03,0.0265,0.299 +45,1.82,273.6,4.82E+16,5.00E+00,4.2,6.29E-03,0.0281,0.245 +47.5,1.34,276.2,3.51E+16,5.00E+00,3.2,4.56E-03,0.03,0.2 +50,0.987,277.2,2.59E+16,4.95E+00,2.5,2.80E-03,0.0322,0.166 +55,5.37E-01,274,1.42E+16,4.85E+00,1.7,1.77E-03,0.0365,0.15 +60,2.88E-01,262.7,7.95E+15,4.50E+00,1.2,1.21E-03,0.0459,0.15 +65,0.147,239.7,4.45E+15,4.00E+00,0.8,8.87E-04,0.0838,0.15 +70,0.071,216.6,2.38E+15,3.30E+00,0.4,6.76E-04,0.118,0.15 +75,3.20E-02,193.6,1.20E+15,2.7,0.2,5.54E-04,0.303,0.15 +80,1.25E-02,170.6,5.31E+14,2,0.18,4.65E-04,0.789,0.15 +85,4.51E-03,161.7,2.02E+14,1.33,0.65,3.98E-04,1.82,0.15 +90,1.61E-03,161.6,7.22E+13,0.85,0.9,3.05E-04,3.4,0.14 +95,6.06E-04,176.8,2.48E+13,0.54,0.8,2.71E-04,5.92,0.13 +100,2.48E-04,190.4,9.44E+12,0.4,0.4,2.44E-04,10.4,0.12 +105,1.13E-04,226,3.62E+12,0.34,0.2,2.21E-04,18.8,0.11 +110,6.00E-05,270.1,1.61E+12,0.28,0.05,2.02E-04,28.7,0.095 +115,3.54E-05,322.7,7.95E+11,0.24,0.005,1.84E-04,38.9,0.06 +120,2.26E-05,380,4.31E+11,0.2,0.0005,0.000185,50,0.03 diff --git a/afgl/subarctic summer.ods b/afgl/subarctic summer.ods new file mode 100644 index 0000000000000000000000000000000000000000..7c19944eb0fc1f239fbeb17492a56cdee1309217 GIT binary patch literal 21815 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 literal 0 HcmV?d00001 diff --git a/afgl/subarctic winter.csv b/afgl/subarctic winter.csv new file mode 100644 index 0000000..4e32b6b --- /dev/null +++ b/afgl/subarctic winter.csv @@ -0,0 +1,52 @@ +subarctic winter,,,,,,,, +altitude Km,pressure mB,temp K,mol*cm-3,h2o ppmv,o3 ppmv,n2o ppmv,co ppmv,ch4 ppmv +0,1.01E+03,257.2,2.86E+19,1.41E+03,1.80E-02,0.31,3.20E-01,1.70E+00 +1,8.88E+02,239.1,2.48E+19,1.62E+03,2.00E-02,0.31,3.20E-01,1.70E+00 +2,7.78E+02,255.9,2.20E+19,1.43E+03,2.34E-02,0.31,3.20E-01,1.70E+00 +3,6.80E+02,252.7,1.95E+19,1.17E+03,2.77E-02,0.31,3.20E-01,1.70E+00 +4,5.93E+02,247.7,1.74E+19,7.90E+03,3.25E-02,0.308,3.20E-01,1.70E+00 +5,5.52E+02,240.9,1.55E+19,4.31E+02,3.80E-02,0.302,3.20E-01,1.69E+00 +6,4.47E+02,234.1,1.38E+19,2.70E+02,4.45E-02,0.291,3.20E-01,1.67E+00 +7,3.85E+02,227.3,1.23E+19,1.47E+02,7.25E-02,0.282,3.20E-01,1.65E+00 +8,3.31E+02,220.6,1.09E+19,3.38E+01,1.04E-01,0.276,3.20E-01,1.63E+00 +9,2.28E+02,217.2,9.44E+18,2.98E+01,2.10E-01,0.27,3.16E-01,1.62E+00 +10,2.42E+02,217.2,8.07E+18,2.00E+01,3.00E-01,0.265,3.10E-01,1.58E+00 +11,2.07E+02,217.2,6.90E+18,1.00E+01,3.50E-01,0.26,2.90E-01,1.54E+00 +12,1.77E+02,217.2,5.89E+18,6,4.00E-01,0.255,2.94E-01,1.51E+00 +13,1.51E+02,217.2,5.04E+18,4.45,6.50E-01,0.249,2.86E-01,1.47 +14,1.29E+02,217.2,4.31E+18,4.5,9.00E-01,0.243,2.80E-01,1.43 +15,1.10E+02,217.2,3.68E+18,4.55,1.20E+00,0.236,2.70E-01,1.39 +16,9.43E+01,216.6,3.16E+18,4.65,1.50E+00,0.228,2.61E-01,1.34 +17,8.06E+01,216,2.70E+18,4.65,1.90E+00,0.218,2.42E-01,1.29E+00 +18,6.88E+01,215.4,2.32E+18,4.75,2.45E+00,0.204,2.17E-01,1.23E+00 +19,5.88E+01,214.8,1.98E+18,4.75,3.1,0.182,1.84E-01,1.16E+00 +20,5.01E+01,214.2,1.70E+18,4.85,3.7,0.157,1.62E-01,1.08 +21,4.28E+01,213.6,1.45E+18,4.85,4,0.135,1.36E-01,1.01E+00 +22,3.65E+01,213,1.24E+18,4.9,4.2,0.122,1.23E-01,9.56E-01 +23,3.11E+01,212.4,1.06E+18,4.95,4.50E+00,0.11,1.12E-01,9.01E-01 +24,2.65E+01,211.8,9.07E+17,5,4.6,0.0989,1.04E-01,8.48E-01 +25,2.26E+01,211.2,7.74E+17,5,4.7,0.0878,9.57E-02,7.96E-01 +27.6,1.51E+01,213.6,5.13E+17,5,4.9,0.0733,6.60E-02,7.45E-01 +30,1.02E+01,216,3.42E+17,5,5.4,0.0594,7.31E-02,6.94E-01 +32.6,6.91E+00,218.5,2.29E+17,5,5.9,0.0415,5.71E-02,6.43E-01 +35,4.701,222.3,1.53E+17,5,6.2,0.0303,4.67E-02,5.88E-01 +37.5,3.23,228.5,1.03E+17,5,6.25,0.0195,3.44E-02,5.24E-01 +40,2.243,234.7,6.93E+16,5,5.9,0.0127,2.47E-02,4.51E-01 +42.5,1.57E+00,240.8,4.73E+16,5,5.10E+00,9.00E-03,1.63E-02,3.71E-01 +45,1.113,247,3.27E+16,5,4.1,6.29E-03,1.07E-02,3.00E-01 +47.5,7.90E-01,253.2,2.26E+16,5,3.00E+00,4.56E-03,7.06E-03,2.45E-01 +50,5.72E-01,259.3,1.60E+16,4.95E+00,2.6,2.80E-03,3.97E-03,1.98E-01 +55,2.99E-01,259.1,8.36E+15,4.85,1.60E+00,1.77E-03,2.51E-03,1.59E-01 +60,1.55E-01,250.9,4.48E+15,4.50E+00,0.95,1.21E-03,1.73E-03,1.50E-01 +65,7.90E-02,248.4,2.31E+15,4.00E+00,6.50E-01,8.87E-04,1.26E-03,1.50E-01 +70,4.00E-02,245.4,1.18E+15,3.3,0.5,6.76E-04,9.60E-04,1.50E-01 +75,2.00E-02,234.7,6.18E+14,2.70E+00,3.30E-01,5.54E-04,7.55E-04,1.50E-01 +80,9.66E-03,223.9,3.13E+14,2,1.30E-01,4.65E-04,6.10E-04,1.50E-01 +85,4.50E-03,213.1,1.53E+14,1.33,0.75,3.98E-04,5.02E-04,1.50E-01 +90,2.02E-03,202.3,7.24E+13,8.50E-01,0.8,3.05E-04,4.21E-04,1.40E-01 +95,9.07E-04,211,3.12E+13,5.40E-01,0.8,2.71E-04,3.58E-04,1.30E-01 +100,4.23E-04,218.5,1.40E+13,0.4,0.4,2.44E-04,3.08E-04,1.20E-01 +105,2.07E-04,234,6.41E+12,0.34,0.2,2.21E-04,2.68E-04,1.10E-01 +110,1.08E-04,252.6,3.10E+12,0.28,0.05,2.02E-04,2.35E-04,9.50E-02 +115,6.00E-05,288.5,1.51E+12,0.24,0.005,1.84E-04,2.08E-04,6.00E-02 +120,3.59E-05,333,7.81E+11,0.2,5.00E-04,0.000185,1.85E-04,3.00E-02 diff --git a/afgl/subarctic winter.ods b/afgl/subarctic winter.ods new file mode 100644 index 0000000000000000000000000000000000000000..2493b34a78a9da923c70852d8eeedc22fd60f980 GIT binary patch literal 23786 zcmb4q1yCfB>I3pMs*gxg-D=<4NJ2Phw2QwoF z2U{x>BWEjsJ(H`wDI>rLXa!^hIGEX+0!&=&%

Rfeub)My5bZGc)HO|EW#Bnvq_9 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 P-@dGFla90Q-KYNnY0g&g literal 0 HcmV?d00001 diff --git a/afgl/tropical.csv b/afgl/tropical.csv new file mode 100644 index 0000000..a912a87 --- /dev/null +++ b/afgl/tropical.csv @@ -0,0 +1,52 @@ +tropical,,,,,,,, +altitude Km,pressure mB,temp K,mol*cm-3,h2o ppmv,o3 ppmv,n2o ppmv,co ppmv,ch4 ppmv +0,1.01E+03,299.7,2.45E+19,2.59E+04,2.97E-02,3.20E-01,1.50E-01,1.70E+00 +1,9.04E+02,293.7,2.23E+19,1.25E+04,3.15E-02,3.20E-01,1.45E-01,1.70E+00 +2,8.05E+02,287.7,2.03E+19,1.53E+04,3.34E-02,3.20E-01,1.40E-01,1.70E+00 +3,7.15E+02,283.7,1.83E+19,8.60E+03,3.50E-02,3.20E-01,1.35E-01,1.70E+00 +4,6.33E+02,277,1.66E+19,4.44E+03,3.56E-02,3.20E-01,1.31E-01,1.70E+00 +5,5.59E+02,270.3,1.50E+19,3.35E+03,3.77E-02,3.20E-01,1.30E-01,1.70E+00 +6,4.92E+02,263.6,1.35E+19,2.10E+03,3.99E-02,3.20E-01,1.29E-01,1.70E+00 +7,4.32E+02,257,1.22E+19,1.29E+03,4.22E-02,3.20E-01,1.25E-01,1.70E+00 +8,3.78E+02,250.3,1.10E+19,7.64E+02,4.47E-02,3.20E-01,1.19E-01,1.70E+00 +9,3.29E+02,243.6,9.79E+18,4.10E+02,5.00E-02,3.20E-01,1.09E-01,1.69E+00 +10,2.86E+02,237,8.75E+18,1.91E+02,5.60E-02,3.18E-01,9.96E-02,1.69E+00 +11,2.47E+02,230.1,7.78E+18,7.31E+01,6.61E-02,3.14E-01,8.96E-02,1.68E+00 +12,2.13E+02,223.6,6.90E+18,2.91E+01,7.82E-02,3.10E-01,7.81E-02,1.66E+00 +13,1.82E+02,217,6.08E+18,9.00E+00,9.29E-02,3.05E-01,6.37E-02,1.65E+00 +14,1.58E+02,210.3,5.38E+18,6.22E+00,1.05E-01,3.00E-01,5.03E-02,1.63E+00 +15,1.32E+02,203.7,4.70E+18,4.00E+00,1.26E-01,2.94E-01,3.94E-02,1.61E+00 +16,1.11E+02,197,4.08E+18,3.00E+00,1.44E-01,2.88E-01,3.07E-02,1.58E+00 +17,9.37E+01,164.8,3.49E+18,2.90E+00,2.50E-01,2.78E-01,2.49E-02,1.55E+00 +18,7.89E+01,168.8,2.88E+18,2.75E+00,5.00E-01,2.67E-01,1.97E-02,1.52E+00 +19,6.66E+01,202.7,2.38E+18,2.60E+00,9.50E-01,2.53E-01,1.55E-02,1.48E+00 +20,5.65E+01,206.7,1.98E+18,2.60E+00,1.40E+00,2.37E-01,1.33E-02,1.42E+00 +21,4.80E+01,210.7,1.65E+18,2.65E+00,1.80E+00,2.19E-01,1.23E-02,1.36E+00 +22,4.09E+01,214.6,1.38E+18,2.80E+00,2.40E+00,2.05E-01,1.23E-02,1.27E+00 +23,3.50E+01,217,1.17E+18,2.90E+00,3.40E+00,1.97E-01,1.31E-02,1.19E+00 +24,3.00E+01,219.2,9.92E+17,3.20E+00,4.30E+00,1.88E-01,1.40E-02,1.12E+00 +25,2.57E+01,221.4,8.41E+17,3.25E+00,5.40E+00,1.76E-01,1.50E-02,1.06E+00 +27.6,1.76E+01,227,5.63E+17,3.60E+00,7.80E+00,1.59E-01,1.60E-02,9.87E-01 +30,1.22E+01,232.3,3.81E+17,4.00E+00,9.30E+00,1.42E-01,1.71E-02,9.14E-01 +32.6,8.52E+00,237.7,2.60E+17,4.30E+00,9.85E+00,1.17E-01,1.85E-02,8.30E-01 +35,6.00E+00,243.1,1.79E+17,4.60E+00,9.70E+00,9.28E-02,2.00E-02,7.46E-01 +37.5,4.26E+00,248.5,1.24E+17,4.90E+00,8.80E+00,6.69E-02,2.15E-02,6.62E-01 +40,3.05E+00,254,8.70E+16,5.20E+00,7.50E+00,4.51E-02,2.33E-02,5.64E-01 +42.5,2.20E+00,259.4,6.15E+16,5.50E+00,5.90E+00,2.75E-02,2.63E-02,4.61E-01 +45,1.59E+00,264.8,4.35E+16,5.70E+00,4.50E+00,1.59E-02,3.06E-02,3.63E-01 +47.5,1.16E+00,269.6,3.12E+16,5.90E+00,3.45E+00,9.38E-03,3.80E-02,2.77E-01 +50,8.54E-01,270.2,2.29E+16,6.00E+00,2.80E+00,4.75E-03,6.25E-02,2.10E-01 +55,4.56E-01,263.4,1.26E+16,6.00E+00,1.80E+00,3.00E-03,1.48E-01,1.65E-01 +60,2.39E-01,253.1,6.84E+15,6.00E+00,1.10E+00,2.07E-03,2.93E-01,1.50E-01 +65,1.21E-01,236,3.72E+15,5.40E+00,6.50E-01,1.51E-03,5.59E-01,1.50E-01 +70,5.80E-02,218.9,1.92E+15,4.50E+00,3.00E-01,1.15E-03,1.08E+00,1.50E-01 +75,2.60E-02,201.8,9.34E+14,3.30E+00,1.80E-01,8.89E-04,1.90E+00,1.50E-01 +80,1.10E-02,184.8,4.31E+14,2.10E+00,3.30E-01,7.06E-04,2.96E+00,1.50E-01 +85,4.40E-03,177.1,1.80E+14,1.30E+00,5.00E-01,5.72E-04,4.53E+00,1.50E-01 +90,1.72E-03,177,7.04E+13,8.50E-01,5.20E-01,4.71E-04,6.86E+00,1.40E-01 +95,6.88E-04,184.3,2.71E+13,5.40E-01,5.00E-01,3.93E-04,1.05E+01,1.30E-01 +100,2.89E-04,190.7,1.10E+13,4.00E-01,4.00E-01,3.32E-04,1.71E+01,1.20E-01 +105,1.30E-04,212,4.45E+12,3.40E-01,2.00E-01,2.84E-04,2.47E+01,1.10E-01 +110,6.47E-05,241.6,1.94E+12,2.80E-01,5.00E-02,2.44E-04,3.36E+01,9.50E-02 +115,3.60E-05,299.7,8.71E+11,2.40E-01,5.00E-03,2.12E-04,4.15E+01,6.00E-02 +120,2.25E-05,380,4.23E+11,2.00E-01,5.00E-04,1.85E-04,5.00E+01,3.00E-02 diff --git a/afgl/tropical.ods b/afgl/tropical.ods new file mode 100644 index 0000000000000000000000000000000000000000..5c6cc455871ce6e3da3eab8e1f67d6a86058fea1 GIT binary patch literal 23990 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�#qi4Y&q`DRt zK-y9I2Dqx>$+2PmZJ%rpMx8cazg~ZKT1#kT7(AB&%bITT>Iu-vHq``Z1@HRnKjKGS zHWO}foJUN8V(G&&o3&DtvtQbr#^Wy#`VQCGkZF#Lo=mh&;K_eEW2Ks=bnu)#S&C`X zm3CxQ+xZTx^M6r|U@2;C#r*vz@j7qQM@Sw~6l%dstH7&QCmQ4UIvcvt|Cv%pV`k%G zCxh$i(*$U$?3XO-Q{KWvDj>cHZ%s9a;ocgKo}0vwqDpymJ@XFke|E4*0|V^ARO+f0 z5s|-T%EzXl22{_{35TpZP+z?et2yavt<25YY%ytD0fG~+m&?!-Tsia3COor~e*>K9 zd*-t}_JwHxH8xBQp2!{F?@gtPmGOnOcOPsergboIBZNRa^F?6^T|rqE4>xpPb!?9? zIvQjx_Y467{xoyNL0o6M@*hanzU$(NI*;@?{(z2s8MHv|kc{4>e6uX0ore&8bAn*1 z3I}t4IQ!GigSPMYVXeA|iv^z-h7Os0{wiI+bgaqPnlPA+lw3b~Eg5T~8lFtzG7Fc* znqu=9a$Qc*_>d@=9ZSL{oW~_qwPK|KZEkjStsMVZ(!89mn4G3~rCa-)dxYTaU$E*G zB_~mehV+}k7?I4E<4I-MMKh(o!DSU3e`(7plEZlc#RP9rNa2HgC#NaZKO7-i?gbCN zV^b}QoynDoz~*(}eme=oC6V9$R{Jd6V#g2!iMOBF^3a9O_$8ysfuca3XKo{u@X{7t7#cV})9)zEx8{5h@pp+LVgqw5D4Qrf=`I{c|lC^N_6p<|5nMt;KFmIvdwt=3<;rg*)>LUFr`%RA}%Z$FL4RFY*& z=gZ)4q5>Y&e$ngJ`~oHN&6K}qex>Vs9!#xoui&MkLwSv$gV$BF@e4_-2$UL3@s%#B z!Mk|!XX>Y6QiRjKaI$Fkr=Uy43)!DiSj5MLxVJ{y(^p!!>y$4d20{}zc%4l;*%$`3 zJowLG!}?txc}3IEPaU2R#oRjDpF}yrdpoG>AOqXGlCsXy|E%v400Zak2QS+k2KSwu z0Jz;=gWk)Sq2Uj|O8yWfrWT1(D&f_IgMTK*6`s)MA}wPl7#G&e8yB%EB-wLDZj7(^ zs-@-bn`#yh*lHmvCEc|v(hu|v>Aa-phNP~r2Pg*<%#y~TraC=-%Pk}`7}vWl_!$vW`xt<)j@CWB8d!m zpoxKB%v=4~-+0i$4+^9vSMCopQm;N$fkp4uayV=zW4AdBKgIYXV+J;ZwhFF+$5x14 zP%l66$%vh4V1{aVw#ABxV@5K=S;FTkHll6f@E%_lLIiFReBcNZ%dd45;0E1l? z8BUSc; z=f5dw_|~Rz(Ejz(tLd;ElaG^?`?7>`-bVWc;JzH^_~(3=L+$!30soYfuQcGSg(kHcD>*76*kZK#1|u>X zJ*VJmFZgC~d0WxXq&8U6D0cXL0>jG>lexF{WMI^-LQCXm_iZiZJ;SF*#IhwmMMnNt z&SW+Fs)uE9#4hwvv+~w)QzLPbvntsgl&wN*T<1~CkDOsh zDf=#WBK54K#uQ7+c`b~35BgCU&G#$;#*0q`Aut_+l%&>3Wy zAg0b+7xRCP>)j-88LZs9PKl~>dqY9xzO6@^PWenb5lBaNDw~2~XdDe$U zJ<(IO>`p652xG{0>}R!Mo?aIXK(a1KsFB?-wIOa2=2sz05yP(uRXeg-%QT6$JMLdE z90d0n)$22coevuvq@7|$DQL-CRza_{p3js4+-W6V;(?H5Rij-8UV_xltfsVUOMrlyAUgm;Ox{c&K<$zZ*f?lVKGdF}Szm@1>LfgP9N^qskGQr`qE z$9BSDu{P1n1_e#yV~gm$;W%3o*#%#TQo8PJ5(MU38#VY91wh0`PS%4qd(Nf7`e-~q zBd-{lVdKb);|MbcPl|d9vpwTy8_Ah(!Cx!CV>x|hDf#y$GduL_h^hA)&~J8dotDT@ zrgx<}1&jK?(m3$BHO*hSfDO0pO0)N9UaGld=mFm@DxBd7V`?&KH;lPj(Dsrm5QsJG zckE$$qCK#y+BBqNVx0d=U++hkn;cV72dbLviO_*(Y<8ganHY*7 zX~DWyv|rGS4q7$JZL}q7wGtm2{X{ypi1IX9a*M|90zop)#_i0N@7uDKiYO%)x9}D~ zy<&drc|3Be=+&hAV0|%xw9E`i7od`~@0`G%*YEsP>22>UpIue}dBJVt9N*y`E~o{R zm;T`NN-Japvsrh6aU7TN1(9#V$LS*>MT*)h9vfCXGfa*ZXxS8^6}e&_&1FXPJFPY& zuE7O9(2$_7Q%?WMVS;+xYzJQ$Khic+N=4Se_xNN#dK`r zpN4TN7Bd+5jO=fPpGr(+p_pEQCpL52*!fw||L*Ef{XN|I06-`VGaqqljs=WfxUIkU z|3ddCV0hvrO9y=Z37coAYP>fspYBB?IyeJJ^=-ga!|GYe_$V9J$`Pef)jE~Yq{Ul~ zS!UbecWE|{k+4&N;oZ{6J7FaaYS3mvq#snQ=_l8m&d22Me61tCr@YuaeI?_vq!iCo zWAFbAAS@aD!l>$I-uKPSV%o2!po4UVXXE5H8nRswSKsQ!o=CYh{-wYaAgai?Urlg= z{+c0RF}R zWkqneJ&#bRlL68$$xMRDs=bx_0Hjeg98N>gE6hmoA$q2=-q4QsPFZTUt_-bisB%Oz zJpSrwB;qUSZi|!HT!Zy`NLu51?0ahoEov%8@sh2ei+h{cnyLbAGw;-n1L33u=D_8F z3HRxPg&DHs#Z`{cQ%^s%fOt~^EESXMdR??C))S1IBNSz=HCU*mU{tF=5C)XMsoo#K znMNgiP%6=wx?FSfW-iR@R1wptP551d3x2}_YOIbI0w0R)#FMoW(|2rb&wlb^p~!ha zjd7`ou0BAAyPGZYk|P9<6H~pnsS;6NF;Tdr&(>G(b@kuF0c_p(u zp-dZ;9_nWa*NcpKiH^8(Fg=wOBzn0`q4!kUw}7#yt`V1e;D1I!d^9H?&T=gI^)i~) zu769gLWhts=S9P6%i(fdoDE;Cg;xzIP?2j$upN#qAjfVR_!T*>p7^O8-HS`?HxmcF<*TZeMgcg9amyp|?swhn#5>i;-@WAXK?Z;vTFn4&PYBU)Qs9)jd2t`lNss?L6x2@Yn7rFQhbwoWCkI z-%F2^elk-{C2;l2E^sHy6iy)RBqDv%4dxn2_FD1?BvF8C(mYWgnh&C6uDR{;{IWzw1-;T#6(YC`p6*s%dYM{zi^hZ)+9P1eaZArBNL211(y_CdCGEaaV4ta1Xi`sMG%4`$CQ!7#j~9 z8alDFHEp4YpQ4bW&byJQX@1_~!PPf1^o7+lc8MhRY0dVNL!Z&FFalGTor!qKqA2mlIx& z&G;10fVq!x;`Qp?!fy$_$7A9uoy(spRy?MPiHao{6c{wPh{+6{0;tJQaWGKyn?KR1 z$~dW^uj^IN)fdO%&dJR2IM0oogt!wQLV>4jFaR0viEp!ylPh^QJuaH9@}_#%yAT|7 z5j?@X4K9bjaoBPR0;aQre^H?ZS%RC#2rXtTTm zB@-JIOuP##p!X_N@d7GmB?wY{=X0l(>TBiabQwSN-zY+u_Oy8O*ajIdP-~bnfr+m+ z0?K1h^F5rYQ~XHznNG5gOoNfZvmMAtN%=PYpIVs`3Y@rnC%0B$d|V6ei~tqK&d!}W>!SnW5KA|U1OVUMtWcSt|P zo*zeZs}Cc<)5T0nrlbI?7>KX4JrdjT+i0AqClT$X3TL4%r_V*k!alc09|N;3T1Hmv z!EbuapGVn@C6F+?1?xtIgCPDhCV%PUWELuQGKey0dS2`~nX_%!^=F3WzK$gCC zK#PW_o-@R<7^P)k`#p5t2zqw_$g|?f7+epFQ}_MS=m>RhZhsG{aEv^Ut&z?&%!IF7 zw6Q`>$TTZPac{<%_;)4gBmp|b@OZ06ys6!sZ! zf1rE}y99aC`maL;6_BW)sG#@s@7E@cUdc-If5906iPfvn-r>9FRL?P~)eBHk>Q|ZZ zS^$Li=!q$T3!2mFHFMCAL;M8hKetUc0#fkc{PEm+6P|wSBB{e0$g-AD z-)b*7Px>A2&%*)%g(d<1G6N$*Hz3gHn7@}xZz7nQBvC@#)^-39{irSi>Ck48Lwb%?j|nMbi~wd9pKoA(&bwKje`YZjj_h)V zGlE>h^nAAWStUo*O9~g<@I*|5jK9lM^Mvi`cjK9#t@dl_(J%%mj=Kvyw;e~ zsac=c#-evx9%O$YP|kiE`4=K_HQDpJH$^crh$TwLFYi=En?wdt>|l0;)pcY;k>=T> zf}GAm8pj0{2p(H2S$X6L+~QR-J;?1m7s$uYe(_p!@r$dQtvc+}0uu zg`O8IyT3q@NmnC@aHIc=gRxUV5+m}D!}BPVlHzRrsCA!61XYJjdr42)k6Vtrt?G5i zOvcH@c{Zi)x*C?`*rBMl&00=d2Np0y?QS3xA3}K@~tyb1WzT`t#-2HCsuQq8@WgA zthnp%7~DN1Mc!*_w7*XDyPVRN)}`_er}J`%928po_$aZ=`cjMZABp7LIEW(neMll7 zTA$T>vxHdTHtg6zl~cPu$McYnw>ps4xrgWx?ym@?t=C`-%VV?yV^MC?&uqIA7fUj$ z*HWgzr^a)ma6q@DC+(upWdQj!_Jy=U*xwNF&`^M%+P5sv1@Uw!k)dJ5ZP zv*LBD(9Xr}@Ek_>bw@Q}eoR%`w~P07V>zA{kHPkxP!X{ySe=ZEhTM+~st^m%-2JBO zYjt@&EHkPb7yU!t(glOu(&lbS$*jpP{(}%6qLEGAsTj=1f1gI_6v~nJzQi3%*W6lp zvgl&^pP-!sj;X`A+wttnj@OOZ!}}*yhv7X?$0Dj%OY`MUCE*k2BLL3xi6$H1b+|Jf z=ty%y6^dtT=z=m{sr$ctq&&LcQ}0ttQziX7P_s4fPZ^W$8Sf|Dj|fsboJ8>ab`u z+@(v9$G0IBI5^>JK1nhH+Jq%O_AFw94Bl1Bki5eSub+wvNE!0f3cnX3TPW>>qc0kd zEm}&A4pk^rAuJKe@`oIBIDilWp) zRhR+I-Bji$;95*|3xFy{5?9zspIY@ND1lbLS&2YeH2!XR9I2oh+BXGs3 zcOgZ@N3NehDLQNh=maeG9O}u~$}tZG|(8Yh02&6lil1);Fv*i7ZxSQ(8W& z=^`XCcfj(6^j} z0|8_`_td|PNV(jB9B5> z5_i_ms6iMYY!WUWcVZH$C+3O6H>{kUPLyO=J13$7dN}MVZ%pG4WGZ?gxQ^!o^6prK-(4`N za7Rt!ThIO!K}P#sgr_;ZGoC+-|Am;+~UlB=htGWQ(_W&1~V#Tj{Psi3b3Gs zJpq4~>C)xViWrMV5NgE43D(}6g(lQ{X*|4d01gK8U|DqUvAp2o7C3(u-TLm`10m@{ zXTUK&vP$+I2Pf;*sqZmxe14Cc_ust`NovtU(^XcK7VRT2%07y7<ZZGNw# z9}54F<UJ4kncq|h^Y;hi?NxeE>E0bqnK>~mCq#EiCnGYbV zeGC3~r|+cj*%P6DNj9x+QBE;9%kuI&Xxs`(_$I^+n%!6t2IiuHh!1y~J$wu^04J@a z;={C!`F}bH>~hNfeqXwG6h0tj*~O3>ZKXn94UbATrMh8qJRmGd`X*dx(DG1iQl`3f zV78lAv#u>YCQ8nDabMHG*UnjJ6&G(ztQdO^Mc>JRd|J8zcS41bLGKzQQFAmQ`P?aHmL`T{dF<9kzZ{FKK{}vUR^#UI>qNd_kUy$=SS86;h}}PK&});4r!u$0 zX;-FaGutROs2=}p8z}C)KhZjzc3)2Uc2T3*pE@Q|3qR_RiuhzMte;;OC{ZE5&eciR zCzfFc#|KnXWATg<%Vg~zPSBdHDZXxFuAAKLTOLeB$ab%}qw#$!MmJvaDy+CiO(LBP zoR?!87*s3z7n_qe$MBy>A5WOE0*$%(0)^1czz7W!wKxVhRd`{$idY81Z{Z=BT=}xM z3I809isqbb{Q8NJtck9N;V2>)so!-sa}*vHlyIY4JR8M3$B}L=GYhq;|Gd(_|3gj ze;8+o>)(C;gx}|+;R&~lHL;19{>vw7s?as0hQqr+o%O^`%Y&D)4A~S&WEWh;y)xig zg6<_=v`~Nfh`(bK%uYzgFJyIv>&sVQRAF~gHXM<p`Z(8E<9x!E+bAC&w8d##0=rV~gnC>fy<0Ajlf{&!qD6|CKSuYa7 z1xN)VsQ;42m(f+Uw{Pkxtmn-0sx1bMjD^6?b3~`wLxpDUNX41TlvbOYx#C*op65o`|_#%gxpH5{ixI#0F+P~ko>n%i5 z;JE)M(y|IwHl^%H!laPJo||GsVDfx%M=^5?aB0 z*LlyyC}UL*57H&6=ydSis5B%0j2G(0Cvusc#CXYY#V&u?5^B5yJ{Qbtb9oL`L#30D zoAhl2R+Q9z_$OJeF3olmE8G3$LwnLdwP?$~;vgpl2<46U-Vu-u ze8=J*11BVtuEphzO&Wd*>&E{-rl{}$ki6Tw0EQvb^#}*k_kUsRV3MM8B2_~A0sniV$bWkN*Ms-3 zB5Y@CYGLN=@Ly>sj?4^>P6kfSj)n#f4F7jt)uBSISYdK$BRTwiXdy1qEMci*W04l2`c?*4R7 z1bp3&cY9mf+MP=}v)E9SyEmSQCz#Hre*se4u{S4ykN1ydx*Mz}>aH9S4tmZU9|uL6 zY7vvV9PM))SGxTSx?e^x+gCxZ*H`7&d>-{l-VS!Jn7;MsTb-V3e^E{*)s|Gwt}dIA zJno-u+1qSnDyNf800K0F&zhYt$H(VyU4X5~VH6aU3&Gl=PW*_xUqe@CO+5*f8xD(8 z84FI#Ri;VanjBa%ksNjRWel@-nyZ_nbZYn2stD?`tH}&n&Z}yfs7%>bJQPnko1R$@ z)poAHYmm#c6r23jIM$V!+>3>}qH;%h$>~++eOT z^k85`BC^b`Y1|Grt}^s03ID*Yr33S-sG1){-2HjCe$bVc9MkuBjSzDtx||#_oMvG| z)&VLUZK?b#yKYBwg!QM|g07Wr-CH2LGaA{`napEZuGmvl)_!3{e*kfBwz|t3Wue27ZM*wj&?XVD z6|&obhupe*ANtJlqBRSsIlJMRNtPwewTLA}ZkyK5<;sWKuHpWAW#3xduBdrB`^9=j zzD@4&ZSAT0i=$~-%w>%gy&ojYa~9C?SvQLWgXOe;iP9`4j%Xrd0s&rIh}yU-f#??yxVC6>=}?q$BI&#p~nxuEuaw~-Ok z065FHp!+OhsQHWzxnO6a-M+=)({BEy{NelhytqEN7AF|~kbhqO>N)ms+*GDVH8WNC z{8#^7OS;OJLEYPkqS%AkVS1Il_U&2Hoib{r%UV~C<8D%iM|%=`Ii1JVmw-+-rgE*T zs;zwe=*UVt>5IU-Qs$TqrJ;I@*PiZELH?3g(_F1!d@ISfnA0vvHiTNc3>TZ<#0pT} z+~n@2#&|z&TN)z$H2hZ9)y~ncE%A3fxm$NfRXr-r1Ta0mYW{rHrK{@J`sU!<${{cn z)u-N=Z{n^V#h!oBq%#RJBW}DG41D6NY(K1cuce;`S*S@fwmq6}$xJ4gUY2};>PiCT z+SFvl86w`hOIx<2oDAFraW2QSQvFB$i-nAxWFt`5JPdUX44!K-3wXw*X+jyrI24oIAN%Ae! zpB7jbZyL!WV{dj__3p0w)I(#Wr@MBqMf*`cSB}<-FZ9}PcK&H|QvEDIv)PZ_J(esx zuJoMyv6c$bQ8NL^>e_u|a@e+wQuzjhBmleGV#4=)C=DzV^{(m1m#7=a_fc3HQ)-JP zU$v~uZCz~nw;;=Wx$9QbErV*>?gyCDM$~s!y{{XK_xDS^Lw7yLm^nMArDZ$rIhutx z0F#dzOVNj1o#418;JMtw`7!ymcI}~4)WHeRxVZS<{Sp4K)ulU`tnT{_H0I9o7BlKq zAXj*HZQ|IdGt~`U86+0$drUg?M-JJYQrAfSs?pco(BaZ$DRH{WtLx}Zz$JFmhsM`c z_}aU5M@aA*+w}CM`0F4Gl8`Qh7XGi`Au#^>($BUMJUQxgz^nCF%^jD8;`c>mC16Fj z#9xe}1#WXy`ymtXCNi2jfv6Tl9e(oMIVy@)s!TW??l?aqCaxSOMzo$d^MjUC10Q{E zE)e{MwnbUn4xWd1ZwtHXC6@;9g&L=en$xQgjsGDjJi1GW;)geMf+Qk{I`+p{&XLge z@x$UTA7_W&Yx|oBXE@TELjtRtjN72^-R>cK%Th2y49Tr1K3wEJ=+OHdii$VoHLp5M zg$ys={(!_T?89e?hrz#}B37S>3#!cJ<=^M9)qL(}#;WyOCx9S4dm+#f72I}4;l{R- z6VyvyS+zDVVC5~SQ~&T=5q;Tp+)jk7YZf;m=uXApLOxX~=w|ZwgK2JWIz=gp+k7H& zhn5v$N16p8YzLLp)`QR%_5n0qtV|e!dyKH2b(OSv8Mh>3$j9^JRiLLN0HX^#z5gH9Q+TR4dR6^R#d;yMJ`PpH zau`ZnoUXA|IfEB!DOXrYYSWACGJqNZ z%X#~6r|EuTe||R13c|;9vXjwM=@P=P%;$y*>e0=18JC?3Z5RMIN#zPJDrr#+i2PxJplHDzf}cP+S^bK7 z?Ov82j7_9yDi@HtIzQ19qr1@9`A24k{v={vIkAQ6)5!hN*UVvA%z=b8llW`&!DZy0 z=*>~_l-Rf_@&oucAKlug2kJ;r->0t9y$q_0O()LK+dTQ#0Jj;tunaSWc+l7J-%E=-sa@l<<7<2CmY>UOT4u*;xdk zKPMIV1j@}dM-u;P+zle9rF#ttanUo@exeu|F9d)=Kt4=@$@qJPej%*~5KzK+_BqD>(8}J&;FG+A~v7g)y`77cx_ep_{>TaI_ zw@txO&9b8a74Rjq95Csbq%1hE9i3v$sc)w=oKgT9+!QK{J<;vNo10n@LY704=u~kD z=m73G@m_|EA7`;C?BYGuBDXY>x8(}hSk5rV^uGaek}B(IfiU_u`QG0lH1a(%lMrPv z8QubaGzs*Wp4@~cLQ(<_EcVI6j>U^+aG6N5z-1mr#fE`_DKt_Er>kP zWeSLfw<6u155f^+kyxRxF^>)4~{cQ zM9_Oq0%6?TEBQXS!>5W9Y&jr)22{rb`|1?q{_k zaoLG=*$zualEZQ#;EK@|!EiYXH%2hOTs~4Rh{8<#=>0@0Rj?4OD-rz}riR`o0pcK^ zD8eOO?4TJQ`QwYb9`3a*&38yLkt-)z`BDe(c`;B*_5_X?uug2jjR+VysFUU=tyFxD zVHHew-xv)Glp;A{JTm4`eknbQa01tgK&p{79V)aQ9E#!R%aT##5@tw$$xBhph`35{ zPeF6BqicDX)yD*gp6iA_5Fg)00cH`iYxp%?+221(M>9X0uW$?4Ad}67i3clRy3;d zjs%DxJUkA#O|U>v(o%r3DRDrE_`M@g%bj;df@7#2qX&(+s1f>@xDQ_ zM3fC;Evo3UcBFPQK6YtwXe$)$H34UfQ1H<9#bcR=n1K)B5hjMywk+BY5IGW6#1Ye; zAX8N;boHoq)B^lQI_6VIDB3V;Y+zJGEsKZ?jcF+sOX7?=P%&7DIQ$cx~)pAse1&o)WLB)_aGMTC7`Tc6FAoEtc@?2((P&~-mz?MOQ{M0MYtgb z%c){Se19gd!h*mze7%e`C;;5471FpErvxwk*xH_aOa|VI5XWAf8hcs$$OVTWjr!td zF9?nXFSO}b-hG&ou5yvdNXE}1u~(<%AlFv`RqpA9U}^MN@*2H-wM?^O^9G%!>0=Ao z7r1Z@7OoYP)m`tU*kczkfuQ*qf>D}g^anUt-HRIn=X(Ozz%K64<>emq6a(|G?R7s^ z@0_=NEkG29O^8v!6uGgEvNTWc34Ap~48u+!{o*CxlIw;1?j70TH#OYXI+{_P1iBSW z?`%02lt;K52=QMLuNfBkN)^mW2&x}FpEtJoPN%)a-Yd7O4OS)&_Tk}RF&}_&w5?75fr>l*~%6J=ZYPYSE71*3*gP@TYdLFpUh^wboC}| zj$A%}Lhgyv==sTT5Ij&K6lr|aiPBC}LU>_EVYFHx^Q5F)vp&7yNPp_t)uV^AFgkOt zDCx(U?P%ZYaPJ2sNgwIx_U!Pa7;nYpWNw_77u6NJlDuj3a6#Mo81>iPdcUir|FCPx ze8jdq*&uw@w=+ZJ`ugC8L_|X$(y{4VAp`(YdqQ)xEE*r{~3|$DzUQMJndTn%#+KAqk#qy25bCiReX0mKjAFfo;MyiNR=bDl zDsr;z@q_pz0t6H97L3(2w!D~~wwdkQl7>A@Dg^(vv z8Q;DepuL5Qr|#%x7O(KP$t@`%M%m^O_Kw4tVa3&j^YI7P#3O~AaZEiUVPD*Iwf7)g zd^WH|<3zW*Mb2=n`^#VJ*gg|uOvGYppYAV~ZOt?oTt@hPDIX}{aX5Yw=?!i043m*p zFi5%{vh%jUg+K(24P^2f153W`F-19;bga(=@?ScfSiRXj;H*P@q-6IzVDIH{;;i3V zLZax$s|Q`o3kT{FGKpIa1Ve@Awj~Hy)08qaQups5+(+Z;TQ{mY2XU?u#ndtI6o-B} zW8P@KJ>2ziCC*#~0N~!uG^alw?(Og=4^MAr8;{%Low@JwU|JaOs>$3UucZ_r4%DMU z;ZzprVp@&h!h2|QZa7H5?2&yZAY(hL`I&Ew^@dQn4(kjNV`%qk&{z0MJ_jGb>vf`hwtz*J|5T z>1Zx*S8ZAw@>gkG-{ka4q63Y}lAvKO)k(vLD8kudbxT%I=4uu!gC!+>h>p0mn~1)l zB}#72lRI6Qb6-0m^QZ@z0;xm_YZyf@D@(^y?W6(qGp=q(xjIgDgd#oLWvo* z^^L!3=TfL{GrfPv9{b9+iQcr}LNaZ?_+GJ#|=a^NHv@e3zQm5cp16n~y7D5IOD~dc^h7{>lm|m$FDjqpD+? zPZjz(nUK04desNGtDDj@z8jBhb4J=L~8tLlt@EwxUhmDVCS+hTZ_p(})(F)vCu?)St_NN>XOZJ>j|cTAlP z5PjNb8_o36t?yr}i}Z^tk!P?uie;U?=$d+6J}h7umAgDpeV`a7rNTv%{KmM;(VwN$ z^o5R)NQXRk2j5C9o1@UZ;7|M%+X!Y3PYZ)9<^z;>E~!;FwcrdVC-Y4d6O4{kkndBw z-*?e_Jv#iC;@Hm%6riT8MNt$9WiP`tRmGoVl-BhX^?daRu*dazzY_`6mXxa@GCo9Ul@8<00WlqiO{A*0YL9L# zWz=uP-3MWPH5z!`L_{po18QAZ?#yOcv_rZ-_|z!C_zY%&vi4D_L{t z#H+=5toW72QU%)YnrpB^v6ncQuymcQv~v6evIIV;?vl-ZS=S1G@+F_v&fS_-uad8I%z6YE! zp0Ajg(8UdAbO;Vatk=sVdRRc_30BSgijyM)=)D7cWs##tY^pfZ#@9s1Z6m8<{Hb4x z0tf?9sk|X<$`UN3m@IGENO8ELq+FzwB3@K4fhnTk+y0l^6~n@mSuV$;mCy}G2}Fv4 z!7$_6T{XI{0MkeDik;mgvxC?rrdIYUr7!S-y+=oP1qv>&TP1B7We ziCkht#X@Afl)idoc;T}TyzwEuYfsp1Idu0PlX$8R@~<|Wql&$ZU0HGmDOnvByX-tV#MP;(S~6;^{Gyo6`dOc z%#m5OZ{%8*#qW);RO%S~aW%U*0nC6sU#!qRJ~`+uNs8AXUysALB!i7`Y@>YUAPEU^@N7e zGyq&Qv>C@P`vi~ujY>KTo2=MA=-M5pTW_M4UVyK=_*hwV=bq0oWC>dqspx69hv6Lz z8ywkAn3O!|+{r_nG*%Wq*sodo}RMIa1uv+y1zI*Favpm%EZsn@J&g@p|ss z>}m0-iE0koWa@p#!0a^ky2q~UV&;iZE)k&fKt%@IljLubnhgxCW1(wjnfot-`lFCPSoMk^{+MPwORvysmDV5xYukyrx80Dt?2maUce;Ymz8&6LM zSG)f-0NeMCJ*Gs7p3RxZ>~Df!Jk-7~fI+QLn_Y`H4eNMN&Lw*{Q8M-wee*LL2~V9c z5u&Y+k8&CSiHC18Gd<3clhO?6rH$l2;4>SjUaISX>GmD`ySG%yryEB!dsoNJlRU-m zN;{*DMky$FfP&?_K^J$pSsPyCnuGWlH84dNH4x>yQ`#O3qsR7_uWU~Cs~cWfL-CDF zKpylNwnd3dJx1=&6ekPyKYKMMM!4pj#j6iFn`@nJea>LZoWB$WZ>1}B z$Z|&Q6psxILC?-M8-Ip+$~;dgN<2oVd5>wHIyfFD4k<{3{Llcsuy=3dZS5I(>dUvV)J)ouF1qc_s+VK?$Yf&AR? zGb=d1!eP}F@jPXdtQssm#s4Gb$4qL}rlI%Cl~n;k;qJXLHD7afu^m$|<=P1XOjQ+( zGvYUfKzT@R4H3zp`v$mG2(VVc_gAbwOR{cG;5cc8X@}`dA_dv_L(oQ@gOXRUiUM_ zYVvWqR$Hw;BmrSw`$&|DMFSNNITlTifk};te?-?`dikU*`V0R3&B08V@y%d>BnBpr z(||1+w<)>qtqEp_Mb5)q#ti3fE<}cuWPhxhZ9Nn?O4?M>*!Ttucxu5F4AzSd85I^XMqFWHPmsNT%|d95XaL+C|I_219w)=BqkZYISeo zbx3!!ydp3XK;GFw$~PgW(uX(t8VS{x96(K>2t4pK&OQlNBw9FvDIBAq-@6L6X5|(@ zCfXOyJp=?tgbOqH7bTE9BfBuwLE3_TqEL6WTWa-M#wR=%SbBa+Q6M+)!KKgp=|%^y zEB5}bbdcfzb>9i}1VW~t$5=6^lg4Q^M(((sSh`n`M z)wn6TZ9MW?bGvL-h*p}M68JQO$0SAAxgR^qy;0&c+aLd!J^*;i$|Haagc}axv^;wi zz@{z|j5dhP5dM%zd26w+9_e(Y{;*Gk2ssBi7nxRDeeT78#)ws{SUYe23VJ?EShK)t zeq?A9A@SM4!Db3`xC=9KUYnD@>sl*ZDU_{4T7K6t)HSqPvix007Z+|E(Yq-(*ycySj2*DquyP|Eo+lcdMc}IoEbN zyt^l2(9UZ9N+UfsFiDKhi$lOD5Ql&U52)pSZpi^Q(TlMJNkD?G=X^VCAMcoYy?_;V z1^Mkg)<>u|Gv1;&_WPbMGwE7Cb%1qqHj6?QGCat4rrmA5y+3o2s zNU;~wJW9FKuBfH91`ewWlItJ9VEGSrqhYEiW9Xj{GN@I1RUW)@k^4lXn7f@{7X>K{ ztgGzmqi(TY-GHx6@a{)%(jeLwIMyNC!!TPXA0ZR4j{1J|A5dBa-MJ@DjSv#b%oc35 z^ZcGs60(LGP3cpA%co-jWEz)QKvW*fqZ0&+8{#NGg8+bxl_H>ab#ua(}n$!C!3vu^2*;z)cQH%DX=!-Kyb!n8m*!{ZQil z8RgeVC;bb`&&s?%4|)2Y8p_SB0|3Ck O`Pkef9SNh`U;hJEi2b(! literal 0 HcmV?d00001 diff --git a/afgl/us standard.csv b/afgl/us standard.csv new file mode 100644 index 0000000..4fab994 --- /dev/null +++ b/afgl/us standard.csv @@ -0,0 +1,52 @@ +us standard,,,,,,,, +altitude Km,pressure mB,temp K,mol*cm-3,h2o ppmv,o3 ppmv,n2o ppmv,co ppmv,ch4 ppmv +0,1.01E+03,288.2,2.55E+19,7.75E+03,2.66E-02,0.31,1.50E-01,1.70E+00 +1,8.99E+02,281.7,2.31E+19,5.07E+03,2.93E-02,0.31,1.45E-01,1.70E+00 +2,7.95E+02,275.2,2.09E+19,4.63E+03,3.24E-02,0.31,1.40E-01,1.70E+00 +3,7.01E+02,268.7,1.89E+19,3.18E+03,3.32E-02,0.31,1.35E-01,1.70E+00 +4,6.17E+02,262.2,1.70E+19,2.16E+03,3.39E-02,0.308,1.31E-01,1.70E+00 +5,5.41E+02,255.7,1.53E+19,1.40E+03,3.77E-02,0.302,1.30E-01,1.70E+00 +6,4.72E+02,249.2,1.37E+19,9.25E+02,4.11E-02,0.291,1.29E-01,1.70E+00 +7,4.11E+02,242.7,1.23E+19,5.72E+02,5.01E-02,0.282,1.25E-01,1.70E+00 +8,3.57E+02,236.2,1.09E+19,3.67E+02,5.97E-02,0.276,1.19E-01,1.69E+00 +9,3.08E+02,229.7,9.72E+18,1.58E+02,9.17E-02,0.27,1.09E-01,1.69E+00 +10,2.65E+02,223.3,8.60E+18,7.00E+01,1.31E-01,0.265,9.96E-02,1.68E+00 +11,2.27E+02,216.8,7.59E+18,3.61E+01,2.15E-01,0.26,8.96E-02,1.66E+00 +12,1.94E+02,216.7,6.49E+18,19.1,3.10E-01,0.255,7.81E-02,1.65E+00 +13,1.56E+02,216.7,5.55E+18,10.9,3.85E-01,0.249,6.37E-02,1.63E+00 +14,1.42E+02,216.7,4.74E+18,5.93,5.03E-01,0.243,5.03E-02,1.61E+00 +15,1.21E+02,216.7,4.05E+18,5,6.51E-01,0.236,3.94E-02,1.58E+00 +16,1.04E+02,216.7,3.46E+18,3.95,8.70E-01,0.228,3.07E-02,1.55E+00 +17,8.65E+01,216.7,2.96E+18,3.85,1.19E+00,0.218,2.49E-02,1.52E+00 +18,7.57E+01,216.7,2.53E+18,3.83,1.59E+00,0.204,1.97E-02,1.48E+00 +19,6.47E+01,216.7,2.16E+18,3.85,2.03,0.182,1.55E-02,1.42E+00 +20,5.53E+01,216.7,1.85E+18,3.9,2.58,0.157,1.33E-02,1.36E+00 +21,4.73E+01,217.6,1.58E+18,3.98,3.03,0.135,1.23E-02,1.27E+00 +22,4.05E+01,218.6,1.34E+18,4.07,3.65,0.122,1.23E-02,1.19E+00 +23,3.47E+01,219.6,1.14E+18,4.2,4.17E+00,0.11,1.31E-02,1.12E+00 +24,2.97E+01,220.6,9.77E+17,4.3,4.63,0.0989,1.40E-02,1.06E+00 +25,2.55E+01,221.6,8.34E+17,4.43,5.12,0.0878,1.50E-02,9.87E-01 +27.6,1.74E+01,224,5.64E+17,4.58,5.8,0.0733,1.60E-02,9.14E-01 +30,1.20E+01,226.5,3.83E+17,4.73,6.55,0.0594,1.71E-02,8.30E-01 +32.6,8.01E+00,230,2.52E+17,4.83,7.37,0.0415,1.85E-02,7.46E-01 +35,5.746,236.5,1.75E+17,4.9,7.84,0.0303,2.01E-02,6.62E-01 +37.5,4.15,242.9,1.24E+17,4.95,7.8,0.0195,2.22E-02,5.64E-01 +40,2.871,250.4,8.31E+16,5.03,7.3,0.0127,2.50E-02,4.61E-01 +42.5,2.06E+00,257.3,5.80E+16,5.15,6.20E+00,9.00E-03,2.82E-02,3.63E-01 +45,1.491,264.2,4.09E+16,5.23,5.25,6.29E-03,3.24E-02,2.77E-01 +47.5,1.09E+00,270.6,2.92E+16,5.25,4.10E+00,4.56E-03,3.72E-02,2.10E-01 +50,7.98E-01,270.7,2.14E+16,5.23E+00,3.1,2.80E-03,4.60E-02,1.65E-01 +55,4.25E-01,260.8,1.18E+16,5.1,1.80E+00,1.77E-03,6.64E-02,1.50E-01 +60,2.19E-01,247,6.43E+15,4.75E+00,1.1,1.21E-03,1.07E-01,1.50E-01 +65,1.09E-01,233.3,3.39E+15,4.20E+00,7.00E-01,8.87E-04,1.86E-01,1.50E-01 +70,5.22E-02,219.6,1.72E+15,3.5,0.3,6.76E-04,3.06E-01,1.50E-01 +75,2.40E-02,208.4,8.35E+14,2.83E+00,2.50E-01,5.54E-04,6.38E-01,1.50E-01 +80,1.05E-02,198.6,3.83E+14,2.05,3.00E-01,4.65E-04,1.50E+00,1.50E-01 +85,4.46E-03,188.9,1.71E+14,1.33,0.5,3.98E-04,3.24E+00,1.50E-01 +90,1.84E-03,186.9,7.14E+13,8.50E-01,0.7,3.05E-04,5.84E+00,1.40E-01 +95,7.60E-04,188.4,2.92E+13,5.40E-01,0.7,2.71E-04,1.01E+01,1.30E-01 +100,3.20E-04,195.1,1.19E+13,0.4,0.4,2.44E-04,1.69E+01,1.20E-01 +105,1.45E-04,208.8,5.03E+12,0.34,0.2,2.21E-04,2.47E+01,1.10E-01 +110,7.10E-05,240,2.14E+12,0.28,0.05,2.02E-04,3.36E+01,9.50E-02 +115,4.01E-05,300,9.69E+11,0.24,0.005,1.84E-04,4.15E+01,6.00E-02 +120,2.54E-05,360,5.11E+11,0.2,5.00E-04,0.000185,5.00E+01,3.00E-02 diff --git a/afgl/us standard.ods b/afgl/us standard.ods new file mode 100644 index 0000000000000000000000000000000000000000..e2e9c3dd1ae8f8e79c84fe041ce089de89075aa7 GIT binary patch literal 23878 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 T$B-L0^P3O&rs;I)-d_C=&hdQ^ literal 0 HcmV?d00001 diff --git a/collins - scenario 1a.pyr b/collins - scenario 1a.pyr deleted file mode 100644 index 2a8ec6a..0000000 --- a/collins - scenario 1a.pyr +++ /dev/null @@ -1,78 +0,0 @@ -# mid latitude summer from Anderson 1986 -# these are duplciating scenarios from Collins et al 2006 as a means to validate, or not, PyRad against other LBL's. -# transmission is only processed up to the tropopause, rather than full height and atm constiuents is greatly reduced. - -surface: 1013.25, 294, 120, 100, 9.8 - -molecule: co2, .000287 -molecule: h2o, .018800 -molecule: o2, .20 -molecule: n2, .77 -molecule: ar, .009 -# molecule: ch4, .00000170 - molecule: o3, .00000003 -# molecule: n2o, .000000320 -# molecule: co, .000000150 - -lapse rate: boundary layer troposphere, 2, 285 -lapse rate: troposphere, 13, 216 -lapse rate: tropopause, 17, 215 -lapse rate: lower stratosphere, 27, 228 -lapse rate: stratosphere, 47.5, 275 -lapse rate: stratopause, 50, 276 -lapse rate: lower mesosphere, 55, 269 -lapse rate: mesosphere, 80, 174 -lapse rate: upper mesosphere, 85, 165 -lapse rate: mesopause, 90, 165 -lapse rate: thermosphere, 100, 190 -lapse rate: upper thermosphere, 120, 380 - -composition rate: WV boundary layer, 3, .005691, h2o -composition rate: WV troposphere, 5, .002266, h2o -composition rate: WV trop2, 6, .0015, h2o -composition rate: wv trop 3, 8, .000647, h2o -composition rate: wv tropopause, 11, .000099, h2o -composition rate: wv tropopause2, 12, .000030, h2o -composition rate: wv tropopause3, 13, .0000054, h2o -composition rate: wv stratosphere, 18, .000003, h2o -composition rate: wv strat2, 25, .0000045, h2o -composition rate: wv strat3, 50, .0000055, h2o -composition rate: wv strat3, 60, .000005, h2o -composition rate: wv meso, 90, .00000085, h2o -composition rate: wv thermo, 120, .0000002, h2o - -composition rate: ozone troposphere, 10, .00000013, o3 -composition rate: ozone tropopause, 17, .0000007, o3 -composition rate: ozone strat1, 35, .0000089, o3 -composition rate: ozone meso, 37, .0000087, o3 -composition rate: ozone meso2, 55, .0000017, o3 -composition rate: ozone meso3, 75, .00000018, o3 -composition rate: ozone meso4, 80, .00000018, o3 -composition rate: ozone meso5, 90, .00000076, o3 -composition rate: ozone thermo, 120, 0, o3 - -#composition rate: n2o 1, 8, .00000032, n2o -#composition rate: n2o 2, 16, .00000026, n2o -#composition rate: n2o 3, 20, .00000013, n2o -#composition rate: n2o 4, 25, .00000009, n2o -#composition rate: n2o 5, 45, .000000008, n2o -#composition rate: n2o 6, 120, 0, n2o - -#composition rate: co 1, 4, .00000013, co -#composition rate: co 2, 6, .000000128, co -#composition rate: co 3, 15, .000000038, co -#composition rate: co 4, 20, .00000012, co -#composition rate: co 5, 60, .00000012, co -#composition rate: co 6, 90, .0000029, co -#composition rate: co 7, 120, .000050, co - -#composition rate: ch4 1, 4, .00000017, ch4 -#composition rate: ch4 2, 9, .000000162, ch4 -#composition rate: ch4 3, 4, .00000017, ch4 -#composition rate: ch4 4, 19, .0000018, ch4 -#composition rate: ch4 5, 25, .00000078, ch4 -#composition rate: ch4 6, 55, .00000015, ch4 -#composition rate: ch4 7, 85, .00000015, ch4 -#composition rate: ch4 8, 120,.00000003, ch4 - - diff --git a/collins - scenario 2a.pyr b/collins - scenario 2a.pyr deleted file mode 100644 index 1717bab..0000000 --- a/collins - scenario 2a.pyr +++ /dev/null @@ -1,78 +0,0 @@ -# mid latitude summer from Anderson 1986 -# these are duplciating scenarios from Collins et al 2006 as a means to validate, or not, PyRad against other LBL's. -# transmission is only processed up to the tropopause, rather than full height and atm constiuents is greatly reduced. - -surface: 1013.25, 294, 120, 100, 9.8 - -molecule: co2, .000369 -molecule: h2o, .018800 -molecule: o2, .20 -molecule: n2, .77 -molecule: ar, .009 -# molecule: ch4, .00000170 - molecule: o3, .00000003 -# molecule: n2o, .000000320 -# molecule: co, .000000150 - -lapse rate: boundary layer troposphere, 2, 285 -lapse rate: troposphere, 13, 216 -lapse rate: tropopause, 17, 215 -lapse rate: lower stratosphere, 27, 228 -lapse rate: stratosphere, 47.5, 275 -lapse rate: stratopause, 50, 276 -lapse rate: lower mesosphere, 55, 269 -lapse rate: mesosphere, 80, 174 -lapse rate: upper mesosphere, 85, 165 -lapse rate: mesopause, 90, 165 -lapse rate: thermosphere, 100, 190 -lapse rate: upper thermosphere, 120, 380 - -composition rate: WV boundary layer, 3, .005691, h2o -composition rate: WV troposphere, 5, .002266, h2o -composition rate: WV trop2, 6, .0015, h2o -composition rate: wv trop 3, 8, .000647, h2o -composition rate: wv tropopause, 11, .000099, h2o -composition rate: wv tropopause2, 12, .000030, h2o -composition rate: wv tropopause3, 13, .0000054, h2o -composition rate: wv stratosphere, 18, .000003, h2o -composition rate: wv strat2, 25, .0000045, h2o -composition rate: wv strat3, 50, .0000055, h2o -composition rate: wv strat3, 60, .000005, h2o -composition rate: wv meso, 90, .00000085, h2o -composition rate: wv thermo, 120, .0000002, h2o - -composition rate: ozone troposphere, 10, .00000013, o3 -composition rate: ozone tropopause, 17, .0000007, o3 -composition rate: ozone strat1, 35, .0000089, o3 -composition rate: ozone meso, 37, .0000087, o3 -composition rate: ozone meso2, 55, .0000017, o3 -composition rate: ozone meso3, 75, .00000018, o3 -composition rate: ozone meso4, 80, .00000018, o3 -composition rate: ozone meso5, 90, .00000076, o3 -composition rate: ozone thermo, 120, 0, o3 - -#composition rate: n2o 1, 8, .00000032, n2o -#composition rate: n2o 2, 16, .00000026, n2o -#composition rate: n2o 3, 20, .00000013, n2o -#composition rate: n2o 4, 25, .00000009, n2o -#composition rate: n2o 5, 45, .000000008, n2o -#composition rate: n2o 6, 120, 0, n2o - -#composition rate: co 1, 4, .00000013, co -#composition rate: co 2, 6, .000000128, co -#composition rate: co 3, 15, .000000038, co -#composition rate: co 4, 20, .00000012, co -#composition rate: co 5, 60, .00000012, co -#composition rate: co 6, 90, .0000029, co -#composition rate: co 7, 120, .000050, co - -#composition rate: ch4 1, 4, .00000017, ch4 -#composition rate: ch4 2, 9, .000000162, ch4 -#composition rate: ch4 3, 4, .00000017, ch4 -#composition rate: ch4 4, 19, .0000018, ch4 -#composition rate: ch4 5, 25, .00000078, ch4 -#composition rate: ch4 6, 55, .00000015, ch4 -#composition rate: ch4 7, 85, .00000015, ch4 -#composition rate: ch4 8, 120,.00000003, ch4 - - diff --git a/collins - scenario 2b.pyr b/collins - scenario 2b.pyr deleted file mode 100644 index 81dc913..0000000 --- a/collins - scenario 2b.pyr +++ /dev/null @@ -1,78 +0,0 @@ -# mid latitude summer from Anderson 1986 -# these are duplciating scenarios from Collins et al 2006 as a means to validate, or not, PyRad against other LBL's. -# transmission is only processed up to the tropopause, rather than full height and atm constiuents is greatly reduced. - -surface: 1013.25, 294, 120, 100, 9.8 - -molecule: co2, .000574 -molecule: h2o, .018800 -molecule: o2, .20 -molecule: n2, .77 -molecule: ar, .009 -# molecule: ch4, .00000170 - molecule: o3, .00000003 -# molecule: n2o, .000000320 -# molecule: co, .000000150 - -lapse rate: boundary layer troposphere, 2, 285 -lapse rate: troposphere, 13, 216 -lapse rate: tropopause, 17, 215 -lapse rate: lower stratosphere, 27, 228 -lapse rate: stratosphere, 47.5, 275 -lapse rate: stratopause, 50, 276 -lapse rate: lower mesosphere, 55, 269 -lapse rate: mesosphere, 80, 174 -lapse rate: upper mesosphere, 85, 165 -lapse rate: mesopause, 90, 165 -lapse rate: thermosphere, 100, 190 -lapse rate: upper thermosphere, 120, 380 - -composition rate: WV boundary layer, 3, .005691, h2o -composition rate: WV troposphere, 5, .002266, h2o -composition rate: WV trop2, 6, .0015, h2o -composition rate: wv trop 3, 8, .000647, h2o -composition rate: wv tropopause, 11, .000099, h2o -composition rate: wv tropopause2, 12, .000030, h2o -composition rate: wv tropopause3, 13, .0000054, h2o -composition rate: wv stratosphere, 18, .000003, h2o -composition rate: wv strat2, 25, .0000045, h2o -composition rate: wv strat3, 50, .0000055, h2o -composition rate: wv strat3, 60, .000005, h2o -composition rate: wv meso, 90, .00000085, h2o -composition rate: wv thermo, 120, .0000002, h2o - -composition rate: ozone troposphere, 10, .00000013, o3 -composition rate: ozone tropopause, 17, .0000007, o3 -composition rate: ozone strat1, 35, .0000089, o3 -composition rate: ozone meso, 37, .0000087, o3 -composition rate: ozone meso2, 55, .0000017, o3 -composition rate: ozone meso3, 75, .00000018, o3 -composition rate: ozone meso4, 80, .00000018, o3 -composition rate: ozone meso5, 90, .00000076, o3 -composition rate: ozone thermo, 120, 0, o3 - -#composition rate: n2o 1, 8, .00000032, n2o -#composition rate: n2o 2, 16, .00000026, n2o -#composition rate: n2o 3, 20, .00000013, n2o -#composition rate: n2o 4, 25, .00000009, n2o -#composition rate: n2o 5, 45, .000000008, n2o -#composition rate: n2o 6, 120, 0, n2o - -#composition rate: co 1, 4, .00000013, co -#composition rate: co 2, 6, .000000128, co -#composition rate: co 3, 15, .000000038, co -#composition rate: co 4, 20, .00000012, co -#composition rate: co 5, 60, .00000012, co -#composition rate: co 6, 90, .0000029, co -#composition rate: co 7, 120, .000050, co - -#composition rate: ch4 1, 4, .00000017, ch4 -#composition rate: ch4 2, 9, .000000162, ch4 -#composition rate: ch4 3, 4, .00000017, ch4 -#composition rate: ch4 4, 19, .0000018, ch4 -#composition rate: ch4 5, 25, .00000078, ch4 -#composition rate: ch4 6, 55, .00000015, ch4 -#composition rate: ch4 7, 85, .00000015, ch4 -#composition rate: ch4 8, 120,.00000003, ch4 - - diff --git a/collins 1a 25 slices.pyr b/collins 1a 25 slices.pyr new file mode 100644 index 0000000..23a71bf --- /dev/null +++ b/collins 1a 25 slices.pyr @@ -0,0 +1,174 @@ +# atm profile for midlatitude summer + +# surface values (pressure, temperature, final height, initial layer thickness, acceleration of gravity, range min, range max) +surface: 1010.0, 294.2, 120, 400, 9.8, 100, 2500 + +# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile +# except for co2, o2, n2, and ar +molecule: co2, .000287 +molecule: h2o, 0.0186 +molecule: o2, .20 +molecule: n2, .77 +molecule: ar, .009 +#molecule: ch4, 1.6999999999999998e-06 +molecule: o3, 3.02e-08 +#molecule: n2o, 3.2e-07 +#molecule: co, 1.5e-07 + +# lapse rate profile +# rules are: name, final height, final value +# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule) +lapse rate: lapse rule 0, 1, 289.7 +lapse rate: lapse rule 1, 2, 295.2 +lapse rate: lapse rule 2, 3, 279.2 +lapse rate: lapse rule 3, 4, 273.2 +lapse rate: lapse rule 4, 5, 287.2 +lapse rate: lapse rule 5, 6, 261.2 +lapse rate: lapse rule 6, 7, 254.7 +lapse rate: lapse rule 7, 8, 248.2 +lapse rate: lapse rule 8, 9, 241.7 +lapse rate: lapse rule 9, 10, 235.3 +lapse rate: lapse rule 10, 11, 228.8 +lapse rate: lapse rule 11, 12, 222.3 +lapse rate: lapse rule 12, 13, 215.8 +lapse rate: lapse rule 13, 14, 215.7 +lapse rate: lapse rule 14, 15, 215.7 +lapse rate: lapse rule 15, 16, 215.7 +lapse rate: lapse rule 16, 17, 215.7 +lapse rate: lapse rule 17, 18, 216.8 +lapse rate: lapse rule 18, 19, 217.9 +lapse rate: lapse rule 19, 20, 219.2 +lapse rate: lapse rule 20, 21, 220.4 +lapse rate: lapse rule 21, 22, 221.6 +lapse rate: lapse rule 22, 23, 222.8 +lapse rate: lapse rule 23, 24, 223.9 +lapse rate: lapse rule 24, 25, 225.1 +lapse rate: lapse rule 25, 27.6, 228.5 +lapse rate: lapse rule 26, 30, 233.7 +lapse rate: lapse rule 27, 32.6, 239 +lapse rate: lapse rule 28, 35, 245.2 +lapse rate: lapse rule 29, 37.5, 251.3 +lapse rate: lapse rule 30, 40, 257.5 +lapse rate: lapse rule 31, 42.5, 263.7 +lapse rate: lapse rule 32, 45, 269.9 +lapse rate: lapse rule 33, 47.5, 275.2 +lapse rate: lapse rule 34, 50, 275.7 +lapse rate: lapse rule 35, 55, 269.3 +lapse rate: lapse rule 36, 60, 257.1 +lapse rate: lapse rule 37, 65, 240.1 +lapse rate: lapse rule 38, 70, 218 +lapse rate: lapse rule 39, 75, 196.1 +lapse rate: lapse rule 40, 80, 174.1 +lapse rate: lapse rule 41, 85, 165.1 +lapse rate: lapse rule 42, 90, 165 +lapse rate: lapse rule 43, 95, 178.3 +lapse rate: lapse rule 44, 100, 190.5 +lapse rate: lapse rule 45, 105, 222.2 +lapse rate: lapse rule 46, 110, 262.4 +lapse rate: lapse rule 47, 115, 316.8 +lapse rate: lapse rule 48, 120, 380 + +# h2o composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: h2o rule 0, 1, 0.0138, h2o +composition rate: h2o rule 1, 2, 0.00968, h2o +composition rate: h2o rule 2, 3, 0.00598, h2o +composition rate: h2o rule 3, 4, 0.00381, h2o +composition rate: h2o rule 4, 5, 0.0022299999999999998, h2o +composition rate: h2o rule 5, 6, 0.0015099999999999998, h2o +composition rate: h2o rule 6, 7, 0.0010199999999999999, h2o +composition rate: h2o rule 7, 8, 0.000646, h2o +composition rate: h2o rule 8, 9, 0.00041299999999999996, h2o +composition rate: h2o rule 9, 10, 0.000247, h2o +composition rate: h2o rule 10, 11, 9.559999999999999e-05, h2o +composition rate: h2o rule 11, 12, 2.9399999999999996e-05, h2o +composition rate: h2o rule 12, 13, 8e-06, h2o +composition rate: h2o rule 13, 14, 4.9999999999999996e-06, h2o +composition rate: h2o rule 14, 15, 3.3999999999999996e-06, h2o +composition rate: h2o rule 15, 16, 3.2999999999999997e-06, h2o +composition rate: h2o rule 16, 17, 3.2e-06, h2o +composition rate: h2o rule 17, 18, 3.15e-06, h2o +composition rate: h2o rule 18, 19, 3.2e-06, h2o +composition rate: h2o rule 19, 20, 3.2999999999999997e-06, h2o +composition rate: h2o rule 20, 21, 3.45e-06, h2o +composition rate: h2o rule 21, 22, 3.6e-06, h2o +composition rate: h2o rule 22, 23, 3.8499999999999996e-06, h2o +composition rate: h2o rule 23, 24, 4e-06, h2o +composition rate: h2o rule 24, 25, 4.2e-06, h2o +composition rate: h2o rule 25, 27.6, 4.45e-06, h2o +composition rate: h2o rule 26, 30, 4.7e-06, h2o +composition rate: h2o rule 27, 32.6, 4.87e-06, h2o +composition rate: h2o rule 28, 35, 4.95e-06, h2o +composition rate: h2o rule 29, 37.5, 4.9999999999999996e-06, h2o +composition rate: h2o rule 30, 40, 5.0999999999999995e-06, h2o +composition rate: h2o rule 31, 42.5, 5.299999999999999e-06, h2o +composition rate: h2o rule 32, 45, 5.45e-06, h2o +composition rate: h2o rule 33, 47.5, 5.5e-06, h2o +composition rate: h2o rule 34, 50, 5.5e-06, h2o +composition rate: h2o rule 35, 55, 5.35e-06, h2o +composition rate: h2o rule 36, 60, 4.9999999999999996e-06, h2o +composition rate: h2o rule 37, 65, 4.4e-06, h2o +composition rate: h2o rule 38, 70, 3.7e-06, h2o +composition rate: h2o rule 39, 75, 2.95e-06, h2o +composition rate: h2o rule 40, 80, 2.1e-06, h2o +composition rate: h2o rule 41, 85, 1.33e-06, h2o +composition rate: h2o rule 42, 90, 8.499999999999999e-07, h2o +composition rate: h2o rule 43, 95, 5.4e-07, h2o +composition rate: h2o rule 44, 100, 4e-07, h2o +composition rate: h2o rule 45, 105, 3.4000000000000003e-07, h2o +composition rate: h2o rule 46, 110, 2.8e-07, h2o +composition rate: h2o rule 47, 115, 2.4e-07, h2o +composition rate: h2o rule 48, 120, 2e-07, h2o + +# o3 composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: o3 rule 0, 1, 3.3399999999999995e-08, o3 +composition rate: o3 rule 1, 2, 3.69e-08, o3 +composition rate: o3 rule 2, 3, 4.22e-08, o3 +composition rate: o3 rule 3, 4, 4.8199999999999995e-08, o3 +composition rate: o3 rule 4, 5, 5.5100000000000004e-08, o3 +composition rate: o3 rule 5, 6, 6.41e-08, o3 +composition rate: o3 rule 6, 7, 7.76e-08, o3 +composition rate: o3 rule 7, 8, 9.13e-08, o3 +composition rate: o3 rule 8, 9, 1.11e-07, o3 +composition rate: o3 rule 9, 10, 1.3e-07, o3 +composition rate: o3 rule 10, 11, 1.7899999999999997e-07, o3 +composition rate: o3 rule 11, 12, 2.23e-07, o3 +composition rate: o3 rule 12, 13, 3e-07, o3 +composition rate: o3 rule 13, 14, 4.3999999999999997e-07, o3 +composition rate: o3 rule 14, 15, 5e-07, o3 +composition rate: o3 rule 15, 16, 6e-07, o3 +composition rate: o3 rule 16, 17, 7e-07, o3 +composition rate: o3 rule 17, 18, 1e-06, o3 +composition rate: o3 rule 18, 19, 1.5e-06, o3 +composition rate: o3 rule 19, 20, 2e-06, o3 +composition rate: o3 rule 20, 21, 2.4e-06, o3 +composition rate: o3 rule 21, 22, 2.8999999999999998e-06, o3 +composition rate: o3 rule 22, 23, 3.3999999999999996e-06, o3 +composition rate: o3 rule 23, 24, 4e-06, o3 +composition rate: o3 rule 24, 25, 4.8e-06, o3 +composition rate: o3 rule 25, 27.6, 6e-06, o3 +composition rate: o3 rule 26, 30, 7e-06, o3 +composition rate: o3 rule 27, 32.6, 8.099999999999999e-06, o3 +composition rate: o3 rule 28, 35, 8.9e-06, o3 +composition rate: o3 rule 29, 37.5, 8.7e-06, o3 +composition rate: o3 rule 30, 40, 7.55e-06, o3 +composition rate: o3 rule 31, 42.5, 5.9e-06, o3 +composition rate: o3 rule 32, 45, 4.5e-06, o3 +composition rate: o3 rule 33, 47.5, 3.5e-06, o3 +composition rate: o3 rule 34, 50, 2.8e-06, o3 +composition rate: o3 rule 35, 55, 1.8e-06, o3 +composition rate: o3 rule 36, 60, 1.3e-06, o3 +composition rate: o3 rule 37, 65, 8e-07, o3 +composition rate: o3 rule 38, 70, 4e-07, o3 +composition rate: o3 rule 39, 75, 1.8999999999999998e-07, o3 +composition rate: o3 rule 40, 80, 2e-07, o3 +composition rate: o3 rule 41, 85, 5.699999999999999e-07, o3 +composition rate: o3 rule 42, 90, 7.5e-07, o3 +composition rate: o3 rule 43, 95, 7e-07, o3 +composition rate: o3 rule 44, 100, 4.03e-07, o3 +composition rate: o3 rule 45, 105, 2e-07, o3 +composition rate: o3 rule 46, 110, 5e-08, o3 +composition rate: o3 rule 47, 115, 5e-09, o3 +composition rate: o3 rule 48, 120, 5e-10, o3 + diff --git a/collins 1a thick.pyr b/collins 1a thick.pyr new file mode 100644 index 0000000..e1245fe --- /dev/null +++ b/collins 1a thick.pyr @@ -0,0 +1,174 @@ +# atm profile for midlatitude summer + +# surface values (pressure, temperature, final height, initial layer thickness, acceleration of gravity, range min, range max) +surface: 1010.0, 294.2, 120, 250, 9.8, 100, 2500 + +# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile +# except for co2, o2, n2, and ar +molecule: co2, .000287 +molecule: h2o, 0.0186 +molecule: o2, .20 +molecule: n2, .77 +molecule: ar, .009 +#molecule: ch4, 1.6999999999999998e-06 +molecule: o3, 3.02e-08 +#molecule: n2o, 3.2e-07 +#molecule: co, 1.5e-07 + +# lapse rate profile +# rules are: name, final height, final value +# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule) +lapse rate: lapse rule 0, 1, 289.7 +lapse rate: lapse rule 1, 2, 295.2 +lapse rate: lapse rule 2, 3, 279.2 +lapse rate: lapse rule 3, 4, 273.2 +lapse rate: lapse rule 4, 5, 287.2 +lapse rate: lapse rule 5, 6, 261.2 +lapse rate: lapse rule 6, 7, 254.7 +lapse rate: lapse rule 7, 8, 248.2 +lapse rate: lapse rule 8, 9, 241.7 +lapse rate: lapse rule 9, 10, 235.3 +lapse rate: lapse rule 10, 11, 228.8 +lapse rate: lapse rule 11, 12, 222.3 +lapse rate: lapse rule 12, 13, 215.8 +lapse rate: lapse rule 13, 14, 215.7 +lapse rate: lapse rule 14, 15, 215.7 +lapse rate: lapse rule 15, 16, 215.7 +lapse rate: lapse rule 16, 17, 215.7 +lapse rate: lapse rule 17, 18, 216.8 +lapse rate: lapse rule 18, 19, 217.9 +lapse rate: lapse rule 19, 20, 219.2 +lapse rate: lapse rule 20, 21, 220.4 +lapse rate: lapse rule 21, 22, 221.6 +lapse rate: lapse rule 22, 23, 222.8 +lapse rate: lapse rule 23, 24, 223.9 +lapse rate: lapse rule 24, 25, 225.1 +lapse rate: lapse rule 25, 27.6, 228.5 +lapse rate: lapse rule 26, 30, 233.7 +lapse rate: lapse rule 27, 32.6, 239 +lapse rate: lapse rule 28, 35, 245.2 +lapse rate: lapse rule 29, 37.5, 251.3 +lapse rate: lapse rule 30, 40, 257.5 +lapse rate: lapse rule 31, 42.5, 263.7 +lapse rate: lapse rule 32, 45, 269.9 +lapse rate: lapse rule 33, 47.5, 275.2 +lapse rate: lapse rule 34, 50, 275.7 +lapse rate: lapse rule 35, 55, 269.3 +lapse rate: lapse rule 36, 60, 257.1 +lapse rate: lapse rule 37, 65, 240.1 +lapse rate: lapse rule 38, 70, 218 +lapse rate: lapse rule 39, 75, 196.1 +lapse rate: lapse rule 40, 80, 174.1 +lapse rate: lapse rule 41, 85, 165.1 +lapse rate: lapse rule 42, 90, 165 +lapse rate: lapse rule 43, 95, 178.3 +lapse rate: lapse rule 44, 100, 190.5 +lapse rate: lapse rule 45, 105, 222.2 +lapse rate: lapse rule 46, 110, 262.4 +lapse rate: lapse rule 47, 115, 316.8 +lapse rate: lapse rule 48, 120, 380 + +# h2o composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: h2o rule 0, 1, 0.0138, h2o +composition rate: h2o rule 1, 2, 0.00968, h2o +composition rate: h2o rule 2, 3, 0.00598, h2o +composition rate: h2o rule 3, 4, 0.00381, h2o +composition rate: h2o rule 4, 5, 0.0022299999999999998, h2o +composition rate: h2o rule 5, 6, 0.0015099999999999998, h2o +composition rate: h2o rule 6, 7, 0.0010199999999999999, h2o +composition rate: h2o rule 7, 8, 0.000646, h2o +composition rate: h2o rule 8, 9, 0.00041299999999999996, h2o +composition rate: h2o rule 9, 10, 0.000247, h2o +composition rate: h2o rule 10, 11, 9.559999999999999e-05, h2o +composition rate: h2o rule 11, 12, 2.9399999999999996e-05, h2o +composition rate: h2o rule 12, 13, 8e-06, h2o +composition rate: h2o rule 13, 14, 4.9999999999999996e-06, h2o +composition rate: h2o rule 14, 15, 3.3999999999999996e-06, h2o +composition rate: h2o rule 15, 16, 3.2999999999999997e-06, h2o +composition rate: h2o rule 16, 17, 3.2e-06, h2o +composition rate: h2o rule 17, 18, 3.15e-06, h2o +composition rate: h2o rule 18, 19, 3.2e-06, h2o +composition rate: h2o rule 19, 20, 3.2999999999999997e-06, h2o +composition rate: h2o rule 20, 21, 3.45e-06, h2o +composition rate: h2o rule 21, 22, 3.6e-06, h2o +composition rate: h2o rule 22, 23, 3.8499999999999996e-06, h2o +composition rate: h2o rule 23, 24, 4e-06, h2o +composition rate: h2o rule 24, 25, 4.2e-06, h2o +composition rate: h2o rule 25, 27.6, 4.45e-06, h2o +composition rate: h2o rule 26, 30, 4.7e-06, h2o +composition rate: h2o rule 27, 32.6, 4.87e-06, h2o +composition rate: h2o rule 28, 35, 4.95e-06, h2o +composition rate: h2o rule 29, 37.5, 4.9999999999999996e-06, h2o +composition rate: h2o rule 30, 40, 5.0999999999999995e-06, h2o +composition rate: h2o rule 31, 42.5, 5.299999999999999e-06, h2o +composition rate: h2o rule 32, 45, 5.45e-06, h2o +composition rate: h2o rule 33, 47.5, 5.5e-06, h2o +composition rate: h2o rule 34, 50, 5.5e-06, h2o +composition rate: h2o rule 35, 55, 5.35e-06, h2o +composition rate: h2o rule 36, 60, 4.9999999999999996e-06, h2o +composition rate: h2o rule 37, 65, 4.4e-06, h2o +composition rate: h2o rule 38, 70, 3.7e-06, h2o +composition rate: h2o rule 39, 75, 2.95e-06, h2o +composition rate: h2o rule 40, 80, 2.1e-06, h2o +composition rate: h2o rule 41, 85, 1.33e-06, h2o +composition rate: h2o rule 42, 90, 8.499999999999999e-07, h2o +composition rate: h2o rule 43, 95, 5.4e-07, h2o +composition rate: h2o rule 44, 100, 4e-07, h2o +composition rate: h2o rule 45, 105, 3.4000000000000003e-07, h2o +composition rate: h2o rule 46, 110, 2.8e-07, h2o +composition rate: h2o rule 47, 115, 2.4e-07, h2o +composition rate: h2o rule 48, 120, 2e-07, h2o + +# o3 composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: o3 rule 0, 1, 3.3399999999999995e-08, o3 +composition rate: o3 rule 1, 2, 3.69e-08, o3 +composition rate: o3 rule 2, 3, 4.22e-08, o3 +composition rate: o3 rule 3, 4, 4.8199999999999995e-08, o3 +composition rate: o3 rule 4, 5, 5.5100000000000004e-08, o3 +composition rate: o3 rule 5, 6, 6.41e-08, o3 +composition rate: o3 rule 6, 7, 7.76e-08, o3 +composition rate: o3 rule 7, 8, 9.13e-08, o3 +composition rate: o3 rule 8, 9, 1.11e-07, o3 +composition rate: o3 rule 9, 10, 1.3e-07, o3 +composition rate: o3 rule 10, 11, 1.7899999999999997e-07, o3 +composition rate: o3 rule 11, 12, 2.23e-07, o3 +composition rate: o3 rule 12, 13, 3e-07, o3 +composition rate: o3 rule 13, 14, 4.3999999999999997e-07, o3 +composition rate: o3 rule 14, 15, 5e-07, o3 +composition rate: o3 rule 15, 16, 6e-07, o3 +composition rate: o3 rule 16, 17, 7e-07, o3 +composition rate: o3 rule 17, 18, 1e-06, o3 +composition rate: o3 rule 18, 19, 1.5e-06, o3 +composition rate: o3 rule 19, 20, 2e-06, o3 +composition rate: o3 rule 20, 21, 2.4e-06, o3 +composition rate: o3 rule 21, 22, 2.8999999999999998e-06, o3 +composition rate: o3 rule 22, 23, 3.3999999999999996e-06, o3 +composition rate: o3 rule 23, 24, 4e-06, o3 +composition rate: o3 rule 24, 25, 4.8e-06, o3 +composition rate: o3 rule 25, 27.6, 6e-06, o3 +composition rate: o3 rule 26, 30, 7e-06, o3 +composition rate: o3 rule 27, 32.6, 8.099999999999999e-06, o3 +composition rate: o3 rule 28, 35, 8.9e-06, o3 +composition rate: o3 rule 29, 37.5, 8.7e-06, o3 +composition rate: o3 rule 30, 40, 7.55e-06, o3 +composition rate: o3 rule 31, 42.5, 5.9e-06, o3 +composition rate: o3 rule 32, 45, 4.5e-06, o3 +composition rate: o3 rule 33, 47.5, 3.5e-06, o3 +composition rate: o3 rule 34, 50, 2.8e-06, o3 +composition rate: o3 rule 35, 55, 1.8e-06, o3 +composition rate: o3 rule 36, 60, 1.3e-06, o3 +composition rate: o3 rule 37, 65, 8e-07, o3 +composition rate: o3 rule 38, 70, 4e-07, o3 +composition rate: o3 rule 39, 75, 1.8999999999999998e-07, o3 +composition rate: o3 rule 40, 80, 2e-07, o3 +composition rate: o3 rule 41, 85, 5.699999999999999e-07, o3 +composition rate: o3 rule 42, 90, 7.5e-07, o3 +composition rate: o3 rule 43, 95, 7e-07, o3 +composition rate: o3 rule 44, 100, 4.03e-07, o3 +composition rate: o3 rule 45, 105, 2e-07, o3 +composition rate: o3 rule 46, 110, 5e-08, o3 +composition rate: o3 rule 47, 115, 5e-09, o3 +composition rate: o3 rule 48, 120, 5e-10, o3 + diff --git a/collins 1a.pyr b/collins 1a.pyr new file mode 100644 index 0000000..0541c9c --- /dev/null +++ b/collins 1a.pyr @@ -0,0 +1,174 @@ +# atm profile for midlatitude summer + +# surface values (pressure, temperature, final height, initial layer thickness, acceleration of gravity, range min, range max) +surface: 1010.0, 294.2, 120, 100, 9.8, 100, 2500 + +# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile +# except for co2, o2, n2, and ar +molecule: co2, .000287 +molecule: h2o, 0.0186 +molecule: o2, .20 +molecule: n2, .77 +molecule: ar, .009 +#molecule: ch4, 1.6999999999999998e-06 +molecule: o3, 3.02e-08 +#molecule: n2o, 3.2e-07 +#molecule: co, 1.5e-07 + +# lapse rate profile +# rules are: name, final height, final value +# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule) +lapse rate: lapse rule 0, 1, 289.7 +lapse rate: lapse rule 1, 2, 295.2 +lapse rate: lapse rule 2, 3, 279.2 +lapse rate: lapse rule 3, 4, 273.2 +lapse rate: lapse rule 4, 5, 287.2 +lapse rate: lapse rule 5, 6, 261.2 +lapse rate: lapse rule 6, 7, 254.7 +lapse rate: lapse rule 7, 8, 248.2 +lapse rate: lapse rule 8, 9, 241.7 +lapse rate: lapse rule 9, 10, 235.3 +lapse rate: lapse rule 10, 11, 228.8 +lapse rate: lapse rule 11, 12, 222.3 +lapse rate: lapse rule 12, 13, 215.8 +lapse rate: lapse rule 13, 14, 215.7 +lapse rate: lapse rule 14, 15, 215.7 +lapse rate: lapse rule 15, 16, 215.7 +lapse rate: lapse rule 16, 17, 215.7 +lapse rate: lapse rule 17, 18, 216.8 +lapse rate: lapse rule 18, 19, 217.9 +lapse rate: lapse rule 19, 20, 219.2 +lapse rate: lapse rule 20, 21, 220.4 +lapse rate: lapse rule 21, 22, 221.6 +lapse rate: lapse rule 22, 23, 222.8 +lapse rate: lapse rule 23, 24, 223.9 +lapse rate: lapse rule 24, 25, 225.1 +lapse rate: lapse rule 25, 27.6, 228.5 +lapse rate: lapse rule 26, 30, 233.7 +lapse rate: lapse rule 27, 32.6, 239 +lapse rate: lapse rule 28, 35, 245.2 +lapse rate: lapse rule 29, 37.5, 251.3 +lapse rate: lapse rule 30, 40, 257.5 +lapse rate: lapse rule 31, 42.5, 263.7 +lapse rate: lapse rule 32, 45, 269.9 +lapse rate: lapse rule 33, 47.5, 275.2 +lapse rate: lapse rule 34, 50, 275.7 +lapse rate: lapse rule 35, 55, 269.3 +lapse rate: lapse rule 36, 60, 257.1 +lapse rate: lapse rule 37, 65, 240.1 +lapse rate: lapse rule 38, 70, 218 +lapse rate: lapse rule 39, 75, 196.1 +lapse rate: lapse rule 40, 80, 174.1 +lapse rate: lapse rule 41, 85, 165.1 +lapse rate: lapse rule 42, 90, 165 +lapse rate: lapse rule 43, 95, 178.3 +lapse rate: lapse rule 44, 100, 190.5 +lapse rate: lapse rule 45, 105, 222.2 +lapse rate: lapse rule 46, 110, 262.4 +lapse rate: lapse rule 47, 115, 316.8 +lapse rate: lapse rule 48, 120, 380 + +# h2o composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: h2o rule 0, 1, 0.0138, h2o +composition rate: h2o rule 1, 2, 0.00968, h2o +composition rate: h2o rule 2, 3, 0.00598, h2o +composition rate: h2o rule 3, 4, 0.00381, h2o +composition rate: h2o rule 4, 5, 0.0022299999999999998, h2o +composition rate: h2o rule 5, 6, 0.0015099999999999998, h2o +composition rate: h2o rule 6, 7, 0.0010199999999999999, h2o +composition rate: h2o rule 7, 8, 0.000646, h2o +composition rate: h2o rule 8, 9, 0.00041299999999999996, h2o +composition rate: h2o rule 9, 10, 0.000247, h2o +composition rate: h2o rule 10, 11, 9.559999999999999e-05, h2o +composition rate: h2o rule 11, 12, 2.9399999999999996e-05, h2o +composition rate: h2o rule 12, 13, 8e-06, h2o +composition rate: h2o rule 13, 14, 4.9999999999999996e-06, h2o +composition rate: h2o rule 14, 15, 3.3999999999999996e-06, h2o +composition rate: h2o rule 15, 16, 3.2999999999999997e-06, h2o +composition rate: h2o rule 16, 17, 3.2e-06, h2o +composition rate: h2o rule 17, 18, 3.15e-06, h2o +composition rate: h2o rule 18, 19, 3.2e-06, h2o +composition rate: h2o rule 19, 20, 3.2999999999999997e-06, h2o +composition rate: h2o rule 20, 21, 3.45e-06, h2o +composition rate: h2o rule 21, 22, 3.6e-06, h2o +composition rate: h2o rule 22, 23, 3.8499999999999996e-06, h2o +composition rate: h2o rule 23, 24, 4e-06, h2o +composition rate: h2o rule 24, 25, 4.2e-06, h2o +composition rate: h2o rule 25, 27.6, 4.45e-06, h2o +composition rate: h2o rule 26, 30, 4.7e-06, h2o +composition rate: h2o rule 27, 32.6, 4.87e-06, h2o +composition rate: h2o rule 28, 35, 4.95e-06, h2o +composition rate: h2o rule 29, 37.5, 4.9999999999999996e-06, h2o +composition rate: h2o rule 30, 40, 5.0999999999999995e-06, h2o +composition rate: h2o rule 31, 42.5, 5.299999999999999e-06, h2o +composition rate: h2o rule 32, 45, 5.45e-06, h2o +composition rate: h2o rule 33, 47.5, 5.5e-06, h2o +composition rate: h2o rule 34, 50, 5.5e-06, h2o +composition rate: h2o rule 35, 55, 5.35e-06, h2o +composition rate: h2o rule 36, 60, 4.9999999999999996e-06, h2o +composition rate: h2o rule 37, 65, 4.4e-06, h2o +composition rate: h2o rule 38, 70, 3.7e-06, h2o +composition rate: h2o rule 39, 75, 2.95e-06, h2o +composition rate: h2o rule 40, 80, 2.1e-06, h2o +composition rate: h2o rule 41, 85, 1.33e-06, h2o +composition rate: h2o rule 42, 90, 8.499999999999999e-07, h2o +composition rate: h2o rule 43, 95, 5.4e-07, h2o +composition rate: h2o rule 44, 100, 4e-07, h2o +composition rate: h2o rule 45, 105, 3.4000000000000003e-07, h2o +composition rate: h2o rule 46, 110, 2.8e-07, h2o +composition rate: h2o rule 47, 115, 2.4e-07, h2o +composition rate: h2o rule 48, 120, 2e-07, h2o + +# o3 composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: o3 rule 0, 1, 3.3399999999999995e-08, o3 +composition rate: o3 rule 1, 2, 3.69e-08, o3 +composition rate: o3 rule 2, 3, 4.22e-08, o3 +composition rate: o3 rule 3, 4, 4.8199999999999995e-08, o3 +composition rate: o3 rule 4, 5, 5.5100000000000004e-08, o3 +composition rate: o3 rule 5, 6, 6.41e-08, o3 +composition rate: o3 rule 6, 7, 7.76e-08, o3 +composition rate: o3 rule 7, 8, 9.13e-08, o3 +composition rate: o3 rule 8, 9, 1.11e-07, o3 +composition rate: o3 rule 9, 10, 1.3e-07, o3 +composition rate: o3 rule 10, 11, 1.7899999999999997e-07, o3 +composition rate: o3 rule 11, 12, 2.23e-07, o3 +composition rate: o3 rule 12, 13, 3e-07, o3 +composition rate: o3 rule 13, 14, 4.3999999999999997e-07, o3 +composition rate: o3 rule 14, 15, 5e-07, o3 +composition rate: o3 rule 15, 16, 6e-07, o3 +composition rate: o3 rule 16, 17, 7e-07, o3 +composition rate: o3 rule 17, 18, 1e-06, o3 +composition rate: o3 rule 18, 19, 1.5e-06, o3 +composition rate: o3 rule 19, 20, 2e-06, o3 +composition rate: o3 rule 20, 21, 2.4e-06, o3 +composition rate: o3 rule 21, 22, 2.8999999999999998e-06, o3 +composition rate: o3 rule 22, 23, 3.3999999999999996e-06, o3 +composition rate: o3 rule 23, 24, 4e-06, o3 +composition rate: o3 rule 24, 25, 4.8e-06, o3 +composition rate: o3 rule 25, 27.6, 6e-06, o3 +composition rate: o3 rule 26, 30, 7e-06, o3 +composition rate: o3 rule 27, 32.6, 8.099999999999999e-06, o3 +composition rate: o3 rule 28, 35, 8.9e-06, o3 +composition rate: o3 rule 29, 37.5, 8.7e-06, o3 +composition rate: o3 rule 30, 40, 7.55e-06, o3 +composition rate: o3 rule 31, 42.5, 5.9e-06, o3 +composition rate: o3 rule 32, 45, 4.5e-06, o3 +composition rate: o3 rule 33, 47.5, 3.5e-06, o3 +composition rate: o3 rule 34, 50, 2.8e-06, o3 +composition rate: o3 rule 35, 55, 1.8e-06, o3 +composition rate: o3 rule 36, 60, 1.3e-06, o3 +composition rate: o3 rule 37, 65, 8e-07, o3 +composition rate: o3 rule 38, 70, 4e-07, o3 +composition rate: o3 rule 39, 75, 1.8999999999999998e-07, o3 +composition rate: o3 rule 40, 80, 2e-07, o3 +composition rate: o3 rule 41, 85, 5.699999999999999e-07, o3 +composition rate: o3 rule 42, 90, 7.5e-07, o3 +composition rate: o3 rule 43, 95, 7e-07, o3 +composition rate: o3 rule 44, 100, 4.03e-07, o3 +composition rate: o3 rule 45, 105, 2e-07, o3 +composition rate: o3 rule 46, 110, 5e-08, o3 +composition rate: o3 rule 47, 115, 5e-09, o3 +composition rate: o3 rule 48, 120, 5e-10, o3 + diff --git a/collins 2a 25 slices.pyr b/collins 2a 25 slices.pyr new file mode 100644 index 0000000..69aa745 --- /dev/null +++ b/collins 2a 25 slices.pyr @@ -0,0 +1,174 @@ +# atm profile for midlatitude summer + +# surface values (pressure, temperature, final height, initial layer thickness, acceleration of gravity, range min, range max) +surface: 1010.0, 294.2, 120, 400, 9.8, 100, 2500 + +# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile +# except for co2, o2, n2, and ar +molecule: co2, .000369 +molecule: h2o, 0.0186 +molecule: o2, .20 +molecule: n2, .77 +molecule: ar, .009 +#molecule: ch4, 1.6999999999999998e-06 +molecule: o3, 3.02e-08 +#molecule: n2o, 3.2e-07 +#molecule: co, 1.5e-07 + +# lapse rate profile +# rules are: name, final height, final value +# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule) +lapse rate: lapse rule 0, 1, 289.7 +lapse rate: lapse rule 1, 2, 295.2 +lapse rate: lapse rule 2, 3, 279.2 +lapse rate: lapse rule 3, 4, 273.2 +lapse rate: lapse rule 4, 5, 287.2 +lapse rate: lapse rule 5, 6, 261.2 +lapse rate: lapse rule 6, 7, 254.7 +lapse rate: lapse rule 7, 8, 248.2 +lapse rate: lapse rule 8, 9, 241.7 +lapse rate: lapse rule 9, 10, 235.3 +lapse rate: lapse rule 10, 11, 228.8 +lapse rate: lapse rule 11, 12, 222.3 +lapse rate: lapse rule 12, 13, 215.8 +lapse rate: lapse rule 13, 14, 215.7 +lapse rate: lapse rule 14, 15, 215.7 +lapse rate: lapse rule 15, 16, 215.7 +lapse rate: lapse rule 16, 17, 215.7 +lapse rate: lapse rule 17, 18, 216.8 +lapse rate: lapse rule 18, 19, 217.9 +lapse rate: lapse rule 19, 20, 219.2 +lapse rate: lapse rule 20, 21, 220.4 +lapse rate: lapse rule 21, 22, 221.6 +lapse rate: lapse rule 22, 23, 222.8 +lapse rate: lapse rule 23, 24, 223.9 +lapse rate: lapse rule 24, 25, 225.1 +lapse rate: lapse rule 25, 27.6, 228.5 +lapse rate: lapse rule 26, 30, 233.7 +lapse rate: lapse rule 27, 32.6, 239 +lapse rate: lapse rule 28, 35, 245.2 +lapse rate: lapse rule 29, 37.5, 251.3 +lapse rate: lapse rule 30, 40, 257.5 +lapse rate: lapse rule 31, 42.5, 263.7 +lapse rate: lapse rule 32, 45, 269.9 +lapse rate: lapse rule 33, 47.5, 275.2 +lapse rate: lapse rule 34, 50, 275.7 +lapse rate: lapse rule 35, 55, 269.3 +lapse rate: lapse rule 36, 60, 257.1 +lapse rate: lapse rule 37, 65, 240.1 +lapse rate: lapse rule 38, 70, 218 +lapse rate: lapse rule 39, 75, 196.1 +lapse rate: lapse rule 40, 80, 174.1 +lapse rate: lapse rule 41, 85, 165.1 +lapse rate: lapse rule 42, 90, 165 +lapse rate: lapse rule 43, 95, 178.3 +lapse rate: lapse rule 44, 100, 190.5 +lapse rate: lapse rule 45, 105, 222.2 +lapse rate: lapse rule 46, 110, 262.4 +lapse rate: lapse rule 47, 115, 316.8 +lapse rate: lapse rule 48, 120, 380 + +# h2o composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: h2o rule 0, 1, 0.0138, h2o +composition rate: h2o rule 1, 2, 0.00968, h2o +composition rate: h2o rule 2, 3, 0.00598, h2o +composition rate: h2o rule 3, 4, 0.00381, h2o +composition rate: h2o rule 4, 5, 0.0022299999999999998, h2o +composition rate: h2o rule 5, 6, 0.0015099999999999998, h2o +composition rate: h2o rule 6, 7, 0.0010199999999999999, h2o +composition rate: h2o rule 7, 8, 0.000646, h2o +composition rate: h2o rule 8, 9, 0.00041299999999999996, h2o +composition rate: h2o rule 9, 10, 0.000247, h2o +composition rate: h2o rule 10, 11, 9.559999999999999e-05, h2o +composition rate: h2o rule 11, 12, 2.9399999999999996e-05, h2o +composition rate: h2o rule 12, 13, 8e-06, h2o +composition rate: h2o rule 13, 14, 4.9999999999999996e-06, h2o +composition rate: h2o rule 14, 15, 3.3999999999999996e-06, h2o +composition rate: h2o rule 15, 16, 3.2999999999999997e-06, h2o +composition rate: h2o rule 16, 17, 3.2e-06, h2o +composition rate: h2o rule 17, 18, 3.15e-06, h2o +composition rate: h2o rule 18, 19, 3.2e-06, h2o +composition rate: h2o rule 19, 20, 3.2999999999999997e-06, h2o +composition rate: h2o rule 20, 21, 3.45e-06, h2o +composition rate: h2o rule 21, 22, 3.6e-06, h2o +composition rate: h2o rule 22, 23, 3.8499999999999996e-06, h2o +composition rate: h2o rule 23, 24, 4e-06, h2o +composition rate: h2o rule 24, 25, 4.2e-06, h2o +composition rate: h2o rule 25, 27.6, 4.45e-06, h2o +composition rate: h2o rule 26, 30, 4.7e-06, h2o +composition rate: h2o rule 27, 32.6, 4.87e-06, h2o +composition rate: h2o rule 28, 35, 4.95e-06, h2o +composition rate: h2o rule 29, 37.5, 4.9999999999999996e-06, h2o +composition rate: h2o rule 30, 40, 5.0999999999999995e-06, h2o +composition rate: h2o rule 31, 42.5, 5.299999999999999e-06, h2o +composition rate: h2o rule 32, 45, 5.45e-06, h2o +composition rate: h2o rule 33, 47.5, 5.5e-06, h2o +composition rate: h2o rule 34, 50, 5.5e-06, h2o +composition rate: h2o rule 35, 55, 5.35e-06, h2o +composition rate: h2o rule 36, 60, 4.9999999999999996e-06, h2o +composition rate: h2o rule 37, 65, 4.4e-06, h2o +composition rate: h2o rule 38, 70, 3.7e-06, h2o +composition rate: h2o rule 39, 75, 2.95e-06, h2o +composition rate: h2o rule 40, 80, 2.1e-06, h2o +composition rate: h2o rule 41, 85, 1.33e-06, h2o +composition rate: h2o rule 42, 90, 8.499999999999999e-07, h2o +composition rate: h2o rule 43, 95, 5.4e-07, h2o +composition rate: h2o rule 44, 100, 4e-07, h2o +composition rate: h2o rule 45, 105, 3.4000000000000003e-07, h2o +composition rate: h2o rule 46, 110, 2.8e-07, h2o +composition rate: h2o rule 47, 115, 2.4e-07, h2o +composition rate: h2o rule 48, 120, 2e-07, h2o + +# o3 composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: o3 rule 0, 1, 3.3399999999999995e-08, o3 +composition rate: o3 rule 1, 2, 3.69e-08, o3 +composition rate: o3 rule 2, 3, 4.22e-08, o3 +composition rate: o3 rule 3, 4, 4.8199999999999995e-08, o3 +composition rate: o3 rule 4, 5, 5.5100000000000004e-08, o3 +composition rate: o3 rule 5, 6, 6.41e-08, o3 +composition rate: o3 rule 6, 7, 7.76e-08, o3 +composition rate: o3 rule 7, 8, 9.13e-08, o3 +composition rate: o3 rule 8, 9, 1.11e-07, o3 +composition rate: o3 rule 9, 10, 1.3e-07, o3 +composition rate: o3 rule 10, 11, 1.7899999999999997e-07, o3 +composition rate: o3 rule 11, 12, 2.23e-07, o3 +composition rate: o3 rule 12, 13, 3e-07, o3 +composition rate: o3 rule 13, 14, 4.3999999999999997e-07, o3 +composition rate: o3 rule 14, 15, 5e-07, o3 +composition rate: o3 rule 15, 16, 6e-07, o3 +composition rate: o3 rule 16, 17, 7e-07, o3 +composition rate: o3 rule 17, 18, 1e-06, o3 +composition rate: o3 rule 18, 19, 1.5e-06, o3 +composition rate: o3 rule 19, 20, 2e-06, o3 +composition rate: o3 rule 20, 21, 2.4e-06, o3 +composition rate: o3 rule 21, 22, 2.8999999999999998e-06, o3 +composition rate: o3 rule 22, 23, 3.3999999999999996e-06, o3 +composition rate: o3 rule 23, 24, 4e-06, o3 +composition rate: o3 rule 24, 25, 4.8e-06, o3 +composition rate: o3 rule 25, 27.6, 6e-06, o3 +composition rate: o3 rule 26, 30, 7e-06, o3 +composition rate: o3 rule 27, 32.6, 8.099999999999999e-06, o3 +composition rate: o3 rule 28, 35, 8.9e-06, o3 +composition rate: o3 rule 29, 37.5, 8.7e-06, o3 +composition rate: o3 rule 30, 40, 7.55e-06, o3 +composition rate: o3 rule 31, 42.5, 5.9e-06, o3 +composition rate: o3 rule 32, 45, 4.5e-06, o3 +composition rate: o3 rule 33, 47.5, 3.5e-06, o3 +composition rate: o3 rule 34, 50, 2.8e-06, o3 +composition rate: o3 rule 35, 55, 1.8e-06, o3 +composition rate: o3 rule 36, 60, 1.3e-06, o3 +composition rate: o3 rule 37, 65, 8e-07, o3 +composition rate: o3 rule 38, 70, 4e-07, o3 +composition rate: o3 rule 39, 75, 1.8999999999999998e-07, o3 +composition rate: o3 rule 40, 80, 2e-07, o3 +composition rate: o3 rule 41, 85, 5.699999999999999e-07, o3 +composition rate: o3 rule 42, 90, 7.5e-07, o3 +composition rate: o3 rule 43, 95, 7e-07, o3 +composition rate: o3 rule 44, 100, 4.03e-07, o3 +composition rate: o3 rule 45, 105, 2e-07, o3 +composition rate: o3 rule 46, 110, 5e-08, o3 +composition rate: o3 rule 47, 115, 5e-09, o3 +composition rate: o3 rule 48, 120, 5e-10, o3 + diff --git a/collins 2a thick.pyr b/collins 2a thick.pyr new file mode 100644 index 0000000..10fdcf3 --- /dev/null +++ b/collins 2a thick.pyr @@ -0,0 +1,174 @@ +# atm profile for midlatitude summer + +# surface values (pressure, temperature, final height, initial layer thickness, acceleration of gravity, range min, range max) +surface: 1010.0, 294.2, 120, 250, 9.8, 100, 2500 + +# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile +# except for co2, o2, n2, and ar +molecule: co2, .000369 +molecule: h2o, 0.0186 +molecule: o2, .20 +molecule: n2, .77 +molecule: ar, .009 +#molecule: ch4, 1.6999999999999998e-06 +molecule: o3, 3.02e-08 +#molecule: n2o, 3.2e-07 +#molecule: co, 1.5e-07 + +# lapse rate profile +# rules are: name, final height, final value +# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule) +lapse rate: lapse rule 0, 1, 289.7 +lapse rate: lapse rule 1, 2, 295.2 +lapse rate: lapse rule 2, 3, 279.2 +lapse rate: lapse rule 3, 4, 273.2 +lapse rate: lapse rule 4, 5, 287.2 +lapse rate: lapse rule 5, 6, 261.2 +lapse rate: lapse rule 6, 7, 254.7 +lapse rate: lapse rule 7, 8, 248.2 +lapse rate: lapse rule 8, 9, 241.7 +lapse rate: lapse rule 9, 10, 235.3 +lapse rate: lapse rule 10, 11, 228.8 +lapse rate: lapse rule 11, 12, 222.3 +lapse rate: lapse rule 12, 13, 215.8 +lapse rate: lapse rule 13, 14, 215.7 +lapse rate: lapse rule 14, 15, 215.7 +lapse rate: lapse rule 15, 16, 215.7 +lapse rate: lapse rule 16, 17, 215.7 +lapse rate: lapse rule 17, 18, 216.8 +lapse rate: lapse rule 18, 19, 217.9 +lapse rate: lapse rule 19, 20, 219.2 +lapse rate: lapse rule 20, 21, 220.4 +lapse rate: lapse rule 21, 22, 221.6 +lapse rate: lapse rule 22, 23, 222.8 +lapse rate: lapse rule 23, 24, 223.9 +lapse rate: lapse rule 24, 25, 225.1 +lapse rate: lapse rule 25, 27.6, 228.5 +lapse rate: lapse rule 26, 30, 233.7 +lapse rate: lapse rule 27, 32.6, 239 +lapse rate: lapse rule 28, 35, 245.2 +lapse rate: lapse rule 29, 37.5, 251.3 +lapse rate: lapse rule 30, 40, 257.5 +lapse rate: lapse rule 31, 42.5, 263.7 +lapse rate: lapse rule 32, 45, 269.9 +lapse rate: lapse rule 33, 47.5, 275.2 +lapse rate: lapse rule 34, 50, 275.7 +lapse rate: lapse rule 35, 55, 269.3 +lapse rate: lapse rule 36, 60, 257.1 +lapse rate: lapse rule 37, 65, 240.1 +lapse rate: lapse rule 38, 70, 218 +lapse rate: lapse rule 39, 75, 196.1 +lapse rate: lapse rule 40, 80, 174.1 +lapse rate: lapse rule 41, 85, 165.1 +lapse rate: lapse rule 42, 90, 165 +lapse rate: lapse rule 43, 95, 178.3 +lapse rate: lapse rule 44, 100, 190.5 +lapse rate: lapse rule 45, 105, 222.2 +lapse rate: lapse rule 46, 110, 262.4 +lapse rate: lapse rule 47, 115, 316.8 +lapse rate: lapse rule 48, 120, 380 + +# h2o composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: h2o rule 0, 1, 0.0138, h2o +composition rate: h2o rule 1, 2, 0.00968, h2o +composition rate: h2o rule 2, 3, 0.00598, h2o +composition rate: h2o rule 3, 4, 0.00381, h2o +composition rate: h2o rule 4, 5, 0.0022299999999999998, h2o +composition rate: h2o rule 5, 6, 0.0015099999999999998, h2o +composition rate: h2o rule 6, 7, 0.0010199999999999999, h2o +composition rate: h2o rule 7, 8, 0.000646, h2o +composition rate: h2o rule 8, 9, 0.00041299999999999996, h2o +composition rate: h2o rule 9, 10, 0.000247, h2o +composition rate: h2o rule 10, 11, 9.559999999999999e-05, h2o +composition rate: h2o rule 11, 12, 2.9399999999999996e-05, h2o +composition rate: h2o rule 12, 13, 8e-06, h2o +composition rate: h2o rule 13, 14, 4.9999999999999996e-06, h2o +composition rate: h2o rule 14, 15, 3.3999999999999996e-06, h2o +composition rate: h2o rule 15, 16, 3.2999999999999997e-06, h2o +composition rate: h2o rule 16, 17, 3.2e-06, h2o +composition rate: h2o rule 17, 18, 3.15e-06, h2o +composition rate: h2o rule 18, 19, 3.2e-06, h2o +composition rate: h2o rule 19, 20, 3.2999999999999997e-06, h2o +composition rate: h2o rule 20, 21, 3.45e-06, h2o +composition rate: h2o rule 21, 22, 3.6e-06, h2o +composition rate: h2o rule 22, 23, 3.8499999999999996e-06, h2o +composition rate: h2o rule 23, 24, 4e-06, h2o +composition rate: h2o rule 24, 25, 4.2e-06, h2o +composition rate: h2o rule 25, 27.6, 4.45e-06, h2o +composition rate: h2o rule 26, 30, 4.7e-06, h2o +composition rate: h2o rule 27, 32.6, 4.87e-06, h2o +composition rate: h2o rule 28, 35, 4.95e-06, h2o +composition rate: h2o rule 29, 37.5, 4.9999999999999996e-06, h2o +composition rate: h2o rule 30, 40, 5.0999999999999995e-06, h2o +composition rate: h2o rule 31, 42.5, 5.299999999999999e-06, h2o +composition rate: h2o rule 32, 45, 5.45e-06, h2o +composition rate: h2o rule 33, 47.5, 5.5e-06, h2o +composition rate: h2o rule 34, 50, 5.5e-06, h2o +composition rate: h2o rule 35, 55, 5.35e-06, h2o +composition rate: h2o rule 36, 60, 4.9999999999999996e-06, h2o +composition rate: h2o rule 37, 65, 4.4e-06, h2o +composition rate: h2o rule 38, 70, 3.7e-06, h2o +composition rate: h2o rule 39, 75, 2.95e-06, h2o +composition rate: h2o rule 40, 80, 2.1e-06, h2o +composition rate: h2o rule 41, 85, 1.33e-06, h2o +composition rate: h2o rule 42, 90, 8.499999999999999e-07, h2o +composition rate: h2o rule 43, 95, 5.4e-07, h2o +composition rate: h2o rule 44, 100, 4e-07, h2o +composition rate: h2o rule 45, 105, 3.4000000000000003e-07, h2o +composition rate: h2o rule 46, 110, 2.8e-07, h2o +composition rate: h2o rule 47, 115, 2.4e-07, h2o +composition rate: h2o rule 48, 120, 2e-07, h2o + +# o3 composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: o3 rule 0, 1, 3.3399999999999995e-08, o3 +composition rate: o3 rule 1, 2, 3.69e-08, o3 +composition rate: o3 rule 2, 3, 4.22e-08, o3 +composition rate: o3 rule 3, 4, 4.8199999999999995e-08, o3 +composition rate: o3 rule 4, 5, 5.5100000000000004e-08, o3 +composition rate: o3 rule 5, 6, 6.41e-08, o3 +composition rate: o3 rule 6, 7, 7.76e-08, o3 +composition rate: o3 rule 7, 8, 9.13e-08, o3 +composition rate: o3 rule 8, 9, 1.11e-07, o3 +composition rate: o3 rule 9, 10, 1.3e-07, o3 +composition rate: o3 rule 10, 11, 1.7899999999999997e-07, o3 +composition rate: o3 rule 11, 12, 2.23e-07, o3 +composition rate: o3 rule 12, 13, 3e-07, o3 +composition rate: o3 rule 13, 14, 4.3999999999999997e-07, o3 +composition rate: o3 rule 14, 15, 5e-07, o3 +composition rate: o3 rule 15, 16, 6e-07, o3 +composition rate: o3 rule 16, 17, 7e-07, o3 +composition rate: o3 rule 17, 18, 1e-06, o3 +composition rate: o3 rule 18, 19, 1.5e-06, o3 +composition rate: o3 rule 19, 20, 2e-06, o3 +composition rate: o3 rule 20, 21, 2.4e-06, o3 +composition rate: o3 rule 21, 22, 2.8999999999999998e-06, o3 +composition rate: o3 rule 22, 23, 3.3999999999999996e-06, o3 +composition rate: o3 rule 23, 24, 4e-06, o3 +composition rate: o3 rule 24, 25, 4.8e-06, o3 +composition rate: o3 rule 25, 27.6, 6e-06, o3 +composition rate: o3 rule 26, 30, 7e-06, o3 +composition rate: o3 rule 27, 32.6, 8.099999999999999e-06, o3 +composition rate: o3 rule 28, 35, 8.9e-06, o3 +composition rate: o3 rule 29, 37.5, 8.7e-06, o3 +composition rate: o3 rule 30, 40, 7.55e-06, o3 +composition rate: o3 rule 31, 42.5, 5.9e-06, o3 +composition rate: o3 rule 32, 45, 4.5e-06, o3 +composition rate: o3 rule 33, 47.5, 3.5e-06, o3 +composition rate: o3 rule 34, 50, 2.8e-06, o3 +composition rate: o3 rule 35, 55, 1.8e-06, o3 +composition rate: o3 rule 36, 60, 1.3e-06, o3 +composition rate: o3 rule 37, 65, 8e-07, o3 +composition rate: o3 rule 38, 70, 4e-07, o3 +composition rate: o3 rule 39, 75, 1.8999999999999998e-07, o3 +composition rate: o3 rule 40, 80, 2e-07, o3 +composition rate: o3 rule 41, 85, 5.699999999999999e-07, o3 +composition rate: o3 rule 42, 90, 7.5e-07, o3 +composition rate: o3 rule 43, 95, 7e-07, o3 +composition rate: o3 rule 44, 100, 4.03e-07, o3 +composition rate: o3 rule 45, 105, 2e-07, o3 +composition rate: o3 rule 46, 110, 5e-08, o3 +composition rate: o3 rule 47, 115, 5e-09, o3 +composition rate: o3 rule 48, 120, 5e-10, o3 + diff --git a/collins 2a.pyr b/collins 2a.pyr new file mode 100644 index 0000000..fb48a44 --- /dev/null +++ b/collins 2a.pyr @@ -0,0 +1,174 @@ +# atm profile for midlatitude summer + +# surface values (pressure, temperature, final height, initial layer thickness, acceleration of gravity, range min, range max) +surface: 1010.0, 294.2, 120, 100, 9.8, 100, 2500 + +# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile +# except for co2, o2, n2, and ar +molecule: co2, .000369 +molecule: h2o, 0.0186 +molecule: o2, .20 +molecule: n2, .77 +molecule: ar, .009 +#molecule: ch4, 1.6999999999999998e-06 +molecule: o3, 3.02e-08 +#molecule: n2o, 3.2e-07 +#molecule: co, 1.5e-07 + +# lapse rate profile +# rules are: name, final height, final value +# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule) +lapse rate: lapse rule 0, 1, 289.7 +lapse rate: lapse rule 1, 2, 295.2 +lapse rate: lapse rule 2, 3, 279.2 +lapse rate: lapse rule 3, 4, 273.2 +lapse rate: lapse rule 4, 5, 287.2 +lapse rate: lapse rule 5, 6, 261.2 +lapse rate: lapse rule 6, 7, 254.7 +lapse rate: lapse rule 7, 8, 248.2 +lapse rate: lapse rule 8, 9, 241.7 +lapse rate: lapse rule 9, 10, 235.3 +lapse rate: lapse rule 10, 11, 228.8 +lapse rate: lapse rule 11, 12, 222.3 +lapse rate: lapse rule 12, 13, 215.8 +lapse rate: lapse rule 13, 14, 215.7 +lapse rate: lapse rule 14, 15, 215.7 +lapse rate: lapse rule 15, 16, 215.7 +lapse rate: lapse rule 16, 17, 215.7 +lapse rate: lapse rule 17, 18, 216.8 +lapse rate: lapse rule 18, 19, 217.9 +lapse rate: lapse rule 19, 20, 219.2 +lapse rate: lapse rule 20, 21, 220.4 +lapse rate: lapse rule 21, 22, 221.6 +lapse rate: lapse rule 22, 23, 222.8 +lapse rate: lapse rule 23, 24, 223.9 +lapse rate: lapse rule 24, 25, 225.1 +lapse rate: lapse rule 25, 27.6, 228.5 +lapse rate: lapse rule 26, 30, 233.7 +lapse rate: lapse rule 27, 32.6, 239 +lapse rate: lapse rule 28, 35, 245.2 +lapse rate: lapse rule 29, 37.5, 251.3 +lapse rate: lapse rule 30, 40, 257.5 +lapse rate: lapse rule 31, 42.5, 263.7 +lapse rate: lapse rule 32, 45, 269.9 +lapse rate: lapse rule 33, 47.5, 275.2 +lapse rate: lapse rule 34, 50, 275.7 +lapse rate: lapse rule 35, 55, 269.3 +lapse rate: lapse rule 36, 60, 257.1 +lapse rate: lapse rule 37, 65, 240.1 +lapse rate: lapse rule 38, 70, 218 +lapse rate: lapse rule 39, 75, 196.1 +lapse rate: lapse rule 40, 80, 174.1 +lapse rate: lapse rule 41, 85, 165.1 +lapse rate: lapse rule 42, 90, 165 +lapse rate: lapse rule 43, 95, 178.3 +lapse rate: lapse rule 44, 100, 190.5 +lapse rate: lapse rule 45, 105, 222.2 +lapse rate: lapse rule 46, 110, 262.4 +lapse rate: lapse rule 47, 115, 316.8 +lapse rate: lapse rule 48, 120, 380 + +# h2o composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: h2o rule 0, 1, 0.0138, h2o +composition rate: h2o rule 1, 2, 0.00968, h2o +composition rate: h2o rule 2, 3, 0.00598, h2o +composition rate: h2o rule 3, 4, 0.00381, h2o +composition rate: h2o rule 4, 5, 0.0022299999999999998, h2o +composition rate: h2o rule 5, 6, 0.0015099999999999998, h2o +composition rate: h2o rule 6, 7, 0.0010199999999999999, h2o +composition rate: h2o rule 7, 8, 0.000646, h2o +composition rate: h2o rule 8, 9, 0.00041299999999999996, h2o +composition rate: h2o rule 9, 10, 0.000247, h2o +composition rate: h2o rule 10, 11, 9.559999999999999e-05, h2o +composition rate: h2o rule 11, 12, 2.9399999999999996e-05, h2o +composition rate: h2o rule 12, 13, 8e-06, h2o +composition rate: h2o rule 13, 14, 4.9999999999999996e-06, h2o +composition rate: h2o rule 14, 15, 3.3999999999999996e-06, h2o +composition rate: h2o rule 15, 16, 3.2999999999999997e-06, h2o +composition rate: h2o rule 16, 17, 3.2e-06, h2o +composition rate: h2o rule 17, 18, 3.15e-06, h2o +composition rate: h2o rule 18, 19, 3.2e-06, h2o +composition rate: h2o rule 19, 20, 3.2999999999999997e-06, h2o +composition rate: h2o rule 20, 21, 3.45e-06, h2o +composition rate: h2o rule 21, 22, 3.6e-06, h2o +composition rate: h2o rule 22, 23, 3.8499999999999996e-06, h2o +composition rate: h2o rule 23, 24, 4e-06, h2o +composition rate: h2o rule 24, 25, 4.2e-06, h2o +composition rate: h2o rule 25, 27.6, 4.45e-06, h2o +composition rate: h2o rule 26, 30, 4.7e-06, h2o +composition rate: h2o rule 27, 32.6, 4.87e-06, h2o +composition rate: h2o rule 28, 35, 4.95e-06, h2o +composition rate: h2o rule 29, 37.5, 4.9999999999999996e-06, h2o +composition rate: h2o rule 30, 40, 5.0999999999999995e-06, h2o +composition rate: h2o rule 31, 42.5, 5.299999999999999e-06, h2o +composition rate: h2o rule 32, 45, 5.45e-06, h2o +composition rate: h2o rule 33, 47.5, 5.5e-06, h2o +composition rate: h2o rule 34, 50, 5.5e-06, h2o +composition rate: h2o rule 35, 55, 5.35e-06, h2o +composition rate: h2o rule 36, 60, 4.9999999999999996e-06, h2o +composition rate: h2o rule 37, 65, 4.4e-06, h2o +composition rate: h2o rule 38, 70, 3.7e-06, h2o +composition rate: h2o rule 39, 75, 2.95e-06, h2o +composition rate: h2o rule 40, 80, 2.1e-06, h2o +composition rate: h2o rule 41, 85, 1.33e-06, h2o +composition rate: h2o rule 42, 90, 8.499999999999999e-07, h2o +composition rate: h2o rule 43, 95, 5.4e-07, h2o +composition rate: h2o rule 44, 100, 4e-07, h2o +composition rate: h2o rule 45, 105, 3.4000000000000003e-07, h2o +composition rate: h2o rule 46, 110, 2.8e-07, h2o +composition rate: h2o rule 47, 115, 2.4e-07, h2o +composition rate: h2o rule 48, 120, 2e-07, h2o + +# o3 composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: o3 rule 0, 1, 3.3399999999999995e-08, o3 +composition rate: o3 rule 1, 2, 3.69e-08, o3 +composition rate: o3 rule 2, 3, 4.22e-08, o3 +composition rate: o3 rule 3, 4, 4.8199999999999995e-08, o3 +composition rate: o3 rule 4, 5, 5.5100000000000004e-08, o3 +composition rate: o3 rule 5, 6, 6.41e-08, o3 +composition rate: o3 rule 6, 7, 7.76e-08, o3 +composition rate: o3 rule 7, 8, 9.13e-08, o3 +composition rate: o3 rule 8, 9, 1.11e-07, o3 +composition rate: o3 rule 9, 10, 1.3e-07, o3 +composition rate: o3 rule 10, 11, 1.7899999999999997e-07, o3 +composition rate: o3 rule 11, 12, 2.23e-07, o3 +composition rate: o3 rule 12, 13, 3e-07, o3 +composition rate: o3 rule 13, 14, 4.3999999999999997e-07, o3 +composition rate: o3 rule 14, 15, 5e-07, o3 +composition rate: o3 rule 15, 16, 6e-07, o3 +composition rate: o3 rule 16, 17, 7e-07, o3 +composition rate: o3 rule 17, 18, 1e-06, o3 +composition rate: o3 rule 18, 19, 1.5e-06, o3 +composition rate: o3 rule 19, 20, 2e-06, o3 +composition rate: o3 rule 20, 21, 2.4e-06, o3 +composition rate: o3 rule 21, 22, 2.8999999999999998e-06, o3 +composition rate: o3 rule 22, 23, 3.3999999999999996e-06, o3 +composition rate: o3 rule 23, 24, 4e-06, o3 +composition rate: o3 rule 24, 25, 4.8e-06, o3 +composition rate: o3 rule 25, 27.6, 6e-06, o3 +composition rate: o3 rule 26, 30, 7e-06, o3 +composition rate: o3 rule 27, 32.6, 8.099999999999999e-06, o3 +composition rate: o3 rule 28, 35, 8.9e-06, o3 +composition rate: o3 rule 29, 37.5, 8.7e-06, o3 +composition rate: o3 rule 30, 40, 7.55e-06, o3 +composition rate: o3 rule 31, 42.5, 5.9e-06, o3 +composition rate: o3 rule 32, 45, 4.5e-06, o3 +composition rate: o3 rule 33, 47.5, 3.5e-06, o3 +composition rate: o3 rule 34, 50, 2.8e-06, o3 +composition rate: o3 rule 35, 55, 1.8e-06, o3 +composition rate: o3 rule 36, 60, 1.3e-06, o3 +composition rate: o3 rule 37, 65, 8e-07, o3 +composition rate: o3 rule 38, 70, 4e-07, o3 +composition rate: o3 rule 39, 75, 1.8999999999999998e-07, o3 +composition rate: o3 rule 40, 80, 2e-07, o3 +composition rate: o3 rule 41, 85, 5.699999999999999e-07, o3 +composition rate: o3 rule 42, 90, 7.5e-07, o3 +composition rate: o3 rule 43, 95, 7e-07, o3 +composition rate: o3 rule 44, 100, 4.03e-07, o3 +composition rate: o3 rule 45, 105, 2e-07, o3 +composition rate: o3 rule 46, 110, 5e-08, o3 +composition rate: o3 rule 47, 115, 5e-09, o3 +composition rate: o3 rule 48, 120, 5e-10, o3 + diff --git a/collins 2b 25 slices.pyr b/collins 2b 25 slices.pyr new file mode 100644 index 0000000..80a8abf --- /dev/null +++ b/collins 2b 25 slices.pyr @@ -0,0 +1,174 @@ +# atm profile for midlatitude summer + +# surface values (pressure, temperature, final height, initial layer thickness, acceleration of gravity, range min, range max) +surface: 1010.0, 294.2, 120, 400, 9.8, 100, 2500 + +# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile +# except for co2, o2, n2, and ar +molecule: co2, .000574 +molecule: h2o, 0.0186 +molecule: o2, .20 +molecule: n2, .77 +molecule: ar, .009 +#molecule: ch4, 1.6999999999999998e-06 +molecule: o3, 3.02e-08 +#molecule: n2o, 3.2e-07 +#molecule: co, 1.5e-07 + +# lapse rate profile +# rules are: name, final height, final value +# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule) +lapse rate: lapse rule 0, 1, 289.7 +lapse rate: lapse rule 1, 2, 295.2 +lapse rate: lapse rule 2, 3, 279.2 +lapse rate: lapse rule 3, 4, 273.2 +lapse rate: lapse rule 4, 5, 287.2 +lapse rate: lapse rule 5, 6, 261.2 +lapse rate: lapse rule 6, 7, 254.7 +lapse rate: lapse rule 7, 8, 248.2 +lapse rate: lapse rule 8, 9, 241.7 +lapse rate: lapse rule 9, 10, 235.3 +lapse rate: lapse rule 10, 11, 228.8 +lapse rate: lapse rule 11, 12, 222.3 +lapse rate: lapse rule 12, 13, 215.8 +lapse rate: lapse rule 13, 14, 215.7 +lapse rate: lapse rule 14, 15, 215.7 +lapse rate: lapse rule 15, 16, 215.7 +lapse rate: lapse rule 16, 17, 215.7 +lapse rate: lapse rule 17, 18, 216.8 +lapse rate: lapse rule 18, 19, 217.9 +lapse rate: lapse rule 19, 20, 219.2 +lapse rate: lapse rule 20, 21, 220.4 +lapse rate: lapse rule 21, 22, 221.6 +lapse rate: lapse rule 22, 23, 222.8 +lapse rate: lapse rule 23, 24, 223.9 +lapse rate: lapse rule 24, 25, 225.1 +lapse rate: lapse rule 25, 27.6, 228.5 +lapse rate: lapse rule 26, 30, 233.7 +lapse rate: lapse rule 27, 32.6, 239 +lapse rate: lapse rule 28, 35, 245.2 +lapse rate: lapse rule 29, 37.5, 251.3 +lapse rate: lapse rule 30, 40, 257.5 +lapse rate: lapse rule 31, 42.5, 263.7 +lapse rate: lapse rule 32, 45, 269.9 +lapse rate: lapse rule 33, 47.5, 275.2 +lapse rate: lapse rule 34, 50, 275.7 +lapse rate: lapse rule 35, 55, 269.3 +lapse rate: lapse rule 36, 60, 257.1 +lapse rate: lapse rule 37, 65, 240.1 +lapse rate: lapse rule 38, 70, 218 +lapse rate: lapse rule 39, 75, 196.1 +lapse rate: lapse rule 40, 80, 174.1 +lapse rate: lapse rule 41, 85, 165.1 +lapse rate: lapse rule 42, 90, 165 +lapse rate: lapse rule 43, 95, 178.3 +lapse rate: lapse rule 44, 100, 190.5 +lapse rate: lapse rule 45, 105, 222.2 +lapse rate: lapse rule 46, 110, 262.4 +lapse rate: lapse rule 47, 115, 316.8 +lapse rate: lapse rule 48, 120, 380 + +# h2o composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: h2o rule 0, 1, 0.0138, h2o +composition rate: h2o rule 1, 2, 0.00968, h2o +composition rate: h2o rule 2, 3, 0.00598, h2o +composition rate: h2o rule 3, 4, 0.00381, h2o +composition rate: h2o rule 4, 5, 0.0022299999999999998, h2o +composition rate: h2o rule 5, 6, 0.0015099999999999998, h2o +composition rate: h2o rule 6, 7, 0.0010199999999999999, h2o +composition rate: h2o rule 7, 8, 0.000646, h2o +composition rate: h2o rule 8, 9, 0.00041299999999999996, h2o +composition rate: h2o rule 9, 10, 0.000247, h2o +composition rate: h2o rule 10, 11, 9.559999999999999e-05, h2o +composition rate: h2o rule 11, 12, 2.9399999999999996e-05, h2o +composition rate: h2o rule 12, 13, 8e-06, h2o +composition rate: h2o rule 13, 14, 4.9999999999999996e-06, h2o +composition rate: h2o rule 14, 15, 3.3999999999999996e-06, h2o +composition rate: h2o rule 15, 16, 3.2999999999999997e-06, h2o +composition rate: h2o rule 16, 17, 3.2e-06, h2o +composition rate: h2o rule 17, 18, 3.15e-06, h2o +composition rate: h2o rule 18, 19, 3.2e-06, h2o +composition rate: h2o rule 19, 20, 3.2999999999999997e-06, h2o +composition rate: h2o rule 20, 21, 3.45e-06, h2o +composition rate: h2o rule 21, 22, 3.6e-06, h2o +composition rate: h2o rule 22, 23, 3.8499999999999996e-06, h2o +composition rate: h2o rule 23, 24, 4e-06, h2o +composition rate: h2o rule 24, 25, 4.2e-06, h2o +composition rate: h2o rule 25, 27.6, 4.45e-06, h2o +composition rate: h2o rule 26, 30, 4.7e-06, h2o +composition rate: h2o rule 27, 32.6, 4.87e-06, h2o +composition rate: h2o rule 28, 35, 4.95e-06, h2o +composition rate: h2o rule 29, 37.5, 4.9999999999999996e-06, h2o +composition rate: h2o rule 30, 40, 5.0999999999999995e-06, h2o +composition rate: h2o rule 31, 42.5, 5.299999999999999e-06, h2o +composition rate: h2o rule 32, 45, 5.45e-06, h2o +composition rate: h2o rule 33, 47.5, 5.5e-06, h2o +composition rate: h2o rule 34, 50, 5.5e-06, h2o +composition rate: h2o rule 35, 55, 5.35e-06, h2o +composition rate: h2o rule 36, 60, 4.9999999999999996e-06, h2o +composition rate: h2o rule 37, 65, 4.4e-06, h2o +composition rate: h2o rule 38, 70, 3.7e-06, h2o +composition rate: h2o rule 39, 75, 2.95e-06, h2o +composition rate: h2o rule 40, 80, 2.1e-06, h2o +composition rate: h2o rule 41, 85, 1.33e-06, h2o +composition rate: h2o rule 42, 90, 8.499999999999999e-07, h2o +composition rate: h2o rule 43, 95, 5.4e-07, h2o +composition rate: h2o rule 44, 100, 4e-07, h2o +composition rate: h2o rule 45, 105, 3.4000000000000003e-07, h2o +composition rate: h2o rule 46, 110, 2.8e-07, h2o +composition rate: h2o rule 47, 115, 2.4e-07, h2o +composition rate: h2o rule 48, 120, 2e-07, h2o + +# o3 composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: o3 rule 0, 1, 3.3399999999999995e-08, o3 +composition rate: o3 rule 1, 2, 3.69e-08, o3 +composition rate: o3 rule 2, 3, 4.22e-08, o3 +composition rate: o3 rule 3, 4, 4.8199999999999995e-08, o3 +composition rate: o3 rule 4, 5, 5.5100000000000004e-08, o3 +composition rate: o3 rule 5, 6, 6.41e-08, o3 +composition rate: o3 rule 6, 7, 7.76e-08, o3 +composition rate: o3 rule 7, 8, 9.13e-08, o3 +composition rate: o3 rule 8, 9, 1.11e-07, o3 +composition rate: o3 rule 9, 10, 1.3e-07, o3 +composition rate: o3 rule 10, 11, 1.7899999999999997e-07, o3 +composition rate: o3 rule 11, 12, 2.23e-07, o3 +composition rate: o3 rule 12, 13, 3e-07, o3 +composition rate: o3 rule 13, 14, 4.3999999999999997e-07, o3 +composition rate: o3 rule 14, 15, 5e-07, o3 +composition rate: o3 rule 15, 16, 6e-07, o3 +composition rate: o3 rule 16, 17, 7e-07, o3 +composition rate: o3 rule 17, 18, 1e-06, o3 +composition rate: o3 rule 18, 19, 1.5e-06, o3 +composition rate: o3 rule 19, 20, 2e-06, o3 +composition rate: o3 rule 20, 21, 2.4e-06, o3 +composition rate: o3 rule 21, 22, 2.8999999999999998e-06, o3 +composition rate: o3 rule 22, 23, 3.3999999999999996e-06, o3 +composition rate: o3 rule 23, 24, 4e-06, o3 +composition rate: o3 rule 24, 25, 4.8e-06, o3 +composition rate: o3 rule 25, 27.6, 6e-06, o3 +composition rate: o3 rule 26, 30, 7e-06, o3 +composition rate: o3 rule 27, 32.6, 8.099999999999999e-06, o3 +composition rate: o3 rule 28, 35, 8.9e-06, o3 +composition rate: o3 rule 29, 37.5, 8.7e-06, o3 +composition rate: o3 rule 30, 40, 7.55e-06, o3 +composition rate: o3 rule 31, 42.5, 5.9e-06, o3 +composition rate: o3 rule 32, 45, 4.5e-06, o3 +composition rate: o3 rule 33, 47.5, 3.5e-06, o3 +composition rate: o3 rule 34, 50, 2.8e-06, o3 +composition rate: o3 rule 35, 55, 1.8e-06, o3 +composition rate: o3 rule 36, 60, 1.3e-06, o3 +composition rate: o3 rule 37, 65, 8e-07, o3 +composition rate: o3 rule 38, 70, 4e-07, o3 +composition rate: o3 rule 39, 75, 1.8999999999999998e-07, o3 +composition rate: o3 rule 40, 80, 2e-07, o3 +composition rate: o3 rule 41, 85, 5.699999999999999e-07, o3 +composition rate: o3 rule 42, 90, 7.5e-07, o3 +composition rate: o3 rule 43, 95, 7e-07, o3 +composition rate: o3 rule 44, 100, 4.03e-07, o3 +composition rate: o3 rule 45, 105, 2e-07, o3 +composition rate: o3 rule 46, 110, 5e-08, o3 +composition rate: o3 rule 47, 115, 5e-09, o3 +composition rate: o3 rule 48, 120, 5e-10, o3 + diff --git a/collins 2b thick.pyr b/collins 2b thick.pyr new file mode 100644 index 0000000..5b24b7f --- /dev/null +++ b/collins 2b thick.pyr @@ -0,0 +1,174 @@ +# atm profile for midlatitude summer + +# surface values (pressure, temperature, final height, initial layer thickness, acceleration of gravity, range min, range max) +surface: 1010.0, 294.2, 120, 250, 9.8, 100, 2500 + +# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile +# except for co2, o2, n2, and ar +molecule: co2, .000574 +molecule: h2o, 0.0186 +molecule: o2, .20 +molecule: n2, .77 +molecule: ar, .009 +#molecule: ch4, 1.6999999999999998e-06 +molecule: o3, 3.02e-08 +#molecule: n2o, 3.2e-07 +#molecule: co, 1.5e-07 + +# lapse rate profile +# rules are: name, final height, final value +# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule) +lapse rate: lapse rule 0, 1, 289.7 +lapse rate: lapse rule 1, 2, 295.2 +lapse rate: lapse rule 2, 3, 279.2 +lapse rate: lapse rule 3, 4, 273.2 +lapse rate: lapse rule 4, 5, 287.2 +lapse rate: lapse rule 5, 6, 261.2 +lapse rate: lapse rule 6, 7, 254.7 +lapse rate: lapse rule 7, 8, 248.2 +lapse rate: lapse rule 8, 9, 241.7 +lapse rate: lapse rule 9, 10, 235.3 +lapse rate: lapse rule 10, 11, 228.8 +lapse rate: lapse rule 11, 12, 222.3 +lapse rate: lapse rule 12, 13, 215.8 +lapse rate: lapse rule 13, 14, 215.7 +lapse rate: lapse rule 14, 15, 215.7 +lapse rate: lapse rule 15, 16, 215.7 +lapse rate: lapse rule 16, 17, 215.7 +lapse rate: lapse rule 17, 18, 216.8 +lapse rate: lapse rule 18, 19, 217.9 +lapse rate: lapse rule 19, 20, 219.2 +lapse rate: lapse rule 20, 21, 220.4 +lapse rate: lapse rule 21, 22, 221.6 +lapse rate: lapse rule 22, 23, 222.8 +lapse rate: lapse rule 23, 24, 223.9 +lapse rate: lapse rule 24, 25, 225.1 +lapse rate: lapse rule 25, 27.6, 228.5 +lapse rate: lapse rule 26, 30, 233.7 +lapse rate: lapse rule 27, 32.6, 239 +lapse rate: lapse rule 28, 35, 245.2 +lapse rate: lapse rule 29, 37.5, 251.3 +lapse rate: lapse rule 30, 40, 257.5 +lapse rate: lapse rule 31, 42.5, 263.7 +lapse rate: lapse rule 32, 45, 269.9 +lapse rate: lapse rule 33, 47.5, 275.2 +lapse rate: lapse rule 34, 50, 275.7 +lapse rate: lapse rule 35, 55, 269.3 +lapse rate: lapse rule 36, 60, 257.1 +lapse rate: lapse rule 37, 65, 240.1 +lapse rate: lapse rule 38, 70, 218 +lapse rate: lapse rule 39, 75, 196.1 +lapse rate: lapse rule 40, 80, 174.1 +lapse rate: lapse rule 41, 85, 165.1 +lapse rate: lapse rule 42, 90, 165 +lapse rate: lapse rule 43, 95, 178.3 +lapse rate: lapse rule 44, 100, 190.5 +lapse rate: lapse rule 45, 105, 222.2 +lapse rate: lapse rule 46, 110, 262.4 +lapse rate: lapse rule 47, 115, 316.8 +lapse rate: lapse rule 48, 120, 380 + +# h2o composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: h2o rule 0, 1, 0.0138, h2o +composition rate: h2o rule 1, 2, 0.00968, h2o +composition rate: h2o rule 2, 3, 0.00598, h2o +composition rate: h2o rule 3, 4, 0.00381, h2o +composition rate: h2o rule 4, 5, 0.0022299999999999998, h2o +composition rate: h2o rule 5, 6, 0.0015099999999999998, h2o +composition rate: h2o rule 6, 7, 0.0010199999999999999, h2o +composition rate: h2o rule 7, 8, 0.000646, h2o +composition rate: h2o rule 8, 9, 0.00041299999999999996, h2o +composition rate: h2o rule 9, 10, 0.000247, h2o +composition rate: h2o rule 10, 11, 9.559999999999999e-05, h2o +composition rate: h2o rule 11, 12, 2.9399999999999996e-05, h2o +composition rate: h2o rule 12, 13, 8e-06, h2o +composition rate: h2o rule 13, 14, 4.9999999999999996e-06, h2o +composition rate: h2o rule 14, 15, 3.3999999999999996e-06, h2o +composition rate: h2o rule 15, 16, 3.2999999999999997e-06, h2o +composition rate: h2o rule 16, 17, 3.2e-06, h2o +composition rate: h2o rule 17, 18, 3.15e-06, h2o +composition rate: h2o rule 18, 19, 3.2e-06, h2o +composition rate: h2o rule 19, 20, 3.2999999999999997e-06, h2o +composition rate: h2o rule 20, 21, 3.45e-06, h2o +composition rate: h2o rule 21, 22, 3.6e-06, h2o +composition rate: h2o rule 22, 23, 3.8499999999999996e-06, h2o +composition rate: h2o rule 23, 24, 4e-06, h2o +composition rate: h2o rule 24, 25, 4.2e-06, h2o +composition rate: h2o rule 25, 27.6, 4.45e-06, h2o +composition rate: h2o rule 26, 30, 4.7e-06, h2o +composition rate: h2o rule 27, 32.6, 4.87e-06, h2o +composition rate: h2o rule 28, 35, 4.95e-06, h2o +composition rate: h2o rule 29, 37.5, 4.9999999999999996e-06, h2o +composition rate: h2o rule 30, 40, 5.0999999999999995e-06, h2o +composition rate: h2o rule 31, 42.5, 5.299999999999999e-06, h2o +composition rate: h2o rule 32, 45, 5.45e-06, h2o +composition rate: h2o rule 33, 47.5, 5.5e-06, h2o +composition rate: h2o rule 34, 50, 5.5e-06, h2o +composition rate: h2o rule 35, 55, 5.35e-06, h2o +composition rate: h2o rule 36, 60, 4.9999999999999996e-06, h2o +composition rate: h2o rule 37, 65, 4.4e-06, h2o +composition rate: h2o rule 38, 70, 3.7e-06, h2o +composition rate: h2o rule 39, 75, 2.95e-06, h2o +composition rate: h2o rule 40, 80, 2.1e-06, h2o +composition rate: h2o rule 41, 85, 1.33e-06, h2o +composition rate: h2o rule 42, 90, 8.499999999999999e-07, h2o +composition rate: h2o rule 43, 95, 5.4e-07, h2o +composition rate: h2o rule 44, 100, 4e-07, h2o +composition rate: h2o rule 45, 105, 3.4000000000000003e-07, h2o +composition rate: h2o rule 46, 110, 2.8e-07, h2o +composition rate: h2o rule 47, 115, 2.4e-07, h2o +composition rate: h2o rule 48, 120, 2e-07, h2o + +# o3 composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: o3 rule 0, 1, 3.3399999999999995e-08, o3 +composition rate: o3 rule 1, 2, 3.69e-08, o3 +composition rate: o3 rule 2, 3, 4.22e-08, o3 +composition rate: o3 rule 3, 4, 4.8199999999999995e-08, o3 +composition rate: o3 rule 4, 5, 5.5100000000000004e-08, o3 +composition rate: o3 rule 5, 6, 6.41e-08, o3 +composition rate: o3 rule 6, 7, 7.76e-08, o3 +composition rate: o3 rule 7, 8, 9.13e-08, o3 +composition rate: o3 rule 8, 9, 1.11e-07, o3 +composition rate: o3 rule 9, 10, 1.3e-07, o3 +composition rate: o3 rule 10, 11, 1.7899999999999997e-07, o3 +composition rate: o3 rule 11, 12, 2.23e-07, o3 +composition rate: o3 rule 12, 13, 3e-07, o3 +composition rate: o3 rule 13, 14, 4.3999999999999997e-07, o3 +composition rate: o3 rule 14, 15, 5e-07, o3 +composition rate: o3 rule 15, 16, 6e-07, o3 +composition rate: o3 rule 16, 17, 7e-07, o3 +composition rate: o3 rule 17, 18, 1e-06, o3 +composition rate: o3 rule 18, 19, 1.5e-06, o3 +composition rate: o3 rule 19, 20, 2e-06, o3 +composition rate: o3 rule 20, 21, 2.4e-06, o3 +composition rate: o3 rule 21, 22, 2.8999999999999998e-06, o3 +composition rate: o3 rule 22, 23, 3.3999999999999996e-06, o3 +composition rate: o3 rule 23, 24, 4e-06, o3 +composition rate: o3 rule 24, 25, 4.8e-06, o3 +composition rate: o3 rule 25, 27.6, 6e-06, o3 +composition rate: o3 rule 26, 30, 7e-06, o3 +composition rate: o3 rule 27, 32.6, 8.099999999999999e-06, o3 +composition rate: o3 rule 28, 35, 8.9e-06, o3 +composition rate: o3 rule 29, 37.5, 8.7e-06, o3 +composition rate: o3 rule 30, 40, 7.55e-06, o3 +composition rate: o3 rule 31, 42.5, 5.9e-06, o3 +composition rate: o3 rule 32, 45, 4.5e-06, o3 +composition rate: o3 rule 33, 47.5, 3.5e-06, o3 +composition rate: o3 rule 34, 50, 2.8e-06, o3 +composition rate: o3 rule 35, 55, 1.8e-06, o3 +composition rate: o3 rule 36, 60, 1.3e-06, o3 +composition rate: o3 rule 37, 65, 8e-07, o3 +composition rate: o3 rule 38, 70, 4e-07, o3 +composition rate: o3 rule 39, 75, 1.8999999999999998e-07, o3 +composition rate: o3 rule 40, 80, 2e-07, o3 +composition rate: o3 rule 41, 85, 5.699999999999999e-07, o3 +composition rate: o3 rule 42, 90, 7.5e-07, o3 +composition rate: o3 rule 43, 95, 7e-07, o3 +composition rate: o3 rule 44, 100, 4.03e-07, o3 +composition rate: o3 rule 45, 105, 2e-07, o3 +composition rate: o3 rule 46, 110, 5e-08, o3 +composition rate: o3 rule 47, 115, 5e-09, o3 +composition rate: o3 rule 48, 120, 5e-10, o3 + diff --git a/collins 2b.pyr b/collins 2b.pyr new file mode 100644 index 0000000..9185ede --- /dev/null +++ b/collins 2b.pyr @@ -0,0 +1,174 @@ +# atm profile for midlatitude summer + +# surface values (pressure, temperature, final height, initial layer thickness, acceleration of gravity, range min, range max) +surface: 1010.0, 294.2, 120, 100, 9.8, 100, 2500 + +# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile +# except for co2, o2, n2, and ar +molecule: co2, .000574 +molecule: h2o, 0.0186 +molecule: o2, .20 +molecule: n2, .77 +molecule: ar, .009 +#molecule: ch4, 1.6999999999999998e-06 +molecule: o3, 3.02e-08 +#molecule: n2o, 3.2e-07 +#molecule: co, 1.5e-07 + +# lapse rate profile +# rules are: name, final height, final value +# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule) +lapse rate: lapse rule 0, 1, 289.7 +lapse rate: lapse rule 1, 2, 295.2 +lapse rate: lapse rule 2, 3, 279.2 +lapse rate: lapse rule 3, 4, 273.2 +lapse rate: lapse rule 4, 5, 287.2 +lapse rate: lapse rule 5, 6, 261.2 +lapse rate: lapse rule 6, 7, 254.7 +lapse rate: lapse rule 7, 8, 248.2 +lapse rate: lapse rule 8, 9, 241.7 +lapse rate: lapse rule 9, 10, 235.3 +lapse rate: lapse rule 10, 11, 228.8 +lapse rate: lapse rule 11, 12, 222.3 +lapse rate: lapse rule 12, 13, 215.8 +lapse rate: lapse rule 13, 14, 215.7 +lapse rate: lapse rule 14, 15, 215.7 +lapse rate: lapse rule 15, 16, 215.7 +lapse rate: lapse rule 16, 17, 215.7 +lapse rate: lapse rule 17, 18, 216.8 +lapse rate: lapse rule 18, 19, 217.9 +lapse rate: lapse rule 19, 20, 219.2 +lapse rate: lapse rule 20, 21, 220.4 +lapse rate: lapse rule 21, 22, 221.6 +lapse rate: lapse rule 22, 23, 222.8 +lapse rate: lapse rule 23, 24, 223.9 +lapse rate: lapse rule 24, 25, 225.1 +lapse rate: lapse rule 25, 27.6, 228.5 +lapse rate: lapse rule 26, 30, 233.7 +lapse rate: lapse rule 27, 32.6, 239 +lapse rate: lapse rule 28, 35, 245.2 +lapse rate: lapse rule 29, 37.5, 251.3 +lapse rate: lapse rule 30, 40, 257.5 +lapse rate: lapse rule 31, 42.5, 263.7 +lapse rate: lapse rule 32, 45, 269.9 +lapse rate: lapse rule 33, 47.5, 275.2 +lapse rate: lapse rule 34, 50, 275.7 +lapse rate: lapse rule 35, 55, 269.3 +lapse rate: lapse rule 36, 60, 257.1 +lapse rate: lapse rule 37, 65, 240.1 +lapse rate: lapse rule 38, 70, 218 +lapse rate: lapse rule 39, 75, 196.1 +lapse rate: lapse rule 40, 80, 174.1 +lapse rate: lapse rule 41, 85, 165.1 +lapse rate: lapse rule 42, 90, 165 +lapse rate: lapse rule 43, 95, 178.3 +lapse rate: lapse rule 44, 100, 190.5 +lapse rate: lapse rule 45, 105, 222.2 +lapse rate: lapse rule 46, 110, 262.4 +lapse rate: lapse rule 47, 115, 316.8 +lapse rate: lapse rule 48, 120, 380 + +# h2o composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: h2o rule 0, 1, 0.0138, h2o +composition rate: h2o rule 1, 2, 0.00968, h2o +composition rate: h2o rule 2, 3, 0.00598, h2o +composition rate: h2o rule 3, 4, 0.00381, h2o +composition rate: h2o rule 4, 5, 0.0022299999999999998, h2o +composition rate: h2o rule 5, 6, 0.0015099999999999998, h2o +composition rate: h2o rule 6, 7, 0.0010199999999999999, h2o +composition rate: h2o rule 7, 8, 0.000646, h2o +composition rate: h2o rule 8, 9, 0.00041299999999999996, h2o +composition rate: h2o rule 9, 10, 0.000247, h2o +composition rate: h2o rule 10, 11, 9.559999999999999e-05, h2o +composition rate: h2o rule 11, 12, 2.9399999999999996e-05, h2o +composition rate: h2o rule 12, 13, 8e-06, h2o +composition rate: h2o rule 13, 14, 4.9999999999999996e-06, h2o +composition rate: h2o rule 14, 15, 3.3999999999999996e-06, h2o +composition rate: h2o rule 15, 16, 3.2999999999999997e-06, h2o +composition rate: h2o rule 16, 17, 3.2e-06, h2o +composition rate: h2o rule 17, 18, 3.15e-06, h2o +composition rate: h2o rule 18, 19, 3.2e-06, h2o +composition rate: h2o rule 19, 20, 3.2999999999999997e-06, h2o +composition rate: h2o rule 20, 21, 3.45e-06, h2o +composition rate: h2o rule 21, 22, 3.6e-06, h2o +composition rate: h2o rule 22, 23, 3.8499999999999996e-06, h2o +composition rate: h2o rule 23, 24, 4e-06, h2o +composition rate: h2o rule 24, 25, 4.2e-06, h2o +composition rate: h2o rule 25, 27.6, 4.45e-06, h2o +composition rate: h2o rule 26, 30, 4.7e-06, h2o +composition rate: h2o rule 27, 32.6, 4.87e-06, h2o +composition rate: h2o rule 28, 35, 4.95e-06, h2o +composition rate: h2o rule 29, 37.5, 4.9999999999999996e-06, h2o +composition rate: h2o rule 30, 40, 5.0999999999999995e-06, h2o +composition rate: h2o rule 31, 42.5, 5.299999999999999e-06, h2o +composition rate: h2o rule 32, 45, 5.45e-06, h2o +composition rate: h2o rule 33, 47.5, 5.5e-06, h2o +composition rate: h2o rule 34, 50, 5.5e-06, h2o +composition rate: h2o rule 35, 55, 5.35e-06, h2o +composition rate: h2o rule 36, 60, 4.9999999999999996e-06, h2o +composition rate: h2o rule 37, 65, 4.4e-06, h2o +composition rate: h2o rule 38, 70, 3.7e-06, h2o +composition rate: h2o rule 39, 75, 2.95e-06, h2o +composition rate: h2o rule 40, 80, 2.1e-06, h2o +composition rate: h2o rule 41, 85, 1.33e-06, h2o +composition rate: h2o rule 42, 90, 8.499999999999999e-07, h2o +composition rate: h2o rule 43, 95, 5.4e-07, h2o +composition rate: h2o rule 44, 100, 4e-07, h2o +composition rate: h2o rule 45, 105, 3.4000000000000003e-07, h2o +composition rate: h2o rule 46, 110, 2.8e-07, h2o +composition rate: h2o rule 47, 115, 2.4e-07, h2o +composition rate: h2o rule 48, 120, 2e-07, h2o + +# o3 composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: o3 rule 0, 1, 3.3399999999999995e-08, o3 +composition rate: o3 rule 1, 2, 3.69e-08, o3 +composition rate: o3 rule 2, 3, 4.22e-08, o3 +composition rate: o3 rule 3, 4, 4.8199999999999995e-08, o3 +composition rate: o3 rule 4, 5, 5.5100000000000004e-08, o3 +composition rate: o3 rule 5, 6, 6.41e-08, o3 +composition rate: o3 rule 6, 7, 7.76e-08, o3 +composition rate: o3 rule 7, 8, 9.13e-08, o3 +composition rate: o3 rule 8, 9, 1.11e-07, o3 +composition rate: o3 rule 9, 10, 1.3e-07, o3 +composition rate: o3 rule 10, 11, 1.7899999999999997e-07, o3 +composition rate: o3 rule 11, 12, 2.23e-07, o3 +composition rate: o3 rule 12, 13, 3e-07, o3 +composition rate: o3 rule 13, 14, 4.3999999999999997e-07, o3 +composition rate: o3 rule 14, 15, 5e-07, o3 +composition rate: o3 rule 15, 16, 6e-07, o3 +composition rate: o3 rule 16, 17, 7e-07, o3 +composition rate: o3 rule 17, 18, 1e-06, o3 +composition rate: o3 rule 18, 19, 1.5e-06, o3 +composition rate: o3 rule 19, 20, 2e-06, o3 +composition rate: o3 rule 20, 21, 2.4e-06, o3 +composition rate: o3 rule 21, 22, 2.8999999999999998e-06, o3 +composition rate: o3 rule 22, 23, 3.3999999999999996e-06, o3 +composition rate: o3 rule 23, 24, 4e-06, o3 +composition rate: o3 rule 24, 25, 4.8e-06, o3 +composition rate: o3 rule 25, 27.6, 6e-06, o3 +composition rate: o3 rule 26, 30, 7e-06, o3 +composition rate: o3 rule 27, 32.6, 8.099999999999999e-06, o3 +composition rate: o3 rule 28, 35, 8.9e-06, o3 +composition rate: o3 rule 29, 37.5, 8.7e-06, o3 +composition rate: o3 rule 30, 40, 7.55e-06, o3 +composition rate: o3 rule 31, 42.5, 5.9e-06, o3 +composition rate: o3 rule 32, 45, 4.5e-06, o3 +composition rate: o3 rule 33, 47.5, 3.5e-06, o3 +composition rate: o3 rule 34, 50, 2.8e-06, o3 +composition rate: o3 rule 35, 55, 1.8e-06, o3 +composition rate: o3 rule 36, 60, 1.3e-06, o3 +composition rate: o3 rule 37, 65, 8e-07, o3 +composition rate: o3 rule 38, 70, 4e-07, o3 +composition rate: o3 rule 39, 75, 1.8999999999999998e-07, o3 +composition rate: o3 rule 40, 80, 2e-07, o3 +composition rate: o3 rule 41, 85, 5.699999999999999e-07, o3 +composition rate: o3 rule 42, 90, 7.5e-07, o3 +composition rate: o3 rule 43, 95, 7e-07, o3 +composition rate: o3 rule 44, 100, 4.03e-07, o3 +composition rate: o3 rule 45, 105, 2e-07, o3 +composition rate: o3 rule 46, 110, 5e-08, o3 +composition rate: o3 rule 47, 115, 5e-09, o3 +composition rate: o3 rule 48, 120, 5e-10, o3 + diff --git a/collins 3a thick.pyr b/collins 3a thick.pyr new file mode 100644 index 0000000..b691d1c --- /dev/null +++ b/collins 3a thick.pyr @@ -0,0 +1,173 @@ +# atm profile for midlatitude summer + +# surface values (pressure, temperature, final height, initial layer thickness, acceleration of gravity, range min, range max) +surface: 1010.0, 294.2, 120, 250, 9.8, 100, 2500 + +# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile +# except for co2, o2, n2, and ar +molecule: co2, .000287 +molecule: h2o, 0.0186 +molecule: o2, .20 +molecule: n2, .77 +molecule: ar, .009 +molecule: ch4, 0.000000806 +molecule: o3, 3.02e-08 +molecule: n2o, 0.000000275 + +# lapse rate profile +# rules are: name, final height, final value +# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule) +lapse rate: lapse rule 0, 1, 289.7 +lapse rate: lapse rule 1, 2, 295.2 +lapse rate: lapse rule 2, 3, 279.2 +lapse rate: lapse rule 3, 4, 273.2 +lapse rate: lapse rule 4, 5, 287.2 +lapse rate: lapse rule 5, 6, 261.2 +lapse rate: lapse rule 6, 7, 254.7 +lapse rate: lapse rule 7, 8, 248.2 +lapse rate: lapse rule 8, 9, 241.7 +lapse rate: lapse rule 9, 10, 235.3 +lapse rate: lapse rule 10, 11, 228.8 +lapse rate: lapse rule 11, 12, 222.3 +lapse rate: lapse rule 12, 13, 215.8 +lapse rate: lapse rule 13, 14, 215.7 +lapse rate: lapse rule 14, 15, 215.7 +lapse rate: lapse rule 15, 16, 215.7 +lapse rate: lapse rule 16, 17, 215.7 +lapse rate: lapse rule 17, 18, 216.8 +lapse rate: lapse rule 18, 19, 217.9 +lapse rate: lapse rule 19, 20, 219.2 +lapse rate: lapse rule 20, 21, 220.4 +lapse rate: lapse rule 21, 22, 221.6 +lapse rate: lapse rule 22, 23, 222.8 +lapse rate: lapse rule 23, 24, 223.9 +lapse rate: lapse rule 24, 25, 225.1 +lapse rate: lapse rule 25, 27.6, 228.5 +lapse rate: lapse rule 26, 30, 233.7 +lapse rate: lapse rule 27, 32.6, 239 +lapse rate: lapse rule 28, 35, 245.2 +lapse rate: lapse rule 29, 37.5, 251.3 +lapse rate: lapse rule 30, 40, 257.5 +lapse rate: lapse rule 31, 42.5, 263.7 +lapse rate: lapse rule 32, 45, 269.9 +lapse rate: lapse rule 33, 47.5, 275.2 +lapse rate: lapse rule 34, 50, 275.7 +lapse rate: lapse rule 35, 55, 269.3 +lapse rate: lapse rule 36, 60, 257.1 +lapse rate: lapse rule 37, 65, 240.1 +lapse rate: lapse rule 38, 70, 218 +lapse rate: lapse rule 39, 75, 196.1 +lapse rate: lapse rule 40, 80, 174.1 +lapse rate: lapse rule 41, 85, 165.1 +lapse rate: lapse rule 42, 90, 165 +lapse rate: lapse rule 43, 95, 178.3 +lapse rate: lapse rule 44, 100, 190.5 +lapse rate: lapse rule 45, 105, 222.2 +lapse rate: lapse rule 46, 110, 262.4 +lapse rate: lapse rule 47, 115, 316.8 +lapse rate: lapse rule 48, 120, 380 + +# h2o composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: h2o rule 0, 1, 0.0138, h2o +composition rate: h2o rule 1, 2, 0.00968, h2o +composition rate: h2o rule 2, 3, 0.00598, h2o +composition rate: h2o rule 3, 4, 0.00381, h2o +composition rate: h2o rule 4, 5, 0.0022299999999999998, h2o +composition rate: h2o rule 5, 6, 0.0015099999999999998, h2o +composition rate: h2o rule 6, 7, 0.0010199999999999999, h2o +composition rate: h2o rule 7, 8, 0.000646, h2o +composition rate: h2o rule 8, 9, 0.00041299999999999996, h2o +composition rate: h2o rule 9, 10, 0.000247, h2o +composition rate: h2o rule 10, 11, 9.559999999999999e-05, h2o +composition rate: h2o rule 11, 12, 2.9399999999999996e-05, h2o +composition rate: h2o rule 12, 13, 8e-06, h2o +composition rate: h2o rule 13, 14, 4.9999999999999996e-06, h2o +composition rate: h2o rule 14, 15, 3.3999999999999996e-06, h2o +composition rate: h2o rule 15, 16, 3.2999999999999997e-06, h2o +composition rate: h2o rule 16, 17, 3.2e-06, h2o +composition rate: h2o rule 17, 18, 3.15e-06, h2o +composition rate: h2o rule 18, 19, 3.2e-06, h2o +composition rate: h2o rule 19, 20, 3.2999999999999997e-06, h2o +composition rate: h2o rule 20, 21, 3.45e-06, h2o +composition rate: h2o rule 21, 22, 3.6e-06, h2o +composition rate: h2o rule 22, 23, 3.8499999999999996e-06, h2o +composition rate: h2o rule 23, 24, 4e-06, h2o +composition rate: h2o rule 24, 25, 4.2e-06, h2o +composition rate: h2o rule 25, 27.6, 4.45e-06, h2o +composition rate: h2o rule 26, 30, 4.7e-06, h2o +composition rate: h2o rule 27, 32.6, 4.87e-06, h2o +composition rate: h2o rule 28, 35, 4.95e-06, h2o +composition rate: h2o rule 29, 37.5, 4.9999999999999996e-06, h2o +composition rate: h2o rule 30, 40, 5.0999999999999995e-06, h2o +composition rate: h2o rule 31, 42.5, 5.299999999999999e-06, h2o +composition rate: h2o rule 32, 45, 5.45e-06, h2o +composition rate: h2o rule 33, 47.5, 5.5e-06, h2o +composition rate: h2o rule 34, 50, 5.5e-06, h2o +composition rate: h2o rule 35, 55, 5.35e-06, h2o +composition rate: h2o rule 36, 60, 4.9999999999999996e-06, h2o +composition rate: h2o rule 37, 65, 4.4e-06, h2o +composition rate: h2o rule 38, 70, 3.7e-06, h2o +composition rate: h2o rule 39, 75, 2.95e-06, h2o +composition rate: h2o rule 40, 80, 2.1e-06, h2o +composition rate: h2o rule 41, 85, 1.33e-06, h2o +composition rate: h2o rule 42, 90, 8.499999999999999e-07, h2o +composition rate: h2o rule 43, 95, 5.4e-07, h2o +composition rate: h2o rule 44, 100, 4e-07, h2o +composition rate: h2o rule 45, 105, 3.4000000000000003e-07, h2o +composition rate: h2o rule 46, 110, 2.8e-07, h2o +composition rate: h2o rule 47, 115, 2.4e-07, h2o +composition rate: h2o rule 48, 120, 2e-07, h2o + +# o3 composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: o3 rule 0, 1, 3.3399999999999995e-08, o3 +composition rate: o3 rule 1, 2, 3.69e-08, o3 +composition rate: o3 rule 2, 3, 4.22e-08, o3 +composition rate: o3 rule 3, 4, 4.8199999999999995e-08, o3 +composition rate: o3 rule 4, 5, 5.5100000000000004e-08, o3 +composition rate: o3 rule 5, 6, 6.41e-08, o3 +composition rate: o3 rule 6, 7, 7.76e-08, o3 +composition rate: o3 rule 7, 8, 9.13e-08, o3 +composition rate: o3 rule 8, 9, 1.11e-07, o3 +composition rate: o3 rule 9, 10, 1.3e-07, o3 +composition rate: o3 rule 10, 11, 1.7899999999999997e-07, o3 +composition rate: o3 rule 11, 12, 2.23e-07, o3 +composition rate: o3 rule 12, 13, 3e-07, o3 +composition rate: o3 rule 13, 14, 4.3999999999999997e-07, o3 +composition rate: o3 rule 14, 15, 5e-07, o3 +composition rate: o3 rule 15, 16, 6e-07, o3 +composition rate: o3 rule 16, 17, 7e-07, o3 +composition rate: o3 rule 17, 18, 1e-06, o3 +composition rate: o3 rule 18, 19, 1.5e-06, o3 +composition rate: o3 rule 19, 20, 2e-06, o3 +composition rate: o3 rule 20, 21, 2.4e-06, o3 +composition rate: o3 rule 21, 22, 2.8999999999999998e-06, o3 +composition rate: o3 rule 22, 23, 3.3999999999999996e-06, o3 +composition rate: o3 rule 23, 24, 4e-06, o3 +composition rate: o3 rule 24, 25, 4.8e-06, o3 +composition rate: o3 rule 25, 27.6, 6e-06, o3 +composition rate: o3 rule 26, 30, 7e-06, o3 +composition rate: o3 rule 27, 32.6, 8.099999999999999e-06, o3 +composition rate: o3 rule 28, 35, 8.9e-06, o3 +composition rate: o3 rule 29, 37.5, 8.7e-06, o3 +composition rate: o3 rule 30, 40, 7.55e-06, o3 +composition rate: o3 rule 31, 42.5, 5.9e-06, o3 +composition rate: o3 rule 32, 45, 4.5e-06, o3 +composition rate: o3 rule 33, 47.5, 3.5e-06, o3 +composition rate: o3 rule 34, 50, 2.8e-06, o3 +composition rate: o3 rule 35, 55, 1.8e-06, o3 +composition rate: o3 rule 36, 60, 1.3e-06, o3 +composition rate: o3 rule 37, 65, 8e-07, o3 +composition rate: o3 rule 38, 70, 4e-07, o3 +composition rate: o3 rule 39, 75, 1.8999999999999998e-07, o3 +composition rate: o3 rule 40, 80, 2e-07, o3 +composition rate: o3 rule 41, 85, 5.699999999999999e-07, o3 +composition rate: o3 rule 42, 90, 7.5e-07, o3 +composition rate: o3 rule 43, 95, 7e-07, o3 +composition rate: o3 rule 44, 100, 4.03e-07, o3 +composition rate: o3 rule 45, 105, 2e-07, o3 +composition rate: o3 rule 46, 110, 5e-08, o3 +composition rate: o3 rule 47, 115, 5e-09, o3 +composition rate: o3 rule 48, 120, 5e-10, o3 + diff --git a/collins 3a.pyr b/collins 3a.pyr new file mode 100644 index 0000000..2d2264d --- /dev/null +++ b/collins 3a.pyr @@ -0,0 +1,173 @@ +# atm profile for midlatitude summer + +# surface values (pressure, temperature, final height, initial layer thickness, acceleration of gravity, range min, range max) +surface: 1010.0, 294.2, 120, 100, 9.8, 100, 2500 + +# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile +# except for co2, o2, n2, and ar +molecule: co2, .000287 +molecule: h2o, 0.0186 +molecule: o2, .20 +molecule: n2, .77 +molecule: ar, .009 +molecule: ch4, 0.000000806 +molecule: o3, 3.02e-08 +molecule: n2o, 0.000000275 + +# lapse rate profile +# rules are: name, final height, final value +# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule) +lapse rate: lapse rule 0, 1, 289.7 +lapse rate: lapse rule 1, 2, 295.2 +lapse rate: lapse rule 2, 3, 279.2 +lapse rate: lapse rule 3, 4, 273.2 +lapse rate: lapse rule 4, 5, 287.2 +lapse rate: lapse rule 5, 6, 261.2 +lapse rate: lapse rule 6, 7, 254.7 +lapse rate: lapse rule 7, 8, 248.2 +lapse rate: lapse rule 8, 9, 241.7 +lapse rate: lapse rule 9, 10, 235.3 +lapse rate: lapse rule 10, 11, 228.8 +lapse rate: lapse rule 11, 12, 222.3 +lapse rate: lapse rule 12, 13, 215.8 +lapse rate: lapse rule 13, 14, 215.7 +lapse rate: lapse rule 14, 15, 215.7 +lapse rate: lapse rule 15, 16, 215.7 +lapse rate: lapse rule 16, 17, 215.7 +lapse rate: lapse rule 17, 18, 216.8 +lapse rate: lapse rule 18, 19, 217.9 +lapse rate: lapse rule 19, 20, 219.2 +lapse rate: lapse rule 20, 21, 220.4 +lapse rate: lapse rule 21, 22, 221.6 +lapse rate: lapse rule 22, 23, 222.8 +lapse rate: lapse rule 23, 24, 223.9 +lapse rate: lapse rule 24, 25, 225.1 +lapse rate: lapse rule 25, 27.6, 228.5 +lapse rate: lapse rule 26, 30, 233.7 +lapse rate: lapse rule 27, 32.6, 239 +lapse rate: lapse rule 28, 35, 245.2 +lapse rate: lapse rule 29, 37.5, 251.3 +lapse rate: lapse rule 30, 40, 257.5 +lapse rate: lapse rule 31, 42.5, 263.7 +lapse rate: lapse rule 32, 45, 269.9 +lapse rate: lapse rule 33, 47.5, 275.2 +lapse rate: lapse rule 34, 50, 275.7 +lapse rate: lapse rule 35, 55, 269.3 +lapse rate: lapse rule 36, 60, 257.1 +lapse rate: lapse rule 37, 65, 240.1 +lapse rate: lapse rule 38, 70, 218 +lapse rate: lapse rule 39, 75, 196.1 +lapse rate: lapse rule 40, 80, 174.1 +lapse rate: lapse rule 41, 85, 165.1 +lapse rate: lapse rule 42, 90, 165 +lapse rate: lapse rule 43, 95, 178.3 +lapse rate: lapse rule 44, 100, 190.5 +lapse rate: lapse rule 45, 105, 222.2 +lapse rate: lapse rule 46, 110, 262.4 +lapse rate: lapse rule 47, 115, 316.8 +lapse rate: lapse rule 48, 120, 380 + +# h2o composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: h2o rule 0, 1, 0.0138, h2o +composition rate: h2o rule 1, 2, 0.00968, h2o +composition rate: h2o rule 2, 3, 0.00598, h2o +composition rate: h2o rule 3, 4, 0.00381, h2o +composition rate: h2o rule 4, 5, 0.0022299999999999998, h2o +composition rate: h2o rule 5, 6, 0.0015099999999999998, h2o +composition rate: h2o rule 6, 7, 0.0010199999999999999, h2o +composition rate: h2o rule 7, 8, 0.000646, h2o +composition rate: h2o rule 8, 9, 0.00041299999999999996, h2o +composition rate: h2o rule 9, 10, 0.000247, h2o +composition rate: h2o rule 10, 11, 9.559999999999999e-05, h2o +composition rate: h2o rule 11, 12, 2.9399999999999996e-05, h2o +composition rate: h2o rule 12, 13, 8e-06, h2o +composition rate: h2o rule 13, 14, 4.9999999999999996e-06, h2o +composition rate: h2o rule 14, 15, 3.3999999999999996e-06, h2o +composition rate: h2o rule 15, 16, 3.2999999999999997e-06, h2o +composition rate: h2o rule 16, 17, 3.2e-06, h2o +composition rate: h2o rule 17, 18, 3.15e-06, h2o +composition rate: h2o rule 18, 19, 3.2e-06, h2o +composition rate: h2o rule 19, 20, 3.2999999999999997e-06, h2o +composition rate: h2o rule 20, 21, 3.45e-06, h2o +composition rate: h2o rule 21, 22, 3.6e-06, h2o +composition rate: h2o rule 22, 23, 3.8499999999999996e-06, h2o +composition rate: h2o rule 23, 24, 4e-06, h2o +composition rate: h2o rule 24, 25, 4.2e-06, h2o +composition rate: h2o rule 25, 27.6, 4.45e-06, h2o +composition rate: h2o rule 26, 30, 4.7e-06, h2o +composition rate: h2o rule 27, 32.6, 4.87e-06, h2o +composition rate: h2o rule 28, 35, 4.95e-06, h2o +composition rate: h2o rule 29, 37.5, 4.9999999999999996e-06, h2o +composition rate: h2o rule 30, 40, 5.0999999999999995e-06, h2o +composition rate: h2o rule 31, 42.5, 5.299999999999999e-06, h2o +composition rate: h2o rule 32, 45, 5.45e-06, h2o +composition rate: h2o rule 33, 47.5, 5.5e-06, h2o +composition rate: h2o rule 34, 50, 5.5e-06, h2o +composition rate: h2o rule 35, 55, 5.35e-06, h2o +composition rate: h2o rule 36, 60, 4.9999999999999996e-06, h2o +composition rate: h2o rule 37, 65, 4.4e-06, h2o +composition rate: h2o rule 38, 70, 3.7e-06, h2o +composition rate: h2o rule 39, 75, 2.95e-06, h2o +composition rate: h2o rule 40, 80, 2.1e-06, h2o +composition rate: h2o rule 41, 85, 1.33e-06, h2o +composition rate: h2o rule 42, 90, 8.499999999999999e-07, h2o +composition rate: h2o rule 43, 95, 5.4e-07, h2o +composition rate: h2o rule 44, 100, 4e-07, h2o +composition rate: h2o rule 45, 105, 3.4000000000000003e-07, h2o +composition rate: h2o rule 46, 110, 2.8e-07, h2o +composition rate: h2o rule 47, 115, 2.4e-07, h2o +composition rate: h2o rule 48, 120, 2e-07, h2o + +# o3 composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: o3 rule 0, 1, 3.3399999999999995e-08, o3 +composition rate: o3 rule 1, 2, 3.69e-08, o3 +composition rate: o3 rule 2, 3, 4.22e-08, o3 +composition rate: o3 rule 3, 4, 4.8199999999999995e-08, o3 +composition rate: o3 rule 4, 5, 5.5100000000000004e-08, o3 +composition rate: o3 rule 5, 6, 6.41e-08, o3 +composition rate: o3 rule 6, 7, 7.76e-08, o3 +composition rate: o3 rule 7, 8, 9.13e-08, o3 +composition rate: o3 rule 8, 9, 1.11e-07, o3 +composition rate: o3 rule 9, 10, 1.3e-07, o3 +composition rate: o3 rule 10, 11, 1.7899999999999997e-07, o3 +composition rate: o3 rule 11, 12, 2.23e-07, o3 +composition rate: o3 rule 12, 13, 3e-07, o3 +composition rate: o3 rule 13, 14, 4.3999999999999997e-07, o3 +composition rate: o3 rule 14, 15, 5e-07, o3 +composition rate: o3 rule 15, 16, 6e-07, o3 +composition rate: o3 rule 16, 17, 7e-07, o3 +composition rate: o3 rule 17, 18, 1e-06, o3 +composition rate: o3 rule 18, 19, 1.5e-06, o3 +composition rate: o3 rule 19, 20, 2e-06, o3 +composition rate: o3 rule 20, 21, 2.4e-06, o3 +composition rate: o3 rule 21, 22, 2.8999999999999998e-06, o3 +composition rate: o3 rule 22, 23, 3.3999999999999996e-06, o3 +composition rate: o3 rule 23, 24, 4e-06, o3 +composition rate: o3 rule 24, 25, 4.8e-06, o3 +composition rate: o3 rule 25, 27.6, 6e-06, o3 +composition rate: o3 rule 26, 30, 7e-06, o3 +composition rate: o3 rule 27, 32.6, 8.099999999999999e-06, o3 +composition rate: o3 rule 28, 35, 8.9e-06, o3 +composition rate: o3 rule 29, 37.5, 8.7e-06, o3 +composition rate: o3 rule 30, 40, 7.55e-06, o3 +composition rate: o3 rule 31, 42.5, 5.9e-06, o3 +composition rate: o3 rule 32, 45, 4.5e-06, o3 +composition rate: o3 rule 33, 47.5, 3.5e-06, o3 +composition rate: o3 rule 34, 50, 2.8e-06, o3 +composition rate: o3 rule 35, 55, 1.8e-06, o3 +composition rate: o3 rule 36, 60, 1.3e-06, o3 +composition rate: o3 rule 37, 65, 8e-07, o3 +composition rate: o3 rule 38, 70, 4e-07, o3 +composition rate: o3 rule 39, 75, 1.8999999999999998e-07, o3 +composition rate: o3 rule 40, 80, 2e-07, o3 +composition rate: o3 rule 41, 85, 5.699999999999999e-07, o3 +composition rate: o3 rule 42, 90, 7.5e-07, o3 +composition rate: o3 rule 43, 95, 7e-07, o3 +composition rate: o3 rule 44, 100, 4.03e-07, o3 +composition rate: o3 rule 45, 105, 2e-07, o3 +composition rate: o3 rule 46, 110, 5e-08, o3 +composition rate: o3 rule 47, 115, 5e-09, o3 +composition rate: o3 rule 48, 120, 5e-10, o3 + diff --git a/earthsimple narrow.pyr b/earthsimple narrow.pyr deleted file mode 100644 index d4b0b61..0000000 --- a/earthsimple narrow.pyr +++ /dev/null @@ -1,38 +0,0 @@ -# A demo file for pyrad - -# mBar , K , km, m , g, cm-1,cm-1 -surface: 1013.25, 288, 120, 100, 9.8, 500, 1000 - -# mol text name, concentration -molecule: co2, .000400 -molecule: h2o, .018000 -molecule: o3, 0 -molecule: o2, .20 -molecule: n2, .77 -molecule: ch4, .0000018 -molecule: ar, .009 - -# name, endHeight, endTemp -lapse rate: troposphere, 11, 216 -lapse rate: tropopause, 20, 216 -lapse rate: stratosphere, 32, 228 -lapse rate: stratosphere, 47, 270 -lapse rate: stratopause, 51, 270 -lapse rate: mesosphere, 71, 214 -lapse rate: mesosphere2, 80, 190 -lapse rate: mesopause, 90, 190 -lapse rate: thermosphere, 120, 228 - -# name, endHeight, endValue, moleculeName -composition rate: WV boundary layer, 2.5, 18000e-6, h2o -composition rate: WV troposphere1, 8, 200e-6, h2o -composition rate: WV troposphere2, 9, 400e-6, h2o -composition rate: WV troposphere2, 10, 400e-6, h2o -composition rate: WV tropopause, 20, 2e-6, h2o -composition rate: WV stratosphere to top,120, 0, h2o - -composition rate: troposphere ozone, 16, 60E-9, o3 -composition rate: tropopause ozone, 32, 5E-6, o3 -composition rate: upper strat ozone, 60, 0, o3 -composition rate: strat on up ozone, 120, 0, o3 - diff --git a/earthsimple.pyr b/earthsimple.pyr deleted file mode 100644 index 5ab3971..0000000 --- a/earthsimple.pyr +++ /dev/null @@ -1,38 +0,0 @@ -# A demo file for pyrad - -# mBar , K , km, m , g, -surface: 1013.25, 288, 120, 100, 9.8 - -# mol text name, concentration -molecule: co2, .000400 -molecule: h2o, .018000 -molecule: o3, 0 -molecule: o2, .20 -molecule: n2, .77 -molecule: ch4, .0000018 -molecule: ar, .009 - -# name, endHeight, endTemp -lapse rate: troposphere, 11, 216 -lapse rate: tropopause, 20, 216 -lapse rate: stratosphere, 32, 228 -lapse rate: stratosphere, 47, 270 -lapse rate: stratopause, 51, 270 -lapse rate: mesosphere, 71, 214 -lapse rate: mesosphere2, 80, 190 -lapse rate: mesopause, 90, 190 -lapse rate: thermosphere, 120, 228 - -# name, endHeight, endValue, moleculeName -composition rate: WV boundary layer, 2.5, 18000e-6, h2o -composition rate: WV troposphere1, 8, 200e-6, h2o -composition rate: WV troposphere2, 9, 400e-6, h2o -composition rate: WV troposphere2, 10, 400e-6, h2o -composition rate: WV tropopause, 20, 2e-6, h2o -composition rate: WV stratosphere to top,120, 0, h2o - -composition rate: troposphere ozone, 16, 60E-9, o3 -composition rate: tropopause ozone, 32, 5E-6, o3 -composition rate: upper strat ozone, 60, 0, o3 -composition rate: strat on up ozone, 120, 0, o3 - diff --git a/marssimple.pyr b/marssimple.pyr index ed0274a..f35e655 100644 --- a/marssimple.pyr +++ b/marssimple.pyr @@ -1,10 +1,10 @@ # mars simple -surface: 6, 220, 100, 200, 3.711 +surface: 6, 220, 100, 200, 3.711, 100, 2500 molecule: co2, .9532 molecule: n2, .027 molecule: o2, .0013 lapse rate: first layer, 45, 120 -lapse rate: final layer, 100, 120 \ No newline at end of file +lapse rate: final layer, 100, 120 diff --git a/midlatitude summer.pyr b/midlatitude summer.pyr new file mode 100644 index 0000000..8166883 --- /dev/null +++ b/midlatitude summer.pyr @@ -0,0 +1,329 @@ +# atm profile for midlatitude summer + +# surface values (pressure, temperature, final height, initial layer thickness, acceleration of gravity, range min, range max) +surface: 1010.0, 294.2, 120, 100, 9.8, 100, 2500 + +# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile +# except for co2, o2, n2, and ar +molecule: co2, .000287 +molecule: h2o, 0.0186 +molecule: o2, .20 +molecule: n2, .77 +molecule: ar, .009 +molecule: ch4, 1.6999999999999998e-06 +molecule: o3, 3.02e-08 +molecule: n2o, 3.2e-07 +molecule: co, 1.5e-07 + +# lapse rate profile +# rules are: name, final height, final value +# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule) +lapse rate: lapse rule 0, 1, 289.7 +lapse rate: lapse rule 1, 2, 295.2 +lapse rate: lapse rule 2, 3, 279.2 +lapse rate: lapse rule 3, 4, 273.2 +lapse rate: lapse rule 4, 5, 287.2 +lapse rate: lapse rule 5, 6, 261.2 +lapse rate: lapse rule 6, 7, 254.7 +lapse rate: lapse rule 7, 8, 248.2 +lapse rate: lapse rule 8, 9, 241.7 +lapse rate: lapse rule 9, 10, 235.3 +lapse rate: lapse rule 10, 11, 228.8 +lapse rate: lapse rule 11, 12, 222.3 +lapse rate: lapse rule 12, 13, 215.8 +lapse rate: lapse rule 13, 14, 215.7 +lapse rate: lapse rule 14, 15, 215.7 +lapse rate: lapse rule 15, 16, 215.7 +lapse rate: lapse rule 16, 17, 215.7 +lapse rate: lapse rule 17, 18, 216.8 +lapse rate: lapse rule 18, 19, 217.9 +lapse rate: lapse rule 19, 20, 219.2 +lapse rate: lapse rule 20, 21, 220.4 +lapse rate: lapse rule 21, 22, 221.6 +lapse rate: lapse rule 22, 23, 222.8 +lapse rate: lapse rule 23, 24, 223.9 +lapse rate: lapse rule 24, 25, 225.1 +lapse rate: lapse rule 25, 27.6, 228.5 +lapse rate: lapse rule 26, 30, 233.7 +lapse rate: lapse rule 27, 32.6, 239 +lapse rate: lapse rule 28, 35, 245.2 +lapse rate: lapse rule 29, 37.5, 251.3 +lapse rate: lapse rule 30, 40, 257.5 +lapse rate: lapse rule 31, 42.5, 263.7 +lapse rate: lapse rule 32, 45, 269.9 +lapse rate: lapse rule 33, 47.5, 275.2 +lapse rate: lapse rule 34, 50, 275.7 +lapse rate: lapse rule 35, 55, 269.3 +lapse rate: lapse rule 36, 60, 257.1 +lapse rate: lapse rule 37, 65, 240.1 +lapse rate: lapse rule 38, 70, 218 +lapse rate: lapse rule 39, 75, 196.1 +lapse rate: lapse rule 40, 80, 174.1 +lapse rate: lapse rule 41, 85, 165.1 +lapse rate: lapse rule 42, 90, 165 +lapse rate: lapse rule 43, 95, 178.3 +lapse rate: lapse rule 44, 100, 190.5 +lapse rate: lapse rule 45, 105, 222.2 +lapse rate: lapse rule 46, 110, 262.4 +lapse rate: lapse rule 47, 115, 316.8 +lapse rate: lapse rule 48, 120, 380 + +# h2o composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: h2o rule 0, 1, 0.0138, h2o +composition rate: h2o rule 1, 2, 0.00968, h2o +composition rate: h2o rule 2, 3, 0.00598, h2o +composition rate: h2o rule 3, 4, 0.00381, h2o +composition rate: h2o rule 4, 5, 0.0022299999999999998, h2o +composition rate: h2o rule 5, 6, 0.0015099999999999998, h2o +composition rate: h2o rule 6, 7, 0.0010199999999999999, h2o +composition rate: h2o rule 7, 8, 0.000646, h2o +composition rate: h2o rule 8, 9, 0.00041299999999999996, h2o +composition rate: h2o rule 9, 10, 0.000247, h2o +composition rate: h2o rule 10, 11, 9.559999999999999e-05, h2o +composition rate: h2o rule 11, 12, 2.9399999999999996e-05, h2o +composition rate: h2o rule 12, 13, 8e-06, h2o +composition rate: h2o rule 13, 14, 4.9999999999999996e-06, h2o +composition rate: h2o rule 14, 15, 3.3999999999999996e-06, h2o +composition rate: h2o rule 15, 16, 3.2999999999999997e-06, h2o +composition rate: h2o rule 16, 17, 3.2e-06, h2o +composition rate: h2o rule 17, 18, 3.15e-06, h2o +composition rate: h2o rule 18, 19, 3.2e-06, h2o +composition rate: h2o rule 19, 20, 3.2999999999999997e-06, h2o +composition rate: h2o rule 20, 21, 3.45e-06, h2o +composition rate: h2o rule 21, 22, 3.6e-06, h2o +composition rate: h2o rule 22, 23, 3.8499999999999996e-06, h2o +composition rate: h2o rule 23, 24, 4e-06, h2o +composition rate: h2o rule 24, 25, 4.2e-06, h2o +composition rate: h2o rule 25, 27.6, 4.45e-06, h2o +composition rate: h2o rule 26, 30, 4.7e-06, h2o +composition rate: h2o rule 27, 32.6, 4.87e-06, h2o +composition rate: h2o rule 28, 35, 4.95e-06, h2o +composition rate: h2o rule 29, 37.5, 4.9999999999999996e-06, h2o +composition rate: h2o rule 30, 40, 5.0999999999999995e-06, h2o +composition rate: h2o rule 31, 42.5, 5.299999999999999e-06, h2o +composition rate: h2o rule 32, 45, 5.45e-06, h2o +composition rate: h2o rule 33, 47.5, 5.5e-06, h2o +composition rate: h2o rule 34, 50, 5.5e-06, h2o +composition rate: h2o rule 35, 55, 5.35e-06, h2o +composition rate: h2o rule 36, 60, 4.9999999999999996e-06, h2o +composition rate: h2o rule 37, 65, 4.4e-06, h2o +composition rate: h2o rule 38, 70, 3.7e-06, h2o +composition rate: h2o rule 39, 75, 2.95e-06, h2o +composition rate: h2o rule 40, 80, 2.1e-06, h2o +composition rate: h2o rule 41, 85, 1.33e-06, h2o +composition rate: h2o rule 42, 90, 8.499999999999999e-07, h2o +composition rate: h2o rule 43, 95, 5.4e-07, h2o +composition rate: h2o rule 44, 100, 4e-07, h2o +composition rate: h2o rule 45, 105, 3.4000000000000003e-07, h2o +composition rate: h2o rule 46, 110, 2.8e-07, h2o +composition rate: h2o rule 47, 115, 2.4e-07, h2o +composition rate: h2o rule 48, 120, 2e-07, h2o + +# ch4 composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: ch4 rule 0, 1, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 1, 2, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 2, 3, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 3, 4, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 4, 5, 1.69e-06, ch4 +composition rate: ch4 rule 5, 6, 1.6699999999999999e-06, ch4 +composition rate: ch4 rule 6, 7, 1.6499999999999999e-06, ch4 +composition rate: ch4 rule 7, 8, 1.6299999999999999e-06, ch4 +composition rate: ch4 rule 8, 9, 1.62e-06, ch4 +composition rate: ch4 rule 9, 10, 1.58e-06, ch4 +composition rate: ch4 rule 10, 11, 1.5399999999999999e-06, ch4 +composition rate: ch4 rule 11, 12, 1.51e-06, ch4 +composition rate: ch4 rule 12, 13, 1.48e-06, ch4 +composition rate: ch4 rule 13, 14, 1.4499999999999999e-06, ch4 +composition rate: ch4 rule 14, 15, 1.42e-06, ch4 +composition rate: ch4 rule 15, 16, 1.3899999999999998e-06, ch4 +composition rate: ch4 rule 16, 17, 1.3600000000000001e-06, ch4 +composition rate: ch4 rule 17, 18, 1.32e-06, ch4 +composition rate: ch4 rule 18, 19, 1.28e-06, ch4 +composition rate: ch4 rule 19, 20, 1.22e-06, ch4 +composition rate: ch4 rule 20, 21, 1.1499999999999998e-06, ch4 +composition rate: ch4 rule 21, 22, 1.07e-06, ch4 +composition rate: ch4 rule 22, 23, 9.729999999999998e-07, ch4 +composition rate: ch4 rule 23, 24, 8.799999999999999e-07, ch4 +composition rate: ch4 rule 24, 25, 7.89e-07, ch4 +composition rate: ch4 rule 25, 27.6, 7.049999999999999e-07, ch4 +composition rate: ch4 rule 26, 30, 6.319999999999999e-07, ch4 +composition rate: ch4 rule 27, 32.6, 5.590000000000001e-07, ch4 +composition rate: ch4 rule 28, 35, 5.009999999999999e-07, ch4 +composition rate: ch4 rule 29, 37.5, 4.45e-07, ch4 +composition rate: ch4 rule 30, 40, 3.92e-07, ch4 +composition rate: ch4 rule 31, 42.5, 3.39e-07, ch4 +composition rate: ch4 rule 32, 45, 2.8699999999999996e-07, ch4 +composition rate: ch4 rule 33, 47.5, 2.38e-07, ch4 +composition rate: ch4 rule 34, 50, 1.94e-07, ch4 +composition rate: ch4 rule 35, 55, 1.57e-07, ch4 +composition rate: ch4 rule 36, 60, 1.5e-07, ch4 +composition rate: ch4 rule 37, 65, 1.5e-07, ch4 +composition rate: ch4 rule 38, 70, 1.5e-07, ch4 +composition rate: ch4 rule 39, 75, 1.5e-07, ch4 +composition rate: ch4 rule 40, 80, 1.5e-07, ch4 +composition rate: ch4 rule 41, 85, 1.5e-07, ch4 +composition rate: ch4 rule 42, 90, 1.4e-07, ch4 +composition rate: ch4 rule 43, 95, 1.3e-07, ch4 +composition rate: ch4 rule 44, 100, 1.2e-07, ch4 +composition rate: ch4 rule 45, 105, 1.0999999999999999e-07, ch4 +composition rate: ch4 rule 46, 110, 9.499999999999999e-08, ch4 +composition rate: ch4 rule 47, 115, 6e-08, ch4 +composition rate: ch4 rule 48, 120, 3e-08, ch4 + +# o3 composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: o3 rule 0, 1, 3.3399999999999995e-08, o3 +composition rate: o3 rule 1, 2, 3.69e-08, o3 +composition rate: o3 rule 2, 3, 4.22e-08, o3 +composition rate: o3 rule 3, 4, 4.8199999999999995e-08, o3 +composition rate: o3 rule 4, 5, 5.5100000000000004e-08, o3 +composition rate: o3 rule 5, 6, 6.41e-08, o3 +composition rate: o3 rule 6, 7, 7.76e-08, o3 +composition rate: o3 rule 7, 8, 9.13e-08, o3 +composition rate: o3 rule 8, 9, 1.11e-07, o3 +composition rate: o3 rule 9, 10, 1.3e-07, o3 +composition rate: o3 rule 10, 11, 1.7899999999999997e-07, o3 +composition rate: o3 rule 11, 12, 2.23e-07, o3 +composition rate: o3 rule 12, 13, 3e-07, o3 +composition rate: o3 rule 13, 14, 4.3999999999999997e-07, o3 +composition rate: o3 rule 14, 15, 5e-07, o3 +composition rate: o3 rule 15, 16, 6e-07, o3 +composition rate: o3 rule 16, 17, 7e-07, o3 +composition rate: o3 rule 17, 18, 1e-06, o3 +composition rate: o3 rule 18, 19, 1.5e-06, o3 +composition rate: o3 rule 19, 20, 2e-06, o3 +composition rate: o3 rule 20, 21, 2.4e-06, o3 +composition rate: o3 rule 21, 22, 2.8999999999999998e-06, o3 +composition rate: o3 rule 22, 23, 3.3999999999999996e-06, o3 +composition rate: o3 rule 23, 24, 4e-06, o3 +composition rate: o3 rule 24, 25, 4.8e-06, o3 +composition rate: o3 rule 25, 27.6, 6e-06, o3 +composition rate: o3 rule 26, 30, 7e-06, o3 +composition rate: o3 rule 27, 32.6, 8.099999999999999e-06, o3 +composition rate: o3 rule 28, 35, 8.9e-06, o3 +composition rate: o3 rule 29, 37.5, 8.7e-06, o3 +composition rate: o3 rule 30, 40, 7.55e-06, o3 +composition rate: o3 rule 31, 42.5, 5.9e-06, o3 +composition rate: o3 rule 32, 45, 4.5e-06, o3 +composition rate: o3 rule 33, 47.5, 3.5e-06, o3 +composition rate: o3 rule 34, 50, 2.8e-06, o3 +composition rate: o3 rule 35, 55, 1.8e-06, o3 +composition rate: o3 rule 36, 60, 1.3e-06, o3 +composition rate: o3 rule 37, 65, 8e-07, o3 +composition rate: o3 rule 38, 70, 4e-07, o3 +composition rate: o3 rule 39, 75, 1.8999999999999998e-07, o3 +composition rate: o3 rule 40, 80, 2e-07, o3 +composition rate: o3 rule 41, 85, 5.699999999999999e-07, o3 +composition rate: o3 rule 42, 90, 7.5e-07, o3 +composition rate: o3 rule 43, 95, 7e-07, o3 +composition rate: o3 rule 44, 100, 4.03e-07, o3 +composition rate: o3 rule 45, 105, 2e-07, o3 +composition rate: o3 rule 46, 110, 5e-08, o3 +composition rate: o3 rule 47, 115, 5e-09, o3 +composition rate: o3 rule 48, 120, 5e-10, o3 + +# n2o composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: n2o rule 0, 1, 3.2e-07, n2o +composition rate: n2o rule 1, 2, 3.2e-07, n2o +composition rate: n2o rule 2, 3, 3.2e-07, n2o +composition rate: n2o rule 3, 4, 3.2e-07, n2o +composition rate: n2o rule 4, 5, 3.2e-07, n2o +composition rate: n2o rule 5, 6, 3.2e-07, n2o +composition rate: n2o rule 6, 7, 3.2e-07, n2o +composition rate: n2o rule 7, 8, 3.2e-07, n2o +composition rate: n2o rule 8, 9, 3.1599999999999997e-07, n2o +composition rate: n2o rule 9, 10, 3.1e-07, n2o +composition rate: n2o rule 10, 11, 2.9899999999999996e-07, n2o +composition rate: n2o rule 11, 12, 2.9399999999999996e-07, n2o +composition rate: n2o rule 12, 13, 2.8599999999999994e-07, n2o +composition rate: n2o rule 13, 14, 2.8e-07, n2o +composition rate: n2o rule 14, 15, 2.72e-07, n2o +composition rate: n2o rule 15, 16, 2.61e-07, n2o +composition rate: n2o rule 16, 17, 2.4199999999999997e-07, n2o +composition rate: n2o rule 17, 18, 2.17e-07, n2o +composition rate: n2o rule 18, 19, 1.8399999999999998e-07, n2o +composition rate: n2o rule 19, 20, 1.61e-07, n2o +composition rate: n2o rule 20, 21, 1.32e-07, n2o +composition rate: n2o rule 21, 22, 1.15e-07, n2o +composition rate: n2o rule 22, 23, 1.0399999999999999e-07, n2o +composition rate: n2o rule 23, 24, 9.619999999999999e-08, n2o +composition rate: n2o rule 24, 25, 8.96e-08, n2o +composition rate: n2o rule 25, 27.6, 8.01e-08, n2o +composition rate: n2o rule 26, 30, 6.7e-08, n2o +composition rate: n2o rule 27, 32.6, 4.95e-08, n2o +composition rate: n2o rule 28, 35, 3.6999999999999994e-08, n2o +composition rate: n2o rule 29, 37.5, 2.52e-08, n2o +composition rate: n2o rule 30, 40, 1.7399999999999997e-08, n2o +composition rate: n2o rule 31, 42.5, 1.1599999999999998e-08, n2o +composition rate: n2o rule 32, 45, 7.67e-09, n2o +composition rate: n2o rule 33, 47.5, 5.32e-09, n2o +composition rate: n2o rule 34, 50, 3.22e-36, n2o +composition rate: n2o rule 35, 55, 2.0300000000000002e-09, n2o +composition rate: n2o rule 36, 60, 1.4e-09, n2o +composition rate: n2o rule 37, 65, 1.02e-09, n2o +composition rate: n2o rule 38, 70, 7.77e-10, n2o +composition rate: n2o rule 39, 75, 6.26e-10, n2o +composition rate: n2o rule 40, 80, 5.17e-10, n2o +composition rate: n2o rule 41, 85, 4.35e-10, n2o +composition rate: n2o rule 42, 90, 3.73e-10, n2o +composition rate: n2o rule 43, 95, 3.24e-10, n2o +composition rate: n2o rule 44, 100, 2.84e-10, n2o +composition rate: n2o rule 45, 105, 2.52e-10, n2o +composition rate: n2o rule 46, 110, 2.2599999999999997e-10, n2o +composition rate: n2o rule 47, 115, 2.04e-10, n2o +composition rate: n2o rule 48, 120, 1.8499999999999998e-10, n2o + +# co composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: co rule 0, 1, 1.45e-07, co +composition rate: co rule 1, 2, 1.4e-07, co +composition rate: co rule 2, 3, 1.35e-07, co +composition rate: co rule 3, 4, 1.31e-07, co +composition rate: co rule 4, 5, 1.3e-07, co +composition rate: co rule 5, 6, 1.29e-07, co +composition rate: co rule 6, 7, 1.26e-07, co +composition rate: co rule 7, 8, 1.2e-07, co +composition rate: co rule 8, 9, 1.09e-07, co +composition rate: co rule 9, 10, 9.959999999999999e-08, co +composition rate: co rule 10, 11, 8.96e-08, co +composition rate: co rule 11, 12, 7.81e-08, co +composition rate: co rule 12, 13, 6.370000000000001e-08, co +composition rate: co rule 13, 14, 5.0299999999999994e-08, co +composition rate: co rule 14, 15, 3.9399999999999995e-08, co +composition rate: co rule 15, 16, 3.07e-08, co +composition rate: co rule 16, 17, 2.4899999999999998e-08, co +composition rate: co rule 17, 18, 1.9699999999999998e-08, co +composition rate: co rule 18, 19, 1.66e-08, co +composition rate: co rule 19, 20, 1.3299999999999998e-08, co +composition rate: co rule 20, 21, 1.23e-08, co +composition rate: co rule 21, 22, 1.23e-08, co +composition rate: co rule 22, 23, 1.31e-08, co +composition rate: co rule 23, 24, 1.4e-08, co +composition rate: co rule 24, 25, 1.52e-08, co +composition rate: co rule 25, 27.6, 1.72e-08, co +composition rate: co rule 26, 30, 2e-08, co +composition rate: co rule 27, 32.6, 2.27e-08, co +composition rate: co rule 28, 35, 2.4899999999999998e-08, co +composition rate: co rule 29, 37.5, 2.72e-08, co +composition rate: co rule 30, 40, 2.96e-08, co +composition rate: co rule 31, 42.5, 3.1399999999999997e-08, co +composition rate: co rule 32, 45, 3.31e-08, co +composition rate: co rule 33, 47.5, 3.49e-08, co +composition rate: co rule 34, 50, 3.6499999999999996e-08, co +composition rate: co rule 35, 55, 3.9199999999999994e-08, co +composition rate: co rule 36, 60, 4.6699999999999995e-08, co +composition rate: co rule 37, 65, 6.4e-08, co +composition rate: co rule 38, 70, 1.1799999999999998e-07, co +composition rate: co rule 39, 75, 2.9399999999999996e-07, co +composition rate: co rule 40, 80, 6.82e-07, co +composition rate: co rule 41, 85, 1.47e-06, co +composition rate: co rule 42, 90, 2.85e-06, co +composition rate: co rule 43, 95, 5.17e-06, co +composition rate: co rule 44, 100, 1.01e-05, co +composition rate: co rule 45, 105, 1.8699999999999997e-05, co +composition rate: co rule 46, 110, 2.86e-05, co +composition rate: co rule 47, 115, 3.89e-05, co +composition rate: co rule 48, 120, 4.9999999999999996e-05, co diff --git a/midlatitude winter.pyr b/midlatitude winter.pyr new file mode 100644 index 0000000..bcb065c --- /dev/null +++ b/midlatitude winter.pyr @@ -0,0 +1,329 @@ +# atm profile for midlatitude winter + +# surface values (pressure, temperature, final height, initial layer thickness, acceleration of gravity, range min, range max) +surface: 1020.0, 272.2, 120, 100, 9.8, 100, 2500 + +# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile +# except for co2, o2, n2, and ar +molecule: co2, .000287 +molecule: h2o, 0.00432 +molecule: o2, .20 +molecule: n2, .77 +molecule: ar, .009 +molecule: ch4, 1.6999999999999998e-06 +molecule: o3, 2.7799999999999997e-08 +molecule: n2o, 3.2e-07 +molecule: co, 1.5e-07 + +# lapse rate profile +# rules are: name, final height, final value +# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule) +lapse rate: lapse rule 0, 1, 268.7 +lapse rate: lapse rule 1, 2, 265.2 +lapse rate: lapse rule 2, 3, 261.7 +lapse rate: lapse rule 3, 4, 255.7 +lapse rate: lapse rule 4, 5, 249.7 +lapse rate: lapse rule 5, 6, 243.7 +lapse rate: lapse rule 6, 7, 237.7 +lapse rate: lapse rule 7, 8, 231.7 +lapse rate: lapse rule 8, 9, 225.7 +lapse rate: lapse rule 9, 10, 219.7 +lapse rate: lapse rule 10, 11, 219.2 +lapse rate: lapse rule 11, 12, 218.7 +lapse rate: lapse rule 12, 13, 218.2 +lapse rate: lapse rule 13, 14, 217.7 +lapse rate: lapse rule 14, 15, 217.2 +lapse rate: lapse rule 15, 16, 216.7 +lapse rate: lapse rule 16, 17, 216.2 +lapse rate: lapse rule 17, 18, 215.7 +lapse rate: lapse rule 18, 19, 215.2 +lapse rate: lapse rule 19, 20, 215.2 +lapse rate: lapse rule 20, 21, 215.2 +lapse rate: lapse rule 21, 22, 215.2 +lapse rate: lapse rule 22, 23, 215.2 +lapse rate: lapse rule 23, 24, 215.2 +lapse rate: lapse rule 24, 25, 215.2 +lapse rate: lapse rule 25, 27.6, 215.5 +lapse rate: lapse rule 26, 30, 217.4 +lapse rate: lapse rule 27, 32.6, 220.4 +lapse rate: lapse rule 28, 35, 227.9 +lapse rate: lapse rule 29, 37.5, 235.5 +lapse rate: lapse rule 30, 40, 243.2 +lapse rate: lapse rule 31, 42.5, 250.8 +lapse rate: lapse rule 32, 45, 258.5 +lapse rate: lapse rule 33, 47.5, 265.1 +lapse rate: lapse rule 34, 50, 265.7 +lapse rate: lapse rule 35, 55, 260.6 +lapse rate: lapse rule 36, 60, 250.8 +lapse rate: lapse rule 37, 65, 240.9 +lapse rate: lapse rule 38, 70, 230.7 +lapse rate: lapse rule 39, 75, 220.4 +lapse rate: lapse rule 40, 80, 210.1 +lapse rate: lapse rule 41, 85, 199.8 +lapse rate: lapse rule 42, 90, 199.5 +lapse rate: lapse rule 43, 95, 208.3 +lapse rate: lapse rule 44, 100, 218.6 +lapse rate: lapse rule 45, 105, 237.1 +lapse rate: lapse rule 46, 110, 259.5 +lapse rate: lapse rule 47, 115, 293 +lapse rate: lapse rule 48, 120, 333 + +# h2o composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: h2o rule 0, 1, 0.00346, h2o +composition rate: h2o rule 1, 2, 0.00279, h2o +composition rate: h2o rule 2, 3, 0.00209, h2o +composition rate: h2o rule 3, 4, 0.0012799999999999999, h2o +composition rate: h2o rule 4, 5, 0.000824, h2o +composition rate: h2o rule 5, 6, 0.0005099999999999999, h2o +composition rate: h2o rule 6, 7, 0.000232, h2o +composition rate: h2o rule 7, 8, 0.000108, h2o +composition rate: h2o rule 8, 9, 5.57e-05, h2o +composition rate: h2o rule 9, 10, 2.96e-05, h2o +composition rate: h2o rule 10, 11, 9.999999999999999e-06, h2o +composition rate: h2o rule 11, 12, 6e-06, h2o +composition rate: h2o rule 12, 13, 4.9999999999999996e-06, h2o +composition rate: h2o rule 13, 14, 4.8e-06, h2o +composition rate: h2o rule 14, 15, 4.7e-06, h2o +composition rate: h2o rule 15, 16, 4.5e-06, h2o +composition rate: h2o rule 16, 17, 4.5e-06, h2o +composition rate: h2o rule 17, 18, 4.5e-06, h2o +composition rate: h2o rule 18, 19, 4.5e-06, h2o +composition rate: h2o rule 19, 20, 4.5e-06, h2o +composition rate: h2o rule 20, 21, 4.5e-06, h2o +composition rate: h2o rule 21, 22, 4.53e-06, h2o +composition rate: h2o rule 22, 23, 4.55e-06, h2o +composition rate: h2o rule 23, 24, 4.599999999999999e-06, h2o +composition rate: h2o rule 24, 25, 4.65e-06, h2o +composition rate: h2o rule 25, 27.6, 4.7e-06, h2o +composition rate: h2o rule 26, 30, 4.749999999999999e-06, h2o +composition rate: h2o rule 27, 32.6, 4.8e-06, h2o +composition rate: h2o rule 28, 35, 4.849999999999999e-06, h2o +composition rate: h2o rule 29, 37.5, 4.9000000000000005e-06, h2o +composition rate: h2o rule 30, 40, 4.95e-06, h2o +composition rate: h2o rule 31, 42.5, 4.9999999999999996e-06, h2o +composition rate: h2o rule 32, 45, 4.9999999999999996e-06, h2o +composition rate: h2o rule 33, 47.5, 4.9999999999999996e-06, h2o +composition rate: h2o rule 34, 50, 4.95e-06, h2o +composition rate: h2o rule 35, 55, 4.849999999999999e-06, h2o +composition rate: h2o rule 36, 60, 4.5e-06, h2o +composition rate: h2o rule 37, 65, 4e-06, h2o +composition rate: h2o rule 38, 70, 3.2999999999999997e-06, h2o +composition rate: h2o rule 39, 75, 2.7e-06, h2o +composition rate: h2o rule 40, 80, 2e-06, h2o +composition rate: h2o rule 41, 85, 1.33e-06, h2o +composition rate: h2o rule 42, 90, 8.499999999999999e-07, h2o +composition rate: h2o rule 43, 95, 5.4e-07, h2o +composition rate: h2o rule 44, 100, 4e-07, h2o +composition rate: h2o rule 45, 105, 3.4000000000000003e-07, h2o +composition rate: h2o rule 46, 110, 2.8e-07, h2o +composition rate: h2o rule 47, 115, 2.4e-07, h2o +composition rate: h2o rule 48, 120, 2e-07, h2o + +# ch4 composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: ch4 rule 0, 1, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 1, 2, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 2, 3, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 3, 4, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 4, 5, 1.69e-06, ch4 +composition rate: ch4 rule 5, 6, 1.6699999999999999e-06, ch4 +composition rate: ch4 rule 6, 7, 1.6499999999999999e-06, ch4 +composition rate: ch4 rule 7, 8, 1.6299999999999999e-06, ch4 +composition rate: ch4 rule 8, 9, 1.62e-06, ch4 +composition rate: ch4 rule 9, 10, 1.58e-06, ch4 +composition rate: ch4 rule 10, 11, 1.5399999999999999e-06, ch4 +composition rate: ch4 rule 11, 12, 1.51e-06, ch4 +composition rate: ch4 rule 12, 13, 1.48e-06, ch4 +composition rate: ch4 rule 13, 14, 1.4499999999999999e-06, ch4 +composition rate: ch4 rule 14, 15, 1.42e-06, ch4 +composition rate: ch4 rule 15, 16, 1.3899999999999998e-06, ch4 +composition rate: ch4 rule 16, 17, 1.3600000000000001e-06, ch4 +composition rate: ch4 rule 17, 18, 1.62e-06, ch4 +composition rate: ch4 rule 18, 19, 1.28e-06, ch4 +composition rate: ch4 rule 19, 20, 1.22e-06, ch4 +composition rate: ch4 rule 20, 21, 1.1499999999999998e-06, ch4 +composition rate: ch4 rule 21, 22, 1.07e-06, ch4 +composition rate: ch4 rule 22, 23, 9.729999999999998e-07, ch4 +composition rate: ch4 rule 23, 24, 8.799999999999999e-07, ch4 +composition rate: ch4 rule 24, 25, 7.93e-07, ch4 +composition rate: ch4 rule 25, 27.6, 7.129999999999999e-07, ch4 +composition rate: ch4 rule 26, 30, 6.44e-07, ch4 +composition rate: ch4 rule 27, 32.6, 5.749999999999999e-07, ch4 +composition rate: ch4 rule 28, 35, 5.049999999999999e-07, ch4 +composition rate: ch4 rule 29, 37.5, 4.48e-07, ch4 +composition rate: ch4 rule 30, 40, 3.93e-07, ch4 +composition rate: ch4 rule 31, 42.5, 3.41e-06, ch4 +composition rate: ch4 rule 32, 45, 2.88e-07, ch4 +composition rate: ch4 rule 33, 47.5, 2.3899999999999996e-07, ch4 +composition rate: ch4 rule 34, 50, 1.94e-07, ch4 +composition rate: ch4 rule 35, 55, 1.57e-07, ch4 +composition rate: ch4 rule 36, 60, 1.5e-07, ch4 +composition rate: ch4 rule 37, 65, 1.5e-07, ch4 +composition rate: ch4 rule 38, 70, 1.5e-07, ch4 +composition rate: ch4 rule 39, 75, 1.5e-07, ch4 +composition rate: ch4 rule 40, 80, 1.5e-07, ch4 +composition rate: ch4 rule 41, 85, 1.5e-07, ch4 +composition rate: ch4 rule 42, 90, 1.4e-07, ch4 +composition rate: ch4 rule 43, 95, 1.3e-07, ch4 +composition rate: ch4 rule 44, 100, 1.2e-07, ch4 +composition rate: ch4 rule 45, 105, 1.0999999999999999e-07, ch4 +composition rate: ch4 rule 46, 110, 9.499999999999999e-08, ch4 +composition rate: ch4 rule 47, 115, 6e-08, ch4 +composition rate: ch4 rule 48, 120, 3e-08, ch4 + +# o3 composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: o3 rule 0, 1, 2.8e-08, o3 +composition rate: o3 rule 1, 2, 2.85e-08, o3 +composition rate: o3 rule 2, 3, 3.2e-08, o3 +composition rate: o3 rule 3, 4, 3.57e-08, o3 +composition rate: o3 rule 4, 5, 4.72e-08, o3 +composition rate: o3 rule 5, 6, 5.84e-08, o3 +composition rate: o3 rule 6, 7, 7.89e-08, o3 +composition rate: o3 rule 7, 8, 1.0399999999999999e-07, o3 +composition rate: o3 rule 8, 9, 1.57e-07, o3 +composition rate: o3 rule 9, 10, 2.3699999999999996e-07, o3 +composition rate: o3 rule 10, 11, 3.62e-07, o3 +composition rate: o3 rule 11, 12, 5.23e-07, o3 +composition rate: o3 rule 12, 13, 7.04e-07, o3 +composition rate: o3 rule 13, 14, 8e-07, o3 +composition rate: o3 rule 14, 15, 9e-07, o3 +composition rate: o3 rule 15, 16, 1.1e-06, o3 +composition rate: o3 rule 16, 17, 1.4e-06, o3 +composition rate: o3 rule 17, 18, 1.8e-06, o3 +composition rate: o3 rule 18, 19, 2.2999999999999996e-06, o3 +composition rate: o3 rule 19, 20, 2.8999999999999998e-06, o3 +composition rate: o3 rule 20, 21, 3.5e-06, o3 +composition rate: o3 rule 21, 22, 3.9e-06, o3 +composition rate: o3 rule 22, 23, 4.2999999999999995e-06, o3 +composition rate: o3 rule 23, 24, 4.7e-06, o3 +composition rate: o3 rule 24, 25, 5.0999999999999995e-06, o3 +composition rate: o3 rule 25, 27.6, 5.6e-06, o3 +composition rate: o3 rule 26, 30, 6.099999999999999e-06, o3 +composition rate: o3 rule 27, 32.6, 6.799999999999999e-06, o3 +composition rate: o3 rule 28, 35, 7.099999999999999e-06, o3 +composition rate: o3 rule 29, 37.5, 7.2e-06, o3 +composition rate: o3 rule 30, 40, 6.9e-06, o3 +composition rate: o3 rule 31, 42.5, 5.9e-06, o3 +composition rate: o3 rule 32, 45, 4.599999999999999e-06, o3 +composition rate: o3 rule 33, 47.5, 3.7e-06, o3 +composition rate: o3 rule 34, 50, 2.75e-06, o3 +composition rate: o3 rule 35, 55, 1.6999999999999998e-06, o3 +composition rate: o3 rule 36, 60, 1e-06, o3 +composition rate: o3 rule 37, 65, 5.5e-07, o3 +composition rate: o3 rule 38, 70, 3.2e-07, o3 +composition rate: o3 rule 39, 75, 2.5e-07, o3 +composition rate: o3 rule 40, 80, 2.3e-07, o3 +composition rate: o3 rule 41, 85, 5.5e-07, o3 +composition rate: o3 rule 42, 90, 8e-07, o3 +composition rate: o3 rule 43, 95, 8e-07, o3 +composition rate: o3 rule 44, 100, 4e-07, o3 +composition rate: o3 rule 45, 105, 2e-07, o3 +composition rate: o3 rule 46, 110, 5.01e-08, o3 +composition rate: o3 rule 47, 115, 5e-09, o3 +composition rate: o3 rule 48, 120, 5e-10, o3 + +# n2o composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: n2o rule 0, 1, 3.2e-07, n2o +composition rate: n2o rule 1, 2, 3.2e-07, n2o +composition rate: n2o rule 2, 3, 3.2e-07, n2o +composition rate: n2o rule 3, 4, 3.2e-07, n2o +composition rate: n2o rule 4, 5, 3.2e-07, n2o +composition rate: n2o rule 5, 6, 3.2e-07, n2o +composition rate: n2o rule 6, 7, 3.2e-07, n2o +composition rate: n2o rule 7, 8, 3.2e-07, n2o +composition rate: n2o rule 8, 9, 3.1599999999999997e-07, n2o +composition rate: n2o rule 9, 10, 3.1e-07, n2o +composition rate: n2o rule 10, 11, 2.9899999999999996e-07, n2o +composition rate: n2o rule 11, 12, 2.9399999999999996e-07, n2o +composition rate: n2o rule 12, 13, 2.8599999999999994e-07, n2o +composition rate: n2o rule 13, 14, 2.8e-07, n2o +composition rate: n2o rule 14, 15, 2.72e-07, n2o +composition rate: n2o rule 15, 16, 2.61e-07, n2o +composition rate: n2o rule 16, 17, 2.4199999999999997e-07, n2o +composition rate: n2o rule 17, 18, 2.17e-07, n2o +composition rate: n2o rule 18, 19, 1.8399999999999998e-07, n2o +composition rate: n2o rule 19, 20, 1.62e-07, n2o +composition rate: n2o rule 20, 21, 1.36e-07, n2o +composition rate: n2o rule 21, 22, 1.23e-07, n2o +composition rate: n2o rule 22, 23, 1.12e-07, n2o +composition rate: n2o rule 23, 24, 1.0499999999999999e-07, n2o +composition rate: n2o rule 24, 25, 9.66e-08, n2o +composition rate: n2o rule 25, 27.6, 8.69e-08, n2o +composition rate: n2o rule 26, 30, 7.52e-08, n2o +composition rate: n2o rule 27, 32.6, 6.13e-08, n2o +composition rate: n2o rule 28, 35, 5.12e-08, n2o +composition rate: n2o rule 29, 37.5, 3.97e-08, n2o +composition rate: n2o rule 30, 40, 3e-08, n2o +composition rate: n2o rule 31, 42.5, 2.0799999999999998e-08, n2o +composition rate: n2o rule 32, 45, 1.31e-08, n2o +composition rate: n2o rule 33, 47.5, 8.07e-09, n2o +composition rate: n2o rule 34, 50, 4.16e-09, n2o +composition rate: n2o rule 35, 55, 2.63e-09, n2o +composition rate: n2o rule 36, 60, 1.81e-09, n2o +composition rate: n2o rule 37, 65, 1.32e-09, n2o +composition rate: n2o rule 38, 70, 1.01e-09, n2o +composition rate: n2o rule 39, 75, 7.88e-10, n2o +composition rate: n2o rule 40, 80, 6.33e-10, n2o +composition rate: n2o rule 41, 85, 5.19e-10, n2o +composition rate: n2o rule 42, 90, 4.33e-10, n2o +composition rate: n2o rule 43, 95, 3.6699999999999997e-10, n2o +composition rate: n2o rule 44, 100, 3.1399999999999995e-10, n2o +composition rate: n2o rule 45, 105, 2.72e-10, n2o +composition rate: n2o rule 46, 110, 2.3699999999999996e-10, n2o +composition rate: n2o rule 47, 115, 2.09e-10, n2o +composition rate: n2o rule 48, 120, 1.8499999999999998e-10, n2o + +# co composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: co rule 0, 1, 1.45e-07, co +composition rate: co rule 1, 2, 1.4e-07, co +composition rate: co rule 2, 3, 1.35e-07, co +composition rate: co rule 3, 4, 1.31e-07, co +composition rate: co rule 4, 5, 1.3e-07, co +composition rate: co rule 5, 6, 1.29e-07, co +composition rate: co rule 6, 7, 1.25e-07, co +composition rate: co rule 7, 8, 1.19e-07, co +composition rate: co rule 8, 9, 1.09e-07, co +composition rate: co rule 9, 10, 9.959999999999999e-08, co +composition rate: co rule 10, 11, 8.96e-08, co +composition rate: co rule 11, 12, 7.81e-08, co +composition rate: co rule 12, 13, 6.370000000000001e-08, co +composition rate: co rule 13, 14, 5.0299999999999994e-08, co +composition rate: co rule 14, 15, 3.9399999999999995e-08, co +composition rate: co rule 15, 16, 3.07e-08, co +composition rate: co rule 16, 17, 2.4899999999999998e-08, co +composition rate: co rule 17, 18, 1.9699999999999998e-08, co +composition rate: co rule 18, 19, 1.55e-08, co +composition rate: co rule 19, 20, 1.3299999999999998e-08, co +composition rate: co rule 20, 21, 1.23e-08, co +composition rate: co rule 21, 22, 1.23e-08, co +composition rate: co rule 22, 23, 1.31e-08, co +composition rate: co rule 23, 24, 1.4e-08, co +composition rate: co rule 24, 25, 1.5e-08, co +composition rate: co rule 25, 27.6, 1.6e-08, co +composition rate: co rule 26, 30, 1.71e-08, co +composition rate: co rule 27, 32.6, 1.8499999999999997e-08, co +composition rate: co rule 28, 35, 2e-08, co +composition rate: co rule 29, 37.5, 2.1499999999999997e-08, co +composition rate: co rule 30, 40, 2.33e-08, co +composition rate: co rule 31, 42.5, 2.63e-08, co +composition rate: co rule 32, 45, 3.0599999999999996e-08, co +composition rate: co rule 33, 47.5, 3.7999999999999996e-08, co +composition rate: co rule 34, 50, 6.25e-08, co +composition rate: co rule 35, 55, 1.4799999999999998e-07, co +composition rate: co rule 36, 60, 2.93e-07, co +composition rate: co rule 37, 65, 5.590000000000001e-07, co +composition rate: co rule 38, 70, 1.08e-06, co +composition rate: co rule 39, 75, 1.8999999999999998e-06, co +composition rate: co rule 40, 80, 2.96e-06, co +composition rate: co rule 41, 85, 4.53e-06, co +composition rate: co rule 42, 90, 6.86e-06, co +composition rate: co rule 43, 95, 1.05e-05, co +composition rate: co rule 44, 100, 1.7100000000000002e-05, co +composition rate: co rule 45, 105, 2.4699999999999997e-05, co +composition rate: co rule 46, 110, 3.36e-05, co +composition rate: co rule 47, 115, 4.15e-05, co +composition rate: co rule 48, 120, 0.0005, co diff --git a/mls summer 286.pyr b/mls summer 286.pyr deleted file mode 100644 index 145d7ef..0000000 --- a/mls summer 286.pyr +++ /dev/null @@ -1,76 +0,0 @@ -# mid latitude summer from Anderson 1986 - -surface: 1013.25, 294, 120, 100, 9.8 - -molecule: co2, .000287 -molecule: h2o, .018800 -molecule: o3, .00000003 -molecule: n2o, .000000320 -molecule: co, .000000150 -molecule: ch4, .00000170 -molecule: o2, .20 -molecule: n2, .77 -molecule: ar, .009 - -lapse rate: boundary layer troposphere, 2, 285 -lapse rate: troposphere, 13, 216 -lapse rate: tropopause, 17, 215 -lapse rate: lower stratosphere, 27, 228 -lapse rate: stratosphere, 47.5, 275 -lapse rate: stratopause, 50, 276 -lapse rate: lower mesosphere, 55, 269 -lapse rate: mesosphere, 80, 174 -lapse rate: upper mesosphere, 85, 165 -lapse rate: mesopause, 90, 165 -lapse rate: thermosphere, 100, 190 -lapse rate: upper thermosphere, 120, 380 - -composition rate: WV boundary layer, 3, .005691, h2o -composition rate: WV troposphere, 5, .002266, h2o -composition rate: WV trop2, 6, .0015, h2o -composition rate: wv trop 3, 8, .000647, h2o -composition rate: wv tropopause, 11, .000099, h2o -composition rate: wv tropopause2, 12, .000030, h2o -composition rate: wv tropopause3, 13, .0000054, h2o -composition rate: wv stratosphere, 18, .000003, h2o -composition rate: wv strat2, 25, .0000045, h2o -composition rate: wv strat3, 50, .0000055, h2o -composition rate: wv strat3, 60, .000005, h2o -composition rate: wv meso, 90, .00000085, h2o -composition rate: wv thermo, 120, .0000002, h2o - -composition rate: ozone troposphere, 10, .00000013, o3 -composition rate: ozone tropopause, 17, .0000007, o3 -composition rate: ozone strat1, 35, .0000089, o3 -composition rate: ozone meso, 37, .0000087, o3 -composition rate: ozone meso2, 55, .0000017, o3 -composition rate: ozone meso3, 75, .00000018, o3 -composition rate: ozone meso4, 80, .00000018, o3 -composition rate: ozone meso5, 90, .00000076, o3 -composition rate: ozone thermo, 120, 0, o3 - -composition rate: n2o 1, 8, .00000032, n2o -composition rate: n2o 2, 16, .00000026, n2o -composition rate: n2o 3, 20, .00000013, n2o -composition rate: n2o 4, 25, .00000009, n2o -composition rate: n2o 5, 45, .000000008, n2o -composition rate: n2o 6, 120, 0, n2o - -composition rate: co 1, 4, .00000013, co -composition rate: co 2, 6, .000000128, co -composition rate: co 3, 15, .000000038, co -composition rate: co 4, 20, .00000012, co -composition rate: co 5, 60, .00000012, co -composition rate: co 6, 90, .0000029, co -composition rate: co 7, 120, .000050, co - -composition rate: ch4 1, 4, .00000017, ch4 -composition rate: ch4 2, 9, .000000162, ch4 -composition rate: ch4 3, 4, .00000017, ch4 -composition rate: ch4 4, 19, .0000018, ch4 -composition rate: ch4 5, 25, .00000078, ch4 -composition rate: ch4 6, 55, .00000015, ch4 -composition rate: ch4 7, 85, .00000015, ch4 -composition rate: ch4 8, 120,.00000003, ch4 - - diff --git a/mls summer 369.pyr b/mls summer 369.pyr deleted file mode 100644 index 6ef3a26..0000000 --- a/mls summer 369.pyr +++ /dev/null @@ -1,76 +0,0 @@ -# mid latitude summer from Anderson 1986 - -surface: 1013.25, 294, 120, 100, 9.8 - -molecule: co2, .000369 -molecule: h2o, .018800 -molecule: o3, .00000003 -molecule: n2o, .000000320 -molecule: co, .000000150 -molecule: ch4, .00000170 -molecule: o2, .20 -molecule: n2, .77 -molecule: ar, .009 - -lapse rate: boundary layer troposphere, 2, 285 -lapse rate: troposphere, 13, 216 -lapse rate: tropopause, 17, 215 -lapse rate: lower stratosphere, 27, 228 -lapse rate: stratosphere, 47.5, 275 -lapse rate: stratopause, 50, 276 -lapse rate: lower mesosphere, 55, 269 -lapse rate: mesosphere, 80, 174 -lapse rate: upper mesosphere, 85, 165 -lapse rate: mesopause, 90, 165 -lapse rate: thermosphere, 100, 190 -lapse rate: upper thermosphere, 120, 380 - -composition rate: WV boundary layer, 3, .005691, h2o -composition rate: WV troposphere, 5, .002266, h2o -composition rate: WV trop2, 6, .0015, h2o -composition rate: wv trop 3, 8, .000647, h2o -composition rate: wv tropopause, 11, .000099, h2o -composition rate: wv tropopause2, 12, .000030, h2o -composition rate: wv tropopause3, 13, .0000054, h2o -composition rate: wv stratosphere, 18, .000003, h2o -composition rate: wv strat2, 25, .0000045, h2o -composition rate: wv strat3, 50, .0000055, h2o -composition rate: wv strat3, 60, .000005, h2o -composition rate: wv meso, 90, .00000085, h2o -composition rate: wv thermo, 120, .0000002, h2o - -composition rate: ozone troposphere, 10, .00000013, o3 -composition rate: ozone tropopause, 17, .0000007, o3 -composition rate: ozone strat1, 35, .0000089, o3 -composition rate: ozone meso, 37, .0000087, o3 -composition rate: ozone meso2, 55, .0000017, o3 -composition rate: ozone meso3, 75, .00000018, o3 -composition rate: ozone meso4, 80, .00000018, o3 -composition rate: ozone meso5, 90, .00000076, o3 -composition rate: ozone thermo, 120, 0, o3 - -composition rate: n2o 1, 8, .00000032, n2o -composition rate: n2o 2, 16, .00000026, n2o -composition rate: n2o 3, 20, .00000013, n2o -composition rate: n2o 4, 25, .00000009, n2o -composition rate: n2o 5, 45, .000000008, n2o -composition rate: n2o 6, 120, 0, n2o - -composition rate: co 1, 4, .00000013, co -composition rate: co 2, 6, .000000128, co -composition rate: co 3, 15, .000000038, co -composition rate: co 4, 20, .00000012, co -composition rate: co 5, 60, .00000012, co -composition rate: co 6, 90, .0000029, co -composition rate: co 7, 120, .000050, co - -composition rate: ch4 1, 4, .00000017, ch4 -composition rate: ch4 2, 9, .000000162, ch4 -composition rate: ch4 3, 4, .00000017, ch4 -composition rate: ch4 4, 19, .0000018, ch4 -composition rate: ch4 5, 25, .00000078, ch4 -composition rate: ch4 6, 55, .00000015, ch4 -composition rate: ch4 7, 85, .00000015, ch4 -composition rate: ch4 8, 120,.00000003, ch4 - - diff --git a/mls summer.pyr b/mls summer.pyr deleted file mode 100644 index 391e170..0000000 --- a/mls summer.pyr +++ /dev/null @@ -1,76 +0,0 @@ -# mid latitude summer from Anderson 1986 - -surface: 1013.25, 294, 120, 100, 9.8 - -molecule: co2, .00033 -molecule: h2o, .018800 -molecule: o3, .00000003 -molecule: n2o, .000000320 -molecule: co, .000000150 -molecule: ch4, .00000170 -molecule: o2, .20 -molecule: n2, .77 -molecule: ar, .009 - -lapse rate: boundary layer troposphere, 2, 285 -lapse rate: troposphere, 13, 216 -lapse rate: tropopause, 17, 215 -lapse rate: lower stratosphere, 27, 228 -lapse rate: stratosphere, 47.5, 275 -lapse rate: stratopause, 50, 276 -lapse rate: lower mesosphere, 55, 269 -lapse rate: mesosphere, 80, 174 -lapse rate: upper mesosphere, 85, 165 -lapse rate: mesopause, 90, 165 -lapse rate: thermosphere, 100, 190 -lapse rate: upper thermosphere, 120, 380 - -composition rate: WV boundary layer, 3, .005691, h2o -composition rate: WV troposphere, 5, .002266, h2o -composition rate: WV trop2, 6, .0015, h2o -composition rate: wv trop 3, 8, .000647, h2o -composition rate: wv tropopause, 11, .000099, h2o -composition rate: wv tropopause2, 12, .000030, h2o -composition rate: wv tropopause3, 13, .0000054, h2o -composition rate: wv stratosphere, 18, .000003, h2o -composition rate: wv strat2, 25, .0000045, h2o -composition rate: wv strat3, 50, .0000055, h2o -composition rate: wv strat3, 60, .000005, h2o -composition rate: wv meso, 90, .00000085, h2o -composition rate: wv thermo, 120, .0000002, h2o - -composition rate: ozone troposphere, 10, .00000013, o3 -composition rate: ozone tropopause, 17, .0000007, o3 -composition rate: ozone strat1, 35, .0000089, o3 -composition rate: ozone meso, 37, .0000087, o3 -composition rate: ozone meso2, 55, .0000017, o3 -composition rate: ozone meso3, 75, .00000018, o3 -composition rate: ozone meso4, 80, .00000018, o3 -composition rate: ozone meso5, 90, .00000076, o3 -composition rate: ozone thermo, 120, 0, o3 - -composition rate: n2o 1, 8, .00000032, n2o -composition rate: n2o 2, 16, .00000026, n2o -composition rate: n2o 3, 20, .00000013, n2o -composition rate: n2o 4, 25, .00000009, n2o -composition rate: n2o 5, 45, .000000008, n2o -composition rate: n2o 6, 120, 0, n2o - -composition rate: co 1, 4, .00000013, co -composition rate: co 2, 6, .000000128, co -composition rate: co 3, 15, .000000038, co -composition rate: co 4, 20, .00000012, co -composition rate: co 5, 60, .00000012, co -composition rate: co 6, 90, .0000029, co -composition rate: co 7, 120, .000050, co - -composition rate: ch4 1, 4, .00000017, ch4 -composition rate: ch4 2, 9, .000000162, ch4 -composition rate: ch4 3, 4, .00000017, ch4 -composition rate: ch4 4, 19, .0000018, ch4 -composition rate: ch4 5, 25, .00000078, ch4 -composition rate: ch4 6, 55, .00000015, ch4 -composition rate: ch4 7, 85, .00000015, ch4 -composition rate: ch4 8, 120,.00000003, ch4 - - diff --git a/pyradClasses.py b/pyradClasses.py index f4a81fe..1b26a6e 100644 --- a/pyradClasses.py +++ b/pyradClasses.py @@ -111,7 +111,7 @@ def readTransmissionFromFile(requestedHeight, folderPath, direction): def processTransmissionBySingleLayer(folderPath, res=1): values = utils.readCompleteProfile(folderPath) - planet = Planet(values['name'], float(values['surfacePressure']), int(values['surfaceTemperature']), + planet = Planet(values['name'], float(values['surfacePressure']), int(float(values['surfaceTemperature'])), float(values['maxHeight']), rangeMin=int(values['rangeMin']), rangeMax=int(values['rangeMax']), initialThickness=int(float(values['initialDepth'])), diff --git a/pyradUtilities.py b/pyradUtilities.py index d069a63..dcea8d6 100644 --- a/pyradUtilities.py +++ b/pyradUtilities.py @@ -173,6 +173,116 @@ def setupDir(): return directoryCheck and fileCheck +def csvToPYR(filePath): + fullPath = cwd + '/afgl/' + filePath + lines = openReturnLines(fullPath) + name = lines[0].split(',')[0] + height_position = 0 + pressure_position = 1 + temp_position = 2 + h2o_position = 4 + o3_posiiton = 5 + n2o_position = 6 + co_posiiton = 7 + ch4_position = 8 + heightList = [] + pressureList = [] + tempList = [] + h2oList = [] + o3List = [] + n2oList = [] + coList = [] + ch4List = [] + for line in lines[2:]: + cells = line.strip().split(',') + heightList.append(cells[height_position]) + pressureList.append(cells[pressure_position]) + tempList.append(cells[temp_position]) + h2oList.append(float(cells[h2o_position]) * 10**-6) + o3List.append(float(cells[o3_posiiton]) * 10**-6) + n2oList.append(float(cells[n2o_position]) * 10**-6) + coList.append(float(cells[co_posiiton]) * 10**-6) + ch4List.append(float(cells[ch4_position]) * 10**-6) + + pyrFilePath = '%s/%s.pyr' % (cwd, name) + + openFile = open(pyrFilePath, 'wb') + + # write comments + text = "# atm profile for %s\n\n" \ + "# surface values (pressure, temperature, final height, initial layer thickness, " \ + "acceleration of gravity, range min, range max)\n" \ + "surface: %s, %s, 120, 100, 9.8, 100, 2500\n" % (name, float(pressureList[0]), tempList[0]) + openFile.write(text.encode('utf-8')) + + # write initial file values + text = "\n# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile\n" \ + "# except for co2, o2, n2, and ar\n" \ + "molecule: co2, .000287\n" \ + "molecule: h2o, %s\n" \ + "molecule: o2, .20\n" \ + "molecule: n2, .77\n" \ + "molecule: ar, .009\n" \ + "molecule: ch4, %s\n" \ + "molecule: o3, %s\n" \ + "molecule: n2o, %s\n" \ + "molecule: co, %s\n" % (float(h2oList[0]), float(ch4List[0]), + float(o3List[0]), float(n2oList[0]), float(coList[0])) + openFile.write(text.encode('utf-8')) + + # write lapse rate + text = "\n# lapse rate profile\n" \ + "# rules are: name, final height, final value\n" \ + "# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule)\n" + openFile.write(text.encode('utf-8')) + i = 0 + for temp, height in zip(tempList[1:], heightList[1:]): + text = 'lapse rate: lapse rule %s, %s, %s\n' % (i, height, temp) + openFile.write(text.encode('utf-8')) + i += 1 + i = 0 + text = "\n# h2o composition profile\n" \ + "# composition rules are: name, final height, final value ppmv, molecule the rule applies to\n" + openFile.write(text.encode('utf-8')) + for h2o, height in zip(h2oList[1:], heightList[1:]): + text = 'composition rate: h2o rule %s, %s, %s, h2o\n' % (i, height, float(h2o)) + openFile.write(text.encode('utf-8')) + i += 1 + i = 0 + text = "\n# ch4 composition profile\n" \ + "# composition rules are: name, final height, final value ppmv, molecule the rule applies to\n" + openFile.write(text.encode('utf-8')) + for ch4, height in zip(ch4List[1:], heightList[1:]): + text = 'composition rate: ch4 rule %s, %s, %s, ch4\n' % (i, height, float(ch4)) + openFile.write(text.encode('utf-8')) + i += 1 + i = 0 + text = "\n# o3 composition profile\n" \ + "# composition rules are: name, final height, final value ppmv, molecule the rule applies to\n" + openFile.write(text.encode('utf-8')) + for o3, height in zip(o3List[1:], heightList[1:]): + text = 'composition rate: o3 rule %s, %s, %s, o3\n' % (i, height, float(o3)) + openFile.write(text.encode('utf-8')) + i += 1 + i = 0 + text = "\n# n2o composition profile\n" \ + "# composition rules are: name, final height, final value ppmv, molecule the rule applies to\n" + openFile.write(text.encode('utf-8')) + for n2o, height in zip(n2oList[1:], heightList[1:]): + text = 'composition rate: n2o rule %s, %s, %s, n2o\n' % (i, height, float(n2o)) + openFile.write(text.encode('utf-8')) + i += 1 + i = 0 + text = "\n# co composition profile\n" \ + "# composition rules are: name, final height, final value ppmv, molecule the rule applies to\n" + openFile.write(text.encode('utf-8')) + for co, height in zip(coList[1:], heightList[1:]): + text = 'composition rate: co rule %s, %s, %s, co\n' % (i, height, float(co)) + openFile.write(text.encode('utf-8')) + i += 1 + openFile.close() + + def writeTheme(fullPath): openFile = open(fullPath, 'wb') text = '# created by PyRad v%s on %s.\n' \ @@ -446,7 +556,7 @@ def parseCustomProfile(name): 'rangeMax': 2000} values = line.split(':')[1].split(',') tempDict['surfacePressure'] = float(values[0]) - tempDict['surfaceTemperature'] = int(values[1]) + tempDict['surfaceTemperature'] = float(values[1]) tempDict['maxHeight'] = float(values[2]) tempDict['initialDepth'] = float(values[3]) tempDict['gravity'] = float(values[4]) diff --git a/subarctic summer.pyr b/subarctic summer.pyr new file mode 100644 index 0000000..70b5cc1 --- /dev/null +++ b/subarctic summer.pyr @@ -0,0 +1,329 @@ +# atm profile for subarctic summer + +# surface values (pressure, temperature, final height, initial layer thickness, acceleration of gravity, range min, range max) +surface: 1010.0, 287.2, 120, 100, 9.8, 100, 2500 + +# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile +# except for co2, o2, n2, and ar +molecule: co2, .000287 +molecule: h2o, 0.011899999999999999 +molecule: o2, .20 +molecule: n2, .77 +molecule: ar, .009 +molecule: ch4, 1.6999999999999998e-06 +molecule: o3, 2.4099999999999997e-08 +molecule: n2o, 3.1e-07 +molecule: co, 1.5e-07 + +# lapse rate profile +# rules are: name, final height, final value +# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule) +lapse rate: lapse rule 0, 1, 281.7 +lapse rate: lapse rule 1, 2, 276.3 +lapse rate: lapse rule 2, 3, 270.9 +lapse rate: lapse rule 3, 4, 265.5 +lapse rate: lapse rule 4, 5, 260.1 +lapse rate: lapse rule 5, 6, 253.1 +lapse rate: lapse rule 6, 7, 246.1 +lapse rate: lapse rule 7, 8, 239.2 +lapse rate: lapse rule 8, 9, 232.2 +lapse rate: lapse rule 9, 10, 225.2 +lapse rate: lapse rule 10, 11, 225.2 +lapse rate: lapse rule 11, 12, 225.2 +lapse rate: lapse rule 12, 13, 225.2 +lapse rate: lapse rule 13, 14, 225.2 +lapse rate: lapse rule 14, 15, 225.2 +lapse rate: lapse rule 15, 16, 225.2 +lapse rate: lapse rule 16, 17, 225.2 +lapse rate: lapse rule 17, 18, 225.2 +lapse rate: lapse rule 18, 19, 225.2 +lapse rate: lapse rule 19, 20, 225.2 +lapse rate: lapse rule 20, 21, 225.2 +lapse rate: lapse rule 21, 22, 225.2 +lapse rate: lapse rule 22, 23, 225.2 +lapse rate: lapse rule 23, 24, 226.6 +lapse rate: lapse rule 24, 25, 228.1 +lapse rate: lapse rule 25, 27.6, 231 +lapse rate: lapse rule 26, 30, 235.1 +lapse rate: lapse rule 27, 32.6, 240 +lapse rate: lapse rule 28, 35, 247.2 +lapse rate: lapse rule 29, 37.5, 254.6 +lapse rate: lapse rule 30, 40, 262.1 +lapse rate: lapse rule 31, 42.5, 269.5 +lapse rate: lapse rule 32, 45, 273.6 +lapse rate: lapse rule 33, 47.5, 276.2 +lapse rate: lapse rule 34, 50, 277.2 +lapse rate: lapse rule 35, 55, 274 +lapse rate: lapse rule 36, 60, 262.7 +lapse rate: lapse rule 37, 65, 239.7 +lapse rate: lapse rule 38, 70, 216.6 +lapse rate: lapse rule 39, 75, 193.6 +lapse rate: lapse rule 40, 80, 170.6 +lapse rate: lapse rule 41, 85, 161.7 +lapse rate: lapse rule 42, 90, 161.6 +lapse rate: lapse rule 43, 95, 176.8 +lapse rate: lapse rule 44, 100, 190.4 +lapse rate: lapse rule 45, 105, 226 +lapse rate: lapse rule 46, 110, 270.1 +lapse rate: lapse rule 47, 115, 322.7 +lapse rate: lapse rule 48, 120, 380 + +# h2o composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: h2o rule 0, 1, 0.0087, h2o +composition rate: h2o rule 1, 2, 0.00675, h2o +composition rate: h2o rule 2, 3, 0.00482, h2o +composition rate: h2o rule 3, 4, 0.0033799999999999998, h2o +composition rate: h2o rule 4, 5, 0.0022199999999999998, h2o +composition rate: h2o rule 5, 6, 0.00133, h2o +composition rate: h2o rule 6, 7, 0.000797, h2o +composition rate: h2o rule 7, 8, 0.00039999999999999996, h2o +composition rate: h2o rule 8, 9, 0.00013, h2o +composition rate: h2o rule 9, 10, 4.2399999999999994e-05, h2o +composition rate: h2o rule 10, 11, 1.33e-05, h2o +composition rate: h2o rule 11, 12, 6e-06, h2o +composition rate: h2o rule 12, 13, 4.45e-06, h2o +composition rate: h2o rule 13, 14, 4e-06, h2o +composition rate: h2o rule 14, 15, 4e-06, h2o +composition rate: h2o rule 15, 16, 4e-06, h2o +composition rate: h2o rule 16, 17, 4.049999999999999e-06, h2o +composition rate: h2o rule 17, 18, 4.2999999999999995e-06, h2o +composition rate: h2o rule 18, 19, 4.5e-06, h2o +composition rate: h2o rule 19, 20, 4.599999999999999e-06, h2o +composition rate: h2o rule 20, 21, 4.7e-06, h2o +composition rate: h2o rule 21, 22, 4.8e-06, h2o +composition rate: h2o rule 22, 23, 4.8299999999999995e-06, h2o +composition rate: h2o rule 23, 24, 4.849999999999999e-06, h2o +composition rate: h2o rule 24, 25, 4.9000000000000005e-06, h2o +composition rate: h2o rule 25, 27.6, 4.95e-06, h2o +composition rate: h2o rule 26, 30, 4.9999999999999996e-06, h2o +composition rate: h2o rule 27, 32.6, 4.9999999999999996e-06, h2o +composition rate: h2o rule 28, 35, 4.9999999999999996e-06, h2o +composition rate: h2o rule 29, 37.5, 4.9999999999999996e-06, h2o +composition rate: h2o rule 30, 40, 4.9999999999999996e-06, h2o +composition rate: h2o rule 31, 42.5, 4.9999999999999996e-06, h2o +composition rate: h2o rule 32, 45, 4.9999999999999996e-06, h2o +composition rate: h2o rule 33, 47.5, 4.9999999999999996e-06, h2o +composition rate: h2o rule 34, 50, 4.95e-06, h2o +composition rate: h2o rule 35, 55, 4.849999999999999e-06, h2o +composition rate: h2o rule 36, 60, 4.5e-06, h2o +composition rate: h2o rule 37, 65, 4e-06, h2o +composition rate: h2o rule 38, 70, 3.2999999999999997e-06, h2o +composition rate: h2o rule 39, 75, 2.7e-06, h2o +composition rate: h2o rule 40, 80, 2e-06, h2o +composition rate: h2o rule 41, 85, 1.33e-06, h2o +composition rate: h2o rule 42, 90, 8.499999999999999e-07, h2o +composition rate: h2o rule 43, 95, 5.4e-07, h2o +composition rate: h2o rule 44, 100, 4e-07, h2o +composition rate: h2o rule 45, 105, 3.4000000000000003e-07, h2o +composition rate: h2o rule 46, 110, 2.8e-07, h2o +composition rate: h2o rule 47, 115, 2.4e-07, h2o +composition rate: h2o rule 48, 120, 2e-07, h2o + +# ch4 composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: ch4 rule 0, 1, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 1, 2, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 2, 3, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 3, 4, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 4, 5, 1.69e-06, ch4 +composition rate: ch4 rule 5, 6, 1.6699999999999999e-06, ch4 +composition rate: ch4 rule 6, 7, 1.6499999999999999e-06, ch4 +composition rate: ch4 rule 7, 8, 1.6299999999999999e-06, ch4 +composition rate: ch4 rule 8, 9, 1.62e-06, ch4 +composition rate: ch4 rule 9, 10, 1.58e-06, ch4 +composition rate: ch4 rule 10, 11, 1.5399999999999999e-06, ch4 +composition rate: ch4 rule 11, 12, 1.51e-06, ch4 +composition rate: ch4 rule 12, 13, 1.47e-06, ch4 +composition rate: ch4 rule 13, 14, 1.4299999999999999e-06, ch4 +composition rate: ch4 rule 14, 15, 1.3899999999999998e-06, ch4 +composition rate: ch4 rule 15, 16, 1.34e-06, ch4 +composition rate: ch4 rule 16, 17, 1.29e-06, ch4 +composition rate: ch4 rule 17, 18, 1.2299999999999999e-06, ch4 +composition rate: ch4 rule 18, 19, 1.16e-06, ch4 +composition rate: ch4 rule 19, 20, 1.07e-06, ch4 +composition rate: ch4 rule 20, 21, 9.9e-07, ch4 +composition rate: ch4 rule 21, 22, 9.17e-07, ch4 +composition rate: ch4 rule 22, 23, 8.569999999999999e-07, ch4 +composition rate: ch4 rule 23, 24, 8.01e-07, ch4 +composition rate: ch4 rule 24, 25, 7.48e-07, ch4 +composition rate: ch4 rule 25, 27.6, 6.959999999999999e-07, ch4 +composition rate: ch4 rule 26, 30, 6.44e-07, ch4 +composition rate: ch4 rule 27, 32.6, 5.89e-07, ch4 +composition rate: ch4 rule 28, 35, 5.24e-07, ch4 +composition rate: ch4 rule 29, 37.5, 4.51e-07, ch4 +composition rate: ch4 rule 30, 40, 3.71e-07, ch4 +composition rate: ch4 rule 31, 42.5, 2.9899999999999996e-07, ch4 +composition rate: ch4 rule 32, 45, 2.45e-07, ch4 +composition rate: ch4 rule 33, 47.5, 2e-07, ch4 +composition rate: ch4 rule 34, 50, 1.66e-07, ch4 +composition rate: ch4 rule 35, 55, 1.5e-07, ch4 +composition rate: ch4 rule 36, 60, 1.5e-07, ch4 +composition rate: ch4 rule 37, 65, 1.5e-07, ch4 +composition rate: ch4 rule 38, 70, 1.5e-07, ch4 +composition rate: ch4 rule 39, 75, 1.5e-07, ch4 +composition rate: ch4 rule 40, 80, 1.5e-07, ch4 +composition rate: ch4 rule 41, 85, 1.5e-07, ch4 +composition rate: ch4 rule 42, 90, 1.4e-07, ch4 +composition rate: ch4 rule 43, 95, 1.3e-07, ch4 +composition rate: ch4 rule 44, 100, 1.2e-07, ch4 +composition rate: ch4 rule 45, 105, 1.0999999999999999e-07, ch4 +composition rate: ch4 rule 46, 110, 9.499999999999999e-08, ch4 +composition rate: ch4 rule 47, 115, 6e-08, ch4 +composition rate: ch4 rule 48, 120, 3e-08, ch4 + +# o3 composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: o3 rule 0, 1, 2.94e-08, o3 +composition rate: o3 rule 1, 2, 3.38e-08, o3 +composition rate: o3 rule 2, 3, 3.89e-08, o3 +composition rate: o3 rule 3, 4, 4.48e-08, o3 +composition rate: o3 rule 4, 5, 5.33e-08, o3 +composition rate: o3 rule 5, 6, 6.56e-08, o3 +composition rate: o3 rule 6, 7, 7.739999999999999e-08, o3 +composition rate: o3 rule 7, 8, 9.11e-08, o3 +composition rate: o3 rule 8, 9, 1.4199999999999997e-07, o3 +composition rate: o3 rule 9, 10, 1.8899999999999999e-07, o3 +composition rate: o3 rule 10, 11, 3.05e-07, o3 +composition rate: o3 rule 11, 12, 4.0999999999999994e-07, o3 +composition rate: o3 rule 12, 13, 5e-07, o3 +composition rate: o3 rule 13, 14, 6e-07, o3 +composition rate: o3 rule 14, 15, 7e-07, o3 +composition rate: o3 rule 15, 16, 8e-07, o3 +composition rate: o3 rule 16, 17, 1e-06, o3 +composition rate: o3 rule 17, 18, 1.3e-06, o3 +composition rate: o3 rule 18, 19, 1.6999999999999998e-06, o3 +composition rate: o3 rule 19, 20, 2.1e-06, o3 +composition rate: o3 rule 20, 21, 2.7e-06, o3 +composition rate: o3 rule 21, 22, 3.2999999999999997e-06, o3 +composition rate: o3 rule 22, 23, 3.7e-06, o3 +composition rate: o3 rule 23, 24, 4.2e-06, o3 +composition rate: o3 rule 24, 25, 4.5e-06, o3 +composition rate: o3 rule 25, 27.6, 5.299999999999999e-06, o3 +composition rate: o3 rule 26, 30, 5.7e-06, o3 +composition rate: o3 rule 27, 32.6, 6.9e-06, o3 +composition rate: o3 rule 28, 35, 7.699999999999999e-06, o3 +composition rate: o3 rule 29, 37.5, 7.8e-06, o3 +composition rate: o3 rule 30, 40, 7e-06, o3 +composition rate: o3 rule 31, 42.5, 5.4e-06, o3 +composition rate: o3 rule 32, 45, 4.2e-06, o3 +composition rate: o3 rule 33, 47.5, 3.2e-06, o3 +composition rate: o3 rule 34, 50, 2.4999999999999998e-06, o3 +composition rate: o3 rule 35, 55, 1.6999999999999998e-06, o3 +composition rate: o3 rule 36, 60, 1.2e-06, o3 +composition rate: o3 rule 37, 65, 8e-07, o3 +composition rate: o3 rule 38, 70, 4e-07, o3 +composition rate: o3 rule 39, 75, 2e-07, o3 +composition rate: o3 rule 40, 80, 1.8e-07, o3 +composition rate: o3 rule 41, 85, 6.5e-07, o3 +composition rate: o3 rule 42, 90, 9e-07, o3 +composition rate: o3 rule 43, 95, 8e-07, o3 +composition rate: o3 rule 44, 100, 4e-07, o3 +composition rate: o3 rule 45, 105, 2e-07, o3 +composition rate: o3 rule 46, 110, 5e-08, o3 +composition rate: o3 rule 47, 115, 5e-09, o3 +composition rate: o3 rule 48, 120, 5e-10, o3 + +# n2o composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: n2o rule 0, 1, 3.1e-07, n2o +composition rate: n2o rule 1, 2, 3.1e-07, n2o +composition rate: n2o rule 2, 3, 3.1e-07, n2o +composition rate: n2o rule 3, 4, 3.08e-07, n2o +composition rate: n2o rule 4, 5, 3.02e-07, n2o +composition rate: n2o rule 5, 6, 2.9099999999999995e-07, n2o +composition rate: n2o rule 6, 7, 2.8199999999999996e-07, n2o +composition rate: n2o rule 7, 8, 2.7600000000000004e-07, n2o +composition rate: n2o rule 8, 9, 2.7e-07, n2o +composition rate: n2o rule 9, 10, 2.65e-07, n2o +composition rate: n2o rule 10, 11, 2.6e-07, n2o +composition rate: n2o rule 11, 12, 2.55e-07, n2o +composition rate: n2o rule 12, 13, 2.4899999999999997e-07, n2o +composition rate: n2o rule 13, 14, 2.43e-07, n2o +composition rate: n2o rule 14, 15, 2.3599999999999997e-07, n2o +composition rate: n2o rule 15, 16, 2.28e-07, n2o +composition rate: n2o rule 16, 17, 2.18e-07, n2o +composition rate: n2o rule 17, 18, 2.0399999999999997e-07, n2o +composition rate: n2o rule 18, 19, 1.82e-07, n2o +composition rate: n2o rule 19, 20, 1.57e-07, n2o +composition rate: n2o rule 20, 21, 1.35e-07, n2o +composition rate: n2o rule 21, 22, 1.2199999999999998e-07, n2o +composition rate: n2o rule 22, 23, 1.0999999999999999e-07, n2o +composition rate: n2o rule 23, 24, 9.889999999999999e-08, n2o +composition rate: n2o rule 24, 25, 8.78e-08, n2o +composition rate: n2o rule 25, 27.6, 7.33e-08, n2o +composition rate: n2o rule 26, 30, 5.9399999999999996e-08, n2o +composition rate: n2o rule 27, 32.6, 4.15e-08, n2o +composition rate: n2o rule 28, 35, 3.03e-08, n2o +composition rate: n2o rule 29, 37.5, 1.95e-08, n2o +composition rate: n2o rule 30, 40, 1.27e-08, n2o +composition rate: n2o rule 31, 42.5, 9e-09, n2o +composition rate: n2o rule 32, 45, 6.2899999999999996e-09, n2o +composition rate: n2o rule 33, 47.5, 4.56e-09, n2o +composition rate: n2o rule 34, 50, 2.8e-09, n2o +composition rate: n2o rule 35, 55, 1.77e-09, n2o +composition rate: n2o rule 36, 60, 1.21e-09, n2o +composition rate: n2o rule 37, 65, 8.869999999999999e-10, n2o +composition rate: n2o rule 38, 70, 6.759999999999999e-10, n2o +composition rate: n2o rule 39, 75, 5.539999999999999e-10, n2o +composition rate: n2o rule 40, 80, 4.65e-10, n2o +composition rate: n2o rule 41, 85, 3.98e-10, n2o +composition rate: n2o rule 42, 90, 3.05e-10, n2o +composition rate: n2o rule 43, 95, 2.7099999999999994e-10, n2o +composition rate: n2o rule 44, 100, 2.44e-10, n2o +composition rate: n2o rule 45, 105, 2.2099999999999999e-10, n2o +composition rate: n2o rule 46, 110, 2.02e-10, n2o +composition rate: n2o rule 47, 115, 1.8399999999999998e-10, n2o +composition rate: n2o rule 48, 120, 1.8499999999999998e-10, n2o + +# co composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: co rule 0, 1, 1.45e-07, co +composition rate: co rule 1, 2, 1.4e-07, co +composition rate: co rule 2, 3, 1.35e-07, co +composition rate: co rule 3, 4, 1.31e-07, co +composition rate: co rule 4, 5, 1.3e-07, co +composition rate: co rule 5, 6, 1.29e-07, co +composition rate: co rule 6, 7, 1.25e-07, co +composition rate: co rule 7, 8, 1.19e-07, co +composition rate: co rule 8, 9, 1.09e-07, co +composition rate: co rule 9, 10, 9.959999999999999e-08, co +composition rate: co rule 10, 11, 8.96e-08, co +composition rate: co rule 11, 12, 7.81e-08, co +composition rate: co rule 12, 13, 6.370000000000001e-08, co +composition rate: co rule 13, 14, 5.0299999999999994e-08, co +composition rate: co rule 14, 15, 3.9399999999999995e-08, co +composition rate: co rule 15, 16, 3.07e-08, co +composition rate: co rule 16, 17, 2.4899999999999998e-08, co +composition rate: co rule 17, 18, 1.9699999999999998e-08, co +composition rate: co rule 18, 19, 1.55e-08, co +composition rate: co rule 19, 20, 1.3299999999999998e-08, co +composition rate: co rule 20, 21, 1.23e-08, co +composition rate: co rule 21, 22, 1.23e-08, co +composition rate: co rule 22, 23, 1.31e-08, co +composition rate: co rule 23, 24, 1.4e-08, co +composition rate: co rule 24, 25, 1.51e-08, co +composition rate: co rule 25, 27.6, 1.65e-08, co +composition rate: co rule 26, 30, 1.81e-08, co +composition rate: co rule 27, 32.6, 2e-08, co +composition rate: co rule 28, 35, 2.18e-08, co +composition rate: co rule 29, 37.5, 2.34e-08, co +composition rate: co rule 30, 40, 2.5e-08, co +composition rate: co rule 31, 42.5, 2.65e-08, co +composition rate: co rule 32, 45, 2.81e-08, co +composition rate: co rule 33, 47.5, 3e-08, co +composition rate: co rule 34, 50, 3.22e-08, co +composition rate: co rule 35, 55, 3.6499999999999996e-08, co +composition rate: co rule 36, 60, 4.59e-08, co +composition rate: co rule 37, 65, 8.38e-08, co +composition rate: co rule 38, 70, 1.1799999999999998e-07, co +composition rate: co rule 39, 75, 3.03e-07, co +composition rate: co rule 40, 80, 7.89e-07, co +composition rate: co rule 41, 85, 1.82e-06, co +composition rate: co rule 42, 90, 3.3999999999999996e-06, co +composition rate: co rule 43, 95, 5.92e-06, co +composition rate: co rule 44, 100, 1.04e-05, co +composition rate: co rule 45, 105, 1.88e-05, co +composition rate: co rule 46, 110, 2.87e-05, co +composition rate: co rule 47, 115, 3.89e-05, co +composition rate: co rule 48, 120, 4.9999999999999996e-05, co diff --git a/subarctic winter.pyr b/subarctic winter.pyr new file mode 100644 index 0000000..05df492 --- /dev/null +++ b/subarctic winter.pyr @@ -0,0 +1,329 @@ +# atm profile for subarctic winter + +# surface values (pressure, temperature, final height, initial layer thickness, acceleration of gravity, range min, range max) +surface: 1010.0, 257.2, 120, 100, 9.8, 100, 2500 + +# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile +# except for co2, o2, n2, and ar +molecule: co2, .000287 +molecule: h2o, 0.00141 +molecule: o2, .20 +molecule: n2, .77 +molecule: ar, .009 +molecule: ch4, 1.6999999999999998e-06 +molecule: o3, 1.8e-08 +molecule: n2o, 3.1e-07 +molecule: co, 3.2e-07 + +# lapse rate profile +# rules are: name, final height, final value +# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule) +lapse rate: lapse rule 0, 1, 239.1 +lapse rate: lapse rule 1, 2, 255.9 +lapse rate: lapse rule 2, 3, 252.7 +lapse rate: lapse rule 3, 4, 247.7 +lapse rate: lapse rule 4, 5, 240.9 +lapse rate: lapse rule 5, 6, 234.1 +lapse rate: lapse rule 6, 7, 227.3 +lapse rate: lapse rule 7, 8, 220.6 +lapse rate: lapse rule 8, 9, 217.2 +lapse rate: lapse rule 9, 10, 217.2 +lapse rate: lapse rule 10, 11, 217.2 +lapse rate: lapse rule 11, 12, 217.2 +lapse rate: lapse rule 12, 13, 217.2 +lapse rate: lapse rule 13, 14, 217.2 +lapse rate: lapse rule 14, 15, 217.2 +lapse rate: lapse rule 15, 16, 216.6 +lapse rate: lapse rule 16, 17, 216 +lapse rate: lapse rule 17, 18, 215.4 +lapse rate: lapse rule 18, 19, 214.8 +lapse rate: lapse rule 19, 20, 214.2 +lapse rate: lapse rule 20, 21, 213.6 +lapse rate: lapse rule 21, 22, 213 +lapse rate: lapse rule 22, 23, 212.4 +lapse rate: lapse rule 23, 24, 211.8 +lapse rate: lapse rule 24, 25, 211.2 +lapse rate: lapse rule 25, 27.6, 213.6 +lapse rate: lapse rule 26, 30, 216 +lapse rate: lapse rule 27, 32.6, 218.5 +lapse rate: lapse rule 28, 35, 222.3 +lapse rate: lapse rule 29, 37.5, 228.5 +lapse rate: lapse rule 30, 40, 234.7 +lapse rate: lapse rule 31, 42.5, 240.8 +lapse rate: lapse rule 32, 45, 247 +lapse rate: lapse rule 33, 47.5, 253.2 +lapse rate: lapse rule 34, 50, 259.3 +lapse rate: lapse rule 35, 55, 259.1 +lapse rate: lapse rule 36, 60, 250.9 +lapse rate: lapse rule 37, 65, 248.4 +lapse rate: lapse rule 38, 70, 245.4 +lapse rate: lapse rule 39, 75, 234.7 +lapse rate: lapse rule 40, 80, 223.9 +lapse rate: lapse rule 41, 85, 213.1 +lapse rate: lapse rule 42, 90, 202.3 +lapse rate: lapse rule 43, 95, 211 +lapse rate: lapse rule 44, 100, 218.5 +lapse rate: lapse rule 45, 105, 234 +lapse rate: lapse rule 46, 110, 252.6 +lapse rate: lapse rule 47, 115, 288.5 +lapse rate: lapse rule 48, 120, 333 + +# h2o composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: h2o rule 0, 1, 0.00162, h2o +composition rate: h2o rule 1, 2, 0.0014299999999999998, h2o +composition rate: h2o rule 2, 3, 0.00117, h2o +composition rate: h2o rule 3, 4, 0.007899999999999999, h2o +composition rate: h2o rule 4, 5, 0.00043099999999999996, h2o +composition rate: h2o rule 5, 6, 0.00027, h2o +composition rate: h2o rule 6, 7, 0.000147, h2o +composition rate: h2o rule 7, 8, 3.3799999999999995e-05, h2o +composition rate: h2o rule 8, 9, 2.98e-05, h2o +composition rate: h2o rule 9, 10, 1.9999999999999998e-05, h2o +composition rate: h2o rule 10, 11, 9.999999999999999e-06, h2o +composition rate: h2o rule 11, 12, 6e-06, h2o +composition rate: h2o rule 12, 13, 4.45e-06, h2o +composition rate: h2o rule 13, 14, 4.5e-06, h2o +composition rate: h2o rule 14, 15, 4.55e-06, h2o +composition rate: h2o rule 15, 16, 4.65e-06, h2o +composition rate: h2o rule 16, 17, 4.65e-06, h2o +composition rate: h2o rule 17, 18, 4.749999999999999e-06, h2o +composition rate: h2o rule 18, 19, 4.749999999999999e-06, h2o +composition rate: h2o rule 19, 20, 4.849999999999999e-06, h2o +composition rate: h2o rule 20, 21, 4.849999999999999e-06, h2o +composition rate: h2o rule 21, 22, 4.9000000000000005e-06, h2o +composition rate: h2o rule 22, 23, 4.95e-06, h2o +composition rate: h2o rule 23, 24, 4.9999999999999996e-06, h2o +composition rate: h2o rule 24, 25, 4.9999999999999996e-06, h2o +composition rate: h2o rule 25, 27.6, 4.9999999999999996e-06, h2o +composition rate: h2o rule 26, 30, 4.9999999999999996e-06, h2o +composition rate: h2o rule 27, 32.6, 4.9999999999999996e-06, h2o +composition rate: h2o rule 28, 35, 4.9999999999999996e-06, h2o +composition rate: h2o rule 29, 37.5, 4.9999999999999996e-06, h2o +composition rate: h2o rule 30, 40, 4.9999999999999996e-06, h2o +composition rate: h2o rule 31, 42.5, 4.9999999999999996e-06, h2o +composition rate: h2o rule 32, 45, 4.9999999999999996e-06, h2o +composition rate: h2o rule 33, 47.5, 4.9999999999999996e-06, h2o +composition rate: h2o rule 34, 50, 4.95e-06, h2o +composition rate: h2o rule 35, 55, 4.849999999999999e-06, h2o +composition rate: h2o rule 36, 60, 4.5e-06, h2o +composition rate: h2o rule 37, 65, 4e-06, h2o +composition rate: h2o rule 38, 70, 3.2999999999999997e-06, h2o +composition rate: h2o rule 39, 75, 2.7e-06, h2o +composition rate: h2o rule 40, 80, 2e-06, h2o +composition rate: h2o rule 41, 85, 1.33e-06, h2o +composition rate: h2o rule 42, 90, 8.499999999999999e-07, h2o +composition rate: h2o rule 43, 95, 5.4e-07, h2o +composition rate: h2o rule 44, 100, 4e-07, h2o +composition rate: h2o rule 45, 105, 3.4000000000000003e-07, h2o +composition rate: h2o rule 46, 110, 2.8e-07, h2o +composition rate: h2o rule 47, 115, 2.4e-07, h2o +composition rate: h2o rule 48, 120, 2e-07, h2o + +# ch4 composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: ch4 rule 0, 1, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 1, 2, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 2, 3, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 3, 4, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 4, 5, 1.69e-06, ch4 +composition rate: ch4 rule 5, 6, 1.6699999999999999e-06, ch4 +composition rate: ch4 rule 6, 7, 1.6499999999999999e-06, ch4 +composition rate: ch4 rule 7, 8, 1.6299999999999999e-06, ch4 +composition rate: ch4 rule 8, 9, 1.62e-06, ch4 +composition rate: ch4 rule 9, 10, 1.58e-06, ch4 +composition rate: ch4 rule 10, 11, 1.5399999999999999e-06, ch4 +composition rate: ch4 rule 11, 12, 1.51e-06, ch4 +composition rate: ch4 rule 12, 13, 1.47e-06, ch4 +composition rate: ch4 rule 13, 14, 1.4299999999999999e-06, ch4 +composition rate: ch4 rule 14, 15, 1.3899999999999998e-06, ch4 +composition rate: ch4 rule 15, 16, 1.34e-06, ch4 +composition rate: ch4 rule 16, 17, 1.29e-06, ch4 +composition rate: ch4 rule 17, 18, 1.2299999999999999e-06, ch4 +composition rate: ch4 rule 18, 19, 1.16e-06, ch4 +composition rate: ch4 rule 19, 20, 1.08e-06, ch4 +composition rate: ch4 rule 20, 21, 1.0099999999999999e-06, ch4 +composition rate: ch4 rule 21, 22, 9.559999999999998e-07, ch4 +composition rate: ch4 rule 22, 23, 9.01e-07, ch4 +composition rate: ch4 rule 23, 24, 8.48e-07, ch4 +composition rate: ch4 rule 24, 25, 7.96e-07, ch4 +composition rate: ch4 rule 25, 27.6, 7.45e-07, ch4 +composition rate: ch4 rule 26, 30, 6.939999999999999e-07, ch4 +composition rate: ch4 rule 27, 32.6, 6.43e-07, ch4 +composition rate: ch4 rule 28, 35, 5.879999999999999e-07, ch4 +composition rate: ch4 rule 29, 37.5, 5.24e-07, ch4 +composition rate: ch4 rule 30, 40, 4.51e-07, ch4 +composition rate: ch4 rule 31, 42.5, 3.71e-07, ch4 +composition rate: ch4 rule 32, 45, 3e-07, ch4 +composition rate: ch4 rule 33, 47.5, 2.45e-07, ch4 +composition rate: ch4 rule 34, 50, 1.98e-07, ch4 +composition rate: ch4 rule 35, 55, 1.59e-07, ch4 +composition rate: ch4 rule 36, 60, 1.5e-07, ch4 +composition rate: ch4 rule 37, 65, 1.5e-07, ch4 +composition rate: ch4 rule 38, 70, 1.5e-07, ch4 +composition rate: ch4 rule 39, 75, 1.5e-07, ch4 +composition rate: ch4 rule 40, 80, 1.5e-07, ch4 +composition rate: ch4 rule 41, 85, 1.5e-07, ch4 +composition rate: ch4 rule 42, 90, 1.4e-07, ch4 +composition rate: ch4 rule 43, 95, 1.3e-07, ch4 +composition rate: ch4 rule 44, 100, 1.2e-07, ch4 +composition rate: ch4 rule 45, 105, 1.0999999999999999e-07, ch4 +composition rate: ch4 rule 46, 110, 9.499999999999999e-08, ch4 +composition rate: ch4 rule 47, 115, 6e-08, ch4 +composition rate: ch4 rule 48, 120, 3e-08, ch4 + +# o3 composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: o3 rule 0, 1, 2e-08, o3 +composition rate: o3 rule 1, 2, 2.34e-08, o3 +composition rate: o3 rule 2, 3, 2.7699999999999997e-08, o3 +composition rate: o3 rule 3, 4, 3.25e-08, o3 +composition rate: o3 rule 4, 5, 3.7999999999999996e-08, o3 +composition rate: o3 rule 5, 6, 4.4499999999999995e-08, o3 +composition rate: o3 rule 6, 7, 7.25e-08, o3 +composition rate: o3 rule 7, 8, 1.0399999999999999e-07, o3 +composition rate: o3 rule 8, 9, 2.0999999999999997e-07, o3 +composition rate: o3 rule 9, 10, 3e-07, o3 +composition rate: o3 rule 10, 11, 3.5e-07, o3 +composition rate: o3 rule 11, 12, 4e-07, o3 +composition rate: o3 rule 12, 13, 6.5e-07, o3 +composition rate: o3 rule 13, 14, 9e-07, o3 +composition rate: o3 rule 14, 15, 1.2e-06, o3 +composition rate: o3 rule 15, 16, 1.5e-06, o3 +composition rate: o3 rule 16, 17, 1.8999999999999998e-06, o3 +composition rate: o3 rule 17, 18, 2.4500000000000003e-06, o3 +composition rate: o3 rule 18, 19, 3.1e-06, o3 +composition rate: o3 rule 19, 20, 3.7e-06, o3 +composition rate: o3 rule 20, 21, 4e-06, o3 +composition rate: o3 rule 21, 22, 4.2e-06, o3 +composition rate: o3 rule 22, 23, 4.5e-06, o3 +composition rate: o3 rule 23, 24, 4.599999999999999e-06, o3 +composition rate: o3 rule 24, 25, 4.7e-06, o3 +composition rate: o3 rule 25, 27.6, 4.9000000000000005e-06, o3 +composition rate: o3 rule 26, 30, 5.4e-06, o3 +composition rate: o3 rule 27, 32.6, 5.9e-06, o3 +composition rate: o3 rule 28, 35, 6.2e-06, o3 +composition rate: o3 rule 29, 37.5, 6.2499999999999995e-06, o3 +composition rate: o3 rule 30, 40, 5.9e-06, o3 +composition rate: o3 rule 31, 42.5, 5.0999999999999995e-06, o3 +composition rate: o3 rule 32, 45, 4.1e-06, o3 +composition rate: o3 rule 33, 47.5, 3e-06, o3 +composition rate: o3 rule 34, 50, 2.6e-06, o3 +composition rate: o3 rule 35, 55, 1.6e-06, o3 +composition rate: o3 rule 36, 60, 9.499999999999999e-07, o3 +composition rate: o3 rule 37, 65, 6.5e-07, o3 +composition rate: o3 rule 38, 70, 5e-07, o3 +composition rate: o3 rule 39, 75, 3.3e-07, o3 +composition rate: o3 rule 40, 80, 1.3e-07, o3 +composition rate: o3 rule 41, 85, 7.5e-07, o3 +composition rate: o3 rule 42, 90, 8e-07, o3 +composition rate: o3 rule 43, 95, 8e-07, o3 +composition rate: o3 rule 44, 100, 4e-07, o3 +composition rate: o3 rule 45, 105, 2e-07, o3 +composition rate: o3 rule 46, 110, 5e-08, o3 +composition rate: o3 rule 47, 115, 5e-09, o3 +composition rate: o3 rule 48, 120, 5e-10, o3 + +# n2o composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: n2o rule 0, 1, 3.1e-07, n2o +composition rate: n2o rule 1, 2, 3.1e-07, n2o +composition rate: n2o rule 2, 3, 3.1e-07, n2o +composition rate: n2o rule 3, 4, 3.08e-07, n2o +composition rate: n2o rule 4, 5, 3.02e-07, n2o +composition rate: n2o rule 5, 6, 2.9099999999999995e-07, n2o +composition rate: n2o rule 6, 7, 2.8199999999999996e-07, n2o +composition rate: n2o rule 7, 8, 2.7600000000000004e-07, n2o +composition rate: n2o rule 8, 9, 2.7e-07, n2o +composition rate: n2o rule 9, 10, 2.65e-07, n2o +composition rate: n2o rule 10, 11, 2.6e-07, n2o +composition rate: n2o rule 11, 12, 2.55e-07, n2o +composition rate: n2o rule 12, 13, 2.4899999999999997e-07, n2o +composition rate: n2o rule 13, 14, 2.43e-07, n2o +composition rate: n2o rule 14, 15, 2.3599999999999997e-07, n2o +composition rate: n2o rule 15, 16, 2.28e-07, n2o +composition rate: n2o rule 16, 17, 2.18e-07, n2o +composition rate: n2o rule 17, 18, 2.0399999999999997e-07, n2o +composition rate: n2o rule 18, 19, 1.82e-07, n2o +composition rate: n2o rule 19, 20, 1.57e-07, n2o +composition rate: n2o rule 20, 21, 1.35e-07, n2o +composition rate: n2o rule 21, 22, 1.2199999999999998e-07, n2o +composition rate: n2o rule 22, 23, 1.0999999999999999e-07, n2o +composition rate: n2o rule 23, 24, 9.889999999999999e-08, n2o +composition rate: n2o rule 24, 25, 8.78e-08, n2o +composition rate: n2o rule 25, 27.6, 7.33e-08, n2o +composition rate: n2o rule 26, 30, 5.9399999999999996e-08, n2o +composition rate: n2o rule 27, 32.6, 4.15e-08, n2o +composition rate: n2o rule 28, 35, 3.03e-08, n2o +composition rate: n2o rule 29, 37.5, 1.95e-08, n2o +composition rate: n2o rule 30, 40, 1.27e-08, n2o +composition rate: n2o rule 31, 42.5, 9e-09, n2o +composition rate: n2o rule 32, 45, 6.2899999999999996e-09, n2o +composition rate: n2o rule 33, 47.5, 4.56e-09, n2o +composition rate: n2o rule 34, 50, 2.8e-09, n2o +composition rate: n2o rule 35, 55, 1.77e-09, n2o +composition rate: n2o rule 36, 60, 1.21e-09, n2o +composition rate: n2o rule 37, 65, 8.869999999999999e-10, n2o +composition rate: n2o rule 38, 70, 6.759999999999999e-10, n2o +composition rate: n2o rule 39, 75, 5.539999999999999e-10, n2o +composition rate: n2o rule 40, 80, 4.65e-10, n2o +composition rate: n2o rule 41, 85, 3.98e-10, n2o +composition rate: n2o rule 42, 90, 3.05e-10, n2o +composition rate: n2o rule 43, 95, 2.7099999999999994e-10, n2o +composition rate: n2o rule 44, 100, 2.44e-10, n2o +composition rate: n2o rule 45, 105, 2.2099999999999999e-10, n2o +composition rate: n2o rule 46, 110, 2.02e-10, n2o +composition rate: n2o rule 47, 115, 1.8399999999999998e-10, n2o +composition rate: n2o rule 48, 120, 1.8499999999999998e-10, n2o + +# co composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: co rule 0, 1, 3.2e-07, co +composition rate: co rule 1, 2, 3.2e-07, co +composition rate: co rule 2, 3, 3.2e-07, co +composition rate: co rule 3, 4, 3.2e-07, co +composition rate: co rule 4, 5, 3.2e-07, co +composition rate: co rule 5, 6, 3.2e-07, co +composition rate: co rule 6, 7, 3.2e-07, co +composition rate: co rule 7, 8, 3.2e-07, co +composition rate: co rule 8, 9, 3.1599999999999997e-07, co +composition rate: co rule 9, 10, 3.1e-07, co +composition rate: co rule 10, 11, 2.9e-07, co +composition rate: co rule 11, 12, 2.9399999999999996e-07, co +composition rate: co rule 12, 13, 2.8599999999999994e-07, co +composition rate: co rule 13, 14, 2.8e-07, co +composition rate: co rule 14, 15, 2.7e-07, co +composition rate: co rule 15, 16, 2.61e-07, co +composition rate: co rule 16, 17, 2.4199999999999997e-07, co +composition rate: co rule 17, 18, 2.17e-07, co +composition rate: co rule 18, 19, 1.8399999999999998e-07, co +composition rate: co rule 19, 20, 1.62e-07, co +composition rate: co rule 20, 21, 1.36e-07, co +composition rate: co rule 21, 22, 1.23e-07, co +composition rate: co rule 22, 23, 1.12e-07, co +composition rate: co rule 23, 24, 1.0399999999999999e-07, co +composition rate: co rule 24, 25, 9.569999999999999e-08, co +composition rate: co rule 25, 27.6, 6.6e-08, co +composition rate: co rule 26, 30, 7.31e-08, co +composition rate: co rule 27, 32.6, 5.7099999999999995e-08, co +composition rate: co rule 28, 35, 4.6699999999999995e-08, co +composition rate: co rule 29, 37.5, 3.44e-08, co +composition rate: co rule 30, 40, 2.47e-08, co +composition rate: co rule 31, 42.5, 1.6299999999999997e-08, co +composition rate: co rule 32, 45, 1.0699999999999998e-08, co +composition rate: co rule 33, 47.5, 7.06e-09, co +composition rate: co rule 34, 50, 3.969999999999999e-09, co +composition rate: co rule 35, 55, 2.51e-09, co +composition rate: co rule 36, 60, 1.7299999999999998e-09, co +composition rate: co rule 37, 65, 1.26e-09, co +composition rate: co rule 38, 70, 9.6e-10, co +composition rate: co rule 39, 75, 7.55e-10, co +composition rate: co rule 40, 80, 6.1e-10, co +composition rate: co rule 41, 85, 5.019999999999999e-10, co +composition rate: co rule 42, 90, 4.21e-10, co +composition rate: co rule 43, 95, 3.5799999999999995e-10, co +composition rate: co rule 44, 100, 3.0799999999999997e-10, co +composition rate: co rule 45, 105, 2.68e-10, co +composition rate: co rule 46, 110, 2.3499999999999996e-10, co +composition rate: co rule 47, 115, 2.0799999999999998e-10, co +composition rate: co rule 48, 120, 1.8499999999999998e-10, co diff --git a/themes/dark.pyr b/themes/dark.pyr index 8bca091..7244948 100644 --- a/themes/dark.pyr +++ b/themes/dark.pyr @@ -42,3 +42,7 @@ colorList: 255, 95, 0 # yellow colorList: 255, 255, 0 + +colorList: 120, 205, 120 +colorList: 0, 95, 255 +colorList: 180, 95, 180 \ No newline at end of file diff --git a/tropical - narrow spectrum.pyr b/tropical - narrow spectrum.pyr new file mode 100644 index 0000000..1b674f1 --- /dev/null +++ b/tropical - narrow spectrum.pyr @@ -0,0 +1,329 @@ +# atm profile for tropical + +# surface values (pressure, temperature, final height, initial layer thickness, acceleration of gravity, range min, range max) +surface: 1010.0, 299.7, 120, 100, 9.8, 600, 1200 + +# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile +# except for co2, o2, n2, and ar +molecule: co2, .000287 +molecule: h2o, 0.0259 +molecule: o2, .20 +molecule: n2, .77 +molecule: ar, .009 +molecule: ch4, 1.6999999999999998e-06 +molecule: o3, 2.9699999999999998e-08 +molecule: n2o, 3.2e-07 +molecule: co, 1.5e-07 + +# lapse rate profile +# rules are: name, final height, final value +# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule) +lapse rate: lapse rule 0, 1, 293.7 +lapse rate: lapse rule 1, 2, 287.7 +lapse rate: lapse rule 2, 3, 283.7 +lapse rate: lapse rule 3, 4, 277 +lapse rate: lapse rule 4, 5, 270.3 +lapse rate: lapse rule 5, 6, 263.6 +lapse rate: lapse rule 6, 7, 257 +lapse rate: lapse rule 7, 8, 250.3 +lapse rate: lapse rule 8, 9, 243.6 +lapse rate: lapse rule 9, 10, 237 +lapse rate: lapse rule 10, 11, 230.1 +lapse rate: lapse rule 11, 12, 223.6 +lapse rate: lapse rule 12, 13, 217 +lapse rate: lapse rule 13, 14, 210.3 +lapse rate: lapse rule 14, 15, 203.7 +lapse rate: lapse rule 15, 16, 197 +lapse rate: lapse rule 16, 17, 164.8 +lapse rate: lapse rule 17, 18, 168.8 +lapse rate: lapse rule 18, 19, 202.7 +lapse rate: lapse rule 19, 20, 206.7 +lapse rate: lapse rule 20, 21, 210.7 +lapse rate: lapse rule 21, 22, 214.6 +lapse rate: lapse rule 22, 23, 217 +lapse rate: lapse rule 23, 24, 219.2 +lapse rate: lapse rule 24, 25, 221.4 +lapse rate: lapse rule 25, 27.6, 227 +lapse rate: lapse rule 26, 30, 232.3 +lapse rate: lapse rule 27, 32.6, 237.7 +lapse rate: lapse rule 28, 35, 243.1 +lapse rate: lapse rule 29, 37.5, 248.5 +lapse rate: lapse rule 30, 40, 254 +lapse rate: lapse rule 31, 42.5, 259.4 +lapse rate: lapse rule 32, 45, 264.8 +lapse rate: lapse rule 33, 47.5, 269.6 +lapse rate: lapse rule 34, 50, 270.2 +lapse rate: lapse rule 35, 55, 263.4 +lapse rate: lapse rule 36, 60, 253.1 +lapse rate: lapse rule 37, 65, 236 +lapse rate: lapse rule 38, 70, 218.9 +lapse rate: lapse rule 39, 75, 201.8 +lapse rate: lapse rule 40, 80, 184.8 +lapse rate: lapse rule 41, 85, 177.1 +lapse rate: lapse rule 42, 90, 177 +lapse rate: lapse rule 43, 95, 184.3 +lapse rate: lapse rule 44, 100, 190.7 +lapse rate: lapse rule 45, 105, 212 +lapse rate: lapse rule 46, 110, 241.6 +lapse rate: lapse rule 47, 115, 299.7 +lapse rate: lapse rule 48, 120, 380 + +# h2o composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: h2o rule 0, 1, 0.012499999999999999, h2o +composition rate: h2o rule 1, 2, 0.0153, h2o +composition rate: h2o rule 2, 3, 0.0086, h2o +composition rate: h2o rule 3, 4, 0.0044399999999999995, h2o +composition rate: h2o rule 4, 5, 0.0033499999999999997, h2o +composition rate: h2o rule 5, 6, 0.0021, h2o +composition rate: h2o rule 6, 7, 0.00129, h2o +composition rate: h2o rule 7, 8, 0.0007639999999999999, h2o +composition rate: h2o rule 8, 9, 0.00041, h2o +composition rate: h2o rule 9, 10, 0.00019099999999999998, h2o +composition rate: h2o rule 10, 11, 7.309999999999999e-05, h2o +composition rate: h2o rule 11, 12, 2.91e-05, h2o +composition rate: h2o rule 12, 13, 9e-06, h2o +composition rate: h2o rule 13, 14, 6.22e-06, h2o +composition rate: h2o rule 14, 15, 4e-06, h2o +composition rate: h2o rule 15, 16, 3e-06, h2o +composition rate: h2o rule 16, 17, 2.8999999999999998e-06, h2o +composition rate: h2o rule 17, 18, 2.75e-06, h2o +composition rate: h2o rule 18, 19, 2.6e-06, h2o +composition rate: h2o rule 19, 20, 2.6e-06, h2o +composition rate: h2o rule 20, 21, 2.6499999999999996e-06, h2o +composition rate: h2o rule 21, 22, 2.8e-06, h2o +composition rate: h2o rule 22, 23, 2.8999999999999998e-06, h2o +composition rate: h2o rule 23, 24, 3.2e-06, h2o +composition rate: h2o rule 24, 25, 3.25e-06, h2o +composition rate: h2o rule 25, 27.6, 3.6e-06, h2o +composition rate: h2o rule 26, 30, 4e-06, h2o +composition rate: h2o rule 27, 32.6, 4.2999999999999995e-06, h2o +composition rate: h2o rule 28, 35, 4.599999999999999e-06, h2o +composition rate: h2o rule 29, 37.5, 4.9000000000000005e-06, h2o +composition rate: h2o rule 30, 40, 5.2e-06, h2o +composition rate: h2o rule 31, 42.5, 5.5e-06, h2o +composition rate: h2o rule 32, 45, 5.7e-06, h2o +composition rate: h2o rule 33, 47.5, 5.9e-06, h2o +composition rate: h2o rule 34, 50, 6e-06, h2o +composition rate: h2o rule 35, 55, 6e-06, h2o +composition rate: h2o rule 36, 60, 6e-06, h2o +composition rate: h2o rule 37, 65, 5.4e-06, h2o +composition rate: h2o rule 38, 70, 4.5e-06, h2o +composition rate: h2o rule 39, 75, 3.2999999999999997e-06, h2o +composition rate: h2o rule 40, 80, 2.1e-06, h2o +composition rate: h2o rule 41, 85, 1.3e-06, h2o +composition rate: h2o rule 42, 90, 8.499999999999999e-07, h2o +composition rate: h2o rule 43, 95, 5.4e-07, h2o +composition rate: h2o rule 44, 100, 4e-07, h2o +composition rate: h2o rule 45, 105, 3.4000000000000003e-07, h2o +composition rate: h2o rule 46, 110, 2.8e-07, h2o +composition rate: h2o rule 47, 115, 2.4e-07, h2o +composition rate: h2o rule 48, 120, 2e-07, h2o + +# ch4 composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: ch4 rule 0, 1, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 1, 2, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 2, 3, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 3, 4, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 4, 5, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 5, 6, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 6, 7, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 7, 8, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 8, 9, 1.69e-06, ch4 +composition rate: ch4 rule 9, 10, 1.69e-06, ch4 +composition rate: ch4 rule 10, 11, 1.6799999999999998e-06, ch4 +composition rate: ch4 rule 11, 12, 1.6599999999999998e-06, ch4 +composition rate: ch4 rule 12, 13, 1.6499999999999999e-06, ch4 +composition rate: ch4 rule 13, 14, 1.6299999999999999e-06, ch4 +composition rate: ch4 rule 14, 15, 1.61e-06, ch4 +composition rate: ch4 rule 15, 16, 1.58e-06, ch4 +composition rate: ch4 rule 16, 17, 1.55e-06, ch4 +composition rate: ch4 rule 17, 18, 1.5199999999999998e-06, ch4 +composition rate: ch4 rule 18, 19, 1.48e-06, ch4 +composition rate: ch4 rule 19, 20, 1.42e-06, ch4 +composition rate: ch4 rule 20, 21, 1.3600000000000001e-06, ch4 +composition rate: ch4 rule 21, 22, 1.27e-06, ch4 +composition rate: ch4 rule 22, 23, 1.1899999999999998e-06, ch4 +composition rate: ch4 rule 23, 24, 1.12e-06, ch4 +composition rate: ch4 rule 24, 25, 1.06e-06, ch4 +composition rate: ch4 rule 25, 27.6, 9.87e-07, ch4 +composition rate: ch4 rule 26, 30, 9.14e-07, ch4 +composition rate: ch4 rule 27, 32.6, 8.299999999999999e-07, ch4 +composition rate: ch4 rule 28, 35, 7.459999999999999e-07, ch4 +composition rate: ch4 rule 29, 37.5, 6.62e-07, ch4 +composition rate: ch4 rule 30, 40, 5.639999999999999e-07, ch4 +composition rate: ch4 rule 31, 42.5, 4.61e-07, ch4 +composition rate: ch4 rule 32, 45, 3.6299999999999995e-07, ch4 +composition rate: ch4 rule 33, 47.5, 2.77e-07, ch4 +composition rate: ch4 rule 34, 50, 2.0999999999999997e-07, ch4 +composition rate: ch4 rule 35, 55, 1.65e-07, ch4 +composition rate: ch4 rule 36, 60, 1.5e-07, ch4 +composition rate: ch4 rule 37, 65, 1.5e-07, ch4 +composition rate: ch4 rule 38, 70, 1.5e-07, ch4 +composition rate: ch4 rule 39, 75, 1.5e-07, ch4 +composition rate: ch4 rule 40, 80, 1.5e-07, ch4 +composition rate: ch4 rule 41, 85, 1.5e-07, ch4 +composition rate: ch4 rule 42, 90, 1.4e-07, ch4 +composition rate: ch4 rule 43, 95, 1.3e-07, ch4 +composition rate: ch4 rule 44, 100, 1.2e-07, ch4 +composition rate: ch4 rule 45, 105, 1.0999999999999999e-07, ch4 +composition rate: ch4 rule 46, 110, 9.499999999999999e-08, ch4 +composition rate: ch4 rule 47, 115, 6e-08, ch4 +composition rate: ch4 rule 48, 120, 3e-08, ch4 + +# o3 composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: o3 rule 0, 1, 3.15e-08, o3 +composition rate: o3 rule 1, 2, 3.3399999999999995e-08, o3 +composition rate: o3 rule 2, 3, 3.5e-08, o3 +composition rate: o3 rule 3, 4, 3.56e-08, o3 +composition rate: o3 rule 4, 5, 3.7699999999999993e-08, o3 +composition rate: o3 rule 5, 6, 3.9899999999999993e-08, o3 +composition rate: o3 rule 6, 7, 4.22e-08, o3 +composition rate: o3 rule 7, 8, 4.4699999999999997e-08, o3 +composition rate: o3 rule 8, 9, 5e-08, o3 +composition rate: o3 rule 9, 10, 5.6e-08, o3 +composition rate: o3 rule 10, 11, 6.61e-08, o3 +composition rate: o3 rule 11, 12, 7.82e-08, o3 +composition rate: o3 rule 12, 13, 9.289999999999999e-08, o3 +composition rate: o3 rule 13, 14, 1.0499999999999999e-07, o3 +composition rate: o3 rule 14, 15, 1.26e-07, o3 +composition rate: o3 rule 15, 16, 1.44e-07, o3 +composition rate: o3 rule 16, 17, 2.5e-07, o3 +composition rate: o3 rule 17, 18, 5e-07, o3 +composition rate: o3 rule 18, 19, 9.499999999999999e-07, o3 +composition rate: o3 rule 19, 20, 1.4e-06, o3 +composition rate: o3 rule 20, 21, 1.8e-06, o3 +composition rate: o3 rule 21, 22, 2.4e-06, o3 +composition rate: o3 rule 22, 23, 3.3999999999999996e-06, o3 +composition rate: o3 rule 23, 24, 4.2999999999999995e-06, o3 +composition rate: o3 rule 24, 25, 5.4e-06, o3 +composition rate: o3 rule 25, 27.6, 7.8e-06, o3 +composition rate: o3 rule 26, 30, 9.3e-06, o3 +composition rate: o3 rule 27, 32.6, 9.849999999999999e-06, o3 +composition rate: o3 rule 28, 35, 9.699999999999999e-06, o3 +composition rate: o3 rule 29, 37.5, 8.8e-06, o3 +composition rate: o3 rule 30, 40, 7.499999999999999e-06, o3 +composition rate: o3 rule 31, 42.5, 5.9e-06, o3 +composition rate: o3 rule 32, 45, 4.5e-06, o3 +composition rate: o3 rule 33, 47.5, 3.45e-06, o3 +composition rate: o3 rule 34, 50, 2.8e-06, o3 +composition rate: o3 rule 35, 55, 1.8e-06, o3 +composition rate: o3 rule 36, 60, 1.1e-06, o3 +composition rate: o3 rule 37, 65, 6.5e-07, o3 +composition rate: o3 rule 38, 70, 3e-07, o3 +composition rate: o3 rule 39, 75, 1.8e-07, o3 +composition rate: o3 rule 40, 80, 3.3e-07, o3 +composition rate: o3 rule 41, 85, 5e-07, o3 +composition rate: o3 rule 42, 90, 5.2e-07, o3 +composition rate: o3 rule 43, 95, 5e-07, o3 +composition rate: o3 rule 44, 100, 4e-07, o3 +composition rate: o3 rule 45, 105, 2e-07, o3 +composition rate: o3 rule 46, 110, 5e-08, o3 +composition rate: o3 rule 47, 115, 5e-09, o3 +composition rate: o3 rule 48, 120, 5e-10, o3 + +# n2o composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: n2o rule 0, 1, 3.2e-07, n2o +composition rate: n2o rule 1, 2, 3.2e-07, n2o +composition rate: n2o rule 2, 3, 3.2e-07, n2o +composition rate: n2o rule 3, 4, 3.2e-07, n2o +composition rate: n2o rule 4, 5, 3.2e-07, n2o +composition rate: n2o rule 5, 6, 3.2e-07, n2o +composition rate: n2o rule 6, 7, 3.2e-07, n2o +composition rate: n2o rule 7, 8, 3.2e-07, n2o +composition rate: n2o rule 8, 9, 3.2e-07, n2o +composition rate: n2o rule 9, 10, 3.18e-07, n2o +composition rate: n2o rule 10, 11, 3.14e-07, n2o +composition rate: n2o rule 11, 12, 3.1e-07, n2o +composition rate: n2o rule 12, 13, 3.05e-07, n2o +composition rate: n2o rule 13, 14, 3e-07, n2o +composition rate: n2o rule 14, 15, 2.9399999999999996e-07, n2o +composition rate: n2o rule 15, 16, 2.88e-07, n2o +composition rate: n2o rule 16, 17, 2.7800000000000003e-07, n2o +composition rate: n2o rule 17, 18, 2.67e-07, n2o +composition rate: n2o rule 18, 19, 2.53e-07, n2o +composition rate: n2o rule 19, 20, 2.3699999999999996e-07, n2o +composition rate: n2o rule 20, 21, 2.19e-07, n2o +composition rate: n2o rule 21, 22, 2.0499999999999997e-07, n2o +composition rate: n2o rule 22, 23, 1.97e-07, n2o +composition rate: n2o rule 23, 24, 1.88e-07, n2o +composition rate: n2o rule 24, 25, 1.76e-07, n2o +composition rate: n2o rule 25, 27.6, 1.59e-07, n2o +composition rate: n2o rule 26, 30, 1.4199999999999997e-07, n2o +composition rate: n2o rule 27, 32.6, 1.17e-07, n2o +composition rate: n2o rule 28, 35, 9.279999999999998e-08, n2o +composition rate: n2o rule 29, 37.5, 6.69e-08, n2o +composition rate: n2o rule 30, 40, 4.51e-08, n2o +composition rate: n2o rule 31, 42.5, 2.7499999999999998e-08, n2o +composition rate: n2o rule 32, 45, 1.59e-08, n2o +composition rate: n2o rule 33, 47.5, 9.379999999999999e-09, n2o +composition rate: n2o rule 34, 50, 4.7499999999999995e-09, n2o +composition rate: n2o rule 35, 55, 3e-09, n2o +composition rate: n2o rule 36, 60, 2.0699999999999997e-09, n2o +composition rate: n2o rule 37, 65, 1.51e-09, n2o +composition rate: n2o rule 38, 70, 1.15e-09, n2o +composition rate: n2o rule 39, 75, 8.89e-10, n2o +composition rate: n2o rule 40, 80, 7.06e-10, n2o +composition rate: n2o rule 41, 85, 5.72e-10, n2o +composition rate: n2o rule 42, 90, 4.71e-10, n2o +composition rate: n2o rule 43, 95, 3.93e-10, n2o +composition rate: n2o rule 44, 100, 3.32e-10, n2o +composition rate: n2o rule 45, 105, 2.84e-10, n2o +composition rate: n2o rule 46, 110, 2.44e-10, n2o +composition rate: n2o rule 47, 115, 2.12e-10, n2o +composition rate: n2o rule 48, 120, 1.8499999999999998e-10, n2o + +# co composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: co rule 0, 1, 1.45e-07, co +composition rate: co rule 1, 2, 1.4e-07, co +composition rate: co rule 2, 3, 1.35e-07, co +composition rate: co rule 3, 4, 1.31e-07, co +composition rate: co rule 4, 5, 1.3e-07, co +composition rate: co rule 5, 6, 1.29e-07, co +composition rate: co rule 6, 7, 1.25e-07, co +composition rate: co rule 7, 8, 1.19e-07, co +composition rate: co rule 8, 9, 1.09e-07, co +composition rate: co rule 9, 10, 9.959999999999999e-08, co +composition rate: co rule 10, 11, 8.96e-08, co +composition rate: co rule 11, 12, 7.81e-08, co +composition rate: co rule 12, 13, 6.370000000000001e-08, co +composition rate: co rule 13, 14, 5.0299999999999994e-08, co +composition rate: co rule 14, 15, 3.9399999999999995e-08, co +composition rate: co rule 15, 16, 3.07e-08, co +composition rate: co rule 16, 17, 2.4899999999999998e-08, co +composition rate: co rule 17, 18, 1.9699999999999998e-08, co +composition rate: co rule 18, 19, 1.55e-08, co +composition rate: co rule 19, 20, 1.3299999999999998e-08, co +composition rate: co rule 20, 21, 1.23e-08, co +composition rate: co rule 21, 22, 1.23e-08, co +composition rate: co rule 22, 23, 1.31e-08, co +composition rate: co rule 23, 24, 1.4e-08, co +composition rate: co rule 24, 25, 1.5e-08, co +composition rate: co rule 25, 27.6, 1.6e-08, co +composition rate: co rule 26, 30, 1.71e-08, co +composition rate: co rule 27, 32.6, 1.8499999999999997e-08, co +composition rate: co rule 28, 35, 2e-08, co +composition rate: co rule 29, 37.5, 2.1499999999999997e-08, co +composition rate: co rule 30, 40, 2.33e-08, co +composition rate: co rule 31, 42.5, 2.63e-08, co +composition rate: co rule 32, 45, 3.0599999999999996e-08, co +composition rate: co rule 33, 47.5, 3.7999999999999996e-08, co +composition rate: co rule 34, 50, 6.25e-08, co +composition rate: co rule 35, 55, 1.4799999999999998e-07, co +composition rate: co rule 36, 60, 2.93e-07, co +composition rate: co rule 37, 65, 5.590000000000001e-07, co +composition rate: co rule 38, 70, 1.08e-06, co +composition rate: co rule 39, 75, 1.8999999999999998e-06, co +composition rate: co rule 40, 80, 2.96e-06, co +composition rate: co rule 41, 85, 4.53e-06, co +composition rate: co rule 42, 90, 6.86e-06, co +composition rate: co rule 43, 95, 1.05e-05, co +composition rate: co rule 44, 100, 1.7100000000000002e-05, co +composition rate: co rule 45, 105, 2.4699999999999997e-05, co +composition rate: co rule 46, 110, 3.36e-05, co +composition rate: co rule 47, 115, 4.15e-05, co +composition rate: co rule 48, 120, 4.9999999999999996e-05, co diff --git a/tropical.pyr b/tropical.pyr new file mode 100644 index 0000000..b0128b9 --- /dev/null +++ b/tropical.pyr @@ -0,0 +1,329 @@ +# atm profile for tropical + +# surface values (pressure, temperature, final height, initial layer thickness, acceleration of gravity, range min, range max) +surface: 1010.0, 299.7, 120, 100, 9.8, 100, 2500 + +# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile +# except for co2, o2, n2, and ar +molecule: co2, .000287 +molecule: h2o, 0.0259 +molecule: o2, .20 +molecule: n2, .77 +molecule: ar, .009 +molecule: ch4, 1.6999999999999998e-06 +molecule: o3, 2.9699999999999998e-08 +molecule: n2o, 3.2e-07 +molecule: co, 1.5e-07 + +# lapse rate profile +# rules are: name, final height, final value +# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule) +lapse rate: lapse rule 0, 1, 293.7 +lapse rate: lapse rule 1, 2, 287.7 +lapse rate: lapse rule 2, 3, 283.7 +lapse rate: lapse rule 3, 4, 277 +lapse rate: lapse rule 4, 5, 270.3 +lapse rate: lapse rule 5, 6, 263.6 +lapse rate: lapse rule 6, 7, 257 +lapse rate: lapse rule 7, 8, 250.3 +lapse rate: lapse rule 8, 9, 243.6 +lapse rate: lapse rule 9, 10, 237 +lapse rate: lapse rule 10, 11, 230.1 +lapse rate: lapse rule 11, 12, 223.6 +lapse rate: lapse rule 12, 13, 217 +lapse rate: lapse rule 13, 14, 210.3 +lapse rate: lapse rule 14, 15, 203.7 +lapse rate: lapse rule 15, 16, 197 +lapse rate: lapse rule 16, 17, 164.8 +lapse rate: lapse rule 17, 18, 168.8 +lapse rate: lapse rule 18, 19, 202.7 +lapse rate: lapse rule 19, 20, 206.7 +lapse rate: lapse rule 20, 21, 210.7 +lapse rate: lapse rule 21, 22, 214.6 +lapse rate: lapse rule 22, 23, 217 +lapse rate: lapse rule 23, 24, 219.2 +lapse rate: lapse rule 24, 25, 221.4 +lapse rate: lapse rule 25, 27.6, 227 +lapse rate: lapse rule 26, 30, 232.3 +lapse rate: lapse rule 27, 32.6, 237.7 +lapse rate: lapse rule 28, 35, 243.1 +lapse rate: lapse rule 29, 37.5, 248.5 +lapse rate: lapse rule 30, 40, 254 +lapse rate: lapse rule 31, 42.5, 259.4 +lapse rate: lapse rule 32, 45, 264.8 +lapse rate: lapse rule 33, 47.5, 269.6 +lapse rate: lapse rule 34, 50, 270.2 +lapse rate: lapse rule 35, 55, 263.4 +lapse rate: lapse rule 36, 60, 253.1 +lapse rate: lapse rule 37, 65, 236 +lapse rate: lapse rule 38, 70, 218.9 +lapse rate: lapse rule 39, 75, 201.8 +lapse rate: lapse rule 40, 80, 184.8 +lapse rate: lapse rule 41, 85, 177.1 +lapse rate: lapse rule 42, 90, 177 +lapse rate: lapse rule 43, 95, 184.3 +lapse rate: lapse rule 44, 100, 190.7 +lapse rate: lapse rule 45, 105, 212 +lapse rate: lapse rule 46, 110, 241.6 +lapse rate: lapse rule 47, 115, 299.7 +lapse rate: lapse rule 48, 120, 380 + +# h2o composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: h2o rule 0, 1, 0.012499999999999999, h2o +composition rate: h2o rule 1, 2, 0.0153, h2o +composition rate: h2o rule 2, 3, 0.0086, h2o +composition rate: h2o rule 3, 4, 0.0044399999999999995, h2o +composition rate: h2o rule 4, 5, 0.0033499999999999997, h2o +composition rate: h2o rule 5, 6, 0.0021, h2o +composition rate: h2o rule 6, 7, 0.00129, h2o +composition rate: h2o rule 7, 8, 0.0007639999999999999, h2o +composition rate: h2o rule 8, 9, 0.00041, h2o +composition rate: h2o rule 9, 10, 0.00019099999999999998, h2o +composition rate: h2o rule 10, 11, 7.309999999999999e-05, h2o +composition rate: h2o rule 11, 12, 2.91e-05, h2o +composition rate: h2o rule 12, 13, 9e-06, h2o +composition rate: h2o rule 13, 14, 6.22e-06, h2o +composition rate: h2o rule 14, 15, 4e-06, h2o +composition rate: h2o rule 15, 16, 3e-06, h2o +composition rate: h2o rule 16, 17, 2.8999999999999998e-06, h2o +composition rate: h2o rule 17, 18, 2.75e-06, h2o +composition rate: h2o rule 18, 19, 2.6e-06, h2o +composition rate: h2o rule 19, 20, 2.6e-06, h2o +composition rate: h2o rule 20, 21, 2.6499999999999996e-06, h2o +composition rate: h2o rule 21, 22, 2.8e-06, h2o +composition rate: h2o rule 22, 23, 2.8999999999999998e-06, h2o +composition rate: h2o rule 23, 24, 3.2e-06, h2o +composition rate: h2o rule 24, 25, 3.25e-06, h2o +composition rate: h2o rule 25, 27.6, 3.6e-06, h2o +composition rate: h2o rule 26, 30, 4e-06, h2o +composition rate: h2o rule 27, 32.6, 4.2999999999999995e-06, h2o +composition rate: h2o rule 28, 35, 4.599999999999999e-06, h2o +composition rate: h2o rule 29, 37.5, 4.9000000000000005e-06, h2o +composition rate: h2o rule 30, 40, 5.2e-06, h2o +composition rate: h2o rule 31, 42.5, 5.5e-06, h2o +composition rate: h2o rule 32, 45, 5.7e-06, h2o +composition rate: h2o rule 33, 47.5, 5.9e-06, h2o +composition rate: h2o rule 34, 50, 6e-06, h2o +composition rate: h2o rule 35, 55, 6e-06, h2o +composition rate: h2o rule 36, 60, 6e-06, h2o +composition rate: h2o rule 37, 65, 5.4e-06, h2o +composition rate: h2o rule 38, 70, 4.5e-06, h2o +composition rate: h2o rule 39, 75, 3.2999999999999997e-06, h2o +composition rate: h2o rule 40, 80, 2.1e-06, h2o +composition rate: h2o rule 41, 85, 1.3e-06, h2o +composition rate: h2o rule 42, 90, 8.499999999999999e-07, h2o +composition rate: h2o rule 43, 95, 5.4e-07, h2o +composition rate: h2o rule 44, 100, 4e-07, h2o +composition rate: h2o rule 45, 105, 3.4000000000000003e-07, h2o +composition rate: h2o rule 46, 110, 2.8e-07, h2o +composition rate: h2o rule 47, 115, 2.4e-07, h2o +composition rate: h2o rule 48, 120, 2e-07, h2o + +# ch4 composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: ch4 rule 0, 1, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 1, 2, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 2, 3, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 3, 4, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 4, 5, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 5, 6, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 6, 7, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 7, 8, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 8, 9, 1.69e-06, ch4 +composition rate: ch4 rule 9, 10, 1.69e-06, ch4 +composition rate: ch4 rule 10, 11, 1.6799999999999998e-06, ch4 +composition rate: ch4 rule 11, 12, 1.6599999999999998e-06, ch4 +composition rate: ch4 rule 12, 13, 1.6499999999999999e-06, ch4 +composition rate: ch4 rule 13, 14, 1.6299999999999999e-06, ch4 +composition rate: ch4 rule 14, 15, 1.61e-06, ch4 +composition rate: ch4 rule 15, 16, 1.58e-06, ch4 +composition rate: ch4 rule 16, 17, 1.55e-06, ch4 +composition rate: ch4 rule 17, 18, 1.5199999999999998e-06, ch4 +composition rate: ch4 rule 18, 19, 1.48e-06, ch4 +composition rate: ch4 rule 19, 20, 1.42e-06, ch4 +composition rate: ch4 rule 20, 21, 1.3600000000000001e-06, ch4 +composition rate: ch4 rule 21, 22, 1.27e-06, ch4 +composition rate: ch4 rule 22, 23, 1.1899999999999998e-06, ch4 +composition rate: ch4 rule 23, 24, 1.12e-06, ch4 +composition rate: ch4 rule 24, 25, 1.06e-06, ch4 +composition rate: ch4 rule 25, 27.6, 9.87e-07, ch4 +composition rate: ch4 rule 26, 30, 9.14e-07, ch4 +composition rate: ch4 rule 27, 32.6, 8.299999999999999e-07, ch4 +composition rate: ch4 rule 28, 35, 7.459999999999999e-07, ch4 +composition rate: ch4 rule 29, 37.5, 6.62e-07, ch4 +composition rate: ch4 rule 30, 40, 5.639999999999999e-07, ch4 +composition rate: ch4 rule 31, 42.5, 4.61e-07, ch4 +composition rate: ch4 rule 32, 45, 3.6299999999999995e-07, ch4 +composition rate: ch4 rule 33, 47.5, 2.77e-07, ch4 +composition rate: ch4 rule 34, 50, 2.0999999999999997e-07, ch4 +composition rate: ch4 rule 35, 55, 1.65e-07, ch4 +composition rate: ch4 rule 36, 60, 1.5e-07, ch4 +composition rate: ch4 rule 37, 65, 1.5e-07, ch4 +composition rate: ch4 rule 38, 70, 1.5e-07, ch4 +composition rate: ch4 rule 39, 75, 1.5e-07, ch4 +composition rate: ch4 rule 40, 80, 1.5e-07, ch4 +composition rate: ch4 rule 41, 85, 1.5e-07, ch4 +composition rate: ch4 rule 42, 90, 1.4e-07, ch4 +composition rate: ch4 rule 43, 95, 1.3e-07, ch4 +composition rate: ch4 rule 44, 100, 1.2e-07, ch4 +composition rate: ch4 rule 45, 105, 1.0999999999999999e-07, ch4 +composition rate: ch4 rule 46, 110, 9.499999999999999e-08, ch4 +composition rate: ch4 rule 47, 115, 6e-08, ch4 +composition rate: ch4 rule 48, 120, 3e-08, ch4 + +# o3 composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: o3 rule 0, 1, 3.15e-08, o3 +composition rate: o3 rule 1, 2, 3.3399999999999995e-08, o3 +composition rate: o3 rule 2, 3, 3.5e-08, o3 +composition rate: o3 rule 3, 4, 3.56e-08, o3 +composition rate: o3 rule 4, 5, 3.7699999999999993e-08, o3 +composition rate: o3 rule 5, 6, 3.9899999999999993e-08, o3 +composition rate: o3 rule 6, 7, 4.22e-08, o3 +composition rate: o3 rule 7, 8, 4.4699999999999997e-08, o3 +composition rate: o3 rule 8, 9, 5e-08, o3 +composition rate: o3 rule 9, 10, 5.6e-08, o3 +composition rate: o3 rule 10, 11, 6.61e-08, o3 +composition rate: o3 rule 11, 12, 7.82e-08, o3 +composition rate: o3 rule 12, 13, 9.289999999999999e-08, o3 +composition rate: o3 rule 13, 14, 1.0499999999999999e-07, o3 +composition rate: o3 rule 14, 15, 1.26e-07, o3 +composition rate: o3 rule 15, 16, 1.44e-07, o3 +composition rate: o3 rule 16, 17, 2.5e-07, o3 +composition rate: o3 rule 17, 18, 5e-07, o3 +composition rate: o3 rule 18, 19, 9.499999999999999e-07, o3 +composition rate: o3 rule 19, 20, 1.4e-06, o3 +composition rate: o3 rule 20, 21, 1.8e-06, o3 +composition rate: o3 rule 21, 22, 2.4e-06, o3 +composition rate: o3 rule 22, 23, 3.3999999999999996e-06, o3 +composition rate: o3 rule 23, 24, 4.2999999999999995e-06, o3 +composition rate: o3 rule 24, 25, 5.4e-06, o3 +composition rate: o3 rule 25, 27.6, 7.8e-06, o3 +composition rate: o3 rule 26, 30, 9.3e-06, o3 +composition rate: o3 rule 27, 32.6, 9.849999999999999e-06, o3 +composition rate: o3 rule 28, 35, 9.699999999999999e-06, o3 +composition rate: o3 rule 29, 37.5, 8.8e-06, o3 +composition rate: o3 rule 30, 40, 7.499999999999999e-06, o3 +composition rate: o3 rule 31, 42.5, 5.9e-06, o3 +composition rate: o3 rule 32, 45, 4.5e-06, o3 +composition rate: o3 rule 33, 47.5, 3.45e-06, o3 +composition rate: o3 rule 34, 50, 2.8e-06, o3 +composition rate: o3 rule 35, 55, 1.8e-06, o3 +composition rate: o3 rule 36, 60, 1.1e-06, o3 +composition rate: o3 rule 37, 65, 6.5e-07, o3 +composition rate: o3 rule 38, 70, 3e-07, o3 +composition rate: o3 rule 39, 75, 1.8e-07, o3 +composition rate: o3 rule 40, 80, 3.3e-07, o3 +composition rate: o3 rule 41, 85, 5e-07, o3 +composition rate: o3 rule 42, 90, 5.2e-07, o3 +composition rate: o3 rule 43, 95, 5e-07, o3 +composition rate: o3 rule 44, 100, 4e-07, o3 +composition rate: o3 rule 45, 105, 2e-07, o3 +composition rate: o3 rule 46, 110, 5e-08, o3 +composition rate: o3 rule 47, 115, 5e-09, o3 +composition rate: o3 rule 48, 120, 5e-10, o3 + +# n2o composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: n2o rule 0, 1, 3.2e-07, n2o +composition rate: n2o rule 1, 2, 3.2e-07, n2o +composition rate: n2o rule 2, 3, 3.2e-07, n2o +composition rate: n2o rule 3, 4, 3.2e-07, n2o +composition rate: n2o rule 4, 5, 3.2e-07, n2o +composition rate: n2o rule 5, 6, 3.2e-07, n2o +composition rate: n2o rule 6, 7, 3.2e-07, n2o +composition rate: n2o rule 7, 8, 3.2e-07, n2o +composition rate: n2o rule 8, 9, 3.2e-07, n2o +composition rate: n2o rule 9, 10, 3.18e-07, n2o +composition rate: n2o rule 10, 11, 3.14e-07, n2o +composition rate: n2o rule 11, 12, 3.1e-07, n2o +composition rate: n2o rule 12, 13, 3.05e-07, n2o +composition rate: n2o rule 13, 14, 3e-07, n2o +composition rate: n2o rule 14, 15, 2.9399999999999996e-07, n2o +composition rate: n2o rule 15, 16, 2.88e-07, n2o +composition rate: n2o rule 16, 17, 2.7800000000000003e-07, n2o +composition rate: n2o rule 17, 18, 2.67e-07, n2o +composition rate: n2o rule 18, 19, 2.53e-07, n2o +composition rate: n2o rule 19, 20, 2.3699999999999996e-07, n2o +composition rate: n2o rule 20, 21, 2.19e-07, n2o +composition rate: n2o rule 21, 22, 2.0499999999999997e-07, n2o +composition rate: n2o rule 22, 23, 1.97e-07, n2o +composition rate: n2o rule 23, 24, 1.88e-07, n2o +composition rate: n2o rule 24, 25, 1.76e-07, n2o +composition rate: n2o rule 25, 27.6, 1.59e-07, n2o +composition rate: n2o rule 26, 30, 1.4199999999999997e-07, n2o +composition rate: n2o rule 27, 32.6, 1.17e-07, n2o +composition rate: n2o rule 28, 35, 9.279999999999998e-08, n2o +composition rate: n2o rule 29, 37.5, 6.69e-08, n2o +composition rate: n2o rule 30, 40, 4.51e-08, n2o +composition rate: n2o rule 31, 42.5, 2.7499999999999998e-08, n2o +composition rate: n2o rule 32, 45, 1.59e-08, n2o +composition rate: n2o rule 33, 47.5, 9.379999999999999e-09, n2o +composition rate: n2o rule 34, 50, 4.7499999999999995e-09, n2o +composition rate: n2o rule 35, 55, 3e-09, n2o +composition rate: n2o rule 36, 60, 2.0699999999999997e-09, n2o +composition rate: n2o rule 37, 65, 1.51e-09, n2o +composition rate: n2o rule 38, 70, 1.15e-09, n2o +composition rate: n2o rule 39, 75, 8.89e-10, n2o +composition rate: n2o rule 40, 80, 7.06e-10, n2o +composition rate: n2o rule 41, 85, 5.72e-10, n2o +composition rate: n2o rule 42, 90, 4.71e-10, n2o +composition rate: n2o rule 43, 95, 3.93e-10, n2o +composition rate: n2o rule 44, 100, 3.32e-10, n2o +composition rate: n2o rule 45, 105, 2.84e-10, n2o +composition rate: n2o rule 46, 110, 2.44e-10, n2o +composition rate: n2o rule 47, 115, 2.12e-10, n2o +composition rate: n2o rule 48, 120, 1.8499999999999998e-10, n2o + +# co composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: co rule 0, 1, 1.45e-07, co +composition rate: co rule 1, 2, 1.4e-07, co +composition rate: co rule 2, 3, 1.35e-07, co +composition rate: co rule 3, 4, 1.31e-07, co +composition rate: co rule 4, 5, 1.3e-07, co +composition rate: co rule 5, 6, 1.29e-07, co +composition rate: co rule 6, 7, 1.25e-07, co +composition rate: co rule 7, 8, 1.19e-07, co +composition rate: co rule 8, 9, 1.09e-07, co +composition rate: co rule 9, 10, 9.959999999999999e-08, co +composition rate: co rule 10, 11, 8.96e-08, co +composition rate: co rule 11, 12, 7.81e-08, co +composition rate: co rule 12, 13, 6.370000000000001e-08, co +composition rate: co rule 13, 14, 5.0299999999999994e-08, co +composition rate: co rule 14, 15, 3.9399999999999995e-08, co +composition rate: co rule 15, 16, 3.07e-08, co +composition rate: co rule 16, 17, 2.4899999999999998e-08, co +composition rate: co rule 17, 18, 1.9699999999999998e-08, co +composition rate: co rule 18, 19, 1.55e-08, co +composition rate: co rule 19, 20, 1.3299999999999998e-08, co +composition rate: co rule 20, 21, 1.23e-08, co +composition rate: co rule 21, 22, 1.23e-08, co +composition rate: co rule 22, 23, 1.31e-08, co +composition rate: co rule 23, 24, 1.4e-08, co +composition rate: co rule 24, 25, 1.5e-08, co +composition rate: co rule 25, 27.6, 1.6e-08, co +composition rate: co rule 26, 30, 1.71e-08, co +composition rate: co rule 27, 32.6, 1.8499999999999997e-08, co +composition rate: co rule 28, 35, 2e-08, co +composition rate: co rule 29, 37.5, 2.1499999999999997e-08, co +composition rate: co rule 30, 40, 2.33e-08, co +composition rate: co rule 31, 42.5, 2.63e-08, co +composition rate: co rule 32, 45, 3.0599999999999996e-08, co +composition rate: co rule 33, 47.5, 3.7999999999999996e-08, co +composition rate: co rule 34, 50, 6.25e-08, co +composition rate: co rule 35, 55, 1.4799999999999998e-07, co +composition rate: co rule 36, 60, 2.93e-07, co +composition rate: co rule 37, 65, 5.590000000000001e-07, co +composition rate: co rule 38, 70, 1.08e-06, co +composition rate: co rule 39, 75, 1.8999999999999998e-06, co +composition rate: co rule 40, 80, 2.96e-06, co +composition rate: co rule 41, 85, 4.53e-06, co +composition rate: co rule 42, 90, 6.86e-06, co +composition rate: co rule 43, 95, 1.05e-05, co +composition rate: co rule 44, 100, 1.7100000000000002e-05, co +composition rate: co rule 45, 105, 2.4699999999999997e-05, co +composition rate: co rule 46, 110, 3.36e-05, co +composition rate: co rule 47, 115, 4.15e-05, co +composition rate: co rule 48, 120, 4.9999999999999996e-05, co diff --git a/us standard.pyr b/us standard.pyr new file mode 100644 index 0000000..0a8e91e --- /dev/null +++ b/us standard.pyr @@ -0,0 +1,329 @@ +# atm profile for us standard + +# surface values (pressure, temperature, final height, initial layer thickness, acceleration of gravity, range min, range max) +surface: 1010.0, 288.2, 120, 100, 9.8, 100, 2500 + +# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile +# except for co2, o2, n2, and ar +molecule: co2, .000287 +molecule: h2o, 0.00775 +molecule: o2, .20 +molecule: n2, .77 +molecule: ar, .009 +molecule: ch4, 1.6999999999999998e-06 +molecule: o3, 2.6599999999999997e-08 +molecule: n2o, 3.1e-07 +molecule: co, 1.5e-07 + +# lapse rate profile +# rules are: name, final height, final value +# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule) +lapse rate: lapse rule 0, 1, 281.7 +lapse rate: lapse rule 1, 2, 275.2 +lapse rate: lapse rule 2, 3, 268.7 +lapse rate: lapse rule 3, 4, 262.2 +lapse rate: lapse rule 4, 5, 255.7 +lapse rate: lapse rule 5, 6, 249.2 +lapse rate: lapse rule 6, 7, 242.7 +lapse rate: lapse rule 7, 8, 236.2 +lapse rate: lapse rule 8, 9, 229.7 +lapse rate: lapse rule 9, 10, 223.3 +lapse rate: lapse rule 10, 11, 216.8 +lapse rate: lapse rule 11, 12, 216.7 +lapse rate: lapse rule 12, 13, 216.7 +lapse rate: lapse rule 13, 14, 216.7 +lapse rate: lapse rule 14, 15, 216.7 +lapse rate: lapse rule 15, 16, 216.7 +lapse rate: lapse rule 16, 17, 216.7 +lapse rate: lapse rule 17, 18, 216.7 +lapse rate: lapse rule 18, 19, 216.7 +lapse rate: lapse rule 19, 20, 216.7 +lapse rate: lapse rule 20, 21, 217.6 +lapse rate: lapse rule 21, 22, 218.6 +lapse rate: lapse rule 22, 23, 219.6 +lapse rate: lapse rule 23, 24, 220.6 +lapse rate: lapse rule 24, 25, 221.6 +lapse rate: lapse rule 25, 27.6, 224 +lapse rate: lapse rule 26, 30, 226.5 +lapse rate: lapse rule 27, 32.6, 230 +lapse rate: lapse rule 28, 35, 236.5 +lapse rate: lapse rule 29, 37.5, 242.9 +lapse rate: lapse rule 30, 40, 250.4 +lapse rate: lapse rule 31, 42.5, 257.3 +lapse rate: lapse rule 32, 45, 264.2 +lapse rate: lapse rule 33, 47.5, 270.6 +lapse rate: lapse rule 34, 50, 270.7 +lapse rate: lapse rule 35, 55, 260.8 +lapse rate: lapse rule 36, 60, 247 +lapse rate: lapse rule 37, 65, 233.3 +lapse rate: lapse rule 38, 70, 219.6 +lapse rate: lapse rule 39, 75, 208.4 +lapse rate: lapse rule 40, 80, 198.6 +lapse rate: lapse rule 41, 85, 188.9 +lapse rate: lapse rule 42, 90, 186.9 +lapse rate: lapse rule 43, 95, 188.4 +lapse rate: lapse rule 44, 100, 195.1 +lapse rate: lapse rule 45, 105, 208.8 +lapse rate: lapse rule 46, 110, 240 +lapse rate: lapse rule 47, 115, 300 +lapse rate: lapse rule 48, 120, 360 + +# h2o composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: h2o rule 0, 1, 0.00507, h2o +composition rate: h2o rule 1, 2, 0.00463, h2o +composition rate: h2o rule 2, 3, 0.0031799999999999997, h2o +composition rate: h2o rule 3, 4, 0.00216, h2o +composition rate: h2o rule 4, 5, 0.0014, h2o +composition rate: h2o rule 5, 6, 0.0009249999999999999, h2o +composition rate: h2o rule 6, 7, 0.000572, h2o +composition rate: h2o rule 7, 8, 0.000367, h2o +composition rate: h2o rule 8, 9, 0.000158, h2o +composition rate: h2o rule 9, 10, 7e-05, h2o +composition rate: h2o rule 10, 11, 3.6099999999999997e-05, h2o +composition rate: h2o rule 11, 12, 1.91e-05, h2o +composition rate: h2o rule 12, 13, 1.09e-05, h2o +composition rate: h2o rule 13, 14, 5.929999999999999e-06, h2o +composition rate: h2o rule 14, 15, 4.9999999999999996e-06, h2o +composition rate: h2o rule 15, 16, 3.95e-06, h2o +composition rate: h2o rule 16, 17, 3.8499999999999996e-06, h2o +composition rate: h2o rule 17, 18, 3.83e-06, h2o +composition rate: h2o rule 18, 19, 3.8499999999999996e-06, h2o +composition rate: h2o rule 19, 20, 3.9e-06, h2o +composition rate: h2o rule 20, 21, 3.98e-06, h2o +composition rate: h2o rule 21, 22, 4.07e-06, h2o +composition rate: h2o rule 22, 23, 4.2e-06, h2o +composition rate: h2o rule 23, 24, 4.2999999999999995e-06, h2o +composition rate: h2o rule 24, 25, 4.43e-06, h2o +composition rate: h2o rule 25, 27.6, 4.58e-06, h2o +composition rate: h2o rule 26, 30, 4.7300000000000005e-06, h2o +composition rate: h2o rule 27, 32.6, 4.8299999999999995e-06, h2o +composition rate: h2o rule 28, 35, 4.9000000000000005e-06, h2o +composition rate: h2o rule 29, 37.5, 4.95e-06, h2o +composition rate: h2o rule 30, 40, 5.03e-06, h2o +composition rate: h2o rule 31, 42.5, 5.15e-06, h2o +composition rate: h2o rule 32, 45, 5.23e-06, h2o +composition rate: h2o rule 33, 47.5, 5.25e-06, h2o +composition rate: h2o rule 34, 50, 5.23e-06, h2o +composition rate: h2o rule 35, 55, 5.0999999999999995e-06, h2o +composition rate: h2o rule 36, 60, 4.749999999999999e-06, h2o +composition rate: h2o rule 37, 65, 4.2e-06, h2o +composition rate: h2o rule 38, 70, 3.5e-06, h2o +composition rate: h2o rule 39, 75, 2.83e-06, h2o +composition rate: h2o rule 40, 80, 2.05e-06, h2o +composition rate: h2o rule 41, 85, 1.33e-06, h2o +composition rate: h2o rule 42, 90, 8.499999999999999e-07, h2o +composition rate: h2o rule 43, 95, 5.4e-07, h2o +composition rate: h2o rule 44, 100, 4e-07, h2o +composition rate: h2o rule 45, 105, 3.4000000000000003e-07, h2o +composition rate: h2o rule 46, 110, 2.8e-07, h2o +composition rate: h2o rule 47, 115, 2.4e-07, h2o +composition rate: h2o rule 48, 120, 2e-07, h2o + +# ch4 composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: ch4 rule 0, 1, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 1, 2, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 2, 3, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 3, 4, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 4, 5, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 5, 6, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 6, 7, 1.6999999999999998e-06, ch4 +composition rate: ch4 rule 7, 8, 1.69e-06, ch4 +composition rate: ch4 rule 8, 9, 1.69e-06, ch4 +composition rate: ch4 rule 9, 10, 1.6799999999999998e-06, ch4 +composition rate: ch4 rule 10, 11, 1.6599999999999998e-06, ch4 +composition rate: ch4 rule 11, 12, 1.6499999999999999e-06, ch4 +composition rate: ch4 rule 12, 13, 1.6299999999999999e-06, ch4 +composition rate: ch4 rule 13, 14, 1.61e-06, ch4 +composition rate: ch4 rule 14, 15, 1.58e-06, ch4 +composition rate: ch4 rule 15, 16, 1.55e-06, ch4 +composition rate: ch4 rule 16, 17, 1.5199999999999998e-06, ch4 +composition rate: ch4 rule 17, 18, 1.48e-06, ch4 +composition rate: ch4 rule 18, 19, 1.42e-06, ch4 +composition rate: ch4 rule 19, 20, 1.3600000000000001e-06, ch4 +composition rate: ch4 rule 20, 21, 1.27e-06, ch4 +composition rate: ch4 rule 21, 22, 1.1899999999999998e-06, ch4 +composition rate: ch4 rule 22, 23, 1.12e-06, ch4 +composition rate: ch4 rule 23, 24, 1.06e-06, ch4 +composition rate: ch4 rule 24, 25, 9.87e-07, ch4 +composition rate: ch4 rule 25, 27.6, 9.14e-07, ch4 +composition rate: ch4 rule 26, 30, 8.299999999999999e-07, ch4 +composition rate: ch4 rule 27, 32.6, 7.459999999999999e-07, ch4 +composition rate: ch4 rule 28, 35, 6.62e-07, ch4 +composition rate: ch4 rule 29, 37.5, 5.639999999999999e-07, ch4 +composition rate: ch4 rule 30, 40, 4.61e-07, ch4 +composition rate: ch4 rule 31, 42.5, 3.6299999999999995e-07, ch4 +composition rate: ch4 rule 32, 45, 2.77e-07, ch4 +composition rate: ch4 rule 33, 47.5, 2.0999999999999997e-07, ch4 +composition rate: ch4 rule 34, 50, 1.65e-07, ch4 +composition rate: ch4 rule 35, 55, 1.5e-07, ch4 +composition rate: ch4 rule 36, 60, 1.5e-07, ch4 +composition rate: ch4 rule 37, 65, 1.5e-07, ch4 +composition rate: ch4 rule 38, 70, 1.5e-07, ch4 +composition rate: ch4 rule 39, 75, 1.5e-07, ch4 +composition rate: ch4 rule 40, 80, 1.5e-07, ch4 +composition rate: ch4 rule 41, 85, 1.5e-07, ch4 +composition rate: ch4 rule 42, 90, 1.4e-07, ch4 +composition rate: ch4 rule 43, 95, 1.3e-07, ch4 +composition rate: ch4 rule 44, 100, 1.2e-07, ch4 +composition rate: ch4 rule 45, 105, 1.0999999999999999e-07, ch4 +composition rate: ch4 rule 46, 110, 9.499999999999999e-08, ch4 +composition rate: ch4 rule 47, 115, 6e-08, ch4 +composition rate: ch4 rule 48, 120, 3e-08, ch4 + +# o3 composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: o3 rule 0, 1, 2.9299999999999998e-08, o3 +composition rate: o3 rule 1, 2, 3.24e-08, o3 +composition rate: o3 rule 2, 3, 3.32e-08, o3 +composition rate: o3 rule 3, 4, 3.39e-08, o3 +composition rate: o3 rule 4, 5, 3.7699999999999993e-08, o3 +composition rate: o3 rule 5, 6, 4.11e-08, o3 +composition rate: o3 rule 6, 7, 5.01e-08, o3 +composition rate: o3 rule 7, 8, 5.97e-08, o3 +composition rate: o3 rule 8, 9, 9.17e-08, o3 +composition rate: o3 rule 9, 10, 1.31e-07, o3 +composition rate: o3 rule 10, 11, 2.1499999999999998e-07, o3 +composition rate: o3 rule 11, 12, 3.1e-07, o3 +composition rate: o3 rule 12, 13, 3.8499999999999997e-07, o3 +composition rate: o3 rule 13, 14, 5.03e-07, o3 +composition rate: o3 rule 14, 15, 6.51e-07, o3 +composition rate: o3 rule 15, 16, 8.699999999999999e-07, o3 +composition rate: o3 rule 16, 17, 1.1899999999999998e-06, o3 +composition rate: o3 rule 17, 18, 1.59e-06, o3 +composition rate: o3 rule 18, 19, 2.0299999999999996e-06, o3 +composition rate: o3 rule 19, 20, 2.58e-06, o3 +composition rate: o3 rule 20, 21, 3.03e-06, o3 +composition rate: o3 rule 21, 22, 3.6499999999999998e-06, o3 +composition rate: o3 rule 22, 23, 4.17e-06, o3 +composition rate: o3 rule 23, 24, 4.63e-06, o3 +composition rate: o3 rule 24, 25, 5.12e-06, o3 +composition rate: o3 rule 25, 27.6, 5.7999999999999995e-06, o3 +composition rate: o3 rule 26, 30, 6.549999999999999e-06, o3 +composition rate: o3 rule 27, 32.6, 7.37e-06, o3 +composition rate: o3 rule 28, 35, 7.84e-06, o3 +composition rate: o3 rule 29, 37.5, 7.8e-06, o3 +composition rate: o3 rule 30, 40, 7.2999999999999996e-06, o3 +composition rate: o3 rule 31, 42.5, 6.2e-06, o3 +composition rate: o3 rule 32, 45, 5.25e-06, o3 +composition rate: o3 rule 33, 47.5, 4.1e-06, o3 +composition rate: o3 rule 34, 50, 3.1e-06, o3 +composition rate: o3 rule 35, 55, 1.8e-06, o3 +composition rate: o3 rule 36, 60, 1.1e-06, o3 +composition rate: o3 rule 37, 65, 7e-07, o3 +composition rate: o3 rule 38, 70, 3e-07, o3 +composition rate: o3 rule 39, 75, 2.5e-07, o3 +composition rate: o3 rule 40, 80, 3e-07, o3 +composition rate: o3 rule 41, 85, 5e-07, o3 +composition rate: o3 rule 42, 90, 7e-07, o3 +composition rate: o3 rule 43, 95, 7e-07, o3 +composition rate: o3 rule 44, 100, 4e-07, o3 +composition rate: o3 rule 45, 105, 2e-07, o3 +composition rate: o3 rule 46, 110, 5e-08, o3 +composition rate: o3 rule 47, 115, 5e-09, o3 +composition rate: o3 rule 48, 120, 5e-10, o3 + +# n2o composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: n2o rule 0, 1, 3.1e-07, n2o +composition rate: n2o rule 1, 2, 3.1e-07, n2o +composition rate: n2o rule 2, 3, 3.1e-07, n2o +composition rate: n2o rule 3, 4, 3.08e-07, n2o +composition rate: n2o rule 4, 5, 3.02e-07, n2o +composition rate: n2o rule 5, 6, 2.9099999999999995e-07, n2o +composition rate: n2o rule 6, 7, 2.8199999999999996e-07, n2o +composition rate: n2o rule 7, 8, 2.7600000000000004e-07, n2o +composition rate: n2o rule 8, 9, 2.7e-07, n2o +composition rate: n2o rule 9, 10, 2.65e-07, n2o +composition rate: n2o rule 10, 11, 2.6e-07, n2o +composition rate: n2o rule 11, 12, 2.55e-07, n2o +composition rate: n2o rule 12, 13, 2.4899999999999997e-07, n2o +composition rate: n2o rule 13, 14, 2.43e-07, n2o +composition rate: n2o rule 14, 15, 2.3599999999999997e-07, n2o +composition rate: n2o rule 15, 16, 2.28e-07, n2o +composition rate: n2o rule 16, 17, 2.18e-07, n2o +composition rate: n2o rule 17, 18, 2.0399999999999997e-07, n2o +composition rate: n2o rule 18, 19, 1.82e-07, n2o +composition rate: n2o rule 19, 20, 1.57e-07, n2o +composition rate: n2o rule 20, 21, 1.35e-07, n2o +composition rate: n2o rule 21, 22, 1.2199999999999998e-07, n2o +composition rate: n2o rule 22, 23, 1.0999999999999999e-07, n2o +composition rate: n2o rule 23, 24, 9.889999999999999e-08, n2o +composition rate: n2o rule 24, 25, 8.78e-08, n2o +composition rate: n2o rule 25, 27.6, 7.33e-08, n2o +composition rate: n2o rule 26, 30, 5.9399999999999996e-08, n2o +composition rate: n2o rule 27, 32.6, 4.15e-08, n2o +composition rate: n2o rule 28, 35, 3.03e-08, n2o +composition rate: n2o rule 29, 37.5, 1.95e-08, n2o +composition rate: n2o rule 30, 40, 1.27e-08, n2o +composition rate: n2o rule 31, 42.5, 9e-09, n2o +composition rate: n2o rule 32, 45, 6.2899999999999996e-09, n2o +composition rate: n2o rule 33, 47.5, 4.56e-09, n2o +composition rate: n2o rule 34, 50, 2.8e-09, n2o +composition rate: n2o rule 35, 55, 1.77e-09, n2o +composition rate: n2o rule 36, 60, 1.21e-09, n2o +composition rate: n2o rule 37, 65, 8.869999999999999e-10, n2o +composition rate: n2o rule 38, 70, 6.759999999999999e-10, n2o +composition rate: n2o rule 39, 75, 5.539999999999999e-10, n2o +composition rate: n2o rule 40, 80, 4.65e-10, n2o +composition rate: n2o rule 41, 85, 3.98e-10, n2o +composition rate: n2o rule 42, 90, 3.05e-10, n2o +composition rate: n2o rule 43, 95, 2.7099999999999994e-10, n2o +composition rate: n2o rule 44, 100, 2.44e-10, n2o +composition rate: n2o rule 45, 105, 2.2099999999999999e-10, n2o +composition rate: n2o rule 46, 110, 2.02e-10, n2o +composition rate: n2o rule 47, 115, 1.8399999999999998e-10, n2o +composition rate: n2o rule 48, 120, 1.8499999999999998e-10, n2o + +# co composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: co rule 0, 1, 1.45e-07, co +composition rate: co rule 1, 2, 1.4e-07, co +composition rate: co rule 2, 3, 1.35e-07, co +composition rate: co rule 3, 4, 1.31e-07, co +composition rate: co rule 4, 5, 1.3e-07, co +composition rate: co rule 5, 6, 1.29e-07, co +composition rate: co rule 6, 7, 1.25e-07, co +composition rate: co rule 7, 8, 1.19e-07, co +composition rate: co rule 8, 9, 1.09e-07, co +composition rate: co rule 9, 10, 9.959999999999999e-08, co +composition rate: co rule 10, 11, 8.96e-08, co +composition rate: co rule 11, 12, 7.81e-08, co +composition rate: co rule 12, 13, 6.370000000000001e-08, co +composition rate: co rule 13, 14, 5.0299999999999994e-08, co +composition rate: co rule 14, 15, 3.9399999999999995e-08, co +composition rate: co rule 15, 16, 3.07e-08, co +composition rate: co rule 16, 17, 2.4899999999999998e-08, co +composition rate: co rule 17, 18, 1.9699999999999998e-08, co +composition rate: co rule 18, 19, 1.55e-08, co +composition rate: co rule 19, 20, 1.3299999999999998e-08, co +composition rate: co rule 20, 21, 1.23e-08, co +composition rate: co rule 21, 22, 1.23e-08, co +composition rate: co rule 22, 23, 1.31e-08, co +composition rate: co rule 23, 24, 1.4e-08, co +composition rate: co rule 24, 25, 1.5e-08, co +composition rate: co rule 25, 27.6, 1.6e-08, co +composition rate: co rule 26, 30, 1.71e-08, co +composition rate: co rule 27, 32.6, 1.8499999999999997e-08, co +composition rate: co rule 28, 35, 2.0099999999999998e-08, co +composition rate: co rule 29, 37.5, 2.22e-08, co +composition rate: co rule 30, 40, 2.5e-08, co +composition rate: co rule 31, 42.5, 2.8199999999999998e-08, co +composition rate: co rule 32, 45, 3.24e-08, co +composition rate: co rule 33, 47.5, 3.7199999999999996e-08, co +composition rate: co rule 34, 50, 4.5999999999999995e-08, co +composition rate: co rule 35, 55, 6.64e-08, co +composition rate: co rule 36, 60, 1.0699999999999999e-07, co +composition rate: co rule 37, 65, 1.86e-07, co +composition rate: co rule 38, 70, 3.0599999999999996e-07, co +composition rate: co rule 39, 75, 6.38e-07, co +composition rate: co rule 40, 80, 1.5e-06, co +composition rate: co rule 41, 85, 3.24e-06, co +composition rate: co rule 42, 90, 5.84e-06, co +composition rate: co rule 43, 95, 1.01e-05, co +composition rate: co rule 44, 100, 1.6899999999999997e-05, co +composition rate: co rule 45, 105, 2.4699999999999997e-05, co +composition rate: co rule 46, 110, 3.36e-05, co +composition rate: co rule 47, 115, 4.15e-05, co +composition rate: co rule 48, 120, 4.9999999999999996e-05, co diff --git a/venussimple.pyr b/venussimple.pyr index 01ab162..b4953bb 100644 --- a/venussimple.pyr +++ b/venussimple.pyr @@ -1,7 +1,7 @@ # A demo file for pyrad # mBar , K , km, m , g, cm-1,cm-1 -surface: 93000, 735, 200, 2, 8.87 +surface: 93000, 735, 200, 10, 8.87, 100, 2500 # mol text name, concentration molecule: co2, .965 From 96bb5585a14c87430080eaf0e7a31e3d06e3c371 Mon Sep 17 00:00:00 2001 From: brad schrag Date: Mon, 11 Feb 2019 20:33:19 -0600 Subject: [PATCH 39/43] adds more profiles --- collins 1a double pressure.pyr | 174 +++++++++++++++++++++++++++++++++ collins 4a thick.pyr | 174 +++++++++++++++++++++++++++++++++ pyradClasses.py | 6 +- trace gas ch4 0.pyr | 120 +++++++++++++++++++++++ trace gas ch4 8e-7.pyr | 120 +++++++++++++++++++++++ trace gas ch4 8e-8.pyr | 120 +++++++++++++++++++++++ venussimple.pyr | 2 +- 7 files changed, 712 insertions(+), 4 deletions(-) create mode 100644 collins 1a double pressure.pyr create mode 100644 collins 4a thick.pyr create mode 100644 trace gas ch4 0.pyr create mode 100644 trace gas ch4 8e-7.pyr create mode 100644 trace gas ch4 8e-8.pyr diff --git a/collins 1a double pressure.pyr b/collins 1a double pressure.pyr new file mode 100644 index 0000000..a9d41ae --- /dev/null +++ b/collins 1a double pressure.pyr @@ -0,0 +1,174 @@ +# atm profile for midlatitude summer + +# surface values (pressure, temperature, final height, initial layer thickness, acceleration of gravity, range min, range max) +surface: 2010.0, 294.2, 120, 250, 9.8, 100, 2500 + +# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile +# except for co2, o2, n2, and ar +molecule: co2, .000287 +molecule: h2o, 0.0186 +molecule: o2, .20 +molecule: n2, .77 +molecule: ar, .009 +#molecule: ch4, 1.6999999999999998e-06 +molecule: o3, 3.02e-08 +#molecule: n2o, 3.2e-07 +#molecule: co, 1.5e-07 + +# lapse rate profile +# rules are: name, final height, final value +# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule) +lapse rate: lapse rule 0, 1, 289.7 +lapse rate: lapse rule 1, 2, 295.2 +lapse rate: lapse rule 2, 3, 279.2 +lapse rate: lapse rule 3, 4, 273.2 +lapse rate: lapse rule 4, 5, 287.2 +lapse rate: lapse rule 5, 6, 261.2 +lapse rate: lapse rule 6, 7, 254.7 +lapse rate: lapse rule 7, 8, 248.2 +lapse rate: lapse rule 8, 9, 241.7 +lapse rate: lapse rule 9, 10, 235.3 +lapse rate: lapse rule 10, 11, 228.8 +lapse rate: lapse rule 11, 12, 222.3 +lapse rate: lapse rule 12, 13, 215.8 +lapse rate: lapse rule 13, 14, 215.7 +lapse rate: lapse rule 14, 15, 215.7 +lapse rate: lapse rule 15, 16, 215.7 +lapse rate: lapse rule 16, 17, 215.7 +lapse rate: lapse rule 17, 18, 216.8 +lapse rate: lapse rule 18, 19, 217.9 +lapse rate: lapse rule 19, 20, 219.2 +lapse rate: lapse rule 20, 21, 220.4 +lapse rate: lapse rule 21, 22, 221.6 +lapse rate: lapse rule 22, 23, 222.8 +lapse rate: lapse rule 23, 24, 223.9 +lapse rate: lapse rule 24, 25, 225.1 +lapse rate: lapse rule 25, 27.6, 228.5 +lapse rate: lapse rule 26, 30, 233.7 +lapse rate: lapse rule 27, 32.6, 239 +lapse rate: lapse rule 28, 35, 245.2 +lapse rate: lapse rule 29, 37.5, 251.3 +lapse rate: lapse rule 30, 40, 257.5 +lapse rate: lapse rule 31, 42.5, 263.7 +lapse rate: lapse rule 32, 45, 269.9 +lapse rate: lapse rule 33, 47.5, 275.2 +lapse rate: lapse rule 34, 50, 275.7 +lapse rate: lapse rule 35, 55, 269.3 +lapse rate: lapse rule 36, 60, 257.1 +lapse rate: lapse rule 37, 65, 240.1 +lapse rate: lapse rule 38, 70, 218 +lapse rate: lapse rule 39, 75, 196.1 +lapse rate: lapse rule 40, 80, 174.1 +lapse rate: lapse rule 41, 85, 165.1 +lapse rate: lapse rule 42, 90, 165 +lapse rate: lapse rule 43, 95, 178.3 +lapse rate: lapse rule 44, 100, 190.5 +lapse rate: lapse rule 45, 105, 222.2 +lapse rate: lapse rule 46, 110, 262.4 +lapse rate: lapse rule 47, 115, 316.8 +lapse rate: lapse rule 48, 120, 380 + +# h2o composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: h2o rule 0, 1, 0.0138, h2o +composition rate: h2o rule 1, 2, 0.00968, h2o +composition rate: h2o rule 2, 3, 0.00598, h2o +composition rate: h2o rule 3, 4, 0.00381, h2o +composition rate: h2o rule 4, 5, 0.0022299999999999998, h2o +composition rate: h2o rule 5, 6, 0.0015099999999999998, h2o +composition rate: h2o rule 6, 7, 0.0010199999999999999, h2o +composition rate: h2o rule 7, 8, 0.000646, h2o +composition rate: h2o rule 8, 9, 0.00041299999999999996, h2o +composition rate: h2o rule 9, 10, 0.000247, h2o +composition rate: h2o rule 10, 11, 9.559999999999999e-05, h2o +composition rate: h2o rule 11, 12, 2.9399999999999996e-05, h2o +composition rate: h2o rule 12, 13, 8e-06, h2o +composition rate: h2o rule 13, 14, 4.9999999999999996e-06, h2o +composition rate: h2o rule 14, 15, 3.3999999999999996e-06, h2o +composition rate: h2o rule 15, 16, 3.2999999999999997e-06, h2o +composition rate: h2o rule 16, 17, 3.2e-06, h2o +composition rate: h2o rule 17, 18, 3.15e-06, h2o +composition rate: h2o rule 18, 19, 3.2e-06, h2o +composition rate: h2o rule 19, 20, 3.2999999999999997e-06, h2o +composition rate: h2o rule 20, 21, 3.45e-06, h2o +composition rate: h2o rule 21, 22, 3.6e-06, h2o +composition rate: h2o rule 22, 23, 3.8499999999999996e-06, h2o +composition rate: h2o rule 23, 24, 4e-06, h2o +composition rate: h2o rule 24, 25, 4.2e-06, h2o +composition rate: h2o rule 25, 27.6, 4.45e-06, h2o +composition rate: h2o rule 26, 30, 4.7e-06, h2o +composition rate: h2o rule 27, 32.6, 4.87e-06, h2o +composition rate: h2o rule 28, 35, 4.95e-06, h2o +composition rate: h2o rule 29, 37.5, 4.9999999999999996e-06, h2o +composition rate: h2o rule 30, 40, 5.0999999999999995e-06, h2o +composition rate: h2o rule 31, 42.5, 5.299999999999999e-06, h2o +composition rate: h2o rule 32, 45, 5.45e-06, h2o +composition rate: h2o rule 33, 47.5, 5.5e-06, h2o +composition rate: h2o rule 34, 50, 5.5e-06, h2o +composition rate: h2o rule 35, 55, 5.35e-06, h2o +composition rate: h2o rule 36, 60, 4.9999999999999996e-06, h2o +composition rate: h2o rule 37, 65, 4.4e-06, h2o +composition rate: h2o rule 38, 70, 3.7e-06, h2o +composition rate: h2o rule 39, 75, 2.95e-06, h2o +composition rate: h2o rule 40, 80, 2.1e-06, h2o +composition rate: h2o rule 41, 85, 1.33e-06, h2o +composition rate: h2o rule 42, 90, 8.499999999999999e-07, h2o +composition rate: h2o rule 43, 95, 5.4e-07, h2o +composition rate: h2o rule 44, 100, 4e-07, h2o +composition rate: h2o rule 45, 105, 3.4000000000000003e-07, h2o +composition rate: h2o rule 46, 110, 2.8e-07, h2o +composition rate: h2o rule 47, 115, 2.4e-07, h2o +composition rate: h2o rule 48, 120, 2e-07, h2o + +# o3 composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: o3 rule 0, 1, 3.3399999999999995e-08, o3 +composition rate: o3 rule 1, 2, 3.69e-08, o3 +composition rate: o3 rule 2, 3, 4.22e-08, o3 +composition rate: o3 rule 3, 4, 4.8199999999999995e-08, o3 +composition rate: o3 rule 4, 5, 5.5100000000000004e-08, o3 +composition rate: o3 rule 5, 6, 6.41e-08, o3 +composition rate: o3 rule 6, 7, 7.76e-08, o3 +composition rate: o3 rule 7, 8, 9.13e-08, o3 +composition rate: o3 rule 8, 9, 1.11e-07, o3 +composition rate: o3 rule 9, 10, 1.3e-07, o3 +composition rate: o3 rule 10, 11, 1.7899999999999997e-07, o3 +composition rate: o3 rule 11, 12, 2.23e-07, o3 +composition rate: o3 rule 12, 13, 3e-07, o3 +composition rate: o3 rule 13, 14, 4.3999999999999997e-07, o3 +composition rate: o3 rule 14, 15, 5e-07, o3 +composition rate: o3 rule 15, 16, 6e-07, o3 +composition rate: o3 rule 16, 17, 7e-07, o3 +composition rate: o3 rule 17, 18, 1e-06, o3 +composition rate: o3 rule 18, 19, 1.5e-06, o3 +composition rate: o3 rule 19, 20, 2e-06, o3 +composition rate: o3 rule 20, 21, 2.4e-06, o3 +composition rate: o3 rule 21, 22, 2.8999999999999998e-06, o3 +composition rate: o3 rule 22, 23, 3.3999999999999996e-06, o3 +composition rate: o3 rule 23, 24, 4e-06, o3 +composition rate: o3 rule 24, 25, 4.8e-06, o3 +composition rate: o3 rule 25, 27.6, 6e-06, o3 +composition rate: o3 rule 26, 30, 7e-06, o3 +composition rate: o3 rule 27, 32.6, 8.099999999999999e-06, o3 +composition rate: o3 rule 28, 35, 8.9e-06, o3 +composition rate: o3 rule 29, 37.5, 8.7e-06, o3 +composition rate: o3 rule 30, 40, 7.55e-06, o3 +composition rate: o3 rule 31, 42.5, 5.9e-06, o3 +composition rate: o3 rule 32, 45, 4.5e-06, o3 +composition rate: o3 rule 33, 47.5, 3.5e-06, o3 +composition rate: o3 rule 34, 50, 2.8e-06, o3 +composition rate: o3 rule 35, 55, 1.8e-06, o3 +composition rate: o3 rule 36, 60, 1.3e-06, o3 +composition rate: o3 rule 37, 65, 8e-07, o3 +composition rate: o3 rule 38, 70, 4e-07, o3 +composition rate: o3 rule 39, 75, 1.8999999999999998e-07, o3 +composition rate: o3 rule 40, 80, 2e-07, o3 +composition rate: o3 rule 41, 85, 5.699999999999999e-07, o3 +composition rate: o3 rule 42, 90, 7.5e-07, o3 +composition rate: o3 rule 43, 95, 7e-07, o3 +composition rate: o3 rule 44, 100, 4.03e-07, o3 +composition rate: o3 rule 45, 105, 2e-07, o3 +composition rate: o3 rule 46, 110, 5e-08, o3 +composition rate: o3 rule 47, 115, 5e-09, o3 +composition rate: o3 rule 48, 120, 5e-10, o3 + diff --git a/collins 4a thick.pyr b/collins 4a thick.pyr new file mode 100644 index 0000000..971ebf0 --- /dev/null +++ b/collins 4a thick.pyr @@ -0,0 +1,174 @@ +# atm profile for midlatitude summer + +# surface values (pressure, temperature, final height, initial layer thickness, acceleration of gravity, range min, range max) +surface: 1010.0, 294.2, 120, 250, 9.8, 100, 2500 + +# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile +# except for co2, o2, n2, and ar +molecule: co2, .001148 +molecule: h2o, 0.0186 +molecule: o2, .20 +molecule: n2, .77 +molecule: ar, .009 +#molecule: ch4, 1.6999999999999998e-06 +molecule: o3, 3.02e-08 +#molecule: n2o, 3.2e-07 +#molecule: co, 1.5e-07 + +# lapse rate profile +# rules are: name, final height, final value +# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule) +lapse rate: lapse rule 0, 1, 289.7 +lapse rate: lapse rule 1, 2, 295.2 +lapse rate: lapse rule 2, 3, 279.2 +lapse rate: lapse rule 3, 4, 273.2 +lapse rate: lapse rule 4, 5, 287.2 +lapse rate: lapse rule 5, 6, 261.2 +lapse rate: lapse rule 6, 7, 254.7 +lapse rate: lapse rule 7, 8, 248.2 +lapse rate: lapse rule 8, 9, 241.7 +lapse rate: lapse rule 9, 10, 235.3 +lapse rate: lapse rule 10, 11, 228.8 +lapse rate: lapse rule 11, 12, 222.3 +lapse rate: lapse rule 12, 13, 215.8 +lapse rate: lapse rule 13, 14, 215.7 +lapse rate: lapse rule 14, 15, 215.7 +lapse rate: lapse rule 15, 16, 215.7 +lapse rate: lapse rule 16, 17, 215.7 +lapse rate: lapse rule 17, 18, 216.8 +lapse rate: lapse rule 18, 19, 217.9 +lapse rate: lapse rule 19, 20, 219.2 +lapse rate: lapse rule 20, 21, 220.4 +lapse rate: lapse rule 21, 22, 221.6 +lapse rate: lapse rule 22, 23, 222.8 +lapse rate: lapse rule 23, 24, 223.9 +lapse rate: lapse rule 24, 25, 225.1 +lapse rate: lapse rule 25, 27.6, 228.5 +lapse rate: lapse rule 26, 30, 233.7 +lapse rate: lapse rule 27, 32.6, 239 +lapse rate: lapse rule 28, 35, 245.2 +lapse rate: lapse rule 29, 37.5, 251.3 +lapse rate: lapse rule 30, 40, 257.5 +lapse rate: lapse rule 31, 42.5, 263.7 +lapse rate: lapse rule 32, 45, 269.9 +lapse rate: lapse rule 33, 47.5, 275.2 +lapse rate: lapse rule 34, 50, 275.7 +lapse rate: lapse rule 35, 55, 269.3 +lapse rate: lapse rule 36, 60, 257.1 +lapse rate: lapse rule 37, 65, 240.1 +lapse rate: lapse rule 38, 70, 218 +lapse rate: lapse rule 39, 75, 196.1 +lapse rate: lapse rule 40, 80, 174.1 +lapse rate: lapse rule 41, 85, 165.1 +lapse rate: lapse rule 42, 90, 165 +lapse rate: lapse rule 43, 95, 178.3 +lapse rate: lapse rule 44, 100, 190.5 +lapse rate: lapse rule 45, 105, 222.2 +lapse rate: lapse rule 46, 110, 262.4 +lapse rate: lapse rule 47, 115, 316.8 +lapse rate: lapse rule 48, 120, 380 + +# h2o composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: h2o rule 0, 1, 0.0138, h2o +composition rate: h2o rule 1, 2, 0.00968, h2o +composition rate: h2o rule 2, 3, 0.00598, h2o +composition rate: h2o rule 3, 4, 0.00381, h2o +composition rate: h2o rule 4, 5, 0.0022299999999999998, h2o +composition rate: h2o rule 5, 6, 0.0015099999999999998, h2o +composition rate: h2o rule 6, 7, 0.0010199999999999999, h2o +composition rate: h2o rule 7, 8, 0.000646, h2o +composition rate: h2o rule 8, 9, 0.00041299999999999996, h2o +composition rate: h2o rule 9, 10, 0.000247, h2o +composition rate: h2o rule 10, 11, 9.559999999999999e-05, h2o +composition rate: h2o rule 11, 12, 2.9399999999999996e-05, h2o +composition rate: h2o rule 12, 13, 8e-06, h2o +composition rate: h2o rule 13, 14, 4.9999999999999996e-06, h2o +composition rate: h2o rule 14, 15, 3.3999999999999996e-06, h2o +composition rate: h2o rule 15, 16, 3.2999999999999997e-06, h2o +composition rate: h2o rule 16, 17, 3.2e-06, h2o +composition rate: h2o rule 17, 18, 3.15e-06, h2o +composition rate: h2o rule 18, 19, 3.2e-06, h2o +composition rate: h2o rule 19, 20, 3.2999999999999997e-06, h2o +composition rate: h2o rule 20, 21, 3.45e-06, h2o +composition rate: h2o rule 21, 22, 3.6e-06, h2o +composition rate: h2o rule 22, 23, 3.8499999999999996e-06, h2o +composition rate: h2o rule 23, 24, 4e-06, h2o +composition rate: h2o rule 24, 25, 4.2e-06, h2o +composition rate: h2o rule 25, 27.6, 4.45e-06, h2o +composition rate: h2o rule 26, 30, 4.7e-06, h2o +composition rate: h2o rule 27, 32.6, 4.87e-06, h2o +composition rate: h2o rule 28, 35, 4.95e-06, h2o +composition rate: h2o rule 29, 37.5, 4.9999999999999996e-06, h2o +composition rate: h2o rule 30, 40, 5.0999999999999995e-06, h2o +composition rate: h2o rule 31, 42.5, 5.299999999999999e-06, h2o +composition rate: h2o rule 32, 45, 5.45e-06, h2o +composition rate: h2o rule 33, 47.5, 5.5e-06, h2o +composition rate: h2o rule 34, 50, 5.5e-06, h2o +composition rate: h2o rule 35, 55, 5.35e-06, h2o +composition rate: h2o rule 36, 60, 4.9999999999999996e-06, h2o +composition rate: h2o rule 37, 65, 4.4e-06, h2o +composition rate: h2o rule 38, 70, 3.7e-06, h2o +composition rate: h2o rule 39, 75, 2.95e-06, h2o +composition rate: h2o rule 40, 80, 2.1e-06, h2o +composition rate: h2o rule 41, 85, 1.33e-06, h2o +composition rate: h2o rule 42, 90, 8.499999999999999e-07, h2o +composition rate: h2o rule 43, 95, 5.4e-07, h2o +composition rate: h2o rule 44, 100, 4e-07, h2o +composition rate: h2o rule 45, 105, 3.4000000000000003e-07, h2o +composition rate: h2o rule 46, 110, 2.8e-07, h2o +composition rate: h2o rule 47, 115, 2.4e-07, h2o +composition rate: h2o rule 48, 120, 2e-07, h2o + +# o3 composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: o3 rule 0, 1, 3.3399999999999995e-08, o3 +composition rate: o3 rule 1, 2, 3.69e-08, o3 +composition rate: o3 rule 2, 3, 4.22e-08, o3 +composition rate: o3 rule 3, 4, 4.8199999999999995e-08, o3 +composition rate: o3 rule 4, 5, 5.5100000000000004e-08, o3 +composition rate: o3 rule 5, 6, 6.41e-08, o3 +composition rate: o3 rule 6, 7, 7.76e-08, o3 +composition rate: o3 rule 7, 8, 9.13e-08, o3 +composition rate: o3 rule 8, 9, 1.11e-07, o3 +composition rate: o3 rule 9, 10, 1.3e-07, o3 +composition rate: o3 rule 10, 11, 1.7899999999999997e-07, o3 +composition rate: o3 rule 11, 12, 2.23e-07, o3 +composition rate: o3 rule 12, 13, 3e-07, o3 +composition rate: o3 rule 13, 14, 4.3999999999999997e-07, o3 +composition rate: o3 rule 14, 15, 5e-07, o3 +composition rate: o3 rule 15, 16, 6e-07, o3 +composition rate: o3 rule 16, 17, 7e-07, o3 +composition rate: o3 rule 17, 18, 1e-06, o3 +composition rate: o3 rule 18, 19, 1.5e-06, o3 +composition rate: o3 rule 19, 20, 2e-06, o3 +composition rate: o3 rule 20, 21, 2.4e-06, o3 +composition rate: o3 rule 21, 22, 2.8999999999999998e-06, o3 +composition rate: o3 rule 22, 23, 3.3999999999999996e-06, o3 +composition rate: o3 rule 23, 24, 4e-06, o3 +composition rate: o3 rule 24, 25, 4.8e-06, o3 +composition rate: o3 rule 25, 27.6, 6e-06, o3 +composition rate: o3 rule 26, 30, 7e-06, o3 +composition rate: o3 rule 27, 32.6, 8.099999999999999e-06, o3 +composition rate: o3 rule 28, 35, 8.9e-06, o3 +composition rate: o3 rule 29, 37.5, 8.7e-06, o3 +composition rate: o3 rule 30, 40, 7.55e-06, o3 +composition rate: o3 rule 31, 42.5, 5.9e-06, o3 +composition rate: o3 rule 32, 45, 4.5e-06, o3 +composition rate: o3 rule 33, 47.5, 3.5e-06, o3 +composition rate: o3 rule 34, 50, 2.8e-06, o3 +composition rate: o3 rule 35, 55, 1.8e-06, o3 +composition rate: o3 rule 36, 60, 1.3e-06, o3 +composition rate: o3 rule 37, 65, 8e-07, o3 +composition rate: o3 rule 38, 70, 4e-07, o3 +composition rate: o3 rule 39, 75, 1.8999999999999998e-07, o3 +composition rate: o3 rule 40, 80, 2e-07, o3 +composition rate: o3 rule 41, 85, 5.699999999999999e-07, o3 +composition rate: o3 rule 42, 90, 7.5e-07, o3 +composition rate: o3 rule 43, 95, 7e-07, o3 +composition rate: o3 rule 44, 100, 4.03e-07, o3 +composition rate: o3 rule 45, 105, 2e-07, o3 +composition rate: o3 rule 46, 110, 5e-08, o3 +composition rate: o3 rule 47, 115, 5e-09, o3 +composition rate: o3 rule 48, 120, 5e-10, o3 + diff --git a/pyradClasses.py b/pyradClasses.py index 1b26a6e..ae79b77 100644 --- a/pyradClasses.py +++ b/pyradClasses.py @@ -1424,7 +1424,7 @@ def plot(propertyToPlot, title, plotList, fill=False): plt.margins(0.1) plt.subplots_adjust(left=.07, bottom=.08, right=.97, top=.90) plt.ylabel(propertyToPlot) - plt.text(650, .5, '%s' % settings.userName, verticalalignment='bottom', horizontalalignment='right', color=theme.textColor, fontsize=8) + # plt.text(650, .5, '%s' % settings.userName, verticalalignment='bottom', horizontalalignment='right', color=theme.textColor, fontsize=8) if propertyToPlot == 'line survey': plt.yscale('log') plt.grid(theme.gridList[0], linewidth=.5, linestyle=':') @@ -1478,10 +1478,10 @@ def plotSpectrum(layer=None, title=None, rangeMin=None, rangeMax=None, objList=N handles = [] if not rangeMax: xAxis = layer.xAxis - for temperature, color in zip(planckTemperatureList, theme.gridList): + for temperature, color in zip(planckTemperatureList, theme.colorList[3:]): yAxis = planckFunction(xAxis, float(temperature)) fig, = plt.plot(xAxis, yAxis, linewidth=.75, color=color, - linestyle=':', label='%sK : %sWm-2' % + label='%sK : %sWm-2' % (temperature, round(integrateSpectrum(yAxis, res=(rangeMax - rangeMin) / len(yAxis)), 2))) handles.append(fig) if objList: diff --git a/trace gas ch4 0.pyr b/trace gas ch4 0.pyr new file mode 100644 index 0000000..67016f6 --- /dev/null +++ b/trace gas ch4 0.pyr @@ -0,0 +1,120 @@ +# atm profile for midlatitude summer + +# surface values (pressure, temperature, final height, initial layer thickness, acceleration of gravity, range min, range max) +surface: 1010.0, 294.2, 120, 250, 9.8, 100, 2500 + +# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile +# except for co2, o2, n2, and ar +molecule: co2, .000287 +molecule: h2o, 0.0186 +molecule: o2, .20 +molecule: n2, .77 +molecule: ar, .009 +#molecule: ch4, 0.000000806 +#molecule: o3, 3.02e-08 +#molecule: n2o, 0.000000275 + +# lapse rate profile +# rules are: name, final height, final value +# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule) +lapse rate: lapse rule 0, 1, 289.7 +lapse rate: lapse rule 1, 2, 295.2 +lapse rate: lapse rule 2, 3, 279.2 +lapse rate: lapse rule 3, 4, 273.2 +lapse rate: lapse rule 4, 5, 287.2 +lapse rate: lapse rule 5, 6, 261.2 +lapse rate: lapse rule 6, 7, 254.7 +lapse rate: lapse rule 7, 8, 248.2 +lapse rate: lapse rule 8, 9, 241.7 +lapse rate: lapse rule 9, 10, 235.3 +lapse rate: lapse rule 10, 11, 228.8 +lapse rate: lapse rule 11, 12, 222.3 +lapse rate: lapse rule 12, 13, 215.8 +lapse rate: lapse rule 13, 14, 215.7 +lapse rate: lapse rule 14, 15, 215.7 +lapse rate: lapse rule 15, 16, 215.7 +lapse rate: lapse rule 16, 17, 215.7 +lapse rate: lapse rule 17, 18, 216.8 +lapse rate: lapse rule 18, 19, 217.9 +lapse rate: lapse rule 19, 20, 219.2 +lapse rate: lapse rule 20, 21, 220.4 +lapse rate: lapse rule 21, 22, 221.6 +lapse rate: lapse rule 22, 23, 222.8 +lapse rate: lapse rule 23, 24, 223.9 +lapse rate: lapse rule 24, 25, 225.1 +lapse rate: lapse rule 25, 27.6, 228.5 +lapse rate: lapse rule 26, 30, 233.7 +lapse rate: lapse rule 27, 32.6, 239 +lapse rate: lapse rule 28, 35, 245.2 +lapse rate: lapse rule 29, 37.5, 251.3 +lapse rate: lapse rule 30, 40, 257.5 +lapse rate: lapse rule 31, 42.5, 263.7 +lapse rate: lapse rule 32, 45, 269.9 +lapse rate: lapse rule 33, 47.5, 275.2 +lapse rate: lapse rule 34, 50, 275.7 +lapse rate: lapse rule 35, 55, 269.3 +lapse rate: lapse rule 36, 60, 257.1 +lapse rate: lapse rule 37, 65, 240.1 +lapse rate: lapse rule 38, 70, 218 +lapse rate: lapse rule 39, 75, 196.1 +lapse rate: lapse rule 40, 80, 174.1 +lapse rate: lapse rule 41, 85, 165.1 +lapse rate: lapse rule 42, 90, 165 +lapse rate: lapse rule 43, 95, 178.3 +lapse rate: lapse rule 44, 100, 190.5 +lapse rate: lapse rule 45, 105, 222.2 +lapse rate: lapse rule 46, 110, 262.4 +lapse rate: lapse rule 47, 115, 316.8 +lapse rate: lapse rule 48, 120, 380 + +# h2o composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: h2o rule 0, 1, 0.0138, h2o +composition rate: h2o rule 1, 2, 0.00968, h2o +composition rate: h2o rule 2, 3, 0.00598, h2o +composition rate: h2o rule 3, 4, 0.00381, h2o +composition rate: h2o rule 4, 5, 0.0022299999999999998, h2o +composition rate: h2o rule 5, 6, 0.0015099999999999998, h2o +composition rate: h2o rule 6, 7, 0.0010199999999999999, h2o +composition rate: h2o rule 7, 8, 0.000646, h2o +composition rate: h2o rule 8, 9, 0.00041299999999999996, h2o +composition rate: h2o rule 9, 10, 0.000247, h2o +composition rate: h2o rule 10, 11, 9.559999999999999e-05, h2o +composition rate: h2o rule 11, 12, 2.9399999999999996e-05, h2o +composition rate: h2o rule 12, 13, 8e-06, h2o +composition rate: h2o rule 13, 14, 4.9999999999999996e-06, h2o +composition rate: h2o rule 14, 15, 3.3999999999999996e-06, h2o +composition rate: h2o rule 15, 16, 3.2999999999999997e-06, h2o +composition rate: h2o rule 16, 17, 3.2e-06, h2o +composition rate: h2o rule 17, 18, 3.15e-06, h2o +composition rate: h2o rule 18, 19, 3.2e-06, h2o +composition rate: h2o rule 19, 20, 3.2999999999999997e-06, h2o +composition rate: h2o rule 20, 21, 3.45e-06, h2o +composition rate: h2o rule 21, 22, 3.6e-06, h2o +composition rate: h2o rule 22, 23, 3.8499999999999996e-06, h2o +composition rate: h2o rule 23, 24, 4e-06, h2o +composition rate: h2o rule 24, 25, 4.2e-06, h2o +composition rate: h2o rule 25, 27.6, 4.45e-06, h2o +composition rate: h2o rule 26, 30, 4.7e-06, h2o +composition rate: h2o rule 27, 32.6, 4.87e-06, h2o +composition rate: h2o rule 28, 35, 4.95e-06, h2o +composition rate: h2o rule 29, 37.5, 4.9999999999999996e-06, h2o +composition rate: h2o rule 30, 40, 5.0999999999999995e-06, h2o +composition rate: h2o rule 31, 42.5, 5.299999999999999e-06, h2o +composition rate: h2o rule 32, 45, 5.45e-06, h2o +composition rate: h2o rule 33, 47.5, 5.5e-06, h2o +composition rate: h2o rule 34, 50, 5.5e-06, h2o +composition rate: h2o rule 35, 55, 5.35e-06, h2o +composition rate: h2o rule 36, 60, 4.9999999999999996e-06, h2o +composition rate: h2o rule 37, 65, 4.4e-06, h2o +composition rate: h2o rule 38, 70, 3.7e-06, h2o +composition rate: h2o rule 39, 75, 2.95e-06, h2o +composition rate: h2o rule 40, 80, 2.1e-06, h2o +composition rate: h2o rule 41, 85, 1.33e-06, h2o +composition rate: h2o rule 42, 90, 8.499999999999999e-07, h2o +composition rate: h2o rule 43, 95, 5.4e-07, h2o +composition rate: h2o rule 44, 100, 4e-07, h2o +composition rate: h2o rule 45, 105, 3.4000000000000003e-07, h2o +composition rate: h2o rule 46, 110, 2.8e-07, h2o +composition rate: h2o rule 47, 115, 2.4e-07, h2o +composition rate: h2o rule 48, 120, 2e-07, h2o diff --git a/trace gas ch4 8e-7.pyr b/trace gas ch4 8e-7.pyr new file mode 100644 index 0000000..791dc06 --- /dev/null +++ b/trace gas ch4 8e-7.pyr @@ -0,0 +1,120 @@ +# atm profile for midlatitude summer + +# surface values (pressure, temperature, final height, initial layer thickness, acceleration of gravity, range min, range max) +surface: 1010.0, 294.2, 120, 250, 9.8, 100, 2500 + +# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile +# except for co2, o2, n2, and ar +molecule: co2, .000287 +molecule: h2o, 0.0186 +molecule: o2, .20 +molecule: n2, .77 +molecule: ar, .009 +molecule: ch4, 0.000000806 +#molecule: o3, 3.02e-08 +#molecule: n2o, 0.000000275 + +# lapse rate profile +# rules are: name, final height, final value +# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule) +lapse rate: lapse rule 0, 1, 289.7 +lapse rate: lapse rule 1, 2, 295.2 +lapse rate: lapse rule 2, 3, 279.2 +lapse rate: lapse rule 3, 4, 273.2 +lapse rate: lapse rule 4, 5, 287.2 +lapse rate: lapse rule 5, 6, 261.2 +lapse rate: lapse rule 6, 7, 254.7 +lapse rate: lapse rule 7, 8, 248.2 +lapse rate: lapse rule 8, 9, 241.7 +lapse rate: lapse rule 9, 10, 235.3 +lapse rate: lapse rule 10, 11, 228.8 +lapse rate: lapse rule 11, 12, 222.3 +lapse rate: lapse rule 12, 13, 215.8 +lapse rate: lapse rule 13, 14, 215.7 +lapse rate: lapse rule 14, 15, 215.7 +lapse rate: lapse rule 15, 16, 215.7 +lapse rate: lapse rule 16, 17, 215.7 +lapse rate: lapse rule 17, 18, 216.8 +lapse rate: lapse rule 18, 19, 217.9 +lapse rate: lapse rule 19, 20, 219.2 +lapse rate: lapse rule 20, 21, 220.4 +lapse rate: lapse rule 21, 22, 221.6 +lapse rate: lapse rule 22, 23, 222.8 +lapse rate: lapse rule 23, 24, 223.9 +lapse rate: lapse rule 24, 25, 225.1 +lapse rate: lapse rule 25, 27.6, 228.5 +lapse rate: lapse rule 26, 30, 233.7 +lapse rate: lapse rule 27, 32.6, 239 +lapse rate: lapse rule 28, 35, 245.2 +lapse rate: lapse rule 29, 37.5, 251.3 +lapse rate: lapse rule 30, 40, 257.5 +lapse rate: lapse rule 31, 42.5, 263.7 +lapse rate: lapse rule 32, 45, 269.9 +lapse rate: lapse rule 33, 47.5, 275.2 +lapse rate: lapse rule 34, 50, 275.7 +lapse rate: lapse rule 35, 55, 269.3 +lapse rate: lapse rule 36, 60, 257.1 +lapse rate: lapse rule 37, 65, 240.1 +lapse rate: lapse rule 38, 70, 218 +lapse rate: lapse rule 39, 75, 196.1 +lapse rate: lapse rule 40, 80, 174.1 +lapse rate: lapse rule 41, 85, 165.1 +lapse rate: lapse rule 42, 90, 165 +lapse rate: lapse rule 43, 95, 178.3 +lapse rate: lapse rule 44, 100, 190.5 +lapse rate: lapse rule 45, 105, 222.2 +lapse rate: lapse rule 46, 110, 262.4 +lapse rate: lapse rule 47, 115, 316.8 +lapse rate: lapse rule 48, 120, 380 + +# h2o composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: h2o rule 0, 1, 0.0138, h2o +composition rate: h2o rule 1, 2, 0.00968, h2o +composition rate: h2o rule 2, 3, 0.00598, h2o +composition rate: h2o rule 3, 4, 0.00381, h2o +composition rate: h2o rule 4, 5, 0.0022299999999999998, h2o +composition rate: h2o rule 5, 6, 0.0015099999999999998, h2o +composition rate: h2o rule 6, 7, 0.0010199999999999999, h2o +composition rate: h2o rule 7, 8, 0.000646, h2o +composition rate: h2o rule 8, 9, 0.00041299999999999996, h2o +composition rate: h2o rule 9, 10, 0.000247, h2o +composition rate: h2o rule 10, 11, 9.559999999999999e-05, h2o +composition rate: h2o rule 11, 12, 2.9399999999999996e-05, h2o +composition rate: h2o rule 12, 13, 8e-06, h2o +composition rate: h2o rule 13, 14, 4.9999999999999996e-06, h2o +composition rate: h2o rule 14, 15, 3.3999999999999996e-06, h2o +composition rate: h2o rule 15, 16, 3.2999999999999997e-06, h2o +composition rate: h2o rule 16, 17, 3.2e-06, h2o +composition rate: h2o rule 17, 18, 3.15e-06, h2o +composition rate: h2o rule 18, 19, 3.2e-06, h2o +composition rate: h2o rule 19, 20, 3.2999999999999997e-06, h2o +composition rate: h2o rule 20, 21, 3.45e-06, h2o +composition rate: h2o rule 21, 22, 3.6e-06, h2o +composition rate: h2o rule 22, 23, 3.8499999999999996e-06, h2o +composition rate: h2o rule 23, 24, 4e-06, h2o +composition rate: h2o rule 24, 25, 4.2e-06, h2o +composition rate: h2o rule 25, 27.6, 4.45e-06, h2o +composition rate: h2o rule 26, 30, 4.7e-06, h2o +composition rate: h2o rule 27, 32.6, 4.87e-06, h2o +composition rate: h2o rule 28, 35, 4.95e-06, h2o +composition rate: h2o rule 29, 37.5, 4.9999999999999996e-06, h2o +composition rate: h2o rule 30, 40, 5.0999999999999995e-06, h2o +composition rate: h2o rule 31, 42.5, 5.299999999999999e-06, h2o +composition rate: h2o rule 32, 45, 5.45e-06, h2o +composition rate: h2o rule 33, 47.5, 5.5e-06, h2o +composition rate: h2o rule 34, 50, 5.5e-06, h2o +composition rate: h2o rule 35, 55, 5.35e-06, h2o +composition rate: h2o rule 36, 60, 4.9999999999999996e-06, h2o +composition rate: h2o rule 37, 65, 4.4e-06, h2o +composition rate: h2o rule 38, 70, 3.7e-06, h2o +composition rate: h2o rule 39, 75, 2.95e-06, h2o +composition rate: h2o rule 40, 80, 2.1e-06, h2o +composition rate: h2o rule 41, 85, 1.33e-06, h2o +composition rate: h2o rule 42, 90, 8.499999999999999e-07, h2o +composition rate: h2o rule 43, 95, 5.4e-07, h2o +composition rate: h2o rule 44, 100, 4e-07, h2o +composition rate: h2o rule 45, 105, 3.4000000000000003e-07, h2o +composition rate: h2o rule 46, 110, 2.8e-07, h2o +composition rate: h2o rule 47, 115, 2.4e-07, h2o +composition rate: h2o rule 48, 120, 2e-07, h2o diff --git a/trace gas ch4 8e-8.pyr b/trace gas ch4 8e-8.pyr new file mode 100644 index 0000000..a1f7f70 --- /dev/null +++ b/trace gas ch4 8e-8.pyr @@ -0,0 +1,120 @@ +# atm profile for midlatitude summer + +# surface values (pressure, temperature, final height, initial layer thickness, acceleration of gravity, range min, range max) +surface: 1010.0, 294.2, 120, 250, 9.8, 100, 2500 + +# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile +# except for co2, o2, n2, and ar +molecule: co2, .000287 +molecule: h2o, 0.0186 +molecule: o2, .20 +molecule: n2, .77 +molecule: ar, .009 +molecule: ch4, 0.0000000806 +#molecule: o3, 3.02e-08 +#molecule: n2o, 0.000000275 + +# lapse rate profile +# rules are: name, final height, final value +# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule) +lapse rate: lapse rule 0, 1, 289.7 +lapse rate: lapse rule 1, 2, 295.2 +lapse rate: lapse rule 2, 3, 279.2 +lapse rate: lapse rule 3, 4, 273.2 +lapse rate: lapse rule 4, 5, 287.2 +lapse rate: lapse rule 5, 6, 261.2 +lapse rate: lapse rule 6, 7, 254.7 +lapse rate: lapse rule 7, 8, 248.2 +lapse rate: lapse rule 8, 9, 241.7 +lapse rate: lapse rule 9, 10, 235.3 +lapse rate: lapse rule 10, 11, 228.8 +lapse rate: lapse rule 11, 12, 222.3 +lapse rate: lapse rule 12, 13, 215.8 +lapse rate: lapse rule 13, 14, 215.7 +lapse rate: lapse rule 14, 15, 215.7 +lapse rate: lapse rule 15, 16, 215.7 +lapse rate: lapse rule 16, 17, 215.7 +lapse rate: lapse rule 17, 18, 216.8 +lapse rate: lapse rule 18, 19, 217.9 +lapse rate: lapse rule 19, 20, 219.2 +lapse rate: lapse rule 20, 21, 220.4 +lapse rate: lapse rule 21, 22, 221.6 +lapse rate: lapse rule 22, 23, 222.8 +lapse rate: lapse rule 23, 24, 223.9 +lapse rate: lapse rule 24, 25, 225.1 +lapse rate: lapse rule 25, 27.6, 228.5 +lapse rate: lapse rule 26, 30, 233.7 +lapse rate: lapse rule 27, 32.6, 239 +lapse rate: lapse rule 28, 35, 245.2 +lapse rate: lapse rule 29, 37.5, 251.3 +lapse rate: lapse rule 30, 40, 257.5 +lapse rate: lapse rule 31, 42.5, 263.7 +lapse rate: lapse rule 32, 45, 269.9 +lapse rate: lapse rule 33, 47.5, 275.2 +lapse rate: lapse rule 34, 50, 275.7 +lapse rate: lapse rule 35, 55, 269.3 +lapse rate: lapse rule 36, 60, 257.1 +lapse rate: lapse rule 37, 65, 240.1 +lapse rate: lapse rule 38, 70, 218 +lapse rate: lapse rule 39, 75, 196.1 +lapse rate: lapse rule 40, 80, 174.1 +lapse rate: lapse rule 41, 85, 165.1 +lapse rate: lapse rule 42, 90, 165 +lapse rate: lapse rule 43, 95, 178.3 +lapse rate: lapse rule 44, 100, 190.5 +lapse rate: lapse rule 45, 105, 222.2 +lapse rate: lapse rule 46, 110, 262.4 +lapse rate: lapse rule 47, 115, 316.8 +lapse rate: lapse rule 48, 120, 380 + +# h2o composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: h2o rule 0, 1, 0.0138, h2o +composition rate: h2o rule 1, 2, 0.00968, h2o +composition rate: h2o rule 2, 3, 0.00598, h2o +composition rate: h2o rule 3, 4, 0.00381, h2o +composition rate: h2o rule 4, 5, 0.0022299999999999998, h2o +composition rate: h2o rule 5, 6, 0.0015099999999999998, h2o +composition rate: h2o rule 6, 7, 0.0010199999999999999, h2o +composition rate: h2o rule 7, 8, 0.000646, h2o +composition rate: h2o rule 8, 9, 0.00041299999999999996, h2o +composition rate: h2o rule 9, 10, 0.000247, h2o +composition rate: h2o rule 10, 11, 9.559999999999999e-05, h2o +composition rate: h2o rule 11, 12, 2.9399999999999996e-05, h2o +composition rate: h2o rule 12, 13, 8e-06, h2o +composition rate: h2o rule 13, 14, 4.9999999999999996e-06, h2o +composition rate: h2o rule 14, 15, 3.3999999999999996e-06, h2o +composition rate: h2o rule 15, 16, 3.2999999999999997e-06, h2o +composition rate: h2o rule 16, 17, 3.2e-06, h2o +composition rate: h2o rule 17, 18, 3.15e-06, h2o +composition rate: h2o rule 18, 19, 3.2e-06, h2o +composition rate: h2o rule 19, 20, 3.2999999999999997e-06, h2o +composition rate: h2o rule 20, 21, 3.45e-06, h2o +composition rate: h2o rule 21, 22, 3.6e-06, h2o +composition rate: h2o rule 22, 23, 3.8499999999999996e-06, h2o +composition rate: h2o rule 23, 24, 4e-06, h2o +composition rate: h2o rule 24, 25, 4.2e-06, h2o +composition rate: h2o rule 25, 27.6, 4.45e-06, h2o +composition rate: h2o rule 26, 30, 4.7e-06, h2o +composition rate: h2o rule 27, 32.6, 4.87e-06, h2o +composition rate: h2o rule 28, 35, 4.95e-06, h2o +composition rate: h2o rule 29, 37.5, 4.9999999999999996e-06, h2o +composition rate: h2o rule 30, 40, 5.0999999999999995e-06, h2o +composition rate: h2o rule 31, 42.5, 5.299999999999999e-06, h2o +composition rate: h2o rule 32, 45, 5.45e-06, h2o +composition rate: h2o rule 33, 47.5, 5.5e-06, h2o +composition rate: h2o rule 34, 50, 5.5e-06, h2o +composition rate: h2o rule 35, 55, 5.35e-06, h2o +composition rate: h2o rule 36, 60, 4.9999999999999996e-06, h2o +composition rate: h2o rule 37, 65, 4.4e-06, h2o +composition rate: h2o rule 38, 70, 3.7e-06, h2o +composition rate: h2o rule 39, 75, 2.95e-06, h2o +composition rate: h2o rule 40, 80, 2.1e-06, h2o +composition rate: h2o rule 41, 85, 1.33e-06, h2o +composition rate: h2o rule 42, 90, 8.499999999999999e-07, h2o +composition rate: h2o rule 43, 95, 5.4e-07, h2o +composition rate: h2o rule 44, 100, 4e-07, h2o +composition rate: h2o rule 45, 105, 3.4000000000000003e-07, h2o +composition rate: h2o rule 46, 110, 2.8e-07, h2o +composition rate: h2o rule 47, 115, 2.4e-07, h2o +composition rate: h2o rule 48, 120, 2e-07, h2o diff --git a/venussimple.pyr b/venussimple.pyr index b4953bb..ab063e2 100644 --- a/venussimple.pyr +++ b/venussimple.pyr @@ -1,7 +1,7 @@ # A demo file for pyrad # mBar , K , km, m , g, cm-1,cm-1 -surface: 93000, 735, 200, 10, 8.87, 100, 2500 +surface: 93000, 735, 200, 8, 8.87, 100, 2500 # mol text name, concentration molecule: co2, .965 From 97f9aa4a34c963368815b282ddf84e5fd9f9b42c Mon Sep 17 00:00:00 2001 From: Brad Schrag Date: Thu, 14 Feb 2019 14:49:47 -0600 Subject: [PATCH 40/43] cleaned up profile files --- collins 1a 25 slices.pyr | 174 ----------------- collins 1a double pressure.pyr | 174 ----------------- collins 1a.pyr | 174 ----------------- collins 2a 25 slices.pyr | 174 ----------------- collins 2a.pyr | 174 ----------------- collins 2b 25 slices.pyr | 174 ----------------- collins 2b.pyr | 174 ----------------- collins 3a.pyr | 173 ----------------- tropical - narrow spectrum.pyr | 329 --------------------------------- venussimple.pyr | 21 --- 10 files changed, 1741 deletions(-) delete mode 100644 collins 1a 25 slices.pyr delete mode 100644 collins 1a double pressure.pyr delete mode 100644 collins 1a.pyr delete mode 100644 collins 2a 25 slices.pyr delete mode 100644 collins 2a.pyr delete mode 100644 collins 2b 25 slices.pyr delete mode 100644 collins 2b.pyr delete mode 100644 collins 3a.pyr delete mode 100644 tropical - narrow spectrum.pyr delete mode 100644 venussimple.pyr diff --git a/collins 1a 25 slices.pyr b/collins 1a 25 slices.pyr deleted file mode 100644 index 23a71bf..0000000 --- a/collins 1a 25 slices.pyr +++ /dev/null @@ -1,174 +0,0 @@ -# atm profile for midlatitude summer - -# surface values (pressure, temperature, final height, initial layer thickness, acceleration of gravity, range min, range max) -surface: 1010.0, 294.2, 120, 400, 9.8, 100, 2500 - -# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile -# except for co2, o2, n2, and ar -molecule: co2, .000287 -molecule: h2o, 0.0186 -molecule: o2, .20 -molecule: n2, .77 -molecule: ar, .009 -#molecule: ch4, 1.6999999999999998e-06 -molecule: o3, 3.02e-08 -#molecule: n2o, 3.2e-07 -#molecule: co, 1.5e-07 - -# lapse rate profile -# rules are: name, final height, final value -# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule) -lapse rate: lapse rule 0, 1, 289.7 -lapse rate: lapse rule 1, 2, 295.2 -lapse rate: lapse rule 2, 3, 279.2 -lapse rate: lapse rule 3, 4, 273.2 -lapse rate: lapse rule 4, 5, 287.2 -lapse rate: lapse rule 5, 6, 261.2 -lapse rate: lapse rule 6, 7, 254.7 -lapse rate: lapse rule 7, 8, 248.2 -lapse rate: lapse rule 8, 9, 241.7 -lapse rate: lapse rule 9, 10, 235.3 -lapse rate: lapse rule 10, 11, 228.8 -lapse rate: lapse rule 11, 12, 222.3 -lapse rate: lapse rule 12, 13, 215.8 -lapse rate: lapse rule 13, 14, 215.7 -lapse rate: lapse rule 14, 15, 215.7 -lapse rate: lapse rule 15, 16, 215.7 -lapse rate: lapse rule 16, 17, 215.7 -lapse rate: lapse rule 17, 18, 216.8 -lapse rate: lapse rule 18, 19, 217.9 -lapse rate: lapse rule 19, 20, 219.2 -lapse rate: lapse rule 20, 21, 220.4 -lapse rate: lapse rule 21, 22, 221.6 -lapse rate: lapse rule 22, 23, 222.8 -lapse rate: lapse rule 23, 24, 223.9 -lapse rate: lapse rule 24, 25, 225.1 -lapse rate: lapse rule 25, 27.6, 228.5 -lapse rate: lapse rule 26, 30, 233.7 -lapse rate: lapse rule 27, 32.6, 239 -lapse rate: lapse rule 28, 35, 245.2 -lapse rate: lapse rule 29, 37.5, 251.3 -lapse rate: lapse rule 30, 40, 257.5 -lapse rate: lapse rule 31, 42.5, 263.7 -lapse rate: lapse rule 32, 45, 269.9 -lapse rate: lapse rule 33, 47.5, 275.2 -lapse rate: lapse rule 34, 50, 275.7 -lapse rate: lapse rule 35, 55, 269.3 -lapse rate: lapse rule 36, 60, 257.1 -lapse rate: lapse rule 37, 65, 240.1 -lapse rate: lapse rule 38, 70, 218 -lapse rate: lapse rule 39, 75, 196.1 -lapse rate: lapse rule 40, 80, 174.1 -lapse rate: lapse rule 41, 85, 165.1 -lapse rate: lapse rule 42, 90, 165 -lapse rate: lapse rule 43, 95, 178.3 -lapse rate: lapse rule 44, 100, 190.5 -lapse rate: lapse rule 45, 105, 222.2 -lapse rate: lapse rule 46, 110, 262.4 -lapse rate: lapse rule 47, 115, 316.8 -lapse rate: lapse rule 48, 120, 380 - -# h2o composition profile -# composition rules are: name, final height, final value ppmv, molecule the rule applies to -composition rate: h2o rule 0, 1, 0.0138, h2o -composition rate: h2o rule 1, 2, 0.00968, h2o -composition rate: h2o rule 2, 3, 0.00598, h2o -composition rate: h2o rule 3, 4, 0.00381, h2o -composition rate: h2o rule 4, 5, 0.0022299999999999998, h2o -composition rate: h2o rule 5, 6, 0.0015099999999999998, h2o -composition rate: h2o rule 6, 7, 0.0010199999999999999, h2o -composition rate: h2o rule 7, 8, 0.000646, h2o -composition rate: h2o rule 8, 9, 0.00041299999999999996, h2o -composition rate: h2o rule 9, 10, 0.000247, h2o -composition rate: h2o rule 10, 11, 9.559999999999999e-05, h2o -composition rate: h2o rule 11, 12, 2.9399999999999996e-05, h2o -composition rate: h2o rule 12, 13, 8e-06, h2o -composition rate: h2o rule 13, 14, 4.9999999999999996e-06, h2o -composition rate: h2o rule 14, 15, 3.3999999999999996e-06, h2o -composition rate: h2o rule 15, 16, 3.2999999999999997e-06, h2o -composition rate: h2o rule 16, 17, 3.2e-06, h2o -composition rate: h2o rule 17, 18, 3.15e-06, h2o -composition rate: h2o rule 18, 19, 3.2e-06, h2o -composition rate: h2o rule 19, 20, 3.2999999999999997e-06, h2o -composition rate: h2o rule 20, 21, 3.45e-06, h2o -composition rate: h2o rule 21, 22, 3.6e-06, h2o -composition rate: h2o rule 22, 23, 3.8499999999999996e-06, h2o -composition rate: h2o rule 23, 24, 4e-06, h2o -composition rate: h2o rule 24, 25, 4.2e-06, h2o -composition rate: h2o rule 25, 27.6, 4.45e-06, h2o -composition rate: h2o rule 26, 30, 4.7e-06, h2o -composition rate: h2o rule 27, 32.6, 4.87e-06, h2o -composition rate: h2o rule 28, 35, 4.95e-06, h2o -composition rate: h2o rule 29, 37.5, 4.9999999999999996e-06, h2o -composition rate: h2o rule 30, 40, 5.0999999999999995e-06, h2o -composition rate: h2o rule 31, 42.5, 5.299999999999999e-06, h2o -composition rate: h2o rule 32, 45, 5.45e-06, h2o -composition rate: h2o rule 33, 47.5, 5.5e-06, h2o -composition rate: h2o rule 34, 50, 5.5e-06, h2o -composition rate: h2o rule 35, 55, 5.35e-06, h2o -composition rate: h2o rule 36, 60, 4.9999999999999996e-06, h2o -composition rate: h2o rule 37, 65, 4.4e-06, h2o -composition rate: h2o rule 38, 70, 3.7e-06, h2o -composition rate: h2o rule 39, 75, 2.95e-06, h2o -composition rate: h2o rule 40, 80, 2.1e-06, h2o -composition rate: h2o rule 41, 85, 1.33e-06, h2o -composition rate: h2o rule 42, 90, 8.499999999999999e-07, h2o -composition rate: h2o rule 43, 95, 5.4e-07, h2o -composition rate: h2o rule 44, 100, 4e-07, h2o -composition rate: h2o rule 45, 105, 3.4000000000000003e-07, h2o -composition rate: h2o rule 46, 110, 2.8e-07, h2o -composition rate: h2o rule 47, 115, 2.4e-07, h2o -composition rate: h2o rule 48, 120, 2e-07, h2o - -# o3 composition profile -# composition rules are: name, final height, final value ppmv, molecule the rule applies to -composition rate: o3 rule 0, 1, 3.3399999999999995e-08, o3 -composition rate: o3 rule 1, 2, 3.69e-08, o3 -composition rate: o3 rule 2, 3, 4.22e-08, o3 -composition rate: o3 rule 3, 4, 4.8199999999999995e-08, o3 -composition rate: o3 rule 4, 5, 5.5100000000000004e-08, o3 -composition rate: o3 rule 5, 6, 6.41e-08, o3 -composition rate: o3 rule 6, 7, 7.76e-08, o3 -composition rate: o3 rule 7, 8, 9.13e-08, o3 -composition rate: o3 rule 8, 9, 1.11e-07, o3 -composition rate: o3 rule 9, 10, 1.3e-07, o3 -composition rate: o3 rule 10, 11, 1.7899999999999997e-07, o3 -composition rate: o3 rule 11, 12, 2.23e-07, o3 -composition rate: o3 rule 12, 13, 3e-07, o3 -composition rate: o3 rule 13, 14, 4.3999999999999997e-07, o3 -composition rate: o3 rule 14, 15, 5e-07, o3 -composition rate: o3 rule 15, 16, 6e-07, o3 -composition rate: o3 rule 16, 17, 7e-07, o3 -composition rate: o3 rule 17, 18, 1e-06, o3 -composition rate: o3 rule 18, 19, 1.5e-06, o3 -composition rate: o3 rule 19, 20, 2e-06, o3 -composition rate: o3 rule 20, 21, 2.4e-06, o3 -composition rate: o3 rule 21, 22, 2.8999999999999998e-06, o3 -composition rate: o3 rule 22, 23, 3.3999999999999996e-06, o3 -composition rate: o3 rule 23, 24, 4e-06, o3 -composition rate: o3 rule 24, 25, 4.8e-06, o3 -composition rate: o3 rule 25, 27.6, 6e-06, o3 -composition rate: o3 rule 26, 30, 7e-06, o3 -composition rate: o3 rule 27, 32.6, 8.099999999999999e-06, o3 -composition rate: o3 rule 28, 35, 8.9e-06, o3 -composition rate: o3 rule 29, 37.5, 8.7e-06, o3 -composition rate: o3 rule 30, 40, 7.55e-06, o3 -composition rate: o3 rule 31, 42.5, 5.9e-06, o3 -composition rate: o3 rule 32, 45, 4.5e-06, o3 -composition rate: o3 rule 33, 47.5, 3.5e-06, o3 -composition rate: o3 rule 34, 50, 2.8e-06, o3 -composition rate: o3 rule 35, 55, 1.8e-06, o3 -composition rate: o3 rule 36, 60, 1.3e-06, o3 -composition rate: o3 rule 37, 65, 8e-07, o3 -composition rate: o3 rule 38, 70, 4e-07, o3 -composition rate: o3 rule 39, 75, 1.8999999999999998e-07, o3 -composition rate: o3 rule 40, 80, 2e-07, o3 -composition rate: o3 rule 41, 85, 5.699999999999999e-07, o3 -composition rate: o3 rule 42, 90, 7.5e-07, o3 -composition rate: o3 rule 43, 95, 7e-07, o3 -composition rate: o3 rule 44, 100, 4.03e-07, o3 -composition rate: o3 rule 45, 105, 2e-07, o3 -composition rate: o3 rule 46, 110, 5e-08, o3 -composition rate: o3 rule 47, 115, 5e-09, o3 -composition rate: o3 rule 48, 120, 5e-10, o3 - diff --git a/collins 1a double pressure.pyr b/collins 1a double pressure.pyr deleted file mode 100644 index a9d41ae..0000000 --- a/collins 1a double pressure.pyr +++ /dev/null @@ -1,174 +0,0 @@ -# atm profile for midlatitude summer - -# surface values (pressure, temperature, final height, initial layer thickness, acceleration of gravity, range min, range max) -surface: 2010.0, 294.2, 120, 250, 9.8, 100, 2500 - -# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile -# except for co2, o2, n2, and ar -molecule: co2, .000287 -molecule: h2o, 0.0186 -molecule: o2, .20 -molecule: n2, .77 -molecule: ar, .009 -#molecule: ch4, 1.6999999999999998e-06 -molecule: o3, 3.02e-08 -#molecule: n2o, 3.2e-07 -#molecule: co, 1.5e-07 - -# lapse rate profile -# rules are: name, final height, final value -# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule) -lapse rate: lapse rule 0, 1, 289.7 -lapse rate: lapse rule 1, 2, 295.2 -lapse rate: lapse rule 2, 3, 279.2 -lapse rate: lapse rule 3, 4, 273.2 -lapse rate: lapse rule 4, 5, 287.2 -lapse rate: lapse rule 5, 6, 261.2 -lapse rate: lapse rule 6, 7, 254.7 -lapse rate: lapse rule 7, 8, 248.2 -lapse rate: lapse rule 8, 9, 241.7 -lapse rate: lapse rule 9, 10, 235.3 -lapse rate: lapse rule 10, 11, 228.8 -lapse rate: lapse rule 11, 12, 222.3 -lapse rate: lapse rule 12, 13, 215.8 -lapse rate: lapse rule 13, 14, 215.7 -lapse rate: lapse rule 14, 15, 215.7 -lapse rate: lapse rule 15, 16, 215.7 -lapse rate: lapse rule 16, 17, 215.7 -lapse rate: lapse rule 17, 18, 216.8 -lapse rate: lapse rule 18, 19, 217.9 -lapse rate: lapse rule 19, 20, 219.2 -lapse rate: lapse rule 20, 21, 220.4 -lapse rate: lapse rule 21, 22, 221.6 -lapse rate: lapse rule 22, 23, 222.8 -lapse rate: lapse rule 23, 24, 223.9 -lapse rate: lapse rule 24, 25, 225.1 -lapse rate: lapse rule 25, 27.6, 228.5 -lapse rate: lapse rule 26, 30, 233.7 -lapse rate: lapse rule 27, 32.6, 239 -lapse rate: lapse rule 28, 35, 245.2 -lapse rate: lapse rule 29, 37.5, 251.3 -lapse rate: lapse rule 30, 40, 257.5 -lapse rate: lapse rule 31, 42.5, 263.7 -lapse rate: lapse rule 32, 45, 269.9 -lapse rate: lapse rule 33, 47.5, 275.2 -lapse rate: lapse rule 34, 50, 275.7 -lapse rate: lapse rule 35, 55, 269.3 -lapse rate: lapse rule 36, 60, 257.1 -lapse rate: lapse rule 37, 65, 240.1 -lapse rate: lapse rule 38, 70, 218 -lapse rate: lapse rule 39, 75, 196.1 -lapse rate: lapse rule 40, 80, 174.1 -lapse rate: lapse rule 41, 85, 165.1 -lapse rate: lapse rule 42, 90, 165 -lapse rate: lapse rule 43, 95, 178.3 -lapse rate: lapse rule 44, 100, 190.5 -lapse rate: lapse rule 45, 105, 222.2 -lapse rate: lapse rule 46, 110, 262.4 -lapse rate: lapse rule 47, 115, 316.8 -lapse rate: lapse rule 48, 120, 380 - -# h2o composition profile -# composition rules are: name, final height, final value ppmv, molecule the rule applies to -composition rate: h2o rule 0, 1, 0.0138, h2o -composition rate: h2o rule 1, 2, 0.00968, h2o -composition rate: h2o rule 2, 3, 0.00598, h2o -composition rate: h2o rule 3, 4, 0.00381, h2o -composition rate: h2o rule 4, 5, 0.0022299999999999998, h2o -composition rate: h2o rule 5, 6, 0.0015099999999999998, h2o -composition rate: h2o rule 6, 7, 0.0010199999999999999, h2o -composition rate: h2o rule 7, 8, 0.000646, h2o -composition rate: h2o rule 8, 9, 0.00041299999999999996, h2o -composition rate: h2o rule 9, 10, 0.000247, h2o -composition rate: h2o rule 10, 11, 9.559999999999999e-05, h2o -composition rate: h2o rule 11, 12, 2.9399999999999996e-05, h2o -composition rate: h2o rule 12, 13, 8e-06, h2o -composition rate: h2o rule 13, 14, 4.9999999999999996e-06, h2o -composition rate: h2o rule 14, 15, 3.3999999999999996e-06, h2o -composition rate: h2o rule 15, 16, 3.2999999999999997e-06, h2o -composition rate: h2o rule 16, 17, 3.2e-06, h2o -composition rate: h2o rule 17, 18, 3.15e-06, h2o -composition rate: h2o rule 18, 19, 3.2e-06, h2o -composition rate: h2o rule 19, 20, 3.2999999999999997e-06, h2o -composition rate: h2o rule 20, 21, 3.45e-06, h2o -composition rate: h2o rule 21, 22, 3.6e-06, h2o -composition rate: h2o rule 22, 23, 3.8499999999999996e-06, h2o -composition rate: h2o rule 23, 24, 4e-06, h2o -composition rate: h2o rule 24, 25, 4.2e-06, h2o -composition rate: h2o rule 25, 27.6, 4.45e-06, h2o -composition rate: h2o rule 26, 30, 4.7e-06, h2o -composition rate: h2o rule 27, 32.6, 4.87e-06, h2o -composition rate: h2o rule 28, 35, 4.95e-06, h2o -composition rate: h2o rule 29, 37.5, 4.9999999999999996e-06, h2o -composition rate: h2o rule 30, 40, 5.0999999999999995e-06, h2o -composition rate: h2o rule 31, 42.5, 5.299999999999999e-06, h2o -composition rate: h2o rule 32, 45, 5.45e-06, h2o -composition rate: h2o rule 33, 47.5, 5.5e-06, h2o -composition rate: h2o rule 34, 50, 5.5e-06, h2o -composition rate: h2o rule 35, 55, 5.35e-06, h2o -composition rate: h2o rule 36, 60, 4.9999999999999996e-06, h2o -composition rate: h2o rule 37, 65, 4.4e-06, h2o -composition rate: h2o rule 38, 70, 3.7e-06, h2o -composition rate: h2o rule 39, 75, 2.95e-06, h2o -composition rate: h2o rule 40, 80, 2.1e-06, h2o -composition rate: h2o rule 41, 85, 1.33e-06, h2o -composition rate: h2o rule 42, 90, 8.499999999999999e-07, h2o -composition rate: h2o rule 43, 95, 5.4e-07, h2o -composition rate: h2o rule 44, 100, 4e-07, h2o -composition rate: h2o rule 45, 105, 3.4000000000000003e-07, h2o -composition rate: h2o rule 46, 110, 2.8e-07, h2o -composition rate: h2o rule 47, 115, 2.4e-07, h2o -composition rate: h2o rule 48, 120, 2e-07, h2o - -# o3 composition profile -# composition rules are: name, final height, final value ppmv, molecule the rule applies to -composition rate: o3 rule 0, 1, 3.3399999999999995e-08, o3 -composition rate: o3 rule 1, 2, 3.69e-08, o3 -composition rate: o3 rule 2, 3, 4.22e-08, o3 -composition rate: o3 rule 3, 4, 4.8199999999999995e-08, o3 -composition rate: o3 rule 4, 5, 5.5100000000000004e-08, o3 -composition rate: o3 rule 5, 6, 6.41e-08, o3 -composition rate: o3 rule 6, 7, 7.76e-08, o3 -composition rate: o3 rule 7, 8, 9.13e-08, o3 -composition rate: o3 rule 8, 9, 1.11e-07, o3 -composition rate: o3 rule 9, 10, 1.3e-07, o3 -composition rate: o3 rule 10, 11, 1.7899999999999997e-07, o3 -composition rate: o3 rule 11, 12, 2.23e-07, o3 -composition rate: o3 rule 12, 13, 3e-07, o3 -composition rate: o3 rule 13, 14, 4.3999999999999997e-07, o3 -composition rate: o3 rule 14, 15, 5e-07, o3 -composition rate: o3 rule 15, 16, 6e-07, o3 -composition rate: o3 rule 16, 17, 7e-07, o3 -composition rate: o3 rule 17, 18, 1e-06, o3 -composition rate: o3 rule 18, 19, 1.5e-06, o3 -composition rate: o3 rule 19, 20, 2e-06, o3 -composition rate: o3 rule 20, 21, 2.4e-06, o3 -composition rate: o3 rule 21, 22, 2.8999999999999998e-06, o3 -composition rate: o3 rule 22, 23, 3.3999999999999996e-06, o3 -composition rate: o3 rule 23, 24, 4e-06, o3 -composition rate: o3 rule 24, 25, 4.8e-06, o3 -composition rate: o3 rule 25, 27.6, 6e-06, o3 -composition rate: o3 rule 26, 30, 7e-06, o3 -composition rate: o3 rule 27, 32.6, 8.099999999999999e-06, o3 -composition rate: o3 rule 28, 35, 8.9e-06, o3 -composition rate: o3 rule 29, 37.5, 8.7e-06, o3 -composition rate: o3 rule 30, 40, 7.55e-06, o3 -composition rate: o3 rule 31, 42.5, 5.9e-06, o3 -composition rate: o3 rule 32, 45, 4.5e-06, o3 -composition rate: o3 rule 33, 47.5, 3.5e-06, o3 -composition rate: o3 rule 34, 50, 2.8e-06, o3 -composition rate: o3 rule 35, 55, 1.8e-06, o3 -composition rate: o3 rule 36, 60, 1.3e-06, o3 -composition rate: o3 rule 37, 65, 8e-07, o3 -composition rate: o3 rule 38, 70, 4e-07, o3 -composition rate: o3 rule 39, 75, 1.8999999999999998e-07, o3 -composition rate: o3 rule 40, 80, 2e-07, o3 -composition rate: o3 rule 41, 85, 5.699999999999999e-07, o3 -composition rate: o3 rule 42, 90, 7.5e-07, o3 -composition rate: o3 rule 43, 95, 7e-07, o3 -composition rate: o3 rule 44, 100, 4.03e-07, o3 -composition rate: o3 rule 45, 105, 2e-07, o3 -composition rate: o3 rule 46, 110, 5e-08, o3 -composition rate: o3 rule 47, 115, 5e-09, o3 -composition rate: o3 rule 48, 120, 5e-10, o3 - diff --git a/collins 1a.pyr b/collins 1a.pyr deleted file mode 100644 index 0541c9c..0000000 --- a/collins 1a.pyr +++ /dev/null @@ -1,174 +0,0 @@ -# atm profile for midlatitude summer - -# surface values (pressure, temperature, final height, initial layer thickness, acceleration of gravity, range min, range max) -surface: 1010.0, 294.2, 120, 100, 9.8, 100, 2500 - -# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile -# except for co2, o2, n2, and ar -molecule: co2, .000287 -molecule: h2o, 0.0186 -molecule: o2, .20 -molecule: n2, .77 -molecule: ar, .009 -#molecule: ch4, 1.6999999999999998e-06 -molecule: o3, 3.02e-08 -#molecule: n2o, 3.2e-07 -#molecule: co, 1.5e-07 - -# lapse rate profile -# rules are: name, final height, final value -# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule) -lapse rate: lapse rule 0, 1, 289.7 -lapse rate: lapse rule 1, 2, 295.2 -lapse rate: lapse rule 2, 3, 279.2 -lapse rate: lapse rule 3, 4, 273.2 -lapse rate: lapse rule 4, 5, 287.2 -lapse rate: lapse rule 5, 6, 261.2 -lapse rate: lapse rule 6, 7, 254.7 -lapse rate: lapse rule 7, 8, 248.2 -lapse rate: lapse rule 8, 9, 241.7 -lapse rate: lapse rule 9, 10, 235.3 -lapse rate: lapse rule 10, 11, 228.8 -lapse rate: lapse rule 11, 12, 222.3 -lapse rate: lapse rule 12, 13, 215.8 -lapse rate: lapse rule 13, 14, 215.7 -lapse rate: lapse rule 14, 15, 215.7 -lapse rate: lapse rule 15, 16, 215.7 -lapse rate: lapse rule 16, 17, 215.7 -lapse rate: lapse rule 17, 18, 216.8 -lapse rate: lapse rule 18, 19, 217.9 -lapse rate: lapse rule 19, 20, 219.2 -lapse rate: lapse rule 20, 21, 220.4 -lapse rate: lapse rule 21, 22, 221.6 -lapse rate: lapse rule 22, 23, 222.8 -lapse rate: lapse rule 23, 24, 223.9 -lapse rate: lapse rule 24, 25, 225.1 -lapse rate: lapse rule 25, 27.6, 228.5 -lapse rate: lapse rule 26, 30, 233.7 -lapse rate: lapse rule 27, 32.6, 239 -lapse rate: lapse rule 28, 35, 245.2 -lapse rate: lapse rule 29, 37.5, 251.3 -lapse rate: lapse rule 30, 40, 257.5 -lapse rate: lapse rule 31, 42.5, 263.7 -lapse rate: lapse rule 32, 45, 269.9 -lapse rate: lapse rule 33, 47.5, 275.2 -lapse rate: lapse rule 34, 50, 275.7 -lapse rate: lapse rule 35, 55, 269.3 -lapse rate: lapse rule 36, 60, 257.1 -lapse rate: lapse rule 37, 65, 240.1 -lapse rate: lapse rule 38, 70, 218 -lapse rate: lapse rule 39, 75, 196.1 -lapse rate: lapse rule 40, 80, 174.1 -lapse rate: lapse rule 41, 85, 165.1 -lapse rate: lapse rule 42, 90, 165 -lapse rate: lapse rule 43, 95, 178.3 -lapse rate: lapse rule 44, 100, 190.5 -lapse rate: lapse rule 45, 105, 222.2 -lapse rate: lapse rule 46, 110, 262.4 -lapse rate: lapse rule 47, 115, 316.8 -lapse rate: lapse rule 48, 120, 380 - -# h2o composition profile -# composition rules are: name, final height, final value ppmv, molecule the rule applies to -composition rate: h2o rule 0, 1, 0.0138, h2o -composition rate: h2o rule 1, 2, 0.00968, h2o -composition rate: h2o rule 2, 3, 0.00598, h2o -composition rate: h2o rule 3, 4, 0.00381, h2o -composition rate: h2o rule 4, 5, 0.0022299999999999998, h2o -composition rate: h2o rule 5, 6, 0.0015099999999999998, h2o -composition rate: h2o rule 6, 7, 0.0010199999999999999, h2o -composition rate: h2o rule 7, 8, 0.000646, h2o -composition rate: h2o rule 8, 9, 0.00041299999999999996, h2o -composition rate: h2o rule 9, 10, 0.000247, h2o -composition rate: h2o rule 10, 11, 9.559999999999999e-05, h2o -composition rate: h2o rule 11, 12, 2.9399999999999996e-05, h2o -composition rate: h2o rule 12, 13, 8e-06, h2o -composition rate: h2o rule 13, 14, 4.9999999999999996e-06, h2o -composition rate: h2o rule 14, 15, 3.3999999999999996e-06, h2o -composition rate: h2o rule 15, 16, 3.2999999999999997e-06, h2o -composition rate: h2o rule 16, 17, 3.2e-06, h2o -composition rate: h2o rule 17, 18, 3.15e-06, h2o -composition rate: h2o rule 18, 19, 3.2e-06, h2o -composition rate: h2o rule 19, 20, 3.2999999999999997e-06, h2o -composition rate: h2o rule 20, 21, 3.45e-06, h2o -composition rate: h2o rule 21, 22, 3.6e-06, h2o -composition rate: h2o rule 22, 23, 3.8499999999999996e-06, h2o -composition rate: h2o rule 23, 24, 4e-06, h2o -composition rate: h2o rule 24, 25, 4.2e-06, h2o -composition rate: h2o rule 25, 27.6, 4.45e-06, h2o -composition rate: h2o rule 26, 30, 4.7e-06, h2o -composition rate: h2o rule 27, 32.6, 4.87e-06, h2o -composition rate: h2o rule 28, 35, 4.95e-06, h2o -composition rate: h2o rule 29, 37.5, 4.9999999999999996e-06, h2o -composition rate: h2o rule 30, 40, 5.0999999999999995e-06, h2o -composition rate: h2o rule 31, 42.5, 5.299999999999999e-06, h2o -composition rate: h2o rule 32, 45, 5.45e-06, h2o -composition rate: h2o rule 33, 47.5, 5.5e-06, h2o -composition rate: h2o rule 34, 50, 5.5e-06, h2o -composition rate: h2o rule 35, 55, 5.35e-06, h2o -composition rate: h2o rule 36, 60, 4.9999999999999996e-06, h2o -composition rate: h2o rule 37, 65, 4.4e-06, h2o -composition rate: h2o rule 38, 70, 3.7e-06, h2o -composition rate: h2o rule 39, 75, 2.95e-06, h2o -composition rate: h2o rule 40, 80, 2.1e-06, h2o -composition rate: h2o rule 41, 85, 1.33e-06, h2o -composition rate: h2o rule 42, 90, 8.499999999999999e-07, h2o -composition rate: h2o rule 43, 95, 5.4e-07, h2o -composition rate: h2o rule 44, 100, 4e-07, h2o -composition rate: h2o rule 45, 105, 3.4000000000000003e-07, h2o -composition rate: h2o rule 46, 110, 2.8e-07, h2o -composition rate: h2o rule 47, 115, 2.4e-07, h2o -composition rate: h2o rule 48, 120, 2e-07, h2o - -# o3 composition profile -# composition rules are: name, final height, final value ppmv, molecule the rule applies to -composition rate: o3 rule 0, 1, 3.3399999999999995e-08, o3 -composition rate: o3 rule 1, 2, 3.69e-08, o3 -composition rate: o3 rule 2, 3, 4.22e-08, o3 -composition rate: o3 rule 3, 4, 4.8199999999999995e-08, o3 -composition rate: o3 rule 4, 5, 5.5100000000000004e-08, o3 -composition rate: o3 rule 5, 6, 6.41e-08, o3 -composition rate: o3 rule 6, 7, 7.76e-08, o3 -composition rate: o3 rule 7, 8, 9.13e-08, o3 -composition rate: o3 rule 8, 9, 1.11e-07, o3 -composition rate: o3 rule 9, 10, 1.3e-07, o3 -composition rate: o3 rule 10, 11, 1.7899999999999997e-07, o3 -composition rate: o3 rule 11, 12, 2.23e-07, o3 -composition rate: o3 rule 12, 13, 3e-07, o3 -composition rate: o3 rule 13, 14, 4.3999999999999997e-07, o3 -composition rate: o3 rule 14, 15, 5e-07, o3 -composition rate: o3 rule 15, 16, 6e-07, o3 -composition rate: o3 rule 16, 17, 7e-07, o3 -composition rate: o3 rule 17, 18, 1e-06, o3 -composition rate: o3 rule 18, 19, 1.5e-06, o3 -composition rate: o3 rule 19, 20, 2e-06, o3 -composition rate: o3 rule 20, 21, 2.4e-06, o3 -composition rate: o3 rule 21, 22, 2.8999999999999998e-06, o3 -composition rate: o3 rule 22, 23, 3.3999999999999996e-06, o3 -composition rate: o3 rule 23, 24, 4e-06, o3 -composition rate: o3 rule 24, 25, 4.8e-06, o3 -composition rate: o3 rule 25, 27.6, 6e-06, o3 -composition rate: o3 rule 26, 30, 7e-06, o3 -composition rate: o3 rule 27, 32.6, 8.099999999999999e-06, o3 -composition rate: o3 rule 28, 35, 8.9e-06, o3 -composition rate: o3 rule 29, 37.5, 8.7e-06, o3 -composition rate: o3 rule 30, 40, 7.55e-06, o3 -composition rate: o3 rule 31, 42.5, 5.9e-06, o3 -composition rate: o3 rule 32, 45, 4.5e-06, o3 -composition rate: o3 rule 33, 47.5, 3.5e-06, o3 -composition rate: o3 rule 34, 50, 2.8e-06, o3 -composition rate: o3 rule 35, 55, 1.8e-06, o3 -composition rate: o3 rule 36, 60, 1.3e-06, o3 -composition rate: o3 rule 37, 65, 8e-07, o3 -composition rate: o3 rule 38, 70, 4e-07, o3 -composition rate: o3 rule 39, 75, 1.8999999999999998e-07, o3 -composition rate: o3 rule 40, 80, 2e-07, o3 -composition rate: o3 rule 41, 85, 5.699999999999999e-07, o3 -composition rate: o3 rule 42, 90, 7.5e-07, o3 -composition rate: o3 rule 43, 95, 7e-07, o3 -composition rate: o3 rule 44, 100, 4.03e-07, o3 -composition rate: o3 rule 45, 105, 2e-07, o3 -composition rate: o3 rule 46, 110, 5e-08, o3 -composition rate: o3 rule 47, 115, 5e-09, o3 -composition rate: o3 rule 48, 120, 5e-10, o3 - diff --git a/collins 2a 25 slices.pyr b/collins 2a 25 slices.pyr deleted file mode 100644 index 69aa745..0000000 --- a/collins 2a 25 slices.pyr +++ /dev/null @@ -1,174 +0,0 @@ -# atm profile for midlatitude summer - -# surface values (pressure, temperature, final height, initial layer thickness, acceleration of gravity, range min, range max) -surface: 1010.0, 294.2, 120, 400, 9.8, 100, 2500 - -# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile -# except for co2, o2, n2, and ar -molecule: co2, .000369 -molecule: h2o, 0.0186 -molecule: o2, .20 -molecule: n2, .77 -molecule: ar, .009 -#molecule: ch4, 1.6999999999999998e-06 -molecule: o3, 3.02e-08 -#molecule: n2o, 3.2e-07 -#molecule: co, 1.5e-07 - -# lapse rate profile -# rules are: name, final height, final value -# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule) -lapse rate: lapse rule 0, 1, 289.7 -lapse rate: lapse rule 1, 2, 295.2 -lapse rate: lapse rule 2, 3, 279.2 -lapse rate: lapse rule 3, 4, 273.2 -lapse rate: lapse rule 4, 5, 287.2 -lapse rate: lapse rule 5, 6, 261.2 -lapse rate: lapse rule 6, 7, 254.7 -lapse rate: lapse rule 7, 8, 248.2 -lapse rate: lapse rule 8, 9, 241.7 -lapse rate: lapse rule 9, 10, 235.3 -lapse rate: lapse rule 10, 11, 228.8 -lapse rate: lapse rule 11, 12, 222.3 -lapse rate: lapse rule 12, 13, 215.8 -lapse rate: lapse rule 13, 14, 215.7 -lapse rate: lapse rule 14, 15, 215.7 -lapse rate: lapse rule 15, 16, 215.7 -lapse rate: lapse rule 16, 17, 215.7 -lapse rate: lapse rule 17, 18, 216.8 -lapse rate: lapse rule 18, 19, 217.9 -lapse rate: lapse rule 19, 20, 219.2 -lapse rate: lapse rule 20, 21, 220.4 -lapse rate: lapse rule 21, 22, 221.6 -lapse rate: lapse rule 22, 23, 222.8 -lapse rate: lapse rule 23, 24, 223.9 -lapse rate: lapse rule 24, 25, 225.1 -lapse rate: lapse rule 25, 27.6, 228.5 -lapse rate: lapse rule 26, 30, 233.7 -lapse rate: lapse rule 27, 32.6, 239 -lapse rate: lapse rule 28, 35, 245.2 -lapse rate: lapse rule 29, 37.5, 251.3 -lapse rate: lapse rule 30, 40, 257.5 -lapse rate: lapse rule 31, 42.5, 263.7 -lapse rate: lapse rule 32, 45, 269.9 -lapse rate: lapse rule 33, 47.5, 275.2 -lapse rate: lapse rule 34, 50, 275.7 -lapse rate: lapse rule 35, 55, 269.3 -lapse rate: lapse rule 36, 60, 257.1 -lapse rate: lapse rule 37, 65, 240.1 -lapse rate: lapse rule 38, 70, 218 -lapse rate: lapse rule 39, 75, 196.1 -lapse rate: lapse rule 40, 80, 174.1 -lapse rate: lapse rule 41, 85, 165.1 -lapse rate: lapse rule 42, 90, 165 -lapse rate: lapse rule 43, 95, 178.3 -lapse rate: lapse rule 44, 100, 190.5 -lapse rate: lapse rule 45, 105, 222.2 -lapse rate: lapse rule 46, 110, 262.4 -lapse rate: lapse rule 47, 115, 316.8 -lapse rate: lapse rule 48, 120, 380 - -# h2o composition profile -# composition rules are: name, final height, final value ppmv, molecule the rule applies to -composition rate: h2o rule 0, 1, 0.0138, h2o -composition rate: h2o rule 1, 2, 0.00968, h2o -composition rate: h2o rule 2, 3, 0.00598, h2o -composition rate: h2o rule 3, 4, 0.00381, h2o -composition rate: h2o rule 4, 5, 0.0022299999999999998, h2o -composition rate: h2o rule 5, 6, 0.0015099999999999998, h2o -composition rate: h2o rule 6, 7, 0.0010199999999999999, h2o -composition rate: h2o rule 7, 8, 0.000646, h2o -composition rate: h2o rule 8, 9, 0.00041299999999999996, h2o -composition rate: h2o rule 9, 10, 0.000247, h2o -composition rate: h2o rule 10, 11, 9.559999999999999e-05, h2o -composition rate: h2o rule 11, 12, 2.9399999999999996e-05, h2o -composition rate: h2o rule 12, 13, 8e-06, h2o -composition rate: h2o rule 13, 14, 4.9999999999999996e-06, h2o -composition rate: h2o rule 14, 15, 3.3999999999999996e-06, h2o -composition rate: h2o rule 15, 16, 3.2999999999999997e-06, h2o -composition rate: h2o rule 16, 17, 3.2e-06, h2o -composition rate: h2o rule 17, 18, 3.15e-06, h2o -composition rate: h2o rule 18, 19, 3.2e-06, h2o -composition rate: h2o rule 19, 20, 3.2999999999999997e-06, h2o -composition rate: h2o rule 20, 21, 3.45e-06, h2o -composition rate: h2o rule 21, 22, 3.6e-06, h2o -composition rate: h2o rule 22, 23, 3.8499999999999996e-06, h2o -composition rate: h2o rule 23, 24, 4e-06, h2o -composition rate: h2o rule 24, 25, 4.2e-06, h2o -composition rate: h2o rule 25, 27.6, 4.45e-06, h2o -composition rate: h2o rule 26, 30, 4.7e-06, h2o -composition rate: h2o rule 27, 32.6, 4.87e-06, h2o -composition rate: h2o rule 28, 35, 4.95e-06, h2o -composition rate: h2o rule 29, 37.5, 4.9999999999999996e-06, h2o -composition rate: h2o rule 30, 40, 5.0999999999999995e-06, h2o -composition rate: h2o rule 31, 42.5, 5.299999999999999e-06, h2o -composition rate: h2o rule 32, 45, 5.45e-06, h2o -composition rate: h2o rule 33, 47.5, 5.5e-06, h2o -composition rate: h2o rule 34, 50, 5.5e-06, h2o -composition rate: h2o rule 35, 55, 5.35e-06, h2o -composition rate: h2o rule 36, 60, 4.9999999999999996e-06, h2o -composition rate: h2o rule 37, 65, 4.4e-06, h2o -composition rate: h2o rule 38, 70, 3.7e-06, h2o -composition rate: h2o rule 39, 75, 2.95e-06, h2o -composition rate: h2o rule 40, 80, 2.1e-06, h2o -composition rate: h2o rule 41, 85, 1.33e-06, h2o -composition rate: h2o rule 42, 90, 8.499999999999999e-07, h2o -composition rate: h2o rule 43, 95, 5.4e-07, h2o -composition rate: h2o rule 44, 100, 4e-07, h2o -composition rate: h2o rule 45, 105, 3.4000000000000003e-07, h2o -composition rate: h2o rule 46, 110, 2.8e-07, h2o -composition rate: h2o rule 47, 115, 2.4e-07, h2o -composition rate: h2o rule 48, 120, 2e-07, h2o - -# o3 composition profile -# composition rules are: name, final height, final value ppmv, molecule the rule applies to -composition rate: o3 rule 0, 1, 3.3399999999999995e-08, o3 -composition rate: o3 rule 1, 2, 3.69e-08, o3 -composition rate: o3 rule 2, 3, 4.22e-08, o3 -composition rate: o3 rule 3, 4, 4.8199999999999995e-08, o3 -composition rate: o3 rule 4, 5, 5.5100000000000004e-08, o3 -composition rate: o3 rule 5, 6, 6.41e-08, o3 -composition rate: o3 rule 6, 7, 7.76e-08, o3 -composition rate: o3 rule 7, 8, 9.13e-08, o3 -composition rate: o3 rule 8, 9, 1.11e-07, o3 -composition rate: o3 rule 9, 10, 1.3e-07, o3 -composition rate: o3 rule 10, 11, 1.7899999999999997e-07, o3 -composition rate: o3 rule 11, 12, 2.23e-07, o3 -composition rate: o3 rule 12, 13, 3e-07, o3 -composition rate: o3 rule 13, 14, 4.3999999999999997e-07, o3 -composition rate: o3 rule 14, 15, 5e-07, o3 -composition rate: o3 rule 15, 16, 6e-07, o3 -composition rate: o3 rule 16, 17, 7e-07, o3 -composition rate: o3 rule 17, 18, 1e-06, o3 -composition rate: o3 rule 18, 19, 1.5e-06, o3 -composition rate: o3 rule 19, 20, 2e-06, o3 -composition rate: o3 rule 20, 21, 2.4e-06, o3 -composition rate: o3 rule 21, 22, 2.8999999999999998e-06, o3 -composition rate: o3 rule 22, 23, 3.3999999999999996e-06, o3 -composition rate: o3 rule 23, 24, 4e-06, o3 -composition rate: o3 rule 24, 25, 4.8e-06, o3 -composition rate: o3 rule 25, 27.6, 6e-06, o3 -composition rate: o3 rule 26, 30, 7e-06, o3 -composition rate: o3 rule 27, 32.6, 8.099999999999999e-06, o3 -composition rate: o3 rule 28, 35, 8.9e-06, o3 -composition rate: o3 rule 29, 37.5, 8.7e-06, o3 -composition rate: o3 rule 30, 40, 7.55e-06, o3 -composition rate: o3 rule 31, 42.5, 5.9e-06, o3 -composition rate: o3 rule 32, 45, 4.5e-06, o3 -composition rate: o3 rule 33, 47.5, 3.5e-06, o3 -composition rate: o3 rule 34, 50, 2.8e-06, o3 -composition rate: o3 rule 35, 55, 1.8e-06, o3 -composition rate: o3 rule 36, 60, 1.3e-06, o3 -composition rate: o3 rule 37, 65, 8e-07, o3 -composition rate: o3 rule 38, 70, 4e-07, o3 -composition rate: o3 rule 39, 75, 1.8999999999999998e-07, o3 -composition rate: o3 rule 40, 80, 2e-07, o3 -composition rate: o3 rule 41, 85, 5.699999999999999e-07, o3 -composition rate: o3 rule 42, 90, 7.5e-07, o3 -composition rate: o3 rule 43, 95, 7e-07, o3 -composition rate: o3 rule 44, 100, 4.03e-07, o3 -composition rate: o3 rule 45, 105, 2e-07, o3 -composition rate: o3 rule 46, 110, 5e-08, o3 -composition rate: o3 rule 47, 115, 5e-09, o3 -composition rate: o3 rule 48, 120, 5e-10, o3 - diff --git a/collins 2a.pyr b/collins 2a.pyr deleted file mode 100644 index fb48a44..0000000 --- a/collins 2a.pyr +++ /dev/null @@ -1,174 +0,0 @@ -# atm profile for midlatitude summer - -# surface values (pressure, temperature, final height, initial layer thickness, acceleration of gravity, range min, range max) -surface: 1010.0, 294.2, 120, 100, 9.8, 100, 2500 - -# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile -# except for co2, o2, n2, and ar -molecule: co2, .000369 -molecule: h2o, 0.0186 -molecule: o2, .20 -molecule: n2, .77 -molecule: ar, .009 -#molecule: ch4, 1.6999999999999998e-06 -molecule: o3, 3.02e-08 -#molecule: n2o, 3.2e-07 -#molecule: co, 1.5e-07 - -# lapse rate profile -# rules are: name, final height, final value -# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule) -lapse rate: lapse rule 0, 1, 289.7 -lapse rate: lapse rule 1, 2, 295.2 -lapse rate: lapse rule 2, 3, 279.2 -lapse rate: lapse rule 3, 4, 273.2 -lapse rate: lapse rule 4, 5, 287.2 -lapse rate: lapse rule 5, 6, 261.2 -lapse rate: lapse rule 6, 7, 254.7 -lapse rate: lapse rule 7, 8, 248.2 -lapse rate: lapse rule 8, 9, 241.7 -lapse rate: lapse rule 9, 10, 235.3 -lapse rate: lapse rule 10, 11, 228.8 -lapse rate: lapse rule 11, 12, 222.3 -lapse rate: lapse rule 12, 13, 215.8 -lapse rate: lapse rule 13, 14, 215.7 -lapse rate: lapse rule 14, 15, 215.7 -lapse rate: lapse rule 15, 16, 215.7 -lapse rate: lapse rule 16, 17, 215.7 -lapse rate: lapse rule 17, 18, 216.8 -lapse rate: lapse rule 18, 19, 217.9 -lapse rate: lapse rule 19, 20, 219.2 -lapse rate: lapse rule 20, 21, 220.4 -lapse rate: lapse rule 21, 22, 221.6 -lapse rate: lapse rule 22, 23, 222.8 -lapse rate: lapse rule 23, 24, 223.9 -lapse rate: lapse rule 24, 25, 225.1 -lapse rate: lapse rule 25, 27.6, 228.5 -lapse rate: lapse rule 26, 30, 233.7 -lapse rate: lapse rule 27, 32.6, 239 -lapse rate: lapse rule 28, 35, 245.2 -lapse rate: lapse rule 29, 37.5, 251.3 -lapse rate: lapse rule 30, 40, 257.5 -lapse rate: lapse rule 31, 42.5, 263.7 -lapse rate: lapse rule 32, 45, 269.9 -lapse rate: lapse rule 33, 47.5, 275.2 -lapse rate: lapse rule 34, 50, 275.7 -lapse rate: lapse rule 35, 55, 269.3 -lapse rate: lapse rule 36, 60, 257.1 -lapse rate: lapse rule 37, 65, 240.1 -lapse rate: lapse rule 38, 70, 218 -lapse rate: lapse rule 39, 75, 196.1 -lapse rate: lapse rule 40, 80, 174.1 -lapse rate: lapse rule 41, 85, 165.1 -lapse rate: lapse rule 42, 90, 165 -lapse rate: lapse rule 43, 95, 178.3 -lapse rate: lapse rule 44, 100, 190.5 -lapse rate: lapse rule 45, 105, 222.2 -lapse rate: lapse rule 46, 110, 262.4 -lapse rate: lapse rule 47, 115, 316.8 -lapse rate: lapse rule 48, 120, 380 - -# h2o composition profile -# composition rules are: name, final height, final value ppmv, molecule the rule applies to -composition rate: h2o rule 0, 1, 0.0138, h2o -composition rate: h2o rule 1, 2, 0.00968, h2o -composition rate: h2o rule 2, 3, 0.00598, h2o -composition rate: h2o rule 3, 4, 0.00381, h2o -composition rate: h2o rule 4, 5, 0.0022299999999999998, h2o -composition rate: h2o rule 5, 6, 0.0015099999999999998, h2o -composition rate: h2o rule 6, 7, 0.0010199999999999999, h2o -composition rate: h2o rule 7, 8, 0.000646, h2o -composition rate: h2o rule 8, 9, 0.00041299999999999996, h2o -composition rate: h2o rule 9, 10, 0.000247, h2o -composition rate: h2o rule 10, 11, 9.559999999999999e-05, h2o -composition rate: h2o rule 11, 12, 2.9399999999999996e-05, h2o -composition rate: h2o rule 12, 13, 8e-06, h2o -composition rate: h2o rule 13, 14, 4.9999999999999996e-06, h2o -composition rate: h2o rule 14, 15, 3.3999999999999996e-06, h2o -composition rate: h2o rule 15, 16, 3.2999999999999997e-06, h2o -composition rate: h2o rule 16, 17, 3.2e-06, h2o -composition rate: h2o rule 17, 18, 3.15e-06, h2o -composition rate: h2o rule 18, 19, 3.2e-06, h2o -composition rate: h2o rule 19, 20, 3.2999999999999997e-06, h2o -composition rate: h2o rule 20, 21, 3.45e-06, h2o -composition rate: h2o rule 21, 22, 3.6e-06, h2o -composition rate: h2o rule 22, 23, 3.8499999999999996e-06, h2o -composition rate: h2o rule 23, 24, 4e-06, h2o -composition rate: h2o rule 24, 25, 4.2e-06, h2o -composition rate: h2o rule 25, 27.6, 4.45e-06, h2o -composition rate: h2o rule 26, 30, 4.7e-06, h2o -composition rate: h2o rule 27, 32.6, 4.87e-06, h2o -composition rate: h2o rule 28, 35, 4.95e-06, h2o -composition rate: h2o rule 29, 37.5, 4.9999999999999996e-06, h2o -composition rate: h2o rule 30, 40, 5.0999999999999995e-06, h2o -composition rate: h2o rule 31, 42.5, 5.299999999999999e-06, h2o -composition rate: h2o rule 32, 45, 5.45e-06, h2o -composition rate: h2o rule 33, 47.5, 5.5e-06, h2o -composition rate: h2o rule 34, 50, 5.5e-06, h2o -composition rate: h2o rule 35, 55, 5.35e-06, h2o -composition rate: h2o rule 36, 60, 4.9999999999999996e-06, h2o -composition rate: h2o rule 37, 65, 4.4e-06, h2o -composition rate: h2o rule 38, 70, 3.7e-06, h2o -composition rate: h2o rule 39, 75, 2.95e-06, h2o -composition rate: h2o rule 40, 80, 2.1e-06, h2o -composition rate: h2o rule 41, 85, 1.33e-06, h2o -composition rate: h2o rule 42, 90, 8.499999999999999e-07, h2o -composition rate: h2o rule 43, 95, 5.4e-07, h2o -composition rate: h2o rule 44, 100, 4e-07, h2o -composition rate: h2o rule 45, 105, 3.4000000000000003e-07, h2o -composition rate: h2o rule 46, 110, 2.8e-07, h2o -composition rate: h2o rule 47, 115, 2.4e-07, h2o -composition rate: h2o rule 48, 120, 2e-07, h2o - -# o3 composition profile -# composition rules are: name, final height, final value ppmv, molecule the rule applies to -composition rate: o3 rule 0, 1, 3.3399999999999995e-08, o3 -composition rate: o3 rule 1, 2, 3.69e-08, o3 -composition rate: o3 rule 2, 3, 4.22e-08, o3 -composition rate: o3 rule 3, 4, 4.8199999999999995e-08, o3 -composition rate: o3 rule 4, 5, 5.5100000000000004e-08, o3 -composition rate: o3 rule 5, 6, 6.41e-08, o3 -composition rate: o3 rule 6, 7, 7.76e-08, o3 -composition rate: o3 rule 7, 8, 9.13e-08, o3 -composition rate: o3 rule 8, 9, 1.11e-07, o3 -composition rate: o3 rule 9, 10, 1.3e-07, o3 -composition rate: o3 rule 10, 11, 1.7899999999999997e-07, o3 -composition rate: o3 rule 11, 12, 2.23e-07, o3 -composition rate: o3 rule 12, 13, 3e-07, o3 -composition rate: o3 rule 13, 14, 4.3999999999999997e-07, o3 -composition rate: o3 rule 14, 15, 5e-07, o3 -composition rate: o3 rule 15, 16, 6e-07, o3 -composition rate: o3 rule 16, 17, 7e-07, o3 -composition rate: o3 rule 17, 18, 1e-06, o3 -composition rate: o3 rule 18, 19, 1.5e-06, o3 -composition rate: o3 rule 19, 20, 2e-06, o3 -composition rate: o3 rule 20, 21, 2.4e-06, o3 -composition rate: o3 rule 21, 22, 2.8999999999999998e-06, o3 -composition rate: o3 rule 22, 23, 3.3999999999999996e-06, o3 -composition rate: o3 rule 23, 24, 4e-06, o3 -composition rate: o3 rule 24, 25, 4.8e-06, o3 -composition rate: o3 rule 25, 27.6, 6e-06, o3 -composition rate: o3 rule 26, 30, 7e-06, o3 -composition rate: o3 rule 27, 32.6, 8.099999999999999e-06, o3 -composition rate: o3 rule 28, 35, 8.9e-06, o3 -composition rate: o3 rule 29, 37.5, 8.7e-06, o3 -composition rate: o3 rule 30, 40, 7.55e-06, o3 -composition rate: o3 rule 31, 42.5, 5.9e-06, o3 -composition rate: o3 rule 32, 45, 4.5e-06, o3 -composition rate: o3 rule 33, 47.5, 3.5e-06, o3 -composition rate: o3 rule 34, 50, 2.8e-06, o3 -composition rate: o3 rule 35, 55, 1.8e-06, o3 -composition rate: o3 rule 36, 60, 1.3e-06, o3 -composition rate: o3 rule 37, 65, 8e-07, o3 -composition rate: o3 rule 38, 70, 4e-07, o3 -composition rate: o3 rule 39, 75, 1.8999999999999998e-07, o3 -composition rate: o3 rule 40, 80, 2e-07, o3 -composition rate: o3 rule 41, 85, 5.699999999999999e-07, o3 -composition rate: o3 rule 42, 90, 7.5e-07, o3 -composition rate: o3 rule 43, 95, 7e-07, o3 -composition rate: o3 rule 44, 100, 4.03e-07, o3 -composition rate: o3 rule 45, 105, 2e-07, o3 -composition rate: o3 rule 46, 110, 5e-08, o3 -composition rate: o3 rule 47, 115, 5e-09, o3 -composition rate: o3 rule 48, 120, 5e-10, o3 - diff --git a/collins 2b 25 slices.pyr b/collins 2b 25 slices.pyr deleted file mode 100644 index 80a8abf..0000000 --- a/collins 2b 25 slices.pyr +++ /dev/null @@ -1,174 +0,0 @@ -# atm profile for midlatitude summer - -# surface values (pressure, temperature, final height, initial layer thickness, acceleration of gravity, range min, range max) -surface: 1010.0, 294.2, 120, 400, 9.8, 100, 2500 - -# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile -# except for co2, o2, n2, and ar -molecule: co2, .000574 -molecule: h2o, 0.0186 -molecule: o2, .20 -molecule: n2, .77 -molecule: ar, .009 -#molecule: ch4, 1.6999999999999998e-06 -molecule: o3, 3.02e-08 -#molecule: n2o, 3.2e-07 -#molecule: co, 1.5e-07 - -# lapse rate profile -# rules are: name, final height, final value -# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule) -lapse rate: lapse rule 0, 1, 289.7 -lapse rate: lapse rule 1, 2, 295.2 -lapse rate: lapse rule 2, 3, 279.2 -lapse rate: lapse rule 3, 4, 273.2 -lapse rate: lapse rule 4, 5, 287.2 -lapse rate: lapse rule 5, 6, 261.2 -lapse rate: lapse rule 6, 7, 254.7 -lapse rate: lapse rule 7, 8, 248.2 -lapse rate: lapse rule 8, 9, 241.7 -lapse rate: lapse rule 9, 10, 235.3 -lapse rate: lapse rule 10, 11, 228.8 -lapse rate: lapse rule 11, 12, 222.3 -lapse rate: lapse rule 12, 13, 215.8 -lapse rate: lapse rule 13, 14, 215.7 -lapse rate: lapse rule 14, 15, 215.7 -lapse rate: lapse rule 15, 16, 215.7 -lapse rate: lapse rule 16, 17, 215.7 -lapse rate: lapse rule 17, 18, 216.8 -lapse rate: lapse rule 18, 19, 217.9 -lapse rate: lapse rule 19, 20, 219.2 -lapse rate: lapse rule 20, 21, 220.4 -lapse rate: lapse rule 21, 22, 221.6 -lapse rate: lapse rule 22, 23, 222.8 -lapse rate: lapse rule 23, 24, 223.9 -lapse rate: lapse rule 24, 25, 225.1 -lapse rate: lapse rule 25, 27.6, 228.5 -lapse rate: lapse rule 26, 30, 233.7 -lapse rate: lapse rule 27, 32.6, 239 -lapse rate: lapse rule 28, 35, 245.2 -lapse rate: lapse rule 29, 37.5, 251.3 -lapse rate: lapse rule 30, 40, 257.5 -lapse rate: lapse rule 31, 42.5, 263.7 -lapse rate: lapse rule 32, 45, 269.9 -lapse rate: lapse rule 33, 47.5, 275.2 -lapse rate: lapse rule 34, 50, 275.7 -lapse rate: lapse rule 35, 55, 269.3 -lapse rate: lapse rule 36, 60, 257.1 -lapse rate: lapse rule 37, 65, 240.1 -lapse rate: lapse rule 38, 70, 218 -lapse rate: lapse rule 39, 75, 196.1 -lapse rate: lapse rule 40, 80, 174.1 -lapse rate: lapse rule 41, 85, 165.1 -lapse rate: lapse rule 42, 90, 165 -lapse rate: lapse rule 43, 95, 178.3 -lapse rate: lapse rule 44, 100, 190.5 -lapse rate: lapse rule 45, 105, 222.2 -lapse rate: lapse rule 46, 110, 262.4 -lapse rate: lapse rule 47, 115, 316.8 -lapse rate: lapse rule 48, 120, 380 - -# h2o composition profile -# composition rules are: name, final height, final value ppmv, molecule the rule applies to -composition rate: h2o rule 0, 1, 0.0138, h2o -composition rate: h2o rule 1, 2, 0.00968, h2o -composition rate: h2o rule 2, 3, 0.00598, h2o -composition rate: h2o rule 3, 4, 0.00381, h2o -composition rate: h2o rule 4, 5, 0.0022299999999999998, h2o -composition rate: h2o rule 5, 6, 0.0015099999999999998, h2o -composition rate: h2o rule 6, 7, 0.0010199999999999999, h2o -composition rate: h2o rule 7, 8, 0.000646, h2o -composition rate: h2o rule 8, 9, 0.00041299999999999996, h2o -composition rate: h2o rule 9, 10, 0.000247, h2o -composition rate: h2o rule 10, 11, 9.559999999999999e-05, h2o -composition rate: h2o rule 11, 12, 2.9399999999999996e-05, h2o -composition rate: h2o rule 12, 13, 8e-06, h2o -composition rate: h2o rule 13, 14, 4.9999999999999996e-06, h2o -composition rate: h2o rule 14, 15, 3.3999999999999996e-06, h2o -composition rate: h2o rule 15, 16, 3.2999999999999997e-06, h2o -composition rate: h2o rule 16, 17, 3.2e-06, h2o -composition rate: h2o rule 17, 18, 3.15e-06, h2o -composition rate: h2o rule 18, 19, 3.2e-06, h2o -composition rate: h2o rule 19, 20, 3.2999999999999997e-06, h2o -composition rate: h2o rule 20, 21, 3.45e-06, h2o -composition rate: h2o rule 21, 22, 3.6e-06, h2o -composition rate: h2o rule 22, 23, 3.8499999999999996e-06, h2o -composition rate: h2o rule 23, 24, 4e-06, h2o -composition rate: h2o rule 24, 25, 4.2e-06, h2o -composition rate: h2o rule 25, 27.6, 4.45e-06, h2o -composition rate: h2o rule 26, 30, 4.7e-06, h2o -composition rate: h2o rule 27, 32.6, 4.87e-06, h2o -composition rate: h2o rule 28, 35, 4.95e-06, h2o -composition rate: h2o rule 29, 37.5, 4.9999999999999996e-06, h2o -composition rate: h2o rule 30, 40, 5.0999999999999995e-06, h2o -composition rate: h2o rule 31, 42.5, 5.299999999999999e-06, h2o -composition rate: h2o rule 32, 45, 5.45e-06, h2o -composition rate: h2o rule 33, 47.5, 5.5e-06, h2o -composition rate: h2o rule 34, 50, 5.5e-06, h2o -composition rate: h2o rule 35, 55, 5.35e-06, h2o -composition rate: h2o rule 36, 60, 4.9999999999999996e-06, h2o -composition rate: h2o rule 37, 65, 4.4e-06, h2o -composition rate: h2o rule 38, 70, 3.7e-06, h2o -composition rate: h2o rule 39, 75, 2.95e-06, h2o -composition rate: h2o rule 40, 80, 2.1e-06, h2o -composition rate: h2o rule 41, 85, 1.33e-06, h2o -composition rate: h2o rule 42, 90, 8.499999999999999e-07, h2o -composition rate: h2o rule 43, 95, 5.4e-07, h2o -composition rate: h2o rule 44, 100, 4e-07, h2o -composition rate: h2o rule 45, 105, 3.4000000000000003e-07, h2o -composition rate: h2o rule 46, 110, 2.8e-07, h2o -composition rate: h2o rule 47, 115, 2.4e-07, h2o -composition rate: h2o rule 48, 120, 2e-07, h2o - -# o3 composition profile -# composition rules are: name, final height, final value ppmv, molecule the rule applies to -composition rate: o3 rule 0, 1, 3.3399999999999995e-08, o3 -composition rate: o3 rule 1, 2, 3.69e-08, o3 -composition rate: o3 rule 2, 3, 4.22e-08, o3 -composition rate: o3 rule 3, 4, 4.8199999999999995e-08, o3 -composition rate: o3 rule 4, 5, 5.5100000000000004e-08, o3 -composition rate: o3 rule 5, 6, 6.41e-08, o3 -composition rate: o3 rule 6, 7, 7.76e-08, o3 -composition rate: o3 rule 7, 8, 9.13e-08, o3 -composition rate: o3 rule 8, 9, 1.11e-07, o3 -composition rate: o3 rule 9, 10, 1.3e-07, o3 -composition rate: o3 rule 10, 11, 1.7899999999999997e-07, o3 -composition rate: o3 rule 11, 12, 2.23e-07, o3 -composition rate: o3 rule 12, 13, 3e-07, o3 -composition rate: o3 rule 13, 14, 4.3999999999999997e-07, o3 -composition rate: o3 rule 14, 15, 5e-07, o3 -composition rate: o3 rule 15, 16, 6e-07, o3 -composition rate: o3 rule 16, 17, 7e-07, o3 -composition rate: o3 rule 17, 18, 1e-06, o3 -composition rate: o3 rule 18, 19, 1.5e-06, o3 -composition rate: o3 rule 19, 20, 2e-06, o3 -composition rate: o3 rule 20, 21, 2.4e-06, o3 -composition rate: o3 rule 21, 22, 2.8999999999999998e-06, o3 -composition rate: o3 rule 22, 23, 3.3999999999999996e-06, o3 -composition rate: o3 rule 23, 24, 4e-06, o3 -composition rate: o3 rule 24, 25, 4.8e-06, o3 -composition rate: o3 rule 25, 27.6, 6e-06, o3 -composition rate: o3 rule 26, 30, 7e-06, o3 -composition rate: o3 rule 27, 32.6, 8.099999999999999e-06, o3 -composition rate: o3 rule 28, 35, 8.9e-06, o3 -composition rate: o3 rule 29, 37.5, 8.7e-06, o3 -composition rate: o3 rule 30, 40, 7.55e-06, o3 -composition rate: o3 rule 31, 42.5, 5.9e-06, o3 -composition rate: o3 rule 32, 45, 4.5e-06, o3 -composition rate: o3 rule 33, 47.5, 3.5e-06, o3 -composition rate: o3 rule 34, 50, 2.8e-06, o3 -composition rate: o3 rule 35, 55, 1.8e-06, o3 -composition rate: o3 rule 36, 60, 1.3e-06, o3 -composition rate: o3 rule 37, 65, 8e-07, o3 -composition rate: o3 rule 38, 70, 4e-07, o3 -composition rate: o3 rule 39, 75, 1.8999999999999998e-07, o3 -composition rate: o3 rule 40, 80, 2e-07, o3 -composition rate: o3 rule 41, 85, 5.699999999999999e-07, o3 -composition rate: o3 rule 42, 90, 7.5e-07, o3 -composition rate: o3 rule 43, 95, 7e-07, o3 -composition rate: o3 rule 44, 100, 4.03e-07, o3 -composition rate: o3 rule 45, 105, 2e-07, o3 -composition rate: o3 rule 46, 110, 5e-08, o3 -composition rate: o3 rule 47, 115, 5e-09, o3 -composition rate: o3 rule 48, 120, 5e-10, o3 - diff --git a/collins 2b.pyr b/collins 2b.pyr deleted file mode 100644 index 9185ede..0000000 --- a/collins 2b.pyr +++ /dev/null @@ -1,174 +0,0 @@ -# atm profile for midlatitude summer - -# surface values (pressure, temperature, final height, initial layer thickness, acceleration of gravity, range min, range max) -surface: 1010.0, 294.2, 120, 100, 9.8, 100, 2500 - -# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile -# except for co2, o2, n2, and ar -molecule: co2, .000574 -molecule: h2o, 0.0186 -molecule: o2, .20 -molecule: n2, .77 -molecule: ar, .009 -#molecule: ch4, 1.6999999999999998e-06 -molecule: o3, 3.02e-08 -#molecule: n2o, 3.2e-07 -#molecule: co, 1.5e-07 - -# lapse rate profile -# rules are: name, final height, final value -# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule) -lapse rate: lapse rule 0, 1, 289.7 -lapse rate: lapse rule 1, 2, 295.2 -lapse rate: lapse rule 2, 3, 279.2 -lapse rate: lapse rule 3, 4, 273.2 -lapse rate: lapse rule 4, 5, 287.2 -lapse rate: lapse rule 5, 6, 261.2 -lapse rate: lapse rule 6, 7, 254.7 -lapse rate: lapse rule 7, 8, 248.2 -lapse rate: lapse rule 8, 9, 241.7 -lapse rate: lapse rule 9, 10, 235.3 -lapse rate: lapse rule 10, 11, 228.8 -lapse rate: lapse rule 11, 12, 222.3 -lapse rate: lapse rule 12, 13, 215.8 -lapse rate: lapse rule 13, 14, 215.7 -lapse rate: lapse rule 14, 15, 215.7 -lapse rate: lapse rule 15, 16, 215.7 -lapse rate: lapse rule 16, 17, 215.7 -lapse rate: lapse rule 17, 18, 216.8 -lapse rate: lapse rule 18, 19, 217.9 -lapse rate: lapse rule 19, 20, 219.2 -lapse rate: lapse rule 20, 21, 220.4 -lapse rate: lapse rule 21, 22, 221.6 -lapse rate: lapse rule 22, 23, 222.8 -lapse rate: lapse rule 23, 24, 223.9 -lapse rate: lapse rule 24, 25, 225.1 -lapse rate: lapse rule 25, 27.6, 228.5 -lapse rate: lapse rule 26, 30, 233.7 -lapse rate: lapse rule 27, 32.6, 239 -lapse rate: lapse rule 28, 35, 245.2 -lapse rate: lapse rule 29, 37.5, 251.3 -lapse rate: lapse rule 30, 40, 257.5 -lapse rate: lapse rule 31, 42.5, 263.7 -lapse rate: lapse rule 32, 45, 269.9 -lapse rate: lapse rule 33, 47.5, 275.2 -lapse rate: lapse rule 34, 50, 275.7 -lapse rate: lapse rule 35, 55, 269.3 -lapse rate: lapse rule 36, 60, 257.1 -lapse rate: lapse rule 37, 65, 240.1 -lapse rate: lapse rule 38, 70, 218 -lapse rate: lapse rule 39, 75, 196.1 -lapse rate: lapse rule 40, 80, 174.1 -lapse rate: lapse rule 41, 85, 165.1 -lapse rate: lapse rule 42, 90, 165 -lapse rate: lapse rule 43, 95, 178.3 -lapse rate: lapse rule 44, 100, 190.5 -lapse rate: lapse rule 45, 105, 222.2 -lapse rate: lapse rule 46, 110, 262.4 -lapse rate: lapse rule 47, 115, 316.8 -lapse rate: lapse rule 48, 120, 380 - -# h2o composition profile -# composition rules are: name, final height, final value ppmv, molecule the rule applies to -composition rate: h2o rule 0, 1, 0.0138, h2o -composition rate: h2o rule 1, 2, 0.00968, h2o -composition rate: h2o rule 2, 3, 0.00598, h2o -composition rate: h2o rule 3, 4, 0.00381, h2o -composition rate: h2o rule 4, 5, 0.0022299999999999998, h2o -composition rate: h2o rule 5, 6, 0.0015099999999999998, h2o -composition rate: h2o rule 6, 7, 0.0010199999999999999, h2o -composition rate: h2o rule 7, 8, 0.000646, h2o -composition rate: h2o rule 8, 9, 0.00041299999999999996, h2o -composition rate: h2o rule 9, 10, 0.000247, h2o -composition rate: h2o rule 10, 11, 9.559999999999999e-05, h2o -composition rate: h2o rule 11, 12, 2.9399999999999996e-05, h2o -composition rate: h2o rule 12, 13, 8e-06, h2o -composition rate: h2o rule 13, 14, 4.9999999999999996e-06, h2o -composition rate: h2o rule 14, 15, 3.3999999999999996e-06, h2o -composition rate: h2o rule 15, 16, 3.2999999999999997e-06, h2o -composition rate: h2o rule 16, 17, 3.2e-06, h2o -composition rate: h2o rule 17, 18, 3.15e-06, h2o -composition rate: h2o rule 18, 19, 3.2e-06, h2o -composition rate: h2o rule 19, 20, 3.2999999999999997e-06, h2o -composition rate: h2o rule 20, 21, 3.45e-06, h2o -composition rate: h2o rule 21, 22, 3.6e-06, h2o -composition rate: h2o rule 22, 23, 3.8499999999999996e-06, h2o -composition rate: h2o rule 23, 24, 4e-06, h2o -composition rate: h2o rule 24, 25, 4.2e-06, h2o -composition rate: h2o rule 25, 27.6, 4.45e-06, h2o -composition rate: h2o rule 26, 30, 4.7e-06, h2o -composition rate: h2o rule 27, 32.6, 4.87e-06, h2o -composition rate: h2o rule 28, 35, 4.95e-06, h2o -composition rate: h2o rule 29, 37.5, 4.9999999999999996e-06, h2o -composition rate: h2o rule 30, 40, 5.0999999999999995e-06, h2o -composition rate: h2o rule 31, 42.5, 5.299999999999999e-06, h2o -composition rate: h2o rule 32, 45, 5.45e-06, h2o -composition rate: h2o rule 33, 47.5, 5.5e-06, h2o -composition rate: h2o rule 34, 50, 5.5e-06, h2o -composition rate: h2o rule 35, 55, 5.35e-06, h2o -composition rate: h2o rule 36, 60, 4.9999999999999996e-06, h2o -composition rate: h2o rule 37, 65, 4.4e-06, h2o -composition rate: h2o rule 38, 70, 3.7e-06, h2o -composition rate: h2o rule 39, 75, 2.95e-06, h2o -composition rate: h2o rule 40, 80, 2.1e-06, h2o -composition rate: h2o rule 41, 85, 1.33e-06, h2o -composition rate: h2o rule 42, 90, 8.499999999999999e-07, h2o -composition rate: h2o rule 43, 95, 5.4e-07, h2o -composition rate: h2o rule 44, 100, 4e-07, h2o -composition rate: h2o rule 45, 105, 3.4000000000000003e-07, h2o -composition rate: h2o rule 46, 110, 2.8e-07, h2o -composition rate: h2o rule 47, 115, 2.4e-07, h2o -composition rate: h2o rule 48, 120, 2e-07, h2o - -# o3 composition profile -# composition rules are: name, final height, final value ppmv, molecule the rule applies to -composition rate: o3 rule 0, 1, 3.3399999999999995e-08, o3 -composition rate: o3 rule 1, 2, 3.69e-08, o3 -composition rate: o3 rule 2, 3, 4.22e-08, o3 -composition rate: o3 rule 3, 4, 4.8199999999999995e-08, o3 -composition rate: o3 rule 4, 5, 5.5100000000000004e-08, o3 -composition rate: o3 rule 5, 6, 6.41e-08, o3 -composition rate: o3 rule 6, 7, 7.76e-08, o3 -composition rate: o3 rule 7, 8, 9.13e-08, o3 -composition rate: o3 rule 8, 9, 1.11e-07, o3 -composition rate: o3 rule 9, 10, 1.3e-07, o3 -composition rate: o3 rule 10, 11, 1.7899999999999997e-07, o3 -composition rate: o3 rule 11, 12, 2.23e-07, o3 -composition rate: o3 rule 12, 13, 3e-07, o3 -composition rate: o3 rule 13, 14, 4.3999999999999997e-07, o3 -composition rate: o3 rule 14, 15, 5e-07, o3 -composition rate: o3 rule 15, 16, 6e-07, o3 -composition rate: o3 rule 16, 17, 7e-07, o3 -composition rate: o3 rule 17, 18, 1e-06, o3 -composition rate: o3 rule 18, 19, 1.5e-06, o3 -composition rate: o3 rule 19, 20, 2e-06, o3 -composition rate: o3 rule 20, 21, 2.4e-06, o3 -composition rate: o3 rule 21, 22, 2.8999999999999998e-06, o3 -composition rate: o3 rule 22, 23, 3.3999999999999996e-06, o3 -composition rate: o3 rule 23, 24, 4e-06, o3 -composition rate: o3 rule 24, 25, 4.8e-06, o3 -composition rate: o3 rule 25, 27.6, 6e-06, o3 -composition rate: o3 rule 26, 30, 7e-06, o3 -composition rate: o3 rule 27, 32.6, 8.099999999999999e-06, o3 -composition rate: o3 rule 28, 35, 8.9e-06, o3 -composition rate: o3 rule 29, 37.5, 8.7e-06, o3 -composition rate: o3 rule 30, 40, 7.55e-06, o3 -composition rate: o3 rule 31, 42.5, 5.9e-06, o3 -composition rate: o3 rule 32, 45, 4.5e-06, o3 -composition rate: o3 rule 33, 47.5, 3.5e-06, o3 -composition rate: o3 rule 34, 50, 2.8e-06, o3 -composition rate: o3 rule 35, 55, 1.8e-06, o3 -composition rate: o3 rule 36, 60, 1.3e-06, o3 -composition rate: o3 rule 37, 65, 8e-07, o3 -composition rate: o3 rule 38, 70, 4e-07, o3 -composition rate: o3 rule 39, 75, 1.8999999999999998e-07, o3 -composition rate: o3 rule 40, 80, 2e-07, o3 -composition rate: o3 rule 41, 85, 5.699999999999999e-07, o3 -composition rate: o3 rule 42, 90, 7.5e-07, o3 -composition rate: o3 rule 43, 95, 7e-07, o3 -composition rate: o3 rule 44, 100, 4.03e-07, o3 -composition rate: o3 rule 45, 105, 2e-07, o3 -composition rate: o3 rule 46, 110, 5e-08, o3 -composition rate: o3 rule 47, 115, 5e-09, o3 -composition rate: o3 rule 48, 120, 5e-10, o3 - diff --git a/collins 3a.pyr b/collins 3a.pyr deleted file mode 100644 index 2d2264d..0000000 --- a/collins 3a.pyr +++ /dev/null @@ -1,173 +0,0 @@ -# atm profile for midlatitude summer - -# surface values (pressure, temperature, final height, initial layer thickness, acceleration of gravity, range min, range max) -surface: 1010.0, 294.2, 120, 100, 9.8, 100, 2500 - -# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile -# except for co2, o2, n2, and ar -molecule: co2, .000287 -molecule: h2o, 0.0186 -molecule: o2, .20 -molecule: n2, .77 -molecule: ar, .009 -molecule: ch4, 0.000000806 -molecule: o3, 3.02e-08 -molecule: n2o, 0.000000275 - -# lapse rate profile -# rules are: name, final height, final value -# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule) -lapse rate: lapse rule 0, 1, 289.7 -lapse rate: lapse rule 1, 2, 295.2 -lapse rate: lapse rule 2, 3, 279.2 -lapse rate: lapse rule 3, 4, 273.2 -lapse rate: lapse rule 4, 5, 287.2 -lapse rate: lapse rule 5, 6, 261.2 -lapse rate: lapse rule 6, 7, 254.7 -lapse rate: lapse rule 7, 8, 248.2 -lapse rate: lapse rule 8, 9, 241.7 -lapse rate: lapse rule 9, 10, 235.3 -lapse rate: lapse rule 10, 11, 228.8 -lapse rate: lapse rule 11, 12, 222.3 -lapse rate: lapse rule 12, 13, 215.8 -lapse rate: lapse rule 13, 14, 215.7 -lapse rate: lapse rule 14, 15, 215.7 -lapse rate: lapse rule 15, 16, 215.7 -lapse rate: lapse rule 16, 17, 215.7 -lapse rate: lapse rule 17, 18, 216.8 -lapse rate: lapse rule 18, 19, 217.9 -lapse rate: lapse rule 19, 20, 219.2 -lapse rate: lapse rule 20, 21, 220.4 -lapse rate: lapse rule 21, 22, 221.6 -lapse rate: lapse rule 22, 23, 222.8 -lapse rate: lapse rule 23, 24, 223.9 -lapse rate: lapse rule 24, 25, 225.1 -lapse rate: lapse rule 25, 27.6, 228.5 -lapse rate: lapse rule 26, 30, 233.7 -lapse rate: lapse rule 27, 32.6, 239 -lapse rate: lapse rule 28, 35, 245.2 -lapse rate: lapse rule 29, 37.5, 251.3 -lapse rate: lapse rule 30, 40, 257.5 -lapse rate: lapse rule 31, 42.5, 263.7 -lapse rate: lapse rule 32, 45, 269.9 -lapse rate: lapse rule 33, 47.5, 275.2 -lapse rate: lapse rule 34, 50, 275.7 -lapse rate: lapse rule 35, 55, 269.3 -lapse rate: lapse rule 36, 60, 257.1 -lapse rate: lapse rule 37, 65, 240.1 -lapse rate: lapse rule 38, 70, 218 -lapse rate: lapse rule 39, 75, 196.1 -lapse rate: lapse rule 40, 80, 174.1 -lapse rate: lapse rule 41, 85, 165.1 -lapse rate: lapse rule 42, 90, 165 -lapse rate: lapse rule 43, 95, 178.3 -lapse rate: lapse rule 44, 100, 190.5 -lapse rate: lapse rule 45, 105, 222.2 -lapse rate: lapse rule 46, 110, 262.4 -lapse rate: lapse rule 47, 115, 316.8 -lapse rate: lapse rule 48, 120, 380 - -# h2o composition profile -# composition rules are: name, final height, final value ppmv, molecule the rule applies to -composition rate: h2o rule 0, 1, 0.0138, h2o -composition rate: h2o rule 1, 2, 0.00968, h2o -composition rate: h2o rule 2, 3, 0.00598, h2o -composition rate: h2o rule 3, 4, 0.00381, h2o -composition rate: h2o rule 4, 5, 0.0022299999999999998, h2o -composition rate: h2o rule 5, 6, 0.0015099999999999998, h2o -composition rate: h2o rule 6, 7, 0.0010199999999999999, h2o -composition rate: h2o rule 7, 8, 0.000646, h2o -composition rate: h2o rule 8, 9, 0.00041299999999999996, h2o -composition rate: h2o rule 9, 10, 0.000247, h2o -composition rate: h2o rule 10, 11, 9.559999999999999e-05, h2o -composition rate: h2o rule 11, 12, 2.9399999999999996e-05, h2o -composition rate: h2o rule 12, 13, 8e-06, h2o -composition rate: h2o rule 13, 14, 4.9999999999999996e-06, h2o -composition rate: h2o rule 14, 15, 3.3999999999999996e-06, h2o -composition rate: h2o rule 15, 16, 3.2999999999999997e-06, h2o -composition rate: h2o rule 16, 17, 3.2e-06, h2o -composition rate: h2o rule 17, 18, 3.15e-06, h2o -composition rate: h2o rule 18, 19, 3.2e-06, h2o -composition rate: h2o rule 19, 20, 3.2999999999999997e-06, h2o -composition rate: h2o rule 20, 21, 3.45e-06, h2o -composition rate: h2o rule 21, 22, 3.6e-06, h2o -composition rate: h2o rule 22, 23, 3.8499999999999996e-06, h2o -composition rate: h2o rule 23, 24, 4e-06, h2o -composition rate: h2o rule 24, 25, 4.2e-06, h2o -composition rate: h2o rule 25, 27.6, 4.45e-06, h2o -composition rate: h2o rule 26, 30, 4.7e-06, h2o -composition rate: h2o rule 27, 32.6, 4.87e-06, h2o -composition rate: h2o rule 28, 35, 4.95e-06, h2o -composition rate: h2o rule 29, 37.5, 4.9999999999999996e-06, h2o -composition rate: h2o rule 30, 40, 5.0999999999999995e-06, h2o -composition rate: h2o rule 31, 42.5, 5.299999999999999e-06, h2o -composition rate: h2o rule 32, 45, 5.45e-06, h2o -composition rate: h2o rule 33, 47.5, 5.5e-06, h2o -composition rate: h2o rule 34, 50, 5.5e-06, h2o -composition rate: h2o rule 35, 55, 5.35e-06, h2o -composition rate: h2o rule 36, 60, 4.9999999999999996e-06, h2o -composition rate: h2o rule 37, 65, 4.4e-06, h2o -composition rate: h2o rule 38, 70, 3.7e-06, h2o -composition rate: h2o rule 39, 75, 2.95e-06, h2o -composition rate: h2o rule 40, 80, 2.1e-06, h2o -composition rate: h2o rule 41, 85, 1.33e-06, h2o -composition rate: h2o rule 42, 90, 8.499999999999999e-07, h2o -composition rate: h2o rule 43, 95, 5.4e-07, h2o -composition rate: h2o rule 44, 100, 4e-07, h2o -composition rate: h2o rule 45, 105, 3.4000000000000003e-07, h2o -composition rate: h2o rule 46, 110, 2.8e-07, h2o -composition rate: h2o rule 47, 115, 2.4e-07, h2o -composition rate: h2o rule 48, 120, 2e-07, h2o - -# o3 composition profile -# composition rules are: name, final height, final value ppmv, molecule the rule applies to -composition rate: o3 rule 0, 1, 3.3399999999999995e-08, o3 -composition rate: o3 rule 1, 2, 3.69e-08, o3 -composition rate: o3 rule 2, 3, 4.22e-08, o3 -composition rate: o3 rule 3, 4, 4.8199999999999995e-08, o3 -composition rate: o3 rule 4, 5, 5.5100000000000004e-08, o3 -composition rate: o3 rule 5, 6, 6.41e-08, o3 -composition rate: o3 rule 6, 7, 7.76e-08, o3 -composition rate: o3 rule 7, 8, 9.13e-08, o3 -composition rate: o3 rule 8, 9, 1.11e-07, o3 -composition rate: o3 rule 9, 10, 1.3e-07, o3 -composition rate: o3 rule 10, 11, 1.7899999999999997e-07, o3 -composition rate: o3 rule 11, 12, 2.23e-07, o3 -composition rate: o3 rule 12, 13, 3e-07, o3 -composition rate: o3 rule 13, 14, 4.3999999999999997e-07, o3 -composition rate: o3 rule 14, 15, 5e-07, o3 -composition rate: o3 rule 15, 16, 6e-07, o3 -composition rate: o3 rule 16, 17, 7e-07, o3 -composition rate: o3 rule 17, 18, 1e-06, o3 -composition rate: o3 rule 18, 19, 1.5e-06, o3 -composition rate: o3 rule 19, 20, 2e-06, o3 -composition rate: o3 rule 20, 21, 2.4e-06, o3 -composition rate: o3 rule 21, 22, 2.8999999999999998e-06, o3 -composition rate: o3 rule 22, 23, 3.3999999999999996e-06, o3 -composition rate: o3 rule 23, 24, 4e-06, o3 -composition rate: o3 rule 24, 25, 4.8e-06, o3 -composition rate: o3 rule 25, 27.6, 6e-06, o3 -composition rate: o3 rule 26, 30, 7e-06, o3 -composition rate: o3 rule 27, 32.6, 8.099999999999999e-06, o3 -composition rate: o3 rule 28, 35, 8.9e-06, o3 -composition rate: o3 rule 29, 37.5, 8.7e-06, o3 -composition rate: o3 rule 30, 40, 7.55e-06, o3 -composition rate: o3 rule 31, 42.5, 5.9e-06, o3 -composition rate: o3 rule 32, 45, 4.5e-06, o3 -composition rate: o3 rule 33, 47.5, 3.5e-06, o3 -composition rate: o3 rule 34, 50, 2.8e-06, o3 -composition rate: o3 rule 35, 55, 1.8e-06, o3 -composition rate: o3 rule 36, 60, 1.3e-06, o3 -composition rate: o3 rule 37, 65, 8e-07, o3 -composition rate: o3 rule 38, 70, 4e-07, o3 -composition rate: o3 rule 39, 75, 1.8999999999999998e-07, o3 -composition rate: o3 rule 40, 80, 2e-07, o3 -composition rate: o3 rule 41, 85, 5.699999999999999e-07, o3 -composition rate: o3 rule 42, 90, 7.5e-07, o3 -composition rate: o3 rule 43, 95, 7e-07, o3 -composition rate: o3 rule 44, 100, 4.03e-07, o3 -composition rate: o3 rule 45, 105, 2e-07, o3 -composition rate: o3 rule 46, 110, 5e-08, o3 -composition rate: o3 rule 47, 115, 5e-09, o3 -composition rate: o3 rule 48, 120, 5e-10, o3 - diff --git a/tropical - narrow spectrum.pyr b/tropical - narrow spectrum.pyr deleted file mode 100644 index 1b674f1..0000000 --- a/tropical - narrow spectrum.pyr +++ /dev/null @@ -1,329 +0,0 @@ -# atm profile for tropical - -# surface values (pressure, temperature, final height, initial layer thickness, acceleration of gravity, range min, range max) -surface: 1010.0, 299.7, 120, 100, 9.8, 600, 1200 - -# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile -# except for co2, o2, n2, and ar -molecule: co2, .000287 -molecule: h2o, 0.0259 -molecule: o2, .20 -molecule: n2, .77 -molecule: ar, .009 -molecule: ch4, 1.6999999999999998e-06 -molecule: o3, 2.9699999999999998e-08 -molecule: n2o, 3.2e-07 -molecule: co, 1.5e-07 - -# lapse rate profile -# rules are: name, final height, final value -# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule) -lapse rate: lapse rule 0, 1, 293.7 -lapse rate: lapse rule 1, 2, 287.7 -lapse rate: lapse rule 2, 3, 283.7 -lapse rate: lapse rule 3, 4, 277 -lapse rate: lapse rule 4, 5, 270.3 -lapse rate: lapse rule 5, 6, 263.6 -lapse rate: lapse rule 6, 7, 257 -lapse rate: lapse rule 7, 8, 250.3 -lapse rate: lapse rule 8, 9, 243.6 -lapse rate: lapse rule 9, 10, 237 -lapse rate: lapse rule 10, 11, 230.1 -lapse rate: lapse rule 11, 12, 223.6 -lapse rate: lapse rule 12, 13, 217 -lapse rate: lapse rule 13, 14, 210.3 -lapse rate: lapse rule 14, 15, 203.7 -lapse rate: lapse rule 15, 16, 197 -lapse rate: lapse rule 16, 17, 164.8 -lapse rate: lapse rule 17, 18, 168.8 -lapse rate: lapse rule 18, 19, 202.7 -lapse rate: lapse rule 19, 20, 206.7 -lapse rate: lapse rule 20, 21, 210.7 -lapse rate: lapse rule 21, 22, 214.6 -lapse rate: lapse rule 22, 23, 217 -lapse rate: lapse rule 23, 24, 219.2 -lapse rate: lapse rule 24, 25, 221.4 -lapse rate: lapse rule 25, 27.6, 227 -lapse rate: lapse rule 26, 30, 232.3 -lapse rate: lapse rule 27, 32.6, 237.7 -lapse rate: lapse rule 28, 35, 243.1 -lapse rate: lapse rule 29, 37.5, 248.5 -lapse rate: lapse rule 30, 40, 254 -lapse rate: lapse rule 31, 42.5, 259.4 -lapse rate: lapse rule 32, 45, 264.8 -lapse rate: lapse rule 33, 47.5, 269.6 -lapse rate: lapse rule 34, 50, 270.2 -lapse rate: lapse rule 35, 55, 263.4 -lapse rate: lapse rule 36, 60, 253.1 -lapse rate: lapse rule 37, 65, 236 -lapse rate: lapse rule 38, 70, 218.9 -lapse rate: lapse rule 39, 75, 201.8 -lapse rate: lapse rule 40, 80, 184.8 -lapse rate: lapse rule 41, 85, 177.1 -lapse rate: lapse rule 42, 90, 177 -lapse rate: lapse rule 43, 95, 184.3 -lapse rate: lapse rule 44, 100, 190.7 -lapse rate: lapse rule 45, 105, 212 -lapse rate: lapse rule 46, 110, 241.6 -lapse rate: lapse rule 47, 115, 299.7 -lapse rate: lapse rule 48, 120, 380 - -# h2o composition profile -# composition rules are: name, final height, final value ppmv, molecule the rule applies to -composition rate: h2o rule 0, 1, 0.012499999999999999, h2o -composition rate: h2o rule 1, 2, 0.0153, h2o -composition rate: h2o rule 2, 3, 0.0086, h2o -composition rate: h2o rule 3, 4, 0.0044399999999999995, h2o -composition rate: h2o rule 4, 5, 0.0033499999999999997, h2o -composition rate: h2o rule 5, 6, 0.0021, h2o -composition rate: h2o rule 6, 7, 0.00129, h2o -composition rate: h2o rule 7, 8, 0.0007639999999999999, h2o -composition rate: h2o rule 8, 9, 0.00041, h2o -composition rate: h2o rule 9, 10, 0.00019099999999999998, h2o -composition rate: h2o rule 10, 11, 7.309999999999999e-05, h2o -composition rate: h2o rule 11, 12, 2.91e-05, h2o -composition rate: h2o rule 12, 13, 9e-06, h2o -composition rate: h2o rule 13, 14, 6.22e-06, h2o -composition rate: h2o rule 14, 15, 4e-06, h2o -composition rate: h2o rule 15, 16, 3e-06, h2o -composition rate: h2o rule 16, 17, 2.8999999999999998e-06, h2o -composition rate: h2o rule 17, 18, 2.75e-06, h2o -composition rate: h2o rule 18, 19, 2.6e-06, h2o -composition rate: h2o rule 19, 20, 2.6e-06, h2o -composition rate: h2o rule 20, 21, 2.6499999999999996e-06, h2o -composition rate: h2o rule 21, 22, 2.8e-06, h2o -composition rate: h2o rule 22, 23, 2.8999999999999998e-06, h2o -composition rate: h2o rule 23, 24, 3.2e-06, h2o -composition rate: h2o rule 24, 25, 3.25e-06, h2o -composition rate: h2o rule 25, 27.6, 3.6e-06, h2o -composition rate: h2o rule 26, 30, 4e-06, h2o -composition rate: h2o rule 27, 32.6, 4.2999999999999995e-06, h2o -composition rate: h2o rule 28, 35, 4.599999999999999e-06, h2o -composition rate: h2o rule 29, 37.5, 4.9000000000000005e-06, h2o -composition rate: h2o rule 30, 40, 5.2e-06, h2o -composition rate: h2o rule 31, 42.5, 5.5e-06, h2o -composition rate: h2o rule 32, 45, 5.7e-06, h2o -composition rate: h2o rule 33, 47.5, 5.9e-06, h2o -composition rate: h2o rule 34, 50, 6e-06, h2o -composition rate: h2o rule 35, 55, 6e-06, h2o -composition rate: h2o rule 36, 60, 6e-06, h2o -composition rate: h2o rule 37, 65, 5.4e-06, h2o -composition rate: h2o rule 38, 70, 4.5e-06, h2o -composition rate: h2o rule 39, 75, 3.2999999999999997e-06, h2o -composition rate: h2o rule 40, 80, 2.1e-06, h2o -composition rate: h2o rule 41, 85, 1.3e-06, h2o -composition rate: h2o rule 42, 90, 8.499999999999999e-07, h2o -composition rate: h2o rule 43, 95, 5.4e-07, h2o -composition rate: h2o rule 44, 100, 4e-07, h2o -composition rate: h2o rule 45, 105, 3.4000000000000003e-07, h2o -composition rate: h2o rule 46, 110, 2.8e-07, h2o -composition rate: h2o rule 47, 115, 2.4e-07, h2o -composition rate: h2o rule 48, 120, 2e-07, h2o - -# ch4 composition profile -# composition rules are: name, final height, final value ppmv, molecule the rule applies to -composition rate: ch4 rule 0, 1, 1.6999999999999998e-06, ch4 -composition rate: ch4 rule 1, 2, 1.6999999999999998e-06, ch4 -composition rate: ch4 rule 2, 3, 1.6999999999999998e-06, ch4 -composition rate: ch4 rule 3, 4, 1.6999999999999998e-06, ch4 -composition rate: ch4 rule 4, 5, 1.6999999999999998e-06, ch4 -composition rate: ch4 rule 5, 6, 1.6999999999999998e-06, ch4 -composition rate: ch4 rule 6, 7, 1.6999999999999998e-06, ch4 -composition rate: ch4 rule 7, 8, 1.6999999999999998e-06, ch4 -composition rate: ch4 rule 8, 9, 1.69e-06, ch4 -composition rate: ch4 rule 9, 10, 1.69e-06, ch4 -composition rate: ch4 rule 10, 11, 1.6799999999999998e-06, ch4 -composition rate: ch4 rule 11, 12, 1.6599999999999998e-06, ch4 -composition rate: ch4 rule 12, 13, 1.6499999999999999e-06, ch4 -composition rate: ch4 rule 13, 14, 1.6299999999999999e-06, ch4 -composition rate: ch4 rule 14, 15, 1.61e-06, ch4 -composition rate: ch4 rule 15, 16, 1.58e-06, ch4 -composition rate: ch4 rule 16, 17, 1.55e-06, ch4 -composition rate: ch4 rule 17, 18, 1.5199999999999998e-06, ch4 -composition rate: ch4 rule 18, 19, 1.48e-06, ch4 -composition rate: ch4 rule 19, 20, 1.42e-06, ch4 -composition rate: ch4 rule 20, 21, 1.3600000000000001e-06, ch4 -composition rate: ch4 rule 21, 22, 1.27e-06, ch4 -composition rate: ch4 rule 22, 23, 1.1899999999999998e-06, ch4 -composition rate: ch4 rule 23, 24, 1.12e-06, ch4 -composition rate: ch4 rule 24, 25, 1.06e-06, ch4 -composition rate: ch4 rule 25, 27.6, 9.87e-07, ch4 -composition rate: ch4 rule 26, 30, 9.14e-07, ch4 -composition rate: ch4 rule 27, 32.6, 8.299999999999999e-07, ch4 -composition rate: ch4 rule 28, 35, 7.459999999999999e-07, ch4 -composition rate: ch4 rule 29, 37.5, 6.62e-07, ch4 -composition rate: ch4 rule 30, 40, 5.639999999999999e-07, ch4 -composition rate: ch4 rule 31, 42.5, 4.61e-07, ch4 -composition rate: ch4 rule 32, 45, 3.6299999999999995e-07, ch4 -composition rate: ch4 rule 33, 47.5, 2.77e-07, ch4 -composition rate: ch4 rule 34, 50, 2.0999999999999997e-07, ch4 -composition rate: ch4 rule 35, 55, 1.65e-07, ch4 -composition rate: ch4 rule 36, 60, 1.5e-07, ch4 -composition rate: ch4 rule 37, 65, 1.5e-07, ch4 -composition rate: ch4 rule 38, 70, 1.5e-07, ch4 -composition rate: ch4 rule 39, 75, 1.5e-07, ch4 -composition rate: ch4 rule 40, 80, 1.5e-07, ch4 -composition rate: ch4 rule 41, 85, 1.5e-07, ch4 -composition rate: ch4 rule 42, 90, 1.4e-07, ch4 -composition rate: ch4 rule 43, 95, 1.3e-07, ch4 -composition rate: ch4 rule 44, 100, 1.2e-07, ch4 -composition rate: ch4 rule 45, 105, 1.0999999999999999e-07, ch4 -composition rate: ch4 rule 46, 110, 9.499999999999999e-08, ch4 -composition rate: ch4 rule 47, 115, 6e-08, ch4 -composition rate: ch4 rule 48, 120, 3e-08, ch4 - -# o3 composition profile -# composition rules are: name, final height, final value ppmv, molecule the rule applies to -composition rate: o3 rule 0, 1, 3.15e-08, o3 -composition rate: o3 rule 1, 2, 3.3399999999999995e-08, o3 -composition rate: o3 rule 2, 3, 3.5e-08, o3 -composition rate: o3 rule 3, 4, 3.56e-08, o3 -composition rate: o3 rule 4, 5, 3.7699999999999993e-08, o3 -composition rate: o3 rule 5, 6, 3.9899999999999993e-08, o3 -composition rate: o3 rule 6, 7, 4.22e-08, o3 -composition rate: o3 rule 7, 8, 4.4699999999999997e-08, o3 -composition rate: o3 rule 8, 9, 5e-08, o3 -composition rate: o3 rule 9, 10, 5.6e-08, o3 -composition rate: o3 rule 10, 11, 6.61e-08, o3 -composition rate: o3 rule 11, 12, 7.82e-08, o3 -composition rate: o3 rule 12, 13, 9.289999999999999e-08, o3 -composition rate: o3 rule 13, 14, 1.0499999999999999e-07, o3 -composition rate: o3 rule 14, 15, 1.26e-07, o3 -composition rate: o3 rule 15, 16, 1.44e-07, o3 -composition rate: o3 rule 16, 17, 2.5e-07, o3 -composition rate: o3 rule 17, 18, 5e-07, o3 -composition rate: o3 rule 18, 19, 9.499999999999999e-07, o3 -composition rate: o3 rule 19, 20, 1.4e-06, o3 -composition rate: o3 rule 20, 21, 1.8e-06, o3 -composition rate: o3 rule 21, 22, 2.4e-06, o3 -composition rate: o3 rule 22, 23, 3.3999999999999996e-06, o3 -composition rate: o3 rule 23, 24, 4.2999999999999995e-06, o3 -composition rate: o3 rule 24, 25, 5.4e-06, o3 -composition rate: o3 rule 25, 27.6, 7.8e-06, o3 -composition rate: o3 rule 26, 30, 9.3e-06, o3 -composition rate: o3 rule 27, 32.6, 9.849999999999999e-06, o3 -composition rate: o3 rule 28, 35, 9.699999999999999e-06, o3 -composition rate: o3 rule 29, 37.5, 8.8e-06, o3 -composition rate: o3 rule 30, 40, 7.499999999999999e-06, o3 -composition rate: o3 rule 31, 42.5, 5.9e-06, o3 -composition rate: o3 rule 32, 45, 4.5e-06, o3 -composition rate: o3 rule 33, 47.5, 3.45e-06, o3 -composition rate: o3 rule 34, 50, 2.8e-06, o3 -composition rate: o3 rule 35, 55, 1.8e-06, o3 -composition rate: o3 rule 36, 60, 1.1e-06, o3 -composition rate: o3 rule 37, 65, 6.5e-07, o3 -composition rate: o3 rule 38, 70, 3e-07, o3 -composition rate: o3 rule 39, 75, 1.8e-07, o3 -composition rate: o3 rule 40, 80, 3.3e-07, o3 -composition rate: o3 rule 41, 85, 5e-07, o3 -composition rate: o3 rule 42, 90, 5.2e-07, o3 -composition rate: o3 rule 43, 95, 5e-07, o3 -composition rate: o3 rule 44, 100, 4e-07, o3 -composition rate: o3 rule 45, 105, 2e-07, o3 -composition rate: o3 rule 46, 110, 5e-08, o3 -composition rate: o3 rule 47, 115, 5e-09, o3 -composition rate: o3 rule 48, 120, 5e-10, o3 - -# n2o composition profile -# composition rules are: name, final height, final value ppmv, molecule the rule applies to -composition rate: n2o rule 0, 1, 3.2e-07, n2o -composition rate: n2o rule 1, 2, 3.2e-07, n2o -composition rate: n2o rule 2, 3, 3.2e-07, n2o -composition rate: n2o rule 3, 4, 3.2e-07, n2o -composition rate: n2o rule 4, 5, 3.2e-07, n2o -composition rate: n2o rule 5, 6, 3.2e-07, n2o -composition rate: n2o rule 6, 7, 3.2e-07, n2o -composition rate: n2o rule 7, 8, 3.2e-07, n2o -composition rate: n2o rule 8, 9, 3.2e-07, n2o -composition rate: n2o rule 9, 10, 3.18e-07, n2o -composition rate: n2o rule 10, 11, 3.14e-07, n2o -composition rate: n2o rule 11, 12, 3.1e-07, n2o -composition rate: n2o rule 12, 13, 3.05e-07, n2o -composition rate: n2o rule 13, 14, 3e-07, n2o -composition rate: n2o rule 14, 15, 2.9399999999999996e-07, n2o -composition rate: n2o rule 15, 16, 2.88e-07, n2o -composition rate: n2o rule 16, 17, 2.7800000000000003e-07, n2o -composition rate: n2o rule 17, 18, 2.67e-07, n2o -composition rate: n2o rule 18, 19, 2.53e-07, n2o -composition rate: n2o rule 19, 20, 2.3699999999999996e-07, n2o -composition rate: n2o rule 20, 21, 2.19e-07, n2o -composition rate: n2o rule 21, 22, 2.0499999999999997e-07, n2o -composition rate: n2o rule 22, 23, 1.97e-07, n2o -composition rate: n2o rule 23, 24, 1.88e-07, n2o -composition rate: n2o rule 24, 25, 1.76e-07, n2o -composition rate: n2o rule 25, 27.6, 1.59e-07, n2o -composition rate: n2o rule 26, 30, 1.4199999999999997e-07, n2o -composition rate: n2o rule 27, 32.6, 1.17e-07, n2o -composition rate: n2o rule 28, 35, 9.279999999999998e-08, n2o -composition rate: n2o rule 29, 37.5, 6.69e-08, n2o -composition rate: n2o rule 30, 40, 4.51e-08, n2o -composition rate: n2o rule 31, 42.5, 2.7499999999999998e-08, n2o -composition rate: n2o rule 32, 45, 1.59e-08, n2o -composition rate: n2o rule 33, 47.5, 9.379999999999999e-09, n2o -composition rate: n2o rule 34, 50, 4.7499999999999995e-09, n2o -composition rate: n2o rule 35, 55, 3e-09, n2o -composition rate: n2o rule 36, 60, 2.0699999999999997e-09, n2o -composition rate: n2o rule 37, 65, 1.51e-09, n2o -composition rate: n2o rule 38, 70, 1.15e-09, n2o -composition rate: n2o rule 39, 75, 8.89e-10, n2o -composition rate: n2o rule 40, 80, 7.06e-10, n2o -composition rate: n2o rule 41, 85, 5.72e-10, n2o -composition rate: n2o rule 42, 90, 4.71e-10, n2o -composition rate: n2o rule 43, 95, 3.93e-10, n2o -composition rate: n2o rule 44, 100, 3.32e-10, n2o -composition rate: n2o rule 45, 105, 2.84e-10, n2o -composition rate: n2o rule 46, 110, 2.44e-10, n2o -composition rate: n2o rule 47, 115, 2.12e-10, n2o -composition rate: n2o rule 48, 120, 1.8499999999999998e-10, n2o - -# co composition profile -# composition rules are: name, final height, final value ppmv, molecule the rule applies to -composition rate: co rule 0, 1, 1.45e-07, co -composition rate: co rule 1, 2, 1.4e-07, co -composition rate: co rule 2, 3, 1.35e-07, co -composition rate: co rule 3, 4, 1.31e-07, co -composition rate: co rule 4, 5, 1.3e-07, co -composition rate: co rule 5, 6, 1.29e-07, co -composition rate: co rule 6, 7, 1.25e-07, co -composition rate: co rule 7, 8, 1.19e-07, co -composition rate: co rule 8, 9, 1.09e-07, co -composition rate: co rule 9, 10, 9.959999999999999e-08, co -composition rate: co rule 10, 11, 8.96e-08, co -composition rate: co rule 11, 12, 7.81e-08, co -composition rate: co rule 12, 13, 6.370000000000001e-08, co -composition rate: co rule 13, 14, 5.0299999999999994e-08, co -composition rate: co rule 14, 15, 3.9399999999999995e-08, co -composition rate: co rule 15, 16, 3.07e-08, co -composition rate: co rule 16, 17, 2.4899999999999998e-08, co -composition rate: co rule 17, 18, 1.9699999999999998e-08, co -composition rate: co rule 18, 19, 1.55e-08, co -composition rate: co rule 19, 20, 1.3299999999999998e-08, co -composition rate: co rule 20, 21, 1.23e-08, co -composition rate: co rule 21, 22, 1.23e-08, co -composition rate: co rule 22, 23, 1.31e-08, co -composition rate: co rule 23, 24, 1.4e-08, co -composition rate: co rule 24, 25, 1.5e-08, co -composition rate: co rule 25, 27.6, 1.6e-08, co -composition rate: co rule 26, 30, 1.71e-08, co -composition rate: co rule 27, 32.6, 1.8499999999999997e-08, co -composition rate: co rule 28, 35, 2e-08, co -composition rate: co rule 29, 37.5, 2.1499999999999997e-08, co -composition rate: co rule 30, 40, 2.33e-08, co -composition rate: co rule 31, 42.5, 2.63e-08, co -composition rate: co rule 32, 45, 3.0599999999999996e-08, co -composition rate: co rule 33, 47.5, 3.7999999999999996e-08, co -composition rate: co rule 34, 50, 6.25e-08, co -composition rate: co rule 35, 55, 1.4799999999999998e-07, co -composition rate: co rule 36, 60, 2.93e-07, co -composition rate: co rule 37, 65, 5.590000000000001e-07, co -composition rate: co rule 38, 70, 1.08e-06, co -composition rate: co rule 39, 75, 1.8999999999999998e-06, co -composition rate: co rule 40, 80, 2.96e-06, co -composition rate: co rule 41, 85, 4.53e-06, co -composition rate: co rule 42, 90, 6.86e-06, co -composition rate: co rule 43, 95, 1.05e-05, co -composition rate: co rule 44, 100, 1.7100000000000002e-05, co -composition rate: co rule 45, 105, 2.4699999999999997e-05, co -composition rate: co rule 46, 110, 3.36e-05, co -composition rate: co rule 47, 115, 4.15e-05, co -composition rate: co rule 48, 120, 4.9999999999999996e-05, co diff --git a/venussimple.pyr b/venussimple.pyr deleted file mode 100644 index ab063e2..0000000 --- a/venussimple.pyr +++ /dev/null @@ -1,21 +0,0 @@ -# A demo file for pyrad - -# mBar , K , km, m , g, cm-1,cm-1 -surface: 93000, 735, 200, 8, 8.87, 100, 2500 - -# mol text name, concentration -molecule: co2, .965 -molecule: h2o, .000020 -molecule: so2, .000150 -molecule: co, .000017 -molecule: n2, .03 -molecule: hcl, .0000003 -molecule: hf, .000000003 - -# name, endHeight, endTemp -lapse rate: atm rate 1, 55, 300 -lapse rate: atm rate 2, 100, 150 -lapse rate: atm rate 3, 200, 300 - - - From 7e099292f2c0424e2785a13622b1f83891edcac2 Mon Sep 17 00:00:00 2001 From: Brad Schrag Date: Thu, 14 Feb 2019 14:59:06 -0600 Subject: [PATCH 41/43] removed dependancy on pympler --- __pycache__/pyradClasses.cpython-36.pyc | Bin 0 -> 52565 bytes __pycache__/pyradUtilities.cpython-36.pyc | Bin 0 -> 32030 bytes pyradUtilities.py | 4 ---- 3 files changed, 4 deletions(-) create mode 100644 __pycache__/pyradClasses.cpython-36.pyc create mode 100644 __pycache__/pyradUtilities.cpython-36.pyc diff --git a/__pycache__/pyradClasses.cpython-36.pyc b/__pycache__/pyradClasses.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..84f384fb7c70c602115bab9a66e72f8a433a5068 GIT binary patch literal 52565 zcmdUY37lkCS#RxISMTfeY&C19Co_{|61K@QTV|3;CY@oX$v_!wd+JnoS50+Q_o>@S zPf-nlP5_aShzNoa5plrE4+q(UlO3FX6bjpU

R5CxP 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 literal 0 HcmV?d00001 diff --git a/__pycache__/pyradUtilities.cpython-36.pyc b/__pycache__/pyradUtilities.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0605c335991a8964c089b0a63bfa45083d2b83c4 GIT binary patch literal 32030 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 literal 0 HcmV?d00001 diff --git a/pyradUtilities.py b/pyradUtilities.py index dcea8d6..8eacb8f 100644 --- a/pyradUtilities.py +++ b/pyradUtilities.py @@ -3,7 +3,6 @@ import urllib.request as urlrequest import urllib.error as urlexception import gc -from pympler import tracker from datetime import datetime @@ -19,9 +18,6 @@ debuggerFile.write(bytes('%s\n' % now.strftime("%Y-%m-%d %H:%M:%S"), 'utf-8')) debuggerFile.close() -mytracker = tracker.SummaryTracker() - - class Theme: def __init__(self, value='dark'): self.theme = value From aaef1ced69ee3e49b507510a2fcc73e5f2489b55 Mon Sep 17 00:00:00 2001 From: Brad Schrag Date: Thu, 14 Feb 2019 15:01:31 -0600 Subject: [PATCH 42/43] removed __pycache__ folder --- .gitignore | 1 + __pycache__/pyradClasses.cpython-36.pyc | Bin 52565 -> 0 bytes __pycache__/pyradUtilities.cpython-36.pyc | Bin 32030 -> 0 bytes 3 files changed, 1 insertion(+) create mode 100644 .gitignore delete mode 100644 __pycache__/pyradClasses.cpython-36.pyc delete mode 100644 __pycache__/pyradUtilities.cpython-36.pyc diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ed8ebf5 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +__pycache__ \ No newline at end of file diff --git a/__pycache__/pyradClasses.cpython-36.pyc b/__pycache__/pyradClasses.cpython-36.pyc deleted file mode 100644 index 84f384fb7c70c602115bab9a66e72f8a433a5068..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 52565 zcmdUY37lkCS#RxISMTfeY&C19Co_{|61K@QTV|3;CY@oX$v_!wd+JnoS50+Q_o>@S zPf-nlP5_aShzNoa5plrE4+q(UlO3FX6bjpU

R5CxP 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 diff --git a/__pycache__/pyradUtilities.cpython-36.pyc b/__pycache__/pyradUtilities.cpython-36.pyc deleted file mode 100644 index 0605c335991a8964c089b0a63bfa45083d2b83c4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32030 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 From 3af68f6bb50a42a9d34610454052388e3bad670f Mon Sep 17 00:00:00 2001 From: Brad Schrag Date: Sat, 16 Feb 2019 15:20:25 -0600 Subject: [PATCH 43/43] adds no ghg earth profile and fixes baseline power spectrum bug --- .gitignore | 4 +- earth no ghg.pyr | 119 +++++++++++++++++++++++++++++++++++++++++++++++ pyradClasses.py | 4 +- 3 files changed, 125 insertions(+), 2 deletions(-) create mode 100644 earth no ghg.pyr diff --git a/.gitignore b/.gitignore index ed8ebf5..f8e5cff 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ -__pycache__ \ No newline at end of file +__pycache__ +/data +logger.txt diff --git a/earth no ghg.pyr b/earth no ghg.pyr new file mode 100644 index 0000000..add0ded --- /dev/null +++ b/earth no ghg.pyr @@ -0,0 +1,119 @@ +# atm profile for midlatitude summer + +# surface values (pressure, temperature, final height, initial layer thickness, acceleration of gravity, range min, range max) +surface: 1010.0, 294.2, 120, 250, 9.8, 100, 2500 + +# initial molecule ppmv. All values are taken from line 0 of their respective AFGL profile +# except for co2, o2, n2, and ar +molecule: o2, .20 +molecule: n2, .77 +molecule: ar, .009 +molecule: o3, 3.02e-08 + +# lapse rate profile +# rules are: name, final height, final value +# initial values for a rule are defined by the final value of the previous rule (or surface for the first rule) +lapse rate: lapse rule 0, 1, 289.7 +lapse rate: lapse rule 1, 2, 295.2 +lapse rate: lapse rule 2, 3, 279.2 +lapse rate: lapse rule 3, 4, 273.2 +lapse rate: lapse rule 4, 5, 287.2 +lapse rate: lapse rule 5, 6, 261.2 +lapse rate: lapse rule 6, 7, 254.7 +lapse rate: lapse rule 7, 8, 248.2 +lapse rate: lapse rule 8, 9, 241.7 +lapse rate: lapse rule 9, 10, 235.3 +lapse rate: lapse rule 10, 11, 228.8 +lapse rate: lapse rule 11, 12, 222.3 +lapse rate: lapse rule 12, 13, 215.8 +lapse rate: lapse rule 13, 14, 215.7 +lapse rate: lapse rule 14, 15, 215.7 +lapse rate: lapse rule 15, 16, 215.7 +lapse rate: lapse rule 16, 17, 215.7 +lapse rate: lapse rule 17, 18, 216.8 +lapse rate: lapse rule 18, 19, 217.9 +lapse rate: lapse rule 19, 20, 219.2 +lapse rate: lapse rule 20, 21, 220.4 +lapse rate: lapse rule 21, 22, 221.6 +lapse rate: lapse rule 22, 23, 222.8 +lapse rate: lapse rule 23, 24, 223.9 +lapse rate: lapse rule 24, 25, 225.1 +lapse rate: lapse rule 25, 27.6, 228.5 +lapse rate: lapse rule 26, 30, 233.7 +lapse rate: lapse rule 27, 32.6, 239 +lapse rate: lapse rule 28, 35, 245.2 +lapse rate: lapse rule 29, 37.5, 251.3 +lapse rate: lapse rule 30, 40, 257.5 +lapse rate: lapse rule 31, 42.5, 263.7 +lapse rate: lapse rule 32, 45, 269.9 +lapse rate: lapse rule 33, 47.5, 275.2 +lapse rate: lapse rule 34, 50, 275.7 +lapse rate: lapse rule 35, 55, 269.3 +lapse rate: lapse rule 36, 60, 257.1 +lapse rate: lapse rule 37, 65, 240.1 +lapse rate: lapse rule 38, 70, 218 +lapse rate: lapse rule 39, 75, 196.1 +lapse rate: lapse rule 40, 80, 174.1 +lapse rate: lapse rule 41, 85, 165.1 +lapse rate: lapse rule 42, 90, 165 +lapse rate: lapse rule 43, 95, 178.3 +lapse rate: lapse rule 44, 100, 190.5 +lapse rate: lapse rule 45, 105, 222.2 +lapse rate: lapse rule 46, 110, 262.4 +lapse rate: lapse rule 47, 115, 316.8 +lapse rate: lapse rule 48, 120, 380 + + + +# o3 composition profile +# composition rules are: name, final height, final value ppmv, molecule the rule applies to +composition rate: o3 rule 0, 1, 3.3399999999999995e-08, o3 +composition rate: o3 rule 1, 2, 3.69e-08, o3 +composition rate: o3 rule 2, 3, 4.22e-08, o3 +composition rate: o3 rule 3, 4, 4.8199999999999995e-08, o3 +composition rate: o3 rule 4, 5, 5.5100000000000004e-08, o3 +composition rate: o3 rule 5, 6, 6.41e-08, o3 +composition rate: o3 rule 6, 7, 7.76e-08, o3 +composition rate: o3 rule 7, 8, 9.13e-08, o3 +composition rate: o3 rule 8, 9, 1.11e-07, o3 +composition rate: o3 rule 9, 10, 1.3e-07, o3 +composition rate: o3 rule 10, 11, 1.7899999999999997e-07, o3 +composition rate: o3 rule 11, 12, 2.23e-07, o3 +composition rate: o3 rule 12, 13, 3e-07, o3 +composition rate: o3 rule 13, 14, 4.3999999999999997e-07, o3 +composition rate: o3 rule 14, 15, 5e-07, o3 +composition rate: o3 rule 15, 16, 6e-07, o3 +composition rate: o3 rule 16, 17, 7e-07, o3 +composition rate: o3 rule 17, 18, 1e-06, o3 +composition rate: o3 rule 18, 19, 1.5e-06, o3 +composition rate: o3 rule 19, 20, 2e-06, o3 +composition rate: o3 rule 20, 21, 2.4e-06, o3 +composition rate: o3 rule 21, 22, 2.8999999999999998e-06, o3 +composition rate: o3 rule 22, 23, 3.3999999999999996e-06, o3 +composition rate: o3 rule 23, 24, 4e-06, o3 +composition rate: o3 rule 24, 25, 4.8e-06, o3 +composition rate: o3 rule 25, 27.6, 6e-06, o3 +composition rate: o3 rule 26, 30, 7e-06, o3 +composition rate: o3 rule 27, 32.6, 8.099999999999999e-06, o3 +composition rate: o3 rule 28, 35, 8.9e-06, o3 +composition rate: o3 rule 29, 37.5, 8.7e-06, o3 +composition rate: o3 rule 30, 40, 7.55e-06, o3 +composition rate: o3 rule 31, 42.5, 5.9e-06, o3 +composition rate: o3 rule 32, 45, 4.5e-06, o3 +composition rate: o3 rule 33, 47.5, 3.5e-06, o3 +composition rate: o3 rule 34, 50, 2.8e-06, o3 +composition rate: o3 rule 35, 55, 1.8e-06, o3 +composition rate: o3 rule 36, 60, 1.3e-06, o3 +composition rate: o3 rule 37, 65, 8e-07, o3 +composition rate: o3 rule 38, 70, 4e-07, o3 +composition rate: o3 rule 39, 75, 1.8999999999999998e-07, o3 +composition rate: o3 rule 40, 80, 2e-07, o3 +composition rate: o3 rule 41, 85, 5.699999999999999e-07, o3 +composition rate: o3 rule 42, 90, 7.5e-07, o3 +composition rate: o3 rule 43, 95, 7e-07, o3 +composition rate: o3 rule 44, 100, 4.03e-07, o3 +composition rate: o3 rule 45, 105, 2e-07, o3 +composition rate: o3 rule 46, 110, 5e-08, o3 +composition rate: o3 rule 47, 115, 5e-09, o3 +composition rate: o3 rule 48, 120, 5e-10, o3 + diff --git a/pyradClasses.py b/pyradClasses.py index ae79b77..5740e39 100644 --- a/pyradClasses.py +++ b/pyradClasses.py @@ -104,7 +104,7 @@ def readTransmissionFromFile(requestedHeight, folderPath, direction): transmissionValues['molList'] = completedValues['molList'] transmissionValues['surfaceEffEmissivity'] = float(completedValues['surfaceEffEmissivity']), transmissionValues['res'] = float(completedValues['res']) - transmissionValues['surfacePower'] = float(completedValues['surfacePower']) + transmissionValues['surfacePower'] = float(transmissionValues['surfacePower'][0]) return transmissionValues @@ -1582,6 +1582,8 @@ def plotPlanetAndComponents(planet, height=None, direction='down', temperatureLi handles.append(fig) surfacePower = transmittanceValues['surfacePower'] + input() + print(surfacePower) powerSpectrum = integrateSpectrum(yTotal, pi, res=res) plt.title('Surface temp: %sK Surface flux: %sWm-2 Effect temp: %sK' % (transmittanceValues['surfaceTemperature'], round(surfacePower, 2), round(stefanB(powerSpectrum), 2)))