From a63f2c1702cad99fd18264b5b8aee3ef6c1aff4d Mon Sep 17 00:00:00 2001 From: field Date: Mon, 6 Jan 2025 09:59:22 -0700 Subject: [PATCH] Various updates over the last few months. --- .../U3ETAS_LossSimulationAnalysis.java | 2586 +++++++++++++++-- 1 file changed, 2298 insertions(+), 288 deletions(-) diff --git a/src/main/java/scratch/ned/GK_Declustering/U3ETAS_LossSimulationAnalysis.java b/src/main/java/scratch/ned/GK_Declustering/U3ETAS_LossSimulationAnalysis.java index a7ff093..652db80 100644 --- a/src/main/java/scratch/ned/GK_Declustering/U3ETAS_LossSimulationAnalysis.java +++ b/src/main/java/scratch/ned/GK_Declustering/U3ETAS_LossSimulationAnalysis.java @@ -2,49 +2,81 @@ import java.awt.Color; import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; +import java.util.GregorianCalendar; import java.util.HashMap; import java.util.List; +import java.util.Random; import org.apache.commons.math3.distribution.LogNormalDistribution; import org.apache.commons.math3.distribution.PoissonDistribution; import org.apache.commons.math3.random.JDKRandomGenerator; +import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics; import org.dom4j.DocumentException; import org.jfree.data.Range; import org.opensha.commons.data.CSVFile; +import org.opensha.commons.data.Site; import org.opensha.commons.data.TimeSpan; +import org.opensha.commons.data.function.AbstractDiscretizedFunc; import org.opensha.commons.data.function.ArbDiscrEmpiricalDistFunc; import org.opensha.commons.data.function.ArbDiscrEmpiricalDistFunc_3D; import org.opensha.commons.data.function.ArbitrarilyDiscretizedFunc; +import org.opensha.commons.data.function.DefaultXY_DataSet; import org.opensha.commons.data.function.DiscretizedFunc; import org.opensha.commons.data.function.EvenlyDiscretizedFunc; import org.opensha.commons.data.function.HistogramFunction; import org.opensha.commons.data.function.XY_DataSet; +import org.opensha.commons.data.region.CaliforniaRegions; import org.opensha.commons.data.uncertainty.UncertainArbDiscFunc; +import org.opensha.commons.geo.GriddedRegion; +import org.opensha.commons.geo.Location; import org.opensha.commons.geo.LocationUtils; +import org.opensha.commons.geo.Region; +import org.opensha.commons.gui.plot.GeographicMapMaker; import org.opensha.commons.gui.plot.PlotCurveCharacterstics; import org.opensha.commons.gui.plot.PlotLineType; +import org.opensha.commons.gui.plot.PlotSymbol; +import org.opensha.commons.mapping.gmt.elements.GMT_CPT_Files; +import org.opensha.commons.param.Parameter; +import org.opensha.commons.param.ParameterList; import org.opensha.commons.util.ExceptionUtils; +import org.opensha.commons.util.cpt.CPT; +import org.opensha.commons.util.cpt.CPTVal; +import org.opensha.sha.calc.HazardCurveCalculator; +import org.opensha.sha.earthquake.ERF; import org.opensha.sha.earthquake.EqkRupture; import org.opensha.sha.earthquake.ProbEqkRupture; +import org.opensha.sha.earthquake.ProbEqkSource; +import org.opensha.sha.earthquake.calc.ERF_Calculator; import org.opensha.sha.earthquake.calc.recurInterval.LognormalDistCalc; import org.opensha.sha.earthquake.faultSysSolution.FaultSystemSolution; +import org.opensha.sha.earthquake.faultSysSolution.modules.RupMFDsModule; import org.opensha.sha.earthquake.observedEarthquake.ObsEqkRupList; import org.opensha.sha.earthquake.observedEarthquake.ObsEqkRupture; import org.opensha.sha.earthquake.observedEarthquake.Declustering.GardnerKnopoffDeclustering; +import org.opensha.sha.earthquake.param.MagDependentAperiodicityParam; import org.opensha.sha.earthquake.param.ProbabilityModelOptions; import org.opensha.sha.earthquake.param.ProbabilityModelParam; +import org.opensha.sha.faultSurface.FaultSection; import org.opensha.sha.magdist.IncrementalMagFreqDist; import org.opensha.sha.magdist.SummedMagFreqDist; +import com.google.common.base.Preconditions; +import com.google.common.collect.HashBasedTable; import com.google.common.math.Quantiles; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import scratch.UCERF3.erf.ETAS.ETAS_Utils; import scratch.UCERF3.erf.FaultSystemSolutionERF; import scratch.UCERF3.erf.ETAS.ETAS_CatalogIO; import scratch.UCERF3.erf.ETAS.ETAS_CatalogIO.ETAS_Catalog; import scratch.UCERF3.erf.ETAS.ETAS_EqkRupture; -import scratch.UCERF3.erf.ETAS.ETAS_Utils; +import scratch.UCERF3.erf.ETAS.ETAS_SimAnalysisTools; +import scratch.UCERF3.erf.ETAS.ETAS_Simulator; import scratch.UCERF3.erf.ETAS.FaultSystemSolutionERF_ETAS; import scratch.UCERF3.erf.ETAS.launcher.ETAS_Launcher; import scratch.UCERF3.griddedSeismicity.AbstractGridSourceProvider; @@ -65,7 +97,8 @@ public class U3ETAS_LossSimulationAnalysis { // static String catalogsFileName = "/Users/field/Field_Other/CEA_WGCEP/UCERF3/DeclusteringAnalysis/Data/U3ETAS_SimulationData/results_m5_preserve_chain_FullTD_totRateScaleFactor1pt14.bin"; // static String catalogsFileName = "/Users/field/Library/CloudStorage/OneDrive-DOI/Field_Other/CEA_WGCEP/UCERF3/DeclusteringOnHazardAnalysisPaper/OtherStuff/Data/U3ETAS_SimulationData/results_m5_preserve_chain_FullTD_totRateScaleFactor1pt14.bin"; - static String catalogsFileName = "/Users/field/Library/CloudStorage/OneDrive-DOI/Field_Other/CEA_WGCEP/UCERF3/DeclusteringOnLossAnalysisPaper2024/Data/2024_06_06-Start2012_500yr_kCOV1p5_Spontaneous_HistCatalog/results_m5_preserve_chain 1.bin"; + static String catalogsFileName = "/Users/field/Library/CloudStorage/OneDrive-DOI/Field_Other/CEA_WGCEP/UCERF3/DeclusteringOnLossAnalysisPaper2024/Data/2024_06_06-Start2012_500yr_kCOV1p5_Spontaneous_HistCatalog/results_m5_preserve_chain.bin"; + static String catalogsFileName2 = "/Users/field/Library/CloudStorage/OneDrive-DOI/Field_Other/CEA_WGCEP/UCERF3/DeclusteringOnLossAnalysisPaper2024/Data/2024_08_23-Start2012_500yr_kCOV1p5_Spontaneous_HistCatalog/results_m5_preserve_chain.bin"; // mean loss data file static String lossDataCSV_Filename = "/Users/field/Library/CloudStorage/OneDrive-DOI/Field_Other/CEA_WGCEP/UCERF3/DeclusteringOnLossAnalysisPaper2024/Data/average_nth_rup_losses_remapped_m2p5.csv"; @@ -93,13 +126,15 @@ public class U3ETAS_LossSimulationAnalysis { static int numMag = 40; // following are units of 1000 dollars - static double lossCurveLogMin = 0; // 1,000 - static double lossCurveLogMax = 9; // 1 trillion +// static double lossCurveLogMin = 0; // 1,000 +// static double lossCurveLogMax = 9; // 1 trillion + static double lossCurveLogMin = 3; // 1,000 + static double lossCurveLogMax = 12; // 1 trillion static int lossCurveNum = 91; //40; static double lossCurveDelta = (lossCurveLogMax-lossCurveLogMin)/(double)(lossCurveNum-1); - ArbitrarilyDiscretizedFunc curveXvals = getBlankLossCurve(0d); + ArbitrarilyDiscretizedFunc curveXvals = getBlankLossExceedCurve(0d); - LossCOV_Model covModel = LossCOV_Model.PORTER_POWER_LAW_2020_09_01_fixed; + LossCOV_Model covModel = LossCOV_Model.PORTER_POWER_LAW_2020_09_01_DOLLARS; double[] randomLossForEventID; int totalNumEvents; @@ -125,8 +160,10 @@ public U3ETAS_LossSimulationAnalysis(int seed) { // Load catalogs & loss data CSVFile lossDataCSV_File=null; + File[] catFileArray = {new File(catalogsFileName),new File(catalogsFileName2)}; +// File[] catFileArray = {new File(catalogsFileName)}; try { - catalogList = loadCatalogs(new File(catalogsFileName), 5.0, false); + catalogList = loadCatalogs(catFileArray, 5.0, false); lossDataCSV_File = CSVFile.readFile(new File(lossDataCSV_Filename), true); } catch (IOException | DocumentException e) { throw ExceptionUtils.asRuntimeException(e); @@ -150,7 +187,7 @@ public U3ETAS_LossSimulationAnalysis(int seed) { fssIndexForNthRup.put(nthIndex, lossDataCSV_File.getInt(r, 1)); gridCellIndexForNthRup.put(nthIndex, lossDataCSV_File.getInt(r, 2)); magForNthRup.put(nthIndex, lossDataCSV_File.getDouble(r, 3)); - meanLossForNthRup.put(nthIndex, lossDataCSV_File.getDouble(r, 4)); + meanLossForNthRup.put(nthIndex, lossDataCSV_File.getDouble(r, 4)*1000d); lossCOVForNthRup.put(nthIndex, lossDataCSV_File.getDouble(r, 5)); } @@ -177,7 +214,7 @@ public U3ETAS_LossSimulationAnalysis(int seed) { for (ObsEqkRupture obsRup : catalog) { ETAS_EqkRupture rup = (ETAS_EqkRupture)obsRup; int nth = rup.getNthERF_Index(); - double magDiff = Math.abs(rup.getMag()/magForNthRup.get(nth) - 1.0); + double magDiff=Math.abs(rup.getMag()/magForNthRup.get(nth) - 1.0); if(magDiff > 1e-4) throw new RuntimeException("ERROR: mags differ for nth rup: "+nth+"; cat mag = "+rup.getMag()+"; loss-file mag = "+ magForNthRup.get(nth)); if(rup.getFSSIndex() != fssIndexForNthRup.get(nth)) @@ -229,29 +266,36 @@ public void plotMFDs() { mfdList.add(catalogGKdeclMFD); mfdList.add(catalogGKfiltMFD); mfdList.add(catalogSpontaneustMFD); - mfdList.add(erfMFD_TD); - mfdList.add(erfMFD_TimeInd); +// mfdList.add(erfMFD_TD); +// mfdList.add(erfMFD_TimeInd); ArrayList plotChars = new ArrayList(); - plotChars.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 2f, Color.BLUE)); - plotChars.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 2f, Color.RED)); - plotChars.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 2f, Color.BLACK)); - plotChars.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 2f, Color.GREEN)); - plotChars.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 2f, Color.ORANGE)); - plotChars.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 2f, Color.GRAY)); - PlottingUtils.writeAndOrPlotFuncs(mfdList, plotChars, "MFDs", "Mag", "Rate (/yr)", - new Range(5,8.5), new Range(1e-5,2), false, true, null, true); + plotChars.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.RED)); + plotChars.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLUE)); + plotChars.add(new PlotCurveCharacterstics(PlotLineType.DOTTED, 1f, Color.BLUE)); + plotChars.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.GRAY)); + plotChars.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.GREEN)); + plotChars.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.ORANGE)); + File outputDir = new File(dirName+ "/MFD_Figs"); + if(!outputDir.exists()) outputDir.mkdir(); + String fileNamePrefix = dirName+"/MFD_Figs/incrMFD"; + PlottingUtils.writeAndOrPlotFuncs(mfdList, plotChars, "", "Magnitude", "Incremental Rate (per year)", + new Range(5,8.5), new Range(1e-5,2), false, true, fileNamePrefix, true); ArrayList mfdCumList = new ArrayList(); mfdCumList.add(catalogMFD.getCumRateDistWithOffset()); mfdCumList.add(catalogGKdeclMFD.getCumRateDistWithOffset()); mfdCumList.add(catalogGKfiltMFD.getCumRateDistWithOffset()); mfdCumList.add(catalogSpontaneustMFD.getCumRateDistWithOffset()); - mfdCumList.add(erfMFD_TD.getCumRateDistWithOffset()); - mfdCumList.add(erfMFD_TimeInd.getCumRateDistWithOffset()); - PlottingUtils.writeAndOrPlotFuncs(mfdCumList, plotChars, "Cumunlative MFDs", "Mag", "Cumulative Rate (/yr)", - new Range(5,8.5), new Range(1e-5,10), false, true, null, true); +// mfdCumList.add(erfMFD_TD.getCumRateDistWithOffset()); +// mfdCumList.add(erfMFD_TimeInd.getCumRateDistWithOffset()); + fileNamePrefix = dirName+"/MFD_Figs/cumMFD"; + PlottingUtils.writeAndOrPlotFuncs(mfdCumList, plotChars, "", "Magnitude", "Cumulative Rate (per year)", + new Range(5,8.5), new Range(1e-5,10), false, true, fileNamePrefix, true); + + IncrementalMagFreqDist catalogMFD_Ratio = makeMFD(); + catalogMFD_Ratio.setName("catalogMFD_Ratio"); IncrementalMagFreqDist mfdGKdeclMFD_Ratio = makeMFD(); mfdGKdeclMFD_Ratio.setName("mfdGKdeclMFD_Ratio"); IncrementalMagFreqDist mfdGKfiltMFD_Ratio = makeMFD(); @@ -259,16 +303,19 @@ public void plotMFDs() { IncrementalMagFreqDist mfdSpontaneousMFD_Ratio = makeMFD(); mfdSpontaneousMFD_Ratio.setName("mfdSpontaneousMFD_Ratio"); for(int i=0;i ratioList = new ArrayList(); + ratioList.add(catalogMFD_Ratio); ratioList.add(mfdGKdeclMFD_Ratio); ratioList.add(mfdGKfiltMFD_Ratio); ratioList.add(mfdSpontaneousMFD_Ratio); - PlottingUtils.writeAndOrPlotFuncs(ratioList, plotChars, "Incr MFD Ratios", "Mag", "Ratio", - new Range(5,8.5), new Range(0,1), false, false, null, true); + fileNamePrefix = dirName+"/MFD_Figs/mfdRatios"; + PlottingUtils.writeAndOrPlotFuncs(ratioList, plotChars, "", "Magnitude", "Incremental Ratio", + new Range(5,8.5), new Range(0,1), false, false, fileNamePrefix, true); } /** @@ -277,30 +324,46 @@ public void plotMFDs() { public void writeAAL_ValuesBillions() { System.out.println("\nAverage Annual losses (AAL; billion $):"); -// double aal_Catalog = getAveAnnaulLossFromCatalogList(catalogList)/1e6d; -// System.out.println("\tAAL from catalogs: "+(float)aal_Catalog); - double[] stats = getLossStatsFromCatalogList(catalogList, true); - System.out.println("\tAAL from catalogs: "+(float)(stats[0]/1e6d)+"\t(AAL=EventRate*MeanLoss)"); + double aal_Catalog = getAveAnnaulLossFromCatalogList(catalogList)/1e9d; + System.out.println("\nCatalog Stats (based on mean loss per rupture):"); + double[] stats = getLossStatsFromCatalogList(catalogList, false, true); + System.out.println("\tAAL from catalogs: "+(float)(stats[0]/1e9d)+"\t(AAL=EventRate*MeanLoss)"); System.out.println("\t\tEventRate = : "+(float)(stats[1])); - System.out.println("\t\tMeanLoss = : "+(float)(stats[2]/1e6d)); - System.out.println("\t\tMedianLoss = : "+(float)(stats[3]/1e6d)); + System.out.println("\t\tMeanLoss = : "+(float)(stats[2]/1e9d)); + System.out.println("\t\tMedianLoss = : "+(float)(stats[3]/1e9d)); System.out.println("\t\tLossCOV = : "+(float)(stats[4])); - System.out.println("\t\tMinNonZeroLoss = : "+(float)(stats[5]/1e6d)); - System.out.println("\t\tMaxLoss = : "+(float)(stats[6]/1e6d)); + System.out.println("\t\tMinNonZeroLoss = : "+(float)(stats[5]/1e9d)); + System.out.println("\t\tMaxLoss = : "+(float)(stats[6]/1e9d)); System.out.println("\t\tfractZeroLossRups = : "+(float)(stats[7])); - - - - double aal_TD = getAveAnnualLossFromERF(true)/1e6d; // Time Dependent + System.out.println("\t\tAAL from faults = : "+(float)(stats[8]/1e9d)); + System.out.println("\t\tAAL from gridded seismicity = : "+(float)(stats[9]/1e9d)); + System.out.println("\t\tAAL for spontaneous seismicity = : "+(float)(stats[10]/1e9d)); + + // NOT sure why this is so painfully slow; main results are equivalent to above +// System.out.println("\nCatalog Stats (based on random loss from COV):"); +// stats = getLossStatsFromCatalogList(catalogList, true, true); +// System.out.println("\tAAL from catalogs: "+(float)(stats[0]/1e9d)+"\t(AAL=EventRate*MeanLoss)"); +// System.out.println("\t\tEventRate = : "+(float)(stats[1])); +// System.out.println("\t\tMeanLoss = : "+(float)(stats[2]/1e9d)); +// System.out.println("\t\tMedianLoss = : "+(float)(stats[3]/1e9d)); +// System.out.println("\t\tLossCOV = : "+(float)(stats[4])); +// System.out.println("\t\tMinNonZeroLoss = : "+(float)(stats[5]/1e9d)); +// System.out.println("\t\tMaxLoss = : "+(float)(stats[6]/1e9d)); +// System.out.println("\t\tfractZeroLossRups = : "+(float)(stats[7])); +// System.out.println("\t\tAAL from faults = : "+(float)(stats[8]/1e9d)); +// System.out.println("\t\tAAL from gridded seismicity = : "+(float)(stats[9]/1e9d)); + + + double aal_TD = getAveAnnualLossFromERF(true)/1e9d; // Time Dependent if(D) System.out.println("\tAAL from ERF-TD = "+(float)aal_TD); - double aal_TimeInd = getAveAnnualLossFromERF(false)/1e6d; // Time Independent + double aal_TimeInd = getAveAnnualLossFromERF(false)/1e9d; // Time Independent if(D) System.out.println("\tAAL from ERF-TimeInd = "+(float)aal_TimeInd); - double aal_GKdeclCatalog = getAveAnnaulLossFromCatalogList(catalogDeclusteredList)/1e6d; + double aal_GKdeclCatalog = getAveAnnaulLossFromCatalogList(catalogDeclusteredList)/1e9d; System.out.println("\tAAL from GK declustered catalogs: "+(float)aal_GKdeclCatalog+"\n"); - double aal_GKfilteredCatalog = getAveAnnaulLossFromCatalogList(getU3_GK_FilteredCatalog(catalogList))/1e6d; + double aal_GKfilteredCatalog = getAveAnnaulLossFromCatalogList(getU3_GK_FilteredCatalog(catalogList))/1e9d; System.out.println("\tAAL from GK U3 filtered catalogs: "+(float)aal_GKfilteredCatalog+"\n"); @@ -355,15 +418,17 @@ public void plotRupLossVsMagStats(ArrayList catList, boolean rand funcList.get(4).setName("16% fractile"); funcList.get(5).setName("84% fractile"); ArrayList plotChars = new ArrayList(); - plotChars.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 2f, Color.BLUE)); - plotChars.add(new PlotCurveCharacterstics(PlotLineType.DOTTED_AND_DASHED, 2f, Color.BLUE)); - plotChars.add(new PlotCurveCharacterstics(PlotLineType.DOTTED, 2f, Color.BLUE)); - plotChars.add(new PlotCurveCharacterstics(PlotLineType.DOTTED, 2f, Color.BLUE)); - plotChars.add(new PlotCurveCharacterstics(PlotLineType.DASHED, 2f, Color.BLUE)); - plotChars.add(new PlotCurveCharacterstics(PlotLineType.DASHED, 2f, Color.BLUE)); - - PlottingUtils.writeAndOrPlotFuncs(funcList, plotChars, "", "Magnitude", "Mean Loss ($1000)", - new Range(5d,8.5), new Range(1e-2,1e8), false, true, 6d, 5d, null, true); + plotChars.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLUE)); + plotChars.add(new PlotCurveCharacterstics(PlotLineType.DOTTED_AND_DASHED, 1f, Color.BLUE)); + plotChars.add(new PlotCurveCharacterstics(PlotLineType.DOTTED, 1f, Color.BLUE)); + plotChars.add(new PlotCurveCharacterstics(PlotLineType.DOTTED, 1f, Color.BLUE)); + plotChars.add(new PlotCurveCharacterstics(PlotLineType.DASHED, 1f, Color.BLUE)); + plotChars.add(new PlotCurveCharacterstics(PlotLineType.DASHED, 1f, Color.BLUE)); + String fileNamePrefix = dirName+"/LossForAllRupStats"; + if(randomFromCOV) + fileNamePrefix += "RandCOV"; + PlottingUtils.writeAndOrPlotFuncs(funcList, plotChars, "", "Magnitude", "Loss ($)", + new Range(5d,8.5), new Range(1e1,1e11), false, true, 6d, 5d, fileNamePrefix, true); } /** @@ -377,37 +442,54 @@ public void plotRupLossVsMagStats(ArrayList catList, boolean rand * stats[5] = minLoss; // minimum non-zero loss * stats[6] = maxLoss; * stats[7] = fractZeroLosses; // fraction of ruptures that are zero-loss + * stats[8] = AAL from faults + * stats[9] = AAL from gridded seismicity * @param catList * @return stats */ - public double[] getLossStatsFromCatalogList(ArrayList catList, boolean mkPlot) { - HistogramFunction hist = getBlankLossCurveLogX(); - double[] stats = new double[8]; + public double[] getLossStatsFromCatalogList(ArrayList catList, boolean randFromCOV, boolean mkPlot) { + HistogramFunction hist = getBlankLossExceedCurveLogX(); + double[] stats = new double[11]; ArbDiscrEmpiricalDistFunc distFunc = new ArbDiscrEmpiricalDistFunc(); - double aal =0; + double aal=0,aal_faults=0,aal_gridded=0, aal_spontaneous=0; int n=0; +int cat =0; int numZeroLosses = 0; double minLoss = Double.MAX_VALUE, maxLoss=0; for (ObsEqkRupList catalog : catList) { +//cat +=1; +//if(randFromCOV) System.out.println("cat "+cat); for (ObsEqkRupture obsRup : catalog) { n+=1; ETAS_EqkRupture rup = (ETAS_EqkRupture)obsRup; - double rupLoss = meanLossForNthRup.get(rup.getNthERF_Index()); + double rupLoss; + if(randFromCOV) + rupLoss = randomLossForEventID[rup.getID()]; + else + rupLoss = meanLossForNthRup.get(rup.getNthERF_Index()); if(rupLoss==0.0) numZeroLosses+=1; else if(minLoss>rupLoss) minLoss=rupLoss; - if(maxLoss0) + aal_faults +=rupLoss; + else + aal_gridded +=rupLoss; + + if(rup.getGeneration()==0) + aal_spontaneous+=rupLoss; + distFunc.set(rupLoss, 1.0); if(mkPlot) { double log10Loss = Math.log10(rupLoss); if(log10Loss catList, bo stats[5] = minLoss; stats[6] = maxLoss; stats[7] = numZeroLosses/(double)n; + stats[8] = aal_faults/((double)catList.size()*catalogDuration); + stats[9] = aal_gridded/((double)catList.size()*catalogDuration); + stats[10] = aal_spontaneous/((double)catList.size()*catalogDuration); if(Math.abs(stats[1]*stats[2]/stats[0] - 1.0) > 1e-6) throw new RuntimeException("AAL != EventRate*MeanLoss"); @@ -431,20 +516,105 @@ public double[] getLossStatsFromCatalogList(ArrayList catList, bo // double aalTest =0; // for(int i=1;i subCatList = getSubcatalogList(getCatalogs(), 1.0); + ArbDiscrEmpiricalDistFunc distFuncTD = new ArbDiscrEmpiricalDistFunc(); + int counter = -1; + double writeAt = 0.1; + for (ObsEqkRupList catalog : subCatList) { + counter+=1; + double percDone = (double)counter/(double)subCatList.size(); + if(percDone > writeAt) { + System.out.println("percDone: "+(float)percDone); + writeAt+=0.1; + } + double totLoss=0; + for (ObsEqkRupture obsRup : catalog) { + ETAS_EqkRupture rup = (ETAS_EqkRupture)obsRup; + if(randFromCOV) + totLoss += randomLossForEventID[rup.getID()]; + else + totLoss += meanLossForNthRup.get(rup.getNthERF_Index()); + } + distFuncTD.set(totLoss, 1.0); + } + DiscretizedFunc cumDistFuncTD = distFuncTD.getCumDist(); + cumDistFuncTD.scale(1.0/distFuncTD.calcSumOfY_Vals()); + cumDistFuncTD.setName("cumDistFuncTD"); +// for(int i=0;i writeAt) { + System.out.println("percDone: "+(float)percDone); + writeAt+=0.1; + } + double totLoss=0; + for (ObsEqkRupture obsRup : catalog) { + ETAS_EqkRupture rup = (ETAS_EqkRupture)obsRup; + if(randFromCOV) + totLoss += randomLossForEventID[rup.getID()]; + else + totLoss += meanLossForNthRup.get(rup.getNthERF_Index()); + } + distFuncTI.set(totLoss, 1.0); + } + DiscretizedFunc cumDistFuncTI = distFuncTI.getCumDist(); + cumDistFuncTI.scale(1.0/distFuncTI.calcSumOfY_Vals()); + cumDistFuncTI.setName("cumDistFuncTI"); +// for(int i=0;i funcList = new ArrayList(); + funcList.add(cumDistFuncTD); + funcList.add(cumDistFuncTI); + ArrayList plotChars = new ArrayList(); + plotChars.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLUE)); + plotChars.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.RED)); + if(randFromCOV) + PlottingUtils.writeAndOrPlotFuncs(funcList, plotChars, "Cumulative Loss Dist; Random From COV", + "Loss($)", "Cumulative Dist", null, null, false, false, null, true); + else + PlottingUtils.writeAndOrPlotFuncs(funcList, plotChars, "Cumulative Loss Dist; Mean Loss", + "Loss ($)", "Cumulative Dist", null, null, true, false, null, true); + } + + /** * AAL in Billions per year @@ -524,7 +694,7 @@ public double getAveAnnualLossFromERF(boolean timeDep) { } public ArbitrarilyDiscretizedFunc getLossExceedProbCurveFromERF() { - ArbitrarilyDiscretizedFunc lossExceedProbCurve = getBlankLossCurve(1d); + ArbitrarilyDiscretizedFunc lossExceedProbCurve = getBlankLossExceedCurve(1d); if(erf==null) erf = getERF(); erf.getTimeSpan().setDuration(1d); @@ -560,10 +730,10 @@ public ArbitrarilyDiscretizedFunc getLossExceedProbCurveFromERF() { */ public ArrayList testCOV_ModelChangesInAug2024() { LossCOV_Model covModel1 = LossCOV_Model.PORTER_POWER_LAW_2020_09_01_fixed; - ArbitrarilyDiscretizedFunc lossExceedProbCurve = getBlankLossCurve(1d); // + ArbitrarilyDiscretizedFunc lossExceedProbCurve = getBlankLossExceedCurve(1d); // LossCOV_Model covModel2 = LossCOV_Model.PORTER_POWER_LAW_2020_09_01; - ArbitrarilyDiscretizedFunc lossExceedProbCurve2 = getBlankLossCurve(1d); // previous - ArbitrarilyDiscretizedFunc lossExceedProbCurve3 = getBlankLossCurve(1d); // old/wrong distribution + ArbitrarilyDiscretizedFunc lossExceedProbCurve2 = getBlankLossExceedCurve(1d); // previous + ArbitrarilyDiscretizedFunc lossExceedProbCurve3 = getBlankLossExceedCurve(1d); // old/wrong distribution // double l = 1e7; // System.out.println("HERE1: "+covModel1.getCOV(l)); @@ -628,7 +798,7 @@ public ArrayList testCOV_ModelChangesInAug2024() { public ArbitrarilyDiscretizedFunc getLossRateCurveFromERF() { - ArbitrarilyDiscretizedFunc lossRateCurve = getBlankLossCurve(0d); + ArbitrarilyDiscretizedFunc lossRateCurve = getBlankLossExceedCurve(0d); if(erf==null) erf = getERF(); erf.getParameter(ProbabilityModelParam.NAME).setValue(ProbabilityModelOptions.POISSON); @@ -654,7 +824,7 @@ public ArbitrarilyDiscretizedFunc getLossRateCurveFromERF() { public ArbitrarilyDiscretizedFunc getLossRateCurveFromERF_zeroCOV() { - ArbitrarilyDiscretizedFunc lossRateCurve = getBlankLossCurve(0d); + ArbitrarilyDiscretizedFunc lossRateCurve = getBlankLossExceedCurve(0d); if(erf==null) erf = getERF(); erf.getParameter(ProbabilityModelParam.NAME).setValue(ProbabilityModelOptions.POISSON); @@ -680,7 +850,7 @@ public ArbitrarilyDiscretizedFunc getLossRateCurveFromERF_zeroCOV() { public ArbitrarilyDiscretizedFunc getLossRateCurveFromCatalogs(ArrayList catList) { if(D) System.out.println("Working on getLossRateCurveFromCatalogs(); num catalogs = "+catList.size()); - ArbitrarilyDiscretizedFunc lossRateCurve = getBlankLossCurve(0d); + ArbitrarilyDiscretizedFunc lossRateCurve = getBlankLossExceedCurve(0d); for (ObsEqkRupList catalog : catList) { for (ObsEqkRupture obsRup : catalog) { ETAS_EqkRupture rup = (ETAS_EqkRupture)obsRup; @@ -699,7 +869,7 @@ public ArbitrarilyDiscretizedFunc getLossRateCurveFromCatalogs(ArrayList catList) { - ArbitrarilyDiscretizedFunc lossRateCurve = getBlankLossCurve(0d); + ArbitrarilyDiscretizedFunc lossRateCurve = getBlankLossExceedCurve(0d); for (ObsEqkRupList catalog : catList) { for (ObsEqkRupture obsRup : catalog) { ETAS_EqkRupture rup = (ETAS_EqkRupture)obsRup; @@ -717,6 +887,28 @@ public ArbitrarilyDiscretizedFunc getLossRateCurveFromCatalogsZeroCOV(ArrayList< lossRateCurve.scale(1.0/((double)catList.size()*catalogDuration)); return lossRateCurve; } + + + public ArbitrarilyDiscretizedFunc getLossRateCurveFromCatalogsRandomFromCOV(ArrayList catList) { + ArbitrarilyDiscretizedFunc lossRateCurve = getBlankLossExceedCurve(0d); + for (ObsEqkRupList catalog : catList) { + for (ObsEqkRupture obsRup : catalog) { + ETAS_EqkRupture rup = (ETAS_EqkRupture)obsRup; + double loss = randomLossForEventID[rup.getID()]; + if(loss == 0.0) + continue; + for(int i=0;i catList, double duration, double lossExceedThresh) { + + ArrayList subCatList = getSubcatalogList(catList, duration); + + int[] numExceedForCatArray = new int[subCatList.size()]; + int c=-1; + for (ObsEqkRupList catalog : subCatList) { + c+=1; + for (ObsEqkRupture obsRup : catalog) { + ETAS_EqkRupture rup = (ETAS_EqkRupture)obsRup; + double randLoss = randomLossForEventID[rup.getID()]; // covModel.getDistribution(aveLoss).sample(); // get randome sample + if(randLoss>=lossExceedThresh) + numExceedForCatArray[c] += 1; + } + +// // TEMP +// if(numExceedForCatArray[c]>250) { +// for (ObsEqkRupture obsRup : subCatList.get(c-1)) { // previous catalog +// ETAS_EqkRupture rup = (ETAS_EqkRupture)obsRup; +// double aveLoss = meanLossForNthRup.get(rup.getNthERF_Index()); +// if(aveLoss==0) +// continue; +// System.out.println(rup.getMag()+"\t"+rup.getGeneration()+"\tPrevious catalog"); // +"\t"+rup.getOriginTimeCal()); +// } +// for (ObsEqkRupture obsRup : catalog) { // this catalog +// ETAS_EqkRupture rup = (ETAS_EqkRupture)obsRup; +// double aveLoss = meanLossForNthRup.get(rup.getNthERF_Index()); +// if(aveLoss==0) +// continue; +// System.out.println(rup.getMag()+"\t"+rup.getGeneration()); // +"\t"+rup.getOriginTimeCal()); +// } +// System.exit(0); +// } + + + } + + int maxNum = 0, catForMaxNum=-1; + for(c=0;cmaxNum) { + maxNum=num; + catForMaxNum=c; + } + } // System.out.println("maxNum: "+maxNum); HistogramFunction hist = new HistogramFunction(0d,(double)maxNum,maxNum+1); for(int num:numExceedForCatArray) @@ -889,22 +1145,22 @@ public UncertainArbDiscFunc getLossExceedProbCurveFromCatalogsRandomFromCOV(Arra // System.out.println("\nhist.calcSumOfY_Vals():\n"+hist.calcSumOfY_Vals()); hist.normalizeBySumOfY_Vals(); - System.out.println("\nnumExceedPDF:\n"+hist); - - return uncertFunc; + hist.setInfo("maxNum="+maxNum+", which occurred in subCat="+catForMaxNum); +// System.out.println("\nnumExceedPDF: for loss="+lossExceedThresh+"\n"+hist); + + return hist; } - public UncertainArbDiscFunc getLossIncrProbDistFromCatalogsRandomFromCOV(ArrayList catList, double duration) { + public UncertainArbDiscFunc testGetLossExceedProbCurveFromCatalogsRandomFromCOV(ArrayList catList, double duration) { - ArbitrarilyDiscretizedFunc lossProbCurve = getBlankLossCurve(0d); - HistogramFunction lossHistLogX = getBlankLossCurveLogX(); + ArbitrarilyDiscretizedFunc lossProbCurve = getBlankLossExceedCurve(0d); ArrayList subCatList = getSubcatalogList(catList, duration); for (ObsEqkRupList catalog : subCatList) { - ArbitrarilyDiscretizedFunc lossProbCurveForSubCat = getBlankLossCurve(0d); + ArbitrarilyDiscretizedFunc lossProbCurveForSubCat = getBlankLossExceedCurve(1d); double maxLoss = 0; for (ObsEqkRupture obsRup : catalog) { ETAS_EqkRupture rup = (ETAS_EqkRupture)obsRup; @@ -912,24 +1168,137 @@ public UncertainArbDiscFunc getLossIncrProbDistFromCatalogsRandomFromCOV(ArrayLi if(aveLoss==0) continue; double randLoss = randomLossForEventID[rup.getID()]; // covModel.getDistribution(aveLoss).sample(); // get randome sample -// if(maxLosslossProbCurve.getY(i)) { // numerical problem + if(D) System.out.println("ISSUE: Low bound above mean:\nmean="+lossProbCurve.getY(i)+"\nlowBound="+confArray[0]+"\nN="+subCatList.size()); + confArray[0] = 0; + } + low95confCurve.set(xVal,confArray[0]); + high95confCurve.set(xVal,confArray[1]); + } + + UncertainArbDiscFunc uncertFunc = new UncertainArbDiscFunc(lossProbCurve,low95confCurve,high95confCurve); + + return uncertFunc; + } + + + + + public UncertainArbDiscFunc getLossIncrProbDistFromCatalogsRandomFromCOV(ArrayList catList, double duration) { + + // this has offset bin x values by half delta + HistogramFunction lossHistLogX = getBlankIncrLossCurveLogX(); + ArbitrarilyDiscretizedFunc lossProbCurve = getBlankIncrLossCurve(0); + double fracZeroLossSubCats = 0; + ArrayList subCatList = getSubcatalogList(catList, duration); + for (ObsEqkRupList catalog : subCatList) { + ArbitrarilyDiscretizedFunc lossProbCurveForSubCat = getBlankIncrLossCurve(0); + double totLoss = 0; + for (ObsEqkRupture obsRup : catalog) { + ETAS_EqkRupture rup = (ETAS_EqkRupture)obsRup; + double aveLoss = meanLossForNthRup.get(rup.getNthERF_Index()); + if(aveLoss==0) + continue; + double randLoss = randomLossForEventID[rup.getID()]; // covModel.getDistribution(aveLoss).sample(); // get randome sample + totLoss+=randLoss; double log10_Loss = Math.log10(randLoss); - if(log10_Loss<=lossCurveLogMin-lossCurveDelta/2.0) + if(log10_Loss<=lossCurveLogMin) // this is the edge of the first bin continue; +//if(randLoss>6.3095734E10) +// System.out.println("LOSS: "+randLoss); int index = lossHistLogX.getClosestXIndex(log10_Loss); - lossProbCurveForSubCat.set(index, 1); + lossProbCurveForSubCat.set(index, 1); // this ends up 1.0 if one or more occurrences } + if(totLoss==0.0) // this should be good enough to avoid numerical problems + fracZeroLossSubCats+=1; for(int i=0;i getGK_DeclusteredCatalog(ArrayList catalogList) { - - if(D) System.out.println("Declustering Catalogs"); - - ArrayList declusteredList = new ArrayList(); - for(ObsEqkRupList rupList: catalogList) { - ObsEqkRupList declusteredCatalog = GardnerKnopoffDeclustering.getDeclusteredCatalog(rupList); - declusteredList.add(declusteredCatalog); - } - if(D) System.out.println("Done Declustering"); - return declusteredList; - } - /** - * This declusters according to whether it was spontaneous in U3ETAS - * @param catalogList - * @return - */ + public UncertainArbDiscFunc getMagExceedProbCurveFromCatalogs(ArrayList catList, double duration) { + + IncrementalMagFreqDist magExceedProbCurve = makeMFD(); + ArrayList subCatList = getSubcatalogList(catList, duration); + + for (ObsEqkRupList catalog : subCatList) { + IncrementalMagFreqDist magExceedProbCurveForSubCat = makeMFD(); + double maxMag = 0; + for (ObsEqkRupture obsRup : catalog) { + if(obsRup.getMag()>maxMag) + maxMag = obsRup.getMag(); + } + for(int i=0;imagExceedProbCurve.getY(i)) { // numerical problem + if(D) System.out.println("ISSUE: Low bound above mean:\nmean="+magExceedProbCurve.getY(i)+"\nlowBound="+confArray[0]+"\nN="+subCatList.size()); + confArray[0] = 0; + } + low95confCurve.set(xVal,confArray[0]); + high95confCurve.set(xVal,confArray[1]); + } + + UncertainArbDiscFunc uncertFunc = new UncertainArbDiscFunc(magExceedProbCurve,low95confCurve,high95confCurve); + return uncertFunc; + } + + + + + public static ArrayList getGK_DeclusteredCatalog(ArrayList catalogList) { + + if(D) System.out.println("Declustering Catalogs"); + + ArrayList declusteredList = new ArrayList(); + for(ObsEqkRupList rupList: catalogList) { + ObsEqkRupList declusteredCatalog = GardnerKnopoffDeclustering.getDeclusteredCatalog(rupList); + declusteredList.add(declusteredCatalog); + } + if(D) System.out.println("Done Declustering"); + return declusteredList; + } + + + /** + * This declusters according to whether it was spontaneous in U3ETAS + * @param catalogList + * @return + */ public static ArrayList getSpontaneousEventsCatalog(ArrayList catalogList) { ArrayList declusteredList = new ArrayList(); for(ObsEqkRupList rupList: catalogList) { @@ -1102,6 +1566,25 @@ public ArrayList getRandomizedCatalogs() { } return catalogRandomizedList; } + + + /** + * This randomizes a single catalog in case you want it to have the exact same set of events + * @param catalog + * @return + */ + public ObsEqkRupList randomizeCatalog(ObsEqkRupList catalog) { + ObsEqkRupList randCat =new ObsEqkRupList(); + for(ObsEqkRupture rup:catalog) { + long randTimeMillis = startTimeMillis + (long)(randomGen.nextDouble()*fullDurationMillis); + ObsEqkRupture newRup = (ObsEqkRupture) rup.clone(); + newRup.setOriginTime(randTimeMillis); + randCat.add(newRup); + } + randCat.sortByOriginTime(); + return randCat; + } + @@ -1234,6 +1717,37 @@ public static FaultSystemSolutionERF_ETAS getERF() { return erf; } + public ArrayList load1yrConditionalCatalogs() throws IOException, DocumentException { + File[] catalogsFileArray = {new File("/Users/field/Library/CloudStorage/OneDrive-DOI/Field_Other/CEA_WGCEP/UCERF3/DeclusteringOnLossAnalysisPaper2024/Data/2024_10_18_1yrConditionalComCatdata_kCOV1p5_MaxPtSrcM/results_m5_preserve_chain.bin")}; + double minMag=5; + boolean checkAgainstERF =true; + ArrayList oneYrCats = loadCatalogs(catalogsFileArray, minMag, checkAgainstERF); + + // check mags & indices against catalogs + double maxCatLengthYears=0; + for (ObsEqkRupList catalog : oneYrCats) { + if(catalog.size()>1) { + double catLength = ((double)(catalog.get(catalog.size()-1).getOriginTime()-catalog.get(0).getOriginTime()))/(double)millisPerYr; + if(maxCatLengthYears 1e-4) + throw new RuntimeException("ERROR: mags differ for nth rup: "+nth+"; cat mag = "+rup.getMag()+"; loss-file mag = "+ magForNthRup.get(nth)); + if(rup.getFSSIndex() != fssIndexForNthRup.get(nth)) + throw new RuntimeException("ERROR: fss indices differ for nth rup: "+nth+"; cat fssID = "+rup.getFSSIndex()+"; loss-file fssID = "+ fssIndexForNthRup.get(nth)); + if(rup.getGridNodeIndex() != gridCellIndexForNthRup.get(nth)) + throw new RuntimeException("ERROR: grid cell indices differ for nth rup: "+nth+"; cat cellID = "+rup.getGridNodeIndex()+"; loss-file cellID = "+gridCellIndexForNthRup.get(nth)); + } + } + if(D) System.out.println("maxCatLengthYears="+(float)maxCatLengthYears); + + return oneYrCats; + } + /** * The check against the ERF does not work because indexing between ERF and catalogs somehow got screwed up, @@ -1247,10 +1761,11 @@ public static FaultSystemSolutionERF_ETAS getERF() { * @throws IOException * @throws DocumentException */ - public ArrayList loadCatalogs(File catalogsFile, double minMag, boolean checkAgainstERF) throws IOException, DocumentException { + public ArrayList loadCatalogs(File[] catalogsFileArray, double minMag, boolean checkAgainstERF) throws IOException, DocumentException { - - List catalogs = ETAS_CatalogIO.loadCatalogsBinary(catalogsFile, minMag); + ArrayList catalogs = new ArrayList(); + for(File catFile:catalogsFileArray) + catalogs.addAll(ETAS_CatalogIO.loadCatalogsBinary(catFile, minMag)); System.out.println("catalogs.size()="+catalogs.size()); @@ -1396,7 +1911,14 @@ public ArrayList loadCatalogs(File catalogsFile, double minMag, b for (ETAS_Catalog catalog : catalogs) { ObsEqkRupList obsEqkRupList = new ObsEqkRupList(); for (ETAS_EqkRupture rup : catalog) { +//if(id<200 && id>100) +// System.out.println(rup.getEventId()+"\t"+rup.getID()+"\t"+rup.getGeneration()+"\t"+rup.getParentID()); +//if(id==199) +// System.exit(id); + if(rup.getMag()>=minMag) { + // put id in EventID (string) so save the info (this field is presently null) + rup.setEventId(Integer.toString(rup.getID())); id+=1; rup.setID(id); obsEqkRupList.add(rup); @@ -1410,22 +1932,38 @@ public ArrayList loadCatalogs(File catalogsFile, double minMag, b } - private static HistogramFunction getBlankLossCurveLogX() { + private static HistogramFunction getBlankLossExceedCurveLogX() { return new HistogramFunction(lossCurveLogMin, lossCurveLogMax, lossCurveNum); } - private static ArbitrarilyDiscretizedFunc getBlankLossCurve(double initYvalues) { + private static ArbitrarilyDiscretizedFunc getBlankLossExceedCurve(double initYvalues) { ArbitrarilyDiscretizedFunc func = new ArbitrarilyDiscretizedFunc(); - HistogramFunction histFunc = getBlankLossCurveLogX(); + HistogramFunction histFunc = getBlankLossExceedCurveLogX(); for (int i=0; i plotLossRateVsMag() { // meanLossForNthRup.get(nth)*erf.getNthRupture(nth).getMeanAnnualRate(duration)); // } + // Scale by delta so y values so the AAL + lossRate_cat.scale(lossRate_cat.getDelta()); +// lossRate_erf.scale(lossRate_erf.getDelta()); + lossRate_catDecl.scale(lossRate_catDecl.getDelta()); + lossRate_spontaneous.scale(lossRate_spontaneous.getDelta()); + + ArrayList mfdList = new ArrayList(); mfdList.add(lossRate_cat); // mfdList.add(lossRate_erf); mfdList.add(lossRate_catDecl); mfdList.add(lossRate_spontaneous); ArrayList plotChars = new ArrayList(); - plotChars.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 2f, Color.BLUE)); - plotChars.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 2f, Color.BLACK)); - plotChars.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 2f, Color.GREEN)); +// plotChars.add(new PlotCurveCharacterstics(PlotLineType.HISTOGRAM, 1f, Color.RED)); +// plotChars.add(new PlotCurveCharacterstics(PlotLineType.HISTOGRAM, 1f, Color.BLUE)); +// plotChars.add(new PlotCurveCharacterstics(PlotLineType.HISTOGRAM, 1f, Color.GRAY)); + plotChars.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.RED)); + plotChars.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLUE)); + plotChars.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.GRAY)); // new Range(1e3,2e4) - PlottingUtils.writeAndOrPlotFuncs(mfdList, plotChars, "Loss Rate vs Mag", "Mag", "Loss Rate (/yr)", - null, new Range(1e3,2e4), false, true, null, true); + String fileNamePrefix = dirName+"/LossRateVsMag"; + + PlottingUtils.writeAndOrPlotFuncs(mfdList, plotChars, "", "Magnitude", "Loss Rate ($ per year)", + new Range(5.0,8.5), new Range(1e5,2e6), false, true, fileNamePrefix, true); return mfdList; } @@ -1766,13 +2388,13 @@ public static ArrayList old_getSubcatalogList(ArrayList getSubcatalogList(ArrayList catalogList, double subDurationYrs) { long runtime = System.currentTimeMillis(); - long subDurationMillis = millisPerYr*(long)subDurationYrs; + long subDurationMillis = (long)(millisPerYr*subDurationYrs); int numSubCatPerCat = (int)(fullDurationMillis/subDurationMillis); // this should truncate if(D) System.out.println("numSubCatPerCat="+numSubCatPerCat); long remainderMillis = fullDurationMillis - numSubCatPerCat*subDurationMillis; - double remainderYears = (double)remainderMillis/(double)subDurationMillis; - if(D) System.out.println("remainderYears="+remainderYears); + double remainderFraction = (double)remainderMillis/(double)subDurationMillis; + if(D) System.out.println("remainderFraction="+remainderFraction); // numSubCatPerCat = (int)((endTimeMillis-1000-startTimeMillis)/durationMillis); // System.out.println("numSubCatPerCat="+numSubCatPerCat); @@ -1790,9 +2412,9 @@ public ArrayList getSubcatalogList(ArrayList catal subCatList.get(catIndex).add(rup); else { numRupsNotUsed+=1; - if(rup.getOriginTime() funcList = new ArrayList(); - String randCOVincluded = ""; - if(randCOV) - randCOVincluded = " (cond loss PDF for each rup randomly sampled)"; - - if(randCOV) { - UncertainArbDiscFunc lossExceedProbFromTD_CatalogsRandFromCOV = getLossExceedProbCurveFromCatalogsRandomFromCOV(getCatalogs(), 1d); - lossExceedProbFromTD_CatalogsRandFromCOV.setName("lossExceedProbFromTD_CatalogsRandFromCOV"); - UncertainArbDiscFunc lossExceedProbFromPoisCatalogsRandFromCOV = getLossExceedProbCurveFromCatalogsRandomFromCOV(getRandomizedCatalogs(), 1d); - lossExceedProbFromPoisCatalogsRandFromCOV.setName("lossExceedProbFromPoisCatalogsRandFromCOV"); - UncertainArbDiscFunc lossExceedProbFromDeclusteredCatalogsRandFromCOV = getLossExceedProbCurveFromCatalogsRandomFromCOV(getCatalogsDeclustered(), 1d); - lossExceedProbFromDeclusteredCatalogsRandFromCOV.setName("lossExceedProbFromDeclusteredCatalogsRandFromCOV"); - UncertainArbDiscFunc lossExceedProbFromSpontaneousCatalogsRandFromCOV = getLossExceedProbCurveFromCatalogsRandomFromCOV(getSpontaneousEventsCatalog(getCatalogs()), 1d); - lossExceedProbFromSpontaneousCatalogsRandFromCOV.setName("lossExceedProbFromSpontaneousCatalogsRandFromCOV"); - funcList.add(lossExceedProbFromTD_CatalogsRandFromCOV); - funcList.add(lossExceedProbFromPoisCatalogsRandFromCOV); - funcList.add(lossExceedProbFromDeclusteredCatalogsRandFromCOV); - funcList.add(lossExceedProbFromSpontaneousCatalogsRandFromCOV); - } - else { - UncertainArbDiscFunc lossExceedProbFromTD_Catalogs = getLossExceedProbCurveFromCatalogs(getCatalogs(), 1d); - lossExceedProbFromTD_Catalogs.setName("lossExceedProbFromTD_Catalogs"); - UncertainArbDiscFunc lossExceedProbFromPoisCatalogs = getLossExceedProbCurveFromCatalogs(getRandomizedCatalogs(), 1d); - lossExceedProbFromPoisCatalogs.setName("lossExceedProbFromPoisCatalogs"); - UncertainArbDiscFunc lossExceedProbFromDeclusteredCatalogs = getLossExceedProbCurveFromCatalogs(getCatalogsDeclustered(), 1d); - lossExceedProbFromDeclusteredCatalogs.setName("lossExceedProbFromDeclusteredCatalogs"); - UncertainArbDiscFunc lossExceedProbFromSpontaneousCatalogs = getLossExceedProbCurveFromCatalogs(getSpontaneousEventsCatalog(getCatalogs()), 1d); - lossExceedProbFromSpontaneousCatalogs.setName("lossExceedProbFromSpontaneousCatalogs"); - funcList.add(lossExceedProbFromTD_Catalogs); - funcList.add(lossExceedProbFromPoisCatalogs); - funcList.add(lossExceedProbFromDeclusteredCatalogs); - funcList.add(lossExceedProbFromSpontaneousCatalogs); + UncertainArbDiscFunc lossExceedProbFromTD_CatalogsRandFromCOV = getLossExceedProbCurveFromCatalogsRandomFromCOV(getCatalogs(), 1d); + lossExceedProbFromTD_CatalogsRandFromCOV.setName("lossExceedProbFromTD_CatalogsRandFromCOV"); + + + System.out.println("DOING ONE YEAR CATS"); + ArrayList oneYrCondCats=null; + try { + oneYrCondCats = load1yrConditionalCatalogs(); + } catch (IOException e) { + e.printStackTrace(); + } catch (DocumentException e) { + e.printStackTrace(); } - System.out.println("\n1yr Loss for CEA probability levels"+randCOVincluded+":\n"); - System.out.println("Probability\tTD_loss\tTD_uncert\tTI_loss\tTI_uncert\tGK_loss\tGK_uncert\tSP_loss\tSP_uncert"); - System.out.println(getTableStringOfCEA_Values(funcList,true)); - System.out.println("\n1yr Loss ratios, relative to TD, for CEA probability levels"+randCOVincluded+":\n"); - System.out.println("Probability\tTIvsTD_loss\tTIvsTD_uncert\tGKvsTD_loss\tGKvsTD_uncert\tSPvsTD_loss\tSPvsTD_uncert"); - System.out.println(getTableStringOfCEA_Ratios(funcList, true)); - System.out.println("TI = Time Dependent\nTI = Time Independent (Poisson)\nGK = Gardner Knopoff declustered\nSP = Spontaneous ETAS events\nuncert = 1-sigma uncertainty normalized by the mean\n"); - ArrayList plotChars2 = new ArrayList(); - plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 2f, Color.BLUE)); - plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 2f, Color.RED)); - plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 2f, Color.BLACK)); - plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 2f, Color.GREEN)); - String fileNamePrefix = dirName+"/FigureA_Losses"; - if(randCOV) fileNamePrefix += "_randCOV"; - PlottingUtils.writeAndOrPlotUncertFuncs(funcList, plotChars2, "", "Loss ($1000)", "Probability", new Range(1e3,1e9), new Range(1e-6,1.0), true, true, fileNamePrefix, true); - - // Make ratio plots - UncertainArbDiscFunc denomCurve = funcList.get(0); - ArrayList funcListRatios = new ArrayList(); - - double xThresh = denomCurve.getClosestXtoY(1e-3); - for(int i=0;ixThresh) + + // Need to make exceedance curve by hand because method above subdivides catalogs and not sure it will work + double aveYearlyLoss=0; + ArbitrarilyDiscretizedFunc lossProbCurve = getBlankLossExceedCurve(0d); + for (ObsEqkRupList catalog : oneYrCondCats) { + double lossSum=0; + ArbitrarilyDiscretizedFunc lossProbCurveForSubCat = getBlankLossExceedCurve(0d); + double maxLoss = 0; + for (ObsEqkRupture obsRup : catalog) { + ETAS_EqkRupture rup = (ETAS_EqkRupture)obsRup; + double aveLoss = meanLossForNthRup.get(rup.getNthERF_Index()); + if(aveLoss==0) + continue; + double randLoss = randomLossForEventID[rup.getID()]; // covModel.getDistribution(aveLoss).sample(); // get randome sample + if(maxLoss1e9) ratio = 1e-9; - ratioCurve.set(denomCurve.getX(j), ratio); } - funcListRatios.add(ratioCurve); - } - fileNamePrefix = dirName+"/FigureA_LossRatios"; - if(randCOV) fileNamePrefix += "_randCOV"; - PlottingUtils.writeAndOrPlotFuncs(funcListRatios, plotChars2, "test", "Loss ($1000)", "Loss Ratio", new Range(1e3,xThresh), new Range(0.0,2.0), true, false, fileNamePrefix, true); - - ArrayList pdfList = new ArrayList(); - for(int i=0;i<2;i++) { - pdfList.add(convertExceedCurveToLog10_PDF_Hist(funcList.get(i))); + for(int i=0;ilossProbCurve.getY(i)) { // numerical problem + if(D) System.out.println("ISSUE: Low bound above mean:\nmean="+lossProbCurve.getY(i)+"\nlowBound="+confArray[0]+"\nN="+oneYrCondCats.size()); + confArray[0] = 0; + } + low95confCurve.set(xVal,confArray[0]); + high95confCurve.set(xVal,confArray[1]); } - PlottingUtils.writeAndOrPlotFuncs(pdfList, plotChars2, "", "Loss ($1000)", "Probability", null, null, false, false, null, true); - - } - - - - - public void makeFigAndTableSetB_1yr_Exceedances() { + UncertainArbDiscFunc oneYrCondExceedUncertFunc = new UncertainArbDiscFunc(lossProbCurve,low95confCurve,high95confCurve); + oneYrCondExceedUncertFunc.setName("oneYrCondExceedUncertFunc"); - ArrayList funcList = new ArrayList(); + funcList.add(lossExceedProbFromTD_CatalogsRandFromCOV); + funcList.add(oneYrCondExceedUncertFunc); - boolean randCOV = true; - String randCOVincluded = ""; - if(randCOV) - randCOVincluded = " (cond loss PDF for each rup randomly sampled)"; - - UncertainArbDiscFunc aggrLossExceedProbFromTD_CatalogsRandFromCOV = getAggrLossExceedProbCurveFromCatalogsRandomFromCOV(getCatalogs(), 1d); - aggrLossExceedProbFromTD_CatalogsRandFromCOV.setName("aggrLossExceedProbFromTD_CatalogsRandFromCOV"); - UncertainArbDiscFunc aggrLossExceedProbFromPoisCatalogsRandFromCOV = getAggrLossExceedProbCurveFromCatalogsRandomFromCOV(getRandomizedCatalogs(), 1d); - aggrLossExceedProbFromPoisCatalogsRandFromCOV.setName("aggrLossExceedProbFromPoisCatalogsRandFromCOV"); - UncertainArbDiscFunc aggrLossExceedProbFromDeclusteredCatalogsRandFromCOV = getAggrLossExceedProbCurveFromCatalogsRandomFromCOV(getCatalogsDeclustered(), 1d); - aggrLossExceedProbFromDeclusteredCatalogsRandFromCOV.setName("aggrLossExceedProbFromDeclusteredCatalogsRandFromCOV"); - UncertainArbDiscFunc aggrLossExceedProbFromSpontaneousCatalogsRandFromCOV = getAggrLossExceedProbCurveFromCatalogsRandomFromCOV(getSpontaneousEventsCatalog(getCatalogs()), 1d); - aggrLossExceedProbFromSpontaneousCatalogsRandFromCOV.setName("aggrLossExceedProbFromSpontaneousCatalogsRandFromCOV"); - funcList.add(aggrLossExceedProbFromTD_CatalogsRandFromCOV); - funcList.add(aggrLossExceedProbFromPoisCatalogsRandFromCOV); - funcList.add(aggrLossExceedProbFromDeclusteredCatalogsRandFromCOV); - funcList.add(aggrLossExceedProbFromSpontaneousCatalogsRandFromCOV); + // Write tables + String tableString = ""; + tableString += "\n1yr Loss for CEA probability levels (cond loss PDF for each rup randomly sampled):\n"+"\n"; + tableString += "Probability\tTD_loss\tTD_uncert\tCond2024_loss\tCond2024_uncert"+"\n"; + tableString += getTableStringOfCEA_Values(funcList,true)+"\n"; + tableString += "\n1yr Loss ratios, relative to TD, for CEA probability levels (cond loss PDF for each rup randomly sampled):\n"+"\n"; + tableString += "Probability\tCond2024_loss\tCond2024_uncert"+"\n"; + tableString += getTableStringOfCEA_Ratios(funcList, true)+"\n"; + System.out.println(tableString); + oneYrCondExceedUncertFunc.setInfo("2024 Expected Loss = "+aveYearlyLoss+"\n\n"+tableString); - System.out.println("\n1yr Loss for CEA probability levels"+randCOVincluded+":\n"); - System.out.println("Probability\tTD_loss\tTD_uncert\tTI_loss\tTI_uncert\tGK_loss\tGK_uncert\tSP_loss\tSP_uncert"); - System.out.println(getTableStringOfCEA_Values(funcList,true)); - System.out.println("\n1yr Loss ratios, relative to TD, for CEA probability levels"+randCOVincluded+":\n"); - System.out.println("Probability\tTIvsTD_loss\tTIvsTD_uncert\tGKvsTD_loss\tGKvsTD_uncert\tSPvsTD_loss\tSPvsTD_uncert"); - System.out.println(getTableStringOfCEA_Ratios(funcList, true)); - System.out.println("TI = Time Dependent\nTI = Time Independent (Poisson)\nGK = Gardner Knopoff declustered\nSP = Spontaneous ETAS events\nuncert = 1-sigma uncertainty normalized by the mean\n"); ArrayList plotChars2 = new ArrayList(); - plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 2f, Color.BLUE)); - plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 2f, Color.RED)); - plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 2f, Color.BLACK)); - plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 2f, Color.GREEN)); - String fileNamePrefix = dirName+"/FigureB_AggrLosses"; - if(randCOV) fileNamePrefix += "_randCOV"; - PlottingUtils.writeAndOrPlotUncertFuncs(funcList, plotChars2, "", "Aggregate Loss ($1000)", "Probability", new Range(1e3,1e9), new Range(1e-6,1.0), true, true, fileNamePrefix, true); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.RED)); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, new Color(0, 180, 0))); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLUE)); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.GRAY)); + + File outputDir = new File(dirName+ "/OneYrCondLossComFigure"); + if(!outputDir.exists()) outputDir.mkdir(); + String fileNamePrefix = dirName+"/OneYrCondLossComFigure/"+"OneYrCondLossComFigure"; + fileNamePrefix += "_randCOV"; + PlottingUtils.writeAndOrPlotUncertFuncs(funcList, plotChars2, "", "Loss ($)", "Exceedance Probability", new Range(1e4,1e11), new Range(1e-5,1.0), true, true, fileNamePrefix, true); + fileNamePrefix += "_zoomed"; + PlottingUtils.writeAndOrPlotUncertFuncs(funcList, plotChars2, "", "Loss ($)", "Exceedance Probability", new Range(1e6,1e11), new Range(1e-4,1.0), true, true, fileNamePrefix, true); // Make ratio plots UncertainArbDiscFunc denomCurve = funcList.get(0); ArrayList funcListRatios = new ArrayList(); - double xThresh = denomCurve.getClosestXtoY(1e-3); + double xThresh = denomCurve.getClosestXtoY(1e-4); for(int i=0;i pdfList = new ArrayList(); - for(int i=0;i<2;i++) { - pdfList.add(convertExceedCurveToLog10_PDF_Hist(funcList.get(i))); - } - PlottingUtils.writeAndOrPlotFuncs(pdfList, plotChars2, "", "Aggregate Loss ($1000)", "Probability", null, null, false, false, null, true); +// // plot incremental distributions +// ArrayList pdfList = new ArrayList(); +// for(int i=0;i<2;i++) { // Only the first two funcs +// pdfList.add(convertExceedToIncrProbDist(funcList.get(i))); +// } +// if(randCOV) { +// UncertainArbDiscFunc lossIncreProbDistFromTD_CatalogsRandFromCOV = getLossIncrProbDistFromCatalogsRandomFromCOV(getCatalogs(), 1d); +// lossIncreProbDistFromTD_CatalogsRandFromCOV.setName("lossIncreProbDistFromTD_CatalogsRandFromCOV"); +// UncertainArbDiscFunc lossIcreProbDistFromPoisCatalogsRandFromCOV = getLossIncrProbDistFromCatalogsRandomFromCOV(getRandomizedCatalogs(), 1d); +// lossIcreProbDistFromPoisCatalogsRandFromCOV.setName("lossIcreProbDistFromPoisCatalogsRandFromCOV"); +// pdfList.add(lossIncreProbDistFromTD_CatalogsRandFromCOV); +// pdfList.add(lossIcreProbDistFromPoisCatalogsRandFromCOV); +// } +// ArrayList plotChars3 = new ArrayList(); +// plotChars3.add(new PlotCurveCharacterstics(PlotLineType.DOTTED, 1f, Color.RED)); +// plotChars3.add(new PlotCurveCharacterstics(PlotLineType.DOTTED, 1f, Color.BLACK)); +// plotChars3.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.RED)); +// plotChars3.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLACK)); +// fileNamePrefix = dirName+"/FigureA/"+durationsYrs+"yr_IncrLoss"; +// if(randCOV) fileNamePrefix += "_randCOV"; +// PlottingUtils.writeAndOrPlotFuncs(pdfList, plotChars3, "", "Loss ($1)", "Incremental Probability", new Range(1e4,1e11), new Range(1e-5,1.0), true, true, fileNamePrefix, true); } + + public void make1yrConditionalAggrLossExceedComparisonFig() { + + ArrayList funcList = new ArrayList(); + + UncertainArbDiscFunc lossExceedProbFromTD_CatalogsRandFromCOV = getAggrLossExceedProbCurveFromCatalogsRandomFromCOV(getCatalogs(), 1d); + lossExceedProbFromTD_CatalogsRandFromCOV.setName("aggrLossExceedProbFromTD_CatalogsRandFromCOV"); + + + System.out.println("DOING ONE YEAR CATS"); + ArrayList oneYrCondCats=null; + try { + oneYrCondCats = load1yrConditionalCatalogs(); + } catch (IOException e) { + e.printStackTrace(); + } catch (DocumentException e) { + e.printStackTrace(); + } + + // Need to make exceedance curve by hand because method above subdivides catalogs and not sure it will work + double aveYearlyLoss=0; + ArbitrarilyDiscretizedFunc lossProbCurve = getBlankLossExceedCurve(0d); + for (ObsEqkRupList catalog : oneYrCondCats) { + double lossSum=0; + ArbitrarilyDiscretizedFunc lossProbCurveForSubCat = getBlankLossExceedCurve(0d); +// double maxLoss = 0; + for (ObsEqkRupture obsRup : catalog) { + ETAS_EqkRupture rup = (ETAS_EqkRupture)obsRup; + double aveLoss = meanLossForNthRup.get(rup.getNthERF_Index()); + if(aveLoss==0) + continue; + double randLoss = randomLossForEventID[rup.getID()]; // covModel.getDistribution(aveLoss).sample(); // get randome sample +// if(maxLosslossProbCurve.getY(i)) { // numerical problem + if(D) System.out.println("ISSUE: Low bound above mean:\nmean="+lossProbCurve.getY(i)+"\nlowBound="+confArray[0]+"\nN="+oneYrCondCats.size()); + confArray[0] = 0; + } + low95confCurve.set(xVal,confArray[0]); + high95confCurve.set(xVal,confArray[1]); + } + UncertainArbDiscFunc oneYrCondExceedUncertFunc = new UncertainArbDiscFunc(lossProbCurve,low95confCurve,high95confCurve); + oneYrCondExceedUncertFunc.setName("oneYrCondAggrExceedUncertFunc"); + + funcList.add(lossExceedProbFromTD_CatalogsRandFromCOV); + funcList.add(oneYrCondExceedUncertFunc); + + // Write tables + String tableString = ""; + tableString += "\n1yr Aggregate Loss for CEA probability levels (cond loss PDF for each rup randomly sampled):\n"+"\n"; + tableString += "Probability\tTD_loss\tTD_uncert\tCond2024_loss\tCond2024_uncert"+"\n"; + tableString += getTableStringOfCEA_Values(funcList,true)+"\n"; + tableString += "\n1yr Aggregate Loss ratios, relative to TD, for CEA probability levels (cond loss PDF for each rup randomly sampled):\n"+"\n"; + tableString += "Probability\tCond2024_loss\tCond2024_uncert"+"\n"; + tableString += getTableStringOfCEA_Ratios(funcList, true)+"\n"; + System.out.println(tableString); + oneYrCondExceedUncertFunc.setInfo("2024 Expected Loss = "+aveYearlyLoss+"\n\n"+tableString); + + ArrayList plotChars2 = new ArrayList(); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.RED)); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, new Color(0, 180, 0))); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLUE)); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.GRAY)); + + File outputDir = new File(dirName+ "/OneYrCondAggrLossComFigure"); + if(!outputDir.exists()) outputDir.mkdir(); + String fileNamePrefix = dirName+"/OneYrCondAggrLossComFigure/"+"OneYrCondAggrLossComFigure"; + fileNamePrefix += "_randCOV"; + PlottingUtils.writeAndOrPlotUncertFuncs(funcList, plotChars2, "", "Aggregate Loss ($)", "Exceedance Probability", new Range(1e4,1e11), new Range(1e-5,1.0), true, true, fileNamePrefix, true); + fileNamePrefix += "_zoomed"; + PlottingUtils.writeAndOrPlotUncertFuncs(funcList, plotChars2, "", "Aggregate Loss ($)", "Exceedance Probability", new Range(1e6,1e11), new Range(1e-4,1.0), true, true, fileNamePrefix, true); + + // Make ratio plots + UncertainArbDiscFunc denomCurve = funcList.get(0); + ArrayList funcListRatios = new ArrayList(); + + double xThresh = denomCurve.getClosestXtoY(1e-4); + for(int i=0;ixThresh) + break; + double ratio = funcList.get(i).getY(j)/denomCurve.getY(j); + if(ratio<1e-9 || ratio>1e9) ratio = 1e-9; + ratioCurve.set(denomCurve.getX(j), ratio); + } + funcListRatios.add(ratioCurve); + } + fileNamePrefix += "_Ratio"; + PlottingUtils.writeAndOrPlotFuncs(funcListRatios, plotChars2, "", "Aggregate Loss ($)", "Exceedance Ratio", new Range(1e4,1e11), new Range(0.0,2.0), true, false, fileNamePrefix, true); + + } + + + /** + * This is for one or more exceedances + * @param randCOV + */ + public void makeFigAndTableSetA_Exceedances(double durationsYrs, boolean randCOV) { + + ArrayList funcList = new ArrayList(); + + String randCOVincluded = ""; + if(randCOV) + randCOVincluded = " (cond loss PDF for each rup randomly sampled)"; + + if(randCOV) { + UncertainArbDiscFunc lossExceedProbFromTD_CatalogsRandFromCOV = getLossExceedProbCurveFromCatalogsRandomFromCOV(getCatalogs(), durationsYrs); + lossExceedProbFromTD_CatalogsRandFromCOV.setName("lossExceedProbFromTD_CatalogsRandFromCOV"); + UncertainArbDiscFunc lossExceedProbFromPoisCatalogsRandFromCOV = getLossExceedProbCurveFromCatalogsRandomFromCOV(getRandomizedCatalogs(), durationsYrs); + lossExceedProbFromPoisCatalogsRandFromCOV.setName("lossExceedProbFromPoisCatalogsRandFromCOV"); + UncertainArbDiscFunc lossExceedProbFromDeclusteredCatalogsRandFromCOV = getLossExceedProbCurveFromCatalogsRandomFromCOV(getCatalogsDeclustered(), durationsYrs); + lossExceedProbFromDeclusteredCatalogsRandFromCOV.setName("lossExceedProbFromDeclusteredCatalogsRandFromCOV"); + UncertainArbDiscFunc lossExceedProbFromSpontaneousCatalogsRandFromCOV = getLossExceedProbCurveFromCatalogsRandomFromCOV(getSpontaneousEventsCatalog(getCatalogs()), durationsYrs); + lossExceedProbFromSpontaneousCatalogsRandFromCOV.setName("lossExceedProbFromSpontaneousCatalogsRandFromCOV"); + funcList.add(lossExceedProbFromTD_CatalogsRandFromCOV); + funcList.add(lossExceedProbFromPoisCatalogsRandFromCOV); + funcList.add(lossExceedProbFromDeclusteredCatalogsRandFromCOV); + funcList.add(lossExceedProbFromSpontaneousCatalogsRandFromCOV); + } + else { + UncertainArbDiscFunc lossExceedProbFromTD_Catalogs = getLossExceedProbCurveFromCatalogs(getCatalogs(), durationsYrs); + lossExceedProbFromTD_Catalogs.setName("lossExceedProbFromTD_Catalogs"); + UncertainArbDiscFunc lossExceedProbFromPoisCatalogs = getLossExceedProbCurveFromCatalogs(getRandomizedCatalogs(), durationsYrs); + lossExceedProbFromPoisCatalogs.setName("lossExceedProbFromPoisCatalogs"); + UncertainArbDiscFunc lossExceedProbFromDeclusteredCatalogs = getLossExceedProbCurveFromCatalogs(getCatalogsDeclustered(), durationsYrs); + lossExceedProbFromDeclusteredCatalogs.setName("lossExceedProbFromDeclusteredCatalogs"); + UncertainArbDiscFunc lossExceedProbFromSpontaneousCatalogs = getLossExceedProbCurveFromCatalogs(getSpontaneousEventsCatalog(getCatalogs()), durationsYrs); + lossExceedProbFromSpontaneousCatalogs.setName("lossExceedProbFromSpontaneousCatalogs"); + funcList.add(lossExceedProbFromTD_Catalogs); + funcList.add(lossExceedProbFromPoisCatalogs); + funcList.add(lossExceedProbFromDeclusteredCatalogs); + funcList.add(lossExceedProbFromSpontaneousCatalogs); + } + + // Write tables + if(durationsYrs==1.0) { // only for 1-year forecast durations + System.out.println("\n"+durationsYrs+"yr Loss for CEA probability levels"+randCOVincluded+":\n"); + System.out.println("Probability\tTD_loss\tTD_uncert\tTI_loss\tTI_uncert\tGK_loss\tGK_uncert\tSP_loss\tSP_uncert"); + System.out.println(getTableStringOfCEA_Values(funcList,true)); + System.out.println("\n"+durationsYrs+"yr Loss ratios, relative to TD, for CEA probability levels"+randCOVincluded+":\n"); + System.out.println("Probability\tTIvsTD_loss\tTIvsTD_uncert\tGKvsTD_loss\tGKvsTD_uncert\tSPvsTD_loss\tSPvsTD_uncert"); + System.out.println(getTableStringOfCEA_Ratios(funcList, true)); + System.out.println("TI = Time Dependent\nTI = Time Independent (Poisson)\nGK = Gardner Knopoff declustered\nSP = Spontaneous ETAS events\nuncert = 1-sigma uncertainty normalized by the mean\n"); + } + + ArrayList plotChars2 = new ArrayList(); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.RED)); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLACK)); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLUE)); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.GRAY)); + + File outputDir = new File(dirName+ "/FigureA"); + if(!outputDir.exists()) outputDir.mkdir(); + String fileNamePrefix = dirName+"/FigureA/"+durationsYrs+"yr_LossExceed"; + if(randCOV) fileNamePrefix += "_randCOV"; + PlottingUtils.writeAndOrPlotUncertFuncs(funcList, plotChars2, "", "Loss ($)", "Exceedance Probability", new Range(1e4,1e11), new Range(1e-5,1.0), true, true, fileNamePrefix, true); + fileNamePrefix += "_zoomed"; + PlottingUtils.writeAndOrPlotUncertFuncs(funcList, plotChars2, "", "Loss ($)", "Exceedance Probability", new Range(1e6,1e10), new Range(1e-2,1.0), true, true, fileNamePrefix, true); + + // Make ratio plots + UncertainArbDiscFunc denomCurve = funcList.get(0); + ArrayList funcListRatios = new ArrayList(); + + double xThresh = denomCurve.getClosestXtoY(1e-4); + for(int i=0;ixThresh) + break; + double ratio = funcList.get(i).getY(j)/denomCurve.getY(j); + if(ratio<1e-9 || ratio>1e9) ratio = 1e-9; + ratioCurve.set(denomCurve.getX(j), ratio); + } + funcListRatios.add(ratioCurve); + } + fileNamePrefix = dirName+"/FigureA/"+durationsYrs+"yr_LossExceedRatio"; + if(randCOV) fileNamePrefix += "_randCOV"; + PlottingUtils.writeAndOrPlotFuncs(funcListRatios, plotChars2, "", "Loss ($)", "Exceedance Ratio", new Range(1e4,1e11), new Range(0.0,2.0), true, false, fileNamePrefix, true); + + // plot incremental distributions + ArrayList pdfList = new ArrayList(); + for(int i=0;i<2;i++) { // Only the first two funcs + pdfList.add(convertExceedToIncrProbDist(funcList.get(i))); + } + if(randCOV) { + UncertainArbDiscFunc lossIncreProbDistFromTD_CatalogsRandFromCOV = getLossIncrProbDistFromCatalogsRandomFromCOV(getCatalogs(), 1d); + lossIncreProbDistFromTD_CatalogsRandFromCOV.setName("lossIncreProbDistFromTD_CatalogsRandFromCOV"); + UncertainArbDiscFunc lossIcreProbDistFromPoisCatalogsRandFromCOV = getLossIncrProbDistFromCatalogsRandomFromCOV(getRandomizedCatalogs(), 1d); + lossIcreProbDistFromPoisCatalogsRandFromCOV.setName("lossIcreProbDistFromPoisCatalogsRandFromCOV"); + pdfList.add(lossIncreProbDistFromTD_CatalogsRandFromCOV); + pdfList.add(lossIcreProbDistFromPoisCatalogsRandFromCOV); + } + ArrayList plotChars3 = new ArrayList(); + plotChars3.add(new PlotCurveCharacterstics(PlotLineType.DOTTED, 1f, Color.RED)); + plotChars3.add(new PlotCurveCharacterstics(PlotLineType.DOTTED, 1f, Color.BLACK)); + plotChars3.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.RED)); + plotChars3.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLACK)); + fileNamePrefix = dirName+"/FigureA/"+durationsYrs+"yr_IncrLoss"; + if(randCOV) fileNamePrefix += "_randCOV"; + PlottingUtils.writeAndOrPlotFuncs(pdfList, plotChars3, "", "Loss ($1)", "Incremental Probability", new Range(1e4,1e11), new Range(1e-5,1.0), true, true, fileNamePrefix, true); + } + + + + /** + * This is for aggregate loss exceedances (only random COV sample supported) + * @param randCOV + */ + + public void makeFigAndTableSetB_1yr_Exceedances() { + + ArrayList funcList = new ArrayList(); + + boolean randCOV = true; + String randCOVincluded = ""; + if(randCOV) + randCOVincluded = " (cond loss PDF for each rup randomly sampled)"; + + UncertainArbDiscFunc aggrLossExceedProbFromTD_CatalogsRandFromCOV = getAggrLossExceedProbCurveFromCatalogsRandomFromCOV(getCatalogs(), 1d); + aggrLossExceedProbFromTD_CatalogsRandFromCOV.setName("aggrLossExceedProbFromTD_CatalogsRandFromCOV"); + UncertainArbDiscFunc aggrLossExceedProbFromPoisCatalogsRandFromCOV = getAggrLossExceedProbCurveFromCatalogsRandomFromCOV(getRandomizedCatalogs(), 1d); + aggrLossExceedProbFromPoisCatalogsRandFromCOV.setName("aggrLossExceedProbFromPoisCatalogsRandFromCOV"); + UncertainArbDiscFunc aggrLossExceedProbFromDeclusteredCatalogsRandFromCOV = getAggrLossExceedProbCurveFromCatalogsRandomFromCOV(getCatalogsDeclustered(), 1d); + aggrLossExceedProbFromDeclusteredCatalogsRandFromCOV.setName("aggrLossExceedProbFromDeclusteredCatalogsRandFromCOV"); + UncertainArbDiscFunc aggrLossExceedProbFromSpontaneousCatalogsRandFromCOV = getAggrLossExceedProbCurveFromCatalogsRandomFromCOV(getSpontaneousEventsCatalog(getCatalogs()), 1d); + aggrLossExceedProbFromSpontaneousCatalogsRandFromCOV.setName("aggrLossExceedProbFromSpontaneousCatalogsRandFromCOV"); + funcList.add(aggrLossExceedProbFromTD_CatalogsRandFromCOV); + funcList.add(aggrLossExceedProbFromPoisCatalogsRandFromCOV); + funcList.add(aggrLossExceedProbFromDeclusteredCatalogsRandFromCOV); + funcList.add(aggrLossExceedProbFromSpontaneousCatalogsRandFromCOV); + + System.out.println("\n1yr Loss for CEA probability levels"+randCOVincluded+":\n"); + System.out.println("Probability\tTD_loss\tTD_uncert\tTI_loss\tTI_uncert\tGK_loss\tGK_uncert\tSP_loss\tSP_uncert"); + System.out.println(getTableStringOfCEA_Values(funcList,true)); + System.out.println("\n1yr Loss ratios, relative to TD, for CEA probability levels"+randCOVincluded+":\n"); + System.out.println("Probability\tTIvsTD_loss\tTIvsTD_uncert\tGKvsTD_loss\tGKvsTD_uncert\tSPvsTD_loss\tSPvsTD_uncert"); + System.out.println(getTableStringOfCEA_Ratios(funcList, true)); + System.out.println("TI = Time Dependent\nTI = Time Independent (Poisson)\nGK = Gardner Knopoff declustered\nSP = Spontaneous ETAS events\nuncert = 1-sigma uncertainty normalized by the mean\n"); + ArrayList plotChars2 = new ArrayList(); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.RED)); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLACK)); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLUE)); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.GRAY)); + File outputDir = new File(dirName+ "/FigureB"); + if(!outputDir.exists()) outputDir.mkdir(); + String fileNamePrefix = dirName+"/FigureB/1.0yr_AggrLossExceed"; + if(randCOV) fileNamePrefix += "_randCOV"; + PlottingUtils.writeAndOrPlotUncertFuncs(funcList, plotChars2, "", "Aggregate Loss ($)", "Exceedance Probability", new Range(1e4,1e11), new Range(1e-5,1.0), true, true, fileNamePrefix, true); + + // Make ratio plots + UncertainArbDiscFunc denomCurve = funcList.get(0); + ArrayList funcListRatios = new ArrayList(); + + double xThresh = denomCurve.getClosestXtoY(1e-4); + for(int i=0;ixThresh) + break; + double ratio = funcList.get(i).getY(j)/denomCurve.getY(j); + if(ratio<1e-9 || ratio>1e9) ratio = 1e-9; + ratioCurve.set(denomCurve.getX(j), ratio); + } + funcListRatios.add(ratioCurve); + } + fileNamePrefix = dirName+"/FigureB/1.0yr_AggrLossExceedRatio"; + if(randCOV) fileNamePrefix += "_randCOV"; + PlottingUtils.writeAndOrPlotFuncs(funcListRatios, plotChars2, "", "Aggregate Loss ($)", "Exceedance Ratio", new Range(1e4,1e11), new Range(0.0,2.0), true, false, fileNamePrefix, true); + + // plot incremental distributions + ArrayList pdfList = new ArrayList(); + for(int i=0;i<2;i++) { + pdfList.add(convertExceedToIncrProbDist(funcList.get(i))); + } + if(randCOV) { + UncertainArbDiscFunc lossAggrIncreProbDistFromTD_CatalogsRandFromCOV = getAggrLossIncrProbDistFromCatalogsRandomFromCOV(getCatalogs(), 1d); + lossAggrIncreProbDistFromTD_CatalogsRandFromCOV.setName("lossAggrIncreProbDistFromTD_CatalogsRandFromCOV"); + UncertainArbDiscFunc lossAggrIcreProbDistFromPoisCatalogsRandFromCOV = getAggrLossIncrProbDistFromCatalogsRandomFromCOV(getRandomizedCatalogs(), 1d); + lossAggrIcreProbDistFromPoisCatalogsRandFromCOV.setName("lossAggrIcreProbDistFromPoisCatalogsRandFromCOV"); + pdfList.add(lossAggrIncreProbDistFromTD_CatalogsRandFromCOV); + pdfList.add(lossAggrIcreProbDistFromPoisCatalogsRandFromCOV); + } + ArrayList plotChars3 = new ArrayList(); + plotChars3.add(new PlotCurveCharacterstics(PlotLineType.DOTTED, 1f, Color.RED)); + plotChars3.add(new PlotCurveCharacterstics(PlotLineType.DOTTED, 1f, Color.BLACK)); + plotChars3.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.RED)); + plotChars3.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLACK)); + fileNamePrefix = dirName+"/FigureB/1.0yr_AggrIncrLoss"; + if(randCOV) fileNamePrefix += "_randCOV"; + PlottingUtils.writeAndOrPlotFuncs(pdfList, plotChars3, "", "Aggregate Loss ($)", "Incremental Probability", new Range(1e4,1e11), new Range(1e-5,1.0), true, true, fileNamePrefix, true); + } + + + public void make1yr_StatsCSV_File() { +// maxLoss, subCatIndexForMaxAggLoss: 8.253113091481961E10, 244544 +// maxAggLoss, subCatIndexForMaxAggLoss: 1.153828487953038E11, 210663 + ArrayList subCatList = getSubcatalogList(getCatalogs(), 1d); +// ObsEqkRupList catalog = subCatList.get(244544); +// MakeFigures.plotEventRateMapForCatalog(catalog, 2.5, "FigRightHere092624", 1d); + + CSVFile csv = new CSVFile<>(true); + csv.addLine("catindex", "numEvents", "numGT_6pt5", "maxRandLoss", "aggrRandLoss", "maxMag", "origCatIndex", "maxMeanLoss", "aggrMeanLoss"); + int catIndex = -1; + for (ObsEqkRupList catalog:subCatList) { + catIndex+=1; + int origCatIndex = (int)((double)catIndex/500d); + double maxRandLoss=0, aggrRandLoss=0, maxMeanLoss=0, aggrMeanLoss=0, nGT6pt5=0, maxMag=0;; + for (ObsEqkRupture obsRup : catalog) { + ETAS_EqkRupture rup = (ETAS_EqkRupture)obsRup; + if(rup.getMag()>=6.5) + nGT6pt5+=1; + if(rup.getMag()>=maxMag) + maxMag=rup.getMag(); + double meanLoss = meanLossForNthRup.get(rup.getNthERF_Index()); + if(maxMeanLoss tempCatList = new ArrayList(); + tempCatList.add(getCatalogs().get(catalogIndex)); + + File outputDir = new File(dirName+ "/MaxAndAggLossVsTime"); + if(!outputDir.exists()) outputDir.mkdir(); + + + double aveAggrOverMax_TD=0; + double aveAggrOverMax_Pois=0; + double aveAggrOverMax_TD_gt1Billion=0; + double aveAggrOverMax_Pois_gt1Billion=0; + double aveAggrOverMax_TD_gt1Billion_num=0; + double aveAggrOverMax_Pois_gt1Billion_num=0; + + ArrayList subCatList = getSubcatalogList(tempCatList, 1d); + HistogramFunction histTD_MaxLoss = new HistogramFunction(0.05,500,1.0); + HistogramFunction histTD_AggrLoss = new HistogramFunction(0.05,500,1.0); + int subCatIndex=-1; + for (ObsEqkRupList catalog:subCatList) { + subCatIndex+=1; + double maxLoss=0, aggrLoss=0; + for (ObsEqkRupture obsRup : catalog) { + ETAS_EqkRupture rup = (ETAS_EqkRupture)obsRup; + double randLoss = randomLossForEventID[rup.getID()]; // covModel.getDistribution(aveLoss).sample(); // get randome sample + if(maxLoss1e9) { + aveAggrOverMax_TD_gt1Billion+=aggrLoss/maxLoss; + aveAggrOverMax_TD_gt1Billion_num+=1; + } + } + else { + aveAggrOverMax_TD += 1.0; + } + histTD_MaxLoss.set(subCatIndex,Math.log10(maxLoss)); + histTD_AggrLoss.set(subCatIndex,Math.log10(aggrLoss)); + if(Math.log10(maxLoss)>ratioHistTD.getMinX()-ratioHistTD.getDelta()/2) { + ratioHistTD.add(Math.log10(maxLoss), aggrLoss/maxLoss); + numHistTD.add(Math.log10(maxLoss), 1.0); + } + } + aveAggrOverMax_TD_gt1Billion /= aveAggrOverMax_TD_gt1Billion_num; + aveAggrOverMax_TD /= subCatList.size(); + histTD_AggrLoss.setInfo("aveAggrOverMax_TD="+aveAggrOverMax_TD+"\naveAggrOverMax_TD_gt1Billion="+aveAggrOverMax_TD_gt1Billion); + ArrayList funcList = new ArrayList(); + funcList.add(histTD_AggrLoss); + funcList.add(histTD_MaxLoss); + ArrayList plotChars = new ArrayList(); + plotChars.add(new PlotCurveCharacterstics(PlotLineType.HISTOGRAM, 2f, Color.RED)); + plotChars.add(new PlotCurveCharacterstics(PlotLineType.HISTOGRAM, 2f, Color.BLUE)); + String fileNamePrefix = dirName+"/MaxAndAggLossVsTime/maxAndAggLossPerYearForTD_Cat_"+catalogIndex; + Range xRange = new Range(0,500); +// Range xRange = new Range(163-50,163+50); + Range yRange = new Range(4,11.3); + PlottingUtils.writeAndOrPlotFuncs(funcList, plotChars, "Full TD", "Year", "Log10(Loss, $)", xRange, yRange, false, false, 6.5, 2.0, fileNamePrefix, true); + + // Now do poisson result + tempCatList = new ArrayList(); + tempCatList.add(getRandomizedCatalogs().get(catalogIndex)); + subCatList = getSubcatalogList(tempCatList, 1d); + HistogramFunction histPois_MaxLoss = new HistogramFunction(0.05,500,1.0); + HistogramFunction histPois_AggrLoss = new HistogramFunction(0.05,500,1.0); + subCatIndex=-1; + for (ObsEqkRupList catalog:subCatList) { + subCatIndex+=1; + double maxLoss=0, aggrLoss=0; + for (ObsEqkRupture obsRup : catalog) { + ETAS_EqkRupture rup = (ETAS_EqkRupture)obsRup; + double randLoss = randomLossForEventID[rup.getID()]; // covModel.getDistribution(aveLoss).sample(); // get randome sample + if(maxLoss1e9) { + aveAggrOverMax_Pois_gt1Billion+=aggrLoss/maxLoss; + aveAggrOverMax_Pois_gt1Billion_num+=1; + } + + } + else { + aveAggrOverMax_Pois += 1.0; + } + + histPois_MaxLoss.set(subCatIndex,Math.log10(maxLoss)); + histPois_AggrLoss.set(subCatIndex,Math.log10(aggrLoss)); + if(Math.log10(maxLoss)>ratioHistPoiss.getMinX()-ratioHistPoiss.getDelta()/2) { + ratioHistPoiss.add(Math.log10(maxLoss), aggrLoss/maxLoss); + numHistPoiss.add(Math.log10(maxLoss), 1.0); + } + + } + aveAggrOverMax_Pois_gt1Billion /= aveAggrOverMax_Pois_gt1Billion_num; + + aveAggrOverMax_Pois /= subCatList.size(); + histPois_AggrLoss.setInfo("aveAggrOverMax_Pois="+aveAggrOverMax_Pois+"\naveAggrOverMax_Pois_gt1Billion="+aveAggrOverMax_Pois_gt1Billion); + ArrayList funcListPoiss = new ArrayList(); + funcListPoiss.add(histPois_AggrLoss); + funcListPoiss.add(histPois_MaxLoss); + fileNamePrefix = dirName+"/MaxAndAggLossVsTime/maxAndAggLossPerYearForTI_Cat_"+catalogIndex; + PlottingUtils.writeAndOrPlotFuncs(funcListPoiss, plotChars, "Full Randomized (Poisson)", "Year", "Log10(Loss, $)", xRange, yRange, false, false, 6.5, 2.0, fileNamePrefix, true); + + // plot aggr/max loss histrograms as func of log10(maxLoss): + for(int i=0;i funcList2 = new ArrayList(); + funcList2.add(ratioHistTD); + funcList2.add(ratioHistPoiss); + ArrayList plotChars2 = new ArrayList(); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.RED)); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLACK)); + fileNamePrefix = dirName+"/MaxAndAggLossVsTime/aveRatioVsMaxLoss"+catalogIndex; + PlottingUtils.writeAndOrPlotFuncs(funcList2, plotChars2, "", "Log10(MaxLoss ($))", "Ratio", null, null, false, false, fileNamePrefix, true); + + + + } + + + public void plotAccumulatedLossVsTimeForCatalog(int catalogIndex) { + + ArbitrarilyDiscretizedFunc accumLossFunc_TD = new ArbitrarilyDiscretizedFunc(); + accumLossFunc_TD.setName("accumLossFunc_TD"); + double accumLoss_TD=0; + accumLossFunc_TD.set(0.0,0.0); + long lastMillis = 0; + for (ObsEqkRupture obsRup : catalogList.get(catalogIndex)) { + ETAS_EqkRupture rup = (ETAS_EqkRupture)obsRup; + long timeMillis = rup.getOriginTime()-startTimeMillis; + if(timeMillis funcList = new ArrayList(); + funcList.add(accumLossFunc_TD); + funcList.add(accumLossFunc_Pois); + ArrayList plotChars = new ArrayList(); + plotChars.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 2f, Color.BLUE)); + plotChars.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 2f, Color.RED)); + String fileNamePrefix = dirName+"/JUNK"; + PlottingUtils.writeAndOrPlotFuncs(funcList, plotChars, "", "Year", "Loss", new Range(0,500), null, false, false, null, true); + + } + + + + public void makeFigSetC_500yrRates(int catIndex) { + double startTimeYears = 0; // this is the time within the catalog to start, will need to set lower than this as our simulations are 500 years long + double durationYears = 500; + int plotWidthPixels = 2000; + double binWidthDays = 365.25; + String prefix = null; + double annotateMinMag = 6; + double annotateBinWidth = 0.5; + // use this because it has <≥2.5 events +// String fullCatFileName = "/Users/field/Field_Other/CEA_WGCEP/UCERF3/DeclusteringAnalysis/testDebugRun/2020_12_03-Start2012_500yr_kCOV1p5_ScaleFactor1p4_Spontaneous_HistoricalCatalog/results_complete.bin"; +// ObsEqkRupList rupList=null; +// try { +// rupList = U3ETAS_SimulationAnalysis.loadCatalogs(new File(U3ETAS_SimulationAnalysis.fssFileName), new File(fullCatFileName), 2.5).get(0); +// } catch (Exception e) { +// e.printStackTrace(); +// } + ArrayList catalog = new ArrayList(); + for(ObsEqkRupture rup:this.getCatalogs().get(catIndex)) + catalog.add((ETAS_EqkRupture)rup); +// String dirName = "/Users/field/Field_Other/CEA_WGCEP/UCERF3/DeclusteringAnalysis/FiguresFromEclipse/Figure1"; + File outputDir = new File(dirName+ "/FigureC"); + if(!outputDir.exists()) outputDir.mkdir(); + try { + ETAS_SimAnalysisTools.plotRateOverTime(catalog, startTimeYears, durationYears, binWidthDays, outputDir, prefix, plotWidthPixels, + annotateMinMag, annotateBinWidth); + } catch (IOException e) { + e.printStackTrace(); + } + + } + + + public void makeFig1_100yrRates(int catIndex, double startTimeYears) { + if(catIndex>999) + throw new RuntimeException("Only the first set of catalogs is supported"); +// double startTimeYears = 163-50; // time within the catalog to start, this time is 50 yrs before the largest aggregate loss + double durationYears = 100; + int plotWidthPixels = 2000; + double binWidthDays = 30; + String prefix = null; + double annotateMinMag = 6; + double annotateBinWidth = 0.5; + // use this because it has <≥2.5 events + String fullCatFileName = "/Users/field/Library/CloudStorage/OneDrive-DOI/Field_Other/CEA_WGCEP/UCERF3/DeclusteringOnLossAnalysisPaper2024/Data/results_complete.bin"; +// ObsEqkRupList rupList=null; + ETAS_Catalog rupList=null; + try { + rupList = ETAS_CatalogIO.loadIndividualCatalogBinary(new File(fullCatFileName), catIndex, true); +// rupList = U3ETAS_SimulationAnalysis.loadCatalogs(new File(U3ETAS_SimulationAnalysis.fssFileName), new File(fullCatFileName), 2.5).get(0); + } catch (Exception e) { + e.printStackTrace(); + } + ArrayList catalog = new ArrayList(); + for(ObsEqkRupture rup:rupList) + catalog.add((ETAS_EqkRupture)rup); + File outputDir = new File(dirName+ "/Figure1_cat"+catIndex); + if(!outputDir.exists()) outputDir.mkdir(); + try { + ETAS_SimAnalysisTools.plotRateOverTime(catalog, startTimeYears, durationYears, binWidthDays, outputDir, prefix, plotWidthPixels, + annotateMinMag, annotateBinWidth); + } catch (IOException e) { + e.printStackTrace(); + } + } + + + /** + * This is for one or more exceedances, randCOV, and for multiple return forecast durations + * @param randCOV + */ + public void makeFigSetD_Exceedances() throws IOException { + + ArrayList funcList = new ArrayList(); + ArrayList funcListRatios = new ArrayList(); + + float[] durationsYrsArray = {1f/365.25f, 7f/365.25f, 1f/12, 1f, 5f, 50f}; // day, week, month, yr, 5yr, 50yr +// float[] durationsYrsArray = {1f}; // day, week, month, yr, 5yr, 50yr + + File outputDir = new File(dirName+ "/FigureD"); + if(!outputDir.exists()) outputDir.mkdir(); + String dataDirName = dirName+ "/FigureD/data"; + File dataDir = new File(dataDirName); + if(!dataDir.exists()) dataDir.mkdir(); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + + for(float durationsYrs:durationsYrsArray) { + System.out.println("working on duration (yrs) = "+durationsYrs); + + UncertainArbDiscFunc lossExceedProbFromTD_CatalogsRandFromCOV; + UncertainArbDiscFunc lossExceedProbFromPoisCatalogsRandFromCOV; + + String fileName = "TD_Func_"+Float.toString(durationsYrs)+".json"; + File outFile = new File(dataDirName+"/"+fileName); + String fileName2 = "TI_Func_"+Float.toString(durationsYrs)+".json"; + File outFile2 = new File(dataDirName+"/"+fileName2); + if(outFile.exists()) { + FileReader fr = new FileReader(outFile); + FileReader fr2 = new FileReader(outFile2); + lossExceedProbFromTD_CatalogsRandFromCOV = gson.fromJson(fr, UncertainArbDiscFunc.class); + lossExceedProbFromPoisCatalogsRandFromCOV = gson.fromJson(fr2, UncertainArbDiscFunc.class); + } + else { + lossExceedProbFromTD_CatalogsRandFromCOV = getLossExceedProbCurveFromCatalogsRandomFromCOV(getCatalogs(), durationsYrs); + lossExceedProbFromTD_CatalogsRandFromCOV.setName("lossExceedProbFromTD_CatalogsRandFromCOV; duration = "+durationsYrs); + lossExceedProbFromPoisCatalogsRandFromCOV = getLossExceedProbCurveFromCatalogsRandomFromCOV(getRandomizedCatalogs(), durationsYrs); + lossExceedProbFromPoisCatalogsRandFromCOV.setName("lossExceedProbFromPoisCatalogsRandFromCOV; duration = "+durationsYrs); + + FileWriter fw = new FileWriter(outFile); + gson.toJson(lossExceedProbFromTD_CatalogsRandFromCOV, fw); + FileWriter fw2 = new FileWriter(outFile2); + gson.toJson(lossExceedProbFromPoisCatalogsRandFromCOV, fw2); + fw.close(); + fw2.close(); + } + + funcList.add(lossExceedProbFromTD_CatalogsRandFromCOV); + funcList.add(lossExceedProbFromPoisCatalogsRandFromCOV); + + ArbitrarilyDiscretizedFunc ratioCurve = new ArbitrarilyDiscretizedFunc(); + double xThresh = lossExceedProbFromTD_CatalogsRandFromCOV.getClosestXtoY(1e-4); + + ratioCurve.setName("Ratio for "+lossExceedProbFromPoisCatalogsRandFromCOV.getName()); + for(int j=0;jxThresh) + break; + double ratio = lossExceedProbFromPoisCatalogsRandFromCOV.getY(j)/lossExceedProbFromTD_CatalogsRandFromCOV.getY(j); + if(ratio<1e-9 || ratio>1e9) ratio = 1e-9; + ratioCurve.set(lossExceedProbFromTD_CatalogsRandFromCOV.getX(j), ratio); + } + funcListRatios.add(ratioCurve); + + } + + + +// // Write tables +// if(durationsYrs==1.0) { // only for 1-year forecast durations +// System.out.println("\n"+durationsYrs+"yr Loss for CEA probability levels"+randCOVincluded+":\n"); +// System.out.println("Probability\tTD_loss\tTD_uncert\tTI_loss\tTI_uncert\tGK_loss\tGK_uncert\tSP_loss\tSP_uncert"); +// System.out.println(getTableStringOfCEA_Values(funcList,true)); +// System.out.println("\n"+durationsYrs+"yr Loss ratios, relative to TD, for CEA probability levels"+randCOVincluded+":\n"); +// System.out.println("Probability\tTIvsTD_loss\tTIvsTD_uncert\tGKvsTD_loss\tGKvsTD_uncert\tSPvsTD_loss\tSPvsTD_uncert"); +// System.out.println(getTableStringOfCEA_Ratios(funcList, true)); +// System.out.println("TI = Time Dependent\nTI = Time Independent (Poisson)\nGK = Gardner Knopoff declustered\nSP = Spontaneous ETAS events\nuncert = 1-sigma uncertainty normalized by the mean\n"); +// } + + ArrayList plotChars1 = new ArrayList(); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.RED)); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLACK)); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.RED)); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLACK)); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.RED)); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLACK)); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.RED)); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLACK)); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.RED)); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLACK)); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.RED)); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLACK)); + + String fileNamePrefix = dirName+"/FigureD/LossExceed_randCOV"; + PlottingUtils.writeAndOrPlotUncertFuncs(funcList, plotChars1, "", "Loss ($)", "Exceedance Probability", new Range(1e4,1e11), new Range(1e-5,1.0), true, true, fileNamePrefix, true); + + // Make ratio plots + ArrayList plotChars2 = new ArrayList(); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.DOTTED, 1f, Color.BLACK)); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.DASHED, 1f, Color.BLACK)); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.DOTTED_AND_DASHED, 1f, Color.BLACK)); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLACK)); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.MAGENTA)); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.DOTTED_AND_DASHED, 1f, Color.MAGENTA)); + fileNamePrefix = dirName+"/FigureD/LossExceedRatio_randCOV"; + PlottingUtils.writeAndOrPlotFuncs(funcListRatios, plotChars2, "", "Loss ($)", "Exceedance Ratio", new Range(1e4,1e11), new Range(0.5,1.5), true, false, fileNamePrefix, true); + + } + + + /** + * This is for aggregate exceedances, randCOV, and for multiple return forecast durations + * @param randCOV + */ + public void makeFigSetE_Exceedances() throws IOException { + + ArrayList funcList = new ArrayList(); + ArrayList funcListRatios = new ArrayList(); + + float[] durationsYrsArray = {1f/365.25f, 7f/365.25f, 1f/12, 1f, 5f, 50f}; // day, week, month, yr, 5yr, 50yr +// float[] durationsYrsArray = {1f}; // day, week, month, yr, 5yr, 50yr + + File outputDir = new File(dirName+ "/FigureE"); + if(!outputDir.exists()) outputDir.mkdir(); + String dataDirName = dirName+ "/FigureE/data"; + File dataDir = new File(dataDirName); + if(!dataDir.exists()) dataDir.mkdir(); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + + for(float durationsYrs:durationsYrsArray) { + System.out.println("working on duration (yrs) = "+durationsYrs); + + UncertainArbDiscFunc lossExceedProbFromTD_CatalogsRandFromCOV; + UncertainArbDiscFunc lossExceedProbFromPoisCatalogsRandFromCOV; + + String fileName = "TD_AggrFunc_"+Float.toString(durationsYrs)+".json"; + File outFile = new File(dataDirName+"/"+fileName); + String fileName2 = "TI_AggrFunc_"+Float.toString(durationsYrs)+".json"; + File outFile2 = new File(dataDirName+"/"+fileName2); + if(outFile.exists()) { + FileReader fr = new FileReader(outFile); + FileReader fr2 = new FileReader(outFile2); + lossExceedProbFromTD_CatalogsRandFromCOV = gson.fromJson(fr, UncertainArbDiscFunc.class); + lossExceedProbFromPoisCatalogsRandFromCOV = gson.fromJson(fr2, UncertainArbDiscFunc.class); + } + else { + lossExceedProbFromTD_CatalogsRandFromCOV = getAggrLossExceedProbCurveFromCatalogsRandomFromCOV(getCatalogs(), durationsYrs); + lossExceedProbFromTD_CatalogsRandFromCOV.setName("aggrLossExceedProbFromTD_CatalogsRandFromCOV; duration = "+durationsYrs); + lossExceedProbFromPoisCatalogsRandFromCOV = getAggrLossExceedProbCurveFromCatalogsRandomFromCOV(getRandomizedCatalogs(), durationsYrs); + lossExceedProbFromPoisCatalogsRandFromCOV.setName("aggrLossExceedProbFromPoisCatalogsRandFromCOV; duration = "+durationsYrs); + + FileWriter fw = new FileWriter(outFile); + gson.toJson(lossExceedProbFromTD_CatalogsRandFromCOV, fw); + FileWriter fw2 = new FileWriter(outFile2); + gson.toJson(lossExceedProbFromPoisCatalogsRandFromCOV, fw2); + fw.close(); + fw2.close(); + } + + funcList.add(lossExceedProbFromTD_CatalogsRandFromCOV); + funcList.add(lossExceedProbFromPoisCatalogsRandFromCOV); + + + ArbitrarilyDiscretizedFunc ratioCurve = new ArbitrarilyDiscretizedFunc(); + double xThresh = lossExceedProbFromTD_CatalogsRandFromCOV.getClosestXtoY(1e-4); + + ratioCurve.setName("Ratio for "+lossExceedProbFromPoisCatalogsRandFromCOV.getName()); + for(int j=0;jxThresh) + break; + double ratio = lossExceedProbFromPoisCatalogsRandFromCOV.getY(j)/lossExceedProbFromTD_CatalogsRandFromCOV.getY(j); + if(ratio<1e-9 || ratio>1e9) ratio = 1e-9; + ratioCurve.set(lossExceedProbFromTD_CatalogsRandFromCOV.getX(j), ratio); + } + funcListRatios.add(ratioCurve); + + } + + ArrayList plotChars1 = new ArrayList(); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.RED)); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLACK)); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.RED)); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLACK)); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.RED)); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLACK)); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.RED)); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLACK)); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.RED)); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLACK)); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.RED)); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLACK)); + String fileNamePrefix = dirName+"/FigureE/AggrLossExceed_randCOV"; + PlottingUtils.writeAndOrPlotUncertFuncs(funcList, plotChars1, "", "Loss ($)", "Aggregate Exceedance Probability", new Range(1e4,1e11), new Range(1e-5,1.0), true, true, fileNamePrefix, true); + + // Make ratio plots + ArrayList plotChars2 = new ArrayList(); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.DOTTED, 1f, Color.BLACK)); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.DASHED, 1f, Color.BLACK)); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.DOTTED_AND_DASHED, 1f, Color.BLACK)); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLACK)); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.MAGENTA)); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.DOTTED_AND_DASHED, 1f, Color.MAGENTA)); + fileNamePrefix = dirName+"/FigureE/AggrLossExceedRatio_randCOV"; + PlottingUtils.writeAndOrPlotFuncs(funcListRatios, plotChars2, "", "Loss ($)", "Aggregate Exceedance Ratio", new Range(1e4,1e11), new Range(0.5,1.5), true, false, fileNamePrefix, true); + + } + + + + + /** + * This is for aggregate exceedances, randCOV, and for multiple return forecast durations + * @param randCOV + */ + public void makeFigSetG_MagExceedances() throws IOException { + + ArrayList funcList = new ArrayList(); + ArrayList funcListRatios = new ArrayList(); + + float[] durationsYrsArray = {1f/365.25f, 7f/365.25f, 1f/12, 1f, 5f, 50f}; // day, week, month, yr, 5yr, 50yr +// float[] durationsYrsArray = {1f}; // day, week, month, yr, 5yr, 50yr + + File outputDir = new File(dirName+ "/FigureG"); + if(!outputDir.exists()) outputDir.mkdir(); + String dataDirName = dirName+ "/FigureG/data"; + File dataDir = new File(dataDirName); + if(!dataDir.exists()) dataDir.mkdir(); + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + + for(float durationsYrs:durationsYrsArray) { + System.out.println("working on duration (yrs) = "+durationsYrs); + + UncertainArbDiscFunc magExceedProbFromTD_Catalogs; + UncertainArbDiscFunc magExceedProbFromPoisCatalogs; + + String fileName = "TD_MagExceedFunc_"+Float.toString(durationsYrs)+".json"; + File outFile = new File(dataDirName+"/"+fileName); + String fileName2 = "TI_MagExceedFunc_"+Float.toString(durationsYrs)+".json"; + File outFile2 = new File(dataDirName+"/"+fileName2); + if(outFile.exists()) { + FileReader fr = new FileReader(outFile); + FileReader fr2 = new FileReader(outFile2); + magExceedProbFromTD_Catalogs = gson.fromJson(fr, UncertainArbDiscFunc.class); + magExceedProbFromPoisCatalogs = gson.fromJson(fr2, UncertainArbDiscFunc.class); + } + else { + magExceedProbFromTD_Catalogs = getMagExceedProbCurveFromCatalogs(getCatalogs(), durationsYrs); + magExceedProbFromTD_Catalogs.setName("magExceedProbFromTD_Catalogs; duration = "+durationsYrs); + magExceedProbFromPoisCatalogs = getMagExceedProbCurveFromCatalogs(getRandomizedCatalogs(), durationsYrs); + magExceedProbFromPoisCatalogs.setName("magExceedProbFromPoisCatalogs; duration = "+durationsYrs); + + FileWriter fw = new FileWriter(outFile); + gson.toJson(magExceedProbFromTD_Catalogs, fw); + FileWriter fw2 = new FileWriter(outFile2); + gson.toJson(magExceedProbFromPoisCatalogs, fw2); + fw.close(); + fw2.close(); + } + + funcList.add(magExceedProbFromTD_Catalogs); + funcList.add(magExceedProbFromPoisCatalogs); + + + ArbitrarilyDiscretizedFunc ratioCurve = new ArbitrarilyDiscretizedFunc(); + double xThresh = magExceedProbFromTD_Catalogs.getClosestXtoY(1e-4); + + ratioCurve.setName("Ratio for "+magExceedProbFromPoisCatalogs.getName()); + for(int j=0;jxThresh) + break; + double ratio = magExceedProbFromPoisCatalogs.getY(j)/magExceedProbFromTD_Catalogs.getY(j); + if(ratio<1e-9 || ratio>1e9) ratio = 1e-9; + ratioCurve.set(magExceedProbFromTD_Catalogs.getX(j), ratio); + } + funcListRatios.add(ratioCurve); + + } + + ArrayList plotChars1 = new ArrayList(); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.RED)); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLACK)); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.RED)); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLACK)); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.RED)); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLACK)); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.RED)); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLACK)); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.RED)); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLACK)); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.RED)); + plotChars1.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLACK)); + String fileNamePrefix = dirName+"/FigureG/MagExceed"; + PlottingUtils.writeAndOrPlotUncertFuncs(funcList, plotChars1, "", "Magnitude", "Exceedance Probability", new Range(5.0,8.5), new Range(1e-7,1), false, true, fileNamePrefix, true); + + // Make ratio plots + ArrayList plotChars2 = new ArrayList(); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.DOTTED, 1f, Color.BLACK)); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.DASHED, 1f, Color.BLACK)); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.DOTTED_AND_DASHED, 1f, Color.BLACK)); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLACK)); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.MAGENTA)); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.DOTTED_AND_DASHED, 1f, Color.MAGENTA)); + fileNamePrefix = dirName+"/FigureG/MagExceedRatio"; + PlottingUtils.writeAndOrPlotFuncs(funcListRatios, plotChars2, "", "Magnitude", "Exceedance Ratio", new Range(5.0,8.5), new Range(0.5,1.5), false, false, fileNamePrefix, true); + + } + + + + public void makeFigSetF_N_ExceedHists() { + // For N event histograms: + File outputDir = new File(dirName+ "/FigureF"); + if(!outputDir.exists()) outputDir.mkdir(); + double[] lossExceedArray = {1e04, 4e7, 1.23e10}; + for(double loss:lossExceedArray) { + HistogramFunction histN_Dist_TD = getNumLossExceedDistFromCatalogsRandomFromCOV(getCatalogs(), 1.0, loss); + histN_Dist_TD.setName("TD N exceed dist for loss = "+loss); + HistogramFunction histN_Dist_TI = getNumLossExceedDistFromCatalogsRandomFromCOV(getRandomizedCatalogs(), 1.0, loss); + histN_Dist_TI.setName("TI N exceed dist for loss = "+loss); + +// // I need a getRateExceedLoss(loss) method +// PoissonDistribution poisDist = new PoissonDistribution(expNum); +// for(int i=0;i funcList = new ArrayList(); + funcList.add(MakeFigures.getStairStepFunction(histN_Dist_TD)); + funcList.add(MakeFigures.getStairStepFunction(histN_Dist_TI)); + ArrayList plotChars = new ArrayList(); + plotChars.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.RED)); + plotChars.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 1f, Color.BLACK)); + String fileNamePrefix = dirName+"/FigureF/N_ExceedForLossDist_"+loss; + PlottingUtils.writeAndOrPlotFuncs(funcList, plotChars, "", "N Exceedances for loss≥"+loss, "Fraction", null, null, false, true, fileNamePrefix, true); + fileNamePrefix = dirName+"/FigureF/N_ExceedForLossDist_"+loss+"_zoomed"; + PlottingUtils.writeAndOrPlotFuncs(funcList, plotChars, "", "N Exceedances for loss≥"+loss, "Fraction", new Range(-0.5,40), new Range(3e-6,1), false, true, fileNamePrefix, true); + } + + } + + + public void write1yrLargeEvents(int subCatalogIndex) { +// try { +// catalogList = loadCatalogs(new File(catalogsFileName), 2.5, false); // this catalog does not have anything below M 5 +// } catch (IOException e) { +// e.printStackTrace(); +// } catch (DocumentException e) { +// e.printStackTrace(); +// } +// MakeFigures.plotEventRateMapForCatalog(catalogList.get(421), 2.5, "testMapRightHere", 500); + + + ArrayList subCatList = getSubcatalogList(catalogList, 1d); +// MakeFigures.plotEventRateMapForCatalog(subCatList.get(210663), 2.5, "testMapRightHere", 1d); + for(ObsEqkRupture rup : subCatList.get(subCatalogIndex)) { + int fssIndex = ((ETAS_EqkRupture)rup).getFSSIndex(); + int gen = ((ETAS_EqkRupture)rup).getGeneration(); + int parID = ((ETAS_EqkRupture)rup).getParentID(); + int rupID = Integer.parseInt(rup.getEventId()); // orig ID here because in ID replaced in this analysis +// the following event is not found so it's probably M≤5 (filtered out) +if(subCatalogIndex==210663 && rupID == 77552) { // this is the parent of the first M≥6 LA area event in subCatalogIndex=210663 (it started everything) + GregorianCalendar cal = rup.getOriginTimeCal(); + String calString = "ORIGIN TIME: Yr="+cal.get(cal.YEAR)+", DayOfYr="+cal.get(cal.DAY_OF_YEAR)+", Hr="+cal.get(cal.HOUR_OF_DAY)+", Min="+cal.get(cal.MINUTE)+", Sec="+cal.get(cal.SECOND); + System.out.println("HERE "+rupID+"\t"+gen+"\t"+parID+"\t"+(float)rup.getMag()+"\t"+calString+"\t"+fssIndex); +} + if(fssIndex>=0) { + int srcIndex = erf.getSrcIndexForFltSysRup(fssIndex); + ProbEqkSource fssSrc = erf.getSource(srcIndex); + GregorianCalendar cal = rup.getOriginTimeCal(); + String calString = "ORIGIN TIME: Yr="+cal.get(cal.YEAR)+", DayOfYr="+cal.get(cal.DAY_OF_YEAR)+", Hr="+cal.get(cal.HOUR_OF_DAY)+", Min="+cal.get(cal.MINUTE)+", Sec="+cal.get(cal.SECOND); + System.out.println(rupID+"\t"+gen+"\t"+parID+"\t"+(float)rup.getMag()+"\t"+calString+"\t"+fssSrc.getName()); + } + else if(rup.getMag()>=6.0) { + GregorianCalendar cal = rup.getOriginTimeCal(); + String calString = "ORIGIN TIME: Yr="+cal.get(cal.YEAR)+", DayOfYr="+cal.get(cal.DAY_OF_YEAR)+", Hr="+cal.get(cal.HOUR_OF_DAY)+", Min="+cal.get(cal.MINUTE)+", Sec="+cal.get(cal.SECOND); + System.out.println(rupID+"\t"+gen+"\t"+parID+"\t"+(float)rup.getMag()+"\t"+calString+"\tHypocenter: "+rup.getHypocenterLocation()); + } + } + } + + + + public void plotCatalogMap(int subCatalogIndex, Region region, boolean includeGriddedSeis) { + + File outputDir = new File(dirName+ "/CatalogMaps"); + if(!outputDir.exists()) outputDir.mkdir(); + + List sectionList = erf.getSolution().getRupSet().getFaultSectionDataList(); + + ArrayList magForSectionList = new ArrayList(); + ArrayList genForSectionList = new ArrayList(); + for(int s=0;s subCatList = getSubcatalogList(catalogList, 1d); + for(ObsEqkRupture rup : subCatList.get(subCatalogIndex)) { + if(rup.getMag()>mMax) + mMax = rup.getMag(); + int fssIndex = ((ETAS_EqkRupture)rup).getFSSIndex(); + if(fssIndex>=0) { +// if(rup.getMag()>7d) continue; + int gen = ((ETAS_EqkRupture)rup).getGeneration(); + for(int s:erf.getSolution().getRupSet().getSectionsIndicesForRup(fssIndex)) { + if(!Double.isNaN(magForSectionList.get(s))) { + System.out.println("WARNING: Subsection # "+s+" ruptured more than once; previous mag="+magForSectionList.get(s)); + // continue; // this keeps the original + } + magForSectionList.set(s, rup.getMag()); + genForSectionList.set(s, (double)gen); + } + int srcIndex = erf.getSrcIndexForFltSysRup(fssIndex); + ProbEqkSource fssSrc = erf.getSource(srcIndex); + GregorianCalendar cal = rup.getOriginTimeCal(); + String calString = "ORIGIN TIME: Yr="+cal.get(cal.YEAR)+", DayOfYr="+cal.get(cal.DAY_OF_YEAR)+", Hr="+cal.get(cal.HOUR_OF_DAY)+", Min="+cal.get(cal.MINUTE)+", Sec="+cal.get(cal.SECOND); + System.out.println(rup.getMag()+"\t"+gen+"\t"+calString+"\t"+fssSrc.getName()); + + } + else { + hypoList.add(rup.getHypocenterLocation()); // everything less that 0.5f is the same size (0.7 is larger) + float size = 0.5f+10f*((float)rup.getMag()-5.0f); + charsMag.add(new PlotCurveCharacterstics(PlotSymbol.CIRCLE, size, cptMag.getColor((float)rup.getMag()))); // (float)rup.getMag()-5f + int gen = ((ETAS_EqkRupture)rup).getGeneration(); + charsGen.add(new PlotCurveCharacterstics(PlotSymbol.CIRCLE, size, cptGen.getColor((float)gen))); // (float)rup.getMag()-5f + if(rup.getMag()>mMax_gridded) + mMax_gridded = rup.getMag(); + + } + } + + System.out.println("mMax="+mMax+"\nmMax_gridded="+mMax_gridded); // 7.76 + + // make map with color based on mag + GeographicMapMaker mapMaker = new GeographicMapMaker(sectionList); + if(region != null) + mapMaker.setRegion(region); + mapMaker.setSkipNaNs(true); + mapMaker.setScalarThickness(8f); + if(includeGriddedSeis) + mapMaker.plotScatters(hypoList, charsMag, outlineSymbol, cptMag, labelMag); + mapMaker.plotSectScalars(magForSectionList, cptMag, null); + // write mag for each section + for(int s=0;s funcList = new ArrayList(); + funcList.add(exceedFuncTI); + funcList.add(testExceedTI); + funcList.add(incrFuncTI); + funcList.add(testIncrFuncTI); + funcList.add(testIncrDistFromRates); + ArrayList plotChars = new ArrayList(); + plotChars.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 2f, Color.RED)); + plotChars.add(new PlotCurveCharacterstics(PlotSymbol.CROSS, 2f, Color.RED)); + plotChars.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 2f, Color.BLACK)); + plotChars.add(new PlotCurveCharacterstics(PlotSymbol.CROSS, 2f, Color.BLACK)); + plotChars.add(new PlotCurveCharacterstics(PlotSymbol.X, 2f, Color.MAGENTA)); + PlottingUtils.writeAndOrPlotFuncs(funcList, plotChars, "TI Test", "Loss ($)", "Probability", new Range(1e6,1e12), new Range(1e-6,1.0), true, true, null, true); + + ArrayList funcList2 = new ArrayList(); + + exceedFuncTD.setName("TD Exceed"); + testExceedTD.setName("TD Exceed converted from Incremental"); + incrFuncTD.setName("TD Incremental"); + testIncrFuncTD.setName("TD Incremental converted from Exceed"); + + funcList2.add(exceedFuncTD); + funcList2.add(testExceedTD); + funcList2.add(incrFuncTD); + funcList2.add(testIncrFuncTD); + ArrayList plotChars2 = new ArrayList(); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 2f, Color.BLUE)); + plotChars2.add(new PlotCurveCharacterstics(PlotSymbol.CROSS, 2f, Color.BLUE)); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 2f, Color.BLACK)); + plotChars2.add(new PlotCurveCharacterstics(PlotSymbol.CROSS, 2f, Color.BLACK)); + PlottingUtils.writeAndOrPlotFuncs(funcList2, plotChars2, "TD Test", "Loss ($)", "Probability", new Range(1e6,1e12), new Range(1e-6,1.0), true, true, null, true); + } + + /** + * + */ + public void testAggrIncrVsExceedCurveTanslations() { + + UncertainArbDiscFunc incrFuncTI = getAggrLossIncrProbDistFromCatalogsRandomFromCOV(getRandomizedCatalogs(), 1.0); + ArbitrarilyDiscretizedFunc testExceedTI = convertAggIncrToExceedProbDist(incrFuncTI); + UncertainArbDiscFunc exceedFuncTI = getAggrLossExceedProbCurveFromCatalogsRandomFromCOV(getRandomizedCatalogs(), 1.0); + ArbitrarilyDiscretizedFunc testIncrFuncTI = convertAggrExceedToIncrProbDist(exceedFuncTI); + + UncertainArbDiscFunc incrFuncTD = getAggrLossIncrProbDistFromCatalogsRandomFromCOV(getCatalogs(), 1.0); + ArbitrarilyDiscretizedFunc testExceedTD = convertAggIncrToExceedProbDist(incrFuncTD); + UncertainArbDiscFunc exceedFuncTD = getAggrLossExceedProbCurveFromCatalogsRandomFromCOV(getCatalogs(), 1.0); + ArbitrarilyDiscretizedFunc testIncrFuncTD = convertAggrExceedToIncrProbDist(exceedFuncTD); + + exceedFuncTI.setName("TI Aggr Exceed"); + testExceedTI.setName("TI Aggr Exceed converted from Incremental"); + incrFuncTI.setName("TI Aggr Incremental"); + testIncrFuncTI.setName("TI Aggr Incremental converted from Exceed"); + ArrayList funcList = new ArrayList(); + funcList.add(exceedFuncTI); + funcList.add(testExceedTI); + funcList.add(incrFuncTI); + funcList.add(testIncrFuncTI); + ArrayList plotChars = new ArrayList(); + plotChars.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 2f, Color.RED)); + plotChars.add(new PlotCurveCharacterstics(PlotSymbol.CROSS, 2f, Color.RED)); + plotChars.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 2f, Color.BLACK)); + plotChars.add(new PlotCurveCharacterstics(PlotSymbol.CROSS, 2f, Color.BLACK)); + PlottingUtils.writeAndOrPlotFuncs(funcList, plotChars, "TI Aggr Test", "Loss ($)", "Probability", new Range(1e6,1e12), new Range(1e-6,1.0), true, true, null, true); + + ArrayList funcList2 = new ArrayList(); + + exceedFuncTD.setName("TD Aggr Exceed"); + testExceedTD.setName("TD Aggr Exceed converted from Incremental"); + incrFuncTD.setName("TD Aggr Incremental"); + testIncrFuncTD.setName("TD Aggr Incremental converted from Exceed"); + + funcList2.add(exceedFuncTD); + funcList2.add(testExceedTD); + funcList2.add(incrFuncTD); + funcList2.add(testIncrFuncTD); + ArrayList plotChars2 = new ArrayList(); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 2f, Color.BLUE)); + plotChars2.add(new PlotCurveCharacterstics(PlotSymbol.CROSS, 2f, Color.BLUE)); + plotChars2.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 2f, Color.BLACK)); + plotChars2.add(new PlotCurveCharacterstics(PlotSymbol.CROSS, 2f, Color.BLACK)); + PlottingUtils.writeAndOrPlotFuncs(funcList2, plotChars2, "TD Aggr Test", "Loss ($)", "Probability", new Range(1e6,1e12), new Range(1e-6,1.0), true, true, null, true); + } + + + /** + * This tests whether averaging non-exceedcance probabilities from catalogs reaches a different answer + * than averaging exceedcance probabilities. Both TI and TD match here + */ + public void testAveragingNonExceedProbs() { + UncertainArbDiscFunc exceedFuncTI = getLossExceedProbCurveFromCatalogsRandomFromCOV(getRandomizedCatalogs(), 1.0); + UncertainArbDiscFunc exceedFuncTI_Alt = testGetLossExceedProbCurveFromCatalogsRandomFromCOV(getRandomizedCatalogs(), 1.0); + ArrayList funcList = new ArrayList(); + funcList.add(exceedFuncTI); + funcList.add(exceedFuncTI_Alt); + ArrayList plotChars = new ArrayList(); + plotChars.add(new PlotCurveCharacterstics(PlotSymbol.CROSS, 2f, Color.RED)); + plotChars.add(new PlotCurveCharacterstics(PlotLineType.SOLID, 2f, Color.RED)); + PlottingUtils.writeAndOrPlotFuncs(funcList, plotChars, "Alt Exceed Test TI", "Loss ($)", "Probability", new Range(1e6,1e12), new Range(1e-6,1.0), true, true, null, true); + UncertainArbDiscFunc exceedFuncTD = getLossExceedProbCurveFromCatalogsRandomFromCOV(getCatalogs(), 1.0); + UncertainArbDiscFunc exceedFuncTD_Alt = testGetLossExceedProbCurveFromCatalogsRandomFromCOV(getCatalogs(), 1.0); + ArrayList funcList2 = new ArrayList(); + funcList2.add(exceedFuncTD); + funcList2.add(exceedFuncTD_Alt); + PlottingUtils.writeAndOrPlotFuncs(funcList2, plotChars, "Alt Exceed Test TD", "Loss ($)", "Probability", new Range(1e6,1e12), new Range(1e-6,1.0), true, true, null, true); + } + public static void main(String[] args) throws IOException, DocumentException { @@ -2363,21 +4224,180 @@ public static void main(String[] args) throws IOException, DocumentException { * * */ - - // make results reproducible - int seed = 123470; + int seed = 123471; U3ETAS_LossSimulationAnalysis analysis = new U3ETAS_LossSimulationAnalysis(seed); + // this shows the MagProbDist discrepancy is less for 1 day than 1 wk or 1 month, as found for losses + analysis.makeFigSetG_MagExceedances(); + + // this examines conditional loss exceedance curves for the year 2024 +// analysis.make1yrConditionalLossExceedComparisonFig(); +// analysis.make1yrConditionalAggrLossExceedComparisonFig(); + + + // This is to find interesting catalogs +// analysis.make1yr_StatsCSV_File(); + // largest aggregate loss (for both rand and ave loss) is for subcatalog 216231 in main catalog=432 + + // Map & info for above highest aggr loss +// Location loc1 = new Location(33d,-120d,0d); +// Location loc2 = new Location(35d,-117d,0d); +// Region region = new Region(loc1,loc2); +// analysis.plotCatalogMap(216231, region, true); +// analysis.plotCatalogMap(216231, region, false); +// analysis.write1yrLargeEvents(216231); + // last method implies the sequences starts on year 2243, which is 2243-2012 = 231 years into the main catalog. + + // no popup window here +// analysis.makeFig1_100yrRates(432, 231-50); // put sequence at 50-yr mark + + + // these are long term MFDs so COV not needed +// analysis.plotMFDs(); + // analysis.writeAAL_ValuesBillions(); + // this assumes COV = 0 +// analysis.plotLossRateVsMag(); + + // Traditional loss exceedance curves: +// analysis.makeFigAndTableSetA_Exceedances(1d, true); + +// analysis.makeFigSetF_N_ExceedHists(); + + // Aggregate loss exceedance curves: +// analysis.makeFigAndTableSetB_1yr_Exceedances(); + + // This makes/plots TD and TI exceedance curves and ratios for different forecast durations. +// analysis.makeFigSetD_Exceedances(); + + // This makes/plots Aggregate TD and TI exceedance curves and ratios for different forecast durations. +// analysis.makeFigSetE_Exceedances(); + +// analysis.plotMaxAndAggrLossesPerYearInCatalog(432); + + + // this plots the distribution of rupture losses as a function of magnitude (not including rup rates) +// analysis.plotRupLossVsMagStats(analysis.getCatalogs(), false, true); +// analysis.plotRupLossVsMagStats(analysis.getCatalogs(), true, true); + + + // this isn't that informative (comment out part allows to toggle to 1.0-CDF); PDF is more informative +// analysis.plotCumAggrYearlyLossDistributions(true, true); + +// System.exit(0); + + + + +// // Map with greatest number of exceedances of loss=40e6 in subcat = 409649; for both 1000 and 2000 500-yr simulations +// analysis.plotCatalogMap(409649, null, true); +// analysis.plotCatalogMap(409649, null, false); +// analysis.write1yrLargeEvents(409649); + + + + + + // OLD: +// analysis.makeFig1_100yrRates(421, 113); // this start time is 50 yrs before first event + + // this doesn't look great (it save to file; no pop up window) +// analysis.makeFigSetC_500yrRates(421); + +// // Map for highest aggr loss year for the 1000 500-yr simulations (first set) +// Location loc1 = new Location(32.5d,-119.5d,0d); +// Location loc2 = new Location(34.5d,-116.5d,0d); +// Region region = new Region(loc1,loc2); +// analysis.plotCatalogMap(210663, region, true); +// // this writes the large events in 1 yr TD subCatalog +// analysis.write1yrLargeEvents(210663); + + + + // this doesn't look great +// analysis.plotAccumulatedLossVsTimeForCatalog(421); + + /** + * This tests whether exceed and incremental distributions agree with respect to translations. + * The TI results do, but not the TD results, which I don't yet understand. For TD, values are higher + * & closer to Poisson for incremental calculations (less discrepancy), which seems consistent with the + * overall rates being lower for incremental calculations (again, less discrepancy). Why the conversion matches + * for Poisson and not for TD is still mysterious. + */ +// analysis.testIncrVsExceedCurveTanslations(); + // This tests whether aggregate incremental distributions from exceedance (and vise versa) are the same. + // They both are identical, but the conversions are different. +// analysis.testAggrIncrVsExceedCurveTanslations(); + + /** + * This tests whether averaging non-exceed probs among catalogs (rather than exceed probs) gives a different result. + * The answer is no for both TI and TD. + */ +// analysis.testAveragingNonExceedProbs(); + + + + + + + + + + + + +// // TEST different time-ind curves - full PDF +// // Any one of the following three work +//// ArbitrarilyDiscretizedFunc lossRateCurveFromCatalogs = analysis.getLossRateCurveFromCatalogs(analysis.getCatalogs()); +//// ArbitrarilyDiscretizedFunc lossRateCurveFromCatalogs = analysis.getLossRateCurveFromCatalogs(analysis.getRandomizedCatalogs()); +// ArbitrarilyDiscretizedFunc lossRateCurveFromCatalogs = analysis.getLossRateCurveFromCatalogs(analysis.getSubcatalogList(analysis.getRandomizedCatalogs(), 1.0)); +// lossRateCurveFromCatalogs.scale(500d); // need this for the last option above +// ArbitrarilyDiscretizedFunc lossExceedProbFromRateCatalogs = analysis.getBlankLossCurve(0.0); +// lossExceedProbFromRateCatalogs.setName("lossExceedProbFromRateCatalogs"); +// for(int i=0;i funcProb3 = new ArrayList(); +// funcProb3.add(lossExceedProbFromRateCatalogs); +// funcProb3.add(lossExceedProbFromCatalogsRandomizedCat); +// analysis.quickPlot(funcProb3, "Loss (thousand $)", "Prob (/yr)", "Test", true, true); + + + // TEST different time-ind curves - random loss +// // Any one of the following three work +// ArbitrarilyDiscretizedFunc lossRateCurveFromCatalogs = analysis.getLossRateCurveFromCatalogsRandomFromCOV(analysis.getCatalogs()); +//// ArbitrarilyDiscretizedFunc lossRateCurveFromCatalogs = analysis.getLossRateCurveFromCatalogsRandomFromCOV(analysis.getRandomizedCatalogs()); +//// ArbitrarilyDiscretizedFunc lossRateCurveFromCatalogs = analysis.getLossRateCurveFromCatalogsRandomFromCOV(analysis.getSubcatalogList(analysis.getRandomizedCatalogs(), 1.0)); +//// lossRateCurveFromCatalogs.scale(500d); // need this for the last option above +// ArbitrarilyDiscretizedFunc lossExceedProbFromRateCatalogs = analysis.getBlankLossCurve(0.0); +// lossExceedProbFromRateCatalogs.setName("lossExceedProbFromRateCatalogsRandomFromCOV"); +// for(int i=0;i funcProb3 = new ArrayList(); +// funcProb3.add(lossExceedProbFromRateCatalogs); +// funcProb3.add(lossExceedProbFromCatalogsRandomizedCat); +// analysis.quickPlot(funcProb3, "Loss (thousand $)", "Prob (/yr)", "Test", true, true); + + + +// // trying to figure out what's wrong with the incremental distributions // UncertainArbDiscFunc lossExceedProbFromTD_CatalogsRandFromCOV = analysis.getLossExceedProbCurveFromCatalogsRandomFromCOV(analysis.getCatalogs(), 1d); +// lossExceedProbFromTD_CatalogsRandFromCOV.setName("lossExceedProbFromTD_CatalogsRandFromCOV"); // UncertainArbDiscFunc lossExceedProbFromPoisCatalogsRandFromCOV = analysis.getLossExceedProbCurveFromCatalogsRandomFromCOV(analysis.getRandomizedCatalogs(), 1d); +// lossExceedProbFromPoisCatalogsRandFromCOV.setName("lossExceedProbFromPoisCatalogsRandFromCOV"); // -// // trying to figure out what's wrong with the incremental distributions // UncertainArbDiscFunc incrTestTD = analysis.getLossIncrProbDistFromCatalogsRandomFromCOV(analysis.getCatalogs(), 1d); +// incrTestTD.setName("incrTestTD"); // UncertainArbDiscFunc incrTestPoiss = analysis.getLossIncrProbDistFromCatalogsRandomFromCOV(analysis.getRandomizedCatalogs(), 1d); +// incrTestPoiss.setName("incrTestPoiss"); // ArrayList funcList = new ArrayList(); // funcList.add(incrTestTD); // funcList.add(incrTestPoiss); @@ -2387,7 +4407,7 @@ public static void main(String[] args) throws IOException, DocumentException { // plotChars2.add(new PlotCurveCharacterstics(PlotLineType.DASHED, 2f, Color.BLUE)); // plotChars2.add(new PlotCurveCharacterstics(PlotLineType.DASHED, 2f, Color.RED)); // String fileNamePrefix = null; -// PlottingUtils.writeAndOrPlotUncertFuncs(funcList, plotChars2, "Incr Test", "Loss ($1000)", "Probability", new Range(1e3,1e9), new Range(1e-6,1.0), true, true, fileNamePrefix, true); +// PlottingUtils.writeAndOrPlotUncertFuncs(funcList, plotChars2, "Incr Test", "Loss ($)", "Probability", new Range(1e6,1e12), new Range(1e-6,1.0), true, true, fileNamePrefix, true); // // ArbitrarilyDiscretizedFunc exceedTestTD = getBlankLossCurve(0d); // ArbitrarilyDiscretizedFunc exceedTestPois = getBlankLossCurve(0d); @@ -2400,30 +4420,19 @@ public static void main(String[] args) throws IOException, DocumentException { // exceedTestTD.set(i,1.0-nonExceed1); // exceedTestPois.set(i,1.0-nonExceed2); // } +// exceedTestTD.setName("exceedTestTD"); +// exceedTestPois.setName("exceedTestPois"); // ArrayList funcList2 = new ArrayList(); // AbstractDiscretizedFunc // funcList2.add(exceedTestTD); // funcList2.add(exceedTestPois); // funcList2.add(lossExceedProbFromTD_CatalogsRandFromCOV); // funcList2.add(lossExceedProbFromPoisCatalogsRandFromCOV); // -// PlottingUtils.writeAndOrPlotFuncs(funcList2, plotChars2, "Exceed Test", "Loss ($1000)", "Probability", new Range(1e3,1e9), new Range(1e-6,1.0), true, true, fileNamePrefix, true); +// PlottingUtils.writeAndOrPlotFuncs(funcList2, plotChars2, "Exceed Test", "Loss ($)", "Probability", new Range(1e6,1e12), new Range(1e-6,1.0), true, true, fileNamePrefix, true); - // this plots the distribution of rupture losses as a function of magnitude (not including rup rates) -// analysis.plotRupLossVsMagStats(analysis.getCatalogs(), false, false); -// analysis.plotRupLossVsMagStats(analysis.getCatalogs(), true, false); - - // these are long term MFDs so COV not needed - // if I want these for the paper see scratch.ned.GK_Declustering.MakeFigures.makeFigure2_Parts(*) -// analysis.plotMFDs(); - - // this assumes COV = 0 -// analysis.plotLossRateVsMag(); - - analysis.makeFigAndTableSetA_1yr_Exceedances(true); -// analysis.makeFigAndTableSetB_1yr_Exceedances(); // // Plotting @@ -2504,7 +4513,8 @@ public static void main(String[] args) throws IOException, DocumentException { // // -// // plot PDF in log10 space & compare to pure gaussian (this ignores spike at zero loss) +// // plot loss PDF in log10 space & compare to pure gaussian (this ignores spike at zero loss) + // note that this filters out the gazillion little earthquakes that have zero loss (so median and mode are really zero) // ArbitrarilyDiscretizedFunc testCurve = analysis.getLossExceedProbCurveFromERF(); // HistogramFunction testHist = convertExceedCurveToLog10_PDF_Hist(testCurve); // testHist.setName("testHist");