Normalizer { public void normalize(){ logger.info(() -> "Normalization started..."); List<VortexData> source = new ArrayList<>(); sourceVariables.forEach(variable -> source.addAll( DataReader.builder() .path(pathToSource) .variable(variable) .build() .getDtos())); List<VortexData> normals = new ArrayList<>(); normalsVariables.forEach(variable -> normals.addAll( DataReader.builder() .path(pathToNormals) .variable(variable) .build() .getDtos())); AtomicReference<ZonedDateTime> intervalStart = new AtomicReference<>(); intervalStart.set(startTime); AtomicInteger count = new AtomicInteger(); while (intervalStart.get().isBefore(endTime)){ ZonedDateTime start = intervalStart.get(); ZonedDateTime end = intervalStart.get().plus(interval); List<VortexGrid> sourceFiltered = source.stream().filter(grid -> ((grid.startTime().isEqual(start) || grid.startTime().isAfter(start)) && (grid.endTime().isEqual(end) || grid.endTime().isBefore(end)))) .map(grid -> (VortexGrid)grid) .collect(Collectors.toList()); if (sourceFiltered.isEmpty()) { logger.warning(() -> format("No source grids for period %s to %s", formatter.format(start), formatter.format(end))); } List<VortexGrid> normalsFiltered = normals.stream().filter(grid -> ((grid.startTime().equals(start) || grid.startTime().isAfter(start)) && (grid.endTime().isEqual(end) || grid.endTime().isBefore(end)))) .map(grid -> (VortexGrid)grid) .collect(Collectors.toList()); if (normalsFiltered.isEmpty()){ logger.warning(() -> format("No normals grids for period %s to %s", formatter.format(start), formatter.format(end))); } List<VortexGrid> output = normalize(sourceFiltered, normalsFiltered); output.forEach(grid -> { List<VortexData> data = new ArrayList<>(); data.add(grid); DataWriter writer = DataWriter.builder() .data(data) .destination(destination) .options(writeOptions) .build(); writer.write(); }); intervalStart.set(end); count.addAndGet(output.size()); } logger.info(() -> format("Normalization complete: %s grids normalized.", count.get())); } private  Normalizer(NormalizerBuilder builder); static NormalizerBuilder builder(); void normalize();  }
@Test void DtoArraysAreNormalized() { VortexGrid dto1 = mock(VortexGrid.class); when(dto1.data()).thenReturn(new float[]{0,Float.NaN,2,4,2,2,2,2}); when(dto1.startTime()).thenReturn(ZonedDateTime.of(0, 1, 1,0,0,0,0, ZoneId.of("UTC"))); when(dto1.endTime()).thenReturn(ZonedDateTime.of(0, 1, 1,0,0,0,0, ZoneId.of("UTC"))); VortexGrid dto2 = mock(VortexGrid.class); when(dto2.data()).thenReturn(new float[]{0,2,2,4,2,2,2,1}); when(dto2.startTime()).thenReturn(ZonedDateTime.of(0, 1, 1,0,0,0,0, ZoneId.of("UTC"))); when(dto2.endTime()).thenReturn(ZonedDateTime.of(0, 1, 1,0,0,0,0, ZoneId.of("UTC"))); VortexGrid dto3 = mock(VortexGrid.class); when(dto3.data()).thenReturn(new float[]{0,2,Float.NaN,6,2,8,2,2}); when(dto3.startTime()).thenReturn(ZonedDateTime.of(0, 1, 1,0,0,0,0, ZoneId.of("UTC"))); when(dto3.endTime()).thenReturn(ZonedDateTime.of(0, 1, 1,0,0,0,0, ZoneId.of("UTC"))); List<VortexGrid> inputs = new ArrayList<>(); inputs.add(dto1); inputs.add(dto2); List<VortexGrid> normals = new ArrayList<>(); normals.add(dto3); List<VortexGrid> normalized = Normalizer.normalize(inputs, normals); float[] expected1 = new float[]{0, Float.NaN, 2, 3, 1, 4, 1, Float.parseFloat("1.333")}; float[] normalized1 = normalized.get(0).data(); for (int i = 0; i < normalized1.length; i++){ try { assertEquals(expected1[i], normalized1[i], 1E-3); }catch(AssertionError e){ System.out.println("Error index: " + i); throw e; } } float[] expected2 = new float[]{0, 2, 2, 3, 1, 4, 1, Float.parseFloat("0.667")}; float[] normalized2 = normalized.get(1).data(); for (int i = 0; i < normalized2.length; i++) { try { assertEquals(expected2[i], normalized2[i], 1E-3); } catch (AssertionError e) { System.out.println("Error index: " + i); throw e; } } }