VLab Issue #4152 - Enhancements to Magnetometer K calculation

Change-Id: I266486d48a312ec2ec16e35a4a739a6bf33c3eb4

Former-commit-id: 987cfaf3ed [formerly 4c89c2e687ad9ec529883029ab8a5d25073a1725]
Former-commit-id: 84bcdcacf6
This commit is contained in:
Stephen Gilbert 2014-07-22 16:52:16 -04:00
parent 805c363590
commit bd8a4cddb2
9 changed files with 225 additions and 45 deletions

View file

@ -10,11 +10,12 @@ import java.util.List;
* <pre>
* SOFTWARE HISTORY
*
* ate Ticket# Engineer Description
* Date Ticket# Engineer Description
* ----------- ---------- ---------- --------------------------
* 05/14/2013 #989 qzhou Initial Creation
* 03/18/2014 #1123 qzhou Add getHdevOrDDev
* 04/09/2014 #1123 qzhou Modified getKIndex for gamma value
* 06/23/2014 R4152 qzhou Fixed on getQHAQDC formula
* </pre>
*
* @author qzhou
@ -25,7 +26,7 @@ public class CalcEach1min {
private static final int MAX_GAP_LENGTH = 15;
private static final int SMOOTH_WINDOW = 60;//
private static final int SMOOTH_WINDOW = 60;
private static final int TRANSITION_TIME = 60;
@ -103,14 +104,14 @@ public class CalcEach1min {
for (int i = 0; i < HOURS; i++) {
fitLength[i] = 30.0f + defLength[i];
ind[i] = (int) Math.floor(i / 3);
ind[i] = (int) Math.floor(i / 3.0f);
curK[i] = kIndex[ind[i]];
if (curK[i] != MISSING_VAL)
fitLength[i] += kLength[(int) curK[i]];
if (fitLength[i] > 1440)
fitLength[i] = 1440;
if (fitLength[i] > 1440.0f)
fitLength[i] = 1440.0f;
}
return fitLength;
@ -365,9 +366,11 @@ public class CalcEach1min {
float jump = qdc[0] - qdc[1439];
for (int i = 0; i < SMOOTH_WINDOW; i++) {
data[1440 - SMOOTH_WINDOW - i] += i / (SMOOTH_WINDOW - 1) * 0.5
* jump;
data[i] -= (1 - i / (SMOOTH_WINDOW - 1)) * 0.5 * jump;
data[1440 - SMOOTH_WINDOW + i] += ((float) i / (SMOOTH_WINDOW - 1))
* 0.5f * jump;
data[i] -= (1.0f - (float) i / (SMOOTH_WINDOW - 1)) * 0.5f * jump;
}
return data;

View file

@ -12,10 +12,11 @@ import java.util.Map;
* <pre>
* SOFTWARE HISTORY
*
* ate Ticket# Engineer Description
* Date Ticket# Engineer Description
* ----------- ---------- ---------- --------------------------
* 05/14/2013 #989 qzhou Initial Creation
* 03/18/2014 #1123 qzhou Add getHQdcOrDQdc
* 06/23/2014 R4152 qzhou Touched up functions that do not affect the results
* </pre>
*
* @author qzhou
@ -162,27 +163,27 @@ public class CalcEach3hr {
for (int j = 0; j < DAYS; j++) {
double sum = 0;
int missing = 0;
int count = 0;
int endOfArray = simpHrAvgH.length;
int endTime = (endOfArray > j * HOURS + HOURS) ? j * HOURS + HOURS
: endOfArray;
for (int i = 0; i < 23; i++) {
int ii = j * HOURS + i;
for (int i = j * HOURS; i < endTime - 1; i++) {
if (simpHrAvgH[i] != MISSING_VAL
&& simpHrAvgD[i] != MISSING_VAL
&& simpHrAvgH[i + 1] != MISSING_VAL
&& simpHrAvgD[i + 1] != MISSING_VAL) {
sum += Math.sqrt(Math.pow(
(simpHrAvgH[i + 1] - simpHrAvgH[i]), 2)
+ Math.pow((simpHrAvgD[i + 1] - simpHrAvgD[i]), 2));
} else
missing++;
if (simpHrAvgH[ii] != MISSING_VAL
&& simpHrAvgD[ii] != MISSING_VAL
&& simpHrAvgH[ii + 1] != MISSING_VAL
&& simpHrAvgD[ii + 1] != MISSING_VAL) {
sum += Math
.sqrt(Math.pow(
(simpHrAvgH[ii + 1] - simpHrAvgH[ii]), 2)
+ Math.pow(
(simpHrAvgD[ii + 1] - simpHrAvgD[ii]),
2));
count++;
}
}
if (missing <= 12) // not 12 or more missing
dB[j] = (float) sum / (HOURS - 1 - missing);
if (count >= 12) // not 12 or more missing
dB[j] = (float) sum / count;
else
dB[j] = MISSING_VAL;
@ -281,7 +282,7 @@ public class CalcEach3hr {
if (dB[jk] < 1)
wk = 1;
else
wk = 1 / (dB[jk] * dB[jk]);
wk = 1.0f / (dB[jk] * dB[jk]);
if (smallHrAvg[ind] != MISSING_VAL) {
sumAvg += wk * smallHrAvg[ind];

View file

@ -17,7 +17,7 @@ import java.util.Map;
* <pre>
* SOFTWARE HISTORY
*
* ate Ticket# Engineer Description
* Date Ticket# Engineer Description
* ----------- ---------- ---------- --------------------------
* 05/14/2013 #989 qzhou Initial Creation
* 03/18/2014 #1123 qzhou default k to 99999

View file

@ -19,9 +19,10 @@ import java.util.Map;
* <pre>
* SOFTWARE HISTORY
*
* ate Ticket# Engineer Description
* Date Ticket# Engineer Description
* ----------- ---------- ---------- --------------------------
* 05/14/2013 #989 qzhou Initial Creation
* 06/23/2014 R4152 qzhou Touched up 3 functions
* </pre>
*
* @author qzhou
@ -181,7 +182,7 @@ public class CalcUtil {
int[] kLimit = new int[10];
int k9Limit = getK9Limit(station);
for (int i = 0; i < kLimit.length; i++) {
kLimit[i] = Math.round(k9Limit * getKConst(i) / 500);
kLimit[i] = Math.round(k9Limit * getKConst(i) / 500.0f);
}
return kLimit;
}
@ -219,11 +220,11 @@ public class CalcUtil {
return kIndex;
}
public static int getGammaFromK(String station, int kIndex) {
int gamma = getK9Limit(station) * getKConst(kIndex) / 500;
return gamma;
}
// public static int getGammaFromK(String station, int kIndex) {
// int gamma = getK9Limit(station) * getKConst(kIndex) / 500;
//
// return gamma;
// }
// assume db time format yyyy-mm-dd hh:mm:ss
public static Date getSPTime(Date currTime) {
@ -414,11 +415,11 @@ public class CalcUtil {
public static boolean isLeapYear(int year) {
boolean isLeap;
if (year / 400 == 0)
if (year % 400 == 0)
isLeap = true;
else if (year / 100 == 0)
else if (year % 100 == 0)
isLeap = false;
else if (year / 4 == 0)
else if (year % 4 == 0)
isLeap = true;
else
isLeap = false;
@ -540,11 +541,12 @@ public class CalcUtil {
break; // to sorted arraySort
int size = newArray.size();
if (size / 2 == 0)
if (size % 2 == 0)
median = (newArray.get(size / 2) + newArray.get(size / 2 - 1)) / 2;
else
median = newArray.get((size - 1) / 2);
return median;
}
}

View file

@ -32,6 +32,7 @@ import com.raytheon.uf.edex.database.query.DatabaseQuery;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 2014/02/12 #1123 qzhou Moved from edex to here
* 2014/06/27 #1136 qzhou Change hour avg to 0-current time
*
* </pre>
*
@ -63,10 +64,11 @@ public class DatabaseUtil {
QueryParam.QueryOperand.LESSTHANEQUALS);
Calendar cal = Calendar.getInstance();
cal.setTime(time);
cal.add(Calendar.HOUR_OF_DAY, -1);
cal.set(Calendar.MINUTE, 0);
// cal.add(Calendar.HOUR_OF_DAY, -1);
query.addQueryParam("dataTime.refTime", cal.getTime(),
QueryParam.QueryOperand.GREATERTHAN);
QueryParam.QueryOperand.GREATERTHANEQUALS);
query.addQueryParam("stationCode", station);
List<?> resultsList = null;

View file

@ -0,0 +1,59 @@
package gov.noaa.nws.ncep.common.dataplugin.geomag.request;
import java.util.Date;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
import com.raytheon.uf.common.serialization.comm.IServerRequest;
/**
*
* Request for a GeoMagk1min for the given dataURI
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 2014/07/01 #1136 qzhou Init
*
* </pre>
*
* @author qzhou
* @version 1.0
*/
@DynamicSerialize
public class RetrieveSingleK1minRequest implements IServerRequest {
@DynamicSerializeElement
private String stationCode;
@DynamicSerializeElement
private Date refTime;
public RetrieveSingleK1minRequest() {
}
public RetrieveSingleK1minRequest(String stationCode, Date refTime) {
super();
this.stationCode = stationCode;
this.refTime = refTime;
}
public String getStationCode() {
return stationCode;
}
public void setStationCode(String stationCode) {
this.stationCode = stationCode;
}
public Date getRefTime() {
return refTime;
}
public void setRefTime(Date refTime) {
this.refTime = refTime;
}
}

View file

@ -54,4 +54,11 @@
<constructor-arg ref="RetrieveK1minHandler" />
</bean>
<bean id="RetrieveSingleK1minHandler"
class="gov.noaa.nws.ncep.edex.plugin.geomag.handler.RetrieveSingleK1minRequestHandler" />
<bean factory-bean="handlerRegistry" factory-method="register">
<constructor-arg
value="gov.noaa.nws.ncep.common.dataplugin.geomag.request.RetrieveSingleK1minRequest" />
<constructor-arg ref="RetrieveSingleK1minHandler" />
</bean>
</beans>

View file

@ -33,8 +33,6 @@ import com.raytheon.uf.common.datastorage.StorageException;
import com.raytheon.uf.common.datastorage.records.IDataRecord;
import com.raytheon.uf.edex.database.plugin.PluginFactory;
//import gov.noaa.nws.ncep.edex.plugin.geomag.request.DatabaseUtil;
/**
* This java class calculates magnetometer k index and related values.
*
@ -45,6 +43,7 @@ import com.raytheon.uf.edex.database.plugin.PluginFactory;
* ----------- ---------- ----------- --------------------------
* 06/07/2013 #989 qzhou Initial Creation, event driven
* 03/18/2014 #1123 qzhou Move some functions to common. Modified FillAvgTimeGap in the moved functions
* 06/26/2014 #1136 qzhou Calculate hourly average when min>=55 instead of min=59
* </pre>
*
* @author qzhou
@ -372,7 +371,14 @@ public class TrigKCalculation {
int min = time.getMinutes();
List<?> dataList = null;
if (min == 59)
// Ideally we want to calculate hourly average for each min=59
// ingest. But MEA and OTT stations only have 23:56 available.
// Calculate hourly average when min>=30 will not miss any
// average data. That might make the performance low.
// Currently we calculate hourly average when min>=55. (i.e.
// write to db 5 times each hour)
if (min >= 55)
dataList = DatabaseUtil.retrieveUriForAvg(dao, dataURI,
time);
else
@ -451,6 +457,20 @@ public class TrigKCalculation {
if (dataList.size() <= HOURS)
continue;
// test code:
// String teststr = "";
// try {
// Date d = CalcUtil.getTimeFromUri(dataURI);
// int day = d.getDate();
// int h = d.getHours();
// int m = d.getMinutes();
// if (h == 10 && m == 41) { // && day == 14
// System.out.println("**dataURI " + dataURI);
// teststr = dataURI;
// }
// } catch (ParseException e1) {
// }
if (dataList != null && dataList.size() >= 5) {
List<Date> dateListFinal = new ArrayList<Date>();
List<Float> hHrAvgListFinal = new ArrayList<Float>();
@ -485,13 +505,41 @@ public class TrigKCalculation {
float[] qha = CalcEach3hr.getQHA(quietHHrAvg);
float[] qda = CalcEach3hr.getQHA(quietDHrAvg);
// test qha
// if (!teststr.equals("")) {
// System.out.println("**qha length " + teststr);
// for (int i = 0; i < qha.length; i++)
// System.out.print((float) qha[i] + " ");
// System.out.println("\n**qda length " + qda.length);
// for (int i = 0; i < qda.length; i++)
// System.out.print((float) qda[i] + " ");
//
// }
float[] hQdc = CalcEach1min.getHarmonicFit(qha);// [1440]
float[] dQdc = CalcEach1min.getHarmonicFit(qda);
// if (!teststr.equals("")) {
// System.out.println("\n**hQdc length " + teststr);
// for (int i = 0; i < hQdc.length; i++)
// System.out.print((float) hQdc[i] + " ");
// System.out.println("\n**dQdc length " + dQdc.length);
// for (int i = 0; i < dQdc.length; i++)
// System.out.print((float) dQdc[i] + " ");
// }
float[] qhaQdc = CalcEach1min.getQHAQDC(hQdc);// [1440]
float[] qdaQdc = CalcEach1min.getQHAQDC(dQdc);
// test hQdc
// if (!teststr.equals("")) {
// System.out.println("\n**qhaQdc length " + teststr);
// for (int i = 0; i < qhaQdc.length; i++)
// System.out.print((float) qhaQdc[i] + " ");
// System.out
// .println("\n**qdaQdc length " + qdaQdc.length);
// for (int i = 0; i < qdaQdc.length; i++)
// System.out.print((float) qdaQdc[i] + " ");
// teststr = "";
// }
/*
* Read H and D
*/

View file

@ -0,0 +1,58 @@
package gov.noaa.nws.ncep.edex.plugin.geomag.handler;
import gov.noaa.nws.ncep.common.dataplugin.geomag.GeoMagK1min;
import gov.noaa.nws.ncep.common.dataplugin.geomag.dao.GeoMagK1minDao;
import gov.noaa.nws.ncep.common.dataplugin.geomag.request.RetrieveSingleK1minRequest;
import java.util.List;
import java.util.logging.Logger;
import com.raytheon.uf.common.serialization.comm.IRequestHandler;
/**
*
* Handler for RetrieveKiminRequest. Retrieves the GeoMagK1min for the given
* datauri
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 2014/02/12 #1110 qzhou Init
*
* </pre>
*
* @author qzhou
* @version 1.0
*/
public class RetrieveSingleK1minRequestHandler implements
IRequestHandler<RetrieveSingleK1minRequest> {
private static Logger logger = Logger
.getLogger(RetrieveSingleK1minRequestHandler.class.toString());
private GeoMagK1minDao dao;
@Override
public Object handleRequest(RetrieveSingleK1minRequest request)
throws Exception {
List<GeoMagK1min> resultsList = null;
logger.info("RetrieveSingleK1minRequest for "
+ request.getStationCode());
try {
dao = new GeoMagK1minDao();
resultsList = dao.getSingleK1min(request.getStationCode(),
request.getRefTime());
} catch (Exception e) {
logger.warning("Error retrieving K1min record for "
+ request.getStationCode());
}
return resultsList;
}
}