SiteCalibrationServiceImpl implements SiteCalibrationService { @Override public Map<FrequencyBand, Map<Station, SiteFrequencyBandParameters>> measureSiteCorrections(Map<FrequencyBand, List<SpectraMeasurement>> dataByFreqBand, MdacParametersFI mdacFI, Map<PICK_TYPES, MdacParametersPS> mdacPS, Map<String, List<ReferenceMwParameters>> refMws, Map<FrequencyBand, SharedFrequencyBandParameters> frequencyBandParameters, PICK_TYPES selectedPhase) { MdacParametersPS psRows = mdacPS.get(selectedPhase); Map<Event, Map<FrequencyBand, Map<Station, SpectraMeasurement>>> evidFreqBandStaMeasurementsMap = mapToEventAndStation(dataByFreqBand); Map<Event, Function<Map<Double, Double>, SortedMap<Double, Double>>> weightFunctionMapByEvent = new HashMap<>(); Map<Station, Map<FrequencyBand, SummaryStatistics>> staFreqBandSiteCorrectionMapReferenceEvents = new HashMap<>(); Map<Event, Map<FrequencyBand, SummaryStatistics>> averageMapByEvent = new HashMap<>(); Map<Station, Map<FrequencyBand, SummaryStatistics>> staFreqBandSiteCorrectionMapAverage = new HashMap<>(); Map<FrequencyBand, Map<Station, SiteFrequencyBandParameters>> siteCorrections = new HashMap<>(); boolean hasGtSpectra = refMws.values().stream().flatMap(refs -> refs.stream()).filter(ref -> ref.getRefApparentStressInMpa() != null).anyMatch(ref -> ref.getRefApparentStressInMpa() > 0.0); for (Entry<Event, Map<FrequencyBand, Map<Station, SpectraMeasurement>>> evidFreqMap : evidFreqBandStaMeasurementsMap.entrySet()) { Event evid = evidFreqMap.getKey(); if (refMws != null && refMws.containsKey(evid.getEventId())) { List<ReferenceMwParameters> refMwsParams = refMws.get(evid.getEventId()); ReferenceMwParameters refMw = refMwsParams.stream().findFirst().orElse(null); if (refMw != null) { double mw = refMw.getRefMw(); boolean evidHasSpectra = false; MdacParametersFI mdacFiEntry = new MdacParametersFI(mdacFI); if (refMw.getRefApparentStressInMpa() != null && refMw.getRefApparentStressInMpa() != 0.0) { mdacFiEntry.setSigma(refMw.getRefApparentStressInMpa()); mdacFiEntry.setPsi(0.0); weightFunctionMapByEvent.put(evid, this::evenWeights); evidHasSpectra = true; } else if (serviceConfig.isSpectraTruncationEnabled() && hasGtSpectra) { mdacFiEntry.setSigma(ARBITRARY_LOW_STRESS_SIGMA); weightFunctionMapByEvent.put(evid, this::evenWeights); } Function<Double, double[]> mdacFunc = mdac.getCalculateMdacSourceSpectraFunction(psRows, mdacFiEntry, mw); double cornerFreq = 0.0; if (hasGtSpectra && !evidHasSpectra) { cornerFreq = mdac.getCornerFrequency(mdacFunc); } for (Entry<FrequencyBand, Map<Station, SpectraMeasurement>> freqStaMap : evidFreqMap.getValue().entrySet()) { FrequencyBand freqBand = freqStaMap.getKey(); Double lowFreq = freqBand.getLowFrequency(); Double highFreq = freqBand.getHighFrequency(); if (serviceConfig.isSpectraTruncationEnabled() && cornerFreq > 0.0 && highFreq > cornerFreq) { continue; } double centerFreq = (highFreq + lowFreq) / 2; double[] refSpectra = mdacFunc.apply(centerFreq); for (Entry<Station, SpectraMeasurement> staMwEntry : freqStaMap.getValue().entrySet()) { double amp = staMwEntry.getValue().getPathCorrected(); if (!staFreqBandSiteCorrectionMapReferenceEvents.containsKey(staMwEntry.getKey())) { staFreqBandSiteCorrectionMapReferenceEvents.put(staMwEntry.getKey(), new HashMap<FrequencyBand, SummaryStatistics>()); } if (!staFreqBandSiteCorrectionMapReferenceEvents.get(staMwEntry.getKey()).containsKey(freqBand)) { staFreqBandSiteCorrectionMapReferenceEvents.get(staMwEntry.getKey()).put(freqBand, new SummaryStatistics()); } double refAmp = Math.log10(refSpectra[1]) + DYNE_LOG10_ADJUSTMENT; double ampDiff = refAmp - amp; staFreqBandSiteCorrectionMapReferenceEvents.get(staMwEntry.getKey()).get(freqBand).addValue(ampDiff); } } } } weightFunctionMapByEvent.putIfAbsent(evid, this::lowerFreqHigherWeights); } for (Entry<Event, Map<FrequencyBand, Map<Station, SpectraMeasurement>>> evidFreqMap : evidFreqBandStaMeasurementsMap.entrySet()) { Event evid = evidFreqMap.getKey(); for (Entry<FrequencyBand, Map<Station, SpectraMeasurement>> freqStaMap : evidFreqMap.getValue().entrySet()) { FrequencyBand freqBand = freqStaMap.getKey(); for (Entry<Station, SpectraMeasurement> staMwEntry : freqStaMap.getValue().entrySet()) { if (staFreqBandSiteCorrectionMapReferenceEvents.containsKey(staMwEntry.getKey()) && staFreqBandSiteCorrectionMapReferenceEvents.get(staMwEntry.getKey()).containsKey(freqBand)) { double amp = staMwEntry.getValue().getPathCorrected(); if (!averageMapByEvent.containsKey(evid)) { averageMapByEvent.put(evid, new HashMap<FrequencyBand, SummaryStatistics>()); } if (!averageMapByEvent.get(evid).containsKey(freqBand)) { averageMapByEvent.get(evid).put(freqBand, new SummaryStatistics()); } double refAmp = amp + staFreqBandSiteCorrectionMapReferenceEvents.get(staMwEntry.getKey()).get(freqBand).getMean(); averageMapByEvent.get(evid).get(freqBand).addValue(refAmp); } } } } for (Entry<Event, Map<FrequencyBand, Map<Station, SpectraMeasurement>>> evidFreqMap : evidFreqBandStaMeasurementsMap.entrySet()) { Event evid = evidFreqMap.getKey(); for (Entry<FrequencyBand, Map<Station, SpectraMeasurement>> freqStaMap : evidFreqMap.getValue().entrySet()) { FrequencyBand freqBand = freqStaMap.getKey(); if (averageMapByEvent.containsKey(evid) && averageMapByEvent.get(evid).containsKey(freqBand)) { for (Entry<Station, SpectraMeasurement> staMwEntry : freqStaMap.getValue().entrySet()) { double amp = staMwEntry.getValue().getPathCorrected(); if (!staFreqBandSiteCorrectionMapAverage.containsKey(staMwEntry.getKey())) { staFreqBandSiteCorrectionMapAverage.put(staMwEntry.getKey(), new HashMap<FrequencyBand, SummaryStatistics>()); } if (!staFreqBandSiteCorrectionMapAverage.get(staMwEntry.getKey()).containsKey(freqBand)) { staFreqBandSiteCorrectionMapAverage.get(staMwEntry.getKey()).put(freqBand, new SummaryStatistics()); } double refAmp = averageMapByEvent.get(evid).get(freqBand).getMean(); double ampDiff = refAmp - amp; staFreqBandSiteCorrectionMapAverage.get(staMwEntry.getKey()).get(freqBand).addValue(ampDiff); } } } } averageMapByEvent.clear(); for (Entry<Event, Map<FrequencyBand, Map<Station, SpectraMeasurement>>> evidFreqMap : evidFreqBandStaMeasurementsMap.entrySet()) { Event evid = evidFreqMap.getKey(); for (Entry<FrequencyBand, Map<Station, SpectraMeasurement>> freqStaMap : evidFreqMap.getValue().entrySet()) { FrequencyBand freqBand = freqStaMap.getKey(); for (Entry<Station, SpectraMeasurement> staMwEntry : freqStaMap.getValue().entrySet()) { if (staFreqBandSiteCorrectionMapAverage.containsKey(staMwEntry.getKey()) && staFreqBandSiteCorrectionMapAverage.get(staMwEntry.getKey()).containsKey(freqBand)) { double amp = staMwEntry.getValue().getPathCorrected(); if (!averageMapByEvent.containsKey(evid)) { averageMapByEvent.put(evid, new HashMap<FrequencyBand, SummaryStatistics>()); } if (!averageMapByEvent.get(evid).containsKey(freqBand)) { averageMapByEvent.get(evid).put(freqBand, new SummaryStatistics()); } double refAmp = amp + staFreqBandSiteCorrectionMapAverage.get(staMwEntry.getKey()).get(freqBand).getMean(); averageMapByEvent.get(evid).get(freqBand).addValue(refAmp); } } } } for (Entry<Station, Map<FrequencyBand, SummaryStatistics>> freqBandCorrectionMap : staFreqBandSiteCorrectionMapAverage.entrySet()) { Station station = freqBandCorrectionMap.getKey(); Set<Entry<FrequencyBand, SummaryStatistics>> bandEntries = freqBandCorrectionMap.getValue().entrySet(); for (Entry<FrequencyBand, SummaryStatistics> freqBandEntry : bandEntries) { SiteFrequencyBandParameters siteParam = new SiteFrequencyBandParameters(); siteParam.setStation(station); siteParam.setHighFrequency(freqBandEntry.getKey().getHighFrequency()); siteParam.setLowFrequency(freqBandEntry.getKey().getLowFrequency()); siteParam.setSiteTerm(freqBandEntry.getValue().getMean()); if (!siteCorrections.containsKey(freqBandEntry.getKey())) { siteCorrections.put(freqBandEntry.getKey(), new HashMap<>()); } siteCorrections.get(freqBandEntry.getKey()).put(station, siteParam); } } overwriteSiteParams(siteCorrections); List<MeasuredMwParameters> measuredMws = spectraCalc.measureMws(averageMapByEvent, weightFunctionMapByEvent, selectedPhase, psRows, mdacFI); overwriteMeasuredMws(measuredMws); return siteCorrections; } @Autowired  SiteCalibrationServiceImpl(ServiceConfig serviceConfig, MdacCalculatorService mdac, SiteFrequencyBandParametersService siteParamsService, MeasuredMwsService measuredMwsService,
            SpectraCalculator spectraCalc); @Override List<MeasuredMwParameters> fitMws(Map<FrequencyBand, List<SpectraMeasurement>> dataByFreqBand, MdacParametersFI mdacFI, Map<PICK_TYPES, MdacParametersPS> mdacPS,
            Map<String, List<ReferenceMwParameters>> refMws, Map<FrequencyBand, Map<Station, SiteFrequencyBandParameters>> stationFrequencyBandParameters, PICK_TYPES selectedPhase); @Override Map<FrequencyBand, Map<Station, SiteFrequencyBandParameters>> measureSiteCorrections(Map<FrequencyBand, List<SpectraMeasurement>> dataByFreqBand, MdacParametersFI mdacFI,
            Map<PICK_TYPES, MdacParametersPS> mdacPS, Map<String, List<ReferenceMwParameters>> refMws, Map<FrequencyBand, SharedFrequencyBandParameters> frequencyBandParameters,
            PICK_TYPES selectedPhase); static Map<Event, Map<FrequencyBand, Map<Station, SpectraMeasurement>>> mapToEventAndStation(Map<FrequencyBand, List<SpectraMeasurement>> dataByFreqBand); MdacCalculatorService getMdac(); SiteCalibrationServiceImpl setMdac(MdacCalculatorService mdac); SiteFrequencyBandParametersService getSiteParamsService(); SiteCalibrationServiceImpl setSiteParamsService(SiteFrequencyBandParametersService siteParamsService); MeasuredMwsService getMeasuredMwsService(); SiteCalibrationServiceImpl setMeasuredMwsService(MeasuredMwsService measuredMwsService); SpectraCalculator getSpectraCalc(); SiteCalibrationServiceImpl setSpectraCalc(SpectraCalculator spectraCalc); ServiceConfig getServiceConfig(); SiteCalibrationServiceImpl setServiceConfig(ServiceConfig serviceConfig);  }
@Test public void testSiteCorrectionsOneStationEvent() throws Exception { Waveform w1 = createWaveform(); Waveform w2 = createWaveform(); w2.getEvent().setEventId("2345"); Waveform w3 = createWaveform(); w3.getEvent().setEventId("2345"); w3.getStream().getStation().setStationName("InvalidEventStation"); Waveform w4 = createWaveform(); w4.getEvent().setEventId("3456"); w4.getStream().getStation().setStationName("InvalidEventStation"); SpectraMeasurement sm = new SpectraMeasurement(); sm.setWaveform(w1); sm.setPathCorrected(1d); sm.setRawAtMeasurementTime(1d); sm.setRawAtStart(1d); SpectraMeasurement sm2 = new SpectraMeasurement(); sm2.setWaveform(w2); sm2.setPathCorrected(1d); sm2.setRawAtMeasurementTime(1d); sm2.setRawAtStart(1d); SpectraMeasurement sm3 = new SpectraMeasurement(); sm3.setWaveform(w3); sm3.setPathCorrected(1d); sm3.setRawAtMeasurementTime(1d); sm3.setRawAtStart(1d); SpectraMeasurement sm4 = new SpectraMeasurement(); sm4.setWaveform(w4); sm4.setPathCorrected(1d); sm4.setRawAtMeasurementTime(1d); sm4.setRawAtStart(1d); List<SpectraMeasurement> spectra = new ArrayList<>(1); spectra.add(sm); spectra.add(sm2); spectra.add(sm3); spectra.add(sm4); Map<FrequencyBand, List<SpectraMeasurement>> spectraMap = new HashMap<>(); spectraMap.put(new FrequencyBand(0d, 1d), spectra); Map<PICK_TYPES, MdacParametersPS> mdacPsMap = new HashMap<>(); mdacPsMap.put(PICK_TYPES.LG, new MdacParametersPS()); Map<FrequencyBand, SharedFrequencyBandParameters> frequencyBandParameterMap = new HashMap<>(); frequencyBandParameterMap.put(new FrequencyBand(0d, 1d), new SharedFrequencyBandParameters()); Map<String, List<ReferenceMwParameters>> refEventMap = new HashMap<>(); refEventMap.put("1234", Collections.singletonList(new ReferenceMwParameters().setRefMw(5d).setEventId("1234"))); Map<FrequencyBand, Map<Station, SiteFrequencyBandParameters>> results = siteCalibrationServiceImpl.measureSiteCorrections( spectraMap, new MdacParametersFI(), mdacPsMap, refEventMap, frequencyBandParameterMap, PICK_TYPES.LG); assertEquals(1, results.size(), "Should have one frequency band"); Map<Station, SiteFrequencyBandParameters> stations = results.values().stream().findFirst().get(); assertEquals(2, stations.size(), "Should have two stations"); assertTrue(stations.values().stream().allMatch(sfb -> sfb.getSiteTerm() == 6.0), "Both stations should have the same site term"); }