def stationmask(inp, stations, out, inv, dribble): """Take list of cells from *inp*, list of stations from *stations*, and output on *out* a list of station identifiers (11-digit) (that are within the cells specified in *inp); locations are taken from the v2.inv file *inv*. """ centres = [row[:11] for row in inp if float(row[16:21])] print >> dribble, len(centres), "centres" centres = [(float(c[:5]),float(c[5:11])) for c in centres] boxes = eqarea.grid8k() selectboxes = [box for box in boxes if [centre for centre in centres if boxcontains(box, centre)]] print >> dribble, len(selectboxes), "boxes" # Set of stations. stations = set(l[:11] for l in stations) meta = list(inv) selected = [] # Iterate over all entries in v2.inv, discarding those not in # *stations*. for line in meta: uid = line[:11] if uid not in stations: continue lat = float(line[43:49]) lon = float(line[50:57]) for box in selectboxes: if eqarea.boxcontains(box, (lat,lon)): selected.append(uid) dribble.write('\r%d stations' % len(selected)) break dribble.write('\n') selected = set(selected) for id11 in sorted(selected): out.write(id11 + '\n')
def topng(inp, date=None): """Convert *inp* into a PNG file. Input file can be a step5mask file (produces greyscale PNG), or if *date* is supplied it can be a subbox file.""" # :todo: move into proper module. from landmask import centrein resolution = 0.25 width = 360 / resolution height = 180 / resolution assert int(width) == width assert int(height) == height width = int(width) height = int(height) cells = eqarea.grid8k() if not date: # Mask file in text format. values = gio.maskboxes(inp, cells) colour = greyscale isgrey = True else: values = extractdate(inp, cells, date) colour = colourscale isgrey = False if isgrey: black = 0 else: black = (0, 0, 0) # an array of rows: a = [[black] * width for _ in range(height)] for v, box in values: v = colour(v) for x, y in centrein(box, resolution): a[y][x] = v # For colour images each row of *a* is of the form: # [(R,G,B), (R,G,B), ...] we want to flatten it to: # [R,G,B,R,G,B,...] if not isgrey: a = [list(itertools.chain(*row)) for row in a] try: outpath = inp.name + '.png' except: outpath = 'out.png' w = png.Writer(width=width, height=height, greyscale=isgrey, alpha=False, bitdepth=8) w.write(open(outpath, 'wb'), a)
def topng(inp, date=None): """Convert *inp* into a PNG file. Input file can be a step5mask file (produces greyscale PNG), or if *date* is supplied it can be a subbox file.""" # :todo: move into proper module. from landmask import centrein resolution = 0.25 width = 360 / resolution height = 180 / resolution assert int(width) == width assert int(height) == height width = int(width) height = int(height) cells = eqarea.grid8k() if not date: # Mask file in text format. values = gio.maskboxes(inp, cells) colour = greyscale isgrey = True else: values = extractdate(inp, cells, date) colour = colourscale isgrey = False if isgrey: black = 0 else: black = (0, 0, 0) # an array of rows: a = [[black] * width for _ in range(height)] for v, box in values: v = colour(v) for x, y in centrein(box, resolution): a[y][x] = v # For colour images each row of *a* is of the form: # [(R,G,B), (R,G,B), ...] we want to flatten it to: # [R,G,B,R,G,B,...] if not isgrey: a = [list(itertools.chain(*row)) for row in a] try: outpath = inp.name + ".png" except: outpath = "out.png" w = png.Writer(width=width, height=height, greyscale=isgrey, alpha=False, bitdepth=8) w.write(open(outpath, "wb"), a)
def maskit(inp, out): """Given a land percent file as input, produce a GISTEMP cell mask as output.""" land = grid(inp) resolution = land.resolution for subbox in eqarea.grid8k(): values = [land.a[y][x] for x,y in centrein(subbox, resolution)] # For GISTEMP we mask as land if there is _any_ land in the # cell. if sum(values) > 0: mask = 1 else: mask = 0 out.write("%sMASK%.3f\n" % (giss_data.boxuid(subbox), mask))
def maskmap(argv): """[command] [--class css-class] mask Draws an SVG map of the cells in mask.""" opts,arg = getopt.getopt(argv[1:], '', ['class=']) option = dict((o[2:],v) for o,v in opts) from code import eqarea maskfile = arg[0] out = sys.stdout def transform(p): u"""Transform p=(lat,lon) into (x,y) used for map system. Which in this case is Plate Carr\xe9e with x from 0 to 720, and y from 0 to 360.""" lat,lon = p y = (90+lat)*2 x = (180+lon)*2 return x,y out.write("""<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">\n""") out.write("""<defs> <style type="text/css"> path.m0 { stroke: none; fill: rgb(0,0,0); fill-opacity: 0.0; } path.m1 { stroke: none; fill: rgb(255,0,0); fill-opacity: 0.4; } </style>\n</defs> """) class_ = option.get('class', 'mask') out.write("<g class='%s' transform='translate(0,360) scale(1,-1)'>\n" % class_) cells = eqarea.grid8k() for v,box in gio.maskboxes(open(maskfile), cells): s,n,w,e = box corners = [(n,w), (n,e), (s,e), (s,w)] corners = map(transform, corners) out.write("<path class='m%.0f'" % v + " d='M %.2f %.2f L" % corners[0] + " %.2f"*6 % tuple(itertools.chain(*corners[1:])) + " z' />\n") out.write("</g>\n") out.write("</svg>\n")
def cells(inp, date=None, trend=True): """ Yield a series of (value, rect) pairs. """ subboxes = eqarea.grid8k() if not date and not trend: # Mask file in text format. values = gio.maskboxes(inp, subboxes) return values assert not (date and trend) if date: values = extract_date(inp, subboxes, date) elif trend: values = extract_trend(inp, subboxes) return values
def rectangle(out, latbound=(-90.0,+90.0), lonbound=(-180.0,+180.0)): """*latbound* should be a pair of (southernbound, northernbound), *lonbound* should be a pair of (westernbound, easternbound). On *out* will be written a step5mask file where every cell whose centre is within the specified rectangle will be marked as "1.000" and every other cell marked as "0.000". """ from code import eqarea from code import giss_data s,n = latbound w,e = lonbound for cell in eqarea.grid8k(): lat,lon = eqarea.centre(cell) if s <= lat < n and w <= lon < e: m = 1.0 else: m = 0.0 out.write("%sMASK%.3f\n" % (giss_data.boxuid(cell), m))
def rectangle(out, latbound=(-90.0, +90.0), lonbound=(-180.0, +180.0)): """*latbound* should be a pair of (southernbound, northernbound), *lonbound* should be a pair of (westernbound, easternbound). On *out* will be written a step5mask file where every cell whose centre is within the specified rectangle will be marked as "1.000" and every other cell marked as "0.000". """ from code import eqarea from code import giss_data s, n = latbound w, e = lonbound for cell in eqarea.grid8k(): lat, lon = eqarea.centre(cell) if s <= lat < n and w <= lon < e: m = 1.0 else: m = 0.0 out.write("%sMASK%.3f\n" % (giss_data.boxuid(cell), m))
def stationmask(inp, stations, out, inv, dribble): """Take list of cells from *inp*, list of stations from *stations*, and output on *out* a list of station identifiers (11-digit) (that are within the cells specified in *inp); locations are taken from the v2.inv file *inv*. """ centres = [row[:11] for row in inp if float(row[16:21])] print >> dribble, len(centres), "centres" centres = [(float(c[:5]), float(c[5:11])) for c in centres] boxes = eqarea.grid8k() selectboxes = [ box for box in boxes if [centre for centre in centres if boxcontains(box, centre)] ] print >> dribble, len(selectboxes), "boxes" # Set of stations. stations = set(l[:11] for l in stations) meta = list(inv) selected = [] # Iterate over all entries in v2.inv, discarding those not in # *stations*. for line in meta: uid = line[:11] if uid not in stations: continue lat = float(line[43:49]) lon = float(line[50:57]) for box in selectboxes: if eqarea.boxcontains(box, (lat, lon)): selected.append(uid) dribble.write('\r%d stations' % len(selected)) break dribble.write('\n') selected = set(selected) for id11 in sorted(selected): out.write(id11 + '\n')