|
1 | 1 | package com.bc.fiduceo.post.plugin.era5; |
2 | 2 |
|
3 | 3 | import com.bc.fiduceo.FiduceoConstants; |
4 | | -import com.bc.fiduceo.reader.ReaderUtils; |
5 | 4 | import com.bc.fiduceo.util.NetCDFUtils; |
6 | | -import ucar.ma2.*; |
| 5 | +import ucar.ma2.Array; |
| 6 | +import ucar.ma2.DataType; |
| 7 | +import ucar.ma2.Index; |
| 8 | +import ucar.ma2.InvalidRangeException; |
7 | 9 | import ucar.nc2.*; |
8 | 10 | import ucar.nc2.Dimension; |
9 | 11 |
|
|
16 | 18 |
|
17 | 19 | class SatelliteFields { |
18 | 20 |
|
| 21 | + private static final int RASTER_WIDTH = 1440; |
| 22 | + |
19 | 23 | private List<Dimension> dimension2d; |
20 | 24 | private List<Dimension> dimension3d; |
21 | 25 | private Map<String, TemplateVariable> variables; |
22 | 26 |
|
| 27 | + static Array readSubset(int numLayers, Rectangle era5RasterPosition, Variable variable) throws IOException, InvalidRangeException { |
| 28 | + Array subset = null; |
| 29 | + final int maxRequestedX = era5RasterPosition.x + era5RasterPosition.width; |
| 30 | + if (era5RasterPosition.x < 0 || maxRequestedX >= RASTER_WIDTH) { |
| 31 | + int xMin = 0; |
| 32 | + int xMax; |
| 33 | + int leftWidth; |
| 34 | + int rightWidth; |
| 35 | + if (era5RasterPosition.x < 0) { |
| 36 | + xMax = RASTER_WIDTH + era5RasterPosition.x; // notabene: rasterposition is negative tb 2021-01-13 |
| 37 | + leftWidth = era5RasterPosition.width + era5RasterPosition.x; |
| 38 | + rightWidth = -era5RasterPosition.x; |
| 39 | + } else { |
| 40 | + xMax = era5RasterPosition.x; |
| 41 | + rightWidth = RASTER_WIDTH - era5RasterPosition.x; |
| 42 | + leftWidth = era5RasterPosition.width - rightWidth; |
| 43 | + } |
| 44 | + final Rectangle leftEraPos = new Rectangle(xMin, era5RasterPosition.y, leftWidth, era5RasterPosition.height); |
| 45 | + final Array leftSubset = readVariableData(numLayers, leftEraPos, variable); |
| 46 | + |
| 47 | + final Rectangle rightEraPos = new Rectangle(xMax, era5RasterPosition.y, rightWidth, era5RasterPosition.height); |
| 48 | + final Array rightSubset = readVariableData(numLayers, rightEraPos, variable); |
| 49 | + |
| 50 | + subset = mergeData(leftSubset, rightSubset, numLayers, era5RasterPosition, variable); |
| 51 | + } else { |
| 52 | + subset = readVariableData(numLayers, era5RasterPosition, variable); |
| 53 | + } |
| 54 | + return NetCDFUtils.scaleIfNecessary(variable, subset); |
| 55 | + } |
| 56 | + |
| 57 | + static Array mergeData(Array leftSubset, Array rightSubset, int numLayers, Rectangle era5RasterPosition, Variable variable) { |
| 58 | + final int rank = variable.getRank(); |
| 59 | + final Array mergedArray; |
| 60 | + if (rank == 4) { |
| 61 | + mergedArray = Array.factory(variable.getDataType(), new int[]{numLayers, era5RasterPosition.height, era5RasterPosition.width}); |
| 62 | + } else { |
| 63 | + mergedArray = Array.factory(variable.getDataType(), new int[]{era5RasterPosition.height, era5RasterPosition.width}); |
| 64 | + final Index targetIndex = mergedArray.getIndex(); |
| 65 | + if (era5RasterPosition.x < 0) { |
| 66 | + Index srcIndex = leftSubset.getIndex(); |
| 67 | + int srcX = 0; |
| 68 | + for (int x = 0; x < -era5RasterPosition.x; x++) { |
| 69 | + for (int y = 0; y < era5RasterPosition.height; y++) { |
| 70 | + targetIndex.set(y, x); |
| 71 | + srcIndex.set(y, srcX); |
| 72 | + mergedArray.setObject(targetIndex, leftSubset.getObject(srcIndex)); |
| 73 | + } |
| 74 | + ++srcX; |
| 75 | + } |
| 76 | + srcIndex = rightSubset.getIndex(); |
| 77 | + srcX = 0; |
| 78 | + for (int x = -era5RasterPosition.x; x < era5RasterPosition.width; x++) { |
| 79 | + for (int y = 0; y < era5RasterPosition.height; y++) { |
| 80 | + targetIndex.set(y, x); |
| 81 | + srcIndex.set(y, srcX); |
| 82 | + mergedArray.setObject(targetIndex, rightSubset.getObject(srcIndex)); |
| 83 | + } |
| 84 | + ++srcX; |
| 85 | + } |
| 86 | + } else { |
| 87 | + Index srcIndex = rightSubset.getIndex(); |
| 88 | + int srcX = 0; |
| 89 | + for (int x = 0; x < RASTER_WIDTH - era5RasterPosition.x; x++) { |
| 90 | + for (int y = 0; y < era5RasterPosition.height; y++) { |
| 91 | + targetIndex.set(y, x); |
| 92 | + srcIndex.set(y, srcX); |
| 93 | + mergedArray.setObject(targetIndex, rightSubset.getObject(srcIndex)); |
| 94 | + } |
| 95 | + ++srcX; |
| 96 | + } |
| 97 | + srcIndex = leftSubset.getIndex(); |
| 98 | + srcX = 0; |
| 99 | + for (int x = RASTER_WIDTH - era5RasterPosition.x; x < era5RasterPosition.width; x++) { |
| 100 | + for (int y = 0; y < era5RasterPosition.height; y++) { |
| 101 | + targetIndex.set(y, x); |
| 102 | + srcIndex.set(y, srcX); |
| 103 | + mergedArray.setObject(targetIndex, leftSubset.getObject(srcIndex)); |
| 104 | + } |
| 105 | + ++srcX; |
| 106 | + } |
| 107 | + } |
| 108 | + } |
| 109 | + |
| 110 | + return mergedArray; |
| 111 | + } |
| 112 | + |
| 113 | + private static Array readVariableData(int numLayers, Rectangle era5RasterPosition, Variable variable) throws IOException, InvalidRangeException { |
| 114 | + final int rank = variable.getRank(); |
| 115 | + Array subset; |
| 116 | + if (rank == 3) { |
| 117 | + final int[] origin = new int[]{0, era5RasterPosition.y, era5RasterPosition.x}; |
| 118 | + final int[] shape = new int[]{1, era5RasterPosition.height, era5RasterPosition.width}; |
| 119 | + subset = variable.read(origin, shape); |
| 120 | + } else if (rank == 4) { |
| 121 | + final int[] origin = new int[]{0, 0, era5RasterPosition.y, era5RasterPosition.x}; |
| 122 | + final int[] shape = new int[]{1, numLayers, era5RasterPosition.height, era5RasterPosition.width}; |
| 123 | + subset = variable.read(origin, shape); |
| 124 | + } else { |
| 125 | + throw new IOException("variable rank invalid: " + variable.getShortName()); |
| 126 | + } |
| 127 | + |
| 128 | + subset = subset.reduce(); |
| 129 | + return subset; |
| 130 | + } |
| 131 | + |
23 | 132 | void prepare(SatelliteFieldsConfiguration satFieldsConfig, NetcdfFile reader, NetcdfFileWriter writer) { |
24 | 133 | satFieldsConfig.verify(); |
25 | 134 | setDimensions(satFieldsConfig, writer, reader); |
@@ -96,7 +205,7 @@ void compute(Configuration config, NetcdfFile reader, NetcdfFileWriter writer) t |
96 | 205 | final Set<String> variableKeys = variables.keySet(); |
97 | 206 | for (final String variableKey : variableKeys) { |
98 | 207 | final Variable variable = variableCache.get(variableKey, era5Time); |
99 | | - final Array subset = readSubset(numLayers, layerRegion, variableKey, variable); |
| 208 | + final Array subset = readSubset(numLayers, layerRegion, variable); |
100 | 209 | final Index subsetIndex = subset.getIndex(); |
101 | 210 |
|
102 | 211 | final Array targetArray = targetArrays.get(variableKey); |
@@ -167,26 +276,6 @@ void compute(Configuration config, NetcdfFile reader, NetcdfFileWriter writer) t |
167 | 276 | } |
168 | 277 | } |
169 | 278 |
|
170 | | - private Array readSubset(int numLayers, Rectangle era5RasterPosition, String variableKey, Variable variable) throws IOException, InvalidRangeException { |
171 | | - final int rank = variable.getRank(); |
172 | | - Array subset; |
173 | | - if (rank == 3) { |
174 | | - final int[] origin = new int[]{0, era5RasterPosition.y, era5RasterPosition.x}; |
175 | | - final int[] shape = new int[]{1, era5RasterPosition.height, era5RasterPosition.width}; |
176 | | - subset = variable.read(origin, shape); |
177 | | - } else if (rank == 4) { |
178 | | - final int[] origin = new int[]{0, 0, era5RasterPosition.y, era5RasterPosition.x}; |
179 | | - final int[] shape = new int[]{1, numLayers, era5RasterPosition.height, era5RasterPosition.width}; |
180 | | - subset = variable.read(origin, shape); |
181 | | - } else { |
182 | | - throw new IOException("variable rank invalid: " + variableKey); |
183 | | - } |
184 | | - |
185 | | - subset = subset.reduce(); |
186 | | - subset = NetCDFUtils.scaleIfNecessary(variable, subset); |
187 | | - return subset; |
188 | | - } |
189 | | - |
190 | 279 | private void addTimeVariable(SatelliteFieldsConfiguration satFieldsConfig, NetcdfFileWriter writer) { |
191 | 280 | final String nwp_time_variable_name = satFieldsConfig.get_nwp_time_variable_name(); |
192 | 281 | final String escapedName = NetCDFUtils.escapeVariableName(nwp_time_variable_name); |
|
0 commit comments