package org.opensha2.gmm; import static com.google.common.math.DoubleMath.fuzzyEquals; import com.google.common.collect.Lists; import java.util.Collection; import java.util.EnumSet; import java.util.List; import java.util.Set; /** * Intesity measure type (Imt) identifiers. {@code SA0P1} stands for spectal * acceleration of 0.1 seconds. * @author Peter Powers */ @SuppressWarnings("javadoc") public enum Imt { PGA, PGV, PGD, ASI, SI, DSI, CAV, DS575, DS595, AI, SA0P01, SA0P02, SA0P025, SA0P03, SA0P04, SA0P05, SA0P075, SA0P08, SA0P1, SA0P12, SA0P15, SA0P17, SA0P2, SA0P25, SA0P3, SA0P4, SA0P5, SA0P6, SA0P7, SA0P75, SA0P8, SA0P9, SA1P0, SA1P25, SA1P5, SA2P0, SA2P5, SA3P0, SA4P0, SA5P0, SA6P0, SA7P5, SA10P0; @Override public String toString() { switch (this) { case PGA: return "Peak ground acceleration"; case PGV: return "Peak ground velocity"; case PGD: return "Peak ground displacement"; case AI: return "Arias intensity"; case ASI: return "Acceleration spectrum intensity"; case DSI: return "Displacement spectrum intensity"; case SI: return "Spectrum intensity"; case CAV: return "Cumulative absolute velocity"; case DS575: return "Significant duration 5-75%"; case DS595: return "Significant duration 5-95%"; default: return period() + " sec spectral acceleration"; } } /** * Return the units in which this {@code Imt} is measured. */ public String units() { switch (this) { case PGA: return "g"; case PGV: return "cm/s"; case PGD: return "cm"; case AI: return "m/s"; case ASI: return "g⋅s"; case DSI: return "cm⋅s"; case SI: return "cm⋅s/s"; case CAV: return "g⋅s"; case DS575: return "s"; case DS595: return "s"; default: return "g"; } } /** * Returns the corresponding period or frequency for this {@code Imt} if it * represents a spectral acceleration. * @return the period for this {@code Imt} if it represents a spectral * acceleration, {@code null} otherwise */ public Double period() { // TODO should this throw an IAE instead or return null? if (ordinal() < 10) { return null; } String valStr = name().substring(2).replace("P", "."); return Double.parseDouble(valStr); } /** * Returns the {@code List} of periods for the supplied {@code Imt}s. The * result will be sorted according to the iteration order of the supplied * {@code Collection}. Any non spectral acceleration {@code Imt}s will have * null values in the returned {@code List}. * * @param imts to list periods for * @return a {@code List} of spectral periods * @see #saImts() */ public static List<Double> periods(Collection<Imt> imts) { List<Double> periodList = Lists.newArrayListWithCapacity(imts.size()); for (Imt imt : imts) { periodList.add(imt.period()); } return periodList; } /** * Returns the spectral acceleration {@code Imt} associated with the supplied * period. Due to potential floating point precision problems, this method * internally checks values to within a small tolerance. * @param period for {@code Imt} * @return an {@code Imt}, or {@code null} if no Imt exsists for the supplied * period */ public static Imt fromPeriod(double period) { for (Imt imt : Imt.values()) { if (imt.name().startsWith("SA")) { double saPeriod = imt.period(); if (fuzzyEquals(saPeriod, period, 0.000001)) { return imt; } } } throw new IllegalArgumentException("No corresponding Imt for period:" + period); } /** * Returns the frequency (in Hz) for this {@code Imt}. {@code PGA} returns 100 * Hz, spectral periods return their expected value (1 / period), and * {@code PGV} and {@code PGD} throw exceptions. * @return the frequency associated with this {@code Imt} * @throws UnsupportedOperationException if called on {@code PGV} or * {@code PGD} */ public double frequency() { if (this == PGA) { return 100; } if (this.isSA()) { return 1.0 / period(); } throw new UnsupportedOperationException("frequncy() not supported for PGD, PGV, etc…"); } /** * Returns true if this Imt is some flavor of spectral acceleration. * @return {@code true} if this is a spectral period, {@code false} otherwise */ public boolean isSA() { return ordinal() > 9; } /** * Returns the {@code Set} of spectal acceleration IMTs. * @return the IMTs that represent spectral accelerations */ public static Set<Imt> saImts() { return EnumSet.complementOf(EnumSet.range(PGA, AI)); } /** * Parses the supplied {@code String} into an {@code Imt}; method expects * labels for specifically named intensity measure types ({@code "PGA"}) and * double value {@code String}s for spectral periods ({@code "0.2"}). This * method is <i>not</i> the same as {@link #valueOf(String)}. * @param s {@code String} to parse * @return an {@code Imt}, or {@code null} if supplied {@code String} is * invalid */ public static Imt parseImt(String s) { s = s.trim().toUpperCase(); if (s.equals("PGA") || s.equals("PGV") || s.equals("PGD")) { return Imt.valueOf(s); } try { double period = Double.parseDouble(s); return fromPeriod(period); } catch (NumberFormatException nfe) { return null; } } }