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

decodes.cwms.rating.CwmsRatingSingleIndep Maven / Gradle / Ivy

Go to download

A collection of software for aggregatting and processing environmental data such as from NOAA GOES satellites.

The newest version!
/**
 * $Id$
 * 
 * $Log$
 * Revision 1.12  2017/10/23 13:36:28  mmaloney
 * Log stack trace on rating exceptions.
 *
 * Revision 1.11  2017/08/22 19:32:37  mmaloney
 * Improve comments
 *
 * Revision 1.10  2017/02/16 14:41:26  mmaloney
 * Close CwmsRatingDao in final block.
 *
 * Revision 1.9  2016/09/29 18:54:37  mmaloney
 * CWMS-8979 Allow Database Process Record to override decodes.properties and
 * user.properties setting. Command line arg -Dsettings=appName, where appName is the
 * name of a process record. Properties assigned to the app will override the file(s).
 *
 * Revision 1.8  2016/01/13 15:15:37  mmaloney
 * rating retrieval
 *
 * Revision 1.7  2015/07/14 17:59:45  mmaloney
 * Added 'useDepLocation' property with default=false.
 * Set to true to use the dep param location for building rating spec.
 *
 * Revision 1.6  2015/01/06 02:09:11  mmaloney
 * dev
 *
 * Revision 1.5  2015/01/06 00:41:58  mmaloney
 * dev
 *
 * Revision 1.4  2015/01/05 21:04:39  mmaloney
 * Automatically convert units to the dataUnits reported by the RatingSet.
 *
 * Revision 1.3  2014/12/23 14:15:57  mmaloney
 * Debug to print input and output to/from HEC Rating method.
 *
 * Revision 1.2  2014/12/18 21:52:21  mmaloney
 * In error messages, print the specId.
 *
 * Revision 1.1.1.1  2014/05/19 15:28:59  mmaloney
 * OPENDCS 6.0 Initial Checkin
 *
 * Revision 1.7  2013/04/25 20:46:07  mmaloney
 * Fixed error message.
 *
 * Revision 1.6  2012/11/20 21:17:18  mmaloney
 * Implemented cache for ratings.
 *
 * Revision 1.5  2012/11/12 19:53:03  mmaloney
 * dev
 *
 * Revision 1.4  2012/11/12 19:36:04  mmaloney
 * Use version of method that passes officeID.
 * The one without office ID always returns a RatingSpec with no Ratings in it.
 *
 * Revision 1.3  2012/11/09 21:50:24  mmaloney
 * fixed init
 *
 * Revision 1.2  2012/11/09 21:10:42  mmaloney
 * Fixed imports.
 *
 * Revision 1.1  2012/11/09 21:06:20  mmaloney
 * Checked in Rating Algorithms.
 *
 * This software was written by Cove Software, LLC ("COVE") under contract 
 * to the United States Government. 
 * 
 * No warranty is provided or implied other than specific contractual terms
 * between COVE and the U.S. Government
 * 
 * Copyright 2016 U.S. Army Corps of Engineers, Hydrologic Engineering Center.
 * All rights reserved.
 */
package decodes.cwms.rating;

import java.io.PrintStream;
import java.sql.Connection;
import java.util.Date;

import ilex.util.EnvExpander;
import ilex.util.Logger;
import ilex.var.NamedVariableList;
import ilex.var.NamedVariable;
import decodes.cwms.CwmsTimeSeriesDb;
import decodes.db.Constants;
import decodes.db.SiteName;
import decodes.tsdb.DbAlgorithmExecutive;
import decodes.tsdb.DbCompException;
import decodes.tsdb.DbIoException;
import decodes.tsdb.VarFlags;
import decodes.tsdb.algo.AWAlgoType;
import decodes.tsdb.CTimeSeries;
import decodes.tsdb.ParmRef;
import ilex.var.TimedVariable;


//AW:IMPORTS
import hec.data.RatingException;
import hec.data.cwmsRating.RatingSet;
import hec.lang.Const;

import java.util.ArrayList;

import decodes.tsdb.TimeSeriesIdentifier;
//AW:IMPORTS_END
import decodes.util.TSUtil;

