Merge "Issue #1495 enable ensemble subset requests in opendap. Change-Id: I5c74b23f6c5c31b397855f102ee08f9c5737ac1a" into 13.2.1_delivery
Former-commit-id: b940fe556d1421d3709ff6c798ee0a39ae09af10
This commit is contained in:
commit
9f9020db61
17 changed files with 369 additions and 192 deletions
|
@ -413,6 +413,7 @@ public class UserSelectComp extends Composite implements IUpdate, IDisplay,
|
|||
u.setEnvelope(groupDefinition.getEnvelope());
|
||||
u.setNumFcstHours(subscription.getTime()
|
||||
.getSelectedTimeIndices().size());
|
||||
u.setNumEnsembleMembers(subscription.getEnsemble());
|
||||
u.determineNumberRequestedGrids(subscription.getParameter());
|
||||
|
||||
Coverage cov = new GriddedCoverage();
|
||||
|
|
|
@ -186,6 +186,9 @@ public class GriddedSubsetManagerDlg
|
|||
|
||||
time.setSelectedTimeIndices(fcstIndices);
|
||||
subscription.setTime(time);
|
||||
|
||||
subscription.setEnsemble(dataSet.getEnsemble());
|
||||
|
||||
return subscription;
|
||||
}
|
||||
|
||||
|
@ -270,7 +273,7 @@ public class GriddedSubsetManagerDlg
|
|||
// Get the temporal data
|
||||
int numFcstHours = this.timingTabControls.getSelectedFcstHours().length;
|
||||
dataSize.setNumFcstHours(numFcstHours);
|
||||
|
||||
dataSize.setNumEnsembleMembers(dataSet.getEnsemble());
|
||||
// Get the Areal data
|
||||
ReferencedEnvelope envelope = this.spatialTabControls.getEnvelope();
|
||||
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
package com.raytheon.uf.common.datadelivery.registry;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
|
@ -30,67 +34,161 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
|||
@DynamicSerialize
|
||||
public class Ensemble implements ISerializableObject {
|
||||
|
||||
/**
|
||||
* names of the various ensemble members
|
||||
*/
|
||||
@DynamicSerializeElement
|
||||
@XmlAttribute
|
||||
private List<String> members;
|
||||
|
||||
/**
|
||||
* which members to request.
|
||||
*/
|
||||
@DynamicSerializeElement
|
||||
@XmlAttribute
|
||||
private List<String> selectedMembers;
|
||||
|
||||
public Ensemble() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* ensemble models set this
|
||||
*/
|
||||
@DynamicSerializeElement
|
||||
@XmlAttribute
|
||||
private String name;
|
||||
public Ensemble(Ensemble other) {
|
||||
if (other.members != null) {
|
||||
members = new ArrayList<String>(other.members);
|
||||
}
|
||||
if (other.selectedMembers != null) {
|
||||
selectedMembers = new ArrayList<String>(other.selectedMembers);
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getMembers() {
|
||||
return members;
|
||||
}
|
||||
|
||||
public void setMembers(List<String> members) {
|
||||
this.members = members;
|
||||
}
|
||||
|
||||
public List<String> getSelectedMembers() {
|
||||
return selectedMembers;
|
||||
}
|
||||
|
||||
public void setSelectedMembers(List<String> selectedMembers) {
|
||||
this.selectedMembers = selectedMembers;
|
||||
}
|
||||
|
||||
public int getMemberCount() {
|
||||
if (members == null) {
|
||||
// if no members are defined then assume a single unnamed member.
|
||||
return 1;
|
||||
} else {
|
||||
return members.size();
|
||||
}
|
||||
}
|
||||
|
||||
public int getSelectedMemberCount() {
|
||||
if (members == null) {
|
||||
// if no members are defined then assume a single unnamed member
|
||||
// which is automatically selected
|
||||
return 1;
|
||||
} else if (selectedMembers == null) {
|
||||
return 0;
|
||||
} else {
|
||||
return selectedMembers.size();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasSelection() {
|
||||
return selectedMembers != null && !selectedMembers.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* ensemble models set this
|
||||
*
|
||||
* Get the range of indices of the selected members, inclusively. This
|
||||
* method should usually be used after a split operation to guarantee that
|
||||
* selected ensembles are consecutive
|
||||
*
|
||||
* @return a int[2] representing the start and end indices of the ensemble
|
||||
* members
|
||||
* @throws IllegalStateException
|
||||
* if the selected member are non consecutive.
|
||||
*/
|
||||
@DynamicSerializeElement
|
||||
@XmlAttribute
|
||||
private String length;
|
||||
public int[] getSelectedRange() {
|
||||
int[] result = new int[2];
|
||||
int[] indexes = getSortedIndexes();
|
||||
if (indexes == null) {
|
||||
return result;
|
||||
}
|
||||
result[0] = indexes[0];
|
||||
result[1] = result[0] - 1;
|
||||
for (int index : indexes) {
|
||||
result[1] += 1;
|
||||
if (result[1] != index) {
|
||||
throw new IllegalStateException(
|
||||
"Cannot get selected range for nonconsecutive ensemble members\nMembers "
|
||||
+ members + "\nSelected" + selectedMembers);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* ensemble models set this
|
||||
* Split this ensemble into multiple Ensembles each with consecutive
|
||||
* members. Used in cases where multiple ensembles can be requested at once
|
||||
* if they are consecutive.
|
||||
*
|
||||
* @param maxEnsembles
|
||||
* The mazximum number of consecutive members in any Ensemble
|
||||
* @return
|
||||
*/
|
||||
@DynamicSerializeElement
|
||||
@XmlAttribute
|
||||
private String init;
|
||||
|
||||
/**
|
||||
* ensemble models set this
|
||||
*/
|
||||
@DynamicSerializeElement
|
||||
@XmlAttribute
|
||||
private Integer size;
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
public List<Ensemble> split(int maxEnsembles) {
|
||||
int[] indexes = getSortedIndexes();
|
||||
if (indexes == null) {
|
||||
return Arrays.asList(new Ensemble(this));
|
||||
}
|
||||
List<Ensemble> result = new ArrayList<Ensemble>();
|
||||
List<String> selected = new ArrayList<String>(selectedMembers.size());
|
||||
int start = indexes[0];
|
||||
int end = start - 1;
|
||||
for (int index : indexes) {
|
||||
end += 1;
|
||||
if (index != end || (end - start) >= maxEnsembles) {
|
||||
// Either we have run out of consecutive indexes or we have the
|
||||
// max consecutive. so split off and start the next one.
|
||||
Ensemble e = new Ensemble(this);
|
||||
e.setSelectedMembers(new ArrayList<String>(selected));
|
||||
selected.clear();
|
||||
result.add(e);
|
||||
start = index;
|
||||
end = start;
|
||||
}
|
||||
selected.add(members.get(index));
|
||||
}
|
||||
Ensemble e = new Ensemble(this);
|
||||
e.setSelectedMembers(selected);
|
||||
result.add(e);
|
||||
return result;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
private int[] getSortedIndexes() {
|
||||
if (!hasSelection()) {
|
||||
return null;
|
||||
}
|
||||
int[] indexes = new int[selectedMembers.size()];
|
||||
int c = 0;
|
||||
for (String selected : selectedMembers) {
|
||||
int index = members.indexOf(selected);
|
||||
if (index >= 0) {
|
||||
indexes[c++] = index;
|
||||
}
|
||||
}
|
||||
if (c == 0) {
|
||||
return null;
|
||||
} else if (c < indexes.length) {
|
||||
indexes = Arrays.copyOf(indexes, c);
|
||||
}
|
||||
Arrays.sort(indexes);
|
||||
return indexes;
|
||||
}
|
||||
|
||||
public void setSize(Integer size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public Integer getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public void setLength(String length) {
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public String getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
public void setInit(String init) {
|
||||
this.init = init;
|
||||
}
|
||||
|
||||
public String getInit() {
|
||||
return init;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
package com.raytheon.uf.common.datadelivery.registry;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
|
@ -59,6 +60,10 @@ public abstract class GriddedDataSet extends DataSet {
|
|||
@DynamicSerializeElement
|
||||
protected Set<Integer> forecastHours = new HashSet<Integer>();
|
||||
|
||||
@DynamicSerializeElement
|
||||
@XmlElement
|
||||
private Ensemble ensemble;
|
||||
|
||||
/**
|
||||
* @return the cycles
|
||||
*/
|
||||
|
@ -89,6 +94,14 @@ public abstract class GriddedDataSet extends DataSet {
|
|||
this.forecastHours = forecastHours;
|
||||
}
|
||||
|
||||
public Ensemble getEnsemble() {
|
||||
return ensemble;
|
||||
}
|
||||
|
||||
public void setEnsemble(Ensemble ensemble) {
|
||||
this.ensemble = ensemble;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -100,6 +113,15 @@ public abstract class GriddedDataSet extends DataSet {
|
|||
GriddedDataSet other = (GriddedDataSet) toCombine;
|
||||
this.getCycles().addAll(other.getCycles());
|
||||
this.getForecastHours().addAll(other.getForecastHours());
|
||||
if (this.getEnsemble() != null) {
|
||||
List<String> mine = this.getEnsemble().getSelectedMembers();
|
||||
List<String> theirs = other.getEnsemble().getSelectedMembers();
|
||||
if (mine == null) {
|
||||
ensemble.setSelectedMembers(theirs);
|
||||
} else if (theirs != null) {
|
||||
mine.addAll(theirs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import java.util.Map;
|
|||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlSeeAlso;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
|
||||
|
@ -60,13 +59,6 @@ public abstract class GriddedDataSetMetaData extends
|
|||
@SlotAttribute(CYCLE_SLOT)
|
||||
private int cycle = NO_CYCLE;
|
||||
|
||||
/**
|
||||
* ensemble models set this
|
||||
*/
|
||||
@DynamicSerializeElement
|
||||
@XmlElement
|
||||
private Ensemble ensemble;
|
||||
|
||||
public void setLevelTypes(Map<DataLevelType, Levels> levelTypes) {
|
||||
this.levelTypes = levelTypes;
|
||||
}
|
||||
|
@ -92,11 +84,4 @@ public abstract class GriddedDataSetMetaData extends
|
|||
return cycle;
|
||||
}
|
||||
|
||||
public void setEnsemble(Ensemble ensemble) {
|
||||
this.ensemble = ensemble;
|
||||
}
|
||||
|
||||
public Ensemble getEnsemble() {
|
||||
return ensemble;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,10 +92,6 @@ public class Parameter implements ISerializableObject, Serializable {
|
|||
@DynamicSerializeElement
|
||||
private String fillValue;
|
||||
|
||||
@XmlAttribute
|
||||
@DynamicSerializeElement
|
||||
private Integer ensemble;
|
||||
|
||||
@XmlAttribute
|
||||
@DynamicSerializeElement
|
||||
private String baseType;
|
||||
|
@ -124,7 +120,6 @@ public class Parameter implements ISerializableObject, Serializable {
|
|||
this.dataType = copy.dataType;
|
||||
this.missingValue = copy.missingValue;
|
||||
this.fillValue = copy.fillValue;
|
||||
this.ensemble = copy.ensemble;
|
||||
this.baseType = copy.baseType;
|
||||
|
||||
// deep copy
|
||||
|
@ -265,14 +260,6 @@ public class Parameter implements ISerializableObject, Serializable {
|
|||
return levels;
|
||||
}
|
||||
|
||||
public void setEnsemble(Integer ensemble) {
|
||||
this.ensemble = ensemble;
|
||||
}
|
||||
|
||||
public Integer getEnsemble() {
|
||||
return ensemble;
|
||||
}
|
||||
|
||||
public void setFillValue(String fillValue) {
|
||||
this.fillValue = fillValue;
|
||||
}
|
||||
|
|
|
@ -243,6 +243,10 @@ public class Subscription implements ISerializableObject, Serializable {
|
|||
@DynamicSerializeElement
|
||||
private ArrayList<Parameter> parameter;
|
||||
|
||||
@XmlElement
|
||||
@DynamicSerializeElement
|
||||
private Ensemble ensemble;
|
||||
|
||||
@XmlAttribute
|
||||
@DynamicSerializeElement
|
||||
private boolean deleted;
|
||||
|
@ -920,4 +924,13 @@ public class Subscription implements ISerializableObject, Serializable {
|
|||
public int getLatencyInMinutes() {
|
||||
return latencyInMinutes;
|
||||
}
|
||||
|
||||
public Ensemble getEnsemble() {
|
||||
return ensemble;
|
||||
}
|
||||
|
||||
public void setEnsemble(Ensemble ensemble) {
|
||||
this.ensemble = ensemble;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.geotools.geometry.jts.ReferencedEnvelope;
|
|||
|
||||
import com.raytheon.uf.common.datadelivery.registry.Coverage;
|
||||
import com.raytheon.uf.common.datadelivery.registry.DataSet;
|
||||
import com.raytheon.uf.common.datadelivery.registry.Ensemble;
|
||||
import com.raytheon.uf.common.datadelivery.registry.GriddedCoverage;
|
||||
import com.raytheon.uf.common.datadelivery.registry.GriddedDataSet;
|
||||
import com.raytheon.uf.common.datadelivery.registry.Levels;
|
||||
|
@ -102,6 +103,8 @@ public class DataSizeUtils {
|
|||
/** Number of forecast hours */
|
||||
private int numFcstHours = 0;
|
||||
|
||||
private int numEnsembleMembers = 0;
|
||||
|
||||
/** Envelope */
|
||||
private ReferencedEnvelope envelope = null;
|
||||
|
||||
|
@ -153,6 +156,7 @@ public class DataSizeUtils {
|
|||
public long getDataSetSizeInBytes() {
|
||||
long l = numRequestedGrids
|
||||
* numFcstHours
|
||||
* numEnsembleMembers
|
||||
* dataSet.getServiceType().getRequestBytesPerParameterPerLevel(
|
||||
numberOfGridCells);
|
||||
return l;
|
||||
|
@ -181,8 +185,15 @@ public class DataSizeUtils {
|
|||
long numCells = griddedCov.getGridCoverage().getNx()
|
||||
* griddedCov.getGridCoverage().getNy();
|
||||
// Default to 1 forecast hour if not a gridded data set
|
||||
long fcstHrs = dataSet instanceof GriddedDataSet ? ((GriddedDataSet) dataSet)
|
||||
.getForecastHours().size() : 1;
|
||||
long numEns = 1;
|
||||
long fcstHrs = 1;
|
||||
if (dataSet instanceof GriddedDataSet) {
|
||||
GriddedDataSet gDataSet = (GriddedDataSet) dataSet;
|
||||
fcstHrs = gDataSet.getForecastHours().size();
|
||||
if (gDataSet.getEnsemble() != null) {
|
||||
numEns = gDataSet.getEnsemble().getMemberCount();
|
||||
}
|
||||
}
|
||||
Map<String, Parameter> paramMap = dataSet.getParameters();
|
||||
|
||||
// get the number of grids available
|
||||
|
@ -196,7 +207,8 @@ public class DataSizeUtils {
|
|||
numGridsAvailable += (numLevels > 0 ? numLevels : 1);
|
||||
}
|
||||
|
||||
fullSize = fcstHrs
|
||||
fullSize = numEns
|
||||
* fcstHrs
|
||||
* numGridsAvailable
|
||||
* dataSet.getServiceType()
|
||||
.getRequestBytesPerParameterPerLevel(
|
||||
|
@ -295,4 +307,13 @@ public class DataSizeUtils {
|
|||
|
||||
this.numRequestedGrids = numGrids;
|
||||
}
|
||||
|
||||
public void setNumEnsembleMembers(Ensemble ensemble) {
|
||||
if (ensemble == null) {
|
||||
this.numEnsembleMembers = 1;
|
||||
} else {
|
||||
this.numEnsembleMembers = ensemble.getSelectedMemberCount();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
|||
|
||||
import com.raytheon.uf.common.datadelivery.registry.Coverage;
|
||||
import com.raytheon.uf.common.datadelivery.registry.CoverageAdapter;
|
||||
import com.raytheon.uf.common.datadelivery.registry.Ensemble;
|
||||
import com.raytheon.uf.common.datadelivery.registry.Parameter;
|
||||
import com.raytheon.uf.common.datadelivery.registry.Time;
|
||||
import com.raytheon.uf.common.serialization.ISerializableObject;
|
||||
|
@ -100,6 +101,10 @@ public class RetrievalAttribute implements ISerializableObject, Serializable {
|
|||
@DynamicSerializeElement
|
||||
private Time time;
|
||||
|
||||
@XmlElement
|
||||
@DynamicSerializeElement
|
||||
private Ensemble ensemble;
|
||||
|
||||
@XmlElement(name = "provider")
|
||||
@DynamicSerializeElement
|
||||
private String provider;
|
||||
|
@ -156,4 +161,12 @@ public class RetrievalAttribute implements ISerializableObject, Serializable {
|
|||
return subName;
|
||||
}
|
||||
|
||||
public Ensemble getEnsemble() {
|
||||
return ensemble;
|
||||
}
|
||||
|
||||
public void setEnsemble(Ensemble ensemble) {
|
||||
this.ensemble = ensemble;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
package com.raytheon.uf.edex.datadelivery.retrieval.metadata.adapters;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.raytheon.edex.util.Util;
|
||||
import com.raytheon.uf.common.datadelivery.registry.GriddedCoverage;
|
||||
|
@ -60,11 +62,18 @@ public class GridMetadataAdapter extends AbstractMetadataAdapter {
|
|||
Level[] levels = getLevels(attXML);
|
||||
int size = levels.length;
|
||||
|
||||
List<String> ensembles = null;
|
||||
if (attXML.getEnsemble() != null && attXML.getEnsemble().hasSelection()) {
|
||||
ensembles = attXML.getEnsemble().getSelectedMembers();
|
||||
size *= ensembles.size();
|
||||
} else {
|
||||
ensembles = Arrays.asList((String) null);
|
||||
}
|
||||
|
||||
if (attXML.getTime().getSelectedTimeIndices() != null) {
|
||||
if (levels.length > 1
|
||||
|| attXML.getTime().getSelectedTimeIndices().size() > 1) {
|
||||
size = levels.length
|
||||
* attXML.getTime().getSelectedTimeIndices().size();
|
||||
size *= attXML.getTime().getSelectedTimeIndices().size();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,20 +89,21 @@ public class GridMetadataAdapter extends AbstractMetadataAdapter {
|
|||
}
|
||||
|
||||
if (attXML.getTime().getSelectedTimeIndices() != null) {
|
||||
|
||||
for (int i = 0; i < attXML.getTime().getSelectedTimeIndices()
|
||||
.size(); i++) {
|
||||
for (int j = 0; j < levels.length; j++) {
|
||||
int bin = (levels.length * i) + j;
|
||||
pdos[bin] = populateGridRecord(attXML.getSubName(),
|
||||
attXML.getParameter(),
|
||||
levels[j], gridCoverage);
|
||||
int bin = 0;
|
||||
for (String ensemble : ensembles) {
|
||||
for (int i = 0; i < attXML.getTime().getSelectedTimeIndices()
|
||||
.size(); i++) {
|
||||
for (int j = 0; j < levels.length; j++) {
|
||||
pdos[bin++] = populateGridRecord(attXML.getSubName(),
|
||||
attXML.getParameter(), levels[j], ensemble,
|
||||
gridCoverage);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
pdos[0] = populateGridRecord(attXML.getSubName(),
|
||||
attXML.getParameter(), levels[0],
|
||||
attXML.getParameter(), levels[0], ensembles.get(0),
|
||||
gridCoverage);
|
||||
|
||||
}
|
||||
|
@ -108,10 +118,9 @@ public class GridMetadataAdapter extends AbstractMetadataAdapter {
|
|||
* @return
|
||||
*/
|
||||
private GridRecord populateGridRecord(String name, Parameter parm,
|
||||
Level level,
|
||||
GridCoverage gridCoverage) {
|
||||
Level level, String ensembleId, GridCoverage gridCoverage) {
|
||||
return ResponseProcessingUtilities.getGridRecord(name, parm, level,
|
||||
gridCoverage);
|
||||
ensembleId, gridCoverage);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -37,6 +37,7 @@ import com.raytheon.uf.common.datadelivery.registry.DataSet;
|
|||
import com.raytheon.uf.common.datadelivery.registry.DataSetMetaData;
|
||||
import com.raytheon.uf.common.datadelivery.registry.DataType;
|
||||
import com.raytheon.uf.common.datadelivery.registry.GriddedCoverage;
|
||||
import com.raytheon.uf.common.datadelivery.registry.GriddedDataSet;
|
||||
import com.raytheon.uf.common.datadelivery.registry.GriddedDataSetMetaData;
|
||||
import com.raytheon.uf.common.datadelivery.registry.Levels;
|
||||
import com.raytheon.uf.common.datadelivery.registry.OpenDapGriddedDataSet;
|
||||
|
@ -179,7 +180,8 @@ class OpenDAPMetaDataParser extends MetaDataParser {
|
|||
* @param dataDateFormat
|
||||
* @return
|
||||
*/
|
||||
private Map<String, Parameter> getParameters(DAS das, DataSet dataSet,
|
||||
private Map<String, Parameter> getParameters(DAS das,
|
||||
GriddedDataSet dataSet,
|
||||
GriddedDataSetMetaData gdsmd, Link link, Collection collection,
|
||||
String dataDateFormat) {
|
||||
|
||||
|
@ -336,7 +338,8 @@ class OpenDAPMetaDataParser extends MetaDataParser {
|
|||
if (das.getAttributeTable(ens) != null) {
|
||||
try {
|
||||
AttributeTable at = das.getAttributeTable(ens);
|
||||
gdsmd.setEnsemble(OpenDAPParseUtility.getInstance().parseEnsemble(at));
|
||||
dataSet.setEnsemble(OpenDAPParseUtility.getInstance()
|
||||
.parseEnsemble(at));
|
||||
} catch (Exception en) {
|
||||
logParsingException(ens, "Ensemble", collectionName, url);
|
||||
}
|
||||
|
@ -414,11 +417,6 @@ class OpenDAPMetaDataParser extends MetaDataParser {
|
|||
levMin, levMax));
|
||||
parm.addLevelType(type);
|
||||
|
||||
// set if an ensemble member
|
||||
if (gdsmd.getEnsemble() != null) {
|
||||
parm.setEnsemble(gdsmd.getEnsemble().getSize());
|
||||
}
|
||||
|
||||
parameters.put(name, parm);
|
||||
|
||||
} catch (Exception le) {
|
||||
|
|
|
@ -52,6 +52,8 @@ final class OpenDAPParseUtility {
|
|||
|
||||
private static final Pattern QUOTES_PATTERN = Pattern.compile("\"");
|
||||
|
||||
private static final Pattern COMMA_PATTERN = Pattern.compile(",");
|
||||
|
||||
/** Singleton instance of this class */
|
||||
private static OpenDAPParseUtility instance = null;
|
||||
|
||||
|
@ -252,35 +254,16 @@ final class OpenDAPParseUtility {
|
|||
*/
|
||||
public Ensemble parseEnsemble(AttributeTable table) {
|
||||
|
||||
String stime = serviceConfig.getConstantValue("TIMEINIT");
|
||||
String slength = serviceConfig.getConstantValue("LENGTH");
|
||||
String sname = serviceConfig.getConstantValue("NAME");
|
||||
int size = new Integer(trim(table.getAttribute(
|
||||
serviceConfig.getConstantValue("SIZE")).getValueAt(0)))
|
||||
.intValue();
|
||||
String name = null;
|
||||
String length = null;
|
||||
String tinit = null;
|
||||
|
||||
if (table.getAttribute(slength) != null) {
|
||||
length = table.getAttribute(slength).getValueAt(0);
|
||||
}
|
||||
Ensemble ens = new Ensemble();
|
||||
|
||||
if (table.getAttribute(sname) != null) {
|
||||
name = table.getAttribute(sname).getValueAt(0);
|
||||
String name = trim(table.getAttribute(sname).getValueAt(0));
|
||||
String[] members = COMMA_PATTERN.split(name);
|
||||
ens.setMembers(Arrays.asList(members));
|
||||
}
|
||||
|
||||
if (table.getAttribute(stime) != null) {
|
||||
tinit = table.getAttribute(stime).getValueAt(0);
|
||||
}
|
||||
|
||||
Ensemble ens = new Ensemble();
|
||||
ens.setSize(size);
|
||||
ens.setLength(length);
|
||||
ens.setName(name);
|
||||
ens.setInit(tinit);
|
||||
|
||||
return ens;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -22,6 +22,7 @@ package com.raytheon.uf.edex.datadelivery.retrieval.opendap;
|
|||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.raytheon.uf.common.datadelivery.registry.Coverage;
|
||||
import com.raytheon.uf.common.datadelivery.registry.Ensemble;
|
||||
import com.raytheon.uf.common.datadelivery.registry.GriddedCoverage;
|
||||
import com.raytheon.uf.common.datadelivery.registry.Levels;
|
||||
import com.raytheon.uf.common.datadelivery.registry.Parameter;
|
||||
|
@ -216,17 +217,17 @@ class OpenDAPRequestBuilder extends RequestBuilder {
|
|||
*/
|
||||
public String processEnsemble() {
|
||||
|
||||
StringBuilder buf = new StringBuilder();
|
||||
|
||||
if (getRetrievalAttribute().getParameter().getEnsemble() != null) {
|
||||
buf.append("["
|
||||
+ (getRetrievalAttribute().getParameter().getEnsemble() - 1)
|
||||
+ "]");
|
||||
if (getRetrievalAttribute().getEnsemble() != null) {
|
||||
Ensemble e = getRetrievalAttribute().getEnsemble();
|
||||
int[] range = e.getSelectedRange();
|
||||
if (range[0] == range[1]) {
|
||||
return "[" + range[0] + "]";
|
||||
} else {
|
||||
return "[" + range[0] + ":" + range[1] + "]";
|
||||
}
|
||||
} else {
|
||||
buf.append("");
|
||||
return "";
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -22,14 +22,15 @@ package com.raytheon.uf.edex.datadelivery.retrieval.opendap;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.raytheon.uf.common.datadelivery.registry.Coverage;
|
||||
import com.raytheon.uf.common.datadelivery.registry.DataSet;
|
||||
import com.raytheon.uf.common.datadelivery.registry.DataSetMetaData;
|
||||
import com.raytheon.uf.common.datadelivery.registry.Ensemble;
|
||||
import com.raytheon.uf.common.datadelivery.registry.GriddedCoverage;
|
||||
import com.raytheon.uf.common.datadelivery.registry.GriddedDataSetMetaData;
|
||||
import com.raytheon.uf.common.datadelivery.registry.Levels;
|
||||
|
@ -265,13 +266,14 @@ class OpenDAPRetrievalGenerator extends RetrievalGenerator {
|
|||
* @param parm
|
||||
* @return
|
||||
*/
|
||||
protected HashMap<DataTime, ArrayList<Level>> getGridDuplicates(
|
||||
protected Map<DataTime, List<Level>> getGridDuplicates(
|
||||
String name,
|
||||
Parameter parm, ArrayList<DataTime> times, ArrayList<Level> levels,
|
||||
Parameter parm, List<DataTime> times, List<Level> levels,
|
||||
List<String> ensembleMembers,
|
||||
GriddedCoverage cov) {
|
||||
|
||||
return RetrievalGeneratorUtilities.findGridDuplicates(name, times,
|
||||
levels,
|
||||
levels, ensembleMembers,
|
||||
parm, cov.getRequestGridCoverage());
|
||||
}
|
||||
|
||||
|
@ -286,6 +288,13 @@ class OpenDAPRetrievalGenerator extends RetrievalGenerator {
|
|||
List<Retrieval> retrievals = new ArrayList<Retrieval>();
|
||||
Subscription sub = bundle.getSubscription();
|
||||
|
||||
if (sub.getEnsemble() != null && !sub.getEnsemble().hasSelection()) {
|
||||
// TODO remove this once the UI allows you to make an ensemble
|
||||
// selection.
|
||||
sub.getEnsemble()
|
||||
.setSelectedMembers(sub.getEnsemble().getMembers());
|
||||
}
|
||||
|
||||
int sfactor = getSizingFactor(getDimensionalSize(sub.getCoverage()));
|
||||
sub = removeDuplicates(sub);
|
||||
|
||||
|
@ -319,6 +328,13 @@ class OpenDAPRetrievalGenerator extends RetrievalGenerator {
|
|||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<Ensemble> ensembles = null;
|
||||
if (sub.getEnsemble() == null) {
|
||||
ensembles = Arrays.asList((Ensemble) null);
|
||||
} else {
|
||||
ensembles = sub.getEnsemble().split(1);
|
||||
}
|
||||
|
||||
for (List<Integer> timeSequence : subTime.getTimeSequences(sfactor)) {
|
||||
|
||||
for (Parameter param : sub.getParameter()) {
|
||||
|
@ -332,9 +348,11 @@ class OpenDAPRetrievalGenerator extends RetrievalGenerator {
|
|||
sub.getTime());
|
||||
|
||||
for (Time time : times) {
|
||||
Retrieval retrieval = getRetrieval(sub, bundle,
|
||||
param, paramLevels, time);
|
||||
retrievals.add(retrieval);
|
||||
for (Ensemble ensemble : ensembles) {
|
||||
Retrieval retrieval = getRetrieval(sub, bundle,
|
||||
param, paramLevels, time, ensemble);
|
||||
retrievals.add(retrieval);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
@ -350,9 +368,12 @@ class OpenDAPRetrievalGenerator extends RetrievalGenerator {
|
|||
// and time
|
||||
for (Time time : times) {
|
||||
for (Levels level : levels) {
|
||||
Retrieval retrieval = getRetrieval(sub,
|
||||
bundle, param, level, time);
|
||||
retrievals.add(retrieval);
|
||||
for (Ensemble ensemble : ensembles) {
|
||||
Retrieval retrieval = getRetrieval(sub,
|
||||
bundle, param, level, time,
|
||||
ensemble);
|
||||
retrievals.add(retrieval);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -375,7 +396,7 @@ class OpenDAPRetrievalGenerator extends RetrievalGenerator {
|
|||
* @return
|
||||
*/
|
||||
private Retrieval getRetrieval(Subscription sub, SubscriptionBundle bundle,
|
||||
Parameter param, Levels level, Time time) {
|
||||
Parameter param, Levels level, Time time, Ensemble ensemble) {
|
||||
|
||||
Retrieval retrieval = new Retrieval();
|
||||
retrieval.setSubscriptionName(sub.getName());
|
||||
|
@ -404,6 +425,7 @@ class OpenDAPRetrievalGenerator extends RetrievalGenerator {
|
|||
lparam.setLevels(level);
|
||||
att.setTime(time);
|
||||
att.setParameter(lparam);
|
||||
att.setEnsemble(ensemble);
|
||||
att.setSubName(retrieval.getSubscriptionName());
|
||||
att.setPlugin(pt.getPlugin());
|
||||
att.setProvider(sub.getProvider());
|
||||
|
@ -488,7 +510,6 @@ class OpenDAPRetrievalGenerator extends RetrievalGenerator {
|
|||
param.setBaseType(origParm.getBaseType());
|
||||
param.setDataType(origParm.getDataType());
|
||||
param.setDefinition(origParm.getDefinition());
|
||||
param.setEnsemble(origParm.getEnsemble());
|
||||
param.setFillValue(origParm.getFillValue());
|
||||
param.setLevelType(origParm.getLevelType());
|
||||
param.setMissingValue(origParm.getMissingValue());
|
||||
|
@ -536,6 +557,13 @@ class OpenDAPRetrievalGenerator extends RetrievalGenerator {
|
|||
|
||||
int sfactor = getSizingFactor(getDimensionalSize(sub.getCoverage()));
|
||||
|
||||
List<String> ensembles = null;
|
||||
if (sub.getEnsemble() != null && sub.getEnsemble().hasSelection()) {
|
||||
ensembles = sub.getEnsemble().getSelectedMembers();
|
||||
} else {
|
||||
ensembles = Arrays.asList((String) null);
|
||||
}
|
||||
|
||||
for (List<Integer> timeSequence : sub.getTime().getTimeSequences(
|
||||
sfactor)) {
|
||||
|
||||
|
@ -557,14 +585,14 @@ class OpenDAPRetrievalGenerator extends RetrievalGenerator {
|
|||
ArrayList<Level> levels = ResponseProcessingUtilities
|
||||
.getOpenDAPGridLevels(param.getLevels());
|
||||
|
||||
HashMap<DataTime, ArrayList<Level>> dups = getGridDuplicates(
|
||||
Map<DataTime, List<Level>> dups = getGridDuplicates(
|
||||
sub.getName(),
|
||||
param, times, levels,
|
||||
param, times, levels, ensembles,
|
||||
(GriddedCoverage) sub.getCoverage());
|
||||
|
||||
for (int i = 0; i < times.size(); i++) {
|
||||
DataTime dtime = times.get(i);
|
||||
ArrayList<Level> levDups = dups.get(dtime);
|
||||
List<Level> levDups = dups.get(dtime);
|
||||
|
||||
if (levDups != null) {
|
||||
// single level, remove the time
|
||||
|
@ -594,14 +622,14 @@ class OpenDAPRetrievalGenerator extends RetrievalGenerator {
|
|||
.getOpenDAPGridLevels(level);
|
||||
}
|
||||
|
||||
HashMap<DataTime, ArrayList<Level>> dups = getGridDuplicates(
|
||||
sub.getName(),
|
||||
param, times, plevels,
|
||||
Map<DataTime, List<Level>> dups = getGridDuplicates(
|
||||
sub.getName(), param, times, plevels,
|
||||
ensembles,
|
||||
((GriddedCoverage) sub.getCoverage()));
|
||||
|
||||
for (int i = 0; i < times.size(); i++) {
|
||||
DataTime dtime = times.get(i);
|
||||
ArrayList<Level> levDups = dups.get(dtime);
|
||||
List<Level> levDups = dups.get(dtime);
|
||||
|
||||
if (levDups != null) {
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ package com.raytheon.uf.edex.datadelivery.retrieval.response;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
|
||||
import com.raytheon.uf.common.datadelivery.registry.GriddedCoverage;
|
||||
import com.raytheon.uf.common.datadelivery.retrieval.xml.RetrievalAttribute;
|
||||
|
@ -149,33 +150,41 @@ public class OpenDAPTranslator extends RetrievalTranslator {
|
|||
PrimitiveVector pm = darray.getPrimitiveVector();
|
||||
float[] values = (float[]) pm.getInternalStorage();
|
||||
|
||||
List<String> ensembles = null;
|
||||
if (attXML.getEnsemble() != null && attXML.getEnsemble().hasSelection()) {
|
||||
ensembles = attXML.getEnsemble().getSelectedMembers();
|
||||
} else {
|
||||
ensembles = Arrays.asList((String) null);
|
||||
}
|
||||
|
||||
// time dependencies
|
||||
int start = 0;
|
||||
PluginDataObject[] records = new PluginDataObject[numLevels * numTimes];
|
||||
PluginDataObject[] records = new PluginDataObject[numLevels * numTimes
|
||||
* ensembles.size()];
|
||||
|
||||
for (int i = 0; i < times.size(); i++) {
|
||||
int bin = 0;
|
||||
for (int i = 0; i < ensembles.size(); i++) {
|
||||
for (DataTime dataTime : times) {
|
||||
for (int j = 0; j < numLevels; j++) {
|
||||
PluginDataObject record = getPdo(bin);
|
||||
record.setDataTime(dataTime);
|
||||
record.constructDataURI();
|
||||
|
||||
DataTime dataTime = times.get(i);
|
||||
int end = start + gridSize;
|
||||
|
||||
for (int j = 0; j < numLevels; j++) {
|
||||
int bin = (numLevels * i) + j;
|
||||
PluginDataObject record = getPdo(bin);
|
||||
record.setDataTime(dataTime);
|
||||
record.constructDataURI();
|
||||
float[] subValues = Arrays.copyOfRange(values, start, end);
|
||||
|
||||
int end = start + gridSize;
|
||||
subValues = GridMetadataAdapter.adjustGrid(nx, ny,
|
||||
subValues, Float.parseFloat(attXML.getParameter()
|
||||
.getMissingValue()), true);
|
||||
|
||||
float[] subValues = Arrays.copyOfRange(values, start, end);
|
||||
|
||||
subValues = GridMetadataAdapter.adjustGrid(nx, ny, subValues,
|
||||
Float.parseFloat(attXML.getParameter()
|
||||
.getMissingValue()), true);
|
||||
|
||||
record.setMessageData(subValues);
|
||||
record.setOverwriteAllowed(true);
|
||||
records[bin] = record;
|
||||
statusHandler.info("Creating record: " + record.getDataURI());
|
||||
start = end;
|
||||
record.setMessageData(subValues);
|
||||
record.setOverwriteAllowed(true);
|
||||
records[bin++] = record;
|
||||
statusHandler.info("Creating record: "
|
||||
+ record.getDataURI());
|
||||
start = end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ public class ResponseProcessingUtilities {
|
|||
.getHandler(ResponseProcessingUtilities.class);
|
||||
|
||||
public static GridRecord getGridRecord(String name, Parameter parm,
|
||||
Level level,
|
||||
Level level, String ensembleId,
|
||||
GridCoverage gridCoverage) {
|
||||
|
||||
com.raytheon.uf.common.parameter.Parameter parameter = new com.raytheon.uf.common.parameter.Parameter();
|
||||
|
@ -75,7 +75,7 @@ public class ResponseProcessingUtilities {
|
|||
record.setLevel(level);
|
||||
record.setParameter(parameter);
|
||||
record.setDatasetId(name);
|
||||
|
||||
record.setEnsembleId(ensembleId);
|
||||
return record;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@ package com.raytheon.uf.edex.datadelivery.retrieval.util;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.raytheon.uf.common.datadelivery.registry.Parameter;
|
||||
import com.raytheon.uf.common.dataplugin.PluginException;
|
||||
|
@ -87,35 +89,39 @@ public class RetrievalGeneratorUtilities {
|
|||
* @param cov
|
||||
* @return
|
||||
*/
|
||||
public static HashMap<DataTime, ArrayList<Level>> findGridDuplicates(
|
||||
String name,
|
||||
ArrayList<DataTime> times, ArrayList<Level> levels, Parameter parm,
|
||||
public static Map<DataTime, List<Level>> findGridDuplicates(String name,
|
||||
List<DataTime> times, List<Level> levels,
|
||||
List<String> ensembleMembers, Parameter parm,
|
||||
GridCoverage cov) {
|
||||
|
||||
HashMap<DataTime, ArrayList<Level>> dups = new HashMap<DataTime, ArrayList<Level>>();
|
||||
HashMap<DataTime, List<Level>> dups = new HashMap<DataTime, List<Level>>();
|
||||
|
||||
for (DataTime time : times) {
|
||||
|
||||
ArrayList<Level> levDups = dups.get(time);
|
||||
List<Level> levDups = dups.get(time);
|
||||
|
||||
if (levDups == null) {
|
||||
levDups = new ArrayList<Level>();
|
||||
}
|
||||
|
||||
for (Level level : levels) {
|
||||
try {
|
||||
for (String ensembleMember : ensembleMembers) {
|
||||
try {
|
||||
|
||||
GridRecord rec = ResponseProcessingUtilities.getGridRecord(
|
||||
name, parm, level, cov);
|
||||
rec.setDataTime(time);
|
||||
rec.constructDataURI();
|
||||
boolean isDup = findDuplicateUri(rec.getDataURI(), "grid");
|
||||
if (isDup) {
|
||||
levDups.add(level);
|
||||
GridRecord rec = ResponseProcessingUtilities
|
||||
.getGridRecord(name, parm, level,
|
||||
ensembleMember, cov);
|
||||
rec.setDataTime(time);
|
||||
rec.constructDataURI();
|
||||
boolean isDup = findDuplicateUri(rec.getDataURI(),
|
||||
"grid");
|
||||
if (isDup) {
|
||||
levDups.add(level);
|
||||
}
|
||||
} catch (PluginException e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
e.getLocalizedMessage(), e);
|
||||
}
|
||||
} catch (PluginException e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
e.getLocalizedMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue