package org.opensha2; import static com.google.common.base.StandardSystemProperty.LINE_SEPARATOR; import org.opensha2.gmm.Gmm; import org.opensha2.gmm.GmmInput; import org.opensha2.gmm.GroundMotionModel; import org.opensha2.gmm.Imt; import org.opensha2.gmm.ScalarGroundMotion; import com.google.common.collect.ImmutableList; import com.google.common.collect.Maps; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Set; /** * Entry point for computing deterministic response spectra. * * <p>In addition to a {@code main()} method, several utility methods are * provided for different target users. For instance * {@link #groundMotion(Gmm, Imt, GmmInput)} and * {@link #spectrum(Gmm, GmmInput)} are convenient for use within Matlab as they * return simple data container objects that are automatically converted to * Matlab structs and arrays. {@link #spectra(Set, GmmInput, boolean)} returns a * more complex result and is for use with web services. * * @author Peter Powers */ public class ResponseSpectra { private static final double PGA_PERIOD = 0.001; /** * Compute the median ground motion and its standard deviation for a specified * {@link GroundMotionModel}, intensity measure type ({@link Imt} ), and * source and site parameterization ({@link GmmInput}). * * <p>{@code enum} types are identified in matlab as e.g. {@link Gmm#ASK_14}. * * @param model to use * @param imt intensity measure type (e.g. {@code PGA}, {@code SA1P00}) * @param source and site parameterization * @return a two-element double[] containing the natural log of the median * ground motion and its standard deviation */ public static double[] groundMotion(Gmm model, Imt imt, GmmInput source) { ScalarGroundMotion sgm = model.instance(imt).calc(source); return new double[] { sgm.mean(), sgm.sigma() }; } /** * Compute a spectrum of ground motions and their standard deviations for a * specified {@link GroundMotionModel} and source and site parameterization ( * {@link GmmInput}). All spectral periods supported by the model are * returned. * * <p>This method is intended for use with Matlab, which converts * {@code Result} to a struct automatically. * * <p>{@code enum} types are identified in matlab as e.g. {@link Gmm#ASK_14}. * * @param model to use * @param input source and site parameterization * @return a Result */ public static Result spectrum(Gmm model, GmmInput input) { Set<Imt> imts = model.responseSpectrumIMTs(); Result spectrum = new Result(imts.size()); int i = 0; for (Imt imt : imts) { ScalarGroundMotion sgm = model.instance(imt).calc(input); spectrum.periods[i] = imt.period(); spectrum.means[i] = sgm.mean(); spectrum.sigmas[i] = sgm.sigma(); i++; } return spectrum; } /** The result produced by calling {@link #spectrum(Gmm, GmmInput)}. */ public static class Result { /** Spectral periods. */ public final double[] periods; /** Ground motion means. */ public final double[] means; /** Ground motion sigmas. */ public final double[] sigmas; Result(int size) { periods = new double[size]; means = new double[size]; sigmas = new double[size]; } } /** * Compute the spectra of ground motions and their standard deviations for * multiple models and a source. This method provides the option to compute * ground motion values either for the set of common spectral accelerations * supported by the {@link Gmm}s specified, or for every spectral acceleration * supported by each {@link Gmm}. PGA is included in the results with a * spectral period of 0.001s. * * @param gmms {@code GroundMotionModel}s to use * @param input source and site parameterization * @param commonImts {@code true} if only ground motions corresponding to the * spectral accelerations common to all {@code gmms} should be * computed; {@code false} if all spectral accelerations supported by * each gmm should be used. * @return a {@link MultiResult} data container */ public static MultiResult spectra(Set<Gmm> gmms, GmmInput input, boolean commonImts) { Map<Gmm, List<Double>> periodMap = Maps.newEnumMap(Gmm.class); Map<Gmm, List<Double>> meanMap = Maps.newEnumMap(Gmm.class); Map<Gmm, List<Double>> sigmaMap = Maps.newEnumMap(Gmm.class); /* * NOTE: At present, program assumes that all supplied Gmms support PGA. * Although most currently implemented models do, this may not be the case * in the future and program may produce unexpected results. */ /* Common imts and periods; may not be used. */ Set<Imt> saImts = Gmm.responseSpectrumIMTs(gmms); ImmutableList<Double> periods = ImmutableList.<Double> builder() .add(PGA_PERIOD) .addAll(Imt.periods(saImts)) .build(); for (Gmm gmm : gmms) { if (!commonImts) { saImts = gmm.responseSpectrumIMTs(); periods = ImmutableList.<Double> builder() .add(PGA_PERIOD) .addAll(Imt.periods(saImts)) .build(); } ImmutableList.Builder<Double> means = ImmutableList.builder(); ImmutableList.Builder<Double> sigmas = ImmutableList.builder(); ScalarGroundMotion pgaGm = gmm.instance(Imt.PGA).calc(input); means.add(pgaGm.mean()); sigmas.add(pgaGm.sigma()); for (Imt imt : saImts) { ScalarGroundMotion sgm = gmm.instance(imt).calc(input); means.add(sgm.mean()); sigmas.add(sgm.sigma()); } periodMap.put(gmm, periods); meanMap.put(gmm, means.build()); sigmaMap.put(gmm, sigmas.build()); } return new MultiResult( Maps.immutableEnumMap(periodMap), Maps.immutableEnumMap(meanMap), Maps.immutableEnumMap(sigmaMap)); } /** The result of calling {@link #spectra(Set, GmmInput, boolean)}. */ public static class MultiResult { /** Spectral periods. */ public final Map<Gmm, List<Double>> periods; /** Map of ground motion means. */ public final Map<Gmm, List<Double>> means; /** Map of ground motion sigmas. */ public final Map<Gmm, List<Double>> sigmas; MultiResult( Map<Gmm, List<Double>> periods, Map<Gmm, List<Double>> means, Map<Gmm, List<Double>> sigmas) { this.periods = periods; this.means = means; this.sigmas = sigmas; } } /** * Entry point for computing deterministic response spectra from the command * line. Quite a few arguments are required to specify the GroundMotionModel * to use and parameterize the earthquake source and site of interest. Example * usage: * * <pre> * java -cp nshmp-haz.jar org.opensha.programs.DeterministicSpectra ... * ... ASK_14 6.5 10.0 10.3 10.0 90.0 14.0 0.5 7.5 0.0 760.0 true NaN NaN * </pre> * * @param args * {@code [Gmm mag rJB rRup rX dip width zTop zHyp rake vs30 vsInf z1p0 z2p5]} */ public static void main(String[] args) { String result = calcMain(args); System.out.println(result); System.exit(0); } private static String calcMain(String[] args) { if (args.length != 14) { System.err.println(USAGE); System.exit(1); } Gmm gmm = Gmm.valueOf(args[0]); GmmInput input = GmmInput.builder() .mag(Double.valueOf(args[1])) .rJB(Double.valueOf(args[2])) .rRup(Double.valueOf(args[3])) .rX(Double.valueOf(args[4])) .dip(Double.valueOf(args[5])) .width(Double.valueOf(args[6])) .zTop(Double.valueOf(args[7])) .zHyp(Double.valueOf(args[8])) .rake(Double.valueOf(args[9])) .vs30(Double.valueOf(args[10])) .vsInf(Boolean.valueOf(args[11])) .z1p0(Double.valueOf(args[12])) .z2p5(Double.valueOf(args[13])) .build(); Result result = spectrum(gmm, input); StringBuilder sb = new StringBuilder(); sb.append("periods=").append(Arrays.toString(result.periods)); sb.append(LINE_SEPARATOR.value()); sb.append("means=").append(Arrays.toString(result.means)); sb.append(LINE_SEPARATOR.value()); sb.append("sigmas=").append(Arrays.toString(result.sigmas)); return sb.toString(); } private static final String USAGE = "DeterministicSpectra usage:" + LINE_SEPARATOR.value() + LINE_SEPARATOR.value() + "command: java -cp nshmp-haz.jar org.opensha.programs.DeterministicSpectra Gmm mag rJB rRup rX dip width zTop zHyp rake vs30 vsInf z1p0 z2p5" + LINE_SEPARATOR.value() + "example: java -cp nshmp-haz.jar org.opensha.programs.DeterministicSpectra ASK_14 6.5 10.0 10.3 10.0 90.0 14.0 0.5 7.5 0.0 760.0 true NaN NaN" + LINE_SEPARATOR.value() + LINE_SEPARATOR.value() + " - For more details, see: http://usgs.github.io/nshmp-haz/docs/org/opensha2/programs/DeterministicSpectra.html"; }