Example #1
0
def width(time1, time2, glacier, type='icefront', datatypes='all'):
    '''
  termt,termwidth = width(time1,time2,glacier,type='icefront')
  
  Calculate calving-front width (i.e., integrate distances along ice front).
  
  Inputs:
  time1,time2: load terminus positions from time1 to time2
  glacier: glacier name
  type: icefront or rift
  
  Outputs:
  termwidth: width of calving front at termt
  '''

    # Load desired values for "glacier"
    termx, termy, termt = load_all(time1,
                                   time2,
                                   glacier,
                                   type='icefront',
                                   datatypes=datatypes)

    # Calculate width for each time
    termwidth = np.zeros(len(termt))
    for i in range(0, len(termt)):
        dists = distlib.transect(termx[:, i], termy[:, i])
        termwidth[i] = np.nanmax(dists)

    return termt, termwidth
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
        sortind = (np.argsort(cut_cresis[:, 1]))
        cut_cresis = cut_cresis[sortind, :]
        other = np.row_stack([cresis_all[0:ind1, :], cresis_all[ind2:-1, :]])
    else:
        cut_cresis = cresis_all[ind2:ind1, :]
        sortind = (np.argsort(cut_cresis[:, 1]))
        cut_cresis = cut_cresis[sortind, :]
        other = np.row_stack([cresis_all[0:ind2, :], cresis_all[ind1:-1, :]])

    # Distances along transect
    xtemp = np.append(cut_cresis[:, 0], [addons[j][0], addons[j][2]])
    ytemp = np.append(cut_cresis[:, 1], [addons[j][1], addons[j][3]])
    sortind = ((np.argsort(ytemp)))
    xtemp = xtemp[sortind]
    ytemp = ytemp[sortind]
    dtemp = distlib.transect(xtemp, ytemp)
    dists = dtemp[1:-1]

    # Get morlighem bed
    cut_dMor = np.linspace(0, dtemp[-1], dtemp[-1] / 150.0)
    cut_xMor = np.interp(cut_dMor, dtemp, xtemp)
    cut_yMor = np.interp(cut_dMor, dtemp, ytemp)
    cut_zMor = bedlib.morlighem_pts(cut_xMor, cut_yMor, glacier, 'geoid')
    cut_cresis_grid = bedlib.cresis_grid_pts(cut_xMor, cut_yMor, glacier,
                                             'geoid')
    del xtemp, ytemp, dtemp

    # Get 2001 Cresis point
    mindist = 100.0
    for i in range(0, len(cut_cresis)):
        pdist = np.min(
import matplotlib.pyplot as plt

##########
# Inputs #
##########
time1=2009
time2=2015

#############
# Load data #
#############

# Load Helheim bed
bed = bedlib.cresis('2001')
bed = bed[17:,:] #throw out points that don't follow a flowline
dists = distlib.transect(bed[:,0],bed[:,1])-5165 # Last value to offset distances so similar zero point as that in "velocity_vs_terminus"

# Terminus positions
term, termt = icefrontlib.distance_along_flowline(bed[:,0],bed[:,1],dists,'icefront')
rift, riftt = icefrontlib.distance_along_flowline(bed[:,0],bed[:,1],dists,'rift')

# Load elevations
elev,elevt = zslib.worldview_at_pts(bed[:,0],bed[:,1],32,[])

# Calculate divergence
v,vx,vy,divx,divy,vt = vellib.divergence_at_eulpoints(bed[:,0],bed[:,1])
indices = np.where((vt > time1) & (vt < time2))
v=v[indices[0],:]
vx=vx[indices[0],:]
vy=vy[indices[0],:]
divx=divx[indices[0],:]
Example #7
0
def fluxbox_geometry(glacier, fluxgate_filename):
    '''
  Find the geometry of the fluxbox by combining the shapefiles for the fluxgates and for the glacier 
  extent.
  '''

    # Get Shapefiles for flux gates and for glacier extent (so we can calculate surface area accurately)
    DIR = os.path.join(os.getenv("DATA_HOME"),
                       "ShapeFiles/FluxGates/" + glacier + "/")
    gate_in_sf = shapefile.Reader(DIR + fluxgate_filename + "_in")
    gate_out_sf = shapefile.Reader(DIR + fluxgate_filename + "_out")

    # Glacier extent shapefile
    glacier_extent = masklib.load_points(glacier)
    #glacier_extent = meshlib..shp_to_xy(os.path.join(os.getenv("DATA_HOME"),
    #		"ShapeFiles/Glaciers/3D/"+glacier+"/glacier_extent_normal"))
    #if glacier == 'Helheim':
    #  glacier_hole1 = meshlib..shp_to_xy(os.path.join(os.getenv("DATA_HOME"),
    #  	"ShapeFiles/Glaciers/3D/Helheim/glacier_hole1"))
    #  glacier_hole2 = meshlib..shp_to_xy(os.path.join(os.getenv("DATA_HOME"),
    #  	"ShapeFiles/Glaciers/3D/Helheim/glacier_hole2"))
    #  glacier_extent = np.row_stack([glacier_extent,glacier_hole1,glacier_hole2])

    # Get end points for flux gates
    gate_in_pts = np.array(gate_in_sf.shapes()[0].points)
    if gate_in_pts[-1, 1] < gate_in_pts[0, 1]:
        gate_in_pts = np.flipud(gate_in_pts)
    gate_out_pts = np.array(gate_out_sf.shapes()[0].points)
    if gate_out_pts[-1, 1] < gate_out_pts[0, 1]:
        gate_out_pts = np.flipud(gate_out_pts)

        # Calculate length of flux gates (i.e., the "width" of glacier)
    L_in = distlib.transect(gate_in_pts[:, 0], gate_in_pts[:, 1])
    L_out = distlib.transect(gate_out_pts[:, 0], gate_out_pts[:, 1])

    dl = 50.

    # Get coordinates of points along upstream flux gate
    l_in = np.linspace(0, L_in[-1], np.ceil(L_in[-1] / dl) + 1)
    dl_in = l_in[1] - l_in[0]
    l_in = l_in[0:-1] + dl_in / 2
    x_in = np.interp(l_in, L_in, gate_in_pts[:, 0])
    y_in = np.interp(l_in, L_in, gate_in_pts[:, 1])

    # Get coordinates of points along downstream flux gate
    l_out = np.linspace(0, L_out[-1], np.ceil(L_out[-1] / dl) + 1)
    dl_out = l_out[1] - l_out[0]
    l_out = l_out[0:-1] + dl_out / 2
    x_out = np.interp(l_out, L_out, gate_out_pts[:, 0])
    y_out = np.interp(l_out, L_out, gate_out_pts[:, 1])

    gate_in_pts = np.column_stack([x_in, y_in])
    gate_out_pts = np.column_stack([x_out, y_out])

    del l_out, l_in, dl_in, dl_out, x_in, x_out, y_in, y_out

    # Find glacier geometry (i.e., points in glacier extent) that lie between the flux gates,
    # so we can calculate glacier area.

    fluxbox_x = []  # boundary points for area between flux gates
    fluxbox_x.append(gate_in_pts[:, 0].T.tolist())
    fluxbox_y = []
    fluxbox_y.append(gate_in_pts[:, 1].T.tolist())
    for i in [0, -1]:
        ind_in = np.argmin((gate_in_pts[i, 0] - glacier_extent[:, 0])**2 +
                           (gate_in_pts[i, -1] - glacier_extent[:, 1])**
                           2)  # get closest index
        ind_out = np.argmin((gate_out_pts[i, 0] - glacier_extent[:, 0])**2 +
                            (gate_out_pts[i, -1] - glacier_extent[:, 1])**
                            2)  # get closest index

        # Check to make sure we didn't grab a point outside the flux box
        # The x-value of glacier extent near the upstream flux gate needs to be greater than the
        # x-value of the flux gate to be in the box. Check to see if it's smaller and if so correct it.
        if gate_in_pts[i, 0] > glacier_extent[ind_in, 0]:
            if gate_in_pts[i, 0] < glacier_extent[ind_in - 1, 0]:
                ind_in = ind_in - 1
            else:
                ind_in = ind_in + 1
        # The opposite is true for the downstream gate.
        if gate_out_pts[i, 0] < glacier_extent[ind_out, 0]:
            if gate_out_pts[i, 0] > glacier_extent[ind_out - 1, 0]:
                ind_out = ind_out - 1
            else:
                ind_out = ind_out + 1

        # Add points from glacier extent to flux box
        if ind_in < ind_out:
            fluxbox_x.append(glacier_extent[ind_in:ind_out + 1, 0].tolist())
            fluxbox_y.append(glacier_extent[ind_in:ind_out + 1, 1].tolist())
        else:
            fluxbox_x.append(glacier_extent[ind_out:ind_in + 1, 0].tolist())
            fluxbox_y.append(glacier_extent[ind_out:ind_in + 1, 1].tolist())
    fluxbox_x.append(gate_out_pts[:, 0].T.tolist())
    fluxbox_y.append(gate_out_pts[:, 1].T.tolist())
    fluxbox_x = sum(fluxbox_x, [])
    fluxbox_y = sum(fluxbox_y, [])
    fluxbox_x, fluxbox_y = coordlib.sort_xy(fluxbox_x, fluxbox_y)
    fluxbox_x.append(fluxbox_x[0])
    fluxbox_y.append(fluxbox_y[0])

    return fluxbox_x, fluxbox_y
Example #8
0
def fluxgate(glacier,
             fluxgate_filename,
             bedsource='smith',
             dl=20.0,
             timing='velocity'):
    '''
  
  time, sumQ, Hbar, ubar, error = fluxgate(glacier,fluxgate_filename,bedsource='smith',dl=20.0,timing='velocity')
  
  Inputs:
  glacier: glacier name
  fluxgate_filename: fluxgate filename
  bedsource: should be use CreSIS radar transects or morlighem/smith bed DEM to define the bed elevation?
  dl: size of blocks for integrating ice flux across fluxgate
  timing: calculate flux either when we have velocities ('velocity') or surface elevaions ('elevation')
  '''

    # Get Shapefiles for flux gates and for glacier extent (so we can calculate surface area accurately)
    DIR = os.path.join(os.getenv("DATA_HOME"),
                       "ShapeFiles/FluxGates/" + glacier + "/")
    gate_sf = shapefile.Reader(DIR + fluxgate_filename)

    # Get end points for flux gates
    gate_pts = np.array(gate_sf.shapes()[0].points)
    sortind = np.argsort(gate_pts[:, 1])
    gate_pts = gate_pts[sortind]

    # Calculate length of flux gates (i.e., the "width" of glacier)
    L = distlib.transect(gate_pts[:, 0], gate_pts[:, 1])

    # Get coordinates of points along flux gate
    l = np.linspace(0, L[-1], np.ceil(L[-1] / dl) + 1)
    dl = l[1] - l[0]
    l = l[0:-1] + dl / 2
    x = np.interp(l, L, gate_pts[:, 0])
    y = np.interp(l, L, gate_pts[:, 1])

    # Get surface elevations
    if glacier == 'Midgaard' or glacier == 'Fenris':
        zs_gimp = zslib.gimp_at_pts(x, y, glacier, verticaldatum='ellipsoid')
        zs_error = np.zeros_like(zs_gimp)
        halfind = int(len(x) / 2)  # Index for halfway along fluxgate
        zpt_atm, zptstd_atm, time_atm = zslib.atm_at_pts(
            [x[halfind]], [y[halfind]],
            glacier,
            maxdist=200,
            verticaldatum='ellipsoid')

        #zs_all = zs_gimp
        #ztime = []
        ztime = time_atm
        zs_all = np.zeros([len(time_atm), len(x)])
        for i in range(0, len(time_atm)):
            diff = zpt_atm[i] - zs_gimp[halfind]
            zs_all[i, :] = zs_gimp + diff
    else:
        zs_all, zs_error, ztime = zslib.dem_at_pts(x,
                                                   y,
                                                   glacier,
                                                   verticaldatum='ellipsoid',
                                                   method='linear')

    # Get bed elevation along flux gates
    if bedsource == 'morlighem':
        print "Using Morlighem bed DEM, should maybe be changed to CreSIS radar transects or Smith bed DEM"
        zb = bedlib.morlighem_pts(x, y, verticaldatum='ellipsoid')
        if glacier == 'Midgaard':
            # The Morlighem bed DEM is HORRIBLE for Midgaard. If it was right, the surface would
            # currently be below the bed. Unfortunately there aren't any better options (very few
            # ice thickness measurements), so what I'm doing is adjusting the morlighem bed DEM
            # by a known ice thickness measurements from ~1 km downstream, which has the ice thickness
            # at 110 m in 2013 with a surface elevation of 253 m.
            zpt_2013 = np.interp(2013.25, time_atm, zpt_atm[:, 0])
            diff = (zpt_2013 - 150) - zb[halfind]
            zb = zb + diff
    elif bedsource == 'smith':
        print "Using Smith bed DEM"
        zb = bedlib.smith_at_pts(x, y, glacier, verticaldatum='ellipsoid')
    else:
        print "Using CreSIS radar products"
        cresis_all = bedlib.cresis('all', glacier, verticaldatum='ellipsoid')

        # Find radar pick indices for flux gate
        zb = np.zeros_like(x)
        # Find points that are within 200~m of CreSIS transect for interpolation
        ind = []
        for i in range(0, len(x)):
            d = np.min(
                np.sqrt((x[i] - cresis_all[:, 0])**2 +
                        (y[i] - cresis_all[:, 1])**2))
            if d < 200.0:
                ind.append(i)
        zb[ind] = scipy.interpolate.griddata(cresis_all[:, 0:2], cresis_all[:,
                                                                            2],
                                             (x[ind], y[ind]))
        f = scipy.interpolate.interp1d(l[ind],
                                       zb[ind],
                                       kind='cubic',
                                       bounds_error=False)
        fex = extrap1d(f)
        zb[zb == 0] = fex(l[zb == 0])
        filt_len = 500.0
        cutoff = (1 / filt_len) / (1 / ((l[1] - l[0]) * 2))
        b, a = scipy.signal.butter(4, cutoff, btype='low')
        zb = scipy.signal.filtfilt(b, a, zb)

    # Get velocities
    if glacier == 'Fenris':
        vpt, tpt, ept, vxpt, vypt = vellib.howat_optical_at_pts(
            x, y, 'Helheim', xy_velocities='True')
        tpt = tpt[:, 0]
    else:
        vpt, tpt, ept, vxpt, vypt = vellib.velocity_at_eulpoints(
            x, y, glacier, data='TSX', xy_velocities='True')

    # Get normal to fluxgate so we can calculate flux through it
    xperp = np.zeros(len(l))
    yperp = np.zeros(len(l))
    for i in range(0, len(l) - 1):
        xperp[i + 1] = -(-y[i + 1] + y[i]) / np.sqrt((y[i + 1] - y[i])**2 +
                                                     (x[i + 1] - x[i])**2)
        yperp[i + 1] = -(x[i + 1] - x[i]) / np.sqrt((y[i + 1] - y[i])**2 +
                                                    (x[i + 1] - x[i])**2)
    xperp[0] = xperp[1]
    yperp[0] = yperp[1]

    # Find dates with complete velocity profiles. We will use these profiles to create a
    # "shape factor" to fill in discontinuous velocity records.
    ind = []
    for i in range(0, len(tpt)):
        nans = np.where(np.isnan(vxpt[i, :]))[0]
        if len(nans) < 1:
            ind.append(i)
    if len(ind) < 1:
        ind = range(0, len(tpt))

    # Velocity shape factor
    sf = np.nanmean(
        abs(xperp * vxpt[ind, :] + yperp * vypt[ind, :]), 0) / np.nanmax(
            np.nanmean(abs(xperp * vxpt[ind, :] + yperp * vypt[ind, :]), 0))
    vperp = (xperp * vxpt + yperp * vypt)
    vperp[:, 0] = sf[0] * np.nanmax(vperp, 1)
    vperp[:, -1] = sf[-1] * np.nanmax(vperp, 1)
    ind = np.where(vperp < 0)
    vperp[ind] = 0.0

    midind = np.argmax(np.nanmean(vperp, axis=0))

    if timing == 'velocity':
        # Find DEMs where more than 90% of the data points are nonnan.
        if len(ztime) > 0:
            ind_DEM = []
            for i in range(0, len(ztime)):
                nonnan = np.where(~(np.isnan(zs_all[i, :])))[0]
                if len(nonnan) > (9. / 10.) * len(l):
                    ind_DEM.append(i)

        Q = np.zeros_like(vperp)  # actual fluxes
        Q[:, :] = float('nan')
        allH = np.zeros_like(vperp)  # actual fluxes
        allH[:, :] = float('nan')
        allU = np.zeros_like(vperp)  # actual fluxes
        allU[:, :] = float('nan')
        time = tpt
        error = np.zeros_like(time)
        error[:] = float('nan')
        ubar = np.zeros_like(time)
        ubar[:] = float('NaN')
        width = np.zeros_like(time)
        width[:] = float('NaN')
        Hbar = np.zeros([len(time), 2])
        Hbar[:, :] = float('NaN')
        Across = np.zeros_like(time)
        Across[:] = float('nan')
        for i in range(0, len(time)):
            # Find places where we have no surface velocities
            nans_vperp = np.where(np.isnan(vperp[i, :]))[0]
            if len(nans_vperp) < 1.0 / 3.0 * len(l):
                # If the number of locations without surface velocities is small, let's use the known
                # surface velocities to interpolate.
                nonnans_vperp = np.where(~(np.isnan(vperp[i, :])))[0]
                vperp_errors = np.zeros(len(l))

                if len(ztime) > 0:
                    # Get surface elevation for that timestep
                    zs = np.zeros(len(l))
                    zs_error_ind = np.zeros(len(l))

                    # Linearly interpolate surface elevations from the available ones.
                    zs = np.zeros_like(l)
                    for j in range(0, len(zs)):
                        nonnan = np.where(~(np.isnan(zs_all[ind_DEM, j])))[0]
                        newind = [ind_DEM[k] for k in nonnan]
                        zs[j] = np.interp(tpt[i], ztime[newind], zs_all[newind,
                                                                        j])
                else:
                    zs = zs_all

                zs_error_ind = zs_error

                # Interpolate surface velocities using a shape factor for the
                # cross-sectional velocity profile
                f = np.arange(
                    np.nanmin(np.nanmax(vperp[:, :], axis=1)) - 500,
                    np.nanmax(np.nanmax(vperp[:, :], axis=1)) + 500, 10)
                mindiff = 1e20
                for j in range(0, len(f)):
                    diff = np.sqrt(
                        np.mean(sf[nonnans_vperp] * f[j] -
                                vperp[i, nonnans_vperp])**2)
                    if diff < mindiff:
                        mindiff = float(diff)
                        fbest = int(j)
                vperp[i, nans_vperp] = sf[nans_vperp] * f[fbest]

                # Set velocity errors
                vperp_errors[nonnans_vperp] = vperp[i, nonnans_vperp] * 0.03
                vperp_errors[nans_vperp] = vperp[i, nans_vperp] * 0.1

                # Let's try filtering data before calculating ice flux
                filt_len = 300.

                cutoff = (1 / filt_len) / (1 / (np.diff(l[1:3]) * 2))
                b, a = scipy.signal.butter(4, cutoff, btype='low')
                zs_filt = scipy.signal.filtfilt(b, a, zs)
                vperp_filt = scipy.signal.filtfilt(b, a, vperp[i, :])

                # Calculate fluxes, only where zs > zb
                Q[i, :] = 0.0
                ind = np.where((zs_filt - zb > 0) & (vperp_filt > 0))[0]
                Q[i, ind] = ((vperp_filt[ind]) * (zs_filt[ind] - zb[ind]) * dl)

                # Get average surface elevations and ice flow velocities for fluxgate
                sf_flux = Q[i, :] / np.nanmax(Q[i, :])
                #Hbar[i,0] = np.nansum(sf_flux*(zs_filt-zb))/np.sum(sf_flux)
                Hbar[i, 0] = np.mean(zs_filt[midind - 200:midind + 201] -
                                     zb[midind - 200:midind + 201])
                Hbar[i, 1] = np.mean(zs_error_ind[midind - 200:midind +
                                                  201]) / np.sqrt(2000. / 300.)
                ubar[i] = np.mean(vperp_filt[midind - 200:midind + 201])
                #ubar[i] = np.nansum(sf_flux*(vperp_filt))/np.sum(sf_flux)
                Across[i] = np.sum((zs_filt[ind] - zb[ind]) * dl)

                allH[i, ind] = zs_filt[ind] - zb[ind]
                allU[i, ind] = (vperp_filt[ind])

                # Calculate errors
                ubar_error = np.sqrt(1 / (np.sum(
                    np.mean(1 / vperp_errors)**2 * np.ones(int(L[1] / 500.)))))
                hbar_error = np.sqrt(1 / (np.sum(
                    np.mean(1 / zs_error_ind)**2 * np.ones(int(L[1] / 32.)))))
                error[i] = np.sum(
                    Q[i, :]) * np.sqrt((ubar_error / ubar[i])**2 +
                                       (hbar_error / Hbar[i, 0])**2)

    elif timing == 'elevation':
        time = ztime
        Q = np.zeros([len(time), len(l)])  # actual fluxes
        Q[:, :] = float('NaN')
        error = np.zeros_like(time)
        error[:] = float('nan')
        ubar = np.zeros_like(time)
        ubar[:] = float('NaN')
        Hbar = np.zeros([len(time), 2])
        Hbar[:, :] = float('NaN')
        Across = np.zeros_like(time)
        Across[:] = float('nan')
        for i in range(0, len(time)):
            nonnans = np.where(~(np.isnan(zs_all[i, :])))[0]
            nans = np.where((np.isnan(zs_all[i, :])))[0]
            if len(nonnans) > (9. / 10) * len(l):
                zs_ind = zs_all[i, :]
                zs_ind[nans] = np.interp(l[nans], l[nonnans], zs_all[i,
                                                                     nonnans])
                ind = np.argmin(abs(time[i] - tpt))
                if (time[i] - tpt[ind]) < 1 / 12.:
                    nonnans = np.where(~(np.isnan(vperp[ind, :])))[0]
                    nans = np.where(np.isnan(vperp[ind, :]))[0]

                    vperp_ind = vperp[ind, :]
                    vperp_ind[nans] = sf[nans] * np.nanmax(vperp[i, :])  #

                    # Calculate fluxes
                    Q[i, :] = (vperp_ind * (zs_ind - zb) * dl)

                    # We don't want negative fluxes so let's toss them out.
                    Q[i, zs_ind < zb] = 0

                    # Get average surface elevations and ice flow velocities for fluxgate
                    ind = np.where(zs_ind - zb > 0)[0]
                    Hbar[i, 0] = np.mean(zs_ind[midind - 200:midind + 201] -
                                         zb[midind - 200:midind + 201])
                    Hbar[i, 1] = zs_error[i] / np.sqrt(2000. / 200.)
                    ubar[i] = np.mean(vperp_ind[midind - 200:midind + 201])
                    Across[i] = np.sum((zs_ind[ind] - zb[ind]) * dl)

    # Add up fluxes along glacier width
    sumQ = np.sum(Q, 1)

    return time, sumQ, Hbar, ubar, error, L[1]
Example #9
0
surf = np.zeros_like(xdata)
bed = np.zeros_like(xdata)
height = np.zeros_like(xdata)
ndata = np.zeros_like(tempdata[:, 0])
elevation = np.zeros_like(tempdata[:, 0])
for i in range(0, len(xdata)):
    colinds = np.array(np.where(tempdata[:, 0] == xdata[i]))
    surf[i] = np.max(tempdata[colinds, 2])  # Surface elevation
    bed[i] = np.min(tempdata[colinds, 2])  # Bed elevation
    height[i] = surf[i] - bed[i]  #height
    elevation[colinds] = tempdata[colinds, 2]
    ndata[colinds] = (tempdata[colinds, 2] -
                      bed[i]) / height[i]  #normalized value

# Compute distance along Kristin's temperature profile
ddata = distlib.transect(tempdata[:, 0], tempdata[:, 1])

# Compute distance between our flowline and Kristin's, so that we can adjust
# the distance in Kristin's temperature profile so that it aligns
dist1 = np.sqrt((xdata[0] - flowline[0, 1])**2 +
                (ydata[0] - flowline[0, 2])**2)
dist2 = np.sqrt((xdata[1] - flowline[0, 1])**2 +
                (ydata[1] - flowline[0, 2])**2)
ddata = ddata - ddata[200] * (dist1 / (dist1 + dist2)) + flowline[0, 0]

# Write out depths for flowline so that we can use those depths for interpolation
pts = np.zeros([len(flowline[:, 0]) * layers * 2, 3])
for i in range(0, len(flowline[:, 0])):
    pts[layers * 2 * i:layers * 2 * (i + 1), 0] = flowline[i, 0]
    pts[layers * 2 * i:layers * 2 * (i + 1), 1] = np.linspace(0, 1, layers * 2)
    pts[layers * 2 * i:layers * 2 * (i + 1),