Example #1
0
def load_points(glacier):

  '''
  Load all points that define where land is located.
  
  pts = load_points(glacier)
  
  Inputs:
  glacier: glacier name
  
  Outputs:
  pts: 2d array of points that define land extent

  '''

  DIR = os.path.join(os.getenv("DATA_HOME"),'ShapeFiles/IceMasks/'+glacier+'/')

  files = os.listdir(DIR)
  
  n=0
  for file in files:
    if (file.endswith('.shp')) and ('hole' in file):
      hole = meshlib.shp_to_xy(DIR+file)
      if n==0:
        pts = hole[:,0:2]  
      else:
        pts = np.row_stack([pts,hole[:,0:2]])
      n=1
      
  return pts
Example #2
0
def load_flowline(glacier,shapefilename='center_flowline',filt_len=2.0e3,verticaldatum='geoid',bedsource='cresis',bedmodel='aniso',bedsmoothing=4,dx=20):

  '''
  x,y,zb_filt,dists = load(glacier,shapefilename='center_flowline')
  
  Load glacier flowline. This script is mostly to keep everything consistent (distance 
  along flowline, chosen bed profile,etc.
  
  Inputs:
  glacier: glacier name
  shapefilename: shapefile to use for the flowline
  filt_len: filter length (in meters) for the bed profile
  verticaldatum: geoid or ellipsoid
  dx: distance between points
  
  Outputs:
  x,y: x,y coordinates of flowline
  zb_filt: bed profile for flowline
  '''

  if glacier == 'Helheim':
    file1 = 'helheim_'
  elif glacier == 'Kanger':
    file1 = 'kanger_'
  elif glacier == 'Midgaard':
    file1 = 'midgaard_'
  else:
    sys.exit("Unknown glacier.") 
  file_flowline_in = os.path.join(os.getenv("DATA_HOME"),"ShapeFiles/Glaciers/Flowlines/"+glacier+"/"+file1+shapefilename)

  
  flowline = meshlib.shp_to_xy(file_flowline_in)
  d = distlib.transect(flowline[:,0],flowline[:,1])

  # Set uniform spacing between nodes along flowline
  dists_old = np.linspace(0,np.max(d),np.max(d)/dx)
  x = np.interp(dists_old,d,flowline[:,0])
  y = np.interp(dists_old,d,flowline[:,1])
  
  # Get new distances
  dists = distlib.transect(x,y)

  # Get average terminus position
  time1 = 2008.0
  time2 = 2016.0
  
  # Get terminus positions so that we can set distance along flowline 
  # relative to the average terminus position
  terminus_val, terminus_time = icefrontlib.distance_along_flowline(x,y,dists,glacier,type='icefront',time1=time1,time2=time2)

  # Average terminus position
  terminus = np.mean(terminus_val)

  # Set dists relative to average terminus position
  dists = dists-terminus

  # Find bed elevation
  if (glacier == 'Helheim') and (bedsource == 'smith'):
    zb = bedlib.smith_at_pts(x,y,glacier,model=bedmodel,smoothing=bedsmoothing,verticaldatum=verticaldatum)
  elif bedsource == 'morlighem':
    zb = bedlib.morlighem_pts(x,y,verticaldatum=verticaldatum)
  elif (glacier == 'Kanger' and (bedsource != 'morlighem')) or (bedsource == 'cresis'):
    cresis = bedlib.cresis('all',glacier,verticaldatum=verticaldatum)
    if glacier == 'Helheim':
      cresis2001 = bedlib.cresis('2001',glacier,verticaldatum=verticaldatum)
      cresis = np.row_stack([cresis,cresis2001])
    cutdist = 200.
    dcresis = []
    zcresis = []
    tcresis = []
    for i in range(0,len(cresis[:,0])):
      mindist = np.min(np.sqrt((cresis[i,0]-x)**2+(cresis[i,1]-y)**2))
      if mindist < cutdist:
        minind = np.argmin(np.sqrt((cresis[i,0]-x)**2+(cresis[i,1]-y)**2))
        dcresis.append(dists[minind])
        zcresis.append(cresis[i,2])
        tcresis.append(cresis[i,4])

    ind = np.argsort(dcresis)
    dcresis = np.array(dcresis)[ind]
    zcresis = np.array(zcresis)[ind]
    zb = np.interp(dists,dcresis,zcresis)

  if filt_len != 'none':
    ind = np.where(~(np.isnan(zb)))[0]
    zb_filt = np.zeros_like(zb)
    zb_filt[:] = float('nan')
    cutoff=(1/filt_len)/(1/(np.diff(dists[1:3])*2))
    b,a=scipy.signal.butter(4,cutoff,btype='low')
    zb_filt[ind] = scipy.signal.filtfilt(b,a,zb[ind])
  else:
    zb_filt = zb
    
  if (glacier == 'Kanger') and (shapefilename=='flowline_flightline'):
    ind = np.where(dists > 3000.)[0]
    zb_filt[ind] = float('nan')
  elif (glacier == 'Helheim') and (shapefilename=='flowline_flightline'):
    ind = np.where(dists > 3900.)[0]
    zb_filt[ind] = float('nan')
    

  return x,y,zb_filt,dists
