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

ucar.nc2.iosp.nexrad2.Level2Record Maven / Gradle / Ivy

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


package ucar.nc2.iosp.nexrad2;

import ucar.unidata.io.RandomAccessFile;
import ucar.ma2.IndexIterator;
import ucar.ma2.Range;

import java.io.IOException;
import java.io.PrintStream;
import java.util.Date;


/**
 * This class reads one record (radial) in an NEXRAD level II file.
 * File must be uncompressed.
 * Not handling messages yet, only data.
 * 

* 10/16/05: Now returns data as a byte, so use scale and offset. *

* Adapted with permission from the Java Iras software developed by David Priegnitz at NSSL. * * @author caron * @author David Priegnitz */ public class Level2Record { static private org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(Level2Record.class); /** * Reflectivity moment identifier */ public static final int REFLECTIVITY = 1; /** * Radial Velocity moment identifier */ public static final int VELOCITY_HI = 2; /** * Radial Velocity moment identifier */ public static final int VELOCITY_LOW = 4; /** * Sprectrum Width moment identifier */ public static final int SPECTRUM_WIDTH = 3; /** * Low doppler resolution code */ public static final int DOPPLER_RESOLUTION_LOW_CODE = 4; /** * High doppler resolution code */ public static final int DOPPLER_RESOLUTION_HIGH_CODE = 2; /** * Horizontal beam width */ public static final float HORIZONTAL_BEAM_WIDTH = (float) 1.5; // LOOK always true ?? /* added for high resolution message type 31 */ public static final int REFLECTIVITY_HIGH = 5; /** * High Resolution Radial Velocity moment identifier */ public static final int VELOCITY_HIGH = 6; /** * High Resolution Sprectrum Width moment identifier */ public static final int SPECTRUM_WIDTH_HIGH = 7; /** * High Resolution Radial Velocity moment identifier */ public static final int DIFF_REFLECTIVITY_HIGH = 8; /** * High Resolution Radial Velocity moment identifier */ public static final int DIFF_PHASE = 9; /** * High Resolution Sprectrum Width moment identifier */ public static final int CORRELATION_COEFFICIENT = 10; // Lookup Tables /** * Initialization flag for lookup tables * public static int data_lut_init_flag = 0; *

* /** Reflectivity look up table * public static float[] Reflectivity_LUT = new float[256]; *

* /** 1 km Velocity look up table * public static float[] Velocity_1km_LUT = new float[256]; *

* /** 1/2 km Velocity look up table * public static float[] Velocity_hkm_LUT = new float[256]; *

* static { * Reflectivity_LUT[0] = 0.0f; // Float.NaN; //(float) SIGNAL_BELOW_THRESHOLD; * Reflectivity_LUT[1] = Float.NaN; //(float) SIGNAL_OVERLAID; * Velocity_1km_LUT[0] = 0.0f; // Float.NaN; //(float) SIGNAL_BELOW_THRESHOLD; * Velocity_1km_LUT[1] = Float.NaN; //(float) SIGNAL_OVERLAID; * Velocity_hkm_LUT[0] = 0.0f; // Float.NaN; //(float) SIGNAL_BELOW_THRESHOLD; * Velocity_hkm_LUT[1] = Float.NaN; //(float) SIGNAL_OVERLAID; *

* for (int i = 2; i < 256; i++) { * Reflectivity_LUT[i] = (float) (i / 2.0 - 33.0); * Velocity_1km_LUT[i] = (float) (i - 129.0); * Velocity_hkm_LUT[i] = (float) (i / 2.0 - 64.5); // also spectrum width * } * } */ public static final byte MISSING_DATA = (byte) 1; public static final byte BELOW_THRESHOLD = (byte) 0; /** * Size of the file header, aka title */ static final int FILE_HEADER_SIZE = 24; /** * Size of the CTM record header */ private static final int CTM_HEADER_SIZE = 12; /** * Size of the the message header, to start of the data message */ private static final int MESSAGE_HEADER_SIZE = 28; /** * Size of the entire message, if its a radar data message */ private static final int RADAR_DATA_SIZE = 2432; static public String getDatatypeName(int datatype) { switch (datatype) { case REFLECTIVITY: return "Reflectivity"; case VELOCITY_HI: case VELOCITY_LOW: return "RadialVelocity"; case SPECTRUM_WIDTH: return "SpectrumWidth"; case REFLECTIVITY_HIGH: return "Reflectivity_HI"; case VELOCITY_HIGH: return "RadialVelocity_HI"; case SPECTRUM_WIDTH_HIGH: return "SpectrumWidth_HI"; case DIFF_REFLECTIVITY_HIGH: return "Reflectivity_DIFF"; case DIFF_PHASE: return "Phase"; case CORRELATION_COEFFICIENT: return "RHO"; default: throw new IllegalArgumentException(); } } static public String getDatatypeUnits(int datatype) { switch (datatype) { case REFLECTIVITY: return "dBz"; case VELOCITY_HI: case VELOCITY_LOW: case SPECTRUM_WIDTH: return "m/s"; case REFLECTIVITY_HIGH: return "dBz"; case DIFF_REFLECTIVITY_HIGH: return "dBz"; case VELOCITY_HIGH: case SPECTRUM_WIDTH_HIGH: return "m/s"; case DIFF_PHASE: return "deg"; case CORRELATION_COEFFICIENT: return "N/A"; } throw new IllegalArgumentException(); } public short getDatatypeSNRThreshhold(int datatype) { switch (datatype) { case REFLECTIVITY_HIGH: return ref_snr_threshold; case VELOCITY_HIGH: return vel_snr_threshold; case SPECTRUM_WIDTH_HIGH: return sw_snr_threshold; case DIFF_REFLECTIVITY_HIGH: return zdrHR_snr_threshold; case DIFF_PHASE: return phiHR_snr_threshold; case CORRELATION_COEFFICIENT: return rhoHR_snr_threshold; default: throw new IllegalArgumentException(); } } public short getDatatypeRangeFoldingThreshhold(int datatype) { switch (datatype) { case REFLECTIVITY_HIGH: return ref_rf_threshold; case VELOCITY_HIGH: return vel_rf_threshold; case SPECTRUM_WIDTH_HIGH: return sw_rf_threshold; case REFLECTIVITY: case VELOCITY_LOW: case VELOCITY_HI: case SPECTRUM_WIDTH: return threshhold; case DIFF_REFLECTIVITY_HIGH: return zdrHR_rf_threshold; case DIFF_PHASE: return phiHR_rf_threshold; case CORRELATION_COEFFICIENT: return rhoHR_rf_threshold; default: throw new IllegalArgumentException(); } } public float getDatatypeScaleFactor(int datatype) { switch (datatype) { case REFLECTIVITY: return 0.5f; case VELOCITY_LOW: return 1.0f; case VELOCITY_HI: case SPECTRUM_WIDTH: return 0.5f; case REFLECTIVITY_HIGH: return 1 / reflectHR_scale; case VELOCITY_HIGH: return 1 / velocityHR_scale; case SPECTRUM_WIDTH_HIGH: return 1 / spectrumHR_scale; case DIFF_REFLECTIVITY_HIGH: return 1.0f / zdrHR_scale; case DIFF_PHASE: return 1.0f / phiHR_scale; case CORRELATION_COEFFICIENT: return 1.0f / rhoHR_scale; default: throw new IllegalArgumentException(); } } public float getDatatypeAddOffset(int datatype) { switch (datatype) { case REFLECTIVITY: return -33.0f; case VELOCITY_LOW: return -129.0f; case VELOCITY_HI: case SPECTRUM_WIDTH: return -64.5f; case REFLECTIVITY_HIGH: return reflectHR_addoffset * (-1) / reflectHR_scale; case VELOCITY_HIGH: return velocityHR_addoffset * (-1) / velocityHR_scale; case SPECTRUM_WIDTH_HIGH: return spectrumHR_addoffset * (-1) / spectrumHR_scale; case DIFF_REFLECTIVITY_HIGH: return zdrHR_addoffset * (-1) / zdrHR_scale; case DIFF_PHASE: return phiHR_addoffset * (-1) / phiHR_scale; case CORRELATION_COEFFICIENT: return rhoHR_addoffset * (-1) / rhoHR_scale; default: throw new IllegalArgumentException(); } } static public String getMessageTypeName(int code) { switch (code) { case 1: return "digital radar data"; case 2: return "RDA status data"; case 3: return "performance/maintainence data"; case 4: return "console message - RDA to RPG"; case 5: return "maintainence log data"; case 6: return "RDA control ocmmands"; case 7: return "volume coverage pattern"; case 8: return "clutter censor zones"; case 9: return "request for data"; case 10: return "console message - RPG to RDA"; case 11: return "loop back test - RDA to RPG"; case 12: return "loop back test - RPG to RDA"; case 13: return "clutter filter bypass map - RDA to RPG"; case 14: return "edited clutter filter bypass map - RDA to RPG"; case 15: return "Notchwidth Map"; case 18: return "RDA Adaptation data"; case 31: return "Digitail Radar Data Generic Format"; default: return "unknown " + code; } } static public String getRadialStatusName(int code) { switch (code) { case 0: return "start of new elevation"; case 1: return "intermediate radial"; case 2: return "end of elevation"; case 3: return "begin volume scan"; case 4: return "end volume scan"; default: return "unknown " + code; } } static public String getVolumeCoveragePatternName(int code) { switch (code) { case 11: return "16 elevation scans every 5 mins"; case 12: return "14 elevation scan every 4.1 mins"; case 21: return "11 elevation scans every 6 mins"; case 31: return "8 elevation scans every 10 mins"; case 32: return "7 elevation scans every 10 mins"; case 121: return "9 elevations, 20 scans every 5 minutes"; case 211: return "14 elevations, 16 scans every 5 mins"; case 212: return "14 elevations, 17 scans every 4 mins"; case 221: return "9 elevations, 11 scans every 5 minutes"; default: return "unknown " + code; } } static public java.util.Date getDate(int julianDays, int msecs) { long total = ((long) (julianDays - 1)) * 24 * 3600 * 1000 + msecs; return new Date(total); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////// int recno; // record number within the file long message_offset; // offset of start of message boolean hasReflectData, hasDopplerData; boolean hasHighResREFData; boolean hasHighResVELData; boolean hasHighResSWData; boolean hasHighResZDRData; boolean hasHighResPHIData; boolean hasHighResRHOData; // message header short message_size = 0; byte id_channel = 0; public byte message_type = 0; short id_sequence = 0; short mess_julian_date = 0; int mess_msecs = 0; short seg_count = 0; short seg_number = 0; // radar data header int data_msecs = 0; short data_julian_date = 0; short unamb_range = 0; int azimuth_ang = 0; short radial_num = 0; // radial number within the elevation : starts with one short radial_status = 0; short elevation_ang = 0; short elevation_num = 0; short reflect_first_gate = 0; // distance to first reflectivity gate (m) short reflect_gate_size = 0; // reflectivity gate size (m) short reflect_gate_count = 0; // number of reflectivity gates short doppler_first_gate = 0; // distance to first reflectivity gate (m) short doppler_gate_size = 0; // reflectivity gate size (m) short doppler_gate_count = 0; // number of reflectivity gates short cut = 0; float calibration = 0; // system gain calibration constant (db biased) short resolution = 0; // dopplar velocity resolution short vcp = 0; // volume coverage pattern short nyquist_vel; // nyquist velocity short attenuation; // atmospheric attenuation factor short threshhold; // threshhold paramter for minimum difference short ref_snr_threshold; // reflectivity signal to noise threshhold short vel_snr_threshold; short sw_snr_threshold; short zdrHR_snr_threshold; short phiHR_snr_threshold; short rhoHR_snr_threshold; short ref_rf_threshold; // reflectivity range folding threshhold short vel_rf_threshold; short sw_rf_threshold; short zdrHR_rf_threshold; short phiHR_rf_threshold; short rhoHR_rf_threshold; private short reflect_offset; // reflectivity data pointer (byte number from start of message) private short velocity_offset; // velocity data pointer (byte number from start of message) private short spectWidth_offset; // spectrum-width data pointer (byte number from start of message) // new addition for message type 31 short rlength = 0; String id; float azimuth; byte compressIdx; byte sp; byte ars; byte rs; float elevation; byte rsbs; byte aim; short dcount; int dbp1; int dbp2; int dbp3; int dbp4; int dbp5; int dbp6; int dbp7; int dbp8; int dbp9; short reflectHR_gate_count = 0; short velocityHR_gate_count = 0; short spectrumHR_gate_count = 0; float reflectHR_scale = 0; float velocityHR_scale = 0; float spectrumHR_scale = 0; float zdrHR_scale = 0; float phiHR_scale = 0; float rhoHR_scale = 0; float reflectHR_addoffset = 0; float velocityHR_addoffset = 0; float spectrumHR_addoffset = 0; float zdrHR_addoffset = 0; float phiHR_addoffset = 0; float rhoHR_addoffset = 0; short reflectHR_offset = 0; short velocityHR_offset = 0; short spectrumHR_offset = 0; short zdrHR_offset = 0; short phiHR_offset = 0; short rhoHR_offset = 0; short zdrHR_gate_count = 0; short phiHR_gate_count = 0; short rhoHR_gate_count = 0; short reflectHR_gate_size = 0; short velocityHR_gate_size = 0; short spectrumHR_gate_size = 0; short zdrHR_gate_size = 0; short phiHR_gate_size = 0; short rhoHR_gate_size = 0; short reflectHR_first_gate = 0; short velocityHR_first_gate = 0; short spectrumHR_first_gate = 0; short zdrHR_first_gate = 0; short phiHR_first_gate = 0; short rhoHR_first_gate = 0; public static Level2Record factory(RandomAccessFile din, int record, long message_offset31) throws IOException { long offset = record * RADAR_DATA_SIZE + FILE_HEADER_SIZE + message_offset31; if (offset >= din.length()) return null; else return new Level2Record(din, record, message_offset31); } public Level2Record(RandomAccessFile din, int record, long message_offset31) throws IOException { this.recno = record; message_offset = record * RADAR_DATA_SIZE + FILE_HEADER_SIZE + message_offset31; din.seek(message_offset); din.skipBytes(CTM_HEADER_SIZE); // Message Header // int size = din.readInt(); message_size = din.readShort(); // size in "halfwords" = 2 bytes id_channel = din.readByte(); // channel id message_type = din.readByte(); id_sequence = din.readShort(); mess_julian_date = din.readShort(); // from 1/1/70; prob "message generation time" mess_msecs = din.readInt(); // message generation time seg_count = din.readShort(); // number of message segments seg_number = din.readShort(); // this segment // if (message_type != 1 ) return; if (message_type == 1) { // data header data_msecs = din.readInt(); // collection time for this radial, msecs since midnight data_julian_date = din.readShort(); // prob "collection time" unamb_range = din.readShort(); // unambiguous range azimuth_ang = din.readUnsignedShort(); // LOOK why unsigned ?? radial_num = din.readShort(); // radial number within the elevation radial_status = din.readShort(); elevation_ang = din.readShort(); elevation_num = din.readShort(); // RDA elevation number reflect_first_gate = din.readShort(); // range to first gate of reflectivity (m) may be negetive doppler_first_gate = din.readShort(); // range to first gate of dopplar (m) may be negetive reflect_gate_size = din.readShort(); // reflectivity data gate size (m) doppler_gate_size = din.readShort(); // dopplar data gate size (m) reflect_gate_count = din.readShort(); // number of reflectivity gates doppler_gate_count = din.readShort(); // number of velocity or spectrum width gates cut = din.readShort(); // sector number within cut calibration = din.readFloat(); // system gain calibration constant (db biased) reflect_offset = din.readShort(); // reflectivity data pointer (byte number from start of message) velocity_offset = din.readShort(); // velocity data pointer (byte number from start of message) spectWidth_offset = din.readShort(); // spectrum-width data pointer (byte number from start of message) resolution = din.readShort(); // dopplar velocity resolution vcp = din.readShort(); // volume coverage pattern din.skipBytes(14); nyquist_vel = din.readShort(); // nyquist velocity attenuation = din.readShort(); // atmospheric attenuation factor threshhold = din.readShort(); // threshhold paramter for minimum difference hasReflectData = (reflect_gate_count > 0); hasDopplerData = (doppler_gate_count > 0); } else if (message_type == 31) { // data header id = din.readString(4); data_msecs = din.readInt(); // collection time for this radial, msecs since midnight data_julian_date = din.readShort(); // prob "collection time" radial_num = din.readShort(); // radial number within the elevation azimuth = din.readFloat(); // LOOK why unsigned ?? compressIdx = din.readByte(); sp = din.readByte(); rlength = din.readShort(); ars = din.readByte(); rs = din.readByte(); elevation_num = din.readByte(); // RDA elevation number cut = din.readByte(); // sector number within cut elevation = din.readFloat(); rsbs = din.readByte(); aim = din.readByte(); dcount = din.readShort(); dbp1 = din.readInt(); dbp2 = din.readInt(); dbp3 = din.readInt(); dbp4 = din.readInt(); dbp5 = din.readInt(); dbp6 = din.readInt(); dbp7 = din.readInt(); dbp8 = din.readInt(); dbp9 = din.readInt(); vcp = getDataBlockValue(din, (short) dbp1, 40); int dbpp4 = 0; int dbpp5 = 0; int dbpp6 = 0; int dbpp7 = 0; int dbpp8 = 0; int dbpp9 = 0; if (dbp4 > 0) { String tname = getDataBlockStringValue(din, (short) dbp4, 1, 3); if (tname.startsWith("REF")) { hasHighResREFData = true; dbpp4 = dbp4; } else if (tname.startsWith("VEL")) { hasHighResVELData = true; dbpp5 = dbp4; } else if (tname.startsWith("SW")) { hasHighResSWData = true; dbpp6 = dbp4; } else if (tname.startsWith("ZDR")) { hasHighResZDRData = true; dbpp7 = dbp4; } else if (tname.startsWith("PHI")) { hasHighResPHIData = true; dbpp8 = dbp4; } else if (tname.startsWith("RHO")) { hasHighResRHOData = true; dbpp9 = dbp4; } else { logger.warn("Missing radial product dbp4={} tname={}", dbp4, tname); } } if (dbp5 > 0) { String tname = getDataBlockStringValue(din, (short) dbp5, 1, 3); if (tname.startsWith("REF")) { hasHighResREFData = true; dbpp4 = dbp5; } else if (tname.startsWith("VEL")) { hasHighResVELData = true; dbpp5 = dbp5; } else if (tname.startsWith("SW")) { hasHighResSWData = true; dbpp6 = dbp5; } else if (tname.startsWith("ZDR")) { hasHighResZDRData = true; dbpp7 = dbp5; } else if (tname.startsWith("PHI")) { hasHighResPHIData = true; dbpp8 = dbp5; } else if (tname.startsWith("RHO")) { hasHighResRHOData = true; dbpp9 = dbp5; } else { logger.warn("Missing radial product dbp5={} tname={}", dbp5, tname); } } if (dbp6 > 0) { String tname = getDataBlockStringValue(din, (short) dbp6, 1, 3); if (tname.startsWith("REF")) { hasHighResREFData = true; dbpp4 = dbp6; } else if (tname.startsWith("VEL")) { hasHighResVELData = true; dbpp5 = dbp6; } else if (tname.startsWith("SW")) { hasHighResSWData = true; dbpp6 = dbp6; } else if (tname.startsWith("ZDR")) { hasHighResZDRData = true; dbpp7 = dbp6; } else if (tname.startsWith("PHI")) { hasHighResPHIData = true; dbpp8 = dbp6; } else if (tname.startsWith("RHO")) { hasHighResRHOData = true; dbpp9 = dbp6; } else { logger.warn("Missing radial product dbp6={} tname={}", dbp6, tname); } } if (dbp7 > 0) { String tname = getDataBlockStringValue(din, (short) dbp7, 1, 3); if (tname.startsWith("REF")) { hasHighResREFData = true; dbpp4 = dbp7; } else if (tname.startsWith("VEL")) { hasHighResVELData = true; dbpp5 = dbp7; } else if (tname.startsWith("SW")) { hasHighResSWData = true; dbpp6 = dbp7; } else if (tname.startsWith("ZDR")) { hasHighResZDRData = true; dbpp7 = dbp7; } else if (tname.startsWith("PHI")) { hasHighResPHIData = true; dbpp8 = dbp7; } else if (tname.startsWith("RHO")) { hasHighResRHOData = true; dbpp9 = dbp7; } else { logger.warn("Missing radial product dbp7={} tname={}", dbp7, tname); } } if (dbp8 > 0) { String tname = getDataBlockStringValue(din, (short) dbp8, 1, 3); if (tname.startsWith("REF")) { hasHighResREFData = true; dbpp4 = dbp8; } else if (tname.startsWith("VEL")) { hasHighResVELData = true; dbpp5 = dbp8; } else if (tname.startsWith("SW")) { hasHighResSWData = true; dbpp6 = dbp8; } else if (tname.startsWith("ZDR")) { hasHighResZDRData = true; dbpp7 = dbp8; } else if (tname.startsWith("PHI")) { hasHighResPHIData = true; dbpp8 = dbp8; } else if (tname.startsWith("RHO")) { hasHighResRHOData = true; dbpp9 = dbp8; } else { logger.warn("Missing radial product dbp8={} tname={}", dbp8, tname); } } if (dbp9 > 0) { String tname = getDataBlockStringValue(din, (short) dbp9, 1, 3); if (tname.startsWith("REF")) { hasHighResREFData = true; dbpp4 = dbp9; } else if (tname.startsWith("VEL")) { hasHighResVELData = true; dbpp5 = dbp9; } else if (tname.startsWith("SW")) { hasHighResSWData = true; dbpp6 = dbp9; } else if (tname.startsWith("ZDR")) { hasHighResZDRData = true; dbpp7 = dbp9; } else if (tname.startsWith("PHI")) { hasHighResPHIData = true; dbpp8 = dbp9; } else if (tname.startsWith("RHO")) { hasHighResRHOData = true; dbpp9 = dbp9; } else { logger.warn("Missing radial product dbp9={} tname={}", dbp9, tname); } } //hasHighResREFData = (dbp4 > 0); if (hasHighResREFData) { reflectHR_gate_count = getDataBlockValue(din, (short) dbpp4, 8); reflectHR_first_gate = getDataBlockValue(din, (short) dbpp4, 10); reflectHR_gate_size = getDataBlockValue(din, (short) dbpp4, 12); ref_rf_threshold = getDataBlockValue(din, (short) dbpp4, 14); ref_snr_threshold = getDataBlockValue(din, (short) dbpp4, 16); reflectHR_scale = getDataBlockValue1(din, (short) dbpp4, 20); reflectHR_addoffset = getDataBlockValue1(din, (short) dbpp4, 24); reflectHR_offset = (short) (dbpp4 + 28); } //hasHighResVELData = (dbp5 > 0); if (hasHighResVELData) { velocityHR_gate_count = getDataBlockValue(din, (short) dbpp5, 8); velocityHR_first_gate = getDataBlockValue(din, (short) dbpp5, 10); velocityHR_gate_size = getDataBlockValue(din, (short) dbpp5, 12); vel_rf_threshold = getDataBlockValue(din, (short) dbpp5, 14); vel_snr_threshold = getDataBlockValue(din, (short) dbpp5, 16); velocityHR_scale = getDataBlockValue1(din, (short) dbpp5, 20); velocityHR_addoffset = getDataBlockValue1(din, (short) dbpp5, 24); velocityHR_offset = (short) (dbpp5 + 28); } // hasHighResSWData = (dbp6 > 0); if (hasHighResSWData) { spectrumHR_gate_count = getDataBlockValue(din, (short) dbpp6, 8); spectrumHR_first_gate = getDataBlockValue(din, (short) dbpp6, 10); spectrumHR_gate_size = getDataBlockValue(din, (short) dbpp6, 12); sw_rf_threshold = getDataBlockValue(din, (short) dbpp6, 14); sw_snr_threshold = getDataBlockValue(din, (short) dbpp6, 16); spectrumHR_scale = getDataBlockValue1(din, (short) dbpp6, 20); spectrumHR_addoffset = getDataBlockValue1(din, (short) dbpp6, 24); spectrumHR_offset = (short) (dbpp6 + 28); } // hasHighResZDRData = (dbp7 > 0); if (hasHighResZDRData) { zdrHR_gate_count = getDataBlockValue(din, (short) dbpp7, 8); zdrHR_first_gate = getDataBlockValue(din, (short) dbpp7, 10); zdrHR_gate_size = getDataBlockValue(din, (short) dbpp7, 12); zdrHR_rf_threshold = getDataBlockValue(din, (short) dbpp7, 14); zdrHR_snr_threshold = getDataBlockValue(din, (short) dbpp7, 16); zdrHR_scale = getDataBlockValue1(din, (short) dbpp7, 20); zdrHR_addoffset = getDataBlockValue1(din, (short) dbpp7, 24); zdrHR_offset = (short) (dbpp7 + 28); } //hasHighResPHIData = (dbp8 > 0); if (hasHighResPHIData) { phiHR_gate_count = getDataBlockValue(din, (short) dbpp8, 8); phiHR_first_gate = getDataBlockValue(din, (short) dbpp8, 10); phiHR_gate_size = getDataBlockValue(din, (short) dbpp8, 12); phiHR_rf_threshold = getDataBlockValue(din, (short) dbpp8, 14); phiHR_snr_threshold = getDataBlockValue(din, (short) dbpp8, 16); phiHR_scale = getDataBlockValue1(din, (short) dbpp8, 20); phiHR_addoffset = getDataBlockValue1(din, (short) dbpp8, 24); phiHR_offset = (short) (dbpp8 + 28); } //hasHighResRHOData = (dbp9 > 0); if (hasHighResRHOData) { rhoHR_gate_count = getDataBlockValue(din, (short) dbpp9, 8); rhoHR_first_gate = getDataBlockValue(din, (short) dbpp9, 10); rhoHR_gate_size = getDataBlockValue(din, (short) dbpp9, 12); rhoHR_rf_threshold = getDataBlockValue(din, (short) dbpp9, 14); rhoHR_snr_threshold = getDataBlockValue(din, (short) dbpp9, 16); rhoHR_scale = getDataBlockValue1(din, (short) dbpp9, 20); rhoHR_addoffset = getDataBlockValue1(din, (short) dbpp9, 24); rhoHR_offset = (short) (dbpp9 + 28); } } } public void dumpMessage(PrintStream out) { out.println(recno + " ---------------------"); out.println(" message type = " + getMessageTypeName(message_type) + " (" + message_type + ")"); out.println(" message size = " + message_size + " segment=" + seg_number + "/" + seg_count); } public void dump(PrintStream out) { out.println(recno + " ------------------------------------------" + message_offset); out.println(" message type = " + getMessageTypeName(message_type)); out.println(" data date = " + data_julian_date + " : " + data_msecs); out.println(" elevation = " + getElevation() + " (" + elevation_num + ")"); out.println(" azimuth = " + getAzimuth()); out.println(" radial = " + radial_num + " status= " + getRadialStatusName(radial_status) + " ratio = " + getAzimuth() / radial_num); out.println(" reflectivity first= " + reflect_first_gate + " size= " + reflect_gate_size + " count= " + reflect_gate_count); out.println(" doppler first= " + doppler_first_gate + " size= " + doppler_gate_size + " count= " + doppler_gate_count); out.println(" offset: reflect= " + reflect_offset + " velocity= " + velocity_offset + " spWidth= " + spectWidth_offset); out.println(" pattern = " + vcp + " cut= " + cut); } public void dump2(PrintStream out) { out.println("recno= " + recno + " massType= " + message_type + " massSize = " + message_size); } public boolean checkOk() { boolean ok = true; if (Float.isNaN(getAzimuth())) { logger.warn("****" + recno + " HAS bad azimuth value = " + azimuth_ang); ok = false; } if (message_type != 1) return ok; if ((seg_count != 1) || (seg_number != 1)) { logger.warn("*** segment = " + seg_number + "/" + seg_count + who()); } if ((reflect_offset < 0) || (reflect_offset > RADAR_DATA_SIZE)) { logger.warn("****" + recno + " HAS bad reflect offset= " + reflect_offset + who()); ok = false; } if ((velocity_offset < 0) || (velocity_offset > RADAR_DATA_SIZE)) { logger.warn("****" + recno + " HAS bad velocity offset= " + velocity_offset + who()); ok = false; } if ((spectWidth_offset < 0) || (spectWidth_offset > RADAR_DATA_SIZE)) { logger.warn("****" + recno + " HAS bad spwidth offset= " + spectWidth_offset + who()); ok = false; } if ((velocity_offset > 0) && (spectWidth_offset <= 0)) { logger.warn("****" + recno + " HAS velocity NOT spectWidth!!" + who()); ok = false; } if ((velocity_offset <= 0) && (spectWidth_offset > 0)) { logger.warn("****" + recno + " HAS spectWidth AND NOT velocity!!" + who()); ok = false; } if (mess_julian_date != data_julian_date) { logger.warn("*** message date = " + mess_julian_date + " : " + mess_msecs + who() + "\n" + " data date = " + data_julian_date + " : " + data_msecs); ok = false; } if (!hasReflectData && !hasDopplerData) { logger.info("*** no reflect or dopplar = " + who()); } return ok; } private String who() { return " message(" + recno + " " + message_offset + ")"; } /** * Get the azimuth in degrees * * @return azimuth angle in degrees 0 = true north, 90 = east */ public float getAzimuth() { if (message_type == 31) return azimuth; else if (message_type == 1) return 180.0f * azimuth_ang / 32768.0f; else return -1.0f; } /** * Get the elevation angle in degrees * * @return elevation angle in degrees 0 = parellel to pedestal base, 90 = perpendicular */ public float getElevation() { if (message_type == 31) return elevation; else if (message_type == 1) return 180.0f * elevation_ang / 32768.0f; else return -1.0f; } /** * This method returns the gate size in meters * * @param datatype which type of data : REFLECTIVITY, VELOCITY_HI, VELOCITY_LO, SPECTRUM_WIDTH * @return the gate size in meters */ public int getGateSize(int datatype) { switch (datatype) { case REFLECTIVITY: return ((int) reflect_gate_size); case VELOCITY_HI: case VELOCITY_LOW: case SPECTRUM_WIDTH: return ((int) doppler_gate_size); //high resolution case REFLECTIVITY_HIGH: return ((int) reflectHR_gate_size); case VELOCITY_HIGH: return ((int) velocityHR_gate_size); case SPECTRUM_WIDTH_HIGH: return ((int) spectrumHR_gate_size); case DIFF_REFLECTIVITY_HIGH: return ((int) zdrHR_gate_size); case DIFF_PHASE: return ((int) phiHR_gate_size); case CORRELATION_COEFFICIENT: return ((int) rhoHR_gate_size); } return -1; } /** * This method returns the starting gate in meters * * @param datatype which type of data : REFLECTIVITY, VELOCITY_HI, VELOCITY_LO, SPECTRUM_WIDTH * @return the starting gate in meters */ public int getGateStart(int datatype) { switch (datatype) { case REFLECTIVITY: return ((int) reflect_first_gate); case VELOCITY_HI: case VELOCITY_LOW: case SPECTRUM_WIDTH: return ((int) doppler_first_gate); //high resolution case REFLECTIVITY_HIGH: return ((int) reflectHR_first_gate); case VELOCITY_HIGH: return ((int) velocityHR_first_gate); case SPECTRUM_WIDTH_HIGH: return ((int) spectrumHR_first_gate); case DIFF_REFLECTIVITY_HIGH: return ((int) zdrHR_first_gate); case DIFF_PHASE: return ((int) phiHR_first_gate); case CORRELATION_COEFFICIENT: return ((int) rhoHR_first_gate); } return -1; } /** * This method returns the number of gates * * @param datatype which type of data : REFLECTIVITY, VELOCITY_HI, VELOCITY_LO, SPECTRUM_WIDTH * @return the number of gates */ public int getGateCount(int datatype) { switch (datatype) { case REFLECTIVITY: return ((int) reflect_gate_count); case VELOCITY_HI: case VELOCITY_LOW: case SPECTRUM_WIDTH: return ((int) doppler_gate_count); // hight resolution case REFLECTIVITY_HIGH: return ((int) reflectHR_gate_count); case VELOCITY_HIGH: return ((int) velocityHR_gate_count); case SPECTRUM_WIDTH_HIGH: return ((int) spectrumHR_gate_count); case DIFF_REFLECTIVITY_HIGH: return ((int) zdrHR_gate_count); case DIFF_PHASE: return ((int) phiHR_gate_count); case CORRELATION_COEFFICIENT: return ((int) rhoHR_gate_count); } return 0; } private short getDataOffset(int datatype) { switch (datatype) { case REFLECTIVITY: return reflect_offset; case VELOCITY_HI: case VELOCITY_LOW: return velocity_offset; case SPECTRUM_WIDTH: return spectWidth_offset; case REFLECTIVITY_HIGH: return reflectHR_offset; case VELOCITY_HIGH: return velocityHR_offset; case SPECTRUM_WIDTH_HIGH: return spectrumHR_offset; case DIFF_REFLECTIVITY_HIGH: return zdrHR_offset; case DIFF_PHASE: return phiHR_offset; case CORRELATION_COEFFICIENT: return rhoHR_offset; } return Short.MIN_VALUE; } private short getDataBlockValue(RandomAccessFile raf, short offset, int skip) throws IOException { long off = offset + message_offset + MESSAGE_HEADER_SIZE; raf.seek(off); raf.skipBytes(skip); return raf.readShort(); } private String getDataBlockStringValue(RandomAccessFile raf, short offset, int skip, int size) throws IOException { long off = offset + message_offset + MESSAGE_HEADER_SIZE; raf.seek(off); raf.skipBytes(skip); return raf.readString(size); } private float getDataBlockValue1(RandomAccessFile raf, short offset, int skip) throws IOException { long off = offset + message_offset + MESSAGE_HEADER_SIZE; raf.seek(off); raf.skipBytes(skip); return raf.readFloat(); } public java.util.Date getDate() { return getDate(data_julian_date, data_msecs); } /** * Read data from this record. * * @param raf read from this file * @param datatype which type of data : REFLECTIVITY, VELOCITY_HI, VELOCITY_LO, SPECTRUM_WIDTH * @param gateRange handles the possible subset of data to return * @param ii put the data here * @throws IOException on read error */ public void readData(RandomAccessFile raf, int datatype, Range gateRange, IndexIterator ii) throws IOException { long offset = message_offset; offset += MESSAGE_HEADER_SIZE; // offset is from "start of digital radar data message header" offset += getDataOffset(datatype); raf.seek(offset); if (logger.isDebugEnabled()) { logger.debug(" read recno " + recno + " at offset " + offset + " count= " + getGateCount(datatype)); logger.debug(" offset: reflect= " + reflect_offset + " velocity= " + velocity_offset + " spWidth= " + spectWidth_offset); } int dataCount = getGateCount(datatype); if (datatype == DIFF_PHASE) { short[] data = new short[dataCount]; raf.readShort(data, 0, dataCount); for (int gateIdx : gateRange) { if (gateIdx >= dataCount) ii.setShortNext(MISSING_DATA); else ii.setShortNext(data[gateIdx]); } } else { byte[] data = new byte[dataCount]; raf.readFully(data); //short [] ds = convertunsignedByte2Short(data); for (int gateIdx : gateRange) { if (gateIdx >= dataCount) ii.setByteNext(MISSING_DATA); else ii.setByteNext(data[gateIdx]); } } } /** * Instances which have same content are equal. *

* public boolean equals(Object oo) { * if (this == oo) return true; * if ( !(oo instanceof Level2Record)) return false; * return hashCode() == oo.hashCode(); * } *

* /** Override Object.hashCode() to implement equals. * * public int hashCode() { * if (hashCode == 0) { * int result = 17; * result = 37*result + elevation_num; * //result = 37*result + cut; * //result = 37*result + datatype; * hashCode = result; * } * return hashCode; * } * private volatile int hashCode = 0; */ public short[] convertunsignedByte2Short(byte[] inb) { int len = inb.length; short[] outs = new short[len]; int i = 0; for (byte b : inb) { outs[i++] = convertunsignedByte2Short(b); } return outs; } public short convertunsignedByte2Short(byte b) { return (short) ((b < 0) ? (short) b + 256 : (short) b); } public String toString() { return "elev= " + elevation_num + " radial_num = " + radial_num; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy