// $Id: SequenceHelper.java 51 2006-07-12 17:13:13Z caron $ /* * Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata * * Portions of this software were developed by the Unidata Program at the * University Corporation for Atmospheric Research. * * Access and use of this software shall impose the following obligations * and understandings on the user. The user is granted the right, without * any fee or cost, to use, copy, modify, alter, enhance and distribute * this software, and any derivative works thereof, and its supporting * documentation for any purpose whatsoever, provided that this entire * notice appears in all copies of the software, derivative works and * supporting documentation. Further, UCAR requests that the user credit * UCAR/Unidata in any publications that result from the use of this * software or in any product that includes this software. The names UCAR * and/or Unidata, however, may not be used in any advertising or publicity * to endorse or promote any products or commercial entity unless specific * written permission is obtained from UCAR/Unidata. The user also * understands that UCAR/Unidata is not obligated to provide the user with * any support, consulting, training or assistance of any kind with regard * to the use, operation and performance of this software nor to provide * the user with any updates, revisions, new versions or "bug fixes." * * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL, * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE. */ package ucar.nc2.dt.point; import ucar.nc2.*; import ucar.nc2.dods.DODSNetcdfFile; import ucar.nc2.dataset.NetcdfDataset; import ucar.nc2.dataset.StructureDS; import ucar.nc2.units.DateUnit; import ucar.nc2.units.DateFormatter; import ucar.nc2.util.CancelTask; import ucar.nc2.dt.*; import ucar.unidata.geoloc.LatLonPointImpl; import ucar.unidata.geoloc.LatLonRect; import ucar.unidata.geoloc.LatLonPoint; import ucar.ma2.*; import java.io.*; import java.util.*; /** * Helper class for dods sequence datasets. * * @author caron * @version $Revision: 51 $ $Date: 2006-07-12 17:13:13Z $ */ public class SequenceHelper { protected NetcdfFile ncfile; protected DODSNetcdfFile dodsFile; protected StructureDS sequenceOuter, sequenceInner; protected Variable latVar, lonVar, altVar, timeVar; protected boolean isProfile; protected DateUnit timeUnit; protected DateFormatter formatter; /** * Constructor. * @param ncfile the netccdf file * @param typedDataVariables list of data variables; all record variables will be added to this list, except . You * can remove extra * @throws IllegalArgumentException if ncfile has no unlimited dimension and recDimName is null. */ public SequenceHelper(NetcdfDataset ncfile, boolean isProfile, StructureDS sequenceOuter, StructureDS sequenceInner, Variable latVar, Variable lonVar, Variable altVar, Variable timeVar, List typedDataVariables, StringBuffer errBuffer) { this.ncfile = ncfile; this.isProfile = isProfile; this.sequenceOuter = sequenceOuter; this.sequenceInner = sequenceInner; this.latVar = latVar; this.lonVar = lonVar; this.altVar = altVar; this.timeVar = timeVar; // Need the underlying DODSNetcdfFile NetcdfFile refFile = ncfile.getReferencedFile(); while (dodsFile == null) { if (refFile instanceof DODSNetcdfFile) dodsFile = (DODSNetcdfFile) refFile; else if (refFile instanceof NetcdfDataset) refFile = ((NetcdfDataset)refFile).getReferencedFile(); else throw new IllegalArgumentException("Must be a DODSNetcdfFile"); } // create member variables List recordMembers = sequenceOuter.getVariables(); for (int i = 0; i < recordMembers.size(); i++) { Variable v = (Variable) recordMembers.get(i); typedDataVariables.add( v); } recordMembers = sequenceInner.getVariables(); for (int i = 0; i < recordMembers.size(); i++) { Variable v = (Variable) recordMembers.get(i); typedDataVariables.add( v); } typedDataVariables.remove(latVar); typedDataVariables.remove(lonVar); typedDataVariables.remove(altVar); typedDataVariables.remove(timeVar); typedDataVariables.remove(sequenceInner); } public void setTimeUnit( DateUnit timeUnit) { this.timeUnit = timeUnit; } public DateUnit getTimeUnit() { return( this.timeUnit ); } /* private Variable getDODSVariable( Variable v) { while (true) { if ((v instanceof DODSVariable) || (v instanceof DODSStructure)) return v; else { if (v == v.getIOVar()) throw new IllegalStateException("Circular reference"); v = v.getIOVar(); } } } */ public List getData(CancelTask cancel) throws IOException { String CE = sequenceOuter.getShortName(); ArrayStructure as = (ArrayStructure) dodsFile.readWithCE(sequenceOuter, CE); extractMembers(as); int n = (int) as.getSize(); ArrayList dataList = new ArrayList(n); for (int i=0; i<n; i++) dataList.add( new SeqPointObs( i, as.getStructureData(i))); return dataList; } public List getData(LatLonRect boundingBox, CancelTask cancel) throws IOException { String CE = sequenceOuter.getShortName() + "&" + makeBB( boundingBox); ArrayStructure as = (ArrayStructure) dodsFile.readWithCE(sequenceOuter, CE); extractMembers(as); int n = (int) as.getSize(); ArrayList dataList = new ArrayList(n); for (int i=0; i<n; i++) dataList.add( new SeqPointObs( i, as.getStructureData(i))); return dataList; } public List getData(LatLonRect boundingBox, Date start, Date end, CancelTask cancel) throws IOException { String CE = sequenceOuter.getShortName() + "&" + makeBB( boundingBox) + "&"+ makeTimeRange( start, end); ArrayStructure as = (ArrayStructure) dodsFile.readWithCE(sequenceOuter, CE); extractMembers(as); int n = (int) as.getSize(); ArrayList dataList = new ArrayList(n); for (int i=0; i<n; i++) dataList.add( new SeqPointObs( i, as.getStructureData(i))); return dataList; } private String makeBB( LatLonRect bb) { return latVar.getShortName()+">="+bb.getLowerLeftPoint().getLatitude()+"&"+ latVar.getShortName()+"<="+bb.getUpperRightPoint().getLatitude()+"&"+ lonVar.getShortName()+">="+bb.getLowerLeftPoint().getLongitude()+"&"+ lonVar.getShortName()+"<="+bb.getUpperRightPoint().getLongitude(); } private String makeTimeRange( Date start, Date end) { double startValue = timeUnit.makeValue(start); double endValue = timeUnit.makeValue(end); return timeVar.getShortName()+">="+startValue+"&"+ // LOOK timeVar.getShortName()+"<="+endValue; } private StructureMembers.Member latMember, lonMember, innerMember, altMember, timeMember; private void extractMembers( ArrayStructure as) { StructureMembers members = as.getStructureMembers(); latMember = members.findMember(latVar.getShortName()); lonMember = members.findMember(lonVar.getShortName()); innerMember = members.findMember(sequenceInner.getShortName()); StructureData first = as.getStructureData(0); StructureData innerFirst = first.getScalarStructure(innerMember); StructureMembers innerMembers = innerFirst.getStructureMembers(); if (isProfile) { timeMember = members.findMember(timeVar.getShortName()); altMember = innerMembers.findMember(altVar.getShortName()); } else { timeMember = innerMembers.findMember(timeVar.getShortName()); altMember = members.findMember(altVar.getShortName()); } } /* private class SeqDatatypeIterator extends DatatypeIterator { protected Object makeDatatypeWithData(int recnum, StructureData sdata) { return new SeqPointObs( recnum, sdata); } SeqDatatypeIterator(Structure struct, int bufferSize) { super( struct, bufferSize); } } */ //////////////////////////////////////////////////////////// public class SeqPointObs extends PointObsDatatypeImpl { protected int recno; protected LatLonPointImpl llpt = null; protected StructureData sdata; /** * Constructor for the case where you keep track of the location, time of each record, but not the data. */ protected SeqPointObs( ucar.unidata.geoloc.EarthLocation location, double obsTime, double nomTime, int recno) { super( location, obsTime, nomTime); this.recno = recno; } /** * Constructor for when you already have the StructureData and want to wrap it in a StationObsDatatype * @param recno record number LOOK why do we need ?? * @param sdata the structure data */ public SeqPointObs(int recno, StructureData sdata) { this.recno = recno; this.sdata = sdata; double lat = sdata.convertScalarDouble( latMember); double lon = sdata.convertScalarDouble( lonMember); // double lat = sdata.convertScalarDouble(latMember); // double lon = sdata.convertScalarDouble(lonMember); StructureData inner = sdata.getScalarStructure(innerMember); double alt = 0.0; if (isProfile) { obsTime = sdata.convertScalarDouble( timeMember); // sdata.convertScalarDouble(timeMember); alt = inner.convertScalarDouble( altMember); // inner.convertScalarDouble(altMember); } else { obsTime = inner.convertScalarDouble( timeMember); // inner.convertScalarDouble(timeMember); alt = sdata.convertScalarDouble( altMember); // sdata.convertScalarDouble(altMember); } nomTime = obsTime; location = new ucar.unidata.geoloc.EarthLocationImpl( lat, lon, alt); } public LatLonPoint getLatLon() { if (llpt == null) llpt = new LatLonPointImpl( location.getLatitude(), location.getLongitude()); return llpt; } public Date getNominalTimeAsDate() { return timeUnit.makeDate( getNominalTime()); } public Date getObservationTimeAsDate() { return timeUnit.makeDate( getObservationTime()); } public StructureData getData() throws IOException { return sdata; } } ///////////////////////// public DataIterator getDataIterator(int bufferSize) throws IOException { return new DataIteratorAdapter( getData(null).iterator()); // LOOK } }