Example #3
0
def load_extent_timeseries(glacier,time1,time2,dt,nofront_shapefile='glacier_extent_nofront',datatypes=['Landsat','TSX','WV']):

  '''
  time, xextents, yxextents, bounds = load_extent_timeseries(glacier,time1,
     time2,dt,nofront_shapefile='glacier_extent_nofront',
     datatypes=['Landsat','TSX','WV'])
     
  Interpolates ice-front positions from picked ice-front positions to create 
  a timeseries of meshes to be used in the terminus-driven model.
  
  Inputs:
  glacier           : glacier name (Helheim, Kanger)
  time1             : fractional start time for timeseries
  time2             : fractional end time for timeseries
  dt                : timestep
  nofront_shapefile : nofront shapefile name for mesh extent
  datatypes         : satellite image types for picked ice fronts
  
  Outputs:
  time     : interpolated time between time1,time2 with timestep dt
  xextents : 2-d array of x-coordinates of extents
  yextents : 2-d array of y-coordinates of extents
  bounds   : boundary numbers for extents
  '''

  # Glacier extent with no ice front
  extent = meshlib.shp_to_xy(os.path.join(os.getenv("DATA_HOME"),"ShapeFiles/Glaciers/3D/"+glacier+"/"+nofront_shapefile))
  if extent[1,1] > extent[0,1]:
    extent = np.flipud(extent)
  
  xextent = extent[:,0]
  yextent = extent[:,1]
  bound_extent = extent[:,2]

  # Interpolate glacier extent to a finer grid to make ice-front interpolation easier
  dextent = distlib.transect(xextent,yextent)
  #dextent = np.arange(0,dold[-1],20.0)
  #xextent = np.interp(dextent,dold,xextent)
  #yextent = np.interp(dextent,dold,yextent)
  #f = scipy.interpolate.interp1d(dold,bound,kind='nearest')
  #bound = f(dextent)
  extent = LineString(np.column_stack([extent[:,0:2]]))

  # Load all ice front positions for that time period
  termx,termy,termt = icefrontlib.load_all(time1-0.5,time2+0.5,glacier,type='icefront',datatypes=datatypes)

  # In case we have multiple ice front picks for the same day, we want to
  # use only one of those for continuity
  [junk,ind] = np.unique(termt,return_index=True)
  termt = np.array(termt)[ind]
  termx = termx[:,ind]
  termy = termy[:,ind]

  # Load a velocity profile to use as interpolation direction to figure out ice-front position
  # on timesteps that fall between picked ice fronts
  x,y,u = geotifflib.read(os.path.join(os.getenv("DATA_HOME"),"Velocity/TSX/"+glacier+"/TIF/all-2008-2016_vx.tif"))
  x,y,v = geotifflib.read(os.path.join(os.getenv("DATA_HOME"),"Velocity/TSX/"+glacier+"/TIF/all-2008-2016_vy.tif"))  

  fu = scipy.interpolate.RegularGridInterpolator((y,x),u)
  fv = scipy.interpolate.RegularGridInterpolator((y,x),v)

  # Get ice-front position for each timestep
  time = np.arange(time1,time2+dt,dt)
  timeseries_x = np.zeros([len(termx[:,0]),len(time)])
  timeseries_y = np.zeros([len(termx[:,0]),len(time)])
  timeseries_advance = np.zeros([len(termx[:,0]),len(time)])
  timeseries_dist = np.zeros([len(termx[:,0]),len(time)])  
  timeseries_x[:,:] = float('nan')
  timeseries_y[:,:] = float('nan')
  timeseries_advance[:,:] = float('nan')
  timeseries_dist[:,:] = float('nan')
  xextents = np.zeros([len(termx[:,0])+len(xextent),len(time)])
  yextents = np.zeros([len(termx[:,0])+len(xextent),len(time)])
  bounds = np.zeros([len(termx[:,0])+len(xextent),len(time)])
  for i in range(0,len(time)):
    # Find picked ice-front positions for before and after timestep for the interpolation
    ind = np.argmin(abs(time[i]-termt))
    if termt[ind] < time[i]:
      ind1 = ind
      ind2 = ind+1
    else:
      ind1 = ind-1
      ind2 = ind
    
    # Fractional time between ind1,ind2 to use for interpolation
    frac = (time[i]-termt[ind1])/(termt[ind2]-termt[ind1])
    
    # Get picked ice-front positions that we will use for the interpolation
    nonnan = np.where(~(np.isnan(termx[:,ind1])))[0]
    termx1 = termx[nonnan,ind1]
    termy1 = termy[nonnan,ind1]
    nonnan = np.where(~(np.isnan(termx[:,ind2])))[0]
    termx2 = termx[nonnan,ind2]
    termy2 = termy[nonnan,ind2]   
    
    if termy1[-1] > termy1[0]:
      termx1 = np.flipud(termx1)
      termy1 = np.flipud(termy1)
    if termy2[-1] > termy2[0]:
      termx2 = np.flipud(termx2)
      termy2 = np.flipud(termy2)
  
    # Get locations where interpolate ice front intersects the glacier extent
    # First, get intersection pts for two closest ice-front positions in time
    term1 = LineString(np.column_stack([termx1,termy1]))
    intersect = extent.intersection(term1)
    try:
      if len(intersect) == 2:
        if intersect[0].y > intersect[1].y:
          top1 = [intersect[0].x,intersect[0].y]
          bot1 = [intersect[1].x,intersect[1].y]
        else:
          top1 = [intersect[1].x,intersect[1].y]
          bot1 = [intersect[0].x,intersect[0].y]
      else:
        print "Need to look at date ", datelib.fracyear_to_date(termt[ind1])
    except:
      print "Need to look at date ", datelib.fracyear_to_date(termt[ind1])
    
    term2 = LineString(np.column_stack([termx2,termy2]))
    intersect = extent.intersection(term2)
    try:
      if len(intersect) == 2:
        if intersect[0].y > intersect[1].y:
          top2 = [intersect[0].x,intersect[0].y]
          bot2 = [intersect[1].x,intersect[1].y]
        else:
          top2 = [intersect[1].x,intersect[1].y]
          bot2 = [intersect[0].x,intersect[0].y]
      else:
        print "Need to look at date ", datelib.fracyear_to_date(termt[ind2])
    except:
      print "Need to look at date ", datelib.fracyear_to_date(termt[ind2])
    # Now find new intersection points
    if top1[0] < top2[0]: # advancing on this side
      ind_top = np.where((xextent > top1[0]) & (xextent < top2[0]) & (abs(top1[1]-yextent) < 500.))[0]
      sortind = np.argsort(xextent[ind_top])
      xtops = np.r_[top1[0],xextent[ind_top[sortind]],top2[0]]
      ytops = np.r_[top1[1],yextent[ind_top[sortind]],top2[1]]
      dtops = distlib.transect(xtops,ytops)
      dtop = dtops[-1]*frac
    elif top1[0] > top2[0]: # retreating on this side
      ind_top = np.where((xextent < top1[0]) & (xextent > top2[0]) & (abs(top1[1]-yextent) < 500.))[0]
      sortind = np.argsort(xextent[ind_top])
      xtops = np.r_[top2[0],xextent[ind_top[sortind]],top1[0]]
      ytops = np.r_[top2[1],yextent[ind_top[sortind]],top1[1]]
      dtops = distlib.transect(xtops,ytops)
      dtop = dtops[-1]*(1-frac)
    else:
      print "not advancing or retreating on top"
    xtop = np.interp(dtop,dtops,xtops)
    ytop = np.interp(dtop,dtops,ytops)
      
    if bot1[0] < bot2[0]: # advancing on this side
      ind_bot = np.where((xextent > bot1[0]) & (xextent < bot2[0]) & (abs(bot1[1]-yextent) < 500.))[0]
      sortind = np.argsort(xextent[ind_bot])
      xbots = np.r_[bot1[0],xextent[ind_bot[sortind]],bot2[0]]
      ybots = np.r_[bot1[1],yextent[ind_bot[sortind]],bot2[1]]
      dbots= distlib.transect(xbots,ybots)
      dbot = (dbots[-1])*frac
    elif bot1[0] > bot2[0]: # retreating on this side
      ind_bot = np.where((xextent < bot1[0]) & (xextent > bot2[0]) & (abs(bot1[1]-yextent) < 500.))[0]
      sortind = np.argsort(xextent[ind_bot])
      xbots = np.r_[bot2[0],xextent[ind_bot[sortind]],bot1[0]]
      ybots = np.r_[bot2[1],yextent[ind_bot[sortind]],bot1[1]]
      dbots= distlib.transect(xbots,ybots)
      dbot = (dbots[-1])*(1-frac)
    else:
      print "not advancing or retreating on bot"

    xbot = np.interp(dbot,dbots,xbots)
    ybot = np.interp(dbot,dbots,ybots)

    # Now that we know the bottom and top points (extent of the ice front), we can start
    # calculating the shape, again based on linear interpolation
    # May need to change next expression to find indices between the sidewalls for Kanger, 
    # but this should work for Helheim
    ind_term1 = np.where((termy1 > bot1[1]) & (termy1 < top1[1]))[0]
    icefront_x = []
    icefront_y = []
    advance = []
    icefront_x.append(xtop)
    icefront_y.append(ytop)
    if i > 0:
      nonnan = np.where(~(np.isnan(xextents[:,i-1])))[0]
      extentpath = Path(np.column_stack([xextents[nonnan,i-1],yextents[nonnan,i-1]]))
      if extentpath.contains_point([xtop,ytop]) or (xtop < xtop_old):
        sign = -1
      else:
        sign = 1
      advance.append(sign*distlib.between_pts(xtop,ytop,xtop_old,ytop_old))
    else:
      advance.append(0)
    for j in ind_term1:
      # Get velocities to create a line, to interpolate between ice fronts
      uj = fu((termy1[j],termx1[j]))
      vj = fv((termy1[j],termx1[j]))
    
      # Create flowline that intersects that point of the ice front
      xunit = uj/(np.sqrt(uj**2+vj**2))
      yunit = vj/(np.sqrt(uj**2+vj**2))
      b = termy1[j] - (yunit/xunit)*termx1[j]
      flowlinex = np.arange(-3000.,3005.,10) + termx1[j]
      flowliney = (yunit/xunit)*flowlinex + b
      flowline = LineString(np.column_stack([flowlinex,flowliney]))
    
      # Find where flowline intersects the next ice-front position
      intersect = flowline.intersection(term2)
      add = False
      try:   
        if len(intersect) > 0: 
          ind = np.argmin(abs([intersect[k].x for k in range(0,len(intersect))]-termx1[j]))
          term2_flowline = [intersect[ind].x,intersect[ind].y]
          add = True
      except:
        try:
          term2_flowline = [intersect.x,intersect.y]
          add = True
        except:
          pass
      dflow = distlib.between_pts(termx1[j],termy1[j],term2_flowline[0],term2_flowline[1])
      dmid = frac*dflow
      xmid = np.interp(dmid,[0,dflow],[termx1[j],term2_flowline[0]])
      ymid = np.interp(dmid,[0,dflow],[termy1[j],term2_flowline[1]])
      if (add == True) and (ymid > ybot) and (ymid < ytop):  
        icefront_x.append(xmid)
        icefront_y.append(ymid)
        if i > 0:
          nonnan = np.where(~(np.isnan(timeseries_x[:,i-1])))[0]
          front_lasttime = LineString(np.column_stack([timeseries_x[nonnan,i-1],timeseries_y[nonnan,i-1]]))
          intersect = flowline.intersection(front_lasttime)
          try:
            diff = distlib.between_pts(xmid,ymid,intersect.x,intersect.y)
          except:
            try:
              diff = 1000.0
              for pt in intersect:
                newdiff = distlib.between_pts(xmid,ymid,pt.x,pt.y)
                if newdiff < diff:
                  diff = newdiff
              if diff == 1000.0:
                diff = 0
            except:
              diff = 0
          if extentpath.contains_point([xmid,ymid]):
              sign = -1
          else:
            sign = 1
          advance.append(sign*diff)
        else:
          advance.append(0)
    
    icefront_x.append(xbot)
    icefront_y.append(ybot)
    if i > 0:
      if extentpath.contains_point([xbot,ybot]) or (xbot < xbot_old):
        sign = -1
      else:
        sign = 1
      advance.append(sign*distlib.between_pts(xbot,ybot,xbot_old,ybot_old))
    else:
      advance.append(0)
    
    # Try sorting icefront to get rid of potential tangles
    icefront_x_old = np.asarray(icefront_x)
    icefront_y_old = np.asarray(icefront_y)
    advance_old = np.asarray(advance)
    icefront_x = np.zeros_like(icefront_x_old)
    icefront_y = np.zeros_like(icefront_y_old)
    advance = np.zeros_like(advance_old)
    icefront_x[0] = icefront_x_old[0]
    icefront_y[0] = icefront_y_old[0]
    advance[0] = advance_old[0]
    ind = range(1,len(icefront_x_old))
    for k in range(1,len(icefront_x_old)):
      mindist = 10000.
      for j in range(0,len(ind)):
        dist = distlib.between_pts(icefront_x[k-1],icefront_y[k-1],icefront_x_old[ind[j]],icefront_y_old[ind[j]])
        if dist < mindist:
          mindist = dist
          minind = ind[j]
      icefront_x[k] = icefront_x_old[minind]
      icefront_y[k] = icefront_y_old[minind]
      advance[k] = advance_old[minind]
      ind.remove(minind)
    
    # Save icefront in timeseries 
    timeseries_x[0:len(icefront_x),i] = icefront_x
    timeseries_y[0:len(icefront_y),i] = icefront_y
    timeseries_dist[0:len(icefront_x),i] = distlib.transect(icefront_x,icefront_y)
    timeseries_advance[0:len(icefront_x),i] = advance
    
    # Now create mesh extent and BC numbers using the interpolated ice front
    boundterminus = np.ones(len(icefront_x))*2.0
    ind1 = np.where((xextent > xbot) & (abs(yextent - ybot) < 1.0e3))[0][0] 
    ind2 = np.where((xextent > xtop) & (abs(yextent - ytop) < 1.0e3))[0][-1]

    extent_x = np.r_[xextent[0:ind1],np.flipud(icefront_x),xextent[ind2+1:]]
    extent_y = np.r_[yextent[0:ind1],np.flipud(icefront_y),yextent[ind2+1:]]
    bound = np.r_[bound_extent[0:ind1],boundterminus,bound_extent[ind2+1:]]
    
    xextents[0:len(extent_x),i] = extent_x
    yextents[0:len(extent_x),i] = extent_y
    bounds[0:len(extent_x),i] = bound
    
    xtop_old = float(xtop)
    ytop_old = float(ytop)
    xbot_old = float(xbot)
    ybot_old = float(ybot)
      
    
  return  time, xextents, yextents, bounds, timeseries_x, timeseries_y, timeseries_advance
