Source code for nexoclom.Input

import os, os.path
import numpy as np
import psycopg2
from astropy.io import ascii
import astropy.units as u
from .produce_image import ModelImage
from .modeldriver import modeldriver
from .configure_model import configfile
from .input_classes import (Geometry, StickingInfo, Forces,
                            SpatialDist, SpeedDist, AngularDist, Options)


[docs]class Input(): def __init__(self, infile, verbose=False): # Read the configuration file self.database, self.savepath, self.datapath = configfile() # Read in the input file: self.inputfile = infile if os.path.isfile(infile): data = ascii.read(infile, delimiter='=', comment=';', data_start=0, names=['Param', 'Value']) else: assert 0, 'Input file {} does not exist.'.format(infile) section = [d.split('.')[0].casefold() for d in data['Param']] param = [d.split('.')[1].casefold() for d in data['Param']] values = [v.split(';')[0].strip().casefold() if ';' in v else v.casefold() for v in data['Value']] # Extract the geometry parameters gparam = {b:c for (a,b,c) in zip(section, param, values) if a == 'geometry'} self.geometry = Geometry(gparam) # Extract the sticking information sparam = {b:c for a,b,c in zip(section, param, values) if a == 'sticking_info'} self.sticking_info = StickingInfo(sparam) # Extract the forces fparam = {b:c for a,b,c in zip(section, param, values) if a == 'forces'} self.forces = Forces(fparam) # Extract the spatial distribution sparam = {b:c for a,b,c in zip(section, param, values) if a == 'spatialdist'} self.spatialdist = SpatialDist(sparam) # Extract the speed distribution sparam = {b:c for a,b,c in zip(section, param, values) if a == 'speeddist'} self.speeddist = SpeedDist(sparam) # Extract the angular distribution aparam = {b:c for a,b,c in zip(section, param, values) if a == 'angulardist'} self.angulardist = AngularDist(aparam, self.spatialdist) # Extract the options oparam = {b:c for a,b,c in zip(section, param, values) if a == 'options'} self.options = Options(oparam, self.geometry.planet) def __str__(self): print(self.geometry) print(self.sticking_info) print(self.forces) print(self.spatialdist) print(self.speeddist) print(self.angulardist) print(self.options) return ''
[docs] def findpackets(self): ''' Search the database for identical inputs ''' # connect to the database con = psycopg2.connect(host='localhost', database=self.database) cur = con.cursor() dtor = np.pi/180. def isNone(x): try: q = x.value except: q = x if type(q) == str: return f'is NULL' if q is None else f"= '{q}'" else: return f'is NULL' if q is None else f"= {q}" def inRange(field, x, delta): return f'ABS({field} - {x}) <= {delta/2}' # Search geometry # Note: StartTime not included in query geometry = self.geometry objs = [obj.object for obj in geometry.objects] objs.sort() objs2 = ','.join(objs) phi = [p.value for p in geometry.phi] assert phi[0] == 0., 'There is a problem with phi' dtaa = (5.*u.deg).to(u.rad) taa = [geometry.taa-dtaa/2., geometry.taa+dtaa/2.] taa = [taa[0].value, taa[1].value] if taa[0] < 0.: taabit = '(taa>={} or taa<{})'.format(2*np.pi+taa[0], taa[1]) elif taa[1] > 2*np.pi: taabit = '(taa>={} or taa<{})'.format(taa[0], taa[1] % (2*np.pi)) else: taabit = inRange('taa', geometry.taa.value, dtaa.value) ptxt = [inRange('phi[{}]'.format(i+1), p, 5.*dtor) for i,p in enumerate(phi)] ptxt2 = ' and '.join(ptxt) query = '''SELECT geo_idnum FROM geometry WHERE planet='{}' and StartPoint='{}' and objects=ARRAY['{}']::SSObject[] and {} and {} and {} and {}'''.format(geometry.planet.object, geometry.startpoint, objs2, ptxt2, inRange('subsolarpt[0]', geometry.subsolarpoint[0].value, 5*dtor), inRange('subsolarpt[1]', geometry.subsolarpoint[1].value, 5*dtor), taabit) cur.execute(query) if cur.rowcount == 0: return [], 0, 0 result = cur.fetchall() georesult = [r[0] for r in result] # Sticking Info sticking_info = self.sticking_info geostr = [str(i) for i in georesult] geostr = '(' + ', '.join(geostr) + ')' if sticking_info.stickcoef == 1: query = '''SELECT st_idnum FROM sticking_info WHERE stickcoef=1 and st_idnum in {}'''.format(geostr) else: query = '''SELECT st_idnum FROM sticking_info WHERE stickcoef={} and tsurf {} and stickfn {} and stick_mapfile {} and epsilon {} and n {} and tmin {} and emitfn {} and accom_mapfile {} and st_idnum in {}'''.format( sticking_info.stickcoef, isNone(sticking_info.tsurf), isNone(sticking_info.stickfn), isNone(sticking_info.stick_mapfile), isNone(sticking_info.epsilon), isNone(sticking_info.n), isNone(sticking_info.tmin), isNone(sticking_info.emitfn), isNone(sticking_info.accom_mapfile), geostr) cur.execute(query) if cur.rowcount == 0: return [], 0, 0 result = cur.fetchall() stickresult = [s[0] for s in result] # Forces stickstr = [str(i) for i in stickresult] stickstr = '(' + ', '.join(stickstr) + ')' forces = self.forces query = '''SELECT f_idnum FROM forces WHERE gravity=%s and radpres=%s and f_idnum in {}'''.format(stickstr) cur.execute(query, (forces.gravity, forces.radpres)) result = cur.fetchall() if cur.rowcount == 0: return [], 0, 0 forceresult = [s[0] for s in result] # SpatialDist spatialdist = self.spatialdist forcestr = [str(i) for i in forceresult] forcestr = '(' + ', '.join(forcestr) + ')' if spatialdist.longitude is None: long0 = 'longitude[1] = 0.' long1 = 'longitude[2] = 0.' else: long0 = inRange('longitude[1]', spatialdist.longitude[0].value, 5*dtor) long1 = inRange('longitude[2]', spatialdist.longitude[1].value, 5*dtor) if spatialdist.latitude is None: lat0 = 'latitude[1] = 0.' lat1 = 'latitude[2] = 0.' else: lat0 = inRange('latitude[1]', spatialdist.latitude[0].value, 5*dtor) lat1 = inRange('latitude[2]', spatialdist.latitude[1].value, 5*dtor) query = '''SELECT spat_idnum FROM spatialdist WHERE type = '{}' and {} and use_map {} and mapfile {} and {} and {} and {} and {} and spat_idnum in {}'''.format( spatialdist.type, inRange('exobase', spatialdist.exobase, 0.05), isNone(spatialdist.use_map), isNone(spatialdist.mapfile), long0, long1, lat0, lat1, forcestr) cur.execute(query) if cur.rowcount == 0: return [], 0, 0 result = cur.fetchall() spatresult = [s[0] for s in result] # Speeddist speeddist = self.speeddist spatstr = [str(i) for i in spatresult] spatstr = '(' + ', '.join(spatstr) + ')' if speeddist.vprob is None: vstr = 'vprob is NULL' else: vstr = inRange('vprob', speeddist.vprob.value, speeddist.vprob.value*0.05) if speeddist.temperature is None: Tstr = 'temperature is NULL' else: Tstr = inRange('temperature', speeddist.temperature.value, speeddist.temperature.value*0.05) query = '''SELECT spd_idnum FROM speeddist WHERE type = '{}' and {} and sigma {} and U {} and alpha {} and beta {} and {} and delv {} and spd_idnum in {}'''.format( speeddist.type, vstr, isNone(speeddist.sigma), isNone(speeddist.U), isNone(speeddist.alpha), isNone(speeddist.beta), Tstr, isNone(speeddist.delv), spatstr) cur.execute(query) if cur.rowcount == 0: return [], 0, 0 result = cur.fetchall() speedresult = [s[0] for s in result] # Angular distribution angdist = self.angulardist spdstr = [str(i) for i in speedresult] spdstr = '(' + ', '.join(spdstr) + ')' if angdist.azimuth is None: az0 = 'azimuth[1] is NULL' az1 = 'azimuth[2] is NULL' else: az0 = inRange('azimuth[1]', angdist.azimuth[0].value, 5*dtor) az1 = inRange('azimuth[2]', angdist.azimuth[1].value, 5*dtor) if angdist.altitude is None: alt0 = 'altitude[1] is NULL' alt1 = 'altitude[2] is NULL' else: alt0 = inRange('altitude[1]', angdist.altitude[0].value, 5*dtor) alt1 = inRange('altitude[2]', angdist.altitude[1].value, 5*dtor) n = isNone(angdist.n) query = '''SELECT ang_idnum from angulardist WHERE type = '{}' and {} and {} and {} and {} and n {} and ang_idnum in {}'''.format(angdist.type, az0, az1, alt0, alt1, n, spdstr) cur.execute(query) if cur.rowcount == 0: return [], 0, 0 result = cur.fetchall() angresult = [a[0] for a in result] # Options options = self.options angstr = [str(i) for i in angresult] angstr = '(' + ', '.join(angstr) + ')' endtime = inRange('endtime', options.endtime.value, options.endtime.value*0.05) outeredge = isNone(options.outeredge) nsteps = isNone(options.nsteps) res = isNone(options.resolution) query = '''SELECT opt_idnum from options WHERE {} and resolution {} and at_once = {} and atom = '{}' and lifetime = {} and fullsystem = {} and outeredge {} and motion = {} and streamlines = {} and nsteps {} and opt_idnum in {}'''.format( endtime, res, options.at_once, options.atom, options.lifetime.value, options.fullsystem, outeredge, options.motion, options.streamlines, nsteps, angstr) cur.execute(query) if cur.rowcount == 0: return [], 0, 0 result = cur.fetchall() finalresult = [str(a[0]) for a in result] finalresult = '(' + ', '.join(finalresult) + ')' # Get final list of files and # packets query = '''SELECT filename, npackets, totalsource FROM outputfile WHERE idnum in {}'''.format(finalresult) cur.execute(query) result = cur.fetchall() filenames = [r[0] for r in result] npackets = sum(r[1] for r in result) totalsource = sum(r[2] for r in result) return filenames, npackets, totalsource
[docs] def run(self, npackets, overwrite=False, compress=True): modeldriver(self, npackets, overwrite, compress)
[docs] def produce_image(self, format_, filenames=None): return ModelImage(self, format_, filenames=filenames)