Merge "Omaha #3226 added total lightning decoder" into omaha_14.4.1
Former-commit-id: ffa3e069c0beb5678ecb863b2950556d8c289ae1
This commit is contained in:
commit
c8b6324240
33 changed files with 1724 additions and 701 deletions
|
@ -0,0 +1,37 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<!--
|
||||||
|
This_software_was_developed_and_/_or_modified_by_Raytheon_Company,
|
||||||
|
pursuant_to_Contract_DG133W-05-CQ-1067_with_the_US_Government.
|
||||||
|
|
||||||
|
U.S._EXPORT_CONTROLLED_TECHNICAL_DATA
|
||||||
|
This_software_product_contains_export-restricted_data_whose
|
||||||
|
export/transfer/disclosure_is_restricted_by_U.S._law._Dissemination
|
||||||
|
to_non-U.S._persons_whether_in_the_United_States_or_abroad_requires
|
||||||
|
an_export_license_or_other_authorization.
|
||||||
|
|
||||||
|
Contractor_Name:________Raytheon_Company
|
||||||
|
Contractor_Address:_____6825_Pine_Street,_Suite_340
|
||||||
|
________________________Mail_Stop_B8
|
||||||
|
________________________Omaha,_NE_68106
|
||||||
|
________________________402.291.0100
|
||||||
|
|
||||||
|
See_the_AWIPS_II_Master_Rights_File_("Master_Rights_File.pdf")_for
|
||||||
|
further_licensing_information.
|
||||||
|
-->
|
||||||
|
<menuTemplate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<contribute xsi:type="bundleItem" file="bundles/LightningPlot60Min.xml"
|
||||||
|
menuText="1hr CG flash plot" id="1HrLightningFlashPlot">
|
||||||
|
</contribute>
|
||||||
|
<contribute xsi:type="bundleItem" file="bundles/LightningPlot15Min.xml"
|
||||||
|
menuText="15min CG flash plot" id="15MinLightningFlashPlot">
|
||||||
|
</contribute>
|
||||||
|
<contribute xsi:type="bundleItem" file="bundles/LightningPlot15MinPN.xml"
|
||||||
|
menuText="15min Pos/Neg CG flash plot" id="15MinPNLightningFlashPlot">
|
||||||
|
</contribute>
|
||||||
|
<contribute xsi:type="bundleItem" file="bundles/LightningPlot5Min.xml"
|
||||||
|
menuText="5min CG flash plot" id="5MinLightningFlashPlot">
|
||||||
|
</contribute>
|
||||||
|
<contribute xsi:type="bundleItem" file="bundles/LightningSeq.xml"
|
||||||
|
menuText="1min Lgtng Seq CG flash" id="1MinLightningFlashSeq">
|
||||||
|
</contribute>
|
||||||
|
</menuTemplate>
|
|
@ -20,27 +20,18 @@
|
||||||
-->
|
-->
|
||||||
<menuTemplate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
<menuTemplate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
<contribute xsi:type="bundleItem" file="bundles/LightningPlot60Min.xml"
|
<contribute xsi:type="bundleItem" file="bundles/LightningPlot60Min.xml"
|
||||||
menuText="1hr CG stroke plot" id="1HrLightningStrokePlot"
|
menuText="1hr CG stroke plot" id="1HrLightningStrokePlot">
|
||||||
productInterval="3600">
|
|
||||||
<dataURI>/binlightning/%</dataURI>
|
|
||||||
</contribute>
|
</contribute>
|
||||||
<contribute xsi:type="bundleItem" file="bundles/LightningPlot15Min.xml"
|
<contribute xsi:type="bundleItem" file="bundles/LightningPlot15Min.xml"
|
||||||
menuText="15min CG stroke plot" id="15MinLightningStrokePlot"
|
menuText="15min CG stroke plot" id="15MinLightningStrokePlot">
|
||||||
productInterval="900">
|
|
||||||
<dataURI>/binlightning/%</dataURI>
|
|
||||||
</contribute>
|
</contribute>
|
||||||
<contribute xsi:type="bundleItem" file="bundles/LightningPlot15MinPN.xml"
|
<contribute xsi:type="bundleItem" file="bundles/LightningPlot15MinPN.xml"
|
||||||
menuText="15min Pos/Neg CG stroke plot" id="15MinPNLightningStrokePlot"
|
menuText="15min Pos/Neg CG stroke plot" id="15MinPNLightningStrokePlot">
|
||||||
productInterval="900">
|
|
||||||
<dataURI>/binlightning/%</dataURI>
|
|
||||||
</contribute>
|
</contribute>
|
||||||
<contribute xsi:type="bundleItem" file="bundles/LightningPlot5Min.xml"
|
<contribute xsi:type="bundleItem" file="bundles/LightningPlot5Min.xml"
|
||||||
menuText="5min CG stroke plot" id="5MinLightningStrokePlot"
|
menuText="5min CG stroke plot" id="5MinLightningStrokePlot">
|
||||||
productInterval="300">
|
|
||||||
<dataURI>/binlightning/%</dataURI>
|
|
||||||
</contribute>
|
</contribute>
|
||||||
<contribute xsi:type="bundleItem" file="bundles/LightningSeq.xml"
|
<contribute xsi:type="bundleItem" file="bundles/LightningSeq.xml"
|
||||||
menuText="1min Lgtng Seq CG stroke" id="1MinLightningStrokeSeq">
|
menuText="1min Lgtng Seq CG stroke" id="1MinLightningStrokeSeq">
|
||||||
<dataURI>/binlightning/%</dataURI>
|
|
||||||
</contribute>
|
</contribute>
|
||||||
</menuTemplate>
|
</menuTemplate>
|
|
@ -29,4 +29,9 @@
|
||||||
<substitute key="source" value="GLD"/>
|
<substitute key="source" value="GLD"/>
|
||||||
</contribute>
|
</contribute>
|
||||||
</contribute>
|
</contribute>
|
||||||
|
<contribute xsi:type="subMenu" menuText="Total Lightning" id="ENTLNSubMenu">
|
||||||
|
<contribute xsi:type="subinclude" fileName="menus/lightning/entlnLightningBundleItems.xml">
|
||||||
|
<substitute key="source" value="ENTLN"/>
|
||||||
|
</contribute>
|
||||||
|
</contribute>
|
||||||
</menuTemplate>
|
</menuTemplate>
|
|
@ -20,27 +20,18 @@
|
||||||
-->
|
-->
|
||||||
<menuTemplate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
<menuTemplate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
<contribute xsi:type="bundleItem" file="bundles/LightningPlot60Min.xml"
|
<contribute xsi:type="bundleItem" file="bundles/LightningPlot60Min.xml"
|
||||||
menuText="1hr CG flash plot" id="1HrLightningFlashPlot"
|
menuText="1hr CG flash plot" id="1HrLightningFlashPlot">
|
||||||
productInterval="3600">
|
|
||||||
<dataURI>/binlightning/%</dataURI>
|
|
||||||
</contribute>
|
</contribute>
|
||||||
<contribute xsi:type="bundleItem" file="bundles/LightningPlot15Min.xml"
|
<contribute xsi:type="bundleItem" file="bundles/LightningPlot15Min.xml"
|
||||||
menuText="15min CG flash plot" id="15MinLightningFlashPlot"
|
menuText="15min CG flash plot" id="15MinLightningFlashPlot">
|
||||||
productInterval="900">
|
|
||||||
<dataURI>/binlightning/%</dataURI>
|
|
||||||
</contribute>
|
</contribute>
|
||||||
<contribute xsi:type="bundleItem" file="bundles/LightningPlot15MinPN.xml"
|
<contribute xsi:type="bundleItem" file="bundles/LightningPlot15MinPN.xml"
|
||||||
menuText="15min Pos/Neg CG flash plot" id="15MinPNLightningFlashPlot"
|
menuText="15min Pos/Neg CG flash plot" id="15MinPNLightningFlashPlot">
|
||||||
productInterval="900">
|
|
||||||
<dataURI>/binlightning/%</dataURI>
|
|
||||||
</contribute>
|
</contribute>
|
||||||
<contribute xsi:type="bundleItem" file="bundles/LightningPlot5Min.xml"
|
<contribute xsi:type="bundleItem" file="bundles/LightningPlot5Min.xml"
|
||||||
menuText="5min CG flash plot" id="5MinLightningFlashPlot"
|
menuText="5min CG flash plot" id="5MinLightningFlashPlot">
|
||||||
productInterval="300">
|
|
||||||
<dataURI>/binlightning/%</dataURI>
|
|
||||||
</contribute>
|
</contribute>
|
||||||
<contribute xsi:type="bundleItem" file="bundles/LightningSeq.xml"
|
<contribute xsi:type="bundleItem" file="bundles/LightningSeq.xml"
|
||||||
menuText="1min Lgtng Seq CG flash" id="1MinLightningFlashSeq">
|
menuText="1min Lgtng Seq CG flash" id="1MinLightningFlashSeq">
|
||||||
<dataURI>/binlightning/%</dataURI>
|
|
||||||
</contribute>
|
</contribute>
|
||||||
</menuTemplate>
|
</menuTemplate>
|
|
@ -35,6 +35,7 @@ import org.opengis.referencing.crs.CoordinateReferenceSystem;
|
||||||
import com.raytheon.uf.common.dataplugin.HDF5Util;
|
import com.raytheon.uf.common.dataplugin.HDF5Util;
|
||||||
import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
||||||
import com.raytheon.uf.common.dataplugin.binlightning.BinLightningRecord;
|
import com.raytheon.uf.common.dataplugin.binlightning.BinLightningRecord;
|
||||||
|
import com.raytheon.uf.common.dataplugin.binlightning.LightningConstants;
|
||||||
import com.raytheon.uf.common.datastorage.DataStoreFactory;
|
import com.raytheon.uf.common.datastorage.DataStoreFactory;
|
||||||
import com.raytheon.uf.common.datastorage.IDataStore;
|
import com.raytheon.uf.common.datastorage.IDataStore;
|
||||||
import com.raytheon.uf.common.datastorage.Request;
|
import com.raytheon.uf.common.datastorage.Request;
|
||||||
|
@ -94,6 +95,7 @@ import com.raytheon.uf.viz.core.rsc.capabilities.MagnificationCapability;
|
||||||
* fields when magnification set to 0
|
* fields when magnification set to 0
|
||||||
* Feb 27, 2013 DCS 152 jgerth/elau Support for WWLLN and multiple sources
|
* Feb 27, 2013 DCS 152 jgerth/elau Support for WWLLN and multiple sources
|
||||||
* Jan 21, 2014 2667 bclement renamed record's lightSource field to source
|
* Jan 21, 2014 2667 bclement renamed record's lightSource field to source
|
||||||
|
* Jun 05, 2014 3226 bclement reference datarecords by LightningConstants
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -637,7 +639,15 @@ public class LightningResource extends
|
||||||
recordList.add(rec);
|
recordList.add(rec);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<IDataRecord> times = recordMap.get("obsTime");
|
List<IDataRecord> times = recordMap
|
||||||
|
.get(LightningConstants.TIME_DATASET);
|
||||||
|
|
||||||
|
List<IDataRecord> intensities = recordMap
|
||||||
|
.get(LightningConstants.INTENSITY_DATASET);
|
||||||
|
List<IDataRecord> lats = recordMap
|
||||||
|
.get(LightningConstants.LAT_DATASET);
|
||||||
|
List<IDataRecord> lons = recordMap
|
||||||
|
.get(LightningConstants.LON_DATASET);
|
||||||
|
|
||||||
int k = 0;
|
int k = 0;
|
||||||
for (IDataRecord timeRec : times) {
|
for (IDataRecord timeRec : times) {
|
||||||
|
@ -647,12 +657,13 @@ public class LightningResource extends
|
||||||
int numRecords = (int) time.getSizes()[0];
|
int numRecords = (int) time.getSizes()[0];
|
||||||
|
|
||||||
long[] timeData = time.getLongData();
|
long[] timeData = time.getLongData();
|
||||||
int[] intensityData = ((IntegerDataRecord) recordMap.get(
|
|
||||||
"intensity").get(k)).getIntData();
|
int[] intensityData = ((IntegerDataRecord) intensities
|
||||||
float[] latitudeData = ((FloatDataRecord) recordMap.get(
|
.get(k)).getIntData();
|
||||||
"latitude").get(k)).getFloatData();
|
float[] latitudeData = ((FloatDataRecord) lats.get(k))
|
||||||
float[] longitudeData = ((FloatDataRecord) recordMap.get(
|
.getFloatData();
|
||||||
"longitude").get(k)).getFloatData();
|
float[] longitudeData = ((FloatDataRecord) lons.get(k))
|
||||||
|
.getFloatData();
|
||||||
|
|
||||||
for (int i = 0; i < numRecords; i++) {
|
for (int i = 0; i < numRecords; i++) {
|
||||||
|
|
||||||
|
|
27
deltaScripts/14.4.1/DR3213/renameLightningStrikeCount.py
Executable file
27
deltaScripts/14.4.1/DR3213/renameLightningStrikeCount.py
Executable file
|
@ -0,0 +1,27 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import h5py
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# multiplicity was incorrectly interpreted as 'stike count' when
|
||||||
|
# it was the number of strokes (AKA pulses) in the strike (AKA flash)
|
||||||
|
|
||||||
|
LIGHTNING_H5_PATH = '/awips2/edex/data/hdf5/binlightning'
|
||||||
|
OLD_NAME = 'strikeCount'
|
||||||
|
NEW_NAME = 'pulseCount'
|
||||||
|
|
||||||
|
for file in os.listdir(LIGHTNING_H5_PATH):
|
||||||
|
if file.endswith('h5'):
|
||||||
|
h5file = None
|
||||||
|
try:
|
||||||
|
fileName = os.path.join(LIGHTNING_H5_PATH, file)
|
||||||
|
h5file = h5py.File(fileName, 'r+')
|
||||||
|
for g in h5file.values():
|
||||||
|
if NEW_NAME not in g and OLD_NAME in g:
|
||||||
|
g[NEW_NAME] = g[OLD_NAME]
|
||||||
|
except Exception, e:
|
||||||
|
print "Error renaming strikeCount in file", fileName, ":", e
|
||||||
|
finally:
|
||||||
|
if h5file:
|
||||||
|
h5file.close()
|
|
@ -9,6 +9,7 @@ Export-Package: com.raytheon.edex.plugin.binlightning.dao
|
||||||
Import-Package: com.raytheon.edex.esb,
|
Import-Package: com.raytheon.edex.esb,
|
||||||
com.raytheon.edex.exception,
|
com.raytheon.edex.exception,
|
||||||
com.raytheon.edex.plugin,
|
com.raytheon.edex.plugin,
|
||||||
|
com.raytheon.uf.common.numeric,
|
||||||
com.raytheon.uf.common.status,
|
com.raytheon.uf.common.status,
|
||||||
com.raytheon.uf.common.wmo,
|
com.raytheon.uf.common.wmo,
|
||||||
gov.noaa.nws.ost.edex.plugin.binlightning,
|
gov.noaa.nws.ost.edex.plugin.binlightning,
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
<bean id="binlightningDecoder"
|
<bean id="binlightningDecoder"
|
||||||
class="com.raytheon.edex.plugin.binlightning.BinLightningDecoder" />
|
class="com.raytheon.edex.plugin.binlightning.BinLightningDecoder" />
|
||||||
|
|
||||||
|
<bean id="totalLightningDecoder" class="com.raytheon.edex.plugin.binlightning.total.TotalLightningDecoder" />
|
||||||
|
|
||||||
<bean id="binlightningDistRegistry" factory-bean="distributionSrv"
|
<bean id="binlightningDistRegistry" factory-bean="distributionSrv"
|
||||||
factory-method="register">
|
factory-method="register">
|
||||||
|
@ -16,42 +18,37 @@
|
||||||
<constructor-arg ref="clusteredBinLightningRoutes" />
|
<constructor-arg ref="clusteredBinLightningRoutes" />
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<camelContext id="clusteredBinLightningRoutes"
|
<camelContext id="clusteredBinLightningRoutes" xmlns="http://camel.apache.org/schema/spring"
|
||||||
xmlns="http://camel.apache.org/schema/spring"
|
errorHandlerRef="errorHandler">
|
||||||
errorHandlerRef="errorHandler">
|
|
||||||
<!--
|
|
||||||
<endpoint id="binlightningFileEndpoint"
|
|
||||||
uri="file:${edex.home}/data/sbn/binlightning?noop=true&idempotent=false" />
|
|
||||||
|
|
||||||
<route id="binlightningFileConsumerRoute">
|
|
||||||
<from ref="binlightningFileEndpoint" />
|
|
||||||
<bean ref="fileToString" />
|
|
||||||
<setHeader headerName="pluginName">
|
|
||||||
<constant>binlightning</constant>
|
|
||||||
</setHeader>
|
|
||||||
<to uri="jms-durable:queue:Ingest.binlightning" />
|
|
||||||
</route>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!-- Begin binlightning routes -->
|
<!-- Begin binlightning routes -->
|
||||||
<route id="binlightningIngestRoute">
|
<route id="binlightningIngestRoute">
|
||||||
<from uri="jms-durable:queue:Ingest.binlightning"/>
|
<from uri="jms-durable:queue:Ingest.binlightning" />
|
||||||
<setHeader headerName="pluginName">
|
<setHeader headerName="pluginName">
|
||||||
<constant>binlightning</constant>
|
<constant>binlightning</constant>
|
||||||
</setHeader>
|
</setHeader>
|
||||||
<doTry>
|
<doTry>
|
||||||
<pipeline>
|
<pipeline>
|
||||||
<bean ref="stringToFile" />
|
<bean ref="stringToFile" />
|
||||||
<bean ref="binlightningDecoder" method="decode" />
|
<choice>
|
||||||
<to uri="direct-vm:persistIndexAlert" />
|
<when>
|
||||||
|
<simple>${in.header.header} regex '^SFPA42 KWBC.*'</simple>
|
||||||
|
<bean ref="totalLightningDecoder" method="decode" />
|
||||||
|
</when>
|
||||||
|
<otherwise>
|
||||||
|
<bean ref="binlightningDecoder" method="decode" />
|
||||||
|
</otherwise>
|
||||||
|
</choice>
|
||||||
|
|
||||||
</pipeline>
|
<to uri="direct-vm:persistIndexAlert" />
|
||||||
<doCatch>
|
|
||||||
<exception>java.lang.Throwable</exception>
|
</pipeline>
|
||||||
<to uri="log:binlightning?level=ERROR"/>
|
<doCatch>
|
||||||
</doCatch>
|
<exception>java.lang.Throwable</exception>
|
||||||
</doTry>
|
<to uri="log:binlightning?level=ERROR" />
|
||||||
|
</doCatch>
|
||||||
|
</doTry>
|
||||||
<!-- bean ref="processUtil" method="delete" / -->
|
<!-- bean ref="processUtil" method="delete" / -->
|
||||||
</route>
|
</route>
|
||||||
</camelContext>
|
</camelContext>
|
||||||
</beans>
|
</beans>
|
|
@ -47,8 +47,6 @@ import com.raytheon.uf.common.dataplugin.binlightning.impl.LightningStrikePoint;
|
||||||
import com.raytheon.uf.common.dataplugin.binlightning.impl.LtgStrikeType;
|
import com.raytheon.uf.common.dataplugin.binlightning.impl.LtgStrikeType;
|
||||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||||
import com.raytheon.uf.common.status.UFStatus;
|
import com.raytheon.uf.common.status.UFStatus;
|
||||||
import com.raytheon.uf.common.time.DataTime;
|
|
||||||
import com.raytheon.uf.common.time.TimeRange;
|
|
||||||
import com.raytheon.uf.common.time.util.TimeUtil;
|
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||||
import com.raytheon.uf.common.wmo.WMOHeader;
|
import com.raytheon.uf.common.wmo.WMOHeader;
|
||||||
import com.raytheon.uf.common.wmo.WMOTimeParser;
|
import com.raytheon.uf.common.wmo.WMOTimeParser;
|
||||||
|
@ -58,17 +56,6 @@ import com.raytheon.uf.edex.decodertools.core.IBinDataSource;
|
||||||
/**
|
/**
|
||||||
* AWIPS decoder adapter strategy for binary lightning data.<br/>
|
* AWIPS decoder adapter strategy for binary lightning data.<br/>
|
||||||
*
|
*
|
||||||
* Normal usage for this adapter is<br/>
|
|
||||||
* <code>
|
|
||||||
* BinLightningDecoder dec = new BinLightningDecoder();
|
|
||||||
* dec.setMessage(data);
|
|
||||||
* while(dec.hasNext())
|
|
||||||
* {
|
|
||||||
* BinLightningRecord r = dec.decode();
|
|
||||||
* // do something with record.
|
|
||||||
* }
|
|
||||||
* dec.dispose();
|
|
||||||
* </code>
|
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
*
|
*
|
||||||
|
@ -98,6 +85,7 @@ import com.raytheon.uf.edex.decodertools.core.IBinDataSource;
|
||||||
* Jun 03, 2014 3226 bclement removed unused WMO patterns, switched to UFStatus
|
* Jun 03, 2014 3226 bclement removed unused WMO patterns, switched to UFStatus
|
||||||
* removed TimeTools usage, removed constructDataURI() call
|
* removed TimeTools usage, removed constructDataURI() call
|
||||||
* added decodeBinLightningData() and decodeBitShiftedBinLightningData() from BinLightningDecoderUtil
|
* added decodeBinLightningData() and decodeBitShiftedBinLightningData() from BinLightningDecoderUtil
|
||||||
|
* Jun 05, 2014 3226 bclement LightningStikePoint refactor, added extractPData()
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -118,7 +106,7 @@ public class BinLightningDecoder extends AbstractDecoder {
|
||||||
* Default lightning strike type for FLASH messages. RT_FLASH documents
|
* Default lightning strike type for FLASH messages. RT_FLASH documents
|
||||||
* indicate no default, but D2D code defaults to STRIKE_CG also.
|
* indicate no default, but D2D code defaults to STRIKE_CG also.
|
||||||
*/
|
*/
|
||||||
public LtgStrikeType DEFAULT_FLASH_TYPE = LtgStrikeType.STRIKE_CG;
|
public LtgStrikeType DEFAULT_FLASH_TYPE = LtgStrikeType.CLOUD_TO_GROUND;
|
||||||
|
|
||||||
private String traceId = null;
|
private String traceId = null;
|
||||||
|
|
||||||
|
@ -153,30 +141,37 @@ public class BinLightningDecoder extends AbstractDecoder {
|
||||||
Calendar baseTime = WMOTimeParser.findDataTime(
|
Calendar baseTime = WMOTimeParser.findDataTime(
|
||||||
wmoHdr.getYYGGgg(), fileName);
|
wmoHdr.getYYGGgg(), fileName);
|
||||||
|
|
||||||
// Because binary nature of the encrypted data, the string created with its byte[] array may not have the same length of the byte[] array length
|
/*
|
||||||
// So when DecoderTools.stripWMOHeader() assumes byte[] length == String length in its logic, it is observed that it may return a shorter byte[] than
|
* Because binary nature of the encrypted data, the string
|
||||||
// the real data array. (Looks like a bug???)
|
* created with its byte[] array may not have the same length of
|
||||||
|
* the byte[] array length So when DecoderTools.stripWMOHeader()
|
||||||
|
* assumes byte[] length == String length in its logic, it is
|
||||||
|
* observed that it may return a shorter byte[] than the real
|
||||||
|
* data array. (Looks like a bug???)
|
||||||
|
*/
|
||||||
// byte[] pdata = DecoderTools.stripWMOHeader(data, SFUS_PATTERN);
|
// byte[] pdata = DecoderTools.stripWMOHeader(data, SFUS_PATTERN);
|
||||||
// if (pdata == null) {
|
// if (pdata == null) {
|
||||||
// pdata = DecoderTools.stripWMOHeader(data, SFPA_PATTERN);
|
// pdata = DecoderTools.stripWMOHeader(data, SFPA_PATTERN);
|
||||||
// }
|
// }
|
||||||
// instead the following is used to strip WMO header a little more safely.
|
/*
|
||||||
byte[] pdata = null;
|
* instead the following is used to strip WMO header a little
|
||||||
if (wmoHdr.isValid() && wmoHdr.getMessageDataStart() > 0) {
|
* more safely.
|
||||||
pdata = new byte[data.length - wmoHdr.getMessageDataStart()];
|
*/
|
||||||
System.arraycopy(data, wmoHdr.getMessageDataStart(), pdata, 0, data.length - wmoHdr.getMessageDataStart());
|
byte[] pdata = extractPData(wmoHdr, data);
|
||||||
}
|
|
||||||
|
|
||||||
if ((pdata == null) || (pdata.length == 0)) {
|
if ((pdata == null) || (pdata.length == 0)) {
|
||||||
return new PluginDataObject[0];
|
return new PluginDataObject[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
/*
|
||||||
// Modified by Wufeng Zhou to handle both legacy bit-shifted and new encryted data
|
* Modified by Wufeng Zhou to handle both legacy bit-shifted and
|
||||||
//
|
* new encryted data
|
||||||
// Preserved the legacy decoding in BinLigntningDecoderUtil.decodeBitShiftedBinLightningData(), and added logic to process
|
*
|
||||||
// both encrypted data and legacy data
|
* Preserved the legacy decoding in
|
||||||
//
|
* BinLigntningDecoderUtil.decodeBitShiftedBinLightningData(),
|
||||||
|
* and added logic to process both encrypted data and legacy
|
||||||
|
* data
|
||||||
|
*/
|
||||||
|
|
||||||
List<LightningStrikePoint> strikes = decodeBinLightningData(
|
List<LightningStrikePoint> strikes = decodeBinLightningData(
|
||||||
data, pdata, traceId, wmoHdr, baseTime.getTime());
|
data, pdata, traceId, wmoHdr, baseTime.getTime());
|
||||||
|
@ -186,18 +181,14 @@ public class BinLightningDecoder extends AbstractDecoder {
|
||||||
return reports;
|
return reports;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
/*
|
||||||
// Done MOD by Wufeng Zhou
|
* Done MOD by Wufeng Zhou
|
||||||
//
|
*/
|
||||||
|
|
||||||
// post processing data - if not keep-alive record
|
// post processing data - if not keep-alive record
|
||||||
BinLightningRecord report = null;
|
BinLightningRecord report = null;
|
||||||
if (strikes.size() > 0) {
|
if (strikes.size() > 0) {
|
||||||
report = new BinLightningRecord(strikes.size());
|
report = new BinLightningRecord(strikes);
|
||||||
for (LightningStrikePoint strike : strikes) {
|
|
||||||
report.addStrike(strike);
|
|
||||||
logger.debug(traceId + "-" + strike);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return new PluginDataObject[0];
|
return new PluginDataObject[0];
|
||||||
}
|
}
|
||||||
|
@ -215,18 +206,8 @@ public class BinLightningDecoder extends AbstractDecoder {
|
||||||
+ " at " + SDF.format(cStart.getTime()));
|
+ " at " + SDF.format(cStart.getTime()));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Calendar cStop = report.getStopTime();
|
report.setTraceId(traceId);
|
||||||
|
reports = new PluginDataObject[] { report };
|
||||||
TimeRange range = new TimeRange(cStart.getTimeInMillis(),
|
|
||||||
cStop.getTimeInMillis());
|
|
||||||
|
|
||||||
DataTime dataTime = new DataTime(cStart, range);
|
|
||||||
report.setDataTime(dataTime);
|
|
||||||
|
|
||||||
if (report != null) {
|
|
||||||
report.setTraceId(traceId);
|
|
||||||
reports = new PluginDataObject[] { report };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -235,6 +216,23 @@ public class BinLightningDecoder extends AbstractDecoder {
|
||||||
return reports;
|
return reports;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove WMO header from data and return the remaining pdata
|
||||||
|
*
|
||||||
|
* @param wmoHdr
|
||||||
|
* @param data
|
||||||
|
* @return null if data is invalid
|
||||||
|
*/
|
||||||
|
public static byte[] extractPData(WMOHeader wmoHdr, byte[] data) {
|
||||||
|
byte[] pdata = null;
|
||||||
|
if (wmoHdr.isValid() && wmoHdr.getMessageDataStart() > 0) {
|
||||||
|
pdata = new byte[data.length - wmoHdr.getMessageDataStart()];
|
||||||
|
System.arraycopy(data, wmoHdr.getMessageDataStart(), pdata, 0,
|
||||||
|
data.length - wmoHdr.getMessageDataStart());
|
||||||
|
}
|
||||||
|
return pdata;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decode bin lightning data, able to handle both legacy bit-shifted and new
|
* Decode bin lightning data, able to handle both legacy bit-shifted and new
|
||||||
* encryted data
|
* encryted data
|
||||||
|
@ -281,50 +279,52 @@ public class BinLightningDecoder extends AbstractDecoder {
|
||||||
boolean decodeDone = false;
|
boolean decodeDone = false;
|
||||||
EncryptedBinLightningCipher cipher = new EncryptedBinLightningCipher();
|
EncryptedBinLightningCipher cipher = new EncryptedBinLightningCipher();
|
||||||
|
|
||||||
//
|
/*
|
||||||
// Using different WMO headers to indicate whether the data is encrypted
|
* Using different WMO headers to indicate whether the data is encrypted
|
||||||
// or not would be a nice option.
|
* or not would be a nice option.
|
||||||
// However, that idea has been discussed but not adopted.
|
* However, that idea has been discussed but not adopted.
|
||||||
// If in the future, WMO header can be different for legacy and
|
* If in the future, WMO header can be different for legacy and
|
||||||
// encrypted data, or some other metadata can be used to decide
|
* encrypted data, or some other metadata can be used to decide
|
||||||
// whether deceyption is needed, logic can be added here.
|
* whether deceyption is needed, logic can be added here.
|
||||||
//
|
*
|
||||||
// Before that happens, we'll use hints and trial & error to decode the
|
* Before that happens, we'll use hints and trial & error to decode the
|
||||||
// data
|
* data
|
||||||
// Hints: Per lightning data format spec, there are 3 bytes in the WMO
|
* Hints: Per lightning data format spec, there are 3 bytes in the WMO
|
||||||
// header starting line that indicates the size of the encrypted block
|
* header starting line that indicates the size of the encrypted block
|
||||||
// or the ASCII sequence # for legacy bit-shifted data
|
* or the ASCII sequence # for legacy bit-shifted data
|
||||||
// However, the starting line is optional and AWIPS decode may not see
|
* However, the starting line is optional and AWIPS decode may not see
|
||||||
// it at all because TG will strip that starting line away
|
* it at all because TG will strip that starting line away
|
||||||
// We'll try to use this hint first, if is is not found, then trial and
|
* We'll try to use this hint first, if is is not found, then trial and
|
||||||
// error way to decrypt and decode
|
* error way to decrypt and decode
|
||||||
//
|
*
|
||||||
// As of 11/05/2013, There is change in data spec. that the 3-bytes will
|
* As of 11/05/2013, There is change in data spec. that the 3-bytes will
|
||||||
// not be encoded as encrypted block size anymore (it will always be
|
* not be encoded as encrypted block size anymore (it will always be
|
||||||
// transmission sequence # if present)
|
* transmission sequence # if present)
|
||||||
// So there should have some minor changes in the logic below for
|
* So there should have some minor changes in the logic below for
|
||||||
// decoding the data.
|
* decoding the data.
|
||||||
// However, as reading into the
|
* However, as reading into the
|
||||||
// com.raytheon.edex.plugin.binlightning.impl.BinLightningFactory.getDecoder()
|
* com.raytheon.edex.plugin.binlightning.impl.BinLightningFactory.getDecoder
|
||||||
// and follow-on code, we see the following data patterns
|
* ()
|
||||||
// for legacy bit-shifted data, which could be used to reduce guess-work
|
* and follow-on code, we see the following data patterns
|
||||||
// in data decryption:
|
* for legacy bit-shifted data, which could be used to reduce guess-work
|
||||||
// The bit-shifted data will have multiple groups of the following
|
* in data decryption:
|
||||||
// patterns:
|
* The bit-shifted data will have multiple groups of the following
|
||||||
// 1-byte (unsigned byte): for size count
|
* patterns:
|
||||||
// 1-byte (unsigned byte): for flash type:
|
* 1-byte (unsigned byte): for size count
|
||||||
// 0x96 for FLASH_RPT (message size is 6 bytes each)
|
* 1-byte (unsigned byte): for flash type:
|
||||||
// 0x97 for RT_FLASH_RPT (message size is 8 bytes each)
|
* 0x96 for FLASH_RPT (message size is 6 bytes each)
|
||||||
// 0xd0 for OTHER_RPT (The D2D decoders declare but do not define this
|
* 0x97 for RT_FLASH_RPT (message size is 8 bytes each)
|
||||||
// message, so unimplemented decoder)
|
* 0xd0 for OTHER_RPT (The D2D decoders declare but do not define this
|
||||||
// 0xd1 for COMM_RPT (The D2D decoders declare but do not define this
|
* message, so unimplemented decoder)
|
||||||
// message, so unimplemented decoder)
|
* 0xd1 for COMM_RPT (The D2D decoders declare but do not define this
|
||||||
// 4-bytes: date time
|
* message, so unimplemented decoder)
|
||||||
// multiple of 6 or 8 bytes (as determined by 2nd byte flash type) with
|
* 4-bytes: date time
|
||||||
// count indicated in 1st byte
|
* multiple of 6 or 8 bytes (as determined by 2nd byte flash type) with
|
||||||
//
|
* count indicated in 1st byte
|
||||||
// So this is be used to determine whether the data need to be
|
*
|
||||||
// decrypted.
|
* So this is be used to determine whether the data need to be
|
||||||
|
* decrypted.
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* // looks like previous assumption on block size bytes are not valid
|
* // looks like previous assumption on block size bytes are not valid
|
||||||
|
@ -343,21 +343,23 @@ public class BinLightningDecoder extends AbstractDecoder {
|
||||||
|
|
||||||
if (needDecrypt) {
|
if (needDecrypt) {
|
||||||
try {
|
try {
|
||||||
// NOTE: 11/14/2013 WZ:
|
/*
|
||||||
// encrypted test data on TNCF (got from Melissa Porricelli)
|
* NOTE: 11/14/2013 WZ:
|
||||||
// seems to have extra 4 bytes (0x0d 0x0d 0x0a 0x03) at the end,
|
* encrypted test data on TNCF (got from Melissa Porricelli)
|
||||||
// making the data size not a multiple of 16. However, original
|
* seems to have extra 4 bytes (0x0d 0x0d 0x0a 0x03) at the end,
|
||||||
// test data do not have this trailing bytes. while NCEP test
|
* making the data size not a multiple of 16. However, original
|
||||||
// data has extra 8 trailing bytes.
|
* test data do not have this trailing bytes. while NCEP test
|
||||||
// Brain Rapp's email on 11/13/2013 confirms that Unidata LDM
|
* data has extra 8 trailing bytes.
|
||||||
// software used by AWIPS II will strips off all SBN protocol
|
* Brain Rapp's email on 11/13/2013 confirms that Unidata LDM
|
||||||
// headers
|
* software used by AWIPS II will strips off all SBN protocol
|
||||||
// that precede the WMO header and adds its own 11 byte header
|
* headers
|
||||||
// like this: "soh cr cr nl 2 5 4 sp cr cr nl". It
|
* that precede the WMO header and adds its own 11 byte header
|
||||||
// also adds a four byte trailer consisting of "cr cr nl etx"
|
* like this: "soh cr cr nl 2 5 4 sp cr cr nl". It
|
||||||
// (0x0d 0x0d 0x0a 0x03)
|
* also adds a four byte trailer consisting of "cr cr nl etx"
|
||||||
// So, it seems necessary to trim trailing bytes if it is not
|
* (0x0d 0x0d 0x0a 0x03)
|
||||||
// multiple of 16, warning messages will be logged though
|
* So, it seems necessary to trim trailing bytes if it is not
|
||||||
|
* multiple of 16, warning messages will be logged though
|
||||||
|
*/
|
||||||
int dataLengthToBeDecrypted = pdata.length;
|
int dataLengthToBeDecrypted = pdata.length;
|
||||||
if (pdata.length % 16 != 0) {
|
if (pdata.length % 16 != 0) {
|
||||||
dataLengthToBeDecrypted = pdata.length
|
dataLengthToBeDecrypted = pdata.length
|
||||||
|
@ -382,8 +384,10 @@ public class BinLightningDecoder extends AbstractDecoder {
|
||||||
decodeDone = true;
|
decodeDone = true;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// not keep-alive record, then check data validity and decode
|
/*
|
||||||
// into an ArrayList<LightningStrikePoint> of strikes
|
* not keep-alive record, then check data validity and decode
|
||||||
|
* into an ArrayList<LightningStrikePoint> of strikes
|
||||||
|
*/
|
||||||
if (BinLightningDecoderUtil
|
if (BinLightningDecoderUtil
|
||||||
.isLightningDataRecords(decryptedData)) {
|
.isLightningDataRecords(decryptedData)) {
|
||||||
strikes = BinLightningDecoderUtil
|
strikes = BinLightningDecoderUtil
|
||||||
|
@ -418,9 +422,11 @@ public class BinLightningDecoder extends AbstractDecoder {
|
||||||
if (decodeDone == false) { // not decoded through decrypt->decode
|
if (decodeDone == false) { // not decoded through decrypt->decode
|
||||||
// process, try the legacy decoder
|
// process, try the legacy decoder
|
||||||
logger.info(traceId + " - decoding as bit-shifted data");
|
logger.info(traceId + " - decoding as bit-shifted data");
|
||||||
// bit-shifting data format check call here will get us some more
|
/*
|
||||||
// information on the data, also can compare the strikes with the
|
* bit-shifting data format check call here will get us some more
|
||||||
// decoder result
|
* information on the data, also can compare the strikes with the
|
||||||
|
* decoder result
|
||||||
|
*/
|
||||||
int estimatedStrikes = BinLightningDecoderUtil
|
int estimatedStrikes = BinLightningDecoderUtil
|
||||||
.getBitShiftedDataStrikeCount(pdata);
|
.getBitShiftedDataStrikeCount(pdata);
|
||||||
strikes = decodeBitShiftedBinLightningData(pdata, wmoHdr);
|
strikes = decodeBitShiftedBinLightningData(pdata, wmoHdr);
|
||||||
|
@ -461,13 +467,15 @@ public class BinLightningDecoder extends AbstractDecoder {
|
||||||
switch (decoder.getError()) {
|
switch (decoder.getError()) {
|
||||||
case IBinLightningDecoder.NO_ERROR: {
|
case IBinLightningDecoder.NO_ERROR: {
|
||||||
for (LightningStrikePoint strike : decoder) {
|
for (LightningStrikePoint strike : decoder) {
|
||||||
// use WMO Header to distinguish NLDN or GLD360 data because
|
/*
|
||||||
// no bit-shifted data spec available for GLD360.
|
* use WMO Header to distinguish NLDN or GLD360 data because
|
||||||
// 12/24/2013, WZ
|
* no bit-shifted data spec available for GLD360.
|
||||||
// The WMO header start string is defined in
|
* 12/24/2013, WZ
|
||||||
// BinLightningAESKey.properties file (normally, GLD360 data
|
* The WMO header start string is defined in
|
||||||
// will have WMO header
|
* BinLightningAESKey.properties file (normally, GLD360 data
|
||||||
// starts with SFPA41, or SFPA99 for test data.)
|
* will have WMO header
|
||||||
|
* starts with SFPA41, or SFPA99 for test data.)
|
||||||
|
*/
|
||||||
String gld360WMOHeaderString = BinLightningAESKey
|
String gld360WMOHeaderString = BinLightningAESKey
|
||||||
.getProps().getProperty(
|
.getProps().getProperty(
|
||||||
"binlightning.gld360WMOHeaderStartString",
|
"binlightning.gld360WMOHeaderStartString",
|
||||||
|
|
|
@ -20,11 +20,17 @@
|
||||||
|
|
||||||
package com.raytheon.edex.plugin.binlightning.dao;
|
package com.raytheon.edex.plugin.binlightning.dao;
|
||||||
|
|
||||||
import com.raytheon.uf.common.dataplugin.binlightning.BinLightningRecord;
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import com.raytheon.uf.common.dataplugin.PluginException;
|
import com.raytheon.uf.common.dataplugin.PluginException;
|
||||||
|
import com.raytheon.uf.common.dataplugin.annotations.DataURI;
|
||||||
|
import com.raytheon.uf.common.dataplugin.binlightning.BinLightningRecord;
|
||||||
|
import com.raytheon.uf.common.dataplugin.binlightning.LightningConstants;
|
||||||
import com.raytheon.uf.common.dataplugin.persist.IPersistable;
|
import com.raytheon.uf.common.dataplugin.persist.IPersistable;
|
||||||
import com.raytheon.uf.common.datastorage.DataStoreFactory;
|
import com.raytheon.uf.common.datastorage.DataStoreFactory;
|
||||||
import com.raytheon.uf.common.datastorage.IDataStore;
|
import com.raytheon.uf.common.datastorage.IDataStore;
|
||||||
|
import com.raytheon.uf.common.datastorage.StorageException;
|
||||||
import com.raytheon.uf.common.datastorage.records.IDataRecord;
|
import com.raytheon.uf.common.datastorage.records.IDataRecord;
|
||||||
import com.raytheon.uf.edex.database.plugin.PluginDao;
|
import com.raytheon.uf.edex.database.plugin.PluginDao;
|
||||||
|
|
||||||
|
@ -36,6 +42,7 @@ import com.raytheon.uf.edex.database.plugin.PluginDao;
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* 1/08/09 1674 bphillip Initial creation
|
* 1/08/09 1674 bphillip Initial creation
|
||||||
|
* Jun 05, 2014 3226 bclement record now contains maps for data arrays
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author bphillip
|
* @author bphillip
|
||||||
|
@ -61,15 +68,38 @@ public class BinLightningDao extends PluginDao {
|
||||||
protected IDataStore populateDataStore(IDataStore dataStore,
|
protected IDataStore populateDataStore(IDataStore dataStore,
|
||||||
IPersistable obj) throws Exception {
|
IPersistable obj) throws Exception {
|
||||||
BinLightningRecord binLightningRec = (BinLightningRecord) obj;
|
BinLightningRecord binLightningRec = (BinLightningRecord) obj;
|
||||||
|
Map<String, Object> strikeDataArrays = binLightningRec
|
||||||
for (int i = 0; i < binLightningRec.getDataArrays().length; i++) {
|
.getStrikeDataArrays();
|
||||||
IDataRecord record = DataStoreFactory.createStorageRecord(
|
populateFromMap(dataStore, obj, binLightningRec.getDataURI(),
|
||||||
binLightningRec.getDataNames()[i], binLightningRec
|
strikeDataArrays);
|
||||||
.getDataURI(), binLightningRec.getDataArrays()[i]);
|
Map<String, Object> pulseDataArrays = binLightningRec
|
||||||
record.setCorrelationObject(binLightningRec);
|
.getPulseDataArrays();
|
||||||
dataStore.addDataRecord(record);
|
String pulseGroup = binLightningRec.getDataURI() + DataURI.SEPARATOR
|
||||||
}
|
+ LightningConstants.PULSE_HDF5_GROUP_SUFFIX;
|
||||||
|
populateFromMap(dataStore, obj, pulseGroup, pulseDataArrays);
|
||||||
return dataStore;
|
return dataStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds each primitive data array object in map to the datastore using the
|
||||||
|
* provided group and the key of the map entry as the name
|
||||||
|
*
|
||||||
|
* @param dataStore
|
||||||
|
* @param obj
|
||||||
|
* @param group
|
||||||
|
* @param data
|
||||||
|
* @throws StorageException
|
||||||
|
*/
|
||||||
|
private void populateFromMap(IDataStore dataStore, IPersistable obj,
|
||||||
|
String group, Map<String, Object> data)
|
||||||
|
throws StorageException {
|
||||||
|
for (Entry<String, Object> e : data.entrySet()) {
|
||||||
|
String name = e.getKey();
|
||||||
|
Object dataArray = e.getValue();
|
||||||
|
IDataRecord record = DataStoreFactory.createStorageRecord(name,
|
||||||
|
group, dataArray);
|
||||||
|
record.setCorrelationObject(obj);
|
||||||
|
dataStore.addDataRecord(record);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,6 @@ import java.util.List;
|
||||||
|
|
||||||
import com.raytheon.uf.common.dataplugin.binlightning.impl.LightningStrikePoint;
|
import com.raytheon.uf.common.dataplugin.binlightning.impl.LightningStrikePoint;
|
||||||
import com.raytheon.uf.common.time.util.TimeUtil;
|
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||||
import com.raytheon.uf.edex.decodertools.core.BasePoint;
|
|
||||||
import com.raytheon.uf.edex.decodertools.core.IBinDataSource;
|
import com.raytheon.uf.edex.decodertools.core.IBinDataSource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -42,6 +41,7 @@ import com.raytheon.uf.edex.decodertools.core.IBinDataSource;
|
||||||
* 20070810 379 jkorman Initial Coding from prototype.
|
* 20070810 379 jkorman Initial Coding from prototype.
|
||||||
* 20070912 379 jkorman Code review cleanup.
|
* 20070912 379 jkorman Code review cleanup.
|
||||||
* May 14, 2014 2536 bclement removed TimeTools
|
* May 14, 2014 2536 bclement removed TimeTools
|
||||||
|
* Jun 05, 2014 3226 bclement parseDate() now returns calendar
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author jkorman
|
* @author jkorman
|
||||||
|
@ -87,13 +87,12 @@ abstract class BaseLightningDecoder implements IBinLightningDecoder
|
||||||
/**
|
/**
|
||||||
* Parse the date field from a given data source. It is assumed that the
|
* Parse the date field from a given data source. It is assumed that the
|
||||||
* data source is pointing to the current date/time data.
|
* data source is pointing to the current date/time data.
|
||||||
* @return A BasePoint object with the time fields set to the observation
|
*
|
||||||
* time.
|
* @return A Calendar object with the time fields set to the observation
|
||||||
|
* time.
|
||||||
*/
|
*/
|
||||||
BasePoint parseDate(IBinDataSource msgData)
|
protected Calendar parseDate(IBinDataSource msgData)
|
||||||
{
|
{
|
||||||
BasePoint point = new BasePoint();
|
|
||||||
|
|
||||||
//********* Don't reorder these reads!!!
|
//********* Don't reorder these reads!!!
|
||||||
int b1 = msgData.getU8();
|
int b1 = msgData.getU8();
|
||||||
int b2 = msgData.getU8();
|
int b2 = msgData.getU8();
|
||||||
|
@ -103,22 +102,18 @@ abstract class BaseLightningDecoder implements IBinLightningDecoder
|
||||||
// number of days since BASE_TIME
|
// number of days since BASE_TIME
|
||||||
int days = ((word1 & DAYS_MASK) >> DAYS_SHFT);
|
int days = ((word1 & DAYS_MASK) >> DAYS_SHFT);
|
||||||
obsTime.add(Calendar.DAY_OF_MONTH, days);
|
obsTime.add(Calendar.DAY_OF_MONTH, days);
|
||||||
|
|
||||||
point.setYear(obsTime.get(Calendar.YEAR));
|
|
||||||
//Increment month, Calendar returns 0..11
|
|
||||||
point.setMonth(obsTime.get(Calendar.MONTH) + 1);
|
|
||||||
point.setDay(obsTime.get(Calendar.DAY_OF_MONTH));
|
|
||||||
|
|
||||||
int hours = (word1 & HOURS_HI_BIT_MASK) << HOURS_HI_BIT_SHFT;
|
int hours = (word1 & HOURS_HI_BIT_MASK) << HOURS_HI_BIT_SHFT;
|
||||||
hours += (b2 & HOURS_LO_NYB_MASK) >>> HOURS_LO_NYB_SHFT;
|
hours += (b2 & HOURS_LO_NYB_MASK) >>> HOURS_LO_NYB_SHFT;
|
||||||
point.setHour(hours);
|
obsTime.set(Calendar.HOUR, hours);
|
||||||
|
|
||||||
int minutes = (b2 & MIN_P1_MASK) << MIN_P1_SHFT;
|
int minutes = (b2 & MIN_P1_MASK) << MIN_P1_SHFT;
|
||||||
minutes += (b1 & MIN_P2_MASK) >>> MIN_P2_SHFT;
|
minutes += (b1 & MIN_P2_MASK) >>> MIN_P2_SHFT;
|
||||||
point.setMinute(minutes);
|
obsTime.set(Calendar.MINUTE, minutes);
|
||||||
|
|
||||||
point.setSecond((b1 & SECONDS_MASK));
|
obsTime.set(Calendar.SECOND, (b1 & SECONDS_MASK));
|
||||||
return point;
|
obsTime.set(Calendar.MILLISECOND, 0);
|
||||||
|
return obsTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -19,9 +19,11 @@
|
||||||
**/
|
**/
|
||||||
package com.raytheon.edex.plugin.binlightning.impl;
|
package com.raytheon.edex.plugin.binlightning.impl;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
|
||||||
import com.raytheon.uf.common.dataplugin.binlightning.impl.LightningStrikePoint;
|
import com.raytheon.uf.common.dataplugin.binlightning.impl.LightningStrikePoint;
|
||||||
import com.raytheon.uf.common.dataplugin.binlightning.impl.LtgMsgType;
|
import com.raytheon.uf.common.dataplugin.binlightning.impl.LtgMsgType;
|
||||||
import com.raytheon.uf.edex.decodertools.core.BasePoint;
|
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||||
import com.raytheon.uf.edex.decodertools.core.IBinDataSource;
|
import com.raytheon.uf.edex.decodertools.core.IBinDataSource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -30,13 +32,14 @@ import com.raytheon.uf.edex.decodertools.core.IBinDataSource;
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* SOFTWARE HISTORY
|
* SOFTWARE HISTORY
|
||||||
*
|
*
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* 20070810 379 jkorman Initial Coding from prototype.
|
* 20070810 379 jkorman Initial Coding from prototype.
|
||||||
|
* Jun 05, 2014 3226 bclement LightningStikePoint refactor
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author jkorman
|
* @author jkorman
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
*/
|
*/
|
||||||
|
@ -62,7 +65,7 @@ public class FlashLightningDecoder extends BaseLightningDecoder
|
||||||
{
|
{
|
||||||
if(msgData.available(TIME_SIZE))
|
if(msgData.available(TIME_SIZE))
|
||||||
{
|
{
|
||||||
BasePoint base = parseDate(msgData);
|
Calendar baseTime = parseDate(msgData);
|
||||||
|
|
||||||
if(msgData.available(FLASH_MSG_SIZE * count))
|
if(msgData.available(FLASH_MSG_SIZE * count))
|
||||||
{
|
{
|
||||||
|
@ -70,17 +73,23 @@ public class FlashLightningDecoder extends BaseLightningDecoder
|
||||||
{
|
{
|
||||||
double lon = getFlashLon(msgData);
|
double lon = getFlashLon(msgData);
|
||||||
double lat = getFlashLat(msgData);
|
double lat = getFlashLat(msgData);
|
||||||
// Create the strike record from the report info and base time information.
|
|
||||||
LightningStrikePoint strikeData = new LightningStrikePoint(base,lat,lon,LtgMsgType.STRIKE_MSG_FL);
|
double strikeStrength = msgData.getS8() * 2.0;
|
||||||
|
|
||||||
strikeData.setStrikeStrength(msgData.getS8() * 2.0);
|
|
||||||
|
|
||||||
// strike count and 1/10s seconds
|
// strike count and 1/10s seconds
|
||||||
int u8 = msgData.getU8();
|
int u8 = msgData.getU8();
|
||||||
strikeData.setStrikeCount(u8 & 0x0F);
|
int flashCount = u8 & 0x0F;
|
||||||
strikeData.setMillis(((u8 & 0xF0) >> 4) * 100);
|
|
||||||
|
Calendar obsTime = TimeUtil.newCalendar(baseTime);
|
||||||
|
obsTime.set(Calendar.MILLISECOND, ((u8 & 0xF0) >> 4) * 100);
|
||||||
|
|
||||||
|
// Create the strike record from the report info and base
|
||||||
|
// time information.
|
||||||
|
LightningStrikePoint strikeData = new LightningStrikePoint(
|
||||||
|
lat, lon, baseTime, LtgMsgType.STRIKE_MSG_FL);
|
||||||
strikeData.setType(DEFAULT_FLASH_TYPE);
|
strikeData.setType(DEFAULT_FLASH_TYPE);
|
||||||
|
strikeData.setStrikeStrength(strikeStrength);
|
||||||
|
strikeData.setPulseCount(flashCount);
|
||||||
addStrike(strikeData);
|
addStrike(strikeData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,22 +26,24 @@ import com.raytheon.uf.common.dataplugin.binlightning.impl.LtgStrikeType;
|
||||||
* Declare the interface for binary lightning decoding. The decoders are
|
* Declare the interface for binary lightning decoding. The decoders are
|
||||||
* expected to implement an Iterable interface. Data decoding will take place
|
* expected to implement an Iterable interface. Data decoding will take place
|
||||||
* during construction of the element.
|
* during construction of the element.
|
||||||
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* the recommended constructor for this interface is
|
* the recommended constructor for this interface is
|
||||||
*
|
*
|
||||||
* @param data An IBinDataSource data source containing the data to be decoded.
|
* @param data An IBinDataSource data source containing the data to be decoded.
|
||||||
* @param count The number of records that this decoder should see.
|
* @param count The number of records that this decoder should see.
|
||||||
* <code>public X (IBinDataSource data, int count)</code>
|
* <code>public X (IBinDataSource data, int count)</code>
|
||||||
*
|
*
|
||||||
* SOFTWARE HISTORY
|
* SOFTWARE HISTORY
|
||||||
*
|
*
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* 20070810 379 jkorman Initial Coding from prototype.
|
* 20070810 379 jkorman Initial Coding from prototype.
|
||||||
* 20070912 379 jkorman Code review cleanup.
|
* 20070912 379 jkorman Code review cleanup.
|
||||||
|
* Jun 05, 2014 3226 bclement LightningStikePoint refactor
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author jkorman
|
* @author jkorman
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
*/
|
*/
|
||||||
|
@ -59,7 +61,7 @@ public interface IBinLightningDecoder extends Iterable<LightningStrikePoint>
|
||||||
public static final int OTHER_RPT = 0xD0;
|
public static final int OTHER_RPT = 0xD0;
|
||||||
public static final int COMM_RPT = 0xD1;
|
public static final int COMM_RPT = 0xD1;
|
||||||
|
|
||||||
public static final LtgStrikeType DEFAULT_FLASH_TYPE = LtgStrikeType.STRIKE_CG;
|
public static final LtgStrikeType DEFAULT_FLASH_TYPE = LtgStrikeType.CLOUD_TO_GROUND;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -19,9 +19,10 @@
|
||||||
**/
|
**/
|
||||||
package com.raytheon.edex.plugin.binlightning.impl;
|
package com.raytheon.edex.plugin.binlightning.impl;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
|
||||||
import com.raytheon.uf.common.dataplugin.binlightning.impl.LightningStrikePoint;
|
import com.raytheon.uf.common.dataplugin.binlightning.impl.LightningStrikePoint;
|
||||||
import com.raytheon.uf.common.dataplugin.binlightning.impl.LtgMsgType;
|
import com.raytheon.uf.common.dataplugin.binlightning.impl.LtgMsgType;
|
||||||
import com.raytheon.uf.edex.decodertools.core.BasePoint;
|
|
||||||
import com.raytheon.uf.edex.decodertools.core.IBinDataSource;
|
import com.raytheon.uf.edex.decodertools.core.IBinDataSource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,6 +38,7 @@ import com.raytheon.uf.edex.decodertools.core.IBinDataSource;
|
||||||
* 20070810 379 jkorman Initial Coding from prototype.
|
* 20070810 379 jkorman Initial Coding from prototype.
|
||||||
* 20070821 379 jkorman Added default strike type.
|
* 20070821 379 jkorman Added default strike type.
|
||||||
* 20080823 379 jkorman getRTLat was using 24 bits instead of 23.
|
* 20080823 379 jkorman getRTLat was using 24 bits instead of 23.
|
||||||
|
* Jun 05, 2014 3226 bclement LightningStikePoint refactor
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author jkorman
|
* @author jkorman
|
||||||
|
@ -66,7 +68,7 @@ public class RTLightningDecoder extends BaseLightningDecoder {
|
||||||
*/
|
*/
|
||||||
private void doDecode(IBinDataSource msgData, int count) {
|
private void doDecode(IBinDataSource msgData, int count) {
|
||||||
if (msgData.available(TIME_SIZE + (RT_MSG_SIZE * count))) {
|
if (msgData.available(TIME_SIZE + (RT_MSG_SIZE * count))) {
|
||||||
BasePoint base = parseDate(msgData);
|
Calendar baseTime = parseDate(msgData);
|
||||||
// for now just consume some data
|
// for now just consume some data
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
long part = msgData.getU32();
|
long part = msgData.getU32();
|
||||||
|
@ -79,11 +81,11 @@ public class RTLightningDecoder extends BaseLightningDecoder {
|
||||||
double lat = getRTLat(part);
|
double lat = getRTLat(part);
|
||||||
int strikeCount = getMult(part);
|
int strikeCount = getMult(part);
|
||||||
|
|
||||||
LightningStrikePoint strikeData = new LightningStrikePoint(
|
LightningStrikePoint strikeData = new LightningStrikePoint(lat,
|
||||||
base, lat, lon, LtgMsgType.STRIKE_MSG_RT);
|
lon, baseTime, LtgMsgType.STRIKE_MSG_RT);
|
||||||
|
|
||||||
strikeData.setStrikeStrength(strength);
|
strikeData.setStrikeStrength(strength);
|
||||||
strikeData.setStrikeCount(strikeCount);
|
strikeData.setPulseCount(strikeCount);
|
||||||
// *****
|
// *****
|
||||||
// NCDC documents indicate that RT data can report both CC/CG
|
// NCDC documents indicate that RT data can report both CC/CG
|
||||||
// but haven't seen any data nor is it in the D2D decoders. Set
|
// but haven't seen any data nor is it in the D2D decoders. Set
|
||||||
|
|
|
@ -0,0 +1,171 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.edex.plugin.binlightning.total;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.numeric.UnsignedNumbers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ByteBuffer wrapper that keeps track of checksums
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Jun 3, 2014 3226 bclement Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author bclement
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public class ChecksumByteBuffer {
|
||||||
|
|
||||||
|
private static final int SHORT_SIZE = Short.SIZE / Byte.SIZE;
|
||||||
|
|
||||||
|
private static final int INT_SIZE = Integer.SIZE / Byte.SIZE;
|
||||||
|
|
||||||
|
private static final int LONG_SIZE = Integer.SIZE / Byte.SIZE;
|
||||||
|
|
||||||
|
private final ByteBuffer buff;
|
||||||
|
|
||||||
|
private long totalSum;
|
||||||
|
|
||||||
|
private long packetSum;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ByteBuffer#wrap(byte[])
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
public ChecksumByteBuffer(byte[] data) {
|
||||||
|
this.buff = ByteBuffer.wrap(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the sum of the next numberOfBytes worth of data
|
||||||
|
*
|
||||||
|
* @param numberOfBytes
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private long getSum(int numberOfBytes) {
|
||||||
|
int start = buff.position();
|
||||||
|
int end = start + numberOfBytes;
|
||||||
|
long rval = 0;
|
||||||
|
for (int i = start; i < end; ++i) {
|
||||||
|
rval += UnsignedNumbers.ubyteToShort(buff.get(i));
|
||||||
|
}
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ByteBuffer#get()
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public byte get() {
|
||||||
|
byte rval = buff.get();
|
||||||
|
short unsignedRval = UnsignedNumbers.ubyteToShort(rval);
|
||||||
|
totalSum += unsignedRval;
|
||||||
|
packetSum += unsignedRval;
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ByteBuffer#getShort()
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public short getShort() {
|
||||||
|
long sum = getSum(SHORT_SIZE);
|
||||||
|
totalSum += sum;
|
||||||
|
packetSum += sum;
|
||||||
|
return buff.getShort();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ByteBuffer#getInt()
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int getInt() {
|
||||||
|
long sum = getSum(INT_SIZE);
|
||||||
|
totalSum += sum;
|
||||||
|
packetSum += sum;
|
||||||
|
return buff.getInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ByteBuffer#getLong()
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public long getLong() {
|
||||||
|
long sum = getSum(LONG_SIZE);
|
||||||
|
totalSum += sum;
|
||||||
|
packetSum += sum;
|
||||||
|
return buff.getLong();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reset the current packet sum to zero
|
||||||
|
*/
|
||||||
|
public void resetPacketSum() {
|
||||||
|
packetSum = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reset all sums to zero
|
||||||
|
*/
|
||||||
|
public void resetAllSums() {
|
||||||
|
resetPacketSum();
|
||||||
|
totalSum = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the totalSum
|
||||||
|
*/
|
||||||
|
public long getTotalSum() {
|
||||||
|
return totalSum;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the packetSum
|
||||||
|
*/
|
||||||
|
public long getPacketSum() {
|
||||||
|
return packetSum;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ByteBuffer#limit()
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int size() {
|
||||||
|
return buff.limit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ByteBuffer#position()
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int position() {
|
||||||
|
return buff.position();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,348 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.edex.plugin.binlightning.total;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.raytheon.edex.esb.Headers;
|
||||||
|
import com.raytheon.edex.exception.DecoderException;
|
||||||
|
import com.raytheon.edex.plugin.binlightning.BinLightningDecoder;
|
||||||
|
import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
||||||
|
import com.raytheon.uf.common.dataplugin.binlightning.BinLightningRecord;
|
||||||
|
import com.raytheon.uf.common.dataplugin.binlightning.impl.BaseLightningPoint;
|
||||||
|
import com.raytheon.uf.common.dataplugin.binlightning.impl.LightningPulsePoint;
|
||||||
|
import com.raytheon.uf.common.dataplugin.binlightning.impl.LightningStrikePoint;
|
||||||
|
import com.raytheon.uf.common.dataplugin.binlightning.impl.LtgMsgType;
|
||||||
|
import com.raytheon.uf.common.dataplugin.binlightning.impl.LtgPulseType;
|
||||||
|
import com.raytheon.uf.common.dataplugin.binlightning.impl.LtgStrikeType;
|
||||||
|
import com.raytheon.uf.common.numeric.UnsignedNumbers;
|
||||||
|
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||||
|
import com.raytheon.uf.common.status.UFStatus;
|
||||||
|
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||||
|
import com.raytheon.uf.common.wmo.WMOHeader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decoder for Earth Networks Total Lightning data
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* May 30, 2014 3226 bclement Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author bclement
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public class TotalLightningDecoder {
|
||||||
|
|
||||||
|
// flash types
|
||||||
|
public static final byte CLOUD_TO_GROUND_TYPE = 0x00;
|
||||||
|
|
||||||
|
public static final byte CLOUD_TO_CLOUD_TYPE = 0x01;
|
||||||
|
|
||||||
|
// pulse types
|
||||||
|
public static final byte RETURN_STROKE_TYPE = 0x00;
|
||||||
|
|
||||||
|
public static final byte NON_RETURN_STROKE_TYPE = 0x01;
|
||||||
|
|
||||||
|
public static final byte KEEP_ALIVE_TYPE = 0x09;
|
||||||
|
|
||||||
|
// conversions
|
||||||
|
public static final double LONLAT_SCALE_FACTOR = 0.0000001;
|
||||||
|
|
||||||
|
public static final double AMPS_PER_KILO_AMP = 1000.0;
|
||||||
|
|
||||||
|
public static final double METERS_PER_KILOMETER = 1000.0;
|
||||||
|
|
||||||
|
// constant metadata
|
||||||
|
public static final String DATA_SOURCE = "ENTLN";
|
||||||
|
|
||||||
|
private static final IUFStatusHandler log = UFStatus
|
||||||
|
.getHandler(TotalLightningDecoder.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse total lightning data into BinLightningRecords
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* @param headers
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public PluginDataObject[] decode(byte[] data, Headers headers) {
|
||||||
|
PluginDataObject[] rval;
|
||||||
|
WMOHeader wmoHdr = new WMOHeader(data);
|
||||||
|
String fileName = (String) headers.get(WMOHeader.INGEST_FILE_NAME);
|
||||||
|
if (wmoHdr.isValid()) {
|
||||||
|
byte[] pdata = BinLightningDecoder.extractPData(wmoHdr, data);
|
||||||
|
if (pdata != null) {
|
||||||
|
try {
|
||||||
|
rval = decodeInternal(fileName, pdata);
|
||||||
|
} catch (Exception e) {
|
||||||
|
error(e, headers, wmoHdr);
|
||||||
|
rval = new PluginDataObject[0];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
warn("Unable to separate data from headers", fileName, wmoHdr);
|
||||||
|
rval = new PluginDataObject[0];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
warn("Invalid WMO header", fileName, wmoHdr);
|
||||||
|
rval = new PluginDataObject[0];
|
||||||
|
}
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display warning message with file and header names
|
||||||
|
*
|
||||||
|
* @param msg
|
||||||
|
* @param fileName
|
||||||
|
* @param wmoHdr
|
||||||
|
*/
|
||||||
|
private void warn(String msg, String fileName, WMOHeader wmoHdr) {
|
||||||
|
log.warn(msg + ". File: " + fileName + ", WMO Header: " + wmoHdr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display error message with file and header names
|
||||||
|
*
|
||||||
|
* @param e
|
||||||
|
* @param headers
|
||||||
|
* @param wmoHdr
|
||||||
|
*/
|
||||||
|
private void error(Exception e, Headers headers, WMOHeader wmoHdr) {
|
||||||
|
String fileName = (String) headers.get(WMOHeader.INGEST_FILE_NAME);
|
||||||
|
log.error(e.getLocalizedMessage() + ". File: " + fileName
|
||||||
|
+ ", WMO Header: " + wmoHdr, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param fileName
|
||||||
|
* @param pdata
|
||||||
|
* data after WMO header is removed
|
||||||
|
* @return
|
||||||
|
* @throws DecoderException
|
||||||
|
*/
|
||||||
|
private PluginDataObject[] decodeInternal(String fileName, byte[] pdata)
|
||||||
|
throws DecoderException {
|
||||||
|
List<LightningStrikePoint> decodeStrikes = decodeStrikes(fileName,
|
||||||
|
pdata);
|
||||||
|
BinLightningRecord record = new BinLightningRecord(decodeStrikes);
|
||||||
|
return new PluginDataObject[] { record };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract strike data from raw binary
|
||||||
|
*
|
||||||
|
* @param fileName
|
||||||
|
* @param pdata
|
||||||
|
* @return
|
||||||
|
* @throws DecoderException
|
||||||
|
*/
|
||||||
|
private List<LightningStrikePoint> decodeStrikes(String fileName,
|
||||||
|
byte[] pdata) throws DecoderException {
|
||||||
|
List<LightningStrikePoint> rval = new ArrayList<LightningStrikePoint>();
|
||||||
|
ChecksumByteBuffer buff = new ChecksumByteBuffer(pdata);
|
||||||
|
while (buff.position() < buff.size()) {
|
||||||
|
int totalBytes = UnsignedNumbers.ushortToInt(buff.getShort());
|
||||||
|
if (totalBytes > (buff.size() - buff.position())) {
|
||||||
|
log.error("Truncated total lightning packet in file: "
|
||||||
|
+ fileName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* start flash packet */
|
||||||
|
buff.resetPacketSum();
|
||||||
|
/* discard flash packet size byte */
|
||||||
|
buff.get();
|
||||||
|
|
||||||
|
LtgStrikeType flashType = getStrikeType(buff.get());
|
||||||
|
LightningStrikePoint strike = new LightningStrikePoint(null,
|
||||||
|
LtgMsgType.TOTAL_LIGHTNING);
|
||||||
|
strike.setLightSource(DATA_SOURCE);
|
||||||
|
strike.setType(flashType);
|
||||||
|
decodeCommonFields(strike, buff);
|
||||||
|
|
||||||
|
int pulseCount = UnsignedNumbers.ubyteToShort(buff.get());
|
||||||
|
strike.setPulseCount(pulseCount);
|
||||||
|
checkSum(buff, false);
|
||||||
|
|
||||||
|
List<LightningPulsePoint> pulses = new ArrayList<LightningPulsePoint>(
|
||||||
|
pulseCount);
|
||||||
|
for (int i = 0; i < pulseCount; ++i) {
|
||||||
|
/* discard size of pulse packet (always 26) */
|
||||||
|
buff.get();
|
||||||
|
LtgPulseType pulseType = getPulseType(buff.get());
|
||||||
|
LightningPulsePoint pulse = new LightningPulsePoint(null,
|
||||||
|
pulseType);
|
||||||
|
decodeCommonFields(pulse, buff);
|
||||||
|
/* discard pulse count (already set in strike) */
|
||||||
|
buff.get();
|
||||||
|
checkSum(buff, false);
|
||||||
|
pulses.add(pulse);
|
||||||
|
}
|
||||||
|
strike.setPulses(pulses);
|
||||||
|
checkSum(buff, true);
|
||||||
|
rval.add(strike);
|
||||||
|
}
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract fields common to both strikes and pulses
|
||||||
|
*
|
||||||
|
* @param point
|
||||||
|
* @param buff
|
||||||
|
*/
|
||||||
|
private static void decodeCommonFields(BaseLightningPoint point,
|
||||||
|
ChecksumByteBuffer buff) {
|
||||||
|
point.setTime(getTime(buff));
|
||||||
|
point.setLatitude(getDouble(buff, LONLAT_SCALE_FACTOR));
|
||||||
|
point.setLongitude(getDouble(buff, LONLAT_SCALE_FACTOR));
|
||||||
|
point.setStrikeStrength(getKiloAmps(buff.getInt()));
|
||||||
|
/* discard reserved byte */
|
||||||
|
buff.get();
|
||||||
|
point.setElevation(getMeters(buff.getShort()));
|
||||||
|
point.setSensorCount(UnsignedNumbers.ubyteToShort(buff.get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create calendar from 4 byte UNIX time and 2 byte millisecond addition
|
||||||
|
*
|
||||||
|
* @param buff
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private static Calendar getTime(ChecksumByteBuffer buff) {
|
||||||
|
long unixTime = UnsignedNumbers.uintToLong(buff.getInt());
|
||||||
|
int additionalMillis = UnsignedNumbers.ushortToInt(buff.getShort());
|
||||||
|
long totalMillis = (unixTime * TimeUtil.MILLIS_PER_SECOND)
|
||||||
|
+ additionalMillis;
|
||||||
|
return TimeUtil.newGmtCalendar(new Date(totalMillis));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure data integrity, resets appropriate sum(s) in buffer after check
|
||||||
|
*
|
||||||
|
* @param buff
|
||||||
|
* @param total
|
||||||
|
* true if total sum should be checked, otherwise checks packet
|
||||||
|
* sum
|
||||||
|
* @throws DecoderException
|
||||||
|
* if check fails
|
||||||
|
*/
|
||||||
|
private static void checkSum(ChecksumByteBuffer buff, boolean total)
|
||||||
|
throws DecoderException {
|
||||||
|
long rawsum = total ? buff.getTotalSum() : buff.getPacketSum();
|
||||||
|
/* convert to overflowed unsigned byte */
|
||||||
|
rawsum &= 0xFF;
|
||||||
|
/* checksum algorithm from total lightning spec */
|
||||||
|
long mungedSum = (256 - rawsum) & 0xFF;
|
||||||
|
/* get expected after sum so it is not reflected in sum */
|
||||||
|
long expected = UnsignedNumbers.ubyteToShort(buff.get());
|
||||||
|
if (mungedSum != expected) {
|
||||||
|
throw new DecoderException("Checksum failed: expected " + expected
|
||||||
|
+ " got " + mungedSum);
|
||||||
|
}
|
||||||
|
if (total) {
|
||||||
|
buff.resetAllSums();
|
||||||
|
} else {
|
||||||
|
buff.resetPacketSum();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get scaled double from 4 byte integer field
|
||||||
|
*
|
||||||
|
* @param buff
|
||||||
|
* @param scaleFactor
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private static double getDouble(ChecksumByteBuffer buff, double scaleFactor) {
|
||||||
|
int raw = buff.getInt();
|
||||||
|
return raw * scaleFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert amps to kiloamps
|
||||||
|
*
|
||||||
|
* @param amps
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private static double getKiloAmps(int amps) {
|
||||||
|
return amps / AMPS_PER_KILO_AMP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert kilometers to meters
|
||||||
|
*
|
||||||
|
* @param kilometers
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private static double getMeters(short kilometers) {
|
||||||
|
return kilometers * METERS_PER_KILOMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map strike byte to internal enum
|
||||||
|
*
|
||||||
|
* @param type
|
||||||
|
* @return
|
||||||
|
* @throws DecoderException
|
||||||
|
*/
|
||||||
|
public static LtgStrikeType getStrikeType(byte type)
|
||||||
|
throws DecoderException {
|
||||||
|
switch (type) {
|
||||||
|
case CLOUD_TO_GROUND_TYPE:
|
||||||
|
return LtgStrikeType.CLOUD_TO_GROUND;
|
||||||
|
case CLOUD_TO_CLOUD_TYPE:
|
||||||
|
return LtgStrikeType.CLOUD_TO_CLOUD;
|
||||||
|
case KEEP_ALIVE_TYPE:
|
||||||
|
return LtgStrikeType.KEEP_ALIVE;
|
||||||
|
}
|
||||||
|
throw new DecoderException("Unknown flash type: " + type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map pulse byte to internal enum
|
||||||
|
*
|
||||||
|
* @param type
|
||||||
|
* @return
|
||||||
|
* @throws DecoderException
|
||||||
|
*/
|
||||||
|
public static LtgPulseType getPulseType(byte type) throws DecoderException {
|
||||||
|
switch (type) {
|
||||||
|
case RETURN_STROKE_TYPE:
|
||||||
|
return LtgPulseType.RETURN_STROKE;
|
||||||
|
case NON_RETURN_STROKE_TYPE:
|
||||||
|
return LtgPulseType.NON_RETURN_STROKE;
|
||||||
|
case KEEP_ALIVE_TYPE:
|
||||||
|
return LtgPulseType.KEEP_ALIVE;
|
||||||
|
}
|
||||||
|
throw new DecoderException("Unknown pulse type: " + type);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -20,5 +20,5 @@
|
||||||
-->
|
-->
|
||||||
<requestPatterns xmlns:ns2="group">
|
<requestPatterns xmlns:ns2="group">
|
||||||
<regex>^SFUS41 KWBC.*</regex>
|
<regex>^SFUS41 KWBC.*</regex>
|
||||||
<regex>^SFPA41 KWBC.*</regex>
|
<regex>^SFPA4[12] KWBC.*</regex>
|
||||||
</requestPatterns>
|
</requestPatterns>
|
||||||
|
|
|
@ -29,11 +29,7 @@ import com.raytheon.edex.plugin.textlightning.impl.TextLightningParser;
|
||||||
import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
||||||
import com.raytheon.uf.common.dataplugin.binlightning.BinLightningRecord;
|
import com.raytheon.uf.common.dataplugin.binlightning.BinLightningRecord;
|
||||||
import com.raytheon.uf.common.dataplugin.binlightning.impl.LightningStrikePoint;
|
import com.raytheon.uf.common.dataplugin.binlightning.impl.LightningStrikePoint;
|
||||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||||
import com.raytheon.uf.common.status.UFStatus;
|
|
||||||
import com.raytheon.uf.common.time.DataTime;
|
|
||||||
import com.raytheon.uf.common.time.TimeRange;
|
|
||||||
import com.raytheon.uf.edex.decodertools.time.TimeTools;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decoder for text lightning data
|
* Decoder for text lightning data
|
||||||
|
@ -47,6 +43,7 @@ import com.raytheon.uf.edex.decodertools.time.TimeTools;
|
||||||
* Mar 25, 2010 jsanchez Initial creation
|
* Mar 25, 2010 jsanchez Initial creation
|
||||||
* Aug 30, 2013 2298 rjpeter Make getPluginName abstract
|
* Aug 30, 2013 2298 rjpeter Make getPluginName abstract
|
||||||
* Feb 12, 2014 2655 njensen Set source
|
* Feb 12, 2014 2655 njensen Set source
|
||||||
|
* Jun 05, 2014 3226 bclement LightningStikePoint refactor
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -57,9 +54,6 @@ import com.raytheon.uf.edex.decodertools.time.TimeTools;
|
||||||
public class TextLightningDecoder extends AbstractDecoder implements
|
public class TextLightningDecoder extends AbstractDecoder implements
|
||||||
IBinaryDecoder {
|
IBinaryDecoder {
|
||||||
|
|
||||||
private static final IUFStatusHandler logger = UFStatus
|
|
||||||
.getHandler(TextLightningDecoder.class);
|
|
||||||
|
|
||||||
private String traceId = null;
|
private String traceId = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -92,37 +86,19 @@ public class TextLightningDecoder extends AbstractDecoder implements
|
||||||
BinLightningRecord report = null;
|
BinLightningRecord report = null;
|
||||||
|
|
||||||
if (strikes.size() > 0) {
|
if (strikes.size() > 0) {
|
||||||
report = new BinLightningRecord(strikes.size());
|
report = new BinLightningRecord(strikes);
|
||||||
for (LightningStrikePoint strike : strikes) {
|
|
||||||
report.addStrike(strike);
|
|
||||||
logger.debug(traceId + "-" + strike);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return new PluginDataObject[0];
|
return new PluginDataObject[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
Calendar c = TimeTools.getSystemCalendar();
|
Calendar c = TimeUtil.newGmtCalendar();
|
||||||
if (c == null) {
|
|
||||||
throw new DecoderException(traceId + "-Error decoding times");
|
|
||||||
}
|
|
||||||
report.setInsertTime(c);
|
report.setInsertTime(c);
|
||||||
|
|
||||||
Calendar cStart = report.getStartTime();
|
report.setTraceId(traceId);
|
||||||
Calendar cStop = report.getStopTime();
|
|
||||||
|
|
||||||
TimeRange range = new TimeRange(cStart.getTimeInMillis(),
|
// TODO anyone have any idea what the source should actually be
|
||||||
cStop.getTimeInMillis());
|
// named?
|
||||||
|
report.setSource("text");
|
||||||
DataTime dataTime = new DataTime(cStart, range);
|
|
||||||
report.setDataTime(dataTime);
|
|
||||||
|
|
||||||
if (report != null) {
|
|
||||||
report.setTraceId(traceId);
|
|
||||||
|
|
||||||
// TODO anyone have any idea what the source should actually be
|
|
||||||
// named?
|
|
||||||
report.setSource("text");
|
|
||||||
}
|
|
||||||
|
|
||||||
return new PluginDataObject[] { report };
|
return new PluginDataObject[] { report };
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,7 @@ import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||||
* lgtng intensities -999 to
|
* lgtng intensities -999 to
|
||||||
* 999
|
* 999
|
||||||
* Feb 12, 2014 2655 njensen Use status handler for logging
|
* Feb 12, 2014 2655 njensen Use status handler for logging
|
||||||
|
* Jun 05, 2014 3226 bclement LightningStikePoint refactor
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -177,7 +178,7 @@ public class TextLightningParser {
|
||||||
Double.parseDouble(latitude),
|
Double.parseDouble(latitude),
|
||||||
Double.parseDouble(longitude));
|
Double.parseDouble(longitude));
|
||||||
strike.setStrikeStrength(Double.parseDouble(strength));
|
strike.setStrikeStrength(Double.parseDouble(strength));
|
||||||
strike.setStrikeCount(Integer.parseInt(count));
|
strike.setPulseCount(Integer.parseInt(count));
|
||||||
strike.setMonth(Integer.parseInt(month));
|
strike.setMonth(Integer.parseInt(month));
|
||||||
strike.setDay(Integer.parseInt(day));
|
strike.setDay(Integer.parseInt(day));
|
||||||
strike.setYear(Integer.parseInt(year));
|
strike.setYear(Integer.parseInt(year));
|
||||||
|
@ -186,7 +187,7 @@ public class TextLightningParser {
|
||||||
strike.setSecond(Integer.parseInt(sec));
|
strike.setSecond(Integer.parseInt(sec));
|
||||||
strike.setMillis(0);
|
strike.setMillis(0);
|
||||||
strike.setMsgType(LtgMsgType.STRIKE_MSG_FL);
|
strike.setMsgType(LtgMsgType.STRIKE_MSG_FL);
|
||||||
strike.setType(LtgStrikeType.STRIKE_CG);
|
strike.setType(LtgStrikeType.CLOUD_TO_GROUND);
|
||||||
strike.setLightSource("UNKN");
|
strike.setLightSource("UNKN");
|
||||||
reports.add(strike);
|
reports.add(strike);
|
||||||
} else {
|
} else {
|
||||||
|
@ -214,7 +215,7 @@ public class TextLightningParser {
|
||||||
Double.parseDouble(latitude), lon);
|
Double.parseDouble(latitude), lon);
|
||||||
strike.setStrikeStrength(Double
|
strike.setStrikeStrength(Double
|
||||||
.parseDouble(strength));
|
.parseDouble(strength));
|
||||||
strike.setStrikeCount(Integer.parseInt(count));
|
strike.setPulseCount(Integer.parseInt(count));
|
||||||
strike.setMonth(Integer.parseInt(month));
|
strike.setMonth(Integer.parseInt(month));
|
||||||
strike.setDay(Integer.parseInt(day));
|
strike.setDay(Integer.parseInt(day));
|
||||||
strike.setYear(Integer.parseInt(year) + 2000);
|
strike.setYear(Integer.parseInt(year) + 2000);
|
||||||
|
@ -223,7 +224,7 @@ public class TextLightningParser {
|
||||||
strike.setSecond(Integer.parseInt(sec));
|
strike.setSecond(Integer.parseInt(sec));
|
||||||
strike.setMillis(Integer.parseInt(msec) * 10);
|
strike.setMillis(Integer.parseInt(msec) * 10);
|
||||||
strike.setMsgType(LtgMsgType.STRIKE_MSG_FL);
|
strike.setMsgType(LtgMsgType.STRIKE_MSG_FL);
|
||||||
strike.setType(LtgStrikeType.STRIKE_CG);
|
strike.setType(LtgStrikeType.CLOUD_TO_GROUND);
|
||||||
strike.setLightSource("UNKN");
|
strike.setLightSource("UNKN");
|
||||||
reports.add(strike);
|
reports.add(strike);
|
||||||
} else {
|
} else {
|
||||||
|
@ -250,7 +251,7 @@ public class TextLightningParser {
|
||||||
Double.parseDouble(longitude));
|
Double.parseDouble(longitude));
|
||||||
strike.setStrikeStrength(Double
|
strike.setStrikeStrength(Double
|
||||||
.parseDouble(strength));
|
.parseDouble(strength));
|
||||||
strike.setStrikeCount(Integer.parseInt(count));
|
strike.setPulseCount(Integer.parseInt(count));
|
||||||
strike.setMonth(Integer.parseInt(month));
|
strike.setMonth(Integer.parseInt(month));
|
||||||
strike.setDay(Integer.parseInt(day));
|
strike.setDay(Integer.parseInt(day));
|
||||||
strike.setYear(Integer.parseInt(year));
|
strike.setYear(Integer.parseInt(year));
|
||||||
|
@ -259,7 +260,7 @@ public class TextLightningParser {
|
||||||
strike.setSecond(Integer.parseInt(sec));
|
strike.setSecond(Integer.parseInt(sec));
|
||||||
strike.setMillis(Integer.parseInt(msec) * 10);
|
strike.setMillis(Integer.parseInt(msec) * 10);
|
||||||
strike.setMsgType(LtgMsgType.STRIKE_MSG_FL);
|
strike.setMsgType(LtgMsgType.STRIKE_MSG_FL);
|
||||||
strike.setType(LtgStrikeType.STRIKE_CG);
|
strike.setType(LtgStrikeType.CLOUD_TO_GROUND);
|
||||||
strike.setLightSource(sls);
|
strike.setLightSource(sls);
|
||||||
reports.add(strike);
|
reports.add(strike);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -19,8 +19,13 @@
|
||||||
**/
|
**/
|
||||||
package com.raytheon.uf.common.dataplugin.binlightning;
|
package com.raytheon.uf.common.dataplugin.binlightning;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
import javax.persistence.Access;
|
import javax.persistence.Access;
|
||||||
import javax.persistence.AccessType;
|
import javax.persistence.AccessType;
|
||||||
|
@ -35,18 +40,17 @@ import org.hibernate.annotations.Index;
|
||||||
|
|
||||||
import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
||||||
import com.raytheon.uf.common.dataplugin.annotations.DataURI;
|
import com.raytheon.uf.common.dataplugin.annotations.DataURI;
|
||||||
|
import com.raytheon.uf.common.dataplugin.binlightning.impl.LightningPulsePoint;
|
||||||
import com.raytheon.uf.common.dataplugin.binlightning.impl.LightningStrikePoint;
|
import com.raytheon.uf.common.dataplugin.binlightning.impl.LightningStrikePoint;
|
||||||
import com.raytheon.uf.common.dataplugin.persist.IPersistable;
|
import com.raytheon.uf.common.dataplugin.persist.IPersistable;
|
||||||
import com.raytheon.uf.common.dataplugin.persist.PersistablePluginDataObject;
|
import com.raytheon.uf.common.dataplugin.persist.PersistablePluginDataObject;
|
||||||
import com.raytheon.uf.common.datastorage.IDataStore;
|
import com.raytheon.uf.common.datastorage.IDataStore;
|
||||||
import com.raytheon.uf.common.datastorage.StorageException;
|
import com.raytheon.uf.common.datastorage.StorageException;
|
||||||
import com.raytheon.uf.common.datastorage.records.ByteDataRecord;
|
|
||||||
import com.raytheon.uf.common.datastorage.records.FloatDataRecord;
|
|
||||||
import com.raytheon.uf.common.datastorage.records.IDataRecord;
|
import com.raytheon.uf.common.datastorage.records.IDataRecord;
|
||||||
import com.raytheon.uf.common.datastorage.records.IntegerDataRecord;
|
|
||||||
import com.raytheon.uf.common.datastorage.records.LongDataRecord;
|
|
||||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
||||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
||||||
|
import com.raytheon.uf.common.time.DataTime;
|
||||||
|
import com.raytheon.uf.common.time.TimeRange;
|
||||||
import com.raytheon.uf.common.time.util.TimeUtil;
|
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -82,6 +86,8 @@ import com.raytheon.uf.common.time.util.TimeUtil;
|
||||||
* Oct 22, 2013 2361 njensen Removed XML annotations
|
* Oct 22, 2013 2361 njensen Removed XML annotations
|
||||||
* Jan 21, 2014 2667 bclement renamed record's lightSource field to source
|
* Jan 21, 2014 2667 bclement renamed record's lightSource field to source
|
||||||
* May 14, 2014 2536 bclement removed TimeTools usage
|
* May 14, 2014 2536 bclement removed TimeTools usage
|
||||||
|
* Jun 05, 2014 3226 bclement moved data arrays into map for easier management
|
||||||
|
* replaced addStrike() with List constructor, added pulses
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -106,43 +112,12 @@ public class BinLightningRecord extends PersistablePluginDataObject implements
|
||||||
|
|
||||||
public static final String PLUGIN_NAME = "binlightning";
|
public static final String PLUGIN_NAME = "binlightning";
|
||||||
|
|
||||||
|
// Data store data items
|
||||||
@Transient
|
@Transient
|
||||||
private long[] obsTimes = null;
|
private final Map<String, Object> strikeDataArrays = new TreeMap<String, Object>();
|
||||||
|
|
||||||
@Transient
|
@Transient
|
||||||
private float[] latitudes = null;
|
private final Map<String, Object> pulseDataArrays = new TreeMap<String, Object>();
|
||||||
|
|
||||||
@Transient
|
|
||||||
private float[] longitudes = null;
|
|
||||||
|
|
||||||
@Transient
|
|
||||||
private int[] intensities = null;
|
|
||||||
|
|
||||||
@Transient
|
|
||||||
private byte[] msgTypes = null;
|
|
||||||
|
|
||||||
@Transient
|
|
||||||
private byte[] strikeTypes = null;
|
|
||||||
|
|
||||||
@Transient
|
|
||||||
private byte[] strikeCounts = null;
|
|
||||||
|
|
||||||
@Transient
|
|
||||||
private Object[] dataArrays = null;
|
|
||||||
|
|
||||||
// Data store data item names
|
|
||||||
@Transient
|
|
||||||
private final String[] dataNames = { "obsTime", "latitude", "longitude",
|
|
||||||
"intensity", "msgType", "strikeType", "strikeCount", };
|
|
||||||
|
|
||||||
@Transient
|
|
||||||
private int insertIndex = 0;
|
|
||||||
|
|
||||||
@Transient
|
|
||||||
private long startTimeMillis = Long.MAX_VALUE;
|
|
||||||
|
|
||||||
@Transient
|
|
||||||
private long stopTimeMillis = Long.MIN_VALUE;
|
|
||||||
|
|
||||||
// Persisted value - Earliest strike time in the collection.
|
// Persisted value - Earliest strike time in the collection.
|
||||||
@DataURI(position = 1)
|
@DataURI(position = 1)
|
||||||
|
@ -177,63 +152,148 @@ public class BinLightningRecord extends PersistablePluginDataObject implements
|
||||||
*
|
*
|
||||||
* @param uri
|
* @param uri
|
||||||
* The dataURI
|
* The dataURI
|
||||||
* @param tableDef
|
|
||||||
* The table definition associated with this class
|
|
||||||
*/
|
*/
|
||||||
public BinLightningRecord(String uri) {
|
public BinLightningRecord(String uri) {
|
||||||
super(uri);
|
super(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct an empty lightning record.
|
* Construct a lightning record from a list of strikes
|
||||||
|
*
|
||||||
|
* @param strikes
|
||||||
*/
|
*/
|
||||||
public BinLightningRecord(int arraysSize) {
|
public BinLightningRecord(final List<LightningStrikePoint> strikes) {
|
||||||
obsTimes = new long[arraysSize];
|
final int arraysSize = strikes.size();
|
||||||
latitudes = new float[arraysSize];
|
long[] obsTimes = new long[arraysSize];
|
||||||
longitudes = new float[arraysSize];
|
float[] latitudes = new float[arraysSize];
|
||||||
|
float[] longitudes = new float[arraysSize];
|
||||||
|
int[] intensities = new int[arraysSize];
|
||||||
|
byte[] msgTypes = new byte[arraysSize];
|
||||||
|
byte[] strikeTypes = new byte[arraysSize];
|
||||||
|
byte[] pulseCounts = new byte[arraysSize];
|
||||||
|
int[] pulseIndexes = new int[arraysSize];
|
||||||
|
int[] heights = new int[arraysSize];
|
||||||
|
int[] sensorCounts = new int[arraysSize];
|
||||||
|
|
||||||
intensities = new int[arraysSize];
|
strikeDataArrays.put(LightningConstants.TIME_DATASET, obsTimes);
|
||||||
msgTypes = new byte[arraysSize];
|
strikeDataArrays.put(LightningConstants.LAT_DATASET, latitudes);
|
||||||
strikeTypes = new byte[arraysSize];
|
strikeDataArrays.put(LightningConstants.LON_DATASET, longitudes);
|
||||||
strikeCounts = new byte[arraysSize];
|
strikeDataArrays.put(LightningConstants.INTENSITY_DATASET, intensities);
|
||||||
dataArrays = new Object[] { obsTimes, latitudes, longitudes,
|
strikeDataArrays.put(LightningConstants.MSG_TYPE_DATASET, msgTypes);
|
||||||
intensities, msgTypes, strikeTypes, strikeCounts, };
|
strikeDataArrays.put(LightningConstants.STRIKE_TYPE_DATASET,
|
||||||
insertIndex = 0;
|
strikeTypes);
|
||||||
|
strikeDataArrays
|
||||||
|
.put(LightningConstants.PULSE_COUNT_DATSET, pulseCounts);
|
||||||
|
strikeDataArrays.put(LightningConstants.PULSE_INDEX_DATASET,
|
||||||
|
pulseIndexes);
|
||||||
|
strikeDataArrays.put(LightningConstants.HEIGHT_DATASET, heights);
|
||||||
|
strikeDataArrays.put(LightningConstants.SENSOR_COUNT_DATASET,
|
||||||
|
sensorCounts);
|
||||||
|
|
||||||
|
if (arraysSize > 0) {
|
||||||
|
LightningStrikePoint sample = strikes.get(0);
|
||||||
|
setDataSource(sample);
|
||||||
|
}
|
||||||
|
|
||||||
|
long startTimeMillis = Long.MAX_VALUE;
|
||||||
|
long stopTimeMillis = Long.MIN_VALUE;
|
||||||
|
|
||||||
|
int pulseDataCount = 0;
|
||||||
|
|
||||||
|
final Iterator<LightningStrikePoint> iter = strikes.iterator();
|
||||||
|
for (int i = 0; i < arraysSize; ++i) {
|
||||||
|
LightningStrikePoint strike = iter.next();
|
||||||
|
Calendar c = strike.getTime();
|
||||||
|
|
||||||
|
long obsTimeMillis = c.getTimeInMillis();
|
||||||
|
|
||||||
|
startTimeMillis = Math.min(startTimeMillis, obsTimeMillis);
|
||||||
|
stopTimeMillis = Math.max(stopTimeMillis, obsTimeMillis);
|
||||||
|
|
||||||
|
obsTimes[i] = obsTimeMillis;
|
||||||
|
latitudes[i] = (float) strike.getLatitude();
|
||||||
|
longitudes[i] = (float) strike.getLongitude();
|
||||||
|
|
||||||
|
intensities[i] = (int) Math.round(strike.getStrikeStrength());
|
||||||
|
msgTypes[i] = (byte) strike.getMsgType().getId();
|
||||||
|
strikeTypes[i] = (byte) strike.getType().getId();
|
||||||
|
/* some types have pulse counts but no pulse data */
|
||||||
|
pulseCounts[i] = (byte) strike.getPulseCount();
|
||||||
|
heights[i] = (int) Math.round(strike.getElevation());
|
||||||
|
sensorCounts[i] = strike.getSensorCount();
|
||||||
|
|
||||||
|
List<LightningPulsePoint> pulses = strike.getPulses();
|
||||||
|
if (pulses != null && !pulses.isEmpty()) {
|
||||||
|
pulseIndexes[i] = pulseDataCount;
|
||||||
|
pulseDataCount += pulses.size();
|
||||||
|
if (pulseCounts[i] != pulses.size()) {
|
||||||
|
pulseCounts[i] = (byte) pulses.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pulseDataCount > 0) {
|
||||||
|
/* at least one of the strikes had pulse data */
|
||||||
|
setPulseData(strikes, pulseDataCount);
|
||||||
|
}
|
||||||
|
startTime = TimeUtil.newGmtCalendar(new Date(startTimeMillis));
|
||||||
|
stopTime = TimeUtil.newGmtCalendar(new Date(stopTimeMillis));
|
||||||
|
|
||||||
|
TimeRange range = new TimeRange(startTime, stopTime);
|
||||||
|
setDataTime(new DataTime(startTime, range));
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
|
||||||
// * Construct an empty lightning record.
|
|
||||||
// *
|
|
||||||
// * @param message
|
|
||||||
// * Lightning data report.
|
|
||||||
// */
|
|
||||||
// public BinLightningRecord(String message) {
|
|
||||||
// super(message);
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Track the current persistence time for the data set.
|
* @param strikes
|
||||||
|
* @param pulseDataCount
|
||||||
|
* total number of pulses for all strikes
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused")
|
private void setPulseData(final List<LightningStrikePoint> strikes,
|
||||||
private void updatePersistenceTime() {
|
final int pulseDataCount) {
|
||||||
if ((startTimeMillis != Long.MAX_VALUE)
|
long[] pulseTimes = new long[pulseDataCount];
|
||||||
&& (stopTimeMillis != Long.MIN_VALUE)) {
|
float[] pulseLats = new float[pulseDataCount];
|
||||||
persistTime = (startTimeMillis + stopTimeMillis) / 2;
|
float[] pulseLons = new float[pulseDataCount];
|
||||||
setPersistenceTime(new Date(persistTime));
|
int[] pulseIntensities = new int[pulseDataCount];
|
||||||
} else {
|
byte[] pulseTypes = new byte[pulseDataCount];
|
||||||
setPersistenceTime(TimeUtil.newGmtCalendar().getTime());
|
int[] pulseHeights = new int[pulseDataCount];
|
||||||
persistTime = getInsertTime().getTimeInMillis();
|
int[] pulseSensorCounts = new int[pulseDataCount];
|
||||||
|
|
||||||
|
pulseDataArrays.put(LightningConstants.TIME_DATASET, pulseTimes);
|
||||||
|
pulseDataArrays.put(LightningConstants.LAT_DATASET, pulseLats);
|
||||||
|
pulseDataArrays.put(LightningConstants.LON_DATASET, pulseLons);
|
||||||
|
pulseDataArrays.put(LightningConstants.INTENSITY_DATASET,
|
||||||
|
pulseIntensities);
|
||||||
|
pulseDataArrays.put(LightningConstants.PULSE_TYPE_DATASET, pulseTypes);
|
||||||
|
pulseDataArrays.put(LightningConstants.HEIGHT_DATASET, pulseHeights);
|
||||||
|
pulseDataArrays.put(LightningConstants.SENSOR_COUNT_DATASET,
|
||||||
|
pulseSensorCounts);
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
for (LightningStrikePoint strike : strikes) {
|
||||||
|
List<LightningPulsePoint> pulses = strike.getPulses();
|
||||||
|
if (pulses != null && !pulses.isEmpty()) {
|
||||||
|
for (LightningPulsePoint pulse : pulses) {
|
||||||
|
pulseTimes[index] = pulse.getTime().getTimeInMillis();
|
||||||
|
pulseLats[index] = (float) pulse.getLatitude();
|
||||||
|
pulseLons[index] = (float) pulse.getLongitude();
|
||||||
|
pulseIntensities[index] = (int) Math.round(pulse
|
||||||
|
.getStrikeStrength());
|
||||||
|
pulseTypes[index] = pulse.getType().getId();
|
||||||
|
pulseHeights[index] = (int) Math
|
||||||
|
.round(pulse.getElevation());
|
||||||
|
pulseSensorCounts[index] = pulse.getSensorCount();
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a strike report to the record collection.
|
* Extract data source from strike
|
||||||
*
|
*
|
||||||
* @param strike
|
* @param strike
|
||||||
* A strike report to add.
|
|
||||||
*/
|
*/
|
||||||
public void addStrike(LightningStrikePoint strike) {
|
private void setDataSource(LightningStrikePoint strike) {
|
||||||
// jjg add
|
|
||||||
if (source == null) {
|
if (source == null) {
|
||||||
if (strike.getLightSource() == null) {
|
if (strike.getLightSource() == null) {
|
||||||
source = "NLDN";
|
source = "NLDN";
|
||||||
|
@ -249,47 +309,6 @@ public class BinLightningRecord extends PersistablePluginDataObject implements
|
||||||
source = "UNKN";
|
source = "UNKN";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// end
|
|
||||||
|
|
||||||
if (insertIndex < obsTimes.length) {
|
|
||||||
long t1 = startTimeMillis;
|
|
||||||
|
|
||||||
Calendar c = TimeUtil.newGmtCalendar(strike.getYear(),
|
|
||||||
strike.getMonth(), strike.getDay());
|
|
||||||
|
|
||||||
c.set(Calendar.HOUR_OF_DAY, strike.getHour());
|
|
||||||
c.set(Calendar.MINUTE, strike.getMinute());
|
|
||||||
c.set(Calendar.SECOND, strike.getSecond());
|
|
||||||
c.set(Calendar.MILLISECOND, strike.getMillis());
|
|
||||||
|
|
||||||
long obsTimeMillis = c.getTimeInMillis();
|
|
||||||
|
|
||||||
startTimeMillis = Math.min(startTimeMillis, obsTimeMillis);
|
|
||||||
stopTimeMillis = Math.max(stopTimeMillis, obsTimeMillis);
|
|
||||||
|
|
||||||
obsTimes[insertIndex] = obsTimeMillis;
|
|
||||||
latitudes[insertIndex] = (float) strike.getLatitude();
|
|
||||||
longitudes[insertIndex] = (float) strike.getLongitude();
|
|
||||||
|
|
||||||
intensities[insertIndex] = Math.round((float) strike
|
|
||||||
.getStrikeStrength());
|
|
||||||
msgTypes[insertIndex] = (byte) strike.getMsgType().ordinal();
|
|
||||||
strikeTypes[insertIndex] = (byte) strike.getType().ordinal();
|
|
||||||
strikeCounts[insertIndex] = (byte) strike.getStrikeCount();
|
|
||||||
insertIndex++;
|
|
||||||
// only update the times if they have changed!
|
|
||||||
if (t1 != startTimeMillis) {
|
|
||||||
startTime = TimeUtil.newGmtCalendar(new Date(startTimeMillis));
|
|
||||||
}
|
|
||||||
if (t1 != stopTimeMillis) {
|
|
||||||
stopTime = TimeUtil.newGmtCalendar(new Date(stopTimeMillis));
|
|
||||||
}
|
|
||||||
|
|
||||||
// updatePersistenceTime();
|
|
||||||
} else {
|
|
||||||
throw new ArrayIndexOutOfBoundsException(String.format(
|
|
||||||
"index greater than length [%d]", insertIndex));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -349,25 +368,14 @@ public class BinLightningRecord extends PersistablePluginDataObject implements
|
||||||
setInsertTime(insert_time);
|
setInsertTime(insert_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String[] getDataNames() {
|
|
||||||
return dataNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object[] getDataArrays() {
|
|
||||||
return dataArrays;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDataArrays(Object[] dataArrays) {
|
|
||||||
this.dataArrays = dataArrays;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gets the obsTimes
|
* gets the obsTimes
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public long[] getObsTimes() {
|
public long[] getObsTimes() {
|
||||||
return obsTimes;
|
Object obj = strikeDataArrays.get(LightningConstants.TIME_DATASET);
|
||||||
|
return obj != null ? (long[]) obj : new long[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -376,7 +384,8 @@ public class BinLightningRecord extends PersistablePluginDataObject implements
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public float[] getLatitudes() {
|
public float[] getLatitudes() {
|
||||||
return latitudes;
|
Object obj = strikeDataArrays.get(LightningConstants.LAT_DATASET);
|
||||||
|
return obj != null ? (float[]) obj : new float[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -385,7 +394,8 @@ public class BinLightningRecord extends PersistablePluginDataObject implements
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public float[] getLongitudes() {
|
public float[] getLongitudes() {
|
||||||
return longitudes;
|
Object obj = strikeDataArrays.get(LightningConstants.LON_DATASET);
|
||||||
|
return obj != null ? (float[]) obj : new float[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -394,7 +404,8 @@ public class BinLightningRecord extends PersistablePluginDataObject implements
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public int[] getIntensities() {
|
public int[] getIntensities() {
|
||||||
return intensities;
|
Object obj = strikeDataArrays.get(LightningConstants.INTENSITY_DATASET);
|
||||||
|
return obj != null ? (int[]) obj : new int[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -403,7 +414,8 @@ public class BinLightningRecord extends PersistablePluginDataObject implements
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public byte[] getMsgTypes() {
|
public byte[] getMsgTypes() {
|
||||||
return msgTypes;
|
Object obj = strikeDataArrays.get(LightningConstants.MSG_TYPE_DATASET);
|
||||||
|
return obj != null ? (byte[]) obj : new byte[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -412,7 +424,9 @@ public class BinLightningRecord extends PersistablePluginDataObject implements
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public byte[] getStrikeTypes() {
|
public byte[] getStrikeTypes() {
|
||||||
return strikeTypes;
|
Object obj = strikeDataArrays
|
||||||
|
.get(LightningConstants.STRIKE_TYPE_DATASET);
|
||||||
|
return obj != null ? (byte[]) obj : new byte[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -420,8 +434,10 @@ public class BinLightningRecord extends PersistablePluginDataObject implements
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public byte[] getStrikeCounts() {
|
public byte[] getPulseCounts() {
|
||||||
return strikeCounts;
|
Object obj = strikeDataArrays
|
||||||
|
.get(LightningConstants.PULSE_COUNT_DATSET);
|
||||||
|
return obj != null ? (byte[]) obj : new byte[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -449,42 +465,55 @@ public class BinLightningRecord extends PersistablePluginDataObject implements
|
||||||
*/
|
*/
|
||||||
public void retrieveFromDataStore(IDataStore dataStore)
|
public void retrieveFromDataStore(IDataStore dataStore)
|
||||||
throws StorageException {
|
throws StorageException {
|
||||||
|
retrieveFromDataStore(dataStore, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the data arrays from the store.
|
||||||
|
*
|
||||||
|
* @param dataStore
|
||||||
|
* @param includePulses
|
||||||
|
* extract pulse data if true
|
||||||
|
*/
|
||||||
|
public void retrieveFromDataStore(IDataStore dataStore,
|
||||||
|
boolean includePulses) throws StorageException {
|
||||||
try {
|
try {
|
||||||
IDataRecord[] dataRec = dataStore.retrieve(getDataURI());
|
IDataRecord[] dataRecs = dataStore.retrieve(getDataURI());
|
||||||
dataArrays = new Object[dataRec.length];
|
for (IDataRecord record : dataRecs) {
|
||||||
for (int i = 0; i < dataRec.length; i++) {
|
strikeDataArrays.put(record.getName(), record.getDataObject());
|
||||||
if (dataRec[i].getName().equals("obsTime")) {
|
}
|
||||||
obsTimes = ((LongDataRecord) dataRec[i]).getLongData();
|
if (includePulses) {
|
||||||
dataArrays[i] = obsTimes;
|
String pulseGroup = getDataURI() + DataURI.SEPARATOR
|
||||||
}
|
+ LightningConstants.PULSE_HDF5_GROUP_SUFFIX;
|
||||||
if (dataRec[i].getName().equals("latitude")) {
|
try {
|
||||||
latitudes = ((FloatDataRecord) dataRec[i]).getFloatData();
|
IDataRecord[] pulseRecords = dataStore.retrieve(pulseGroup);
|
||||||
dataArrays[i] = latitudes;
|
for (IDataRecord record : pulseRecords) {
|
||||||
} else if (dataRec[i].getName().equals("longitude")) {
|
pulseDataArrays.put(record.getName(),
|
||||||
longitudes = ((FloatDataRecord) dataRec[i]).getFloatData();
|
record.getDataObject());
|
||||||
dataArrays[i] = longitudes;
|
}
|
||||||
} else if (dataRec[i].getName().equals("intensity")) {
|
} catch (Exception e) {
|
||||||
intensities = ((IntegerDataRecord) dataRec[i]).getIntData();
|
/* FIXME better way to find out if group doesn't exist */
|
||||||
dataArrays[i] = intensities;
|
|
||||||
} else if (dataRec[i].getName().equals("msgType")) {
|
|
||||||
msgTypes = ((ByteDataRecord) dataRec[i]).getByteData();
|
|
||||||
dataArrays[i] = msgTypes;
|
|
||||||
} else if (dataRec[i].getName().equals("strikeType")) {
|
|
||||||
strikeTypes = ((ByteDataRecord) dataRec[i]).getByteData();
|
|
||||||
dataArrays[i] = strikeTypes;
|
|
||||||
} else if (dataRec[i].getName().equals("strikeCount")) {
|
|
||||||
strikeCounts = ((ByteDataRecord) dataRec[i]).getByteData();
|
|
||||||
dataArrays[i] = strikeCounts;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setDataArrays(dataArrays);
|
} catch (FileNotFoundException e) {
|
||||||
|
throw new StorageException(e.getLocalizedMessage(), null, e);
|
||||||
} catch (Exception se) {
|
|
||||||
se.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the strikeDataArrays
|
||||||
|
*/
|
||||||
|
public Map<String, Object> getStrikeDataArrays() {
|
||||||
|
return strikeDataArrays;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the pulseDataArrays
|
||||||
|
*/
|
||||||
|
public Map<String, Object> getPulseDataArrays() {
|
||||||
|
return pulseDataArrays;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Column
|
@Column
|
||||||
@Access(AccessType.PROPERTY)
|
@Access(AccessType.PROPERTY)
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.common.dataplugin.binlightning;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constants used for lightning data such as dataset names in HDF5
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* May 30, 2014 3226 bclement Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author bclement
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public class LightningConstants {
|
||||||
|
|
||||||
|
public static final String PULSE_HDF5_GROUP_SUFFIX = "pulse";
|
||||||
|
|
||||||
|
// HDF5 dataset names
|
||||||
|
|
||||||
|
public static final String TIME_DATASET = "obsTime";
|
||||||
|
|
||||||
|
public static final String LAT_DATASET = "latitude";
|
||||||
|
|
||||||
|
public static final String LON_DATASET = "longitude";
|
||||||
|
|
||||||
|
public static final String INTENSITY_DATASET = "intensity";
|
||||||
|
|
||||||
|
public static final String MSG_TYPE_DATASET = "msgType";
|
||||||
|
|
||||||
|
public static final String STRIKE_TYPE_DATASET = "strikeType";
|
||||||
|
|
||||||
|
public static final String PULSE_COUNT_DATSET = "pulseCount";
|
||||||
|
|
||||||
|
public static final String PULSE_INDEX_DATASET = "pulseIndex";
|
||||||
|
|
||||||
|
public static final String PULSE_TYPE_DATASET = "pulseType";
|
||||||
|
|
||||||
|
public static final String HEIGHT_DATASET = "height";
|
||||||
|
|
||||||
|
public static final String SENSOR_COUNT_DATASET = "sensorCount";
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,259 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.common.dataplugin.binlightning.impl;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||||
|
import com.vividsolutions.jts.geom.Coordinate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lightning information common to strikes and pulses
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Jun 3, 2014 3226 bclement Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author bclement
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public class BaseLightningPoint {
|
||||||
|
|
||||||
|
private final Coordinate point;
|
||||||
|
|
||||||
|
private Calendar time;
|
||||||
|
|
||||||
|
// Lightning strike strength and polarity
|
||||||
|
private double strikeStrength;
|
||||||
|
|
||||||
|
private int sensorCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public BaseLightningPoint() {
|
||||||
|
this(TimeUtil.newGmtCalendar());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param time
|
||||||
|
*/
|
||||||
|
public BaseLightningPoint(Calendar time) {
|
||||||
|
this(new Coordinate(), time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param point
|
||||||
|
*/
|
||||||
|
public BaseLightningPoint(Coordinate point, Calendar time) {
|
||||||
|
this.point = point;
|
||||||
|
this.time = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param latitude
|
||||||
|
* @param longitude
|
||||||
|
*/
|
||||||
|
public BaseLightningPoint(double latitude, double longitude, Calendar time) {
|
||||||
|
this(new Coordinate(longitude, latitude), time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the year part of the date.
|
||||||
|
*
|
||||||
|
* @param year
|
||||||
|
* Year.
|
||||||
|
*/
|
||||||
|
public void setYear(int year) {
|
||||||
|
this.time.set(Calendar.YEAR, year);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the day of the month part of the date.
|
||||||
|
*
|
||||||
|
* @param day
|
||||||
|
* Day of month [1..12].
|
||||||
|
*/
|
||||||
|
public void setMonth(int month) {
|
||||||
|
this.time.set(Calendar.MONTH, month - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the day of the month part of the date.
|
||||||
|
*
|
||||||
|
* @param day
|
||||||
|
* Day of month [1..12].
|
||||||
|
*/
|
||||||
|
public void setDay(int day) {
|
||||||
|
this.time.set(Calendar.DAY_OF_MONTH, day);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the hour part of the time.
|
||||||
|
*
|
||||||
|
* @param hour
|
||||||
|
* Hour of the day [0..23].
|
||||||
|
*/
|
||||||
|
public void setHour(int hour) {
|
||||||
|
this.time.set(Calendar.HOUR, hour);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the minute of the hour.
|
||||||
|
*
|
||||||
|
* @param minute
|
||||||
|
* The minute of the hour [0..59]
|
||||||
|
*/
|
||||||
|
public void setMinute(int minute) {
|
||||||
|
this.time.set(Calendar.MINUTE, minute);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the second of the minute.
|
||||||
|
*
|
||||||
|
* @param second
|
||||||
|
* The second of the minute [0..59]
|
||||||
|
*/
|
||||||
|
public void setSecond(int second) {
|
||||||
|
this.time.set(Calendar.SECOND, second);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the milliseconds part of the time.
|
||||||
|
*
|
||||||
|
* @param millis
|
||||||
|
* Milliseconds [0..999].
|
||||||
|
*/
|
||||||
|
public void setMillis(int millis) {
|
||||||
|
this.time.set(Calendar.MILLISECOND, millis);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the time
|
||||||
|
*/
|
||||||
|
public Calendar getTime() {
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param time
|
||||||
|
* the time to set
|
||||||
|
*/
|
||||||
|
public void setTime(Calendar time) {
|
||||||
|
this.time = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the strike strength.
|
||||||
|
*
|
||||||
|
* @return The strike strength.
|
||||||
|
*/
|
||||||
|
public double getStrikeStrength() {
|
||||||
|
return strikeStrength;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the strike strength.
|
||||||
|
*
|
||||||
|
* @return The strike strength.
|
||||||
|
*/
|
||||||
|
public void setStrikeStrength(double strikeStrength) {
|
||||||
|
this.strikeStrength = strikeStrength;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the sensorCount
|
||||||
|
*/
|
||||||
|
public int getSensorCount() {
|
||||||
|
return sensorCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param sensorCount
|
||||||
|
* the sensorCount to set
|
||||||
|
*/
|
||||||
|
public void setSensorCount(int sensorCount) {
|
||||||
|
this.sensorCount = sensorCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the latitude of this point.
|
||||||
|
*
|
||||||
|
* @return The latitude.
|
||||||
|
*/
|
||||||
|
public double getLatitude() {
|
||||||
|
return point.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the latitude for this point.
|
||||||
|
*
|
||||||
|
* @param latitude
|
||||||
|
* The latitude.
|
||||||
|
*/
|
||||||
|
public void setLatitude(double latitude) {
|
||||||
|
this.point.y = latitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the longitude of this point.
|
||||||
|
*
|
||||||
|
* @return The longitude.
|
||||||
|
*/
|
||||||
|
public double getLongitude() {
|
||||||
|
return point.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the longitude for this point.
|
||||||
|
*
|
||||||
|
* @param longitude
|
||||||
|
* The longitude.
|
||||||
|
*/
|
||||||
|
public void setLongitude(double longitude) {
|
||||||
|
this.point.x = longitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the elevation of this point. No units are specified.
|
||||||
|
*
|
||||||
|
* @return The elevation of this point.
|
||||||
|
*/
|
||||||
|
public double getElevation() {
|
||||||
|
return this.point.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the elevation of this point. No units are specified.
|
||||||
|
*
|
||||||
|
* @param elevation
|
||||||
|
* The elevation of this point.
|
||||||
|
*/
|
||||||
|
public void setElevation(double elevation) {
|
||||||
|
this.point.z = elevation;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.common.dataplugin.binlightning.impl;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lightning pulse information
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Jun 3, 2014 3226 bclement Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author bclement
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public class LightningPulsePoint extends BaseLightningPoint {
|
||||||
|
|
||||||
|
private final LtgPulseType type;
|
||||||
|
|
||||||
|
public LightningPulsePoint(LtgPulseType type) {
|
||||||
|
super();
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LightningPulsePoint(Calendar time, LtgPulseType type) {
|
||||||
|
super(time);
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LightningPulsePoint(double latitude, double longitude,
|
||||||
|
Calendar time, LtgPulseType type) {
|
||||||
|
super(latitude, longitude, time);
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the type
|
||||||
|
*/
|
||||||
|
public LtgPulseType getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -19,53 +19,59 @@
|
||||||
**/
|
**/
|
||||||
package com.raytheon.uf.common.dataplugin.binlightning.impl;
|
package com.raytheon.uf.common.dataplugin.binlightning.impl;
|
||||||
|
|
||||||
import com.raytheon.uf.edex.decodertools.core.BasePoint;
|
import java.util.Calendar;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Record implementation for the Binary Lightning data decoder.
|
* Record implementation for the Binary Lightning data decoder.
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
*
|
*
|
||||||
* SOFTWARE HISTORY
|
* SOFTWARE HISTORY
|
||||||
*
|
*
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* 20070810 379 jkorman Initial Coding from prototype.
|
* 20070810 379 jkorman Initial Coding from prototype.
|
||||||
* 20130227 DCS 152 jgerth Support for WWLLN and multiple sources
|
* 20130227 DCS 152 jgerth Support for WWLLN and multiple sources
|
||||||
|
* Jun 3, 2014 3226 bclement refactor to support pulse data
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author jkorman
|
* @author jkorman
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
*/
|
*/
|
||||||
public class LightningStrikePoint extends BasePoint
|
public class LightningStrikePoint extends BaseLightningPoint
|
||||||
{
|
{
|
||||||
|
|
||||||
private LtgStrikeType type;
|
private LtgStrikeType type;
|
||||||
|
|
||||||
private LtgMsgType msgType;
|
private LtgMsgType msgType;
|
||||||
|
|
||||||
// Lightning strike strength and polarity
|
// Number of pulses for this record.
|
||||||
private double strikeStrength;
|
private int pulseCount;
|
||||||
|
|
||||||
// Number of strikes for this record.
|
|
||||||
private int strikeCount;
|
|
||||||
|
|
||||||
// JJG - Lightning data source
|
// JJG - Lightning data source
|
||||||
private String lightSource;
|
private String lightSource;
|
||||||
|
|
||||||
|
private List<LightningPulsePoint> pulses;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a LightningStrikePoint using given data.
|
* Construct a LightningStrikePoint using given data.
|
||||||
* @param base The base point which should contain a valid time.
|
*
|
||||||
* @param latitude The latitude of the strike.
|
* @param latitude
|
||||||
* @param longitude The longitude of the strike.
|
* The latitude of the strike.
|
||||||
* @param type The strike message type.
|
* @param longitude
|
||||||
|
* The longitude of the strike.
|
||||||
|
* @param time
|
||||||
|
* @param type
|
||||||
|
* The strike message type.
|
||||||
*/
|
*/
|
||||||
public LightningStrikePoint(BasePoint base, double latitude, double longitude, LtgMsgType type)
|
public LightningStrikePoint(double latitude, double longitude,
|
||||||
|
Calendar time, LtgMsgType type)
|
||||||
{
|
{
|
||||||
super(base);
|
super(latitude, longitude, time);
|
||||||
setLatitude(latitude);
|
|
||||||
setLongitude(longitude);
|
|
||||||
setElevation(0);
|
setElevation(0);
|
||||||
this.msgType = type;
|
this.msgType = type;
|
||||||
}
|
}
|
||||||
|
@ -77,44 +83,37 @@ public class LightningStrikePoint extends BasePoint
|
||||||
*/
|
*/
|
||||||
public LightningStrikePoint(double latitude, double longitude)
|
public LightningStrikePoint(double latitude, double longitude)
|
||||||
{
|
{
|
||||||
super(latitude,longitude);
|
super(latitude, longitude, TimeUtil.newGmtCalendar());
|
||||||
setElevation(0);
|
setElevation(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the strike count.
|
* @param time
|
||||||
* @return The strike count.
|
* @param type
|
||||||
*/
|
*/
|
||||||
public int getStrikeCount()
|
public LightningStrikePoint(Calendar time, LtgMsgType type) {
|
||||||
{
|
super(time);
|
||||||
return strikeCount;
|
this.msgType = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the strike count.
|
* Get the pulse count.
|
||||||
* @return The strike count.
|
*
|
||||||
|
* @return The pulse count.
|
||||||
*/
|
*/
|
||||||
public void setStrikeCount(int strikeCount)
|
public int getPulseCount()
|
||||||
{
|
{
|
||||||
this.strikeCount = strikeCount;
|
return pulseCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the strike strength.
|
* Set the pulse count.
|
||||||
* @return The strike strength.
|
*
|
||||||
|
* @return The pulse count.
|
||||||
*/
|
*/
|
||||||
public double getStrikeStrength()
|
public void setPulseCount(int pulseCount)
|
||||||
{
|
{
|
||||||
return strikeStrength;
|
this.pulseCount = pulseCount;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the strike strength.
|
|
||||||
* @return The strike strength.
|
|
||||||
*/
|
|
||||||
public void setStrikeStrength(double strikeStrength)
|
|
||||||
{
|
|
||||||
this.strikeStrength = strikeStrength;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -189,13 +188,22 @@ public class LightningStrikePoint extends BasePoint
|
||||||
{
|
{
|
||||||
buffer = new StringBuilder();
|
buffer = new StringBuilder();
|
||||||
}
|
}
|
||||||
buffer.append(String.format("%4d%02d%02d",getYear(),getMonth(),getDay()));
|
Calendar obsTime = getTime();
|
||||||
buffer.append(String.format("%02d%02d%02d",getHour(),getMinute(),getSecond()));
|
int year = obsTime.get(Calendar.YEAR);
|
||||||
|
int month = obsTime.get(Calendar.MONTH) + 1;
|
||||||
|
int day = obsTime.get(Calendar.DAY_OF_MONTH);
|
||||||
|
int hour = obsTime.get(Calendar.HOUR);
|
||||||
|
int minute = obsTime.get(Calendar.MINUTE);
|
||||||
|
int second = obsTime.get(Calendar.SECOND);
|
||||||
|
int millis = obsTime.get(Calendar.MILLISECOND);
|
||||||
|
buffer.append(String.format("%4d%02d%02d", year, month, day));
|
||||||
|
buffer.append(String.format("%02d%02d%02d", hour, minute, second));
|
||||||
|
|
||||||
buffer.append(String.format(" %9.5f %10.5f ",getLatitude(), getLongitude() ));
|
buffer.append(String.format(" %9.5f %10.5f ",getLatitude(), getLongitude() ));
|
||||||
buffer.append(String.format("%2s %2s ",msgType.getType(),type.getType()));
|
buffer.append(String.format("%2s %2s ",msgType.getType(),type.getType()));
|
||||||
|
|
||||||
buffer.append(String.format("%4.0f %02d %02d", strikeStrength,(getMillis() / 100),strikeCount));
|
buffer.append(String.format("%4.0f %02d %02d", getStrikeStrength(),
|
||||||
|
(millis / 100), pulseCount));
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
@ -213,5 +221,20 @@ public class LightningStrikePoint extends BasePoint
|
||||||
{
|
{
|
||||||
return toString(null).toString();
|
return toString(null).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the pulses
|
||||||
|
*/
|
||||||
|
public List<LightningPulsePoint> getPulses() {
|
||||||
|
return pulses;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param pulses
|
||||||
|
* the pulses to set
|
||||||
|
*/
|
||||||
|
public void setPulses(List<LightningPulsePoint> pulses) {
|
||||||
|
this.pulses = pulses;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,32 +23,51 @@ package com.raytheon.uf.common.dataplugin.binlightning.impl;
|
||||||
* Enums for the lightning message type, Flash or RT Flash.
|
* Enums for the lightning message type, Flash or RT Flash.
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
*
|
*
|
||||||
* SOFTWARE HISTORY
|
* SOFTWARE HISTORY
|
||||||
*
|
*
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* 20070810 379 jkorman Initial Coding from prototype.
|
* 20070810 379 jkorman Initial Coding from prototype.
|
||||||
|
* Jun 3, 2014 3226 bclement added id, added TOTAL_LIGHTNING
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author jkorman
|
* @author jkorman
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
*/
|
*/
|
||||||
public enum LtgMsgType
|
public enum LtgMsgType
|
||||||
{
|
{
|
||||||
STRIKE_MSG_FL("FL"),
|
STRIKE_MSG_FL((byte) 0, "FL"), STRIKE_MSG_RT((byte) 1, "RT"), TOTAL_LIGHTNING(
|
||||||
STRIKE_MSG_RT("RT");
|
(byte) 2, "TL");
|
||||||
|
|
||||||
private final String strikeType;
|
private final String msgType;
|
||||||
|
|
||||||
|
private final byte id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct the type.
|
* Construct the type.
|
||||||
* @param type Lightning strike type.
|
*
|
||||||
|
* @param type
|
||||||
|
* Lightning message type.
|
||||||
*/
|
*/
|
||||||
private LtgMsgType(String type)
|
private LtgMsgType(byte id, String type)
|
||||||
{
|
{
|
||||||
strikeType = type;
|
this.msgType = type;
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param id
|
||||||
|
* @return null if no type found for id
|
||||||
|
*/
|
||||||
|
public static LtgMsgType getById(byte id) {
|
||||||
|
for (LtgMsgType type : LtgMsgType.values()) {
|
||||||
|
if (type.id == id) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -57,6 +76,13 @@ public enum LtgMsgType
|
||||||
*/
|
*/
|
||||||
public String getType()
|
public String getType()
|
||||||
{
|
{
|
||||||
return strikeType;
|
return msgType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return unique id for type
|
||||||
|
*/
|
||||||
|
public byte getId() {
|
||||||
|
return this.id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.common.dataplugin.binlightning.impl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stroke type enum for lightning pulses. Mainly categorizes between return and
|
||||||
|
* non-return strokes.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Jun 3, 2014 3226 bclement Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author bclement
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public enum LtgPulseType {
|
||||||
|
|
||||||
|
RETURN_STROKE((byte) 0), NON_RETURN_STROKE((byte) 1), KEEP_ALIVE((byte) 9);
|
||||||
|
|
||||||
|
private final byte id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param id
|
||||||
|
*/
|
||||||
|
private LtgPulseType(byte id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param id
|
||||||
|
* @return null if no type is found for id
|
||||||
|
*/
|
||||||
|
public static LtgPulseType getById(byte id) {
|
||||||
|
for (LtgPulseType type : LtgPulseType.values()) {
|
||||||
|
if (type.id == id) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return unique id for this type
|
||||||
|
*/
|
||||||
|
public byte getId() {
|
||||||
|
return this.id;
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,34 +23,52 @@ package com.raytheon.uf.common.dataplugin.binlightning.impl;
|
||||||
* Enums for the lightning strike type, cloud-to-cloud or cloud-to-ground.
|
* Enums for the lightning strike type, cloud-to-cloud or cloud-to-ground.
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
*
|
*
|
||||||
* SOFTWARE HISTORY
|
* SOFTWARE HISTORY
|
||||||
*
|
*
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* 20070810 379 jkorman Initial Coding from prototype.
|
* 20070810 379 jkorman Initial Coding from prototype.
|
||||||
* 20130425 DCS 112 Wufeng Zhou Added STRIKE_TF (for Total Flash) in definition for Total Flash
|
* 20130425 DCS 112 Wufeng Zhou Added STRIKE_TF (for Total Flash) in definition for Total Flash
|
||||||
|
* Jun 3, 2014 3226 bclement added id, changed to more descriptive names, added KEEP_ALIVE
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author jkorman
|
* @author jkorman
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
*/
|
*/
|
||||||
public enum LtgStrikeType
|
public enum LtgStrikeType
|
||||||
{
|
{
|
||||||
STRIKE_CC("CC"),
|
CLOUD_TO_CLOUD((byte)0, "CC"), CLOUD_TO_GROUND((byte)1, "CG"), TOTAL_FLASH((byte)2, "TF"), KEEP_ALIVE((byte)9,
|
||||||
STRIKE_CG("CG"),
|
"");
|
||||||
STRIKE_TF("TF");
|
|
||||||
|
|
||||||
private final String strikeType;
|
private final String strikeType;
|
||||||
|
|
||||||
|
private final byte id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct the type.
|
* Construct the type.
|
||||||
|
* @param id unique id for type
|
||||||
* @param type Lightning strike type.
|
* @param type Lightning strike type.
|
||||||
*/
|
*/
|
||||||
private LtgStrikeType(String type)
|
private LtgStrikeType(byte id, String type)
|
||||||
{
|
{
|
||||||
strikeType = type;
|
this.id = id;
|
||||||
|
this.strikeType = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param id
|
||||||
|
* unique id for type
|
||||||
|
* @return null if no type is found for id
|
||||||
|
*/
|
||||||
|
public static LtgStrikeType getById(byte id) {
|
||||||
|
for (LtgStrikeType type : LtgStrikeType.values()) {
|
||||||
|
if (type.id == id) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -61,4 +79,11 @@ public enum LtgStrikeType
|
||||||
{
|
{
|
||||||
return strikeType;
|
return strikeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return id
|
||||||
|
*/
|
||||||
|
public int getId() {
|
||||||
|
return this.id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,6 +76,8 @@ import com.vividsolutions.jts.io.WKTWriter;
|
||||||
* 12/20/2013 DR 16894 gzhang Fixed getZRvalue2() bias issue.
|
* 12/20/2013 DR 16894 gzhang Fixed getZRvalue2() bias issue.
|
||||||
* 05/12/2014 3133 njensen Extracted getLightningRecord
|
* 05/12/2014 3133 njensen Extracted getLightningRecord
|
||||||
* 05/13/2014 3133 njensen Moved convertStrankValue here from ScanConfig
|
* 05/13/2014 3133 njensen Moved convertStrankValue here from ScanConfig
|
||||||
|
* Jun 05, 2014 3226 bclement BinLightning refactor
|
||||||
|
* compare lightning strike type by id instead of ordinal
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author dhladky
|
* @author dhladky
|
||||||
|
@ -1292,7 +1294,7 @@ public class ScanUtils {
|
||||||
(double) rec.getLatitudes()[i],
|
(double) rec.getLatitudes()[i],
|
||||||
(double) rec.getLongitudes()[i],
|
(double) rec.getLongitudes()[i],
|
||||||
rec.getIntensities()[i], rec.getStrikeTypes()[i],
|
rec.getIntensities()[i], rec.getStrikeTypes()[i],
|
||||||
rec.getMsgTypes()[i], rec.getStrikeCounts()[i]);
|
rec.getMsgTypes()[i], rec.getPulseCounts()[i]);
|
||||||
|
|
||||||
strikeList.add(strike);
|
strikeList.add(strike);
|
||||||
}
|
}
|
||||||
|
@ -1311,7 +1313,7 @@ public class ScanUtils {
|
||||||
if (ls.getIntensity() > 0) {
|
if (ls.getIntensity() > 0) {
|
||||||
totalPosStrikes++;
|
totalPosStrikes++;
|
||||||
}
|
}
|
||||||
if (ls.getStrikeType() == LtgStrikeType.STRIKE_CG.ordinal()) {
|
if (ls.getStrikeType() == LtgStrikeType.CLOUD_TO_GROUND.getId()) {
|
||||||
totalCGStrikes++;
|
totalCGStrikes++;
|
||||||
}
|
}
|
||||||
totalStrikes++;
|
totalStrikes++;
|
||||||
|
|
|
@ -19,12 +19,14 @@
|
||||||
**/
|
**/
|
||||||
package com.raytheon.uf.edex.decodertools.core;
|
package com.raytheon.uf.edex.decodertools.core;
|
||||||
|
|
||||||
|
import com.vividsolutions.jts.geom.Coordinate;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BasePoint provides a simple 4D (latitude, longitude, elevation, and time)
|
* BasePoint provides a simple 3D (latitude, longitude, elevation) base class
|
||||||
* base class for observation data. Sub-classes of BasePoint are responsible for
|
* for observation data. Sub-classes of BasePoint are responsible for adding
|
||||||
* adding additional checking or using specific units as required. An example
|
* additional checking or using specific units as required. Most attributes of
|
||||||
* would be adding a accessors for a Calendar to expose the date information.
|
* this class do not have units.
|
||||||
* Most attributes of this class do not have units.
|
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
*
|
*
|
||||||
|
@ -35,11 +37,14 @@ package com.raytheon.uf.edex.decodertools.core;
|
||||||
* 27 July 2007 411 jkorman Initial Development
|
* 27 July 2007 411 jkorman Initial Development
|
||||||
* 20070911 379 jkorman Added comments.
|
* 20070911 379 jkorman Added comments.
|
||||||
* 20070912 379 jkorman Code review cleanup.
|
* 20070912 379 jkorman Code review cleanup.
|
||||||
|
* Jun 05, 2014 3226 bclement deprecated class, removed time
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
* @deprecated use {@link Coordinate} instead
|
||||||
* @author jkorman
|
* @author jkorman
|
||||||
* @version 1
|
* @version 1
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public class BasePoint {
|
public class BasePoint {
|
||||||
private double latitude;
|
private double latitude;
|
||||||
|
|
||||||
|
@ -47,20 +52,6 @@ public class BasePoint {
|
||||||
|
|
||||||
private double elevation;
|
private double elevation;
|
||||||
|
|
||||||
private int year;
|
|
||||||
|
|
||||||
private int month;
|
|
||||||
|
|
||||||
private int day;
|
|
||||||
|
|
||||||
private int hour;
|
|
||||||
|
|
||||||
private int minute;
|
|
||||||
|
|
||||||
private int second;
|
|
||||||
|
|
||||||
private int millis;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an empty basepoint instance.
|
* Create an empty basepoint instance.
|
||||||
*/
|
*/
|
||||||
|
@ -74,16 +65,9 @@ public class BasePoint {
|
||||||
* A basepoint to copy.
|
* A basepoint to copy.
|
||||||
*/
|
*/
|
||||||
public BasePoint(BasePoint point) {
|
public BasePoint(BasePoint point) {
|
||||||
latitude = point.latitude;
|
this.latitude = point.latitude;
|
||||||
longitude = point.longitude;
|
this.longitude = point.longitude;
|
||||||
elevation = point.elevation;
|
this.elevation = point.elevation;
|
||||||
year = point.year;
|
|
||||||
month = point.month;
|
|
||||||
day = point.day;
|
|
||||||
hour = point.hour;
|
|
||||||
minute = point.minute;
|
|
||||||
second = point.second;
|
|
||||||
millis = point.millis;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -154,136 +138,4 @@ public class BasePoint {
|
||||||
this.elevation = elevation;
|
this.elevation = elevation;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the year part of the date.
|
|
||||||
*
|
|
||||||
* @return The year.
|
|
||||||
*/
|
|
||||||
public int getYear() {
|
|
||||||
return year;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the year part of the date.
|
|
||||||
*
|
|
||||||
* @param year
|
|
||||||
* Year.
|
|
||||||
*/
|
|
||||||
public void setYear(int year) {
|
|
||||||
this.year = year;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the month part of the date.
|
|
||||||
*
|
|
||||||
* @return The month of the year.
|
|
||||||
*/
|
|
||||||
public int getMonth() {
|
|
||||||
return month;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the day of the month part of the date.
|
|
||||||
*
|
|
||||||
* @param day
|
|
||||||
* Day of month [1..12].
|
|
||||||
*/
|
|
||||||
public void setMonth(int month) {
|
|
||||||
this.month = month;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the day part of the month.
|
|
||||||
*
|
|
||||||
* @return The day of the month.
|
|
||||||
*/
|
|
||||||
public int getDay() {
|
|
||||||
return day;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the day of the month part of the date.
|
|
||||||
*
|
|
||||||
* @param day
|
|
||||||
* Day of month [1..12].
|
|
||||||
*/
|
|
||||||
public void setDay(int day) {
|
|
||||||
this.day = day;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the hours part of the day.
|
|
||||||
*
|
|
||||||
* @return The hours part of the day.
|
|
||||||
*/
|
|
||||||
public int getHour() {
|
|
||||||
return hour;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the hour part of the time.
|
|
||||||
*
|
|
||||||
* @param hour
|
|
||||||
* Hour of the day [0..23].
|
|
||||||
*/
|
|
||||||
public void setHour(int hour) {
|
|
||||||
this.hour = hour;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the minutes part of the hour.
|
|
||||||
*
|
|
||||||
* @return The minutes part of the hour.
|
|
||||||
*/
|
|
||||||
public int getMinute() {
|
|
||||||
return minute;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the minute of the hour.
|
|
||||||
*
|
|
||||||
* @param minute
|
|
||||||
* The minute of the hour [0..59]
|
|
||||||
*/
|
|
||||||
public void setMinute(int minute) {
|
|
||||||
this.minute = minute;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the seconds part of the minute.
|
|
||||||
*
|
|
||||||
* @return The seconds part of the minute.
|
|
||||||
*/
|
|
||||||
public int getSecond() {
|
|
||||||
return second;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the second of the minute.
|
|
||||||
*
|
|
||||||
* @param second
|
|
||||||
* The second of the minute [0..59]
|
|
||||||
*/
|
|
||||||
public void setSecond(int second) {
|
|
||||||
this.second = second;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the milliseconds part of the time.
|
|
||||||
*
|
|
||||||
* @return The milliseconds part of the time.
|
|
||||||
*/
|
|
||||||
public int getMillis() {
|
|
||||||
return millis;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the milliseconds part of the time.
|
|
||||||
*
|
|
||||||
* @param millis
|
|
||||||
* Milliseconds [0..999].
|
|
||||||
*/
|
|
||||||
public void setMillis(int millis) {
|
|
||||||
this.millis = millis;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,7 @@ import com.vividsolutions.jts.geom.Coordinate;
|
||||||
* Jan 10, 2013 1448 bgonzale Added app context check in runOnSchedule().
|
* Jan 10, 2013 1448 bgonzale Added app context check in runOnSchedule().
|
||||||
* Jan 18, 2013 1469 bkowal Removed the hdf5 data directory.
|
* Jan 18, 2013 1469 bkowal Removed the hdf5 data directory.
|
||||||
* Mar 28, 2014 2952 mpduff Changed to use UFStatus for logging.
|
* Mar 28, 2014 2952 mpduff Changed to use UFStatus for logging.
|
||||||
|
* Jun 05, 2014 3226 bclement BinLightning refactor
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -138,7 +139,7 @@ public class MpeLightningSrv {
|
||||||
float[] latitudes = ltngRec.getLatitudes();
|
float[] latitudes = ltngRec.getLatitudes();
|
||||||
float[] longitudes = ltngRec.getLongitudes();
|
float[] longitudes = ltngRec.getLongitudes();
|
||||||
long[] obstimes = ltngRec.getObsTimes();
|
long[] obstimes = ltngRec.getObsTimes();
|
||||||
byte[] strikes = ltngRec.getStrikeCounts();
|
byte[] strikes = ltngRec.getPulseCounts();
|
||||||
|
|
||||||
// convert latitude and longitude to grid coordinate
|
// convert latitude and longitude to grid coordinate
|
||||||
HRAP hrap = HRAP.getInstance();
|
HRAP hrap = HRAP.getInstance();
|
||||||
|
|
|
@ -58,6 +58,7 @@ import com.vividsolutions.jts.geom.GeometryFactory;
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* 05/07/2009 2037 dhladky Initial Creation.
|
* 05/07/2009 2037 dhladky Initial Creation.
|
||||||
* Apr 30, 2014 2060 njensen Updates for removal of grid dataURI column
|
* Apr 30, 2014 2060 njensen Updates for removal of grid dataURI column
|
||||||
|
* Jun 05, 2014 3226 bclement compare lightning strike type by id instead of ordinal
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -292,7 +293,7 @@ public abstract class ScanProduct implements Serializable {
|
||||||
rec.getIntensities()[i],
|
rec.getIntensities()[i],
|
||||||
rec.getStrikeTypes()[i],
|
rec.getStrikeTypes()[i],
|
||||||
rec.getMsgTypes()[i],
|
rec.getMsgTypes()[i],
|
||||||
rec.getStrikeCounts()[i]);
|
rec.getPulseCounts()[i]);
|
||||||
|
|
||||||
strikeList.add(strike);
|
strikeList.add(strike);
|
||||||
}
|
}
|
||||||
|
@ -310,8 +311,8 @@ public abstract class ScanProduct implements Serializable {
|
||||||
if (ls.getIntensity() > 0) {
|
if (ls.getIntensity() > 0) {
|
||||||
totalPosStrikes++;
|
totalPosStrikes++;
|
||||||
}
|
}
|
||||||
if (ls.getStrikeType() == LtgStrikeType.STRIKE_CG
|
if (ls.getStrikeType() == LtgStrikeType.CLOUD_TO_GROUND
|
||||||
.ordinal()) {
|
.getId()) {
|
||||||
totalCGStrikes++;
|
totalCGStrikes++;
|
||||||
}
|
}
|
||||||
totalStrikes++;
|
totalStrikes++;
|
||||||
|
|
|
@ -3,8 +3,8 @@ package gov.noaa.nws.ncep.viz.rsc.lightning.rsc;
|
||||||
import gov.noaa.nws.ncep.viz.common.ui.NmapCommon;
|
import gov.noaa.nws.ncep.viz.common.ui.NmapCommon;
|
||||||
import gov.noaa.nws.ncep.viz.resources.AbstractNatlCntrsResource;
|
import gov.noaa.nws.ncep.viz.resources.AbstractNatlCntrsResource;
|
||||||
import gov.noaa.nws.ncep.viz.resources.INatlCntrsResource;
|
import gov.noaa.nws.ncep.viz.resources.INatlCntrsResource;
|
||||||
import gov.noaa.nws.ncep.viz.resources.colorBar.ColorBarResourceData;
|
|
||||||
import gov.noaa.nws.ncep.viz.resources.colorBar.ColorBarResource;
|
import gov.noaa.nws.ncep.viz.resources.colorBar.ColorBarResource;
|
||||||
|
import gov.noaa.nws.ncep.viz.resources.colorBar.ColorBarResourceData;
|
||||||
import gov.noaa.nws.ncep.viz.ui.display.ColorBar;
|
import gov.noaa.nws.ncep.viz.ui.display.ColorBar;
|
||||||
import gov.noaa.nws.ncep.viz.ui.display.NCMapDescriptor;
|
import gov.noaa.nws.ncep.viz.ui.display.NCMapDescriptor;
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ import java.util.List;
|
||||||
import com.raytheon.uf.common.dataplugin.HDF5Util;
|
import com.raytheon.uf.common.dataplugin.HDF5Util;
|
||||||
import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
||||||
import com.raytheon.uf.common.dataplugin.binlightning.BinLightningRecord;
|
import com.raytheon.uf.common.dataplugin.binlightning.BinLightningRecord;
|
||||||
|
import com.raytheon.uf.common.dataplugin.binlightning.LightningConstants;
|
||||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
||||||
import com.raytheon.uf.common.datastorage.DataStoreFactory;
|
import com.raytheon.uf.common.datastorage.DataStoreFactory;
|
||||||
import com.raytheon.uf.common.datastorage.IDataStore;
|
import com.raytheon.uf.common.datastorage.IDataStore;
|
||||||
|
@ -42,15 +43,14 @@ import com.raytheon.uf.viz.core.drawables.IWireframeShape;
|
||||||
import com.raytheon.uf.viz.core.drawables.PaintProperties;
|
import com.raytheon.uf.viz.core.drawables.PaintProperties;
|
||||||
import com.raytheon.uf.viz.core.drawables.ResourcePair;
|
import com.raytheon.uf.viz.core.drawables.ResourcePair;
|
||||||
import com.raytheon.uf.viz.core.exception.VizException;
|
import com.raytheon.uf.viz.core.exception.VizException;
|
||||||
import com.raytheon.uf.viz.core.map.MapDescriptor;
|
|
||||||
import com.raytheon.uf.viz.core.rsc.LoadProperties;
|
import com.raytheon.uf.viz.core.rsc.LoadProperties;
|
||||||
import com.raytheon.uf.viz.core.rsc.ResourceProperties;
|
import com.raytheon.uf.viz.core.rsc.ResourceProperties;
|
||||||
import com.raytheon.uf.viz.core.rsc.ResourceType;
|
import com.raytheon.uf.viz.core.rsc.ResourceType;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LigntningResource - Display Lightning data.
|
* LigntningResource - Display Lightning data. *
|
||||||
* *
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* SOFTWARE HISTORY
|
* SOFTWARE HISTORY
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
|
@ -65,10 +65,11 @@ import com.raytheon.uf.viz.core.rsc.ResourceType;
|
||||||
* 05/23/12 785 Q. Zhou Added getName for legend.
|
* 05/23/12 785 Q. Zhou Added getName for legend.
|
||||||
* 12/19/2012 #960 Greg Hull override propertiesChanged() to update colorBar.
|
* 12/19/2012 #960 Greg Hull override propertiesChanged() to update colorBar.
|
||||||
* 05/07/2013 #993 Greg Hull change key for strikeMap from URI to the HDF5 group
|
* 05/07/2013 #993 Greg Hull change key for strikeMap from URI to the HDF5 group
|
||||||
*
|
* Jun 05, 2014 3226 bclement reference datarecords by LightningConstants
|
||||||
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author ghull
|
* @author ghull
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
*/
|
*/
|
||||||
public class LightningResource extends AbstractNatlCntrsResource<LightningResourceData, NCMapDescriptor>
|
public class LightningResource extends AbstractNatlCntrsResource<LightningResourceData, NCMapDescriptor>
|
||||||
|
@ -366,20 +367,17 @@ public class LightningResource extends AbstractNatlCntrsResource<LightningResour
|
||||||
|
|
||||||
for( int s=0 ; s<hdf5Rec.getSizes()[0] ; s++ ) {
|
for( int s=0 ; s<hdf5Rec.getSizes()[0] ; s++ ) {
|
||||||
LtngStrikeDataObj strikeInfo = strikeList.get(s);
|
LtngStrikeDataObj strikeInfo = strikeList.get(s);
|
||||||
if( hdf5Rec.getName().equals("intensity") ) {
|
String name = hdf5Rec.getName();
|
||||||
|
if (name.equals(LightningConstants.INTENSITY_DATASET)) {
|
||||||
strikeInfo.intensity = ((IntegerDataRecord) hdf5Rec).getIntData()[s];
|
strikeInfo.intensity = ((IntegerDataRecord) hdf5Rec).getIntData()[s];
|
||||||
} else if( hdf5Rec.getName().equals("latitude") ) {
|
} else if (name.equals(LightningConstants.LAT_DATASET)) {
|
||||||
strikeInfo.lat = ((FloatDataRecord) hdf5Rec).getFloatData()[s];
|
strikeInfo.lat = ((FloatDataRecord) hdf5Rec).getFloatData()[s];
|
||||||
} else if( hdf5Rec.getName().equals("longitude") ) {
|
} else if (name.equals(LightningConstants.LON_DATASET)) {
|
||||||
strikeInfo.lon = ((FloatDataRecord) hdf5Rec).getFloatData()[s];
|
strikeInfo.lon = ((FloatDataRecord) hdf5Rec).getFloatData()[s];
|
||||||
} else if( hdf5Rec.getName().equals("obsTime") ) {
|
} else if (name.equals(LightningConstants.TIME_DATASET)) {
|
||||||
strikeInfo.strikeTime = ((LongDataRecord) hdf5Rec).getLongData()[s];
|
strikeInfo.strikeTime = ((LongDataRecord) hdf5Rec).getLongData()[s];
|
||||||
// if( strikeInfo.obsTime > latestStrike ) {
|
} else if (name
|
||||||
// latestStrike = strikeInfo.obsTime;
|
.equals(LightningConstants.MSG_TYPE_DATASET)) {
|
||||||
// }
|
|
||||||
// } else if( hdf5Rec.getName().equals("strikeCount") ) {
|
|
||||||
// strikeInfo.lon = ((FloatDataRecord) hdf5Rec).getFloatData()[s];
|
|
||||||
} else if( hdf5Rec.getName().equals("msgType") ) {
|
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ import com.raytheon.uf.common.dataplugin.binlightning.impl.LtgMsgType;
|
||||||
import com.raytheon.uf.common.dataplugin.binlightning.impl.LtgStrikeType;
|
import com.raytheon.uf.common.dataplugin.binlightning.impl.LtgStrikeType;
|
||||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||||
import com.raytheon.uf.common.status.UFStatus;
|
import com.raytheon.uf.common.status.UFStatus;
|
||||||
import com.raytheon.uf.edex.decodertools.core.BasePoint;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BinLigntningDecoderUtil
|
* BinLigntningDecoderUtil
|
||||||
|
@ -38,6 +37,7 @@ import com.raytheon.uf.edex.decodertools.core.BasePoint;
|
||||||
* moved from com.raytheon.edex.plugin.binlightning to gov.noaa.nws.ost.edex.plugin.binlightning
|
* moved from com.raytheon.edex.plugin.binlightning to gov.noaa.nws.ost.edex.plugin.binlightning
|
||||||
* moved decodeBinLightningData() and decodeBitShiftedBinLightningData()
|
* moved decodeBinLightningData() and decodeBitShiftedBinLightningData()
|
||||||
* to BinLightningDecoder to solve circular dependency
|
* to BinLightningDecoder to solve circular dependency
|
||||||
|
* Jun 05, 2014 3226 bclement LightningStrikePoint refactor
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author Wufeng Zhou
|
* @author Wufeng Zhou
|
||||||
|
@ -132,20 +132,16 @@ public class BinLightningDecoderUtil {
|
||||||
// int reserved = buffer.getShort() & 0xffff;
|
// int reserved = buffer.getShort() & 0xffff;
|
||||||
|
|
||||||
// Create the strike record from the report info and base time information.
|
// Create the strike record from the report info and base time information.
|
||||||
BasePoint base = new BasePoint(lat, lon);
|
|
||||||
Calendar cal = Calendar.getInstance();
|
Calendar cal = Calendar.getInstance();
|
||||||
cal.setTimeInMillis(epochTime);
|
cal.setTimeInMillis(epochTime);
|
||||||
base.setYear(cal.get(Calendar.YEAR));
|
|
||||||
base.setMonth(cal.get(Calendar.MONTH) + 1);
|
|
||||||
base.setDay(cal.get(Calendar.DAY_OF_MONTH));
|
|
||||||
base.setHour(cal.get(Calendar.HOUR_OF_DAY));
|
|
||||||
base.setMinute(cal.get(Calendar.MINUTE));
|
|
||||||
base.setSecond(cal.get(Calendar.SECOND));
|
|
||||||
base.setMillis(cal.get(Calendar.MILLISECOND));
|
|
||||||
|
|
||||||
// new spec does not seem to have lightning message type indicator such as FL (Flash Lightning) or RT (Real Time flash lightning)
|
/*
|
||||||
// The source of lightning data in the vendor specific data bytes (byte 16-17) may related to this (???),
|
* new spec does not seem to have lightning message type indicator
|
||||||
// and it is used here for now. 04/182/013 Wufeng Zhou
|
* such as FL (Flash Lightning) or RT (Real Time flash lightning)
|
||||||
|
* The source of lightning data in the vendor specific data bytes
|
||||||
|
* (byte 16-17) may related to this (???),
|
||||||
|
* and it is used here for now. 04/182/013 Wufeng Zhou
|
||||||
|
*/
|
||||||
/** 05/02/2013, found DSI-9603 Spec (http://www1.ncdc.noaa.gov/pub/data/documentlibrary/tddoc/td9603.pdf) on NLDN lightning data format,
|
/** 05/02/2013, found DSI-9603 Spec (http://www1.ncdc.noaa.gov/pub/data/documentlibrary/tddoc/td9603.pdf) on NLDN lightning data format,
|
||||||
* on Message Type and Stroke Type:
|
* on Message Type and Stroke Type:
|
||||||
* POS: 37-38 Message Type
|
* POS: 37-38 Message Type
|
||||||
|
@ -165,19 +161,24 @@ public class BinLightningDecoderUtil {
|
||||||
msgType = LtgMsgType.STRIKE_MSG_RT;
|
msgType = LtgMsgType.STRIKE_MSG_RT;
|
||||||
}
|
}
|
||||||
|
|
||||||
LightningStrikePoint lsp = new LightningStrikePoint(base, lat, lon, msgType);
|
LightningStrikePoint lsp = new LightningStrikePoint(lat, lon, cal,
|
||||||
LtgStrikeType ltgStrikeType = LtgStrikeType.STRIKE_CG; // default ??
|
msgType);
|
||||||
|
LtgStrikeType ltgStrikeType = LtgStrikeType.CLOUD_TO_GROUND; // default ??
|
||||||
if (strokeType == 0x0000) {
|
if (strokeType == 0x0000) {
|
||||||
ltgStrikeType = LtgStrikeType.STRIKE_CG;
|
ltgStrikeType = LtgStrikeType.CLOUD_TO_GROUND;
|
||||||
} else if (strokeType == 0x00ff) {
|
} else if (strokeType == 0x00ff) {
|
||||||
ltgStrikeType = LtgStrikeType.STRIKE_CC;
|
ltgStrikeType = LtgStrikeType.CLOUD_TO_CLOUD;
|
||||||
} else if (strokeType == 0xffff) {
|
} else if (strokeType == 0xffff) {
|
||||||
ltgStrikeType = LtgStrikeType.STRIKE_TF;
|
ltgStrikeType = LtgStrikeType.TOTAL_FLASH;
|
||||||
}
|
}
|
||||||
lsp.setType(ltgStrikeType);
|
lsp.setType(ltgStrikeType);
|
||||||
|
|
||||||
// as of OB13.3 for World Wide Lightning Location Network (WWLLN) data (decoded by textlightning though, not this bin lightning decoder),
|
/*
|
||||||
// added lightning source field in LightningStrikePoint, as well as column in binlightning database table defaults to NLDN
|
* as of OB13.3 for World Wide Lightning Location Network (WWLLN)
|
||||||
|
* data (decoded by textlightning though, not this bin lightning
|
||||||
|
* decoder), added lightning source field in LightningStrikePoint,
|
||||||
|
* as well as column in binlightning database table defaults to NLDN
|
||||||
|
*/
|
||||||
if (vendor == ((short)0x0001)) { // CONUS source
|
if (vendor == ((short)0x0001)) { // CONUS source
|
||||||
lsp.setLightSource("NLDN");
|
lsp.setLightSource("NLDN");
|
||||||
} else if (vendor == ((short)0x0002)) { // long range source, i.e., GLD360.
|
} else if (vendor == ((short)0x0002)) { // long range source, i.e., GLD360.
|
||||||
|
@ -185,7 +186,7 @@ public class BinLightningDecoderUtil {
|
||||||
lsp.setLightSource("GLD");
|
lsp.setLightSource("GLD");
|
||||||
}
|
}
|
||||||
|
|
||||||
lsp.setStrikeCount(strokeMultiplicity);
|
lsp.setPulseCount(strokeMultiplicity);
|
||||||
lsp.setStrikeStrength(strokeKiloAmps);
|
lsp.setStrikeStrength(strokeKiloAmps);
|
||||||
// stroke duration does not seem to be used
|
// stroke duration does not seem to be used
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue