Example #1
0
def generate_image(global_data, filename):
    """
    This function generates an RGB composite directly from a scene with
    loaded channels and saves to a GeoTiff
    :param global_data: an mpop scene object with data from IR channels
    12.0, 10.8, 8.7
    :param filename: a string with the name of the image file to be generated
    """

    # Generate a dust composite with Pytroll inbuilt function
    img = global_data.image.dust()

    # Save the image initially so it can be read in as an image object
    img.save("/ouce-home/students/hert4173/SEVIRI_imagery/" + filename)

    # Read it back in as an image object
    img = Image.open("/ouce-home/students/hert4173/SEVIRI_imagery/" + filename)

    # Define projection parameters
    proj4_string = '+proj=geos +lon_0=0.0 +a=6378169.00 +b=6356583.80 ' \
                   '+h=35785831.0'
    area_extent = (-2000000, 0, 3000000, 4000000)
    area_def = (proj4_string, area_extent)

    # ContourWriterAGG here requires the 'aggdraw' package
    cw = ContourWriterAGG(
        '/ouce-home/students/hert4173/.conda_envs/virtual_env/lib/python2.7/'
        'pycoast/GSHHS_DATA_ROOT')
    cw.add_coastlines(img, area_def, resolution='i', width=3)
    cw.add_borders(img,
                   area_def,
                   outline=(255, 255, 255),
                   resolution='i',
                   width=3)
    img.save("/ouce-home/students/hert4173/SEVIRI_imagery/" + filename)
Example #2
0
    def test_europe_agg(self):
        from pycoast import ContourWriterAGG
        euro_img = Image.open(
            os.path.join(os.path.dirname(__file__), 'contours_europe_agg.png'))
        euro_data = np.array(euro_img)

        img = Image.new('RGB', (640, 480))
        proj4_string = '+proj=stere +lon_0=8.00 +lat_0=50.00 +lat_ts=50.00 +ellps=WGS84'
        area_extent = (-3363403.31, -2291879.85, 2630596.69, 2203620.1)
        area_def = (proj4_string, area_extent)
        cw = ContourWriterAGG(gshhs_root_dir)
        cw.add_coastlines(img, area_def, resolution='l', level=4)
        cw.add_rivers(img,
                      area_def,
                      level=5,
                      outline='blue',
                      width=0.5,
                      outline_opacity=127)
        cw.add_borders(img,
                       area_def,
                       outline=(255, 0, 0),
                       width=3,
                       outline_opacity=32)
        res = np.array(img)
        self.failUnless(fft_metric(euro_data, res),
                        'Writing of contours failed for AGG')
Example #3
0
def add_overlay(orig, area, coast_dir, color=(0, 0, 0), width=0.5, resolution=None):
    """Add coastline and political borders to image, using *color* (tuple
    of integers between 0 and 255).
    Warning: Loses the masks !
    *resolution* is chosen automatically if None (default), otherwise it should be one of:
    +-----+-------------------------+---------+
    | 'f' | Full resolution         | 0.04 km |
    | 'h' | High resolution         | 0.2 km  |
    | 'i' | Intermediate resolution | 1.0 km  |
    | 'l' | Low resolution          | 5.0 km  |
    | 'c' | Crude resolution        | 25  km  |
    +-----+-------------------------+---------+
    """
    img = orig.pil_image()

    if area is None:
        raise ValueError("Area of image is None, can't add overlay.")

    from satpy.resample import get_area_def
    if isinstance(area, str):
        area = get_area_def(area)
    LOG.info("Add coastlines and political borders to image.")

    if resolution is None:

        x_resolution = ((area.area_extent[2] -
                         area.area_extent[0]) /
                        area.x_size)
        y_resolution = ((area.area_extent[3] -
                         area.area_extent[1]) /
                        area.y_size)
        res = min(x_resolution, y_resolution)

        if res > 25000:
            resolution = "c"
        elif res > 5000:
            resolution = "l"
        elif res > 1000:
            resolution = "i"
        elif res > 200:
            resolution = "h"
        else:
            resolution = "f"

        LOG.debug("Automagically choose resolution " + resolution)

    from pycoast import ContourWriterAGG
    cw_ = ContourWriterAGG(coast_dir)
    cw_.add_coastlines(img, area, outline=color,
                       resolution=resolution, width=width)
    cw_.add_borders(img, area, outline=color,
                    resolution=resolution, width=width)

    arr = np.array(img)

    if len(orig.channels) == 1:
        orgi.channels[0] = np.ma.array(arr[:, :] / 255.0)
    else:
        for idx in range(len(orig.channels)):
            orig.channels[idx] = np.ma.array(arr[:, :, idx] / 255.0)
Example #4
0
def add_overlay(orig, area, coast_dir, color=(0, 0, 0), width=0.5, resolution=None,
                level_coast=1, level_borders=1):
    """Add coastline and political borders to image, using *color* (tuple
    of integers between 0 and 255).
    Warning: Loses the masks !
    *resolution* is chosen automatically if None (default), otherwise it should be one of:
    +-----+-------------------------+---------+
    | 'f' | Full resolution         | 0.04 km |
    | 'h' | High resolution         | 0.2 km  |
    | 'i' | Intermediate resolution | 1.0 km  |
    | 'l' | Low resolution          | 5.0 km  |
    | 'c' | Crude resolution        | 25  km  |
    +-----+-------------------------+---------+
    """

    if area is None:
        raise ValueError("Area of image is None, can't add overlay.")

    from pycoast import ContourWriterAGG
    if isinstance(area, str):
        area = get_area_def(area)
    LOG.info("Add coastlines and political borders to image.")

    if resolution is None:

        x_resolution = ((area.area_extent[2] -
                         area.area_extent[0]) /
                        area.x_size)
        y_resolution = ((area.area_extent[3] -
                         area.area_extent[1]) /
                        area.y_size)
        res = min(x_resolution, y_resolution)

        if res > 25000:
            resolution = "c"
        elif res > 5000:
            resolution = "l"
        elif res > 1000:
            resolution = "i"
        elif res > 200:
            resolution = "h"
        else:
            resolution = "f"

        LOG.debug("Automagically choose resolution %s", resolution)

    img = orig.pil_image()
    cw_ = ContourWriterAGG(coast_dir)
    cw_.add_coastlines(img, area, outline=color,
                       resolution=resolution, width=width, level=level_coast)
    cw_.add_borders(img, area, outline=color,
                    resolution=resolution, width=width, level=level_borders)

    arr = da.from_array(np.array(img) / 255.0, chunks=CHUNK_SIZE)

    orig.data = xr.DataArray(arr, dims=['y', 'x', 'bands'],
                             coords={'y': orig.data.coords['y'],
                                     'x': orig.data.coords['x'],
                                     'bands': list(img.mode)})
Example #5
0
 def layout(self):
     self.layouter.layout()
     cw = ContourWriterAGG(self.layouter.shapes)
     LOGGER.debug("Add border layout (resolution %s, level %s)" %
                  (self.resolution, BorderLayouter.MAX_LEVEL))
     cw.add_borders(self.layouter.image,
                    self.layouter.area,
                    resolution=self.resolution,
                    level=1)
Example #6
0
 def layout(self):
     self.layouter.layout()
     cw = ContourWriterAGG(self.layouter.shapes)
     LOGGER.debug("Add border layout (resolution %s, level %s)" %
                  (self.resolution, BorderLayouter.MAX_LEVEL))
     cw.add_borders(self.layouter.image,
                    self.layouter.area,
                    resolution=self.resolution,
                    level=1)
Example #7
0
    def test_add_points_agg(self):
        from pycoast import ContourWriterAGG
        from pyresample.geometry import AreaDefinition

        font_file = os.path.join(os.path.dirname(__file__), 'test_data',
                                 'DejaVuSerif.ttf')

        grid_img = Image.open(
            os.path.join(os.path.dirname(__file__), 'nh_points_agg.png'))
        grid_data = np.array(grid_img)

        img = Image.new('RGB', (1024, 1024), (255, 255, 255))
        proj4_string = '+proj=laea +lat_0=90 +lon_0=0 +a=6371228.0 +units=m'
        area_extent = (-5326849.0625, -5326849.0625, 5326849.0625,
                       5326849.0625)

        area_def = AreaDefinition('nh', 'nh', 'nh', proj4_string, 1024, 1024,
                                  area_extent)

        cw = ContourWriterAGG(gshhs_root_dir)
        cw.add_coastlines(img,
                          area_def,
                          outline='black',
                          resolution='l',
                          level=4)
        cw.add_borders(img,
                       area_def,
                       outline='black',
                       width=3,
                       level=1,
                       resolution='c')

        points_list = [((2.3522, 48.8566), 'Paris'),
                       ((0.1278, 51.5074), 'London')]
        cw.add_points(img,
                      area_def,
                      points_list=points_list,
                      font_file=font_file,
                      symbol='circle',
                      ptsize=16,
                      outline='black',
                      width=3,
                      fill='red',
                      fill_opacity=128,
                      box_outline='blue',
                      box_linewidth=0.5,
                      box_fill='yellow',
                      box_opacity=200)

        res = np.array(img)
        self.assertTrue(fft_metric(grid_data, res),
                        'Writing of nh points failed')
Example #8
0
    def test_europe_agg(self):
        from pycoast import ContourWriterAGG
        euro_img = Image.open(os.path.join(os.path.dirname(__file__),
                                           'contours_europe_agg.png'))
        euro_data = np.array(euro_img)

        img = Image.new('RGB', (640, 480))
        proj4_string = '+proj=stere +lon_0=8.00 +lat_0=50.00 +lat_ts=50.00 +ellps=WGS84'
        area_extent = (-3363403.31, -2291879.85, 2630596.69, 2203620.1)
        area_def = (proj4_string, area_extent)
        cw = ContourWriterAGG(gshhs_root_dir)
        cw.add_coastlines(img, area_def, resolution='l', level=4)
        cw.add_rivers(img, area_def, level=5, outline='blue', width=0.5, outline_opacity=127)
        cw.add_borders(img, area_def, outline=(255, 0, 0), width=3, outline_opacity=32)
        res = np.array(img)
        self.failUnless(fft_metric(euro_data, res), 'Writing of contours failed for AGG')
Example #9
0
    def add_overlay(self, color=(0, 0, 0), width=0.5, resolution=None):
        """Add coastline and political borders to image, using *color* (tuple
        of integers between 0 and 255).
        Warning: Loses the masks !

        *resolution* is chosen automatically if None (default), otherwise it should be one of:
        +-----+-------------------------+---------+
        | 'f' | Full resolution         | 0.04 km |
        | 'h' | High resolution         | 0.2 km  |
        | 'i' | Intermediate resolution | 1.0 km  |
        | 'l' | Low resolution          | 5.0 km  |
        | 'c' | Crude resolution        | 25  km  |
        +-----+-------------------------+---------+
        """

        img = self.pil_image()

        import ConfigParser
        conf = ConfigParser.ConfigParser()
        conf.read(os.path.join(CONFIG_PATH, "mpop.cfg"))

        coast_dir = conf.get('shapes', 'dir')

        logger.debug("Getting area for overlay: " + str(self.area))

        if self.area is None:
            raise ValueError("Area of image is None, can't add overlay.")

        from mpop.projector import get_area_def
        if isinstance(self.area, str):
            self.area = get_area_def(self.area)
        logger.info("Add coastlines and political borders to image.")
        logger.debug("Area = " + str(self.area))

        if resolution is None:

            x_resolution = ((self.area.area_extent[2] -
                             self.area.area_extent[0]) /
                            self.area.x_size)
            y_resolution = ((self.area.area_extent[3] -
                             self.area.area_extent[1]) /
                            self.area.y_size)
            res = min(x_resolution, y_resolution)

            if res > 25000:
                resolution = "c"
            elif res > 5000:
                resolution = "l"
            elif res > 1000:
                resolution = "i"
            elif res > 200:
                resolution = "h"
            else:
                resolution = "f"

            logger.debug("Automagically choose resolution " + resolution)

        from pycoast import ContourWriterAGG
        cw_ = ContourWriterAGG(coast_dir)
        cw_.add_coastlines(img, self.area, outline=color,
                           resolution=resolution, width=width)
        cw_.add_borders(img, self.area, outline=color,
                        resolution=resolution, width=width)

        arr = np.array(img)

        if len(self.channels) == 1:
            self.channels[0] = np.ma.array(arr[:, :] / 255.0)
        else:
            for idx in range(len(self.channels)):
                self.channels[idx] = np.ma.array(arr[:, :, idx] / 255.0)
                      outline='white',
                      resolution=resolution,
                      outline_opacity=127,
                      width=1,
                      level=2)  #, outline_opacity=0

    outline = (255, 0, 0)
    outline = 'red'
    cw.add_coastlines(PIL_image,
                      area_def,
                      outline=outline,
                      resolution=resolution,
                      width=2)  #, outline_opacity=0
    cw.add_borders(PIL_image,
                   area_def,
                   outline=outline,
                   resolution=resolution,
                   width=2)  #, outline_opacity=0

add_logos = 1
add_colorscale = 0
add_title = 1
verbose = 1
layer = ' 2nd layer'

ticks = 20
tick_marks = 20  # default
minor_tick_marks = 10  # default
title_color = 'white'
units = global_data[prop_str].info["units"]
#global_data[prop_str].units
Example #11
0
if add_borders:
    from pycoast import ContourWriterAGG
    # define contour write for coasts, borders, rivers
    cw = ContourWriterAGG('/data/OWARNA/hau/maps_pytroll/')
    # define area
    from mpop.projector import get_area_def
    # obj_area = get_area_def('ccs4')
    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_def = (proj4_string, area_extent)
    resolution = 'h'
    cw.add_borders(PIL_image,
                   area_def,
                   outline=(255, 0, 0),
                   resolution=resolution,
                   width=1)  #, outline_opacity=0

if False:
    print('... add cell velocities')
    from math import isnan

    print("traj_ID             Rank    x0     y0     vx      vy")

    for traj in global_data.traj_IDs:

        if global_data.TRT[traj].RANKr > min_rank:

            x0 = global_data.TRT[traj].jCH
            y0 = global_data.TRT[traj].iCH
Example #12
0
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
Example #13
0
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)
PIL_image = img.pil_image()
from pycoast import ContourWriterAGG
cw = ContourWriterAGG('/opt/users/common/shapes/')
obj_area = get_area_def(area)
area_def = (obj_area.proj4_string, obj_area.area_extent)
resolution = 'l'
cw.add_coastlines(PIL_image,
                  area_def,
                  outline='white',
                  resolution=resolution,
                  outline_opacity=127,
                  width=1,
                  level=2)
cw.add_borders(PIL_image,
               area_def,
               outline='white',
               resolution=resolution,
               width=1)  #, outline_opacity=0

add_colorscale = True
if add_colorscale:
    print('... add colorscale ranging from min_radar (', min_radar,
          ') to max_radar (', max_radar, ')')
    from pydecorate import DecoratorAGG
    dc = DecoratorAGG(PIL_image)
    dc.align_right()
    dc.write_vertically()
    ticks = 20
    tick_marks = 20  # default
    minor_tick_marks = 10  # default
    fontsize = 18
Example #15
0
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
Example #16
0
    resolution = 'l'
    #if area=='Etna':
    #    resolution='h'
    #outline = (255, 0, 0)
    #outline = 'white'
    #outline = 'red'
    cw.add_coastlines(PIL_image,
                      area_def,
                      outline='black',
                      resolution=resolution,
                      level=2,
                      width=0.5)  #, outline_opacity=127, outline_opacity=0
    #cw.add_coastlines(PIL_image, area_def, outline=outline, resolution=resolution, width=2)  #, outline_opacity=0
    cw.add_borders(PIL_image,
                   area_def,
                   outline='black',
                   resolution=resolution,
                   width=0.5)  #, outline_opacity=0

if False:
    from plot_msg import add_title
    from pydecorate import DecoratorAGG

    if socket.gethostname()[0:5] == 'zueub':
        font_file = "/usr/openv/java/jre/lib/fonts/LucidaTypewriterBold.ttf"
    elif socket.gethostname()[0:7] == 'keschln' or socket.gethostname(
    )[0:7] == "eschaln":
        font_file = "/usr/share/fonts/dejavu/DejaVuSansMono.ttf"
    else:
        print("*** ERROR, unknown computer, unknown location of the ttf-file")
        quit()
Example #17
0
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)
Example #18
0
def add_overlay(orig,
                area,
                coast_dir,
                color=(0, 0, 0),
                width=0.5,
                resolution=None,
                level_coast=1,
                level_borders=1,
                fill_value=None,
                grid=None):
    """Add coastline, political borders and grid(graticules) to image.

    Uses ``color`` for feature colors where ``color`` is a 3-element tuple
    of integers between 0 and 255 representing (R, G, B).

    .. warning::

        This function currently loses the data mask (alpha band).

    ``resolution`` is chosen automatically if None (default),
    otherwise it should be one of:

    +-----+-------------------------+---------+
    | 'f' | Full resolution         | 0.04 km |
    +-----+-------------------------+---------+
    | 'h' | High resolution         | 0.2 km  |
    +-----+-------------------------+---------+
    | 'i' | Intermediate resolution | 1.0 km  |
    +-----+-------------------------+---------+
    | 'l' | Low resolution          | 5.0 km  |
    +-----+-------------------------+---------+
    | 'c' | Crude resolution        | 25  km  |
    +-----+-------------------------+---------+

    ``grid`` is a dictionary with key values as documented in detail in pycoast

    eg. overlay={'grid': {'major_lonlat': (10, 10),
                          'write_text': False,
                          'outline': (224, 224, 224),
                          'width': 0.5}}

    Here major_lonlat is plotted every 10 deg for both longitude and latitude,
    no labels for the grid lines are plotted, the color used for the grid lines
    is light gray, and the width of the gratucules is 0.5 pixels.

    For grid if aggdraw is used, font option is mandatory, if not
    ``write_text`` is set to False::

        font = aggdraw.Font('black', '/usr/share/fonts/truetype/msttcorefonts/Arial.ttf',
                            opacity=127, size=16)

    """

    if area is None:
        raise ValueError("Area of image is None, can't add overlay.")

    from pycoast import ContourWriterAGG
    if isinstance(area, str):
        area = get_area_def(area)
    LOG.info("Add coastlines and political borders to image.")

    if resolution is None:

        x_resolution = ((area.area_extent[2] - area.area_extent[0]) /
                        area.x_size)
        y_resolution = ((area.area_extent[3] - area.area_extent[1]) /
                        area.y_size)
        res = min(x_resolution, y_resolution)

        if res > 25000:
            resolution = "c"
        elif res > 5000:
            resolution = "l"
        elif res > 1000:
            resolution = "i"
        elif res > 200:
            resolution = "h"
        else:
            resolution = "f"

        LOG.debug("Automagically choose resolution %s", resolution)

    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.pil_image(fill_value=fill_value)
    cw_ = ContourWriterAGG(coast_dir)
    cw_.add_coastlines(img,
                       area,
                       outline=color,
                       resolution=resolution,
                       width=width,
                       level=level_coast)
    cw_.add_borders(img,
                    area,
                    outline=color,
                    resolution=resolution,
                    width=width,
                    level=level_borders)
    # Only add grid if major_lonlat is given.
    if grid and 'major_lonlat' in grid and grid['major_lonlat']:
        major_lonlat = grid.pop('major_lonlat')
        minor_lonlat = grid.pop('minor_lonlat', major_lonlat)

        cw_.add_grid(img, area, major_lonlat, minor_lonlat, **grid)

    arr = da.from_array(np.array(img) / 255.0, chunks=CHUNK_SIZE)

    new_data = xr.DataArray(arr,
                            dims=['y', 'x', 'bands'],
                            coords={
                                'y': orig.data.coords['y'],
                                'x': orig.data.coords['x'],
                                'bands': list(img.mode)
                            },
                            attrs=orig.data.attrs)
    return XRImage(new_data)
Example #19
0
def add_overlay(orig, area, coast_dir, color=(0, 0, 0), width=0.5, resolution=None,
                level_coast=1, level_borders=1, fill_value=None):
    """Add coastline and political borders to image.

    Uses ``color`` for feature colors where ``color`` is a 3-element tuple
    of integers between 0 and 255 representing (R, G, B).

    .. warning::

        This function currently loses the data mask (alpha band).

    ``resolution`` is chosen automatically if None (default), otherwise it should be one of:

    +-----+-------------------------+---------+
    | 'f' | Full resolution         | 0.04 km |
    | 'h' | High resolution         | 0.2 km  |
    | 'i' | Intermediate resolution | 1.0 km  |
    | 'l' | Low resolution          | 5.0 km  |
    | 'c' | Crude resolution        | 25  km  |
    +-----+-------------------------+---------+

    """

    if area is None:
        raise ValueError("Area of image is None, can't add overlay.")

    from pycoast import ContourWriterAGG
    if isinstance(area, str):
        area = get_area_def(area)
    LOG.info("Add coastlines and political borders to image.")

    if resolution is None:

        x_resolution = ((area.area_extent[2] -
                         area.area_extent[0]) /
                        area.x_size)
        y_resolution = ((area.area_extent[3] -
                         area.area_extent[1]) /
                        area.y_size)
        res = min(x_resolution, y_resolution)

        if res > 25000:
            resolution = "c"
        elif res > 5000:
            resolution = "l"
        elif res > 1000:
            resolution = "i"
        elif res > 200:
            resolution = "h"
        else:
            resolution = "f"

        LOG.debug("Automagically choose resolution %s", resolution)

    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.pil_image(fill_value=fill_value)
    cw_ = ContourWriterAGG(coast_dir)
    cw_.add_coastlines(img, area, outline=color,
                       resolution=resolution, width=width, level=level_coast)
    cw_.add_borders(img, area, outline=color,
                    resolution=resolution, width=width, level=level_borders)

    arr = da.from_array(np.array(img) / 255.0, chunks=CHUNK_SIZE)

    new_data = xr.DataArray(arr, dims=['y', 'x', 'bands'],
                            coords={'y': orig.data.coords['y'],
                                    'x': orig.data.coords['x'],
                                    'bands': list(img.mode)},
                            attrs=orig.data.attrs)
    return XRImage(new_data)