def show_swath_pycoast(self, start, period=None): """ A helper method that displays the orbital swath starting at datetime start, for a period number of minutes. If, start is iterable, then the method assumes it is an iterable of datetimes, plotting a number of swaths at those times. """ # test if start is iterable, EAFP style: try: for e in start: pass except TypeError: start = [start] start.sort() from PIL import Image from pycoast import ContourWriterAGG from pydecorate import DecoratorAGG img = Image.new('RGB', (650, 650)) proj4_string = "" for x in self.working_projection: proj4_string += "+%s=%s "%(x,self.working_projection[x]) area_extent = (-6700000.0, -6700000.0, 6700000.0, 6700000.0) area_def = (proj4_string, area_extent) cw = ContourWriterAGG() cw.add_grid(img, area_def, (10.0,10.0),(2.0,2.0), fill='blue', outline='gray', outline_opacity=130, minor_outline=None, write_text=False) # Plot granules for t in start: # fetch the coordinates xys_segs = self.swath_working_projection(t, period) for xys in xys_segs: lls = self.proj(xys[0],xys[1],inverse=True) cw.add_polygon(img, area_def, zip(lls[0], lls[1]), outline="blue", fill="blue", fill_opacity=70, width=1) cw.add_coastlines(img, area_def, resolution='l') aoi_coords = zip(*self.aoi) ## TODO: Handle single point case properly if len(aoi_coords) == 1: x, y = aoi_coords[0] d = 0.5 line_coords = [(x-d,y),(x+d,y)] cw.add_line(img, area_def, line_coords, outline="red", fill="red", fill_opacity=100, width=2) elif len(aoi_coords) == 2: cw.add_line(img, area_def, aoi_coords, outline="red", fill="red", fill_opacity=100, width=10) else: cw.add_polygon(img, area_def, aoi_coords, outline="red", fill="red", fill_opacity=100, width=2) # Decorate dc = DecoratorAGG(img) text = "Granules from time: %s + %.2f min."%(start[0].strftime('%Y.%m.%d %H:%M:%S'), (start[-1]-start[0]).total_seconds()/60.0) dc.align_bottom() dc.add_text(text,height=0) img.show()
def decorate_pilimg(self, pilimg): """Apply decorations to an image Parameters ---------- pilimg : PIL.Image """ dc = DecoratorAGG(pilimg) dc.align_bottom() self.apply_colorbar(dc) self.apply_label(dc)
def show_image(data, dataname, save_png, colors="rainbow", min_data=None, max_data=None, title=None, add_colorscale=True): if min_data is None: min_data=data.min() if max_data is None: max_data=data.max() img = trollimage(data, mode="L", fill_value=[0,0,0]) colormap = get_colormap(colors, min_data, max_data) img.colorize(colormap) if title is not None: title_color=(255,255,255) from PIL import ImageFont from PIL import ImageDraw PIL_image=img.pil_image() draw = ImageDraw.Draw(PIL_image) fontsize=18 font = ImageFont.truetype("/usr/openv/java/jre/lib/fonts/LucidaTypewriterBold.ttf", fontsize) draw.text( (10, 10), title, title_color, font=font) if add_colorscale: dc = DecoratorAGG(PIL_image) colormap_r = colormap.reverse() dc.align_right() dc.write_vertically() dc.add_scale(colormap_r, extend=True, tick_marks=5, minor_tick_marks=1, line_opacity=100) #, tick_marks=tick_marks, minor_tick_marks=minor_tick_marks, unit=units show_or_save_image(PIL_image, save_png, dataname)
def test_colorbar(tmp_path, orientation_func_name, align_func_name, clims): fn = tmp_path / "test_colorbar.png" img = Image.fromarray(np.zeros((200, 100, 3), dtype=np.uint8)) dc = DecoratorAGG(img) getattr(dc, align_func_name)() getattr(dc, orientation_func_name)() cmap = rdbu.set_range(*clims, inplace=False) dc.add_scale(cmap, extend=True, tick_marks=5.0, line_opacity=100, unit="K") img.save(fn) # check results output_img = Image.open(fn) arr = np.array(output_img) _assert_colorbar_orientation_alignment(arr, orientation_func_name, align_func_name)
def add_decorate(orig, fill_value=None, **decorate): """Decorate an image with text and/or logos/images. This call adds text/logos in order as given in the input to keep the alignment features available in pydecorate. An example of the decorate config:: decorate = { 'decorate': [ {'logo': {'logo_path': <path to a logo>, 'height': 143, 'bg': 'white', 'bg_opacity': 255}}, {'text': {'txt': start_time_txt, 'align': {'top_bottom': 'bottom', 'left_right': 'right'}, 'font': <path to ttf font>, 'font_size': 22, 'height': 30, 'bg': 'black', 'bg_opacity': 255, 'line': 'white'}} ] } Any numbers of text/logo in any order can be added to the decorate list, but the order of the list is kept as described above. Note that a feature given in one element, eg. bg (which is the background color) will also apply on the next elements unless a new value is given. align is a special keyword telling where in the image to start adding features, top_bottom is either top or bottom and left_right is either left or right. """ LOG.info("Decorate image.") # Need to create this here to possible keep the alignment # when adding text and/or logo with pydecorate if hasattr(orig, 'convert'): # image must be in RGB space to work with pycoast/pydecorate orig = orig.convert('RGBA' if orig.mode.endswith('A') else 'RGB') elif not orig.mode.startswith('RGB'): raise RuntimeError("'trollimage' 1.6+ required to support adding " "overlays/decorations to non-RGB data.") img_orig = orig.pil_image(fill_value=fill_value) from pydecorate import DecoratorAGG dc = DecoratorAGG(img_orig) # decorate need to be a list to maintain the alignment # as ordered in the list img = orig if 'decorate' in decorate: for dec in decorate['decorate']: if 'logo' in dec: img = add_logo(img, dc, img_orig, logo=dec['logo']) elif 'text' in dec: img = add_text(img, dc, img_orig, text=dec['text']) elif 'scale' in dec: img = add_scale(img, dc, img_orig, scale=dec['scale']) return img
def add_decorate(orig, fill_value=None, **decorate): """Decorate an image with text and/or logos/images. This call adds text/logos in order as given in the input to keep the alignment features available in pydecorate. An example of the decorate config:: decorate = { 'decorate': [ {'logo': {'logo_path': <path to a logo>, 'height': 143, 'bg': 'white', 'bg_opacity': 255}}, {'text': {'txt': start_time_txt, 'align': {'top_bottom': 'bottom', 'left_right': 'right'}, 'font': <path to ttf font>, 'font_size': 22, 'height': 30, 'bg': 'black', 'bg_opacity': 255, 'line': 'white'}} ] } Any numbers of text/logo in any order can be added to the decorate list, but the order of the list is kept as described above. Note that a feature given in one element, eg. bg (which is the background color) will also apply on the next elements unless a new value is given. align is a special keyword telling where in the image to start adding features, top_bottom is either top or bottom and left_right is either left or right. """ LOG.info("Decorate image.") # Need to create this here to possible keep the alignment # when adding text and/or logo with pydecorate img_orig = orig.pil_image(fill_value=fill_value) from pydecorate import DecoratorAGG dc = DecoratorAGG(img_orig) # decorate need to be a list to maintain the alignment # as ordered in the list if 'decorate' in decorate: for dec in decorate['decorate']: if 'logo' in dec: add_logo(orig, dc, img_orig, logo=dec['logo']) elif 'text' in dec: add_text(orig, dc, img_orig, text=dec['text'])
def test_style_retention(): # import aggdraw from PIL import Image from trollimage.colormap import rdbu from pydecorate import DecoratorAGG # font = aggdraw.Font("navy", DEJAVU_FONT, size=20) # font_scale = aggdraw.Font("black", DEJAVU_FONT, size=12) rdbu.colors = rdbu.colors[::-1] rdbu.set_range(-90, 10) img = Image.open(os.path.join(REPOS_ROOT, "BMNG_clouds_201109181715_areaT2.png")) dc = DecoratorAGG(img) # dc.write_vertically() # dc.add_logo("logos/pytroll_light_big.png") # dc.add_logo("logos/NASA_Logo.gif",margins=[10,10],bg='yellow') # dc.add_logo("logos/pytroll_light_big.png") # font = aggdraw.Font("blue", DEJAVU_FONT, size=16) # dc.add_text("Some text",font=font) # dc.align_right() dc.add_scale(rdbu, extend=True, tick_marks=5.0, line_opacity=100, unit="K") # dc.align_bottom() # dc.add_scale(rdbu, extend=True, tick_marks=2.0, line_opacity=100, width=60) # dc.align_right() # dc.write_vertically() dc.align_bottom() dc.add_scale(rdbu, extend=True, tick_marks=5.0, line_opacity=100, unit="K") # dc.align_left() # dc.add_scale(rdbu, extend=True, font=font_scale, tick_marks=2.0, minor_tick_marks=1.0, # line_opacity=100, width=60, unit='K') # img.show() img.save("style_retention.png")
def savefig(fname, loc=1, decorate=True, **kwargs): """save figure and add the MONET logo . Parameters ---------- fname : str output file name. loc : int the location for the monet logo. decorate : bool Description of parameter `decorate`. **kwargs : dict kwargs for the matplotlib.pyplot.savefig function. Returns ------- type Description of returned object. """ import io import os import sys from PIL import Image import matplotlib.pyplot as plt try: from pydecorate import DecoratorAGG pydecorate = True except ImportError: pydecorate = False plt.savefig(fname, **kwargs) if pydecorate and decorate: img = Image.open(fname) dc = DecoratorAGG(img) if loc == 1: dc.align_bottom() elif loc == 2: dc.align_bottom() dc.align_right() elif loc == 3: dc.align_right() # sys.argv[0])[-5] + 'data/MONET_logo.png' # print(os.path.basename(__file__)) logo = os.path.abspath(__file__)[:-17] + 'data/MONET-logo.png' # print(logo) dc.add_logo(logo) if fname.split('.')[-1] == 'png': img.save(fname, "PNG") elif fname.split('.')[-1] == 'jpg': img.save(fname, "JPEG")
def scatter_rad_rcz(in_msg): # get date of the last SEVIRI observation if in_msg.datetime is None: in_msg.get_last_SEVIRI_date() yearS = str(in_msg.datetime.year) #yearS = yearS[2:] monthS = "%02d" % in_msg.datetime.month dayS = "%02d" % in_msg.datetime.day hourS = "%02d" % in_msg.datetime.hour minS = "%02d" % in_msg.datetime.minute dateS = yearS + '-' + monthS + '-' + dayS timeS = hourS + '-' + minS if in_msg.sat_nr is None: in_msg.sat_nr = choose_msg(in_msg.datetime, in_msg.RSS) # check if PyResample is loaded try: # Work around for on demand import of pyresample. pyresample depends # on scipy.spatial which memory leaks on multiple imports IS_PYRESAMPLE_LOADED = False from pyresample import geometry from mpop.projector import get_area_def IS_PYRESAMPLE_LOADED = True except ImportError: LOGGER.warning( "pyresample missing. Can only work in satellite projection") if in_msg.datetime.year > 2012: if in_msg.sat_nr == 8: area_loaded = get_area_def("EuropeCanary35") elif in_msg.sat_nr == 9: # rapid scan service satellite area_loaded = get_area_def("EuropeCanary95") elif in_msg.sat_nr == 10: # default satellite area_loaded = get_area_def( "met09globeFull" ) # full disk service, like EUMETSATs NWC-SAF products elif in_msg.sat_nr == 0: # fake satellite for reprojected ccs4 data in netCDF area_loaded = get_area_def("ccs4") # #area_loaded = get_area_def("EuropeCanary") #area_loaded = get_area_def("alps") # new projection of SAM else: print("*** Error, unknown satellite number ", in_msg.sat_nr) area_loaded = get_area_def("hsaf") # else: if in_msg.sat_nr == 8: area_loaded = get_area_def("EuropeCanary95") elif in_msg.sat_nr == 9: # default satellite area_loaded = get_area_def("EuropeCanary") # define contour write for coasts, borders, rivers cw = ContourWriterAGG(in_msg.mapDir) if type(in_msg.sat_nr) is int: sat_nr_str = str(in_msg.sat_nr).zfill(2) elif type(in_msg.sat_nr) is str: sat_nr_str = in_msg.sat_nr else: print("*** Waring, unknown type of sat_nr", type(in_msg.sat_nr)) sat_nr_str = in_msg.sat_nr if in_msg.verbose: print('*** Create plots for ') print(' Satellite/Sensor: ' + in_msg.sat + ' ' + sat_nr_str) print(' Date/Time: ' + dateS + ' ' + hourS + ':' + minS + 'UTC') print(' RGBs: ', in_msg.RGBs) print(' Area: ', in_msg.areas) # check if input data is complete if in_msg.verbose: print("*** check input data") RGBs = check_input(in_msg, in_msg.sat + sat_nr_str, in_msg.datetime) if len(RGBs) != len(in_msg.RGBs): print("*** Warning, input not complete.") print("*** Warning, process only: ", RGBs) # define time and data object global_data = GeostationaryFactory.create_scene(in_msg.sat, sat_nr_str, "seviri", in_msg.datetime) # print "type(global_data) ", type(global_data) # <class 'mpop.scene.SatelliteInstrumentScene'> # print "dir(global_data)", dir(global_data) [..., '__init__', ... 'area', 'area_def', 'area_id', 'channel_list', 'channels', # 'channels_to_load', 'check_channels', 'fullname', 'get_area', 'image', 'info', 'instrument_name', 'lat', 'load', 'loaded_channels', # 'lon', 'number', 'orbit', 'project', 'remove_attribute', 'satname', 'save', 'set_area', 'time_slot', 'unload', 'variant'] global_data_radar = GeostationaryFactory.create_scene( "swissradar", "", "radar", in_msg.datetime) global_data_radar.load(['precip']) if len(RGBs) == 0: return RGBs if in_msg.verbose: print( "*** load satellite channels for " + in_msg.sat + sat_nr_str + " ", global_data.fullname) # initialize processed RGBs RGBs_done = [] # load all channels / information for rgb in RGBs: if in_msg.verbose: print(" load prerequisites for: ", rgb) if rgb in products.MSG or rgb in products.MSG_color: for channel in products.MSG: if rgb.find( channel ) != -1: # if a channel name (IR_108) is in the rgb name (IR_108c) if in_msg.verbose: print(" load prerequisites by name: ", channel) if in_msg.reader_level is None: global_data.load( [channel], area_extent=area_loaded.area_extent ) # try all reader levels load the corresponding data else: global_data.load([channel], area_extent=area_loaded.area_extent, reader_level=in_msg.reader_level ) # load the corresponding data if rgb in products.RGBs_buildin or rgb in products.RGBs_user: obj_image = get_image(global_data, rgb) # find corresponding RGB image object if in_msg.verbose: print(" load prerequisites by function: ", obj_image.prerequisites) global_data.load( obj_image.prerequisites, area_extent=area_loaded.area_extent) # load prerequisites if rgb in products.CMa or rgb in products.CT or rgb in products.CTTH or rgb in products.SPhR: if rgb in products.CMa: pge = "CloudMask" elif rgb in products.CT: pge = "CloudType" elif rgb in products.CTTH: pge = "CTTH" elif rgb in products.SPhR: pge = "SPhR" else: print("*** Error in scatter_rad_rcz (" + inspect.getfile(inspect.currentframe()) + ")") print(" unknown NWC-SAF PGE ", rgb) quit() if in_msg.verbose: print(" load NWC-SAF product: " + pge) global_data.load( [pge], calibrate=in_msg.nwcsaf_calibrate, reader_level="seviri-level3" ) # False, area_extent=area_loaded.area_extent (difficulties to find correct h5 input file) #print global_data.loaded_channels() #loaded_channels = [chn.name for chn in global_data.loaded_channels()] #if pge not in loaded_channels: # return [] if area_loaded != global_data[pge].area: print("*** Warning: NWC-SAF input file on a differnt grid (" + global_data[pge].area.name + ") than suggested input area (" + area_loaded.name + ")") print(" use " + global_data[pge].area.name + " as standard grid") area_loaded = global_data[pge].area convert_NWCSAF_to_radiance_format(global_data, area_loaded, rgb, IS_PYRESAMPLE_LOADED) if rgb in products.HSAF: if in_msg.verbose: print(" load hsaf product by name: ", rgb) global_data.load( [rgb] ) # , area_extent=area_loaded.area_extent load the corresponding data if in_msg.HRV_enhancement: # load also the HRV channel (there is a check inside in the load function, if the channel is already loaded) if in_msg.verbose: print( " load additionally the HRV channel for HR enhancement") global_data.load(["HRV"], area_extent=area_loaded.area_extent) # loaded_channels = [chn.name for chn in global_data.loaded_channels()] # print loaded_channels # check if all prerequisites are loaded #rgb_complete = [] #for rgb in RGBs: # all_loaded = True # if rgb in products.RGBs_buildin or rgb in products.RGB_user: # obj_image = get_image(global_data, rgb) # for pre in obj_image.prerequisites: # if pre not in loaded_channels: # all_loaded = False # elif rgb in products.MSG_color: # if rgb.replace("c","") not in loaded_channels: # all_loaded = False # else: # if rgb not in loaded_channels: # all_loaded = False # if all_loaded: # rgb_complete.append(rgb) #print "rgb_complete", rgb_complete # preprojecting the data to another area # -------------------------------------- for area in in_msg.areas: print("") obj_area = get_area_def(area) if obj_area == area_loaded: if in_msg.verbose: print("*** Use data for the area loaded: ", area) #obj_area = area_loaded data = global_data resolution = 'l' else: if in_msg.verbose: print("*** Reproject data to area: ", area, "(org projection: ", area_loaded.name, ")") obj_area = get_area_def(area) # PROJECT data to new area data = global_data.project(area) resolution = 'i' if in_msg.mapResolution is None: if area.find("EuropeCanary") != -1: resolution = 'l' if area.find("ccs4") != -1: resolution = 'i' if area.find("ticino") != -1: resolution = 'h' else: resolution = in_msg.mapResolution # define area proj4_string = obj_area.proj4_string # e.g. proj4_string = '+proj=geos +lon_0=0.0 +a=6378169.00 +b=6356583.80 +h=35785831.0' area_extent = obj_area.area_extent # e.g. area_extent = (-5570248.4773392612, -5567248.074173444, 5567248.074173444, 5570248.4773392612) area_tuple = (proj4_string, area_extent) # save reprojected data if area in in_msg.save_reprojected_data: # and area != area_loaded _sat_nr = int(data.number) - 7 if int(data.number) - 7 > 0 else 0 nc_dir = ( global_data.time_slot.strftime(in_msg.reprojected_data_dir) % { "area": area, "msg": "MSG" + str(_sat_nr) }) nc_file = (global_data.time_slot.strftime( in_msg.reprojected_data_filename) % { "area": area, "msg": "MSG" + str(_sat_nr) }) ncOutputFile = nc_dir + nc_file # check if output directory exists, if not create it path = dirname(ncOutputFile) if not exists(path): if in_msg.verbose: print('... create output directory: ' + path) makedirs(path) if in_msg.verbose: print("... save reprojected data: ncview " + ncOutputFile + " &") #data.save(ncOutputFile, to_format="netcdf4", compression=False) data.save(ncOutputFile, band_axis=0, concatenate_bands=False) # mask for the cloud depths tests (masked data) #if area == 'ccs4': if area == False: print('... apply convective mask') mask_depth = data.image.mask_clouddepth() #print type(mask_depth.max) #print dir(mask_depth.max) index = where( mask_depth < 5) # less than 5 (of 6) tests successfull -> mask out for rgb in RGBs: if rgb in products.MSG_color: rgb2 = rgb.replace("c", "") data[rgb2].data.mask[index] = True fill_value = data[rgb2].data.fill_value #data["IR_108"].data[index] = fill_value #print "data[IR_108].data.min/max ", data["IR_108"].data.min(), data["IR_108"].data.max() #if rgb == "IR_108c": # print type(data["IR_108"].data) # print dir(data["IR_108"].data) #print data["IR_108"].data.mask # save average values if in_msg.save_statistics: mean_array = zeros(len(RGBs)) #statisticFile = '/data/COALITION2/database/meteosat/ccs4/'+yearS+'/'+monthS+'/'+dayS+'/MSG_'+area+'_'+yearS[2:]+monthS+dayS+'.txt' statisticFile = './' + yearS + '-' + monthS + '-' + dayS + '/MSG_' + area + '_' + yearS[ 2:] + monthS + dayS + '.txt' if in_msg.verbose: print("*** write statistics (average values) to " + statisticFile) f1 = open(statisticFile, 'a') # mode append i_rgb = 0 for rgb in RGBs: if rgb in products.MSG_color: mean_array[i_rgb] = data[rgb.replace("c", "")].data.mean() i_rgb = i_rgb + 1 # create string to write str2write = dateS + ' ' + hourS + ' : ' + minS + ' UTC ' for mm in mean_array: str2write = str2write + ' ' + "%7.2f" % mm str2write = str2write + "\n" f1.write(str2write) f1.close() print("y.shape ", global_data_radar['precip'].data.shape) from numpy import copy y = copy(global_data_radar['precip'].data) y = y.ravel() print("y.shape ", y.shape) if 1 == 0: if 'X' in locals(): del X from numpy import column_stack, append, concatenate for rgb in RGBs: # poor mans parallax correction if rgb in products.MSG_color: rgb2 = rgb.replace("c", "") else: rgb2 = rgb x1 = data[rgb2].data.ravel() if 'X' not in locals(): X = x1 X = [X] else: concatenate((X, [x1]), axis=0) print("X.shape ", X.shape) X = append(X, [[1] * len(x1)], axis=1) print("y.shape ", y.shape) #theta = np.linalg.lstsq(X,y)[0] return ind_gt_1 = y > 1 x = x[ind_gt_1] y = y[ind_gt_1] ind_lt_200 = y < 200 x = x[ind_lt_200] y = y[ind_lt_200] #ind_gt_0 = x>0 #x = x[ind_gt_0] #y = y[ind_gt_0] #X = np.column_stack(x+[[1]*len(x[0])]) #beta_hat = np.linalg.lstsq(X,y)[0] #print beta_hat #X_hat= np.dot(X,theta) #y_hat = X_hat.reshape((640, 710)) # creating plots/images if in_msg.make_plots: ind_cloudy = data['CTH'].data > 0 ind_clear = data['CTH'].data <= 0 ind_cloudy = ind_cloudy.ravel() for rgb in RGBs: if rgb in products.MSG_color: rgb2 = rgb.replace("c", "") else: rgb2 = rgb if rgb == 'ir108': rgb2 = 'IR_108' # poor mans parallax correction if 1 == 0: print("... poor mans parallax correction") data[rgb2].data[25:640, :] = data[rgb2].data[0:615, :] #data[rgb2].data[15:640,:] = data[rgb2].data[0:625,:] data[rgb2].data[:, 0:700] = data[rgb2].data[:, 10:710] # create output filename outputDir = format_name(in_msg.outputDir, data.time_slot, area=area, rgb=rgb, sat_nr=data.number) outputFile = outputDir + format_name(in_msg.outputFile, data.time_slot, area=area, rgb=rgb, sat_nr=data.number) PIL_image = create_PIL_image( rgb, data, in_msg ) # !!! in_msg.colorbar[rgb] is initialized inside (give attention to rgbs) !!! if 1 == 1: y = copy(global_data_radar['precip'].data) ind_gt_300 = y > 300 # replace no rain marker with 0mm/h y[ind_gt_300] = 0 y = y.ravel() print("y.shape ", y.shape) x = copy(data[rgb2].data) x = x.ravel() ## get rid of clear sky x = x[ind_cloudy] y = y[ind_cloudy] #ind_gt_01 = x>0.1 #x = x[ind_gt_01] #y = y[ind_gt_01] # get rid of no rain limits for rainfall ind_gt_01 = y > 0.1 x = x[ind_gt_01] y = y[ind_gt_01] ind_lt_300 = y < 300 x = x[ind_lt_300] y = y[ind_lt_300] plt.figure() plt.title('Scatterplot precipitation - radiance') plt.xlabel(rgb) plt.ylabel('precipitation in mm/h') plt.scatter(x, y) #, s=area, c=colors, alpha=0.5 outputDir = format_name(in_msg.outputDir, data.time_slot, area=area, rgb=rgb, sat_nr=data.number) outputFileScatter = outputDir + format_name( 'scatterplot_%(area)s_%Y%m%d%H%M_%(rgb)s_precip_pc.png', data.time_slot, area=area, rgb=rgb, sat_nr=data.number) #plt.show() from numpy import arange x_line = arange(x.min(), x.max(), 1) print("*** display " + outputFileScatter + " &") from numpy import ones, linalg, array print(x.min(), x.max(), y.min(), y.max()) A = array([x, ones(x.size)]) w = linalg.lstsq(A.T, y)[0] # obtaining the parameters y_line = w[0] * x_line + w[1] # regression line #--- #from scipy import stats #slope, intercept, r_value, p_value, std_err = stats.linregress(x,y) #print "slope, intercept, r_value, p_value, std_err" #print slope, intercept, r_value, p_value, std_err #y_line = slope*x_line + intercept from pylab import plot plot(x_line, y_line, 'r-') plt.savefig(outputFileScatter) y_hat = w[0] * data[rgb2].data + w[1] print("y_hat.shape: ", y_hat.shape) # set clear sky to 0 y_hat[ind_clear] = 0 y_hat = ma.asarray(y_hat) y_hat.mask = (y_hat == 9999.9) | (y_hat <= 0.0001) from trollimage.colormap import RainRate colormap = rainbow min_data = 0.0 #max_data=y_hat.max() max_data = 8 colormap.set_range(min_data, max_data) #colormap = RainRate in_msg.colormap[rgb] = colormap units = 'mm/h' img = trollimage(y_hat, mode="L") img.colorize(in_msg.colormap[rgb]) in_msg.colormap[rgb] = colormap.reverse() PIL_image = img.pil_image() outputFile = outputDir + format_name( 'fit_%(area)s_%Y%m%d%H%M_%(rgb)s_precip.png', data.time_slot, area=area, rgb=rgb, sat_nr=data.number) #PIL_image.save(outputFile) ## add coasts, borders, and rivers, database is heree ## http://www.soest.hawaii.edu/pwessel/gshhs/index.html ## possible resolutions ## f full resolution: Original (full) data resolution. ## h high resolution: About 80 % reduction in size and quality. ## i intermediate resolution: Another ~80 % reduction. ## l low resolution: Another ~80 % reduction. ## c crude resolution: Another ~80 % reduction. if in_msg.add_rivers: if in_msg.verbose: print(" add rivers to image (resolution=" + resolution + ")") cw.add_rivers(PIL_image, area_tuple, outline='blue', resolution=resolution, outline_opacity=127, width=0.5, level=5) # if in_msg.verbose: print(" add lakes to image (resolution=" + resolution + ")") cw.add_coastlines(PIL_image, area_tuple, outline='blue', resolution=resolution, outline_opacity=127, width=0.5, level=2) #, outline_opacity=0 if in_msg.add_borders: if in_msg.verbose: print(" add coastlines to image (resolution=" + resolution + ")") cw.add_coastlines(PIL_image, area_tuple, outline=(255, 0, 0), resolution=resolution, width=1) #, outline_opacity=0 if in_msg.verbose: print(" add borders to image (resolution=" + resolution + ")") cw.add_borders(PIL_image, area_tuple, outline=(255, 0, 0), resolution=resolution, width=1) #, outline_opacity=0 #if area.find("EuropeCanary") != -1 or area.find("ccs4") != -1: dc = DecoratorAGG(PIL_image) # add title to image if in_msg.add_title: PIL_image = add_title(PIL_image, rgb, int(data.number), dateS, hourS, minS, area, dc, in_msg.font_file, in_msg.verbose) # add MeteoSwiss and Pytroll logo if in_msg.add_logos: if in_msg.verbose: print('... add logos') dc.align_right() if in_msg.add_colorscale: dc.write_vertically() dc.add_logo("../logos/meteoSwiss3.jpg", height=60.0) dc.add_logo("../logos/pytroll3.jpg", height=60.0) # add colorscale if in_msg.add_colorscale and in_msg.colormap[rgb] is not None: dc.align_right() dc.write_vertically() font_scale = aggdraw.Font( "black", "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSerif-Bold.ttf", size=16) # get tick marks tick_marks = 20 # default minor_tick_marks = 5 # default if rgb in list(in_msg.tick_marks.keys()): tick_marks = in_msg.tick_marks[rgb] if rgb in list(in_msg.minor_tick_marks.keys()): minor_tick_marks = in_msg.minor_tick_marks[rgb] if rgb.find( "-" ) != -1: # for channel differences use tickmarks of 1 tick_marks = 1 minor_tick_marks = 1 tick_marks = 2 # default minor_tick_marks = 1 # default if in_msg.verbose: print('... add colorscale') dc.add_scale(in_msg.colormap[rgb], extend=True, tick_marks=tick_marks, minor_tick_marks=minor_tick_marks, font=font_scale, line_opacity=100) #, unit='T / K' ## test to plot a wind barb #import matplotlib.pyplot as plt #ax = plt.axes(PIL_image) #ax.barbs(0, 0, 20, 20, length=8, pivot='middle', barbcolor='red') #ax.barbs(8, 46, 20, 20, length=8, pivot='middle', barbcolor='red') # check if output directory exists, if not create it path = dirname(outputFile) if not exists(path): if in_msg.verbose: print('... create output directory: ' + path) makedirs(path) # save file if in_msg.verbose: print('... save final file :' + outputFile) PIL_image.save(outputFile, optimize=True) # optimize -> minimize file size if in_msg.compress_to_8bit: if in_msg.verbose: print('... compress to 8 bit image: display ' + outputFile.replace(".png", "-fs8.png") + ' &') subprocess.call("/usr/bin/pngquant -force 256 " + outputFile + " 2>&1 &", shell=True) # 256 == "number of colors" #if in_msg.verbose: # print " add coastlines to "+outputFile ## alternative: reopen image and modify it (takes longer due to additional reading and saving) #cw.add_rivers_to_file(img, area_tuple, level=5, outline='blue', width=0.5, outline_opacity=127) #cw.add_coastlines_to_file(outputFile, obj_area, resolution=resolution, level=4) #cw.add_borders_to_file(outputFile, obj_area, outline=outline, resolution=resolution) # copy to another place if in_msg.scpOutput: if in_msg.verbose: print("... secure copy " + outputFile + " to " + in_msg.scpOutputDir) subprocess.call("scp " + in_msg.scpID + " " + outputFile + " " + in_msg.scpOutputDir + " 2>&1 &", shell=True) if in_msg.compress_to_8bit: if in_msg.verbose: print("... secure copy " + outputFile.replace(".png", "-fs8.png") + " to " + in_msg.scpOutputDir) subprocess.call( "scp " + in_msg.scpID + " " + outputFile.replace(".png", "-fs8.png") + " " + in_msg.scpOutputDir + " 2>&1 &", shell=True) if rgb not in RGBs_done: RGBs_done.append(rgb) ## start postprocessing if area in in_msg.postprocessing_areas: postprocessing(in_msg, global_data.time_slot, data.number, area) if in_msg.verbose: print(" ") return RGBs_done
def main(): parser = get_parser() args = parser.parse_args() levels = [logging.ERROR, logging.WARN, logging.INFO, logging.DEBUG] logging.basicConfig(level=levels[min(3, args.verbosity)]) if args.output_filename is None: args.output_filename = [x[:-3] + "png" for x in args.input_tiff] else: assert len(args.output_filename) == len( args.input_tiff ), "Output filenames must be equal to number of input tiffs" if not (args.add_borders or args.add_coastlines or args.add_grid or args.add_rivers or args.add_colorbar): LOG.error( "Please specify one of the '--add-X' options to modify the image") return -1 # we may be dealing with large images that look like decompression bombs # let's turn off the check for the image size in PIL/Pillow Image.MAX_IMAGE_PIXELS = None for input_tiff, output_filename in zip(args.input_tiff, args.output_filename): LOG.info("Creating {} from {}".format(output_filename, input_tiff)) gtiff = gdal.Open(input_tiff) proj4_str = osr.SpatialReference(gtiff.GetProjection()).ExportToProj4() ul_x, res_x, _, ul_y, _, res_y = gtiff.GetGeoTransform() half_pixel_x = res_x / 2. half_pixel_y = res_y / 2. area_extent = ( ul_x - half_pixel_x, # lower-left X ul_y + res_y * gtiff.RasterYSize - half_pixel_y, # lower-left Y ul_x + res_x * gtiff.RasterXSize + half_pixel_x, # upper-right X ul_y + half_pixel_y, # upper-right Y ) img = Image.open(input_tiff).convert('RGBA' if gtiff.RasterCount in ( 2, 4) else 'RGB') area_def = (proj4_str, area_extent) cw = ContourWriterAGG(args.shapes_dir) if args.add_coastlines: outline = args.coastlines_outline[0] if len( args.coastlines_outline) == 1 else tuple( int(x) for x in args.coastlines_outline) if args.coastlines_fill: fill = args.coastlines_fill[0] if len( args.coastlines_fill) == 1 else tuple( int(x) for x in args.coastlines_fill) else: fill = None cw.add_coastlines(img, area_def, resolution=args.coastlines_resolution, level=args.coastlines_level, width=args.coastlines_width, outline=outline, fill=fill) if args.add_rivers: outline = args.rivers_outline[0] if len( args.rivers_outline) == 1 else tuple( int(x) for x in args.rivers_outline) cw.add_rivers(img, area_def, resolution=args.rivers_resolution, level=args.rivers_level, width=args.rivers_width, outline=outline) if args.add_borders: outline = args.borders_outline[0] if len( args.borders_outline) == 1 else tuple( int(x) for x in args.borders_outline) cw.add_borders(img, area_def, resolution=args.borders_resolution, level=args.borders_level, outline=outline, width=args.borders_width) if args.add_grid: outline = args.grid_outline[0] if len( args.grid_outline) == 1 else tuple( int(x) for x in args.grid_outline) minor_outline = args.grid_minor_outline[0] if len( args.grid_minor_outline) == 1 else tuple( int(x) for x in args.grid_minor_outline) fill = args.grid_fill[0] if len(args.grid_fill) == 1 else tuple( int(x) for x in args.grid_fill) font_path = find_font(args.grid_font, args.grid_text_size) font = Font(outline, font_path, size=args.grid_text_size) cw.add_grid(img, area_def, args.grid_D, args.grid_d, font, fill=fill, outline=outline, minor_outline=minor_outline, write_text=args.grid_text, width=args.grid_width, lon_placement=args.grid_lon_placement, lat_placement=args.grid_lat_placement) if args.add_colorbar: from pydecorate import DecoratorAGG font_color = args.colorbar_text_color font_color = font_color[0] if len(font_color) == 1 else tuple( int(x) for x in font_color) font_path = find_font(args.colorbar_font, args.colorbar_text_size) # this actually needs an aggdraw font font = Font(font_color, font_path, size=args.colorbar_text_size) band_count = gtiff.RasterCount if band_count not in [1, 2]: raise ValueError("Can't add colorbar to RGB/RGBA image") # figure out what colormap we are dealing with band = gtiff.GetRasterBand(1) cmap = get_colormap(band, band_count) # figure out our limits vmin = args.colorbar_min vmax = args.colorbar_max metadata = gtiff.GetMetadata_Dict() vmin = vmin or metadata.get('min_in') vmax = vmax or metadata.get('max_in') if isinstance(vmin, str): vmin = float(vmin) if isinstance(vmax, str): vmax = float(vmax) if vmin is None or vmax is None: data = gtiff.GetRasterBand(1).ReadAsArray() vmin = vmin or np.iinfo(data.dtype).min vmax = vmax or np.iinfo(data.dtype).max cmap.set_range(vmin, vmax) dc = DecoratorAGG(img) if args.colorbar_align == 'top': dc.align_top() elif args.colorbar_align == 'bottom': dc.align_bottom() elif args.colorbar_align == 'left': dc.align_left() elif args.colorbar_align == 'right': dc.align_right() if args.colorbar_vertical: dc.write_vertically() else: dc.write_horizontally() if args.colorbar_width is None or args.colorbar_height is None: LOG.warning("'--colorbar-width' or '--colorbar-height' were " "not specified. Forcing '--colorbar-extend'.") args.colorbar_extend = True kwargs = {} if args.colorbar_width: kwargs['width'] = args.colorbar_width if args.colorbar_height: kwargs['height'] = args.colorbar_height dc.add_scale(cmap, extend=args.colorbar_extend, font=font, line=font_color, tick_marks=args.colorbar_tick_marks, title=args.colorbar_title, unit=args.colorbar_units, **kwargs) img.save(output_filename)
def plot(data, text, minmax=None, transpose=False, filename=None, position=(-16.743860721,64.915348712,712.4), tilt=None, target_position=None, target_name="", vfov=18.5, tick_distance=50.0): if transpose: data = data.transpose() if minmax is None: rainbow.set_range(data.min(),data.max()) else: rainbow.set_range(minmax[0],minmax[1]) img = Image(data, mode="L") img.colorize(rainbow) img = img.pil_image() # Decoration dc = DecoratorAGG(img) dc.align_bottom() #dc.add_logo("/home/sat/dev/pydecorate/logos/VI_Logo_Transp.png") #dc.add_logo("Nicarnica-Aviation-22-oct-300x102.png") try: dc.add_logo("/home/master/bin/futurevolc_logo.png", height=47) dc.add_logo("/home/master/bin/nicarnica_logo.png") dc.add_logo("/home/master/bin/vi_logo.png") except IOError: dc.add_logo("bin/futurevolc_logo.png", height=47) dc.add_logo("bin/nicarnica_logo.png") dc.add_logo("bin/vi_logo.png") dc.add_text(text, font=font) tick_space = 5.0 #dc.add_scale(rainbow, extend=True, unit='°C', tick_marks=tick_space, minor_tick_marks=tick_space) # target distance and km/px ny = data.shape[0] nx = data.shape[1] distance = distance_longlat(target_position,position) # plot grid lines, texts = prepare_graticule(nx, ny, distance=distance, vfov=vfov, tilt=tilt, tick_distance=tick_distance, height=position[2],target_height=target_position[2], target_name=target_name) draw_lines(img, lines) draw_texts(img, texts) if filename == None: img.show() else: img.save(filename, "JPEG", quality=90)
def plot_msg_minus_cosmo(in_msg): # do statistics for the last full hour (minutes=0, seconds=0) in_msg.datetime = datetime(in_msg.datetime.year, in_msg.datetime.month, in_msg.datetime.day, in_msg.datetime.hour, 0, 0) area_loaded = choose_area_loaded_msg(in_msg.sat, in_msg.sat_nr, in_msg.datetime) # define contour write for coasts, borders, rivers cw = ContourWriterAGG(in_msg.mapDir) # check if input data is complete if in_msg.verbose: print("*** check input data for ", in_msg.sat_str()) RGBs = check_input(in_msg, in_msg.sat_str(layout="%(sat)s") + in_msg.sat_nr_str(), in_msg.datetime) # in_msg.sat_nr might be changed to backup satellite if in_msg.verbose: print('*** Create plots for ') print(' Satellite/Sensor: ' + in_msg.sat_str()) print(' Satellite number: ' + in_msg.sat_nr_str() + ' // ' + str(in_msg.sat_nr)) print(' Satellite instrument: ' + in_msg.instrument) print(' Date/Time: ' + str(in_msg.datetime)) print(' RGBs: ', in_msg.RGBs) print(' Area: ', in_msg.areas) print(' reader level: ', in_msg.reader_level) # define satellite data object #global_data = GeostationaryFactory.create_scene(in_msg.sat, in_msg.sat_nr_str(), "seviri", in_msg.datetime) global_data = GeostationaryFactory.create_scene(in_msg.sat_str(), in_msg.sat_nr_str(), in_msg.instrument, in_msg.datetime) # global_data = GeostationaryFactory.create_scene("msg-ot", "", "Overshooting_Tops", in_msg.datetime) if len(RGBs) == 0 and len(in_msg.postprocessing_areas) == 0: return RGBs if in_msg.verbose: print( "*** load satellite channels for " + in_msg.sat_str() + in_msg.sat_nr_str() + " ", global_data.fullname) # initialize processed RGBs RGBs_done = [] # ------------------------------------------------------------------- # load reflectivities, brightness temperatures, NWC-SAF products ... # ------------------------------------------------------------------- area_loaded = load_products(global_data, RGBs, in_msg, area_loaded) cosmo_input_file = "input_cosmo_cronjob.py" print("... read COSMO input file: ", cosmo_input_file) in_cosmo = parse_commandline_and_read_inputfile( input_file=cosmo_input_file) # add composite in_msg.scpOutput = True in_msg.resize_montage = 70 in_msg.postprocessing_montage = [[ "MSG_IR-108cpc", "COSMO_SYNMSG-BT-CL-IR10.8", "MSG_IR-108-COSMO-minus-MSGpc" ]] in_msg.scpProducts = [[ "MSG_IR-108cpc", "COSMO_SYNMSG-BT-CL-IR10.8", "MSG_IR-108-COSMO-minus-MSGpc" ]] #in_msg.scpProducts = ["all"] # define satellite data object cosmo_data = GeostationaryFactory.create_scene(in_cosmo.sat_str(), in_cosmo.sat_nr_str(), in_cosmo.instrument, in_cosmo.datetime) area_loaded_cosmo = load_products(cosmo_data, ['SYNMSG_BT_CL_IR10.8'], in_cosmo, area_loaded) # preprojecting the data to another area # -------------------------------------- if len(RGBs) > 0: for area in in_msg.areas: print("") obj_area = get_area_def(area) if area != 'ccs4': print("*** WARNING, diff MSG-COSMO only implemented for ccs4") continue # reproject data to new area print(area_loaded) if obj_area == area_loaded: if in_msg.verbose: print("*** Use data for the area loaded: ", area) #obj_area = area_loaded data = global_data resolution = 'l' else: if in_msg.verbose: print("*** Reproject data to area: ", area, "(org projection: ", area_loaded.name, ")") obj_area = get_area_def(area) # PROJECT data to new area data = global_data.project(area, precompute=True) resolution = 'i' if in_msg.parallax_correction: loaded_products = [chn.name for chn in data.loaded_channels()] if 'CTH' not in loaded_products: print("*** Error in plot_msg (" + inspect.getfile(inspect.currentframe()) + ")") print( " Cloud Top Height is needed for parallax correction " ) print( " either load CTH or specify the estimation of the CTH in the input file (load 10.8 in this case)" ) quit() if in_msg.verbose: print( " perform parallax correction for loaded channels: ", loaded_products) data = data.parallax_corr(fill=in_msg.parallax_gapfilling, estimate_cth=in_msg.estimate_cth, replace=True) # save reprojected data if area in in_msg.save_reprojected_data: save_reprojected_data(data, area, in_msg) # apply a mask to the data (switched off at the moment) if False: mask_data(data, area) # save average values if in_msg.save_statistics: mean_array = zeros(len(RGBs)) #statisticFile = '/data/COALITION2/database/meteosat/ccs4/'+yearS+'/'+monthS+'/'+dayS+'/MSG_'+area+'_'+yearS[2:]+monthS+dayS+'.txt' statisticFile = './' + yearS + '-' + monthS + '-' + dayS + '/MSG_' + area + '_' + yearS[ 2:] + monthS + dayS + '.txt' if in_msg.verbose: print("*** write statistics (average values) to " + statisticFile) f1 = open(statisticFile, 'a') # mode append i_rgb = 0 for rgb in RGBs: if rgb in products.MSG_color: mean_array[i_rgb] = data[rgb.replace("c", "")].data.mean() i_rgb = i_rgb + 1 # create string to write str2write = dateS + ' ' + hourS + ' : ' + minS + ' UTC ' for mm in mean_array: str2write = str2write + ' ' + "%7.2f" % mm str2write = str2write + "\n" f1.write(str2write) f1.close() # creating plots/images if in_msg.make_plots: # choose map resolution in_msg.resolution = choose_map_resolution( area, in_msg.mapResolution) # define area proj4_string = obj_area.proj4_string # e.g. proj4_string = '+proj=geos +lon_0=0.0 +a=6378169.00 +b=6356583.80 +h=35785831.0' area_extent = obj_area.area_extent # e.g. area_extent = (-5570248.4773392612, -5567248.074173444, 5567248.074173444, 5570248.4773392612) area_tuple = (proj4_string, area_extent) RGBs = ['IR_108-COSMO-minus-MSG'] print(data['IR_108'].data.shape) print(cosmo_data['SYNMSG_BT_CL_IR10.8'].data.shape) diff_MSG_COSMO = cosmo_data['SYNMSG_BT_CL_IR10.8'].data - data[ 'IR_108'].data HRV_enhance_str = '' # add IR difference as "channel object" to satellite regional "data" object data.channels.append( Channel(name=RGBs[0], wavelength_range=[0., 0., 0.], resolution=data['IR_108'].resolution, data=diff_MSG_COSMO)) for rgb in RGBs: if not check_loaded_channels(rgb, data): continue PIL_image = create_PIL_image(rgb, data, in_msg, obj_area=obj_area) # !!! in_msg.colorbar[rgb] is initialized inside (give attention to rgbs) !!! add_borders_and_rivers(PIL_image, cw, area_tuple, add_borders=in_msg.add_borders, border_color=in_msg.border_color, add_rivers=in_msg.add_rivers, river_color=in_msg.river_color, resolution=in_msg.resolution, verbose=in_msg.verbose) # indicate mask if in_msg.indicate_mask: PIL_image = indicate_mask(rgb, PIL_image, data, in_msg.verbose) #if area.find("EuropeCanary") != -1 or area.find("ccs4") != -1: dc = DecoratorAGG(PIL_image) # add title to image if in_msg.add_title: add_title(PIL_image, in_msg.title, HRV_enhance_str + rgb, in_msg.sat_str(), data.sat_nr(), in_msg.datetime, area, dc, in_msg.font_file, in_msg.verbose, title_color=in_msg.title_color, title_y_line_nr=in_msg.title_y_line_nr ) # !!! needs change # add MeteoSwiss and Pytroll logo if in_msg.add_logos: if in_msg.verbose: print('... add logos') dc.align_right() if in_msg.add_colorscale: dc.write_vertically() if PIL_image.mode != 'L': height = 60 # height=60.0 normal resolution dc.add_logo(in_msg.logos_dir + "/pytroll3.jpg", height=height) # height=60.0 dc.add_logo(in_msg.logos_dir + "/meteoSwiss3.jpg", height=height) dc.add_logo( in_msg.logos_dir + "/EUMETSAT_logo2_tiny_white_square.png", height=height) # height=60.0 # add colorscale if in_msg.add_colorscale and in_msg.colormap[rgb] != None: if rgb in products.MSG_color: unit = data[rgb.replace("c", "")].info['units'] #elif rgb in products.MSG or rgb in products.NWCSAF or rgb in products.HSAF: # unit = data[rgb].info['units'] else: unit = None loaded_channels = [ chn.name for chn in data.loaded_channels() ] if rgb in loaded_channels: if hasattr(data[rgb], 'info'): print(" hasattr(data[rgb], 'info')", list(data[rgb].info.keys())) if 'units' in list(data[rgb].info.keys()): print( "'units' in data[rgb].info.keys()") unit = data[rgb].info['units'] print("... units = ", unit) add_colorscale(dc, rgb, in_msg, unit=unit) if in_msg.parallax_correction: parallax_correction_str = 'pc' else: parallax_correction_str = '' rgb += parallax_correction_str # create output filename outputDir = format_name( in_msg.outputDir, data.time_slot, area=area, rgb=rgb, sat=data.satname, sat_nr=data.sat_nr()) # !!! needs change outputFile = outputDir + "/" + format_name( in_msg.outputFile, data.time_slot, area=area, rgb=rgb, sat=data.satname, sat_nr=data.sat_nr()) # !!! needs change # check if output directory exists, if not create it path = dirname(outputFile) if not exists(path): if in_msg.verbose: print('... create output directory: ' + path) makedirs(path) # save file if exists(outputFile) and not in_msg.overwrite: if stat(outputFile).st_size > 0: print('... outputFile ' + outputFile + ' already exists (keep old file)') else: print( '*** Warning, outputFile' + outputFile + ' already exists, but is empty (overwrite file)' ) PIL_image.save(outputFile, optimize=True ) # optimize -> minimize file size chmod( outputFile, 0o777 ) ## FOR PYTHON3: 0o664 # give access read/write access to group members else: if in_msg.verbose: print('... save final file: ' + outputFile) PIL_image.save( outputFile, optimize=True) # optimize -> minimize file size chmod( outputFile, 0o777 ) ## FOR PYTHON3: 0o664 # give access read/write access to group members if in_msg.compress_to_8bit: if in_msg.verbose: print('... compress to 8 bit image: display ' + outputFile.replace(".png", "-fs8.png") + ' &') subprocess.call( "/usr/bin/pngquant -force 256 " + outputFile + " 2>&1 &", shell=True) # 256 == "number of colors" #if in_msg.verbose: # print " add coastlines to "+outputFile ## alternative: reopen image and modify it (takes longer due to additional reading and saving) #cw.add_rivers_to_file(img, area_tuple, level=5, outline='blue', width=0.5, outline_opacity=127) #cw.add_coastlines_to_file(outputFile, obj_area, resolution=resolution, level=4) #cw.add_borders_to_file(outputFile, obj_area, outline=outline, resolution=resolution) # secure copy file to another place if in_msg.scpOutput: if (rgb in in_msg.scpProducts) or ('all' in [ x.lower() for x in in_msg.scpProducts if type(x) == str ]): scpOutputDir = format_name(in_msg.scpOutputDir, data.time_slot, area=area, rgb=rgb, sat=data.satname, sat_nr=data.sat_nr()) if in_msg.compress_to_8bit: if in_msg.verbose: print("... secure copy " + outputFile.replace( ".png", "-fs8.png") + " to " + scpOutputDir) subprocess.call( "scp " + in_msg.scpID + " " + outputFile.replace(".png", "-fs8.png") + " " + scpOutputDir + " 2>&1 &", shell=True) else: if in_msg.verbose: print("... secure copy " + outputFile + " to " + scpOutputDir) subprocess.call("scp " + in_msg.scpID + " " + outputFile + " " + scpOutputDir + " 2>&1 &", shell=True) if in_msg.scpOutput and in_msg.scpID2 != None and in_msg.scpOutputDir2 != None: if (rgb in in_msg.scpProducts2) or ('all' in [ x.lower() for x in in_msg.scpProducts2 if type(x) == str ]): scpOutputDir2 = format_name(in_msg.scpOutputDir2, data.time_slot, area=area, rgb=rgb, sat=data.satname, sat_nr=data.sat_nr()) if in_msg.compress_to_8bit: if in_msg.verbose: print("... secure copy " + outputFile.replace( ".png", "-fs8.png") + " to " + scpOutputDir2) subprocess.call( "scp " + in_msg.scpID2 + " " + outputFile.replace(".png", "-fs8.png") + " " + scpOutputDir2 + " 2>&1 &", shell=True) else: if in_msg.verbose: print("... secure copy " + outputFile + " to " + scpOutputDir2) subprocess.call("scp " + in_msg.scpID2 + " " + outputFile + " " + scpOutputDir2 + " 2>&1 &", shell=True) if 'ninjotif' in in_msg.outputFormats: ninjotif_file = format_name(outputDir + '/' + in_msg.ninjotifFilename, data.time_slot, sat_nr=data.sat_nr(), RSS=in_msg.RSS, area=area, rgb=rgb) from plot_coalition2 import pilimage2geoimage GEO_image = pilimage2geoimage(PIL_image, obj_area, data.time_slot) GEO_image.save(ninjotif_file, fformat='mpop.imageo.formats.ninjotiff', ninjo_product_name=rgb, chan_id=products.ninjo_chan_id[ rgb.replace("_", "-") + "_" + area], nbits=8) chmod(ninjotif_file, 0o777) print(("... save ninjotif image: display ", ninjotif_file, " &")) if rgb not in RGBs_done: RGBs_done.append(rgb) ## start postprocessing for area in in_msg.postprocessing_areas: postprocessing(in_msg, global_data.time_slot, int(data.sat_nr()), area) if in_msg.verbose: print(" ") return RGBs_done
def nostradamus_rain(in_msg): if in_msg.datetime is None: in_msg.get_last_SEVIRI_date() if in_msg.end_date is None: in_msg.end_date = in_msg.datetime #in_msg.end_date = in_msg.datetime + timedelta(15) delta = timedelta(minutes=15) # automatic choise of the FULL DISK SERVICE Meteosat satellite if in_msg.datetime < datetime(2008, 5, 13, 0, 0): # before 13.05.2008 only nominal MSG1 (meteosat8), no Rapid Scan Service yet sat_nr = "08" elif in_msg.datetime < datetime(2013, 2, 27, 9, 0): # 13.05.2008 ... 27.02.2013 sat_nr = "09" # MSG-2 (meteosat9) became nominal satellite, MSG-1 (meteosat8) started RSS elif in_msg.datetime < datetime(2018, 3, 9, 0, 0): # 27.02.2013 9:00UTC ... 09.03.2013 sat_nr = "10" # MSG-3 (meteosat10) became nominal satellite, MSG-2 started RSS (MSG1 is backup for MSG2) else: sat_nr = "11" print ("... work with Meteosat"+str(sat_nr)) print ("") if in_msg.verbose: print ('*** Create plots for ') print (' Satellite/Sensor: ' + in_msg.sat_str()) print (' Satellite number: ' + in_msg.sat_nr_str() +' // ' +str(in_msg.sat_nr)) print (' Satellite instrument: ' + in_msg.instrument) print (' Start Date/Time: '+ str(in_msg.datetime)) print (' End Date/Time: '+ str(in_msg.datetime)) print (' Areas: ', in_msg.areas) for area in in_msg.plots.keys(): print (' plots['+area+']: ', in_msg.plots[area]) #print (' parallax_correction: ', in_msg.parallax_correction) #print (' reader level: ', in_msg.reader_level) ## read in all the constants files print('=================================') print('*** load the constant fields (radar mask, viewing geometry, and land/sea mask plus surface elevation)') global_radar_mask, global_vg, global_ls_ele = load_constant_fields(sat_nr) ############################################### ## load the mlp for the precip detection (pd) # ############################################### if in_msg.model == 'mlp': dir_start_pd= './models/precipitation_detection/mlp/2hl_100100hu_10-7alpha_log/' dir_start_rr= './models/precipitation_rate/mlp/2hl_5050hu_10-2alpha_log/' if not in_msg.read_from_netCDF: clf_pd = joblib.load(dir_start_pd+'clf.pkl') scaler_pd = joblib.load(dir_start_pd+'scaler.pkl') feature_list_pd = joblib.load(dir_start_pd+'featurelist.pkl') thres_pd=np.load(dir_start_pd+'opt_orig_posteriorprobab_thres.npy') ######################################### ## load the mlp for the rain rates (rr) # ######################################### reg_rr = joblib.load(dir_start_rr+'reg.pkl') scaler_rr = joblib.load(dir_start_rr+'scaler.pkl') feature_list_rr = joblib.load(dir_start_rr+'featurelist.pkl') #################################### ## load the reference sets for a climatological probab matching (pm) if requested #################################### if in_msg.probab_match: # load in the ref data sets created with the script: rr_probab_matching_create_refset.ipynb ody_rr_ref=np.load(dir_start_rr+'pm_valid_data_ody_rr_ref.npy') pred_rr_ref=np.load(dir_start_rr+'pm_valid_data_pred_rr_ref.npy') # initialize processed RGBs plots_done={} time_slot = copy.deepcopy(in_msg.datetime) while time_slot <= in_msg.end_date: print('... processing for time: ', time_slot) ################################################ ## CHOOSE THE SETUP (time_slot, area, model) ################################################ ########################## ## LOAD THE NEEDED INPUTS ########################## if not in_msg.read_from_netCDF: ## read observations at the specific time print('=================================') print('*** load the time slot specific fields with in_msg.parallax_gapfilling:', in_msg.parallax_gapfilling) global_radar, global_sat, global_nwc, global_cth, global_hsaf = load_input(sat_nr, time_slot, in_msg.parallax_gapfilling, read_HSAF=in_msg.read_HSAF) # def load_input(sat_nr, time_slot, par_fill, read_HSAF=True): else: print('read Odyssey radar composite') from mpop.satellites import GeostationaryFactory global_radar = GeostationaryFactory.create_scene("odyssey", "", "radar", time_slot) global_radar.load(['RATE']) print(global_radar) print('=========================') for area in in_msg.areas: print ("================================") print ("*** PROCESSING FOR AREA: "+area) # declare "precipitation detection" and "rainrate dictionary", the applied model (e.g. MLP) is used as key pd = {} rr = {} plots_done[area]=[] if in_msg.read_from_netCDF: # reproject Odyssey radar mask to area of interest #radar_mask = global_radar_mask.project(area, precompute=True) data_radar = global_radar.project(area, precompute=True) # radar mask to see where odyssey ground truth exists mask_r = data_radar['RATE-MASK'].data.data==False rr['ody'] = copy.deepcopy(data_radar['RATE'].data.data) # do not trust values below 0.3 & above 130 -> do not consider it as rain and set all values to 0 rr['ody'][np.logical_or(rr['ody'] < 0.3,rr['ody'] >= 130.0)] = 0.0 print (rr['ody'].min(), rr['ody'].max(), rr['ody'].shape, type(rr['ody'])) from netCDF4 import Dataset # read from file outdir_netCDF = time_slot.strftime('/data/COALITION2/database/meteosat/nostradamus_RR/%Y/%m/%d/') file_netCDF = time_slot.strftime('MSG_rr-'+in_msg.model+'-'+area+'_%Y%m%d%H%M.nc') print ("*** read precip prediction from", outdir_netCDF+"/"+file_netCDF) ncfile = Dataset(outdir_netCDF+"/"+file_netCDF,'r') rr_tmp = ncfile.variables['rainfall_rate'][:,:] ### now, we read radar data directly from odyssey file #rr['ody'] = ncfile.variables['rainfall_rate (odyssey)'][:,:] #print (rr['ody'].min(), rr['ody'].max(), rr['ody'].shape, type(rr['ody'])) ### now, we read radar mask directly from odyssey file #mask_r = ncfile.variables['odyssey_mask'][:,:] #print ("... convert mask_r (1, 0) from int to bolean (True, False)") #mask_r = (mask_r == 1) # create fake mask_h (where rainfall is larger than 0 mm/h) mask_h = rr_tmp>0 pd[in_msg.model] = rr_tmp>0 rr_tmp = rr_tmp.flatten() # remove 0 entries rr_tmp = rr_tmp [ rr_tmp != 0 ] if False: import matplotlib.pyplot as plt #fig = plt.figure() fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(6,6)) plt.subplot(2, 1, 1) plt.imshow(mask_h) #plt.colorbar() plt.subplot(2, 1, 2) plt.imshow(mask_r) #plt.colorbar() fig.savefig("mask_h_mask_r_netCDF.png") print("... display mask_h_mask_r_netCDF.png &") #plt.show() #quit() else: ## project all data to the desired projection radar_mask, vg, ls_ele, data_radar, data_sat, data_nwc, data_cth, data_hsaf = \ project_data(area, global_radar_mask, global_vg, global_ls_ele, global_radar, global_sat, global_nwc, global_cth, global_hsaf, read_HSAF=in_msg.read_HSAF) ########################################################### ## SINGLE TIME SLOT TO CARRY OUT A FULL RAIN RATE RETRIEVAL ########################################################### # preprocess the data # mask_h: field indicating where NWCSAF products are available & thus where predictions are carried out: True if NWCSAF products available # mask_r: field indicating where radar products are available: True if radar product is available # mask_rnt: field indicating where radar product available but not trustworthy: i.e. in threshold_mask, 0<rr<0.3, rr>130 overlaid: True if radar product is NOT trustworthy all_data, all_data_names, mask_h, mask_r, mask_rnt, rr['ody'], rr['hsaf'], lon, lat = \ pd_rr_preprocess_data_single_scene( area, time_slot, radar_mask, vg, ls_ele, data_radar, data_sat, data_nwc, data_cth, data_hsaf, in_msg.parallax_gapfilling, 'rr', read_HSAF=in_msg.read_HSAF) #pd_rr_preprocess_data_single_scene( sat_nr, area, time_slot, 'nearest', 'rr', read_HSAF=False) if False: import matplotlib.pyplot as plt #fig = plt.figure() fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(6,6)) plt.subplot(2, 1, 1) plt.imshow(mask_h) #plt.colorbar() plt.subplot(2, 1, 2) plt.imshow(mask_r) #plt.colorbar() fig.savefig("mask_h_mask_r.png") print("... display mask_h_mask_r.png &") #plt.show() #quit() del rr['hsaf'] # since not actually needed in this script # project all data to desired projection # ... print('... predictions at ' + str(mask_h.sum())+' out of ' +str(mask_h.flatten().shape[0])+ ' points') #################################### ## precip detection #################################### # create y_pd, y_hsaf_pd, X_raw_pd y_pd_vec, y_hsaf_pd_vec, X_raw, feature_list = pd_rr_create_y_yhsaf_Xraw( all_data, all_data_names, 'pd', cut_precip=False ) del y_pd_vec, y_hsaf_pd_vec # (since not actually ever needed in this script) if in_msg.remove_vg==True: print('... remove viewing geometry from predictors') feature_list = np.append(feature_list[:6],feature_list[8:]) X_raw = np.hstack([X_raw[:,:6],X_raw[:,8:]]) print(' new X_raw.shape:', X_raw.shape) feature_list # check features if np.array_equal(feature_list, feature_list_pd): print('OK, input features correspond to input features required by the loaded model') else: print('ATTENTION, input features do not correspond to input features required by the loaded model') quit() # create X_pd X_pd=scaler_pd.transform(X_raw) # create final precip detection fields: opera + hsaf pd['ody']=rr['ody']>=0.3 # make precip detection predictions print ("*** make precip detection predictions") pd_probab = clf_pd.predict_proba(X_pd)[:,1] # probab precip balanced classes pd_vec_h = pd_probab>=thres_pd pd[in_msg.model] = np.zeros(lon.shape,dtype=bool) pd[in_msg.model][mask_h] = pd_vec_h #################################### ## rain rate on above identified precipitating pixels #################################### # reduce X_raw to the points where rain was predicted by the mlp X_raw= X_raw[pd_vec_h,:] # check, if read features correspond to the trained model if np.array_equal(feature_list, feature_list_rr): print('OK, input features correspond to input features required by the loaded model') else: print('ATTENTION, input features do not correspond to input features required by the loaded model') quit() # create X_rr X_rr=scaler_rr.transform(X_raw) # rain rate prediction at places where precip detected by mlp rr_tmp=reg_rr.predict(X_rr) # carry out a probability machting if requested if in_msg.probab_match: print("... do probability matching for:", in_msg.model) pm_str = str(in_msg.model)+'_pm' rr_tmp_pm = probab_match_rr_refprovide(ody_rr_ref,pred_rr_ref,rr_tmp) #rr[pm_str] = np.zeros_like(lon) rr[pm_str] = np.zeros_like(rr['ody']) # also casts the type float rr[pm_str][pd[in_msg.model]]=rr_tmp_pm print("... probability matching done for:", in_msg.model) # copy rainrate data to the final place # replace all prediction lower than precipitation detection threshold with threhold rain rate rr_tmp[rr_tmp<0.3]=0.3 # correct upward all too low predictions (i.e. the ones below the precip detection threshold) rr[in_msg.model] = np.zeros_like(rr['ody']) rr[in_msg.model][pd[in_msg.model]]=rr_tmp ##################################### ## SAVE RESULT AS NETCDF ##################################### if area in in_msg.save_netCDF and (not in_msg.read_from_netCDF): outdir_netCDF = time_slot.strftime(in_msg.outdir_netCDF) file_netCDF = time_slot.strftime(in_msg.file_netCDF) file_netCDF = file_netCDF.replace("%(area)s", area) file_netCDF = file_netCDF.replace("%(model)s", in_msg.model) #save_RR_as_netCDF(outdir_netCDF, file_netCDF, rr[in_msg.model], save_rr_ody=True, rr_ody=rr['ody'], save_ody_mask=True, ody_mask=mask_r, zlib=True) save_RR_as_netCDF(outdir_netCDF, file_netCDF, rr[in_msg.model]) ##################################### ## SINGLE TIME SLOT TO DRAW THE MAPS ##################################### print ("*** start to create plots") #################################### ## plot precip detection #################################### if 'pdMlp' in in_msg.plots[area]: mask_rt = np.logical_and(mask_r, mask_rnt==False) # trusted radar i.e. True where I have a trustworthy radar product available mod_ss = [in_msg.model] + ['ody'] # ver for verification; ver={} for x in mod_ss: ver[x]=np.zeros_like(lon) # sat: no ver[x][pd[x]>0] = 1 # sat: yes ver[x][np.logical_and(ver[x]==0,mask_rnt)] = 2 # sat: no (rad clutter) ver[x][np.logical_and(ver[x]==1,mask_rnt)] = 3 # sat: yes (rad clutter) ver[x][np.logical_and(mask_rt,np.logical_and(pd[x]==1,pd['ody']==1))] = 4 # hit ver[x][np.logical_and(mask_rt,np.logical_and(pd[x]==1,pd['ody']==0))] = 5 # false alarm ver[x][np.logical_and(mask_rt,np.logical_and(pd[x]==0,pd['ody']==0))] = 6 # correct reject ver[x][np.logical_and(mask_rt,np.logical_and(pd[x]==0,pd['ody']==1))] = 7 # miss # define colorkey v_pd=np.array([-0.5,0.5,1.5,2.5,3.5,4.5,5.5,6.5,7.5]) cmap_pd, norm_pd = from_levels_and_colors(v_pd, colors =['darkgrey', '#984ea3','lightgrey','plum', '#377eb8', '#e41a1c','ivory','#ff7f00'], extend='neither') plot_precipitation_detection=False if plot_precipitation_detection: # single prediction plot #fig,ax= plt.subplots(figsize=(20, 10)) #plt.rcParams.update({'font.size': 16}) fig,ax= plt.subplots(figsize=(10, 5)) plt.rcParams.update({'font.size': 8}) plt.rcParams.update({'mathtext.default':'regular'}) m = map_plot(axis=ax,area=area) m.ax.set_title('precip detection based on sat vs opera') # plot sat precip detection product against opera product tick_label_pd_nr=np.array([0,1,2,3,4,5,6,7]) tick_label_pd=['sat: no','sat: yes','sat: no (rad unr)','sat: yes (rad unr)','hit','false alarm','correct reject','miss'] im=m.pcolormesh( lon, lat, ver['mlp'], cmap=cmap_pd, norm=norm_pd, latlon=True ) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="4%", pad=0.05) cbar = fig.colorbar(im, cax=cax, ticks=tick_label_pd_nr, spacing='uniform') a=cbar.ax.set_yticklabels(tick_label_pd) outfile= 'precip_detection_sat'+in_msg.model+'_vs_opera_%s' fig.savefig((in_msg.outputDir+outfile %time_slot.strftime('%Y%m%d%H%M')), dpi=300, bbox_inches='tight') print('... create figure: display ' + in_msg.outputDir+outfile %time_slot.strftime('%Y%m%d%H%M') + '.png') plots_done[area].append('pdMlp') #################################### ## plot rain rate with matplotlib #################################### if 'rrMatplotlib' in in_msg.plots[area]: # create the combi rr field rr['combi']=copy.deepcopy(rr[in_msg.model+'_pm']) rr['combi'][mask_r]=rr['ody'][mask_r] # determine where I have >0.3 mm/h precip on the permanent mask -> overlay end picture with a pink(?) color there pd_nt=np.logical_and(mask_rnt,pd['ody']>=0.3) #precip detected but not trusted t = time.time() #fig, axes = plt.subplots(1, 2,figsize=(19, 6)) #plt.rcParams.update({'font.size': 16}) fig, axes = plt.subplots(1, 2,figsize=(9.5, 3)) plt.rcParams.update({'font.size': 8}) plt.rcParams.update({'mathtext.default':'regular'}) ## 1st subplot m = map_plot(axis=axes[0],area=area) m.ax.set_title('Rain Rate (opera + MSG ANN), '+str(time_slot)) # plot a white colored background where I have data available v_pd_nt=np.array([0.5,1.5]) cmap_pd_nt, norm_pd_nt = from_levels_and_colors(v_pd_nt, colors=['white'], extend='neither') im4=m.pcolormesh(lon,lat,np.ones(lon.shape),cmap=cmap_pd_nt,norm=norm_pd_nt,latlon=True) # plot mask which contains no rad & not trusted rad values nr_ntr = copy.deepcopy(ver['ody']) nr_ntr=np.ma.masked_greater(nr_ntr,2) nr_ntr=np.ma.masked_equal(nr_ntr,1) im2=m.pcolormesh(lon,lat,nr_ntr,cmap=cmap_pd,norm=norm_pd,latlon=True) # plot combined precip opera + sat v_rr = [0.3,0.6,1.2,2.4,4.8,9.6] cmap_rr,norm_rr=smart_colormap(v_rr,name='coolwarm',extend='max') im=m.pcolormesh(lon,lat,rr['combi'],cmap=cmap_rr,norm=norm_rr,latlon=True) # plot pink pixels everywhere on permanently not trusted radar mask where we observe > 0.3 mm/h precip v_pd_nt=np.array([0.5,1.5]) cmap_pd_nt, norm_pd_nt = from_levels_and_colors(v_pd_nt, colors=['plum'], extend='neither') im3=m.pcolormesh(lon,lat,pd_nt,cmap=cmap_pd_nt,norm=norm_pd_nt,latlon=True) ## 2nd subplot # plot purely satellite based precip product m = map_plot(axis=axes[1],area=area) m.ax.set_title('Rain Rate (MSG ANN), '+str(time_slot)) if in_msg.IR_108 and not in_msg.read_from_netCDF: # plot the IR_108 channel clevs = np.arange(225,316,10) cmap_sat,norm_sat=smart_colormap(clevs,name='Greys',extend='both') im4 = m.pcolormesh(lon,lat,data_sat['IR_108_PC'].data,cmap=cmap_sat,norm=norm_sat,latlon=True) else: # plot a white surface to distinguish between the regions where the produ v_pd_nt=np.array([0.5,1.5]) cmap_pd_nt, norm_pd_nt = from_levels_and_colors(v_pd_nt, colors=['white'], extend='neither') im4=m.pcolormesh(lon,lat,np.ones(lon.shape),cmap=cmap_pd_nt,norm=norm_pd_nt,latlon=True) if in_msg.probab_match: im=m.pcolormesh(lon, lat,rr[in_msg.model+'_pm'], cmap=cmap_rr, norm=norm_rr, latlon=True) else: im=m.pcolormesh(lon, lat,rr[in_msg.model], cmap=cmap_rr, norm=norm_rr, latlon=True) if in_msg.IR_108 and in_msg.probab_match: outfile= 'rr_combioperasat'+in_msg.model+'pm_satIR108'+in_msg.model+'pm_%s' elif in_msg.IR_108 and (in_msg.probab_match==False): outfile= 'rr_combioperasat'+in_msg.model+'_satIR108'+in_msg.model+'_%s' elif (in_msg.IR_108==False) and in_msg.probab_match: outfile= 'rr_combioperasat'+in_msg.model+'pm_sat'+in_msg.model+'pm_%s' elif (in_msg.IR_108==False) and (in_msg.probab_match==False): outfile= 'rr_combioperasat'+in_msg.model+'_sat'+in_msg.model+'_%s' fig.subplots_adjust(bottom=0.15) cbar_ax = fig.add_axes([0.25, 0.05, 0.5, 0.05]) cbar=fig.colorbar(im, cax=cbar_ax, orientation='horizontal') cbar.set_label('$mm\,h^{-1}$') fig.savefig((in_msg.outputDir+outfile %time_slot.strftime('%Y%m%d%H%M')), dpi=300, bbox_inches='tight') print('... create figure: display ' + in_msg.outputDir+outfile %time_slot.strftime('%Y%m%d%H%M') + '.png') elapsed = time.time() - t print("... elapsed time for creating the rainrate image in seconds: "+str(elapsed)) plots_done[area].append('rrMatplotlib') #################################### ## plot rain rate with trollimage #################################### plot_trollimage=True if plot_trollimage: from plotting_tools import create_trollimage from plot_msg import add_title print ("*** create plot with trollimage") from copy import deepcopy from trollimage.colormap import RainRate colormap = deepcopy(RainRate) # define contour write for coasts, borders, rivers from pycoast import ContourWriterAGG cw = ContourWriterAGG(in_msg.mapDir) from plot_msg import choose_map_resolution resolution = choose_map_resolution(area, None) #resolution='l' # odyssey, europe #resolution='i' # ccs4 print (" resolution=", resolution) IR_file=time_slot.strftime(in_msg.outputDir+'MSG_IR-108-'+area+'_%Y%m%d%H%M.png') if 'IR_108' in in_msg.plots[area] and not in_msg.read_from_netCDF: # create black white background #img_IR_108 = data_sat.image.channel_image('IR_108_PC') img_IR_108 = data_sat.image.ir108() img_IR_108.save(IR_file) for rgb in in_msg.plots[area]: if rgb == 'RATE': prop = np.ma.masked_equal(rr['ody'], 0) mask2plot=deepcopy(mask_r) elif rgb =='rrMlp': prop = np.ma.masked_equal(rr[in_msg.model], 0) mask2plot=None elif rgb == 'rrMlpPm': prop = np.ma.masked_equal(rr[in_msg.model+'_pm'], 0) mask2plot=None elif rgb == 'rrOdyMlp': rr['combi']=copy.deepcopy(rr[in_msg.model]) rr['combi'][mask_r]=rr['ody'][mask_r] prop = np.ma.masked_equal(rr['combi'], 0) mask2plot=deepcopy(mask_r) elif rgb == 'rrOdyMlpPm': rr['combi']=copy.deepcopy(rr[in_msg.model+'_pm']) rr['combi'][mask_r] = rr['ody'][mask_r] prop = np.ma.masked_equal(rr['combi'], 0) mask2plot=deepcopy(mask_r) elif rgb == 'IR_108': continue else: "*** Error, unknown product requested" quit() filename = None if area in in_msg.postprocessing_composite: composite_file = in_msg.outputDir+"/"+'MSG_'+in_msg.postprocessing_composite[area][0]+"-"+area+'_%Y%m%d%H%M.png' composite_file = composite_file.replace("%(rgb)s", rgb) else: composite_file = None PIL_image = create_trollimage(rgb, prop, colormap, cw, filename, time_slot, area, composite_file=composite_file, background=IR_file, mask=mask2plot, resolution=resolution, scpOutput=in_msg.scpOutput) # add title to image dc = DecoratorAGG(PIL_image) if in_msg.add_title: add_title(PIL_image, in_msg.title, rgb, 'MSG', sat_nr, in_msg.datetime, area, dc, in_msg.font_file, True, title_color=in_msg.title_color, title_y_line_nr=in_msg.title_y_line_nr ) # !!! needs change # save image as file outfile = time_slot.strftime(in_msg.outputDir+"/"+in_msg.outputFile).replace("%(rgb)s", rgb).replace("%(area)s", area).replace("%(model)s", in_msg.model) PIL_image.save(outfile, optimize=True) if isfile(outfile): print ("... create figure: display "+outfile+" &") chmod(outfile, 0777) plots_done[area].append(rgb) else: print ("*** Error: "+outfile+" could not be generated") quit() print('=================================') ############################################## ## potential other map setups ############################################## ############################################## ############################################## ## opera composite vs the prediction... but I think it'd be less confusing to only show the prediction ############################################## if 'OdyVsRr' in in_msg.plots[area]: fig, axes = plt.subplots(1, 2,figsize=(23.5, 5)) # will be switched to basemap once have new training set together plt.rcParams.update({'font.size': 16}) plt.rcParams.update({'mathtext.default':'regular'}) # set up nn subplot m = map_plot(axis=axes[0],area=area) m.ax.set_title('precip detection based on mlp vs opera') v_pd=np.array([-0.5,0.5,1.5,2.5,3.5,4.5,5.5,6.5,7.5]) cmap_pd, norm_pd = from_levels_and_colors(v_pd, colors=['darkgrey', '#984ea3','lightgrey','plum', '#377eb8', '#e41a1c','ivory','#ff7f00'], extend='neither') tick_label_pd_nr=np.array([0,1,2,3,4,5,6,7]) tick_label_pd=['sat: no','sat: yes','sat: no (rad unr)','sat: yes (rad unr)','hit','false alarm','correct reject','miss'] im=m.pcolormesh(lon,lat,ver['mlp'],cmap=cmap_pd, norm=norm_pd, latlon=True) divider = make_axes_locatable(m.ax) cax = divider.append_axes("right", size="4%", pad=0.05) cbar = fig.colorbar(im,cax=cax, ticks=tick_label_pd_nr, spacing='uniform') cbar.ax.set_yticklabels(tick_label_pd, fontsize=14) m = map_plot(axis=axes[1],area=area) m.ax.set_title('precip detection based on opera vs opera') v_pd=np.array([-0.5,0.5,2.5,3.5,4.5,6.5]) cmap_pd, norm_pd = from_levels_and_colors(v_pd, colors=['darkgrey','lightgrey','plum', '#377eb8','ivory'], extend='neither') tick_label_pd_nr=np.array([0,1.5,3,4,5.5]) tick_label_pd=['no rad','rad clutter: no','rad clutter: yes','rad: yes','rad: no'] im=m.pcolormesh(lon,lat,ver['ody'],cmap=cmap_pd,norm=norm_pd,latlon=True) divider = make_axes_locatable(m.ax) cax = divider.append_axes("right", size="4%", pad=0.05) cbar = fig.colorbar(im,cax=cax,ticks=tick_label_pd_nr,spacing='uniform') a=cbar.ax.set_yticklabels(tick_label_pd,fontsize=14) outfile= 'test_%s' fig.savefig((in_msg.outputDir+ outfile %time_slot.strftime('%Y%m%d%H%M')), dpi=300, bbox_inches='tight') print('... create figure: display ' + in_msg.outputDir+outfile %time_slot.strftime('%Y%m%d%H%M') + '.png') plots_done[area].append('OdyVsRr') ############################################## ## cth visualisation without parallax corr for a test ############################################## if 'CTH' in in_msg.plots[area]: fig, axes = plt.subplots(1, 1,figsize=(5, 3)) plt.rcParams.update({'font.size': 16}) plt.rcParams.update({'mathtext.default':'regular'}) ## 1st subplot m = map_plot(axis=axes,area=area) m.ax.set_title('CTH (without parallax corr)') v_rr = np.arange(6000,12001,1000) cmap_rr,norm_rr=smart_colormap(v_rr,name='coolwarm',extend='neither') im4 = m.pcolormesh(lon,lat,data_cth['CTTH'].height,cmap=cmap_rr,norm=norm_rr,latlon=True) fig.colorbar(im4) data_cth['CTTH'].height outfile= 'CTH_without_parallax_%s' fig.savefig((in_msg.outputDir+ outfile %time_slot.strftime('%Y%m%d%H%M')), dpi=300, bbox_inches='tight') print('... create figure: display ' + in_msg.outputDir+outfile %time_slot.strftime('%Y%m%d%H%M') + '.png') plots_done[area].append('CTH') # end of area loop ## start postprocessing for area in in_msg.postprocessing_areas: postprocessing(in_msg, time_slot, int(sat_nr), area) # increase the time by a time delta time_slot += delta # end of time loop return plots_done
from PIL import Image from pydecorate import DecoratorAGG import aggdraw font=aggdraw.Font("navy","/usr/share/fonts/truetype/ttf-dejavu/DejaVuSerif.ttf",size=20) font_scale=aggdraw.Font("black","/usr/share/fonts/truetype/ttf-dejavu/DejaVuSerif.ttf",size=12) from trollimage.colormap import rdbu rdbu.colors = rdbu.colors[::-1] rdbu.set_range(-90, 10) print type(rdbu) img = Image.open('BMNG_clouds_201109181715_areaT2.png') dc = DecoratorAGG(img) #dc.write_vertically() #dc.add_logo("logos/pytroll_light_big.png") #dc.add_logo("logos/NASA_Logo.gif",margins=[10,10],bg='yellow') #dc.add_logo("logos/pytroll_light_big.png") font=aggdraw.Font("blue","/usr/share/fonts/truetype/ttf-dejavu/DejaVuSerif.ttf",size=16) #dc.add_text("Some text",font=font) #dc.align_right() print rdbu.values print rdbu.colors dc.add_scale(rdbu, extend=True, tick_marks=5.0, line_opacity=100, unit='K')
def show_swath_pycoast(self, start, period=None): """ A helper method that displays the orbital swath starting at datetime start, for a period number of minutes. If, start is iterable, then the method assumes it is an iterable of datetimes, plotting a number of swaths at those times. """ # test if start is iterable, EAFP style: try: for e in start: pass except TypeError: start = [start] start.sort() from PIL import Image from pycoast import ContourWriterAGG from pydecorate import DecoratorAGG img = Image.new('RGB', (650, 650)) proj4_string = "" for x in self.working_projection: proj4_string += "+%s=%s " % (x, self.working_projection[x]) area_extent = (-6700000.0, -6700000.0, 6700000.0, 6700000.0) area_def = (proj4_string, area_extent) cw = ContourWriterAGG() cw.add_grid(img, area_def, (10.0, 10.0), (2.0, 2.0), fill='blue', outline='gray', outline_opacity=130, minor_outline=None, write_text=False) # Plot granules for t in start: # fetch the coordinates xys_segs = self.swath_working_projection(t, period) for xys in xys_segs: lls = self.proj(xys[0], xys[1], inverse=True) cw.add_polygon(img, area_def, zip(lls[0], lls[1]), outline="blue", fill="blue", fill_opacity=70, width=1) cw.add_coastlines(img, area_def, resolution='l') aoi_coords = zip(*self.aoi) ## TODO: Handle single point case properly if len(aoi_coords) == 1: x, y = aoi_coords[0] d = 0.5 line_coords = [(x - d, y), (x + d, y)] cw.add_line(img, area_def, line_coords, outline="red", fill="red", fill_opacity=100, width=2) elif len(aoi_coords) == 2: cw.add_line(img, area_def, aoi_coords, outline="red", fill="red", fill_opacity=100, width=10) else: cw.add_polygon(img, area_def, aoi_coords, outline="red", fill="red", fill_opacity=100, width=2) # Decorate dc = DecoratorAGG(img) text = "Granules from time: %s + %.2f min." % ( start[0].strftime('%Y.%m.%d %H:%M:%S'), (start[-1] - start[0]).total_seconds() / 60.0) dc.align_bottom() dc.add_text(text, height=0) img.show()
# colormap.set_range(min_data, max_data) # no return value! #PIL_image=img.pil_image() if add_borders: add_borders_and_rivers(PIL_image, cw, area_tuple, add_borders=in_msg.add_borders, border_color=in_msg.border_color, add_rivers=in_msg.add_rivers, river_color=in_msg.river_color, resolution=in_msg.resolution, verbose=in_msg.verbose) #if area.find("EuropeCanary") != -1 or area.find("ccs4") != -1: dc = DecoratorAGG(PIL_image) # add title to image if in_msg.add_title: add_title(PIL_image, rgb, int(data.number), dateS, hourS, minS, area, dc, in_msg.font_file, in_msg.verbose) # create output filename outputDir = format_name(in_msg.outputDir, data.time_slot, area=area, rgb=rgb, sat_nr=data.number) outputFile = outputDir + format_name( in_msg.outputFile + 'p' + str(it * delta_t).zfill(2) + '.png', data.time_slot,
import aggdraw font = aggdraw.Font("navy", "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSerif.ttf", size=20) font_scale = aggdraw.Font( "black", "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSerif.ttf", size=12) from trollimage.colormap import rdbu rdbu.colors = rdbu.colors[::-1] rdbu.set_range(-90, 10) print type(rdbu) img = Image.open('BMNG_clouds_201109181715_areaT2.png') dc = DecoratorAGG(img) #dc.write_vertically() #dc.add_logo("logos/pytroll_light_big.png") #dc.add_logo("logos/NASA_Logo.gif",margins=[10,10],bg='yellow') #dc.add_logo("logos/pytroll_light_big.png") font = aggdraw.Font("blue", "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSerif.ttf", size=16) #dc.add_text("Some text",font=font) #dc.align_right() print rdbu.values print rdbu.colors dc.add_scale(rdbu, extend=True, tick_marks=5.0, line_opacity=100, unit='K')
def main(): parser = get_parser() args = parser.parse_args() levels = [logging.ERROR, logging.WARN, logging.INFO, logging.DEBUG] logging.basicConfig(level=levels[min(3, args.verbosity)]) if args.output_filename is None: args.output_filename = [x[:-3] + "png" for x in args.input_tiff] else: assert len(args.output_filename) == len(args.input_tiff), "Output filenames must be equal to number of input tiffs" if not (args.add_borders or args.add_coastlines or args.add_grid or args.add_rivers or args.add_colorbar): LOG.error("Please specify one of the '--add-X' options to modify the image") return -1 # we may be dealing with large images that look like decompression bombs # let's turn off the check for the image size in PIL/Pillow Image.MAX_IMAGE_PIXELS = None for input_tiff, output_filename in zip(args.input_tiff, args.output_filename): LOG.info("Creating {} from {}".format(output_filename, input_tiff)) gtiff = gdal.Open(input_tiff) proj4_str = osr.SpatialReference(gtiff.GetProjection()).ExportToProj4() ul_x, res_x, _, ul_y, _, res_y = gtiff.GetGeoTransform() half_pixel_x = res_x / 2. half_pixel_y = res_y / 2. area_extent = ( ul_x - half_pixel_x, # lower-left X ul_y + res_y * gtiff.RasterYSize - half_pixel_y, # lower-left Y ul_x + res_x * gtiff.RasterXSize + half_pixel_x, # upper-right X ul_y + half_pixel_y, # upper-right Y ) img = Image.open(input_tiff).convert('RGB') area_def = (proj4_str, area_extent) cw = ContourWriterAGG(args.shapes_dir) if args.add_coastlines: outline = args.coastlines_outline[0] if len(args.coastlines_outline) == 1 else tuple(int(x) for x in args.coastlines_outline) if args.coastlines_fill: fill = args.coastlines_fill[0] if len(args.coastlines_fill) == 1 else tuple(int(x) for x in args.coastlines_fill) else: fill = None cw.add_coastlines(img, area_def, resolution=args.coastlines_resolution, level=args.coastlines_level, outline=outline, fill=fill) if args.add_rivers: outline = args.rivers_outline[0] if len(args.rivers_outline) == 1 else tuple(int(x) for x in args.rivers_outline) cw.add_rivers(img, area_def, resolution=args.rivers_resolution, level=args.rivers_level, outline=outline) if args.add_borders: outline = args.borders_outline[0] if len(args.borders_outline) == 1 else tuple(int(x) for x in args.borders_outline) cw.add_borders(img, area_def, resolution=args.borders_resolution, level=args.borders_level, outline=outline) if args.add_grid: outline = args.grid_outline[0] if len(args.grid_outline) == 1 else tuple(int(x) for x in args.grid_outline) minor_outline = args.grid_minor_outline[0] if len(args.grid_minor_outline) == 1 else tuple(int(x) for x in args.grid_minor_outline) fill = args.grid_fill[0] if len(args.grid_fill) == 1 else tuple(int(x) for x in args.grid_fill) font_path = find_font(args.grid_font, args.grid_text_size) font = Font(outline, font_path, size=args.grid_text_size) cw.add_grid(img, area_def, args.grid_D, args.grid_d, font, fill=fill, outline=outline, minor_outline=minor_outline, write_text=args.grid_text, lon_placement=args.grid_lon_placement, lat_placement=args.grid_lat_placement) if args.add_colorbar: from pydecorate import DecoratorAGG font_color = args.colorbar_text_color font_color = font_color[0] if len(font_color) == 1 else tuple(int(x) for x in font_color) font_path = find_font(args.colorbar_font, args.colorbar_text_size) # this actually needs an aggdraw font font = Font(font_color, font_path, size=args.colorbar_text_size) band_count = gtiff.RasterCount if band_count not in [1, 2]: raise ValueError("Can't add colorbar to RGB/RGBA image") # figure out what colormap we are dealing with band = gtiff.GetRasterBand(1) cmap = get_colormap(band, band_count) # figure out our limits vmin = args.colorbar_min vmax = args.colorbar_max metadata = gtiff.GetMetadata_Dict() vmin = vmin or metadata.get('min_in') vmax = vmax or metadata.get('max_in') if isinstance(vmin, str): vmin = float(vmin) if isinstance(vmax, str): vmax = float(vmax) if vmin is None or vmax is None: data = gtiff.GetRasterBand(1).ReadAsArray() vmin = vmin or np.iinfo(data.dtype).min vmax = vmax or np.iinfo(data.dtype).max cmap.set_range(vmin, vmax) dc = DecoratorAGG(img) if args.colorbar_align == 'top': dc.align_top() elif args.colorbar_align == 'bottom': dc.align_bottom() elif args.colorbar_align == 'left': dc.align_left() elif args.colorbar_align == 'right': dc.align_right() if args.colorbar_vertical: dc.write_vertically() else: dc.write_horizontally() if args.colorbar_width is None or args.colorbar_height is None: LOG.warning("'--colorbar-width' or '--colorbar-height' were " "not specified. Forcing '--colorbar-extend'.") args.colorbar_extend = True kwargs = {} if args.colorbar_width: kwargs['width'] = args.colorbar_width if args.colorbar_height: kwargs['height'] = args.colorbar_height dc.add_scale(cmap, extend=args.colorbar_extend, font=font, line=font_color, tick_marks=args.colorbar_tick_marks, title=args.colorbar_title, unit=args.colorbar_units, **kwargs) img.save(output_filename)
def savefig(fname, loc=1, decorate=True, **kwargs): import io import os import sys from PIL import Image import matplotlib.pyplot as plt try: from pydecorate import DecoratorAGG pydecorate = True except ImportError: pydecorate = False plt.savefig(fname, **kwargs) if pydecorate and decorate: img = Image.open(fname) dc = DecoratorAGG(img) if loc == 1: dc.align_bottom() elif loc == 2: dc.align_bottom() dc.align_right() elif loc == 3: dc.align_right() # sys.argv[0])[-5] + 'data/MONET_logo.png' # print(os.path.basename(__file__)) logo = os.path.abspath(__file__)[:-17] + 'data/MONET-logo.png' # print(logo) dc.add_logo(logo) if fname.split('.')[-1] == 'png': img.save(fname, "PNG") elif fname.split('.')[-1] == 'jpg': img.save(fname, "JPEG")
def main(): parser = get_parser() args = parser.parse_args() levels = [logging.ERROR, logging.WARN, logging.INFO, logging.DEBUG] logging.basicConfig(level=levels[min(3, args.verbosity)]) if args.output_filename is None: args.output_filename = [x[:-3] + "png" for x in args.input_tiff] else: assert len(args.output_filename) == len( args.input_tiff ), "Output filenames must be equal to number of input tiffs" if not (args.add_borders or args.add_coastlines or args.add_grid or args.add_rivers or args.add_colorbar): LOG.error("Please specify one of the '--add-X' options to modify the image") return -1 if args.cache_dir and not os.path.isdir(args.cache_dir): LOG.info(f"Creating cache directory: {args.cache_dir}") os.makedirs(args.cache_dir, exist_ok=True) # we may be dealing with large images that look like decompression bombs # let's turn off the check for the image size in PIL/Pillow Image.MAX_IMAGE_PIXELS = None # gather all options into a single dictionary that we can pass to pycoast pycoast_options = _args_to_pycoast_dict(args) for input_tiff, output_filename in zip(args.input_tiff, args.output_filename): LOG.info("Creating {} from {}".format(output_filename, input_tiff)) img = Image.open(input_tiff) img_bands = img.getbands() num_bands = len(img_bands) # P = palette which we assume to be an RGBA colormap img = img.convert("RGBA" if num_bands in (2, 4) or "P" in img_bands else "RGB") if pycoast_options: area_id = os.path.splitext(input_tiff[0])[0] area_def = get_area_def_from_raster(input_tiff, area_id=area_id) cw = ContourWriterAGG(args.shapes_dir) cw.add_overlay_from_dict(pycoast_options, area_def, background=img) if args.add_colorbar: from pydecorate import DecoratorAGG font_color = args.colorbar_text_color font_color = font_color[0] if len(font_color) == 1 else tuple(int(x) for x in font_color) font_path = find_font(args.colorbar_font, args.colorbar_text_size) # this actually needs an aggdraw font font = Font(font_color, font_path, size=args.colorbar_text_size) if num_bands not in (1, 2): raise ValueError("Can't add colorbar to RGB/RGBA image") # figure out what colormap we are dealing with rio_ds = rasterio.open(input_tiff) input_dtype = np.dtype(rio_ds.meta["dtype"]) rio_ct = _get_rio_colormap(rio_ds, 1) cmap = get_colormap(input_dtype, rio_ct, num_bands) # figure out our limits vmin = args.colorbar_min vmax = args.colorbar_max metadata = rio_ds.tags() vmin = vmin or metadata.get("min_in") vmax = vmax or metadata.get("max_in") if isinstance(vmin, str): vmin = float(vmin) if isinstance(vmax, str): vmax = float(vmax) if vmin is None or vmax is None: vmin = vmin or np.iinfo(input_dtype).min vmax = vmax or np.iinfo(input_dtype).max cmap.set_range(vmin, vmax) dc = DecoratorAGG(img) if args.colorbar_align == "top": dc.align_top() elif args.colorbar_align == "bottom": dc.align_bottom() elif args.colorbar_align == "left": dc.align_left() elif args.colorbar_align == "right": dc.align_right() if args.colorbar_vertical: dc.write_vertically() else: dc.write_horizontally() if args.colorbar_width is None or args.colorbar_height is None: LOG.warning( "'--colorbar-width' or '--colorbar-height' were " "not specified. Forcing '--colorbar-extend'." ) args.colorbar_extend = True kwargs = {} if args.colorbar_width: kwargs["width"] = args.colorbar_width if args.colorbar_height: kwargs["height"] = args.colorbar_height dc.add_scale( cmap, extend=args.colorbar_extend, font=font, line=font_color, tick_marks=args.colorbar_tick_marks, title=args.colorbar_title, unit=args.colorbar_units, **kwargs, ) img.save(output_filename)
colorscale = False black_vel = True PIL_image = TRTimage( global_data.traj_IDs, global_data.TRT, obj_area) # , fill=False, minRank=8, alpha_max=1.0, plot_vel=True #PIL_image = TRTimage( global_data.traj_IDs, global_data.TRT, obj_area, minRank=15.01) # minRank=8, alpha_max=1.0, plot_vel=True #PIL_image = TRTimage( global_data.traj_IDs, global_data.TRT, obj_area, TRTcell_ID="2018080113300129", minRank=3) # minRank=8, alpha_max=1.0, plot_vel=True #PIL_image = TRTimage( global_data.traj_IDs, global_data.TRT, obj_area, TRTcell_ID="2018080721300099", minRank=3) # minRank=8, alpha_max=1.0, plot_vel=True #PIL_image = TRTimage( global_data.traj_IDs, global_data.TRT, obj_area, TRTcell_ID="2018080710200036", minRank=-1, plot_nowcast=True, fill=True, Rank_predicted=Rank_predicted) # minRank=3, minRank=8, alpha_max=1.0, plot_vel=True #PIL_image = TRTimage( global_data.traj_IDs, global_data.TRT, obj_area, fill=False) # minRank=8, alpha_max=1.0, plot_vel=True #PIL_image = TRTimage( global_data.traj_IDs, global_data.TRT, obj_area, plot_nowcast=True) # minRank=8, alpha_max=1.0, plot_vel=True # create decorator dc = DecoratorAGG(PIL_image) draw = ImageDraw.Draw(PIL_image) if colorscale: print('... add colorscale ranging from min_data (', min_data, ') to max_data (', max_data, ')') dc.align_right() dc.write_vertically() font_scale = aggdraw.Font( "black", "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSerif-Bold.ttf", size=16) colormap_r.set_range(min_data, max_data) dc.add_scale(colormap_r, extend=True, tick_marks=tick_marks,
#print colorscale[1:,4], type(colorscale[0,:]) #print colorscale[1:,1:4] else: print("*** ERROR, unknown color mode") print('... use trollimage to ', method,' plot data (min,max)=',min_data, max_data) if 'fill_value' in locals(): img = trollimage(prop, mode="L", fill_value=fill_value) else: img = trollimage(prop, mode="L") img.colorize(colormap) PIL_image=img.pil_image() dc = DecoratorAGG(PIL_image) # define contour write for coasts, borders, rivers cw = ContourWriterAGG('/data/OWARNA/hau/maps_pytroll/') resolution='l' if area.find("EuropeCanary") != -1: resolution='l' if area.find("ccs4") != -1: resolution='i' if area.find("ticino") != -1: resolution='h' # define area print('obj_area ', obj_area) proj4_string = obj_area.proj4_string
if prop_str == 'ACRR': min_data = 0 max_data = 250 lower_value = 0.15 if lower_value > -1000: prop[prop < lower_value] = np.ma.masked LOG.debug("min_data/max_data: " + str(min_data) + " / " + str(max_data)) colormap.set_range(min_data, max_data) img = trollimage(prop, mode="L", fill_value=fill_value) img.colorize(colormap) PIL_image = img.pil_image() dc = DecoratorAGG(PIL_image) resolution = 'l' if False: cw = ContourWriterAGG('/data/OWARNA/hau/pytroll/shapes/') cw.add_coastlines(PIL_image, area_def, outline='white', resolution=resolution, outline_opacity=127, width=1, level=2) #, outline_opacity=0 outline = (255, 0, 0) outline = 'red'
def plot_msg(in_msg): # get date of the last SEVIRI observation if in_msg.datetime == None: in_msg.get_last_SEVIRI_date() yearS = str(in_msg.datetime.year) #yearS = yearS[2:] monthS = "%02d" % in_msg.datetime.month dayS = "%02d" % in_msg.datetime.day hourS = "%02d" % in_msg.datetime.hour minS = "%02d" % in_msg.datetime.minute dateS=yearS+'-'+monthS+'-'+dayS timeS=hourS+'-'+minS if in_msg.sat_nr==None: in_msg.sat_nr=choose_msg(in_msg.datetime,in_msg.RSS) if in_msg.datetime.year > 2012: if in_msg.sat_nr == 8: area_loaded = get_area_def("EuropeCanary35") elif in_msg.sat_nr == 9: # rapid scan service satellite area_loaded = get_area_def("EuropeCanary95") elif in_msg.sat_nr == 10: # default satellite area_loaded = get_area_def("met09globeFull") # full disk service, like EUMETSATs NWC-SAF products elif in_msg.sat_nr == 0: # fake satellite for reprojected ccs4 data in netCDF area_loaded = get_area_def("ccs4") # #area_loaded = get_area_def("EuropeCanary") #area_loaded = get_area_def("alps") # new projection of SAM else: print("*** Error, unknown satellite number ", in_msg.sat_nr) area_loaded = get_area_def("hsaf") # else: if in_msg.sat_nr == 8: area_loaded = get_area_def("EuropeCanary95") elif in_msg.sat_nr == 9: # default satellite area_loaded = get_area_def("EuropeCanary") # define contour write for coasts, borders, rivers cw = ContourWriterAGG(in_msg.mapDir) if type(in_msg.sat_nr) is int: sat_nr_str = str(in_msg.sat_nr).zfill(2) elif type(in_msg.sat_nr) is str: sat_nr_str = in_msg.sat_nr else: print("*** Waring, unknown type of sat_nr", type(in_msg.sat_nr)) sat_nr_str = in_msg.sat_nr if in_msg.verbose: print('*** Create plots for ') print(' Satellite/Sensor: '+in_msg.sat + ' ' + sat_nr_str) print(' Date/Time: '+dateS +' '+hourS+':'+minS+'UTC') print(' RGBs: ', in_msg.RGBs) print(' Area: ', in_msg.areas) # check if input data is complete if in_msg.verbose: print("*** check input data") RGBs = check_input(in_msg, in_msg.sat+sat_nr_str, in_msg.datetime) if len(RGBs) != len(in_msg.RGBs): print("*** Warning, input not complete.") print("*** Warning, process only: ", RGBs) # define satellite data object global_data = GeostationaryFactory.create_scene(in_msg.sat, sat_nr_str, "seviri", in_msg.datetime) # print "type(global_data) ", type(global_data) # <class 'mpop.scene.SatelliteInstrumentScene'> # print "dir(global_data)", dir(global_data) [..., '__init__', ... 'area', 'area_def', 'area_id', 'channel_list', 'channels', # 'channels_to_load', 'check_channels', 'fullname', 'get_area', 'image', 'info', 'instrument_name', 'lat', 'load', 'loaded_channels', # 'lon', 'number', 'orbit', 'project', 'remove_attribute', 'satname', 'save', 'set_area', 'time_slot', 'unload', 'variant'] ## define satellite data object one scan before #if in_msg.RSS: # scan_time = 5 # min #else: # scan_time = 15 # min scan_time = 15 # min datetime_m1 = in_msg.datetime - timedelta(minutes=scan_time) global_data_m1 = GeostationaryFactory.create_scene(in_msg.sat, sat_nr_str, "seviri", datetime_m1) if len(RGBs) == 0: return RGBs if in_msg.verbose: print("*** load satellite channels for "+in_msg.sat+sat_nr_str+" ", global_data.fullname) # initialize processed RGBs RGBs_done=[] # load reflectivities, brightness temperatures, NWC-SAF products ... print("*** read ", str(in_msg.datetime)) area_loaded = load_products(global_data, RGBs, in_msg, area_loaded) #print "*** read ", str(datetime_m1) #area_loaded = load_products(global_data_m1, RGBs, in_msg, area_loaded) # check if all prerequisites are loaded #rgb_complete = [] #for rgb in RGBs: # all_loaded = True # if rgb in products.RGBs_buildin or rgb in products.RGB_user: # obj_image = get_image(global_data, rgb) # for pre in obj_image.prerequisites: # if pre not in loaded_channels: # all_loaded = False # elif rgb in products.MSG_color: # if rgb.replace("c","") not in loaded_channels: # all_loaded = False # else: # if rgb not in loaded_channels: # all_loaded = False # if all_loaded: # rgb_complete.append(rgb) #print "rgb_complete", rgb_complete # preprojecting the data to another area # -------------------------------------- for area in in_msg.areas: print("") obj_area = get_area_def(area) # reproject data to new area if obj_area == area_loaded: if in_msg.verbose: print("*** Use data for the area loaded: ", area) #obj_area = area_loaded data = global_data data_m1 = global_data_m1 resolution='l' else: if in_msg.verbose: print("*** Reproject data to area: ", area, "(org projection: ", area_loaded.name, ")") obj_area = get_area_def(area) # PROJECT data to new area data = global_data.project(area, precompute=True) data_m1 = global_data_m1.project(area, precompute=True) resolution='i' loaded_products = [chn.name for chn in data.loaded_channels()] print(loaded_products) #loaded_products_m1 = [chn.name for chn in data_m1.loaded_channels()] #print loaded_products_m1 #for prod in loaded_products: # print "xxx ", prod # print data_m1[prod] # data[prod] = data[prod] - data_m1[prod] # # save reprojected data if area in in_msg.save_reprojected_data: save_reprojected_data(data, area, in_msg) # apply a mask to the data (switched off at the moment) if False: mask_data(data, area) # save average values if in_msg.save_statistics: mean_array = zeros(len(RGBs)) #statisticFile = '/data/COALITION2/database/meteosat/ccs4/'+yearS+'/'+monthS+'/'+dayS+'/MSG_'+area+'_'+yearS[2:]+monthS+dayS+'.txt' statisticFile = './'+yearS+'-'+monthS+'-'+dayS+'/MSG_'+area+'_'+yearS[2:]+monthS+dayS+'.txt' if in_msg.verbose: print("*** write statistics (average values) to "+statisticFile) f1 = open(statisticFile,'a') # mode append i_rgb=0 for rgb in RGBs: if rgb in products.MSG_color: mean_array[i_rgb]=data[rgb.replace("c","")].data.mean() i_rgb=i_rgb+1 # create string to write str2write = dateS +' '+hourS+' : '+minS+' UTC ' for mm in mean_array: str2write = str2write+' '+ "%7.2f" % mm str2write = str2write+"\n" f1.write(str2write) f1.close() # creating plots/images if in_msg.make_plots: # choose map resolution resolution = choose_map_resolution(area, in_msg.mapResolution) # define area proj4_string = obj_area.proj4_string # e.g. proj4_string = '+proj=geos +lon_0=0.0 +a=6378169.00 +b=6356583.80 +h=35785831.0' area_extent = obj_area.area_extent # e.g. area_extent = (-5570248.4773392612, -5567248.074173444, 5567248.074173444, 5570248.4773392612) area_tuple = (proj4_string, area_extent) for rgb in RGBs: PIL_image = create_PIL_image(rgb, data, in_msg) # !!! in_msg.colorbar[rgb] is initialized inside (give attention to rgbs) !!! if in_msg.add_rivers: if in_msg.verbose: print(" add rivers to image (resolution="+resolution+")") cw.add_rivers(PIL_image, area_tuple, outline='blue', resolution=resolution, outline_opacity=127, width=0.5, level=5) # if in_msg.verbose: print(" add lakes to image (resolution="+resolution+")") cw.add_coastlines(PIL_image, area_tuple, outline='blue', resolution=resolution, outline_opacity=127, width=0.5, level=2) #, outline_opacity=0 if in_msg.add_borders: if in_msg.verbose: print(" add coastlines to image (resolution="+resolution+")") cw.add_coastlines(PIL_image, area_tuple, outline=(255, 0, 0), resolution=resolution, width=1) #, outline_opacity=0 if in_msg.verbose: print(" add borders to image (resolution="+resolution+")") cw.add_borders(PIL_image, area_tuple, outline=(255, 0, 0), resolution=resolution, width=1) #, outline_opacity=0 #if area.find("EuropeCanary") != -1 or area.find("ccs4") != -1: dc = DecoratorAGG(PIL_image) # add title to image if in_msg.add_title: add_title(PIL_image, rgb, int(data.number), dateS, hourS, minS, area, dc, in_msg.font_file, in_msg.verbose ) # add MeteoSwiss and Pytroll logo if in_msg.add_logos: if in_msg.verbose: print('... add logos') dc.align_right() if in_msg.add_colorscale: dc.write_vertically() dc.add_logo("../logos/meteoSwiss3.jpg",height=60.0) dc.add_logo("../logos/pytroll3.jpg",height=60.0) # add colorscale if in_msg.add_colorscale and in_msg.colormap[rgb] != None: add_colorscale(dc, rgb, in_msg) # create output filename outputDir = format_name(in_msg.outputDir, data.time_slot, area=area, rgb=rgb, sat_nr=data.number) outputFile = outputDir + format_name(in_msg.outputFile, data.time_slot, area=area, rgb=rgb, sat_nr=data.number) # check if output directory exists, if not create it path= dirname(outputFile) if not exists(path): if in_msg.verbose: print('... create output directory: ' + path) makedirs(path) # save file if in_msg.verbose: print('... save final file :' + outputFile) PIL_image.save(outputFile, optimize=True) # optimize -> minimize file size if in_msg.compress_to_8bit: if in_msg.verbose: print('... compress to 8 bit image: display '+outputFile.replace(".png","-fs8.png")+' &') subprocess.call("/usr/bin/pngquant -force 256 "+outputFile+" 2>&1 &", shell=True) # 256 == "number of colors" #if in_msg.verbose: # print " add coastlines to "+outputFile ## alternative: reopen image and modify it (takes longer due to additional reading and saving) #cw.add_rivers_to_file(img, area_tuple, level=5, outline='blue', width=0.5, outline_opacity=127) #cw.add_coastlines_to_file(outputFile, obj_area, resolution=resolution, level=4) #cw.add_borders_to_file(outputFile, obj_area, outline=outline, resolution=resolution) # copy to another place if in_msg.scpOutput: if in_msg.verbose: print("... secure copy "+outputFile+ " to "+in_msg.scpOutputDir) subprocess.call("scp "+in_msg.scpID+" "+outputFile+" "+in_msg.scpOutputDir+" 2>&1 &", shell=True) if in_msg.compress_to_8bit: if in_msg.verbose: print("... secure copy "+outputFile.replace(".png","-fs8.png")+ " to "+in_msg.scpOutputDir) subprocess.call("scp "+in_msg.scpID+" "+outputFile.replace(".png","-fs8.png")+" "+in_msg.scpOutputDir+" 2>&1 &", shell=True) if rgb not in RGBs_done: RGBs_done.append(rgb) ## start postprocessing if area in in_msg.postprocessing_areas: postprocessing(in_msg, global_data.time_slot, data.number, area) if in_msg.verbose: print(" ") return RGBs_done