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

ucar.nc2.iosp.fysat.FysatHeader Maven / Gradle / Ivy

Go to download

The NetCDF-Java Library is a Java interface to NetCDF files, as well as to many other types of scientific data formats.

There is a newer version: 4.3.22
Show newest version
// $Id:FysatHeader.java 63 2006-07-12 21:50:51Z edavis $
/*
 * Copyright 1997-2006 Unidata Program Center/University Corporation for
 * Atmospheric Research, P.O. Box 3000, Boulder, CO 80307,
 * [email protected].
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or (at
 * your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
 * General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, strlenwrite to the Free Software Foundation,
 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
package ucar.nc2.iosp.fysat;


import java.io.*;
import java.util.*;
import java.text.*;



import ucar.nc2.*;
import ucar.nc2.units.DateFormatter;
import ucar.nc2.constants._Coordinate;
import ucar.nc2.constants.AxisType;
import ucar.nc2.iosp.fysat.util.EndianByteBuffer;
 
import ucar.unidata.geoloc.*;
import ucar.unidata.geoloc.projection.LambertConformal;
import ucar.unidata.geoloc.projection.Stereographic;
import ucar.unidata.geoloc.projection.Mercator;
import ucar.unidata.geoloc.projection.LatLonProjection;
import ucar.unidata.io.RandomAccessFile;
import ucar.ma2.Array;
import ucar.ma2.DataType;
import ucar.unidata.util.Parameter;


/**
 * Netcdf header reading and writing for version 3 file format.
 * This is used by Fysatiosp.
 */

public final class FysatHeader {

  private boolean debug = false;
  private boolean debugPos = false;
  private boolean debugString = false;
  private boolean debugHeaderSize = false;
  private RandomAccessFile raf;
  private ucar.nc2.NetcdfFile ncfile;
  //private PrintStream out = System.out;
  static private org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(FysatHeader.class);
  int numrecs = 0; // number of records written
  int recsize = 0; // size of each record (padded)
  
  int recStart = 0; // where the record data starts
  
  int FY_AWX_PIB_LEN = 40;   // FY Satellite AWX product indentification block
//  int FY_AWX_LEN ;  // FY Satellite AWX product description block
//  int FY_AWX_HED_LEN ;  // FY Satellite AWX product header 
 
  
  double DEG_TO_RAD = 0.017453292;
  double EARTH_RAD_KMETERS = 6371.200;
  byte Z_DEFLATED = 8;
  byte DEF_WBITS = 15;
  private long actualSize;
  private long calcSize;
  protected int Z_type = 0;
  
 
  private AwxFileFirstHeader firstHeader;
  private AwxFileSecondHeader secondHeader;

  


   public boolean isValidFile( ucar.unidata.io.RandomAccessFile raf)
   {
    // first check the size of file
    try {
        this.actualSize = raf.length();
    }
    catch ( IOException e ){
        return( false );
    }
    //  second check the file name
    if(!((raf.getLocation().endsWith(".AWX")|| raf.getLocation().endsWith(".awx") )))
    {
    	return false;
    }
    // more serious checking
    try {
    	return this.readPIB( raf );// not FY Satellite AWX product file
    }
    catch ( IOException e )
    {
        return( false );
    }
   }

    /**
   * Read the header and populate the ncfile
   * @param raf
   * @throws IOException
   */
   boolean readPIB(RandomAccessFile raf ) throws IOException {
    
	this.firstHeader = new AwxFileFirstHeader();
	
	this.raf = raf;
    
    int pos = 0;
    raf.seek(pos);

    // gini header process
    byte[] buf = new byte[FY_AWX_PIB_LEN];
    int count = raf.read(buf);
    EndianByteBuffer byteBuffer = null;
    if(count == FY_AWX_PIB_LEN){
	    byteBuffer = new EndianByteBuffer(buf);  
	   
	    this.firstHeader.fillHeader(byteBuffer);
	    
	    // if big endian bytes, fill the head with BIG_ENDIAN instead; 
	    if(this.firstHeader.byteOrder != EndianByteBuffer.LITTLE_ENDIAN){
	    	byteBuffer = new EndianByteBuffer(buf, EndianByteBuffer.BIG_ENDIAN);
	    }
	    	
    }
    else{
    	return false;
    }
    
    if(!((this.firstHeader.fileName.endsWith(".AWX")|| this.firstHeader.fileName.endsWith(".awx") )
    	&& this.firstHeader.firstHeaderLength == FY_AWX_PIB_LEN))
    {
    	return false;
    }
    
    // skip the fills of the first record
  //  raf.seek(FY_AWX_PIB_LEN + this.firstHeader.fillSectionLength);    
    buf = new byte[this.firstHeader.secondHeaderLength];
    raf.read(buf);
    byteBuffer = new EndianByteBuffer(buf, this.firstHeader.byteOrder ); 
    switch(this.firstHeader.typeOfProduct){
    	case AwxFileFirstHeader.AWX_PRODUCT_TYPE_UNDEFINED:
    		throw new UnsupportedDatasetException();
    	case AwxFileFirstHeader.AWX_PRODUCT_TYPE_GEOSAT_IMAGE:
    		secondHeader = new AwxFileGeoSatelliteSecondHeader();
    		secondHeader.fillHeader(byteBuffer);
    		break;
    	case AwxFileFirstHeader.AWX_PRODUCT_TYPE_POLARSAT_IMAGE:
    		throw new UnsupportedDatasetException();
    		
    	case AwxFileFirstHeader.AWX_PRODUCT_TYPE_GRID:
    		secondHeader = new AwxFileGridProductSecondHeader();
    		secondHeader.fillHeader(byteBuffer);
    		
    		break;
    	case AwxFileFirstHeader.AWX_PRODUCT_TYPE_DISCREET:
    		throw new UnsupportedDatasetException();
    		
    	case AwxFileFirstHeader.AWX_PRODUCT_TYPE_GRAPH_ANALIYSIS:
    		throw new UnsupportedDatasetException();
    			
    }
    
    return true;
    
  }

