All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ucar.unidata.geoloc.vertical.OceanSG1 Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 1998-2018 University Corporation for Atmospheric Research/Unidata
 * See LICENSE for license information.
 */

package ucar.unidata.geoloc.vertical;


import ucar.ma2.*;
import ucar.nc2.*;
import ucar.nc2.constants.CDM;
import ucar.unidata.util.Parameter;
import java.io.IOException;
import java.util.List;


/**
 * Create a 3D height(z,y,x) array using the CF formula for
 * "ocean s vertical coordinate g1".
 * standard name: ocean_s_coordinate_g1
 * 
 * @author Sachin ([email protected])
 * @see http://cf-pcmdi.llnl.gov/
 * @see https://www.myroms.org/wiki/index.php/Vertical_S-coordinate#Metadata_Considerations
 */

public class OceanSG1 extends VerticalTransformImpl {

  /**
   * The eta variable name identifier
   */
  public static final String ETA = "Eta_variableName";

  /**
   * The "s" variable name identifier
   */
  public static final String S = "S_variableName";

  /**
   * The "depth" variable name identifier
   */
  public static final String DEPTH = "Depth_variableName";

  /**
   * The "depth c" variable name identifier
   */
  public static final String DEPTH_C = "Depth_c_variableName";

  /**
   * The "C" variable name identifier
   */
  public static final String C = "c_variableName";
  /**
   * the values of depth_c
   */
  private double depth_c;

  /**
   * The eta, s, C and depth variables
   */
  private Variable etaVar, sVar, depthVar, cVar, depthCVar;


  /**
   * Create a new vertical transform for Ocean_S_coordinate_g1
   *
   * @param ds dataset
   * @param timeDim time dimension
   * @param params list of transformation Parameters
   */
  public OceanSG1(NetcdfFile ds, Dimension timeDim, List params) {

    super(timeDim);
    String etaName = getParameterStringValue(params, ETA);
    String sName = getParameterStringValue(params, S);
    String depthName = getParameterStringValue(params, DEPTH);
    String depthCName = getParameterStringValue(params, DEPTH_C);
    String cName = getParameterStringValue(params, C);

    etaVar = ds.findVariable(etaName);
    sVar = ds.findVariable(sName);
    depthVar = ds.findVariable(depthName);
    depthCVar = ds.findVariable(depthCName);
    cVar = ds.findVariable(cName);

    units = depthVar.findAttributeString(CDM.UNITS, "none");
  }

  /**
   * Get the 3D vertical coordinate array for this time step.
   *
   * @param timeIndex the time index. Ignored if !isTimeDependent().
   * @return vertical coordinate array
   * @throws java.io.IOException problem reading data
   * @throws ucar.ma2.InvalidRangeException _more_
   */
  public ArrayDouble.D3 getCoordinateArray(int timeIndex) throws IOException, InvalidRangeException {
    Array etaArray = readArray(etaVar, timeIndex);
    Array sArray = readArray(sVar, timeIndex);
    Array depthArray = readArray(depthVar, timeIndex);
    Array cArray = readArray(cVar, timeIndex);

    depth_c = depthCVar.readScalarDouble();

    return makeHeight(etaArray, sArray, depthArray, cArray, depth_c);
  }

  /**
   * Get the 1D vertical coordinate array for this time step and
   * the specified X,Y index for Lat-Lon point.
   *
   * @param timeIndex the time index. Ignored if !isTimeDependent().
   * @param xIndex the x index
   * @param yIndex the y index
   * @return vertical coordinate array
   * @throws java.io.IOException problem reading data
   * @throws ucar.ma2.InvalidRangeException _more_
   */
  public ArrayDouble.D1 getCoordinateArray1D(int timeIndex, int xIndex, int yIndex)
      throws IOException, InvalidRangeException {
    Array etaArray = readArray(etaVar, timeIndex);
    Array sArray = readArray(sVar, timeIndex);
    Array depthArray = readArray(depthVar, timeIndex);
    Array cArray = readArray(cVar, timeIndex);

    depth_c = depthCVar.readScalarDouble();



    return makeHeight1D(etaArray, sArray, depthArray, cArray, depth_c, xIndex, yIndex);
  }

  /**
   * Make height from the given data. 
* * height(x,y,z) = S(x,y,z) + eta(x,y) * (1 + S(x,y,z) / depth([n],x,y) ) * * where, * S(x,y,z) = depth_c*s(z) + (depth([n],x,y)-depth_c)*C(z) * / * * @param eta eta Array * @param s s Array * @param depth depth Array * @param c c Array * @param depth_c value of depth_c * @return height data */ private ArrayDouble.D3 makeHeight(Array eta, Array s, Array depth, Array c, double depth_c) { int nz = (int) s.getSize(); Index sIndex = s.getIndex(); Index cIndex = c.getIndex(); int[] shape2D = eta.getShape(); int ny = shape2D[0]; int nx = shape2D[1]; Index etaIndex = eta.getIndex(); Index depthIndex = depth.getIndex(); ArrayDouble.D3 height = new ArrayDouble.D3(nz, ny, nx); for (int z = 0; z < nz; z++) { double sz = s.getDouble(sIndex.set(z)); double cz = c.getDouble(cIndex.set(z)); double term1 = depth_c * sz; for (int y = 0; y < ny; y++) { for (int x = 0; x < nx; x++) { double fac1 = depth.getDouble(depthIndex.set(y, x)); double term2 = (fac1 - depth_c) * cz; double Sterm = term1 + term2; double term3 = eta.getDouble(etaIndex.set(y, x)); double term4 = 1 + Sterm / fac1; double hterm = Sterm + term3 * term4; height.set(z, y, x, hterm); } } } return height; } private ArrayDouble.D1 makeHeight1D(Array eta, Array s, Array depth, Array c, double depth_c, int x_index, int y_index) { int nz = (int) s.getSize(); Index sIndex = s.getIndex(); Index cIndex = c.getIndex(); Index etaIndex = eta.getIndex(); Index depthIndex = depth.getIndex(); ArrayDouble.D1 height = new ArrayDouble.D1(nz); for (int z = 0; z < nz; z++) { double sz = s.getDouble(sIndex.set(z)); double cz = c.getDouble(cIndex.set(z)); double term1 = depth_c * sz; double fac1 = depth.getDouble(depthIndex.set(y_index, x_index)); double term2 = (fac1 - depth_c) * cz; double Sterm = term1 + term2; double term3 = eta.getDouble(etaIndex.set(y_index, x_index)); double term4 = 1 + Sterm / fac1; double hterm = Sterm + term3 * term4; height.set(z, hterm); } return height; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy