ucar.nc2.iosp.cinrad.Cinrad2IOServiceProvider Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of netcdf Show documentation
Show all versions of netcdf Show documentation
The NetCDF-Java Library is a Java interface to NetCDF files,
as well as to many other types of scientific data formats.
/*
* Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
*
* Portions of this software were developed by the Unidata Program at the
* University Corporation for Atmospheric Research.
*
* Access and use of this software shall impose the following obligations
* and understandings on the user. The user is granted the right, without
* any fee or cost, to use, copy, modify, alter, enhance and distribute
* this software, and any derivative works thereof, and its supporting
* documentation for any purpose whatsoever, provided that this entire
* notice appears in all copies of the software, derivative works and
* supporting documentation. Further, UCAR requests that the user credit
* UCAR/Unidata in any publications that result from the use of this
* software or in any product that includes this software. The names UCAR
* and/or Unidata, however, may not be used in any advertising or publicity
* to endorse or promote any products or commercial entity unless specific
* written permission is obtained from UCAR/Unidata. The user also
* understands that UCAR/Unidata is not obligated to provide the user with
* any support, consulting, training or assistance of any kind with regard
* to the use, operation and performance of this software nor to provide
* the user with any updates, revisions, new versions or "bug fixes."
*
* THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
*/
package ucar.nc2.iosp.cinrad;
import ucar.ma2.*;
import ucar.nc2.*;
import ucar.nc2.iosp.nexrad2.NexradStationDB;
import ucar.nc2.iosp.AbstractIOServiceProvider;
import ucar.nc2.units.DateFormatter;
import ucar.nc2.constants.AxisType;
import ucar.nc2.constants._Coordinate;
import ucar.nc2.util.CancelTask;
import ucar.unidata.io.RandomAccessFile;
import java.io.IOException;
import java.util.*;
/**
* An IOServiceProvider for CINRAD level II files.
*
*
* @author caron
*/
public class Cinrad2IOServiceProvider extends AbstractIOServiceProvider {
static private org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(Cinrad2IOServiceProvider.class);
static private final int MISSING_INT = -9999;
static private final float MISSING_FLOAT = Float.NaN;
public boolean isValidFileOld( RandomAccessFile raf) {
try {
String loc = raf.getLocation();
int posFirst = loc.lastIndexOf('/') + 1;
if (posFirst < 0) posFirst = 0;
String stationId = loc.substring(posFirst,posFirst+4);
NexradStationDB.init();
NexradStationDB.Station station = NexradStationDB.get("K"+ stationId);
if(station != null )
return true;
else
return false;
} catch (IOException ioe) {
return false;
}
}
public boolean isValidFile( RandomAccessFile raf) {
int data_msecs = 0;
short data_julian_date = 0;
try{
raf.order(RandomAccessFile.LITTLE_ENDIAN);
raf.seek(0);
raf.skipBytes(14);
short message_type = raf.readShort();
if (message_type != 1) return false;
raf.skipBytes(12);
// data header
byte [] b4 = raf.readBytes(4);
data_msecs = bytesToInt(b4, true);
byte [] b2 = raf.readBytes(2);
data_julian_date = (short)bytesToShort(b2, true);
java.util.Date dd =Cinrad2Record.getDate(data_julian_date,data_msecs);
Calendar cal = new GregorianCalendar(new SimpleTimeZone(0, "GMT"));
cal.clear();
cal.setTime(dd);
int year = cal.get(Calendar.YEAR);
cal.setTime(new Date());
int cyear = cal.get(Calendar.YEAR);
if(year < 1990 || year > cyear ) return false;
return true;
} catch (IOException ioe) {
return false;
}
}
public static int bytesToInt(byte [] bytes, boolean swapBytes) {
byte a = bytes[0];
byte b = bytes[1];
byte c = bytes[2];
byte d = bytes[3];
if (swapBytes) {
return ((a & 0xff) ) +
((b & 0xff) << 8 ) +
((c & 0xff) << 16 ) +
((d & 0xff) << 24);
} else {
return ((a & 0xff) << 24 ) +
((b & 0xff) << 16 ) +
((c & 0xff) << 8 ) +
((d & 0xff) );
}
}
public static int bytesToShort(byte [] bytes, boolean swapBytes) {
byte a = bytes[0];
byte b = bytes[1];
if (swapBytes) {
return ((a & 0xff) ) +
((b & 0xff) << 8 );
} else {
return ((a & 0xff) << 24 ) +
((b & 0xff) << 16 );
}
}
public String getFileTypeId() {
return "CINRAD";
}
public String getFileTypeDescription() {
return "Chinese Level-II Base Data";
}
private Cinrad2VolumeScan volScan;
private Dimension radialDim;
private double radarRadius;
private DateFormatter formatter = new DateFormatter();
public void open(RandomAccessFile raf, NetcdfFile ncfile, CancelTask cancelTask) throws IOException {
NexradStationDB.init();
volScan = new Cinrad2VolumeScan( raf, cancelTask);
if (volScan.hasDifferentDopplarResolutions())
throw new IllegalStateException("volScan.hasDifferentDopplarResolutions");
radialDim = new Dimension("radial", volScan.getMaxRadials());
ncfile.addDimension( null, radialDim);
makeVariable( ncfile, Cinrad2Record.REFLECTIVITY, "Reflectivity", "Reflectivity", "R", volScan.getReflectivityGroups());
int velocity_type = (volScan.getDopplarResolution() == Cinrad2Record.DOPPLER_RESOLUTION_HIGH_CODE) ? Cinrad2Record.VELOCITY_HI : Cinrad2Record.VELOCITY_LOW;
Variable v = makeVariable( ncfile, velocity_type, "RadialVelocity", "Radial Velocity", "V", volScan.getVelocityGroups());
makeVariableNoCoords( ncfile, Cinrad2Record.SPECTRUM_WIDTH, "SpectrumWidth", "Spectrum Width", v);
if (volScan.getStationId() != null) {
ncfile.addAttribute(null, new Attribute("Station", volScan.getStationId()));
ncfile.addAttribute(null, new Attribute("StationName", volScan.getStationName()));
ncfile.addAttribute(null, new Attribute("StationLatitude", new Double(volScan.getStationLatitude())));
ncfile.addAttribute(null, new Attribute("StationLongitude", new Double(volScan.getStationLongitude())));
ncfile.addAttribute(null, new Attribute("StationElevationInMeters", new Double(volScan.getStationElevation())));
double latRadiusDegrees = Math.toDegrees( radarRadius / ucar.unidata.geoloc.Earth.getRadius());
ncfile.addAttribute(null, new Attribute("geospatial_lat_min", new Double(volScan.getStationLatitude() - latRadiusDegrees)));
ncfile.addAttribute(null, new Attribute("geospatial_lat_max", new Double(volScan.getStationLatitude() + latRadiusDegrees)));
double cosLat = Math.cos( Math.toRadians(volScan.getStationLatitude()));
double lonRadiusDegrees = Math.toDegrees( radarRadius / cosLat / ucar.unidata.geoloc.Earth.getRadius());
ncfile.addAttribute(null, new Attribute("geospatial_lon_min", new Double(volScan.getStationLongitude() - lonRadiusDegrees)));
ncfile.addAttribute(null, new Attribute("geospatial_lon_max", new Double(volScan.getStationLongitude() + lonRadiusDegrees)));
// add a radial coordinate transform (experimental)
Variable ct = new Variable(ncfile, null, null, "radialCoordinateTransform");
ct.setDataType(DataType.CHAR);
ct.setDimensions(""); // scalar
ct.addAttribute( new Attribute("transform_name", "Radial"));
ct.addAttribute( new Attribute("center_latitude", new Double(volScan.getStationLatitude())));
ct.addAttribute( new Attribute("center_longitude", new Double(volScan.getStationLongitude())));
ct.addAttribute( new Attribute("center_elevation", new Double(volScan.getStationElevation())));
ct.addAttribute( new Attribute(_Coordinate.TransformType, "Radial"));
ct.addAttribute( new Attribute(_Coordinate.AxisTypes, "RadialElevation RadialAzimuth RadialDistance"));
Array data = Array.factory(DataType.CHAR.getPrimitiveClassType(), new int[0], new char[] {' '});
ct.setCachedData(data, true);
ncfile.addVariable(null, ct);
}
DateFormatter formatter = new DateFormatter();
ncfile.addAttribute(null, new Attribute("Conventions", _Coordinate.Convention));
ncfile.addAttribute(null, new Attribute("format", volScan.getDataFormat()));
//Date d = Cinrad2Record.getDate(volScan.getTitleJulianDays(), volScan.getTitleMsecs());
//ncfile.addAttribute(null, new Attribute("base_date", formatter.toDateOnlyString(d)));
ncfile.addAttribute(null, new Attribute("time_coverage_start", formatter.toDateTimeStringISO(volScan.getStartDate())));; //.toDateTimeStringISO(d)));
ncfile.addAttribute(null, new Attribute("time_coverage_end", formatter.toDateTimeStringISO(volScan.getEndDate())));
ncfile.addAttribute(null, new Attribute("history", "Direct read of Nexrad Level 2 file into NetCDF-Java 2.2 API"));
ncfile.addAttribute(null, new Attribute("DataType", "Radial"));
ncfile.addAttribute(null, new Attribute("Title", "Nexrad Level 2 Station "+volScan.getStationId()+" from "+
formatter.toDateTimeStringISO(volScan.getStartDate()) + " to " +
formatter.toDateTimeStringISO(volScan.getEndDate())));
ncfile.addAttribute(null, new Attribute("Summary", "Weather Surveillance Radar-1988 Doppler (WSR-88D) "+
"Level II data are the three meteorological base data quantities: reflectivity, mean radial velocity, and "+
"spectrum width."));
ncfile.addAttribute(null, new Attribute("keywords", "WSR-88D; NEXRAD; Radar Level II; reflectivity; mean radial velocity; spectrum width"));
ncfile.addAttribute(null, new Attribute("VolumeCoveragePatternName",
Cinrad2Record.getVolumeCoveragePatternName(volScan.getVCP())));
ncfile.addAttribute(null, new Attribute("VolumeCoveragePattern", new Integer(volScan.getVCP())));
ncfile.addAttribute(null, new Attribute("HorizonatalBeamWidthInDegrees", new Double(Cinrad2Record.HORIZONTAL_BEAM_WIDTH)));
ncfile.finish();
}
public Variable makeVariable(NetcdfFile ncfile, int datatype, String shortName, String longName, String abbrev, List groups) throws IOException {
int nscans = groups.size();
if (nscans == 0) {
throw new IllegalStateException("No data for "+shortName);
}
// get representative record
List firstGroup = (List) groups.get(0);
Cinrad2Record firstRecord = (Cinrad2Record) firstGroup.get(0);
int ngates = firstRecord.getGateCount(datatype);
String scanDimName = "scan"+abbrev;
String gateDimName = "gate"+abbrev;
Dimension scanDim = new Dimension(scanDimName, nscans);
Dimension gateDim = new Dimension(gateDimName, ngates);
ncfile.addDimension( null, scanDim);
ncfile.addDimension( null, gateDim);
ArrayList dims = new ArrayList();
dims.add( scanDim);
dims.add( radialDim);
dims.add( gateDim);
Variable v = new Variable(ncfile, null, null, shortName);
v.setDataType(DataType.BYTE);
v.setDimensions(dims);
ncfile.addVariable(null, v);
v.addAttribute( new Attribute("units", Cinrad2Record.getDatatypeUnits(datatype)));
v.addAttribute( new Attribute("long_name", longName));
byte[] b = new byte[2];
b[0] = Cinrad2Record.MISSING_DATA;
b[1] = Cinrad2Record.BELOW_THRESHOLD;
Array missingArray = Array.factory(DataType.BYTE.getPrimitiveClassType(), new int[] {2}, b);
v.addAttribute( new Attribute("missing_value", missingArray));
v.addAttribute( new Attribute("signal_below_threshold", new Byte( Cinrad2Record.BELOW_THRESHOLD)));
v.addAttribute( new Attribute("scale_factor", new Float( Cinrad2Record.getDatatypeScaleFactor(datatype))));
v.addAttribute( new Attribute("add_offset", new Float( Cinrad2Record.getDatatypeAddOffset(datatype))));
v.addAttribute( new Attribute("_Unsigned", "true"));
ArrayList dim2 = new ArrayList();
dim2.add( scanDim);
dim2.add( radialDim);
// add time coordinate variable
String timeCoordName = "time"+abbrev;
Variable timeVar = new Variable(ncfile, null, null, timeCoordName);
timeVar.setDataType(DataType.INT);
timeVar.setDimensions(dim2);
ncfile.addVariable(null, timeVar);
// int julianDays = volScan.getTitleJulianDays();
// Date d = Cinrad2Record.getDate( julianDays, 0);
// Date d = Cinrad2Record.getDate(volScan.getTitleJulianDays(), volScan.getTitleMsecs());
Date d= volScan.getStartDate();
String units = "msecs since "+formatter.toDateTimeStringISO(d);
timeVar.addAttribute( new Attribute("long_name", "time since base date"));
timeVar.addAttribute( new Attribute("units", units));
timeVar.addAttribute( new Attribute("missing_value", new Integer(MISSING_INT)));
timeVar.addAttribute( new Attribute(_Coordinate.AxisType, AxisType.Time.toString()));
// add elevation coordinate variable
String elevCoordName = "elevation"+abbrev;
Variable elevVar = new Variable(ncfile, null, null, elevCoordName);
elevVar.setDataType(DataType.FLOAT);
elevVar.setDimensions(dim2);
ncfile.addVariable(null, elevVar);
elevVar.addAttribute( new Attribute("units", "degrees"));
elevVar.addAttribute( new Attribute("long_name", "elevation angle in degres: 0 = parallel to pedestal base, 90 = perpendicular"));
elevVar.addAttribute( new Attribute("missing_value", new Float(MISSING_FLOAT)));
elevVar.addAttribute( new Attribute(_Coordinate.AxisType, AxisType.RadialElevation.toString()));
// add azimuth coordinate variable
String aziCoordName = "azimuth"+abbrev;
Variable aziVar = new Variable(ncfile, null, null, aziCoordName);
aziVar.setDataType(DataType.FLOAT);
aziVar.setDimensions(dim2);
ncfile.addVariable(null, aziVar);
aziVar.addAttribute( new Attribute("units", "degrees"));
aziVar.addAttribute( new Attribute("long_name", "azimuth angle in degrees: 0 = true north, 90 = east"));
aziVar.addAttribute( new Attribute("missing_value", new Float(MISSING_FLOAT)));
aziVar.addAttribute( new Attribute(_Coordinate.AxisType, AxisType.RadialAzimuth.toString()));
// add gate coordinate variable
String gateCoordName = "distance"+abbrev;
Variable gateVar = new Variable(ncfile, null, null, gateCoordName);
gateVar.setDataType(DataType.FLOAT);
gateVar.setDimensions(gateDimName);
Array data = Array.makeArray( DataType.FLOAT, ngates,
(double) firstRecord.getGateStart(datatype), (double) firstRecord.getGateSize(datatype));
gateVar.setCachedData( data, false);
ncfile.addVariable(null, gateVar);
radarRadius = firstRecord.getGateStart(datatype) + ngates * firstRecord.getGateSize(datatype);
gateVar.addAttribute( new Attribute("units", "m"));
gateVar.addAttribute( new Attribute("long_name", "radial distance to start of gate"));
gateVar.addAttribute( new Attribute(_Coordinate.AxisType, AxisType.RadialDistance.toString()));
// add number of radials variable
String nradialsName = "numRadials"+abbrev;
Variable nradialsVar = new Variable(ncfile, null, null, nradialsName);
nradialsVar.setDataType(DataType.INT);
nradialsVar.setDimensions(scanDim.getName());
nradialsVar.addAttribute( new Attribute("long_name", "number of valid radials in this scan"));
ncfile.addVariable(null, nradialsVar);
// add number of gates variable
String ngateName = "numGates"+abbrev;
Variable ngateVar = new Variable(ncfile, null, null, ngateName);
ngateVar.setDataType(DataType.INT);
ngateVar.setDimensions(scanDim.getName());
ngateVar.addAttribute( new Attribute("long_name", "number of valid gates in this scan"));
ncfile.addVariable(null, ngateVar);
makeCoordinateDataWithMissing( datatype, timeVar, elevVar, aziVar, nradialsVar, ngateVar, groups);
// back to the data variable
String coordinates = timeCoordName+" "+elevCoordName +" "+ aziCoordName+" "+gateCoordName;
v.addAttribute( new Attribute(_Coordinate.Axes, coordinates));
// make the record map
int nradials = radialDim.getLength();
Cinrad2Record[][] map = new Cinrad2Record[nscans][nradials];
for (int i = 0; i < groups.size(); i++) {
Cinrad2Record[] mapScan = map[i];
List group = (List) groups.get(i);
for (int j = 0; j < group.size(); j++) {
Cinrad2Record r = (Cinrad2Record) group.get(j);
int radial = r.radial_num-1;
mapScan[radial] = r;
}
}
Vgroup vg = new Vgroup(datatype, map);
v.setSPobject( vg);
return v;
}
private void makeVariableNoCoords(NetcdfFile ncfile, int datatype, String shortName, String longName, Variable from) {
Variable v = new Variable(ncfile, null, null, shortName);
v.setDataType(DataType.BYTE);
v.setDimensions( from.getDimensions());
ncfile.addVariable(null, v);
v.addAttribute( new Attribute("units", Cinrad2Record.getDatatypeUnits(datatype)));
v.addAttribute( new Attribute("long_name", longName));
byte[] b = new byte[2];
b[0] = Cinrad2Record.MISSING_DATA;
b[1] = Cinrad2Record.BELOW_THRESHOLD;
Array missingArray = Array.factory(DataType.BYTE.getPrimitiveClassType(), new int[] {2}, b);
v.addAttribute( new Attribute("missing_value", missingArray));
v.addAttribute( new Attribute("signal_below_threshold", new Byte( Cinrad2Record.BELOW_THRESHOLD)));
v.addAttribute( new Attribute("scale_factor", new Float( Cinrad2Record.getDatatypeScaleFactor(datatype))));
v.addAttribute( new Attribute("add_offset", new Float( Cinrad2Record.getDatatypeAddOffset(datatype))));
v.addAttribute( new Attribute("_Unsigned", "true"));
Attribute fromAtt = from.findAttribute(_Coordinate.Axes);
v.addAttribute( new Attribute(_Coordinate.Axes, fromAtt));
Vgroup vgFrom = (Vgroup) from.getSPobject();
Vgroup vg = new Vgroup(datatype, vgFrom.map);
v.setSPobject( vg);
}
private void makeCoordinateData(int datatype, Variable time, Variable elev, Variable azi, Variable nradialsVar,
Variable ngatesVar, List groups) {
Array timeData = Array.factory( time.getDataType().getPrimitiveClassType(), time.getShape());
IndexIterator timeDataIter = timeData.getIndexIterator();
Array elevData = Array.factory( elev.getDataType().getPrimitiveClassType(), elev.getShape());
IndexIterator elevDataIter = elevData.getIndexIterator();
Array aziData = Array.factory( azi.getDataType().getPrimitiveClassType(), azi.getShape());
IndexIterator aziDataIter = aziData.getIndexIterator();
Array nradialsData = Array.factory( nradialsVar.getDataType().getPrimitiveClassType(), nradialsVar.getShape());
IndexIterator nradialsIter = nradialsData.getIndexIterator();
Array ngatesData = Array.factory( ngatesVar.getDataType().getPrimitiveClassType(), ngatesVar.getShape());
IndexIterator ngatesIter = ngatesData.getIndexIterator();
int last_msecs = Integer.MIN_VALUE;
int nscans = groups.size();
int maxRadials = volScan.getMaxRadials();
for (int i = 0; i < nscans; i++) {
List scanGroup = (List) groups.get(i);
int nradials = scanGroup.size();
Cinrad2Record first = null;
for (int j = 0; j < nradials; j++) {
Cinrad2Record r = (Cinrad2Record) scanGroup.get(j);
if (first == null) first = r;
timeDataIter.setIntNext( r.data_msecs);
elevDataIter.setFloatNext( r.getElevation());
aziDataIter.setFloatNext( r.getAzimuth());
if (r.data_msecs < last_msecs) logger.warn("makeCoordinateData time out of order "+r.data_msecs);
last_msecs = r.data_msecs;
}
for (int j = nradials; j < maxRadials; j++) {
timeDataIter.setIntNext( MISSING_INT);
elevDataIter.setFloatNext( MISSING_FLOAT);
aziDataIter.setFloatNext( MISSING_FLOAT);
}
nradialsIter.setIntNext( nradials);
ngatesIter.setIntNext( first.getGateCount( datatype));
}
time.setCachedData( timeData, false);
elev.setCachedData( elevData, false);
azi.setCachedData( aziData, false);
nradialsVar.setCachedData( nradialsData, false);
ngatesVar.setCachedData( ngatesData, false);
}
private void makeCoordinateDataWithMissing(int datatype, Variable time, Variable elev, Variable azi, Variable nradialsVar,
Variable ngatesVar, List groups) {
Array timeData = Array.factory( time.getDataType().getPrimitiveClassType(), time.getShape());
Index timeIndex = timeData.getIndex();
Array elevData = Array.factory( elev.getDataType().getPrimitiveClassType(), elev.getShape());
Index elevIndex = elevData.getIndex();
Array aziData = Array.factory( azi.getDataType().getPrimitiveClassType(), azi.getShape());
Index aziIndex = aziData.getIndex();
Array nradialsData = Array.factory( nradialsVar.getDataType().getPrimitiveClassType(), nradialsVar.getShape());
IndexIterator nradialsIter = nradialsData.getIndexIterator();
Array ngatesData = Array.factory( ngatesVar.getDataType().getPrimitiveClassType(), ngatesVar.getShape());
IndexIterator ngatesIter = ngatesData.getIndexIterator();
// first fill with missing data
IndexIterator ii = timeData.getIndexIterator();
while (ii.hasNext())
ii.setIntNext(MISSING_INT);
ii = elevData.getIndexIterator();
while (ii.hasNext())
ii.setFloatNext(MISSING_FLOAT);
ii = aziData.getIndexIterator();
while (ii.hasNext())
ii.setFloatNext(MISSING_FLOAT);
// now set the coordinate variables from the Cinrad2Record radial
int last_msecs = Integer.MIN_VALUE;
int nscans = groups.size();
try {
for (int scan = 0; scan < nscans; scan++) {
List scanGroup = (List) groups.get(scan);
int nradials = scanGroup.size();
Cinrad2Record first = null;
for (int j = 0; j < nradials; j++) {
Cinrad2Record r = (Cinrad2Record) scanGroup.get(j);
if (first == null) first = r;
int radial = r.radial_num-1;
timeData.setInt( timeIndex.set(scan, radial), r.data_msecs);
elevData.setFloat( elevIndex.set(scan, radial), r.getElevation());
aziData.setFloat( aziIndex.set(scan, radial), r.getAzimuth());
if (r.data_msecs < last_msecs) logger.warn("makeCoordinateData time out of order "+r.data_msecs);
last_msecs = r.data_msecs;
}
nradialsIter.setIntNext( nradials);
ngatesIter.setIntNext( first.getGateCount( datatype));
} }catch(java.lang.ArrayIndexOutOfBoundsException ae) {
logger.debug("Cinrad2IOSP.uncompress ", ae);
}
time.setCachedData( timeData, false);
elev.setCachedData( elevData, false);
azi.setCachedData( aziData, false);
nradialsVar.setCachedData( nradialsData, false);
ngatesVar.setCachedData( ngatesData, false);
}
public Array readData(Variable v2, Section section) throws IOException, InvalidRangeException {
Vgroup vgroup = (Vgroup) v2.getSPobject();
Range scanRange = section.getRange(0);
Range radialRange = section.getRange(1);
Range gateRange = section.getRange(2);
Array data = Array.factory(v2.getDataType().getPrimitiveClassType(), section.getShape());
IndexIterator ii = data.getIndexIterator();
for (int i=scanRange.first(); i<=scanRange.last(); i+= scanRange.stride()) {
Cinrad2Record[] mapScan = vgroup.map[i];
readOneScan(mapScan, radialRange, gateRange, vgroup.datatype, ii);
}
return data;
}
private void readOneScan(Cinrad2Record[] mapScan, Range radialRange, Range gateRange, int datatype, IndexIterator ii) throws IOException {
for (int i=radialRange.first(); i<=radialRange.last(); i+= radialRange.stride()) {
Cinrad2Record r = mapScan[i];
readOneRadial(r, datatype, gateRange, ii);
}
}
private void readOneRadial(Cinrad2Record r, int datatype, Range gateRange, IndexIterator ii) throws IOException {
if (r == null) {
for (int i=gateRange.first(); i<=gateRange.last(); i+= gateRange.stride())
ii.setByteNext( Cinrad2Record.MISSING_DATA);
return;
}
r.readData(volScan.raf, datatype, gateRange, ii);
}
private class Vgroup {
Cinrad2Record[][] map;
int datatype;
Vgroup( int datatype, Cinrad2Record[][] map) {
this.datatype = datatype;
this.map = map;
}
}
/////////////////////////////////////////////////////////////////////
public void close() throws IOException {
volScan.raf.close();
}
}