Example #4
0
def load_extent(glacier,time,nofront_shapefile='glacier_extent_nofront'):
  
  '''
  extent = load_extent(glacier,time)
  
  Find the glacier extent that is closest to "time".
  
  Inputs:
  glacier: glacier name
  time: time (fractional year) when we want the glacier extent
  
  Outputs:
  xextent,yextent: 1-D arrays of x and y coordinates that define glacier extent for that date
  '''
  
  # Glacier extent with no ice front
  extent = meshlib.shp_to_xy(os.path.join(os.getenv("DATA_HOME"),"ShapeFiles/Glaciers/3D/"+glacier+"/"+nofront_shapefile))
  
  if extent[1,1] > extent[0,1]:
    extent = np.flipud(extent)
  
  xextent = extent[:,0]
  yextent = extent[:,1]
  bound = extent[:,2]
  
  dold = distlib.transect(xextent,yextent)
  dnew = np.arange(0,dold[-1],20.0)
  xextent = np.interp(dnew,dold,xextent)
  yextent = np.interp(dnew,dold,yextent)

  f = scipy.interpolate.interp1d(dold,bound,kind='nearest')
  bound = f(dnew)
  
  # Terminus coordinates
  xterminus,yterminus,time_terminus = icefrontlib.near_time(time,glacier)
  if yterminus[-1] > yterminus[0]:
    xterminus = np.flipud(xterminus)
    yterminus = np.flipud(yterminus)
  
  glacierperimeter = Path(extent[:,0:2])
  ind = glacierperimeter.contains_points(np.column_stack([xterminus,yterminus]))
  xterminus = xterminus[ind]
  yterminus = yterminus[ind]
  boundterminus = np.ones(len(xterminus))*2.0

  ind1 = np.argmin((xterminus[0]-xextent)**2+(yterminus[0]-yextent)**2)
  ind2 = np.argmin((xterminus[-1]-xextent)**2+(yterminus[-1]-yextent)**2)
  if ind2 > ind1:
    if yextent[ind2] < yextent[ind1]:
      xextent = np.r_[np.delete(xextent[0:ind2],range(ind1+1,ind2)),np.flipud(xterminus),xextent[ind2+1:]]
      yextent = np.r_[np.delete(yextent[0:ind2],range(ind1+1,ind2)),np.flipud(yterminus),yextent[ind2+1:]]
      bound = np.r_[np.delete(bound[0:ind2],range(ind1+1,ind2)),boundterminus,bound[ind2+1:]]
    else:
      xextent = np.r_[np.delete(xextent[0:ind2],range(ind1+1,ind2)),xterminus,xextent[ind2+1:]]
      yextent = np.r_[np.delete(yextent[0:ind2],range(ind1+1,ind2)),yterminus,yextent[ind2+1:]]
      bound = np.r_[np.delete(bound[0:ind2],range(ind1+1,ind2)),boundterminus,bound[ind2+1:]]
  else:
    if yextent[ind2] < yextent[ind1]:
      xextent = np.r_[np.delete(xextent[0:ind1],range(ind2+1,ind1)),np.flipud(xterminus),xextent[ind1+1:]]
      yextent = np.r_[np.delete(yextent[0:ind1],range(ind2+1,ind1)),np.flipud(yterminus),yextent[ind1+1:]]
      bound = np.r_[np.delete(bound[0:ind1],range(ind2+1,ind1)),np.flipud(boundterminus),bound[ind1+1:]]
    else:
      xextent = np.r_[np.delete(xextent[0:ind1],range(ind2+1,ind1)),xterminus,xextent[ind1+1:]]
      yextent = np.r_[np.delete(yextent[0:ind1],range(ind2+1,ind1)),yterminus,yextent[ind1+1:]]
      bound = np.r_[np.delete(bound[0:ind1],range(ind2+1,ind1)),boundterminus,bound[ind1+1:]]
  
  return np.column_stack([xextent,yextent,bound])
Example #5
0
        imagetime = datelib.date_to_fracyear(2014, 7, 4)
        ximage, yimage, image = geotifflib.readrgb(
            os.path.join(
                os.getenv("DATA_HOME"),
                "Imagery/Landsat/Helheim/TIF/20140704140535_LC82330132014185LGN00.tif"
            ))
    elif glacier == "Kanger":
        imagetime = datelib.date_to_fracyear(2014, 7, 6)
        ximage, yimage, image = geotifflib.readrgb(
            os.path.join(
                os.getenv("DATA_HOME"),
                "Imagery/Landsat/Kanger/TIF/20140706135251_LC82310122014187LGN00.tif"
            ))

    extent = meshlib.shp_to_xy(
        os.path.join(
            os.getenv("DATA_HOME"), "ShapeFiles/Glaciers/3D/" + glacier +
            "/glacier_extent_inversion_front.shp"))

    # Load velocity record
    xvel = np.arange(np.min(ximage), np.max(ximage), 100)
    yvel = np.arange(np.min(yimage), np.max(yimage), 100)
    vx, vy = vellib.inversion_3D(glacier,
                                 xvel,
                                 yvel,
                                 imagetime,
                                 dir_velocity_out='none',
                                 blur=False)
    vel = np.sqrt(vx**2 + vy**2)
    del vx, vy

    # Load mask
