Skip to content

Commit 66a3e60

Browse files
committed
implemented anti-meridian interpolation for time-series
1 parent bc82806 commit 66a3e60

File tree

3 files changed

+148
-143
lines changed

3 files changed

+148
-143
lines changed
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,155 @@
11
package com.bc.fiduceo.post.plugin.era5;
22

3+
import com.bc.fiduceo.util.NetCDFUtils;
4+
import ucar.ma2.Array;
5+
import ucar.ma2.Index;
6+
import ucar.ma2.InvalidRangeException;
7+
8+
import java.awt.*;
9+
import java.io.IOException;
10+
311
class FieldsProcessor {
412

13+
private static final int RASTER_WIDTH = 1440;
14+
515
TemplateVariable createTemplate(String name, String units, String longName, String standardName, boolean is3d) {
616
return new TemplateVariable(name, units, longName, standardName, is3d);
717
}
18+
19+
static Array readSubset(int numLayers, Rectangle era5RasterPosition, VariableCache.CacheEntry cacheEntry) throws IOException, InvalidRangeException {
20+
Array subset;
21+
22+
final int maxRequestedX = era5RasterPosition.x + era5RasterPosition.width - 1;
23+
if (era5RasterPosition.x < 0 || maxRequestedX >= RASTER_WIDTH) {
24+
subset = readVariableDataOverlapped(numLayers, era5RasterPosition, cacheEntry.array);
25+
} else {
26+
subset = readVariableData(numLayers, era5RasterPosition, cacheEntry.array);
27+
}
28+
29+
return NetCDFUtils.scaleIfNecessary(cacheEntry.variable, subset);
30+
}
31+
32+
private static Array readVariableDataOverlapped(int numLayers, Rectangle era5RasterPosition, Array array) throws IOException, InvalidRangeException {
33+
Array subset;
34+
int xMin = 0;
35+
int xMax;
36+
int leftWidth;
37+
int rightWidth;
38+
if (era5RasterPosition.x < 0) {
39+
xMax = RASTER_WIDTH + era5RasterPosition.x; // notabene: rasterposition is negative tb 2021-01-13
40+
leftWidth = era5RasterPosition.width + era5RasterPosition.x;
41+
rightWidth = -era5RasterPosition.x;
42+
} else {
43+
xMax = era5RasterPosition.x;
44+
rightWidth = RASTER_WIDTH - era5RasterPosition.x;
45+
leftWidth = era5RasterPosition.width - rightWidth;
46+
}
47+
final Rectangle leftEraPos = new Rectangle(xMin, era5RasterPosition.y, leftWidth, era5RasterPosition.height);
48+
final Array leftSubset = readVariableData(numLayers, leftEraPos, array);
49+
50+
final Rectangle rightEraPos = new Rectangle(xMax, era5RasterPosition.y, rightWidth, era5RasterPosition.height);
51+
final Array rightSubset = readVariableData(numLayers, rightEraPos, array);
52+
53+
subset = mergeData(leftSubset, rightSubset, numLayers, era5RasterPosition, array);
54+
return subset;
55+
}
56+
57+
static Array mergeData(Array leftSubset, Array rightSubset, int numLayers, Rectangle era5RasterPosition, Array array) {
58+
final int rank = array.getRank();
59+
final Array mergedArray;
60+
if (rank == 4) {
61+
mergedArray = Array.factory(array.getDataType(), new int[]{numLayers, era5RasterPosition.height, era5RasterPosition.width});
62+
if (era5RasterPosition.x < 0) {
63+
final int xMax = era5RasterPosition.width + era5RasterPosition.x;
64+
mergeArrays_3D(leftSubset, rightSubset, era5RasterPosition, mergedArray, xMax);
65+
} else {
66+
final int xMax = RASTER_WIDTH - era5RasterPosition.x;
67+
mergeArrays_3D(rightSubset, leftSubset, era5RasterPosition, mergedArray, xMax);
68+
}
69+
} else {
70+
mergedArray = Array.factory(array.getDataType(), new int[]{era5RasterPosition.height, era5RasterPosition.width});
71+
if (era5RasterPosition.x < 0) {
72+
final int xMax = era5RasterPosition.width + era5RasterPosition.x;
73+
mergeArrays(leftSubset, rightSubset, era5RasterPosition, mergedArray, xMax);
74+
} else {
75+
final int xMax = RASTER_WIDTH - era5RasterPosition.x;
76+
mergeArrays(rightSubset, leftSubset, era5RasterPosition, mergedArray, xMax);
77+
}
78+
}
79+
80+
return mergedArray;
81+
}
82+
83+
private static void mergeArrays(Array leftSubset, Array rightSubset, Rectangle era5RasterPosition, Array mergedArray, int xMax) {
84+
final Index targetIndex = mergedArray.getIndex();
85+
Index srcIndex = leftSubset.getIndex();
86+
int srcX = 0;
87+
for (int x = 0; x < xMax; x++) {
88+
for (int y = 0; y < era5RasterPosition.height; y++) {
89+
targetIndex.set(y, x);
90+
srcIndex.set(y, srcX);
91+
mergedArray.setObject(targetIndex, leftSubset.getObject(srcIndex));
92+
}
93+
++srcX;
94+
}
95+
srcIndex = rightSubset.getIndex();
96+
srcX = 0;
97+
for (int x = xMax; x < era5RasterPosition.width; x++) {
98+
for (int y = 0; y < era5RasterPosition.height; y++) {
99+
targetIndex.set(y, x);
100+
srcIndex.set(y, srcX);
101+
mergedArray.setObject(targetIndex, rightSubset.getObject(srcIndex));
102+
}
103+
++srcX;
104+
}
105+
}
106+
107+
private static void mergeArrays_3D(Array leftSubset, Array rightSubset, Rectangle era5RasterPosition, Array mergedArray, int xMax) {
108+
final Index targetIndex = mergedArray.getIndex();
109+
Index srcIndex = leftSubset.getIndex();
110+
int srcX = 0;
111+
final int numLayers = leftSubset.getShape()[0];
112+
for (int x = 0; x < xMax; x++) {
113+
for (int y = 0; y < era5RasterPosition.height; y++) {
114+
for (int z = 0; z < numLayers; z++) {
115+
targetIndex.set(z, y, x);
116+
srcIndex.set(z, y, srcX);
117+
mergedArray.setObject(targetIndex, leftSubset.getObject(srcIndex));
118+
}
119+
}
120+
++srcX;
121+
}
122+
srcIndex = rightSubset.getIndex();
123+
srcX = 0;
124+
for (int x = xMax; x < era5RasterPosition.width; x++) {
125+
for (int y = 0; y < era5RasterPosition.height; y++) {
126+
for (int z = 0; z < numLayers; z++) {
127+
targetIndex.set(z, y, x);
128+
srcIndex.set(z, y, srcX);
129+
mergedArray.setObject(targetIndex, rightSubset.getObject(srcIndex));
130+
}
131+
}
132+
++srcX;
133+
}
134+
}
135+
136+
private static Array readVariableData(int numLayers, Rectangle era5RasterPosition, Array array) throws IOException, InvalidRangeException {
137+
final int rank = array.getRank();
138+
Array subset;
139+
if (rank == 2) {
140+
final int[] origin = new int[]{era5RasterPosition.y, era5RasterPosition.x};
141+
final int[] shape = new int[]{era5RasterPosition.height, era5RasterPosition.width};
142+
final int[] stride = new int[]{1, 1};
143+
subset = array.sectionNoReduce(origin, shape, stride).copy();
144+
} else if (rank == 3) {
145+
final int[] origin = new int[]{0, era5RasterPosition.y, era5RasterPosition.x};
146+
final int[] shape = new int[]{numLayers, era5RasterPosition.height, era5RasterPosition.width};
147+
final int[] stride = new int[]{1, 1, 1};
148+
subset = array.sectionNoReduce(origin, shape, stride).copy();
149+
} else {
150+
throw new IOException("variable rank invalid");
151+
}
152+
153+
return subset;
154+
}
8155
}

post-processing-tool/src/main/java/com/bc/fiduceo/post/plugin/era5/MatchupFields.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,6 @@ void compute(Configuration config, NetcdfFile reader, NetcdfFileWriter writer) t
115115

116116
final InterpolationContext interpolationContext = Era5PostProcessing.getInterpolationContext(lonLayer, latLayer);
117117
final Rectangle layerRegion = interpolationContext.getEra5Region();
118-
final int[] offset = new int[]{layerRegion.y, layerRegion.x};
119-
final int[] shape = new int[]{layerRegion.height, layerRegion.width};
120118

121119
// iterate over time stamps
122120
for (int t = 0; t < numTimeSteps; t++) {
@@ -132,8 +130,7 @@ void compute(Configuration config, NetcdfFile reader, NetcdfFileWriter writer) t
132130
VariableCache.CacheEntry cacheEntry = variableCache.get(variableKey, timeStamp);
133131

134132
// read and get rid of fake z-dimension
135-
Array subset = cacheEntry.array.section(offset, shape);
136-
subset = NetCDFUtils.scaleIfNecessary(cacheEntry.variable, subset);
133+
final Array subset = readSubset(1, layerRegion, cacheEntry);
137134
final Index subsetIndex = subset.getIndex();
138135
final BilinearInterpolator bilinearInterpolator = interpolationContext.get(0, 0);
139136
if (bilinearInterpolator == null) {

post-processing-tool/src/main/java/com/bc/fiduceo/post/plugin/era5/SatelliteFields.java

Lines changed: 0 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -18,150 +18,11 @@
1818

1919
class SatelliteFields extends FieldsProcessor {
2020

21-
private static final int RASTER_WIDTH = 1440;
22-
2321
private List<Dimension> dimension2d;
2422
private List<Dimension> dimension3d;
2523
private Map<String, TemplateVariable> variables;
2624
private Era5Collection collection;
2725

28-
static Array readSubset(int numLayers, Rectangle era5RasterPosition, VariableCache.CacheEntry cacheEntry) throws IOException, InvalidRangeException {
29-
Array subset;
30-
31-
final int maxRequestedX = era5RasterPosition.x + era5RasterPosition.width - 1;
32-
if (era5RasterPosition.x < 0 || maxRequestedX >= RASTER_WIDTH) {
33-
subset = readVariableDataOverlapped(numLayers, era5RasterPosition, cacheEntry.array);
34-
} else {
35-
subset = readVariableData(numLayers, era5RasterPosition, cacheEntry.array);
36-
}
37-
38-
return NetCDFUtils.scaleIfNecessary(cacheEntry.variable, subset);
39-
}
40-
41-
private static Array readVariableDataOverlapped(int numLayers, Rectangle era5RasterPosition, Array array) throws IOException, InvalidRangeException {
42-
Array subset;
43-
int xMin = 0;
44-
int xMax;
45-
int leftWidth;
46-
int rightWidth;
47-
if (era5RasterPosition.x < 0) {
48-
xMax = RASTER_WIDTH + era5RasterPosition.x; // notabene: rasterposition is negative tb 2021-01-13
49-
leftWidth = era5RasterPosition.width + era5RasterPosition.x;
50-
rightWidth = -era5RasterPosition.x;
51-
} else {
52-
xMax = era5RasterPosition.x;
53-
rightWidth = RASTER_WIDTH - era5RasterPosition.x;
54-
leftWidth = era5RasterPosition.width - rightWidth;
55-
}
56-
final Rectangle leftEraPos = new Rectangle(xMin, era5RasterPosition.y, leftWidth, era5RasterPosition.height);
57-
final Array leftSubset = readVariableData(numLayers, leftEraPos, array);
58-
59-
final Rectangle rightEraPos = new Rectangle(xMax, era5RasterPosition.y, rightWidth, era5RasterPosition.height);
60-
final Array rightSubset = readVariableData(numLayers, rightEraPos, array);
61-
62-
subset = mergeData(leftSubset, rightSubset, numLayers, era5RasterPosition, array);
63-
return subset;
64-
}
65-
66-
static Array mergeData(Array leftSubset, Array rightSubset, int numLayers, Rectangle era5RasterPosition, Array array) {
67-
final int rank = array.getRank();
68-
final Array mergedArray;
69-
if (rank == 4) {
70-
mergedArray = Array.factory(array.getDataType(), new int[]{numLayers, era5RasterPosition.height, era5RasterPosition.width});
71-
if (era5RasterPosition.x < 0) {
72-
final int xMax = era5RasterPosition.width + era5RasterPosition.x;
73-
mergeArrays_3D(leftSubset, rightSubset, era5RasterPosition, mergedArray, xMax);
74-
} else {
75-
final int xMax = RASTER_WIDTH - era5RasterPosition.x;
76-
mergeArrays_3D(rightSubset, leftSubset, era5RasterPosition, mergedArray, xMax);
77-
}
78-
} else {
79-
mergedArray = Array.factory(array.getDataType(), new int[]{era5RasterPosition.height, era5RasterPosition.width});
80-
if (era5RasterPosition.x < 0) {
81-
final int xMax = era5RasterPosition.width + era5RasterPosition.x;
82-
mergeArrays(leftSubset, rightSubset, era5RasterPosition, mergedArray, xMax);
83-
} else {
84-
final int xMax = RASTER_WIDTH - era5RasterPosition.x;
85-
mergeArrays(rightSubset, leftSubset, era5RasterPosition, mergedArray, xMax);
86-
}
87-
}
88-
89-
return mergedArray;
90-
}
91-
92-
private static void mergeArrays(Array leftSubset, Array rightSubset, Rectangle era5RasterPosition, Array mergedArray, int xMax) {
93-
final Index targetIndex = mergedArray.getIndex();
94-
Index srcIndex = leftSubset.getIndex();
95-
int srcX = 0;
96-
for (int x = 0; x < xMax; x++) {
97-
for (int y = 0; y < era5RasterPosition.height; y++) {
98-
targetIndex.set(y, x);
99-
srcIndex.set(y, srcX);
100-
mergedArray.setObject(targetIndex, leftSubset.getObject(srcIndex));
101-
}
102-
++srcX;
103-
}
104-
srcIndex = rightSubset.getIndex();
105-
srcX = 0;
106-
for (int x = xMax; x < era5RasterPosition.width; x++) {
107-
for (int y = 0; y < era5RasterPosition.height; y++) {
108-
targetIndex.set(y, x);
109-
srcIndex.set(y, srcX);
110-
mergedArray.setObject(targetIndex, rightSubset.getObject(srcIndex));
111-
}
112-
++srcX;
113-
}
114-
}
115-
116-
private static void mergeArrays_3D(Array leftSubset, Array rightSubset, Rectangle era5RasterPosition, Array mergedArray, int xMax) {
117-
final Index targetIndex = mergedArray.getIndex();
118-
Index srcIndex = leftSubset.getIndex();
119-
int srcX = 0;
120-
final int numLayers = leftSubset.getShape()[0];
121-
for (int x = 0; x < xMax; x++) {
122-
for (int y = 0; y < era5RasterPosition.height; y++) {
123-
for (int z = 0; z < numLayers; z++) {
124-
targetIndex.set(z, y, x);
125-
srcIndex.set(z, y, srcX);
126-
mergedArray.setObject(targetIndex, leftSubset.getObject(srcIndex));
127-
}
128-
}
129-
++srcX;
130-
}
131-
srcIndex = rightSubset.getIndex();
132-
srcX = 0;
133-
for (int x = xMax; x < era5RasterPosition.width; x++) {
134-
for (int y = 0; y < era5RasterPosition.height; y++) {
135-
for (int z = 0; z < numLayers; z++) {
136-
targetIndex.set(z, y, x);
137-
srcIndex.set(z, y, srcX);
138-
mergedArray.setObject(targetIndex, rightSubset.getObject(srcIndex));
139-
}
140-
}
141-
++srcX;
142-
}
143-
}
144-
145-
private static Array readVariableData(int numLayers, Rectangle era5RasterPosition, Array array) throws IOException, InvalidRangeException {
146-
final int rank = array.getRank();
147-
Array subset;
148-
if (rank == 2) {
149-
final int[] origin = new int[]{era5RasterPosition.y, era5RasterPosition.x};
150-
final int[] shape = new int[]{era5RasterPosition.height, era5RasterPosition.width};
151-
final int[] stride = new int[]{1, 1};
152-
subset = array.sectionNoReduce(origin, shape, stride);
153-
} else if (rank == 3) {
154-
final int[] origin = new int[]{0, era5RasterPosition.y, era5RasterPosition.x};
155-
final int[] shape = new int[]{numLayers, era5RasterPosition.height, era5RasterPosition.width};
156-
final int[] stride = new int[]{1, 1, 1};
157-
subset = array.sectionNoReduce(origin, shape, stride);
158-
} else {
159-
throw new IOException("variable rank invalid");
160-
}
161-
162-
return subset;
163-
}
164-
16526
void prepare(SatelliteFieldsConfiguration satFieldsConfig, NetcdfFile reader, NetcdfFileWriter writer, Era5Collection collection) {
16627
satFieldsConfig.verify();
16728
setDimensions(satFieldsConfig, writer, reader);

0 commit comments

Comments
 (0)