Esempio n. 1
0
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
Esempio n. 2
0
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)
Esempio n. 3
0
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)
Esempio n. 4
0
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)
Esempio n. 5
0
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)
Esempio n. 6
0
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
Esempio n. 7
0
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
Esempio n. 8
0
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
Esempio n. 9
0
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
Esempio n. 10
0
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)
Esempio n. 11
0
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
Esempio n. 12
0
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
Esempio n. 13
0
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. For a list of cross-section only molecules, type %s. If no value given, %s will be used: '
        % (util.underlineCyan(text), util.magentaText('help'),
           util.magentaText('xsc'), util.limeText(default)),
        validMoleculeName,
        default=default)
    return moleculeName
Esempio n. 14
0
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
Esempio n. 15
0
    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:
            if entry.selectionKey:
                validEntry.append(entry.selectionKey.lower())
                print(
                    ' %s)   %s' %
                    (util.magentaText(entry.selectionKey.upper()), entry.name))
            else:
                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
        if self.hint:
            print(util.limeText('**' + self.hint))

        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:
                try:
                    userChoice = self.entries[int(userInput) - 1]
                except ValueError:
                    # this means the user entered a letter but it is in the valid choices
                    # roll through the entries to find the matching choice
                    userChoice = next(
                        filter(
                            lambda x: x.selectionKey and x.selectionKey.lower(
                            ) == userInput.lower(), self.entries))
                if userChoice.nextFunction:
                    userChoice.nextFunction(userChoice.functionParams)
                    validChoice = True
                elif userChoice.nextMenu:
                    userChoice.nextMenu.displayMenu()
                    validChoice = True
            else:
                print('Invalid entry. Try again.')
Esempio n. 16
0
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)
Esempio n. 17
0
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)
Esempio n. 18
0
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
Esempio n. 19
0
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)
Esempio n. 20
0
def selectXscFile(params):
    def relevanceScore(layerT,
                       layerP,
                       fileT,
                       fileP,
                       weightedT=1,
                       weightedP=1.1):
        tDiff = abs(layerT - fileT) * weightedT
        pDiff = abs(layerP - fileP) * weightedP
        total = tDiff + pDiff
        return total

    layer = params['layer']
    xsc = params['xsc']

    if 'sort' not in params:
        params['sort'] = 'RELEVANT_P'
    sort = params['sort']
    entries = []
    unsortedFiles = util.returnXscFilesInDirectory(xsc)
    if unsortedFiles is False or unsortedFiles == []:
        question = "Either that directory doesn't exist or it was empty. Would you like to try downloading the data from HITRAN?"
        if receiveInput(question, validYorN) == 'y':
            filepath = util.downloadXscZipFile(xsc)
            util.unzipFile(filepath)
            util.mergeXsc(xsc)
            selectXscFile(params)
        else:
            return
    else:
        hintText = "Layer P and T will be adjusted according to the xsc file"

        unsortedValues = list(
            map(lambda file: util.parseXscFileName(file), unsortedFiles))
        if sort == 'TEMP':
            sortedValues = sorted(unsortedValues,
                                  key=lambda i:
                                  (float(i['TEMP']), float(i['PRESSURE'])))
            sortedValues.reverse()
            hintText += '\nCurrently sorted by temperature with largest values at bottom'
        elif sort == 'PRESSURE':
            sortedValues = sorted(unsortedValues,
                                  key=lambda i:
                                  (float(i['PRESSURE']), float(i['TEMP'])))
            sortedValues.reverse()
            hintText += '\nCurrently sorted by pressure with largest values at bottom'
        elif sort == 'RELEVANT_P':
            sortedValues = sorted(
                unsortedValues,
                key=lambda i:
                (relevanceScore(layer.T, layer.P, float(i['TEMP']),
                                float(i['PRESSURE']) * 1.31579)))
            sortedValues.reverse()
            hintText += '\nCurrently sorted closest minimizing pressure difference, with closest match at bottom'
        elif sort == 'RELEVANT_T':
            sortedValues = sorted(
                unsortedValues,
                key=lambda i: (relevanceScore(layer.T,
                                              layer.P,
                                              float(i['TEMP']),
                                              float(i['PRESSURE']) * 1.31579,
                                              weightedP=1,
                                              weightedT=1.1)))
            hintText += '\nCurrently sorted closest minimizing temperature difference, with closest match at bottom'
            sortedValues.reverse()

        for v in sortedValues:
            if sort == 'TEMP' or sort == 'RELEVANT_T':
                displayName = 'Temp: %s  -- Pressure: %s  --  Range: %s' % (
                    util.limeText(v['TEMP'] + 'K'),
                    util.cyanText(v['PRESSURE'] + 'Torr'),
                    util.magentaText(v['RANGE'] + 'cm-1'))
            elif sort == 'PRESSURE' or sort == 'RELEVANT_P':
                displayName = 'Pressure: %s  -- Temp: %s  --  Range: %s' % (
                    util.cyanText(v['PRESSURE'] + 'Torr'),
                    util.limeText(v['TEMP'] + 'K'),
                    util.magentaText(v['RANGE'] + 'cm-1'))
            entries.append(
                Entry(displayName,
                      nextFunction=addXscToLayer,
                      functionParams={
                          'layer': layer,
                          'file': v['LONG_FILENAME'],
                          'xsc': xsc
                      }))
        pressureParams = params.copy()
        pressureParams.update({'sort': 'PRESSURE'})
        entries.append(
            Entry('Sort by pressure',
                  nextFunction=selectXscFile,
                  functionParams=pressureParams,
                  selectionKey='P'))
        tempParams = params.copy()
        tempParams.update({'sort': 'TEMP'})
        entries.append(
            Entry('Sort by temperature',
                  nextFunction=selectXscFile,
                  functionParams=tempParams,
                  selectionKey='T'))
        tempParams = params.copy()
        tempParams.update({'sort': 'RELEVANT_T'})
        entries.append(
            Entry('Sort by closest temperature',
                  nextFunction=selectXscFile,
                  functionParams=tempParams,
                  selectionKey='minT'))
        tempParams = params.copy()
        tempParams.update({'sort': 'RELEVANT_P'})
        entries.append(
            Entry('Sort by closest pressure',
                  nextFunction=selectXscFile,
                  functionParams=tempParams,
                  selectionKey='minP'))
        menu = Menu('Choose file to use', entries, hint=hintText)
        menu.displayMenu()
    return
Esempio n. 21
0
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