  void read(RandomAccessFile raf, NetcdfFile ncfile) throws IOException {
    this.raf = raf;
    this.ncfile = ncfile;
    


    if((this.firstHeader == null) && (this.secondHeader == null)){
    	readPIB(raf );
    }
    
   // if (out != null) this.out = out;
    actualSize = raf.length();

 
    Attribute att ;
//    Attribute att = new Attribute( "Conventions", "AWX");
//    this.ncfile.addAttribute(null, att);	
	
	att = new Attribute( "version", this.firstHeader.version);
    this.ncfile.addAttribute(null, att);
    
	String vname;

    switch(this.firstHeader.typeOfProduct){
	
		case AwxFileFirstHeader.AWX_PRODUCT_TYPE_UNDEFINED:
			throw new UnsupportedDatasetException();
		case AwxFileFirstHeader.AWX_PRODUCT_TYPE_GEOSAT_IMAGE:
		{
			AwxFileGeoSatelliteSecondHeader geoSatelliteSecondHeader = (AwxFileGeoSatelliteSecondHeader)this.secondHeader;
			
			att = new Attribute( "satellite_name", geoSatelliteSecondHeader.satelliteName);			
		    this.ncfile.addAttribute(null, att);
		     
		    DateFormat dformat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
		    dformat.setTimeZone(java.util.TimeZone.getTimeZone("GMT"));
		    Calendar cal = Calendar.getInstance();
		    cal.set(geoSatelliteSecondHeader.year, 
		    		geoSatelliteSecondHeader.month - 1,
		    		geoSatelliteSecondHeader.day,
		    		geoSatelliteSecondHeader.hour,
		    		geoSatelliteSecondHeader.minute);
		    cal.setTimeZone(java.util.TimeZone.getTimeZone("GMT"));
		    String dstring = dformat.format(cal.getTime());		    
		    this.ncfile.addAttribute(null, new Attribute("time_coverage", dstring));		    
            int nz = 1;
		   	Dimension dimT  = new Dimension( "time", nz, true, false, false);
		    ncfile.addDimension( null, dimT);

            String timeCoordName = "time";
            Variable taxis = new Variable(ncfile, null, null, timeCoordName);
            taxis.setDataType(DataType.DOUBLE);
            taxis.setDimensions("time");
            taxis.addAttribute( new Attribute("long_name", "time since base date"));
            taxis.addAttribute( new Attribute(_Coordinate.AxisType, AxisType.Time.toString()));
            double [] tdata = new double[1];
            tdata[0] = cal.getTimeInMillis();
            Array dataA = Array.factory(DataType.DOUBLE.getPrimitiveClassType(), new int[] {1}, tdata);
            taxis.setCachedData( dataA, false);
            DateFormatter formatter = new DateFormatter();
            taxis.addAttribute( new Attribute("units", "msecs since "+formatter.toDateTimeStringISO(new Date(0))));
            ncfile.addVariable(null, taxis);
		    //  Get dimensions
		    Integer ni = new Integer(geoSatelliteSecondHeader.widthOfImage);
		    att = new Attribute( "NX", ni);
		    this.ncfile.addAttribute(null, att);	
		   
		    ni = new Integer(geoSatelliteSecondHeader.heightOfImage);
		    att = new Attribute( "NY", ni);
		    this.ncfile.addAttribute(null, att);

            vname = getGeoSatelliteProductName(geoSatelliteSecondHeader.channel);
		    if(vname == null)
		    	throw new UnsupportedDatasetException("Unsupported GeoSatellite Procuct Dataset");


		    // set projection attribute
		    // ? which projection
            ProjectionImpl projection = null;
            double dxKm = 0.0, dyKm = 0.0;
            short nv = geoSatelliteSecondHeader.flagOfProjection;
		    att = new Attribute( "ProjIndex", nv);
		    this.ncfile.addAttribute(null, att);
		    int proj = nv;
		    if( proj == 2) {
		        att = new Attribute( "ProjName", "MERCATOR");
                double lat0 = geoSatelliteSecondHeader.centerLatitudeOfProjection;
                double lon0 = geoSatelliteSecondHeader.centerLongitudeOfProjection;
                double par = geoSatelliteSecondHeader.standardLatitude1;
                dxKm = geoSatelliteSecondHeader.horizontalResolution;
                dyKm = geoSatelliteSecondHeader.verticalResolution;
                projection = new Mercator( lon0, par) ;
            } else if (proj == 1) {
		        att = new Attribute( "ProjName", "LAMBERT_CONFORNAL");
                double lat0 = geoSatelliteSecondHeader.centerLatitudeOfProjection;
                double lon0 = geoSatelliteSecondHeader.centerLongitudeOfProjection;
                double par1 = geoSatelliteSecondHeader.standardLatitude1;
                double par2 = geoSatelliteSecondHeader.standardLatitude2;
                dxKm = geoSatelliteSecondHeader.horizontalResolution/100;
                dyKm = geoSatelliteSecondHeader.verticalResolution/100;
                projection = new LambertConformal(lat0, lon0, par1, par2);
            } else if (proj == 3) {
		        att = new Attribute( "ProjName", "POLARSTEREOGRAPHIC");
                double latt =  geoSatelliteSecondHeader.centerLatitudeOfProjection;
                double lont = geoSatelliteSecondHeader.centerLongitudeOfProjection;
                double scale = (1. + Math.sin(DEG_TO_RAD*latt))/2.;
                dxKm = geoSatelliteSecondHeader.horizontalResolution;
                dyKm = geoSatelliteSecondHeader.verticalResolution;
                projection = new Stereographic(90.0,  lont,  scale);
            } else if (proj == 4) {
		        att = new Attribute( "ProjName", "LatLonProjection");
                projection = new LatLonProjection();
            }
		    this.ncfile.addAttribute(null, att);
		    
		    // coordinate transform variable
            if( proj != 4)  {

            }
		    //double dxKm = 0.0, dyKm = 0.0, latin, lonProjectionOrigin ;
		    
		    // deal with projection	  

		    
		    this.ncfile.addAttribute(null, new Attribute("channel", geoSatelliteSecondHeader.channel));
		    
		    this.ncfile.addAttribute(null, new Attribute("geospatial_lat_min", new Float(geoSatelliteSecondHeader.latitudeOfSouth)));
		    this.ncfile.addAttribute(null, new Attribute("geospatial_lat_max", new Float(geoSatelliteSecondHeader.latitudeOfNorth)));
		    this.ncfile.addAttribute(null, new Attribute("geospatial_lon_min", new Float(geoSatelliteSecondHeader.longitudeOfWest)));
		    this.ncfile.addAttribute(null, new Attribute("geospatial_lon_max", new Float(geoSatelliteSecondHeader.longitudeOfEast)));
		    this.ncfile.addAttribute(null, new Attribute("geospatial_vertical_min", new Float(0.0)));
		    this.ncfile.addAttribute(null, new Attribute("geospatial_vertical_max", new Float(0.0)));
		    
		    
		    this.ncfile.addAttribute(null, new Attribute("sample_ratio", geoSatelliteSecondHeader.sampleRatio));

	
	
		    att = new Attribute( "horizontal_resolution", geoSatelliteSecondHeader.horizontalResolution);
		    this.ncfile.addAttribute(null, att);
		    att = new Attribute( "vertical_resolution", geoSatelliteSecondHeader.verticalResolution);
		    this.ncfile.addAttribute(null, att);

		    
		    // only one data variable per awx file
		    
		    //  set vname and units according to grid feature

		    Variable var = new Variable( ncfile, ncfile.getRootGroup(), null, vname);
		    
		    var.addAttribute( new Attribute("long_name", vname)); 
	
		    // get dimensions
		    int velems;
		    boolean isRecord = false;
		    
		    
		    int nx = geoSatelliteSecondHeader.widthOfImage;
		    int ny = geoSatelliteSecondHeader.heightOfImage;

	
		    Dimension dimX  ;
		    Dimension dimY  ;

            if(proj != 4) {
                dimX  = new Dimension( "x", nx, true, false, false);
		        dimY  = new Dimension( "y", ny, true, false, false);
            } else {
                dimX  = new Dimension( "lon", nx, true, false, false);
		        dimY  = new Dimension( "lat", ny, true, false, false);
            }

            ncfile.addDimension( null, dimY);
		    ncfile.addDimension( null, dimX);
	
		    int byteAmountofData = 1;
		    velems = dimX.getLength() * dimY.getLength() * byteAmountofData;
		    ArrayList dims = new ArrayList();
		    dims.add(dimT);
		    dims.add(dimY);
		    dims.add(dimX);
		    
	
		    var.setDimensions(dims);
	
		    // data type
		    Class dataType = null;
		    switch(byteAmountofData){
		    case 1:
		    	var.setDataType( DataType.BYTE);
		    	dataType = DataType.BYTE.getPrimitiveClassType();
		    	break;
		    case 2:
		    	var.setDataType( DataType.SHORT);
		    	dataType = DataType.SHORT.getPrimitiveClassType();
		    	break;
		    case 4:
		    	var.setDataType( DataType.INT);
		    	dataType = DataType.INT.getPrimitiveClassType();
		    	break;
		    default:
		    	System.out.println("Unsupported Grid Procuct Dataset!");
		    	throw new UnsupportedDatasetException("Unsupported Grid Procuct Dataset");
		    			    
		    }
		    
		    var .addAttribute(new Attribute("coordinates", "Lon Lat"));
		    
		    var.addAttribute(new Attribute("_unsigned", "true"));
		    var.addAttribute(new Attribute("units", "percent"));
           // if(var.getDataType() == DataType.BYTE) {
           //     var.addAttribute(new Attribute("_missing_value", new Byte((byte)-1)));
           //     var.addAttribute( new Attribute("scale_factor", new Byte((byte)(1))));
           //     var.addAttribute( new Attribute("add_offset", new Byte((byte)(0))));
          //  } else {
                var.addAttribute(new Attribute("_missing_value", new Short((short)-1)));
                var.addAttribute( new Attribute("scale_factor", new Short((short)(1))));
                var.addAttribute( new Attribute("add_offset", new Short((short)(0))));
          //  }
		    
    	      // size and beginning data position in file
    	    int vsize = velems;
    	    long begin = this.firstHeader.recordsOfHeader * this.firstHeader.recoderLength ;
    	    if (debug) log.warn(" name= "+vname+" vsize="+vsize+" velems="+velems+" begin= "+begin+" isRecord="+isRecord+"\n");
    	    var.setSPobject( new Vinfo (vsize, begin, isRecord, nx, ny, dataType, this.firstHeader.byteOrder));
    	    String coordinates ;
            if(proj != 4) {
                coordinates = "x y time";
            } else {
                coordinates = "Lon Lat time";
            }

    	    var.addAttribute( new Attribute(_Coordinate.Axes, coordinates));
    	    
    	    ncfile.addVariable(ncfile.getRootGroup(), var);
    

//    	    if (debug) System.out.println("start at proj coord "+start);

    	    LatLonPointImpl startPnt = new LatLonPointImpl( geoSatelliteSecondHeader.latitudeOfNorth, geoSatelliteSecondHeader.longitudeOfWest);
    	    LatLonPointImpl endPnt = new LatLonPointImpl( geoSatelliteSecondHeader.latitudeOfSouth, geoSatelliteSecondHeader.longitudeOfEast);
    	    if (debug) System.out.println("start at geo coord :"+startPnt);
    	    
            if(proj != 4) {
                 // we have to project in order to find the origin
    	        ProjectionPointImpl start = (ProjectionPointImpl) projection.latLonToProj(
                        new LatLonPointImpl( geoSatelliteSecondHeader.latitudeOfSouth,
                                             geoSatelliteSecondHeader.longitudeOfWest));
                double startx = start.getX();
                double starty = start.getY();

                Variable xaxis = new Variable( ncfile, null, null, "x");
                xaxis.setDataType( DataType.DOUBLE);
                xaxis.setDimensions( "x");
                xaxis.addAttribute( new Attribute("long_name", "projection x coordinate"));
                xaxis.addAttribute( new Attribute("units", "km"));
                xaxis.addAttribute( new Attribute(_Coordinate.AxisType, "GeoX"));
                double[] data = new double[nx];
                if( proj == 2 ) {
                    double lon_1 = geoSatelliteSecondHeader.longitudeOfEast;
                    double lon_2 = geoSatelliteSecondHeader.longitudeOfWest;
                    if ( lon_1 < 0 ) lon_1 += 360.0;
                    if ( lon_2 < 0 ) lon_2 += 360.0;
                    double dx = (lon_1 - lon_2) /(nx-1);

                    for (int i = 0; i < data.length; i++) {
                      double ln = lon_2 + i * dx;
                      ProjectionPointImpl pt = (ProjectionPointImpl) projection.latLonToProj(
                              new LatLonPointImpl( geoSatelliteSecondHeader.latitudeOfSouth, ln));
                      data[i] = pt.getX();  // startx + i*dx;
                    }
                }
                else {
                    for (int i = 0; i < data.length; i++)
                      data[i] = startx + i*dxKm;
                }

                dataA = Array.factory(DataType.DOUBLE.getPrimitiveClassType(), new int[] {nx}, data);
                xaxis.setCachedData( dataA, false);
                ncfile.addVariable(null, xaxis);

                Variable yaxis = new Variable( ncfile, null, null, "y");
                yaxis.setDataType( DataType.DOUBLE);
                yaxis.setDimensions( "y");
                yaxis.addAttribute( new Attribute("long_name", "projection y coordinate"));
                yaxis.addAttribute( new Attribute("units", "km"));
                yaxis.addAttribute( new Attribute(_Coordinate.AxisType, "GeoY"));
                data = new double[ny];
                double endy = starty + dyKm * (data.length - 1); // apparently lat1,lon1 is always the lower ledt, but data is upper left
                double lat2 = geoSatelliteSecondHeader.latitudeOfNorth;
                double lat1 = geoSatelliteSecondHeader.latitudeOfSouth;
                if(proj == 2) {
                    double dy = (lat2 - lat1 ) / (ny-1);
                    for (int i = 0; i < data.length; i++) {
                      double la = lat2 - i*dy;
                      ProjectionPointImpl pt = (ProjectionPointImpl) projection.latLonToProj(
                              new LatLonPointImpl( la, geoSatelliteSecondHeader.longitudeOfWest));
                      data[i] = pt.getY();  //endyy - i*dy;
                    }
                }
                else {
                    for (int i = 0; i < data.length; i++)
                      data[i] = endy - i*dyKm;
                }
                dataA = Array.factory(DataType.DOUBLE.getPrimitiveClassType(), new int[] {ny}, data);
                yaxis.setCachedData( dataA, false);
                ncfile.addVariable(null, yaxis);

                // coordinate transform variable
                Variable ct = new Variable( ncfile, null, null, projection.getClassName());
                ct.setDataType( DataType.CHAR);
                ct.setDimensions( "");
                List params = projection.getProjectionParameters();
                for (int i = 0; i < params.size(); i++) {
                  Parameter p = (Parameter) params.get(i);
                  ct.addAttribute( new Attribute(p));
                }
                ct.addAttribute( new Attribute(_Coordinate.TransformType, "Projection"));
                ct.addAttribute( new Attribute(_Coordinate.Axes, "x, y"));
                // fake data
                dataA = Array.factory(DataType.CHAR.getPrimitiveClassType(), new int[] {});
                dataA.setChar(dataA.getIndex(), ' ');
                ct.setCachedData(dataA, false);

                ncfile.addVariable(null, ct);
                ncfile.addAttribute( null, new Attribute("Conventions", _Coordinate.Convention));
            } else {
                Variable yaxis = new Variable( ncfile, null, null, "lat");
                yaxis.setDataType( DataType.DOUBLE);
                yaxis.setDimensions( "lat");
                yaxis.addAttribute( new Attribute("long_name", "latitude"));
                yaxis.addAttribute( new Attribute("units", "degree"));
                yaxis.addAttribute( new Attribute(_Coordinate.AxisType, "Lat"));
                double[] data = new double[ny];

                double dy = (endPnt.getLatitude() - startPnt.getLatitude()) /(ny-1);
                for (int i = 0; i < data.length; i++) {
                  data[i] = startPnt.getLatitude() + i * dy; // starty + i*dy;
                }

                dataA = Array.factory(DataType.DOUBLE.getPrimitiveClassType(), new int[] {ny}, data);
                yaxis.setCachedData( dataA, false);
                ncfile.addVariable(null, yaxis);


             // create coordinate variables
                Variable xaxis = new Variable( ncfile, null, null, "lon");
                xaxis.setDataType( DataType.DOUBLE);
                xaxis.setDimensions( "lon");
                xaxis.addAttribute( new Attribute("long_name", "longitude"));
                xaxis.addAttribute( new Attribute("units", "degree"));
                xaxis.addAttribute( new Attribute(_Coordinate.AxisType, "Lon"));
                data = new double[nx];

                double dx = (endPnt.getLongitude() - startPnt.getLongitude()) /(nx-1);
                for (int i = 0; i < data.length; i++) {
                  data[i] = startPnt.getLongitude() + i * dx; // startx + i*dx;

                }

                dataA = Array.factory(DataType.DOUBLE.getPrimitiveClassType(), new int[] {nx}, data);
                xaxis.setCachedData( dataA, false);
                ncfile.addVariable(null, xaxis);
            }
			break;
		}
		case AwxFileFirstHeader.AWX_PRODUCT_TYPE_POLARSAT_IMAGE:
			throw new UnsupportedDatasetException();
			
		case AwxFileFirstHeader.AWX_PRODUCT_TYPE_GRID:
			{
				AwxFileGridProductSecondHeader gridprocuctSecondHeader = (AwxFileGridProductSecondHeader)this.secondHeader;
			
			
				att = new Attribute( "satellite_name", gridprocuctSecondHeader.satelliteName);			
			    this.ncfile.addAttribute(null, att);
			    
			    att = new Attribute( "grid_feature", gridprocuctSecondHeader.gridFeature);			
			    this.ncfile.addAttribute(null, att);
			    
			    att = new Attribute( "byte_amount_of_data", gridprocuctSecondHeader.byteAmountofData);			
			    this.ncfile.addAttribute(null, att);
			    
			    att = new Attribute( "data_scale", gridprocuctSecondHeader.dataScale);			
			    this.ncfile.addAttribute(null, att);
			    
	//		    this.ncfile.addAttribute(null, new Attribute("cdm_data_type", thredds.catalog.DataType.GRID.toString()));	    
			     
			    DateFormat dformat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
			    dformat.setTimeZone(java.util.TimeZone.getTimeZone("GMT"));
			    Calendar cal = Calendar.getInstance();
			    cal.set(gridprocuctSecondHeader.startYear, 
			    		gridprocuctSecondHeader.startMonth - 1,
			    		gridprocuctSecondHeader.startDay,
			    		gridprocuctSecondHeader.startHour,
			    		gridprocuctSecondHeader.startMinute,0);
			    cal.setTimeZone(java.util.TimeZone.getTimeZone("GMT"));
			    String dstring = dformat.format(cal.getTime());		    
			    this.ncfile.addAttribute(null, new Attribute("time_coverage_start", dstring));
			    int nz = 1;
                Dimension dimT  = new Dimension( "time", nz, true, false, false);
                ncfile.addDimension( null, dimT);

                // set time variable with time_coverage_start
                String timeCoordName = "time";
                Variable taxis = new Variable(ncfile, null, null, timeCoordName);
                taxis.setDataType(DataType.DOUBLE);
                taxis.setDimensions("time");
                taxis.addAttribute( new Attribute("long_name", "time since base date"));
                taxis.addAttribute( new Attribute(_Coordinate.AxisType, AxisType.Time.toString()));
                double [] tdata = new double[1];
                tdata[0] = cal.getTimeInMillis();
                Array dataA = Array.factory(DataType.DOUBLE.getPrimitiveClassType(), new int[] {1}, tdata);
                taxis.setCachedData( dataA, false);
                DateFormatter formatter = new DateFormatter();
                taxis.addAttribute( new Attribute("units", "msecs since "+formatter.toDateTimeStringISO(new Date(0))));
                ncfile.addVariable(null, taxis);


                cal.set(gridprocuctSecondHeader.endYear,
			    		gridprocuctSecondHeader.endMonth - 1,
			    		gridprocuctSecondHeader.endDay,
			    		gridprocuctSecondHeader.endHour,
			    		gridprocuctSecondHeader.endMinute,0);		    
			    dstring = dformat.format(cal.getTime());		
			    this.ncfile.addAttribute(null, new Attribute("time_coverage_end", dstring));
			    
			    
			    //  Get dimensions
			    Integer ni = new Integer(gridprocuctSecondHeader.amountofHorizontalSpacing);
			    att = new Attribute( "NX", ni);
			    this.ncfile.addAttribute(null, att);	
			   
			    ni = new Integer(gridprocuctSecondHeader.amountofVerticalSpacing);
			    att = new Attribute( "NY", ni);
			    this.ncfile.addAttribute(null, att);
			    
			    
			    // set projection attribute
			    // ? which projection
			    Byte nv = 0;
			    att = new Attribute( "ProjIndex", nv);
			    this.ncfile.addAttribute(null, att);
			    int proj = nv.intValue();
			    if( proj == 1) {
			     att = new Attribute( "ProjName", "MERCATOR");
			    } else if (proj == 3) {
			     att = new Attribute( "ProjName", "LAMBERT_CONFORNAL");
			    } else if (proj == 5) {
			     att = new Attribute( "ProjName", "POLARSTEREOGRAPGIC");
			    }	
			    this.ncfile.addAttribute(null, att);
			    
			    
			    
			    
			    ProjectionImpl projection = null;
			    double dxKm = 0.0, dyKm = 0.0, latin, lonProjectionOrigin ;
			    
			    // deal with projection	  
			   // System.out.println("unimplemented projection");
		
			    
			    
			    
			    this.ncfile.addAttribute(null, new Attribute("geospatial_lat_min", new Float(gridprocuctSecondHeader.rightBottomLat)));
			    this.ncfile.addAttribute(null, new Attribute("geospatial_lat_max", new Float(gridprocuctSecondHeader.leftTopLat)));
			    this.ncfile.addAttribute(null, new Attribute("geospatial_lon_min", new Float(gridprocuctSecondHeader.leftTopLon)));
			    this.ncfile.addAttribute(null, new Attribute("geospatial_lon_max", new Float(gridprocuctSecondHeader.rightBottomLon)));
			    this.ncfile.addAttribute(null, new Attribute("geospatial_vertical_min", new Float(0.0)));
			    this.ncfile.addAttribute(null, new Attribute("geospatial_vertical_max", new Float(0.0)));
			    
			    this.ncfile.addAttribute(null, new Attribute("spacing_unit", gridprocuctSecondHeader.getSpacingUnit()));
			    this.ncfile.addAttribute(null, new Attribute("horizontal_spacing", gridprocuctSecondHeader.horizontalSpacing));
			    this.ncfile.addAttribute(null, new Attribute("vertical_spacing", gridprocuctSecondHeader.verticalSpacing));
			    this.ncfile.addAttribute(null, new Attribute("amount_of_horizontal_spacing", gridprocuctSecondHeader.amountofHorizontalSpacing));
			    this.ncfile.addAttribute(null, new Attribute("amount_of_vertical_spacing", gridprocuctSecondHeader.amountofVerticalSpacing));
			    

	//		    att = new Attribute( "imageResolution", nv);
	//		    this.ncfile.addAttribute(null, att);
			   
			    // only one data variable per awx file
                 vname = getGridProductName(gridprocuctSecondHeader.gridFeature);
                 if(vname == null)
                        throw new UnsupportedDatasetException("Unsupported Grid Procuct Dataset");
                //  set vname and units according to grid feature
			    //String vname= this.firstHeader.fileName.substring(0, this.firstHeader.fileName.length() -4);
			    Variable var = new Variable( ncfile, ncfile.getRootGroup(), null, vname);
			    
			    var.addAttribute( new Attribute("long_name", vname)); // getPhysElemLongName(phys_elem, ent_id)));
			    var.addAttribute( new Attribute("units", getPhysElemUnits(gridprocuctSecondHeader.gridFeature)));
	// 		    var.addAttribute( new Attribute("missing_value", new Byte((byte) 0))); // ??
		
			      // get dimensions
			    int velems;
			    boolean isRecord = false;
			    
			    
			    int nx = gridprocuctSecondHeader.amountofHorizontalSpacing;
			    int ny = gridprocuctSecondHeader.amountofVerticalSpacing;
			    //int nz = 1;
		
			    Dimension dimX  = new Dimension( "lon", nx, true, false, false);
			    Dimension dimY  = new Dimension( "lat", ny, true, false, false);

			    ncfile.addDimension( null, dimY);
			    ncfile.addDimension( null, dimX);
		
			    velems = dimX.getLength() * dimY.getLength() * gridprocuctSecondHeader.byteAmountofData;
			    ArrayList dims = new ArrayList();
			    dims.add(dimT);
			    dims.add(dimY);
			    dims.add(dimX);
			    
		
			    var.setDimensions(dims);
		
			    // data type
			    Class dataType = null;
			    switch(gridprocuctSecondHeader.byteAmountofData){
			    case 1:
			    	var.setDataType( DataType.BYTE);
			    	dataType = DataType.BYTE.getPrimitiveClassType();
			    	break;
			    case 2:
			    	var.setDataType( DataType.SHORT);
			    	dataType = DataType.SHORT.getPrimitiveClassType();
			    	break;
			    case 4:
			    	var.setDataType( DataType.INT);
			    	dataType = DataType.INT.getPrimitiveClassType();
			    	break;
			    default:
			    	System.out.println("Unsupported Grid Procuct Dataset!");
			    	throw new UnsupportedDatasetException("Unsupported Grid Procuct Dataset");
			    			    
			    }
			    
			    var .addAttribute(new Attribute("coordinates", "lon lat"));
			    
			    var.addAttribute(new Attribute("_Unsigned", "true"));
			    //var.addAttribute(new Attribute("units", "percent"));


	            if(var.getDataType() == DataType.BYTE) {
                    var.addAttribute(new Attribute("_missing_value", new Byte((byte)-1)));
                    var.addAttribute( new Attribute("add_offset", (short)gridprocuctSecondHeader.dataBaseValue));
                    var.addAttribute( new Attribute("scale_factor", (short)gridprocuctSecondHeader.dataBaseValue));
                 } else {
                    var.addAttribute(new Attribute("_missing_value", new Short((short)-1)));
                    var.addAttribute( new Attribute("add_offset",(short)gridprocuctSecondHeader.dataBaseValue));
                    var.addAttribute( new Attribute("scale_factor", (short)gridprocuctSecondHeader.dataScale));
                }
			    
	    	      // size and beginning data position in file
	    	    int vsize = velems;
	    	    long begin = this.firstHeader.recordsOfHeader * this.firstHeader.recoderLength ;
	    	    if (debug) log.warn(" name= "+vname+" vsize="+vsize+" velems="+velems+" begin= "+begin+" isRecord="+isRecord+"\n");
	    	    var.setSPobject( new Vinfo (vsize, begin, isRecord, nx, ny, dataType, this.firstHeader.byteOrder));
	    	    String coordinates = "lon lat time";
	    	    var.addAttribute( new Attribute(_Coordinate.Axes, coordinates));
	    	    
	    	    ncfile.addVariable(ncfile.getRootGroup(), var);
	    
	    	    // we have to project in order to find the origin
	//    	    ProjectionPointImpl start = (ProjectionPointImpl) projection.latLonToProj( new LatLonPointImpl( lat1, lon1));
	//    	    if (debug) System.out.println("start at proj coord "+start);
	
	    	    LatLonPointImpl startPnt = new LatLonPointImpl( gridprocuctSecondHeader.leftTopLat, gridprocuctSecondHeader.leftTopLon);
	    	    LatLonPointImpl endPnt = new LatLonPointImpl( gridprocuctSecondHeader.rightBottomLat, gridprocuctSecondHeader.rightBottomLon);
	    	    if (debug) System.out.println("start at geo coord :"+startPnt);

	    	    
	    
	    	    Variable yaxis = new Variable( ncfile, null, null, "lat");
	    	    yaxis.setDataType( DataType.DOUBLE);
	    	    yaxis.setDimensions( "lat");
	    	    yaxis.addAttribute( new Attribute("long_name", "latitude"));
	    	    yaxis.addAttribute( new Attribute("units", "degree_north"));
	    	    yaxis.addAttribute( new Attribute(_Coordinate.AxisType, "latitude"));
	    	    double[] data = new double[ny];
	    	    
	    	    double dy = (endPnt.getLatitude() - startPnt.getLatitude()) /(ny-1);
		        for (int i = 0; i < data.length; i++) {
		          data[i] = startPnt.getLatitude() + i * dy; // starty + i*dy;       
		        }
		          
		        dataA = Array.factory(DataType.DOUBLE.getPrimitiveClassType(), new int[] {ny}, data);
	    	    yaxis.setCachedData( dataA, false);
	    	    ncfile.addVariable(null, yaxis);   
	    	    
	    	    
	    	 // create coordinate variables
	    	    Variable xaxis = new Variable( ncfile, null, null, "lon");
	    	    xaxis.setDataType( DataType.DOUBLE);
	    	    xaxis.setDimensions( "lon");
	    	    xaxis.addAttribute( new Attribute("long_name", "longitude"));
	    	    xaxis.addAttribute( new Attribute("units", "degree_east"));
	    	    xaxis.addAttribute( new Attribute(_Coordinate.AxisType, "longitude"));
	    	    data = new double[nx];
	
		        double dx = (endPnt.getLongitude() - startPnt.getLongitude()) /(nx-1);
		        for (int i = 0; i < data.length; i++) {
		          data[i] = startPnt.getLongitude() + i * dx; // startx + i*dx;       
		          
		        }   	 
		        
		        dataA = Array.factory(DataType.DOUBLE.getPrimitiveClassType(), new int[] {nx}, data);
	    	    xaxis.setCachedData( dataA, false);
	    	    ncfile.addVariable(null, xaxis);
	    	    
	    	    
	//    	    // coordinate transform variable
	//    	    Variable ct = new Variable( ncfile, null, null, projection.getClassName());
	//    	    ct.setDataType( DataType.CHAR);
	//    	    ct.setDimensions( "");
	//    	    List params = projection.getProjectionParameters();
	//    	    for (int i = 0; i < params.size(); i++) {
	//    	      Parameter p = (Parameter) params.get(i);
	//    	      ct.addAttribute( new Attribute(p));
	//    	    }
	//    	    ct.addAttribute( new Attribute(_Coordinate.TransformType, "Projection"));
	//    	    ct.addAttribute( new Attribute(_Coordinate.Axes, "x y "));
	//    	    // fake data
	//    	    dataA = Array.factory(DataType.CHAR.getPrimitiveClassType(), new int[] {});
	//    	    dataA.setChar(dataA.getIndex(), ' ');
	//    	    ct.setCachedData(dataA, false);
	//    
	//    	    ncfile.addVariable(null, ct);
	//  	    ncfile.addAttribute( null, new Attribute("Conventions", _Coordinate.Convention));
			    
			    
			   
			    
			    // add more addAttributes
	
			    
	//		    String timeCoordName = "time";
	//		    Variable taxis = new Variable(ncfile, null, null, timeCoordName);
	//		    taxis.setDataType(DataType.DOUBLE);
	//		    taxis.setDimensions("time");
	//		    taxis.addAttribute( new Attribute("long_name", "time since base date"));
	//		    taxis.addAttribute( new Attribute(_Coordinate.AxisType, AxisType.Time.toString()));
	//		    double [] tdata = new double[1];
	//		    tdata[0] = cal.getTimeInMillis();
	//		    Array dataA = Array.factory(DataType.DOUBLE.getPrimitiveClassType(), new int[] {1}, tdata);
	//		    taxis.setCachedData( dataA, false);
	//		    DateFormatter formatter = new DateFormatter();
	//		    taxis.addAttribute( new Attribute("units", "msecs since "+formatter.toDateTimeStringISO(new Date(0))));
	//		    ncfile.addVariable(null, taxis);
	//		    
				break;
			}
		case AwxFileFirstHeader.AWX_PRODUCT_TYPE_DISCREET:
			throw new UnsupportedDatasetException();
			
		case AwxFileFirstHeader.AWX_PRODUCT_TYPE_GRAPH_ANALIYSIS:
			throw new UnsupportedDatasetException();
	}
    

    // finish
    ncfile.finish();
  }
    String getGeoSatelliteProductName(int channel) {
        String vname;
        switch( channel) {
            case 1:
                vname = "IR";
                break;
            case 2:
                vname = "WV";
                break;
            case 3:
                vname = "IR_WV";
                break;
            case 4:
                vname = "VIS";
                break;
            case 34:
                vname = "DST";
                break;
            default: {
              System.out.println("Unsupported GeoSatellite Procuct Dataset!");
              return null;
              }
          }
        return vname;
    }

  String getGridProductName(int feature) {
      String vname;
      switch( feature) {
            case 1:
                vname = "SST";
                break;
            case 2:
                vname = "SeaICE";
                break;
            case 3:
                vname = "SeaICEDensity";
                break;
            case 4:
                vname = "LongWaveRadiation";
                break;
            case 5:
                vname = "plantIdx";
                break;
            case 6:
                vname = "plantIdxRatio";
                break;
            case 7:
                vname = "snow";
                break;
            case 8:
                vname = "soilHumidity";
                break;
            case 9:
                vname = "sunshine";
                break;
            case 10:
                vname = "cloudTopHeight";
                break;
            case 11:
                vname = "cloudTopTemp";
                break;
            case 12:
                vname = "lowCloudVolume";
                break;
            case 13:
                vname = "highCloudVolume";
                break;
            case 14:
                vname = "precipIdx1hour";
                break;
            case 15:
                vname = "precipIdx6hour";
                break;
            case 16:
                vname = "precipIdx12hour";
                break;
            case 17:
                vname = "precipIdx24hour";
                break;
            case 18:
                vname = "waterVapor";
                break;
            case 19:
                vname = "cloudTemp";
                break;
            case 501:
                vname = "TOVS";
                break;
            case 502:
                vname = "TOVS";
                break;
            case 503:
                vname = "TOVS";
                break;
            case 504:
                vname = "TOVS";
                break;
            case 505:
                vname = "TOVS";
                break;
            case 506:
                vname = "TOVS";
                break;
            case 507:
                vname = "TOVS";
                break;
            default: {
                System.out.println("Unsupported Satellite Grid Procuct Dataset!");
                return null;
            }
        }
      return vname;
    }

    String   getPhysElemUnits(int feature) {
        String unit;

        switch( feature) {
            case 1:
                unit = "K";
                break;
            case 2:
                unit = "";
                break;
            case 3:
                unit = "";
                break;
            case 4:
                unit = "W/m2";
                break;
            case 5:
                unit = "";
                break;
            case 6:
                unit = "";
                break;
            case 7:
                unit = "";
                break;
            case 8:
                unit = "kg/m3";
                break;
            case 9:
                unit = "hour";
                break;
            case 10:
                unit = "hPa";
                break;
            case 11:
                unit = "K";
                break;
            case 12:
                unit = "";
                break;
            case 13:
                unit = "";
                break;
            case 14:
                unit = "mm/hour";
                break;
            case 15:
                unit = "mm/(6 hour)";
                break;
            case 16:
                unit = "mm/(12 hour)";
                break;
            case 17:
                unit = "mm/(24 hour)";
                break;
            case 18:
                unit = "";
                break;
            case 19:
                unit = "K";
                break;
            case 501:
                unit = "";
                break;
            case 502:
                unit = "mm";
                break;
            case 503:
                unit = "Db";
                break;
            case 504:
                unit = "W/m2";
                break;
            case 505:
                unit = "hPa";
                break;
            case 506:
                unit = "K";
                break;
            case 507:
                unit = "";
                break;
            default: {
                System.out.println("Unsupported Satellite Grid Procuct Dataset!");
                return null;
            }

        }
        return unit;
    }

    int getCompressType( )
    {
       return Z_type;
    }

  // Return the string of entity ID for the GINI image file




//  ////////////////////////////////////////////////////////////////////////////////////////////////////////
//
  // variable info for reading/writing
  class Vinfo {
    int vsize; // size of array in bytes. if isRecord, size per record.
    long begin; // offset of start of data from start of file
    boolean isRecord; // is it a record variable?
    int nx;
    int ny;
    Class classType;
    short byteOrder;
    Vinfo( int vsize, long begin, boolean isRecord, int x, int y, Class dt,short byteOrder) {
      this.vsize = vsize;
      this.begin = begin;
      this.isRecord = isRecord;
      this.nx = x;
      this.ny = y;
      this.classType = dt;
      this.byteOrder = byteOrder;
    }
  }

}
/* Change History:
   $Log: FysatHeader.java,v $
  

 */




© 2015 - 2024 Weber Informatics LLC | Privacy Policy