//AW:JAVADOC
/**
Implements CWMS rating computations.
Uses the CWMS API provided by HEC to do the rating.
*/
//AW:JAVADOC_END
public class CwmsRatingSingleIndep
	extends decodes.tsdb.algo.AW_AlgorithmBase
{
//AW:INPUTS
	public double indep;	//AW:TYPECODE=i
	String _inputNames[] = { "indep" };
//AW:INPUTS_END

//AW:LOCALVARS
	RatingSet ratingSet = null;
	Date beginTime = null;
	Date endTime = null;
	ArrayList indepTimes = new ArrayList();
	ArrayList indepValues = new ArrayList();
	String specId = "";
	public static final String module = "CwmsRatingSingleIndep";
//AW:LOCALVARS_END

//AW:OUTPUTS
	public NamedVariable dep = new NamedVariable("dep", 0);
	String _outputNames[] = { "dep" };
//AW:OUTPUTS_END

//AW:PROPERTIES
	public String templateVersion = "USGS-EXSA";
	public String specVersion = "Production";
	public boolean useDepLocation = false;
	public String _propertyNames[] = { "templateVersion", "specVersion", "useDepLocation" };
//AW:PROPERTIES_END

	// Allow javac to generate a no-args constructor.

	/**
	 * Algorithm-specific initialization provided by the subclass.
	 */
	protected void initAWAlgorithm( )
		throws DbCompException
	{
//AW:INIT
		_awAlgoType = AWAlgoType.TIME_SLICE;
//AW:INIT_END

//AW:USERINIT
//AW:USERINIT_END
	}
	
	/**
	 * This method is called once before iterating all time slices.
	 */
	protected void beforeTimeSlices()
		throws DbCompException
	{
//AW:BEFORE_TIMESLICES
		// Get parm refs for indep and dep
		ParmRef indepParmRef = getParmRef("indep");
		ParmRef depParmRef = getParmRef("dep");
		
		// Build rating spec ID as follows:
		// {CwmsLocID}.{indep:cwmsDataType};{dep:cwmsDataType}.{templateVersion}.{specVersion}
		TimeSeriesIdentifier indepTsid = indepParmRef.timeSeries.getTimeSeriesIdentifier();
		
		String specLocation = indepTsid.getSiteName();
		// OpenDCS 6.1 RC10 feature allows location to be taken from dep variable:
		if (useDepLocation)
		{
			SiteName depSiteName = depParmRef.compParm.getSiteName(Constants.snt_CWMS);
			if (depSiteName == null)
				debug1("No dependent site name available, using site from indep1");
			else
				specLocation = depSiteName.getNameValue();
		}
		
		specId = specLocation + "." 
			+ indepTsid.getDataType().getCode() + ";"
			+ depParmRef.compParm.getDataType().getCode() + "."
			+ templateVersion + "." + specVersion;
			
		// Retrieve the RatingSet object
		CwmsRatingDao crd = new CwmsRatingDao((CwmsTimeSeriesDb)tsdb);
		try
		{
			Date earliestBaseTime = baseTimes.first();
//debug3("Will do rating for the following " + baseTimes.size() + " base times:");
//for(Date baseTime : baseTimes)
//{
//	debug3("    " + baseTime.toString());
//}
			if (earliestBaseTime == null)
				earliestBaseTime = new Date();
			ratingSet = crd.getRatingSet(specId);
			
			// As per instructions from Mike Perryman: I must find out what the native units
			// for the rating are and convert before calling the Java rating. The Java rating
			// method assumes that data are already in correct units.
			String punits[] = ratingSet.getDataUnits();
			if (punits.length > 0 && punits[0] != null
			 && indepParmRef.timeSeries.getUnitsAbbr() != null
			 && !indepParmRef.timeSeries.getUnitsAbbr().equalsIgnoreCase(punits[0]))
			{
				debug1(module + " Converting indep units for time series " 
					+ indepParmRef.timeSeries.getTimeSeriesIdentifier().getUniqueString() + " from "
					+ indepParmRef.timeSeries.getUnitsAbbr() + " to " + punits[0]);
				TSUtil.convertUnits(indepParmRef.timeSeries, punits[0]);
			}
			// Likewise for the dependent param:
			if (punits.length > 1 && punits[1] != null
			 && depParmRef.timeSeries.getUnitsAbbr() != null
			 && !depParmRef.timeSeries.getUnitsAbbr().equalsIgnoreCase(punits[1]))
			{
debug1(module + " depTSID=" + depParmRef.timeSeries.getTimeSeriesIdentifier());
				debug1(module + " Converting dep units from "
					+ depParmRef.timeSeries.getUnitsAbbr() + " to " + punits[1]);
				TSUtil.convertUnits(depParmRef.timeSeries, punits[1]);
			}
		}
		catch (RatingException ex)
		{
			throw new DbCompException("Cannot read rating for '" + specId + "': " + ex);
		}
		finally
		{
			crd.close();
		}

		indepTimes.clear();
		indepValues.clear();
//AW:BEFORE_TIMESLICES_END
	}

	/**
	 * Do the algorithm for a single time slice.
	 * AW will fill in user-supplied code here.
	 * Base class will set inputs prior to calling this method.
	 * User code should call one of the setOutput methods for a time-slice
	 * output variable.
	 *
	 * @throw DbCompException (or subclass thereof) if execution of this
	 *        algorithm is to be aborted.
	 */
	protected void doAWTimeSlice()
		throws DbCompException
	{
//AW:TIMESLICE
		if (ratingSet == null)
			throw new DbCompException("No rating set!");
		
		// Just collect the times & values. We do the rating after Time Slices.
		indepTimes.add(_timeSliceBaseTime.getTime());
		indepValues.add(indep);
//AW:TIMESLICE_END
	}

	/**
	 * This method is called once after iterating all time slices.
	 */
	protected void afterTimeSlices()
	{
//AW:AFTER_TIMESLICES
		long []times = new long[indepTimes.size()];
		double []vals = new double[indepTimes.size()];
		for(int i=0; iLINEAR
		//	ERROR
		//	ERROR
		// Consequently, always use the array type rating method and let the database
		// determine what happens.
		// If NULL is the method then the dep output wil be set to Const.UNDEFINED_DOUBLE

		Connection conn = tsdb.getConnection();
		try
		{
			debug1("Calling rate with " + times.length + " times/values");
			double depVals[] = ratingSet.rate(conn, times, vals);
					//ratingSet.rate(times, vals);
			
			for(int i=0; i




© 2015 - 2024 Weber Informatics LLC | Privacy Policy