Example #6
0
def glacierwidth(flowline, file_rightside_in, file_leftside_in, filt_len):
    print "\n## Calculating glacier width ##"

    import os
    import sys
    import math
    import numpy as np
    import meshlib
    import scipy.interpolate as interpolate
    import scipy.signal as signal
    import matplotlib.pyplot as plt

    R = len(flowline[:, 0])
    width = [0] * R
    width_interped = [0] * R

    # Load channel boundaries for calculating width
    rightside = meshlib.shp_to_xy(file_rightside_in)
    leftside = meshlib.shp_to_xy(file_leftside_in)
    del file_rightside_in, file_leftside_in

    # Set up channel boundaries as functions
    f_left = interpolate.interp1d(leftside[:, 0], leftside[:, 1], 'linear')
    f_right = interpolate.interp1d(rightside[:, 0], rightside[:, 1], 'linear')

    # Go through all points in the flowline
    no_interp = 0
    for i in range(1, R - 1):
        # Surrounding points
        x1 = flowline[i - 1, 1]
        y1 = flowline[i - 1, 2]
        x2 = flowline[i, 1]
        y2 = flowline[i, 2]
        x3 = flowline[i + 1, 1]
        y3 = flowline[i + 1, 2]

        # Find intersection between perpendicular line and the "leftside" and "rightside" of the channel
        if y1 == y3:
            # In case the perpendicular line is vertical, which will make the slope calculation fail
            yR = f_right(x2)
            yL = f_left(x2)
            width[i] = yR - yL
            del yR, yL
        else:
            # In all other cases, we first find the slope of the perpendicular line, find the line
            # with that slope, subtract the two functions, and find the minimum distance (the root)
            m_para = (y3 - y1) / (x3 - x1)
            m_perp = -1 / m_para
            b = y2 - m_perp * x2

            xL = np.linspace(
                min(leftside[:, 0]), max(leftside[:, 0]),
                math.ceil((max(leftside[:, 0]) - min(leftside[:, 0])) / 5))
            f_perp_L = interpolate.interp1d(xL, m_perp * xL + b, 'linear')
            xR = np.linspace(
                min(rightside[:, 0]), max(rightside[:, 0]),
                math.ceil((max(rightside[:, 0]) - min(rightside[:, 0])) / 5))
            f_perp_R = interpolate.interp1d(xR, m_perp * xR + b, 'linear')

            ind_left = []
            mindist = 200
            dists = f_perp_L(xL) - f_left(xL)
            for j in range(0, len(dists)):
                if abs(dists[j]) < mindist:
                    mindist = abs(dists[j])
                    ind_left = j
            del dists, mindist
            ind_right = []
            mindist = 200
            dists = f_perp_R(xR) - f_right(xR)
            for j in range(0, len(dists)):
                if abs(dists[j]) < mindist:
                    mindist = abs(dists[j])
                    ind_right = j
            if not ind_right or not ind_left:
                no_interp = no_interp + 1
            try:
                width[i] = (math.sqrt((xL[ind_left] - xR[ind_right])**2 +
                                      (f_left(xL[ind_left]) -
                                       f_right(xR[ind_right]))**2))
            except:
                pass
            del xL, xR, ind_left, ind_right, mindist, dists, m_para, m_perp
        del x1, x2, x3, y1, y2, y3
    print "Could not find an intersection point for width estimation at", no_interp, "points"

    m = []
    n = []
    indices = []
    for i in range(0, R):
        if width[i] is not 0:
            m.append(flowline[i, 0])
            n.append(width[i])
            indices.append(i)

    fwidth = interpolate.interp1d(m, n)
    width_interped[indices[0]:indices[len(indices) - 1]] = fwidth(
        flowline[indices[0]:indices[len(indices) - 1], 0])
    for i in range(0, indices[0]):
        width_interped[i] = width_interped[indices[0]]
    for i in range(indices[len(indices) - 1], R):
        width_interped[i] = width_interped[indices[len(indices) - 2]]

    print "Filtering with a butterworth filter with a cutoff of", filt_len, "m"
    cutoff = (1 / filt_len) / (1 / (np.diff(flowline[1:3, 0]) * 2))
    b, a = signal.butter(4, cutoff, btype='low')
    width_filtered = signal.filtfilt(b, a, width_interped)

    return width_filtered
Example #7
0
def load_grid(glacier,xmin,xmax,ymin,ymax,dx,ice=0,icefront_time='none',icefront_type='all'):

  '''
  Load ice mask grid.
  
  x,y,mask = load_grid(glacier,xmin,xmax,ymin,ymax,dx,ice=0,icefront_time='none')
  
  Inputs:
  glacier: glacier name
  xmin,xmax,ymin,ymax: output dimensions for grid
  dx: grid spacing
  ice: set ice grid points to 0 or 1
  icefront_time: sometimes we will want the fjord to be part of the mask, so 
  	this option also masks the fjord according to the ice front for the given time
  
  
  Outputs:
  x,y: grid points
  mask: mask grid of 0,1's 
  '''

  # Directory for holes for mask
  DIR = os.path.join(os.getenv("DATA_HOME"),'ShapeFiles/IceMasks/'+glacier+'/')
  files = os.listdir(DIR)
  
  # Set up grid
  nx = int(np.ceil((xmax-xmin)/dx))+1
  x = np.linspace(xmin,xmin+dx*(nx-1),nx)
  ny = int(np.ceil((ymax-ymin)/dx))+1
  y = np.linspace(ymin,ymin+dx*(ny-1),ny)
  
  if ice == 1:
    mask = np.ones([ny,nx])
  else: 
    mask = np.zeros([ny,nx])
  xgrid,ygrid = np.meshgrid(x,y)
  
  xflatten = xgrid.flatten()
  yflatten = ygrid.flatten()
  points = np.column_stack([xflatten,yflatten])
  maskflatten = mask.flatten()
  
  for file in files:
    if file.endswith('.shp') and 'hole' in file:
      hole = meshlib.shp_to_xy(DIR+file)
      holepath = path.Path(hole[:,0:2])
      cond = holepath.contains_points(points)
      ind = np.where(cond==True)[0]
      if ice == 1:
        maskflatten[ind]=0
      else: 
        maskflatten[ind]=1
 
  # If we want to mask out icefree fjord
  if icefront_time !='none':
    xfjord = []
    yfjord = []
    xfront,yfront,time = icefrontlib.near_time(icefront_time,glacier,type=icefront_type)
    south = meshlib.shp_to_xy(DIR+'icemask_southfjordwall.shp')
    north = meshlib.shp_to_xy(DIR+'icemask_northfjordwall.shp')
    if north[0,1] > north[-1,0]:
      north = np.flipud(north)
    if south[0,1] < south[-1,0]:
      south = np.flipud(south) 
    if yfront[0] > yfront[-1]:
      xfront = np.flipud(xfront)
      yfront = np.flipud(yfront)  
    xfjord = xfront
    yfjord = yfront
    nind = np.argmin((xfront[-1]-north[:,0])**2+(yfront[-1]-north[:,1])**2)
    xfjord = np.r_[xfjord,north[nind:,0]]
    yfjord = np.r_[yfjord,north[nind:,1]]
    sind = np.argmin((xfront[0]-south[:,0])**2+(yfront[0]-south[:,1])**2)
    xfjord = np.r_[xfjord,south[0:sind+1,0]]
    yfjord = np.r_[yfjord,south[0:sind+1,1]]
    fjordpath = path.Path(np.column_stack([xfjord,yfjord]))
    cond = fjordpath.contains_points(points)
    ind = np.where(cond==True)[0] 
    if ice == 1:
      maskflatten[ind]=0
    else: 
      maskflatten[ind]=1
          
  mask = np.reshape(maskflatten,[ny,nx])    

  return x,y,mask
Example #8
0
parser.add_argument("-mesh",dest="mesh",required = True,
                help = "Mesh directory name.")

args, _ = parser.parse_known_args(sys.argv)
glacier = args.glacier
mesh = args.mesh

# Directory
DIR = os.path.join(os.getenv("MODEL_HOME"),glacier+"/3D/"+mesh)

###############################
# Load shapefiles for regions #
###############################

if glacier == 'Helheim':
    extent_region_U = meshlib.shp_to_xy(os.path.join(os.getenv("DATA_HOME"),\
          "ShapeFiles/Glaciers/3D/"+glacier+"/glacier_region1.shp"))
    extent_region_U = np.row_stack([extent_region_U,extent_region_U[0,:]])

    extent_region_M = meshlib.shp_to_xy(os.path.join(os.getenv("DATA_HOME"),\
                    "ShapeFiles/Glaciers/3D/"+glacier+"/glacier_region5.shp"))
    extent_region_M = np.row_stack([extent_region_M,extent_region_M[0,:]])

    extent_region_L = meshlib.shp_to_xy(os.path.join(os.getenv("DATA_HOME"),\
          "ShapeFiles/Glaciers/3D/"+glacier+"/glacier_region2.shp"))
    extent_region_L = np.row_stack([extent_region_L,extent_region_L[0,:]])
  
    extent_region_S1 = meshlib.shp_to_xy(os.path.join(os.getenv("DATA_HOME"),\
          "ShapeFiles/Glaciers/3D/"+glacier+"/glacier_region3.shp"))
    extent_region_S1 = np.row_stack([extent_region_S1,extent_region_S1[0,:]])
  
    extent_region_S2 = meshlib.shp_to_xy(os.path.join(os.getenv("DATA_HOME"),\
Example #9
0
                                       nofront_shapefile=meshshp)
elif meshshp.endswith('_front') or meshshp.endswith('_front.shp'):
    if timeseries == True:
        if meshshp.endswith('.shp'):
            meshshp_nofront = meshshp[0:-9] + 'nofront.shp'
        else:
            meshshp_nofront = meshshp[0:-5] + 'nofront.shp'
        if len(date2) < 8:
            sys.exit(
                "Need an end date (-d2) to calculate a timeseries of meshes.")
        time2 = datelib.date_to_fracyear(int(date2[0:4]), int(date2[4:6]),
                                         int(date2[6:8]))
        print "Calculating timeseries of meshes from " + date1 + " to " + date2
        times, xextents, yextents, bounds, icefronts_x, icefronts_y, icefronts_advance = glaclib.load_extent_timeseries(
            glacier, time1, time2, dt, nofront_shapefile=meshshp_nofront)
    exterior = meshlib.shp_to_xy(DIRX + meshshp)
else:
    exterior = meshlib.shp_to_xy(DIRX + meshshp)
np.savetxt(inputs + "mesh_extent.dat", exterior[:, 0:2])

if timeseries == True:
    np.savetxt(inputs + "mesh_timeseries_x.dat", xextents)
    np.savetxt(inputs + "mesh_timeseries_y.dat", yextents)
    np.savetxt(inputs + "mesh_timeseries_times.dat", times)

# Mesh holes
holes = []
if os.path.isfile(DIRX + "glacier_hole1.shp"):
    hole1 = meshlib.shp_to_xy(DIRX + "glacier_hole1")
    np.savetxt(inputs + "mesh_hole1.dat", hole1[:, 0:2])
    holes.append({'xy': hole1})