/**
  * Reads rupture depth distribution data (rupture magnitude vs. rupture depth) and returns an
  * {@link ArbitrarilyDiscretizedFunc}
  */
 private ArbitrarilyDiscretizedFunc getRuptureDepthDistribution(Element ruptureDepthDist) {
   ArbitrarilyDiscretizedFunc rupDepthDist = new ArbitrarilyDiscretizedFunc();
   String xVals = (String) ruptureDepthDist.element(MAGNITUDE).getData();
   String yVals = (String) ruptureDepthDist.element(DEPTH).getData();
   StringTokenizer xVal = new StringTokenizer(xVals);
   StringTokenizer yVal = new StringTokenizer(yVals);
   while (xVal.hasMoreTokens())
     rupDepthDist.set(Double.valueOf(xVal.nextToken()), Double.valueOf(yVal.nextToken()));
   return rupDepthDist;
 }
 /**
  * set x values back from the log space to the original linear values for Hazard Function after
  * completion of the Hazard Calculations if the selected IMT are SA , PGA or PGV It accepts 1
  * parameters
  *
  * @param hazFunction : this is the function with X values set
  */
 private ArbitrarilyDiscretizedFunc toggleHazFuncLogValues(
     ArbitrarilyDiscretizedFunc hazFunc, double[] xValues) {
   int numPoints = hazFunc.getNum();
   DiscretizedFuncAPI tempFunc = hazFunc.deepClone();
   hazFunc = new ArbitrarilyDiscretizedFunc();
   // take log only if it is PGA, PGV or SA
   if (this.xLogFlag) {
     for (int i = 0; i < numPoints; ++i) hazFunc.set(xValues[i], tempFunc.getY(i));
     return hazFunc;
   } else throw new RuntimeException("Unsupported IMT");
 }
  /** This makes and returns the nth probEqkRupture for this source. */
  public ProbEqkRupture getRupture(int nthRupture) {

    // set the magnitude
    double mag = mags.get(nthRupture).doubleValue();
    probEqkRupture.setMag(mag);

    // set the probability if it's Poissonian (otherwise this was already
    // set)
    if (isPoissonian)
      probEqkRupture.setProbability(
          1 - Math.exp(-duration * ((Double) rates.get(nthRupture)).doubleValue()));

    // set the rake, depth, and dip if necessary
    if (variableDepthRakeAndDip) {
      probEqkRupture.setAveRake(rakes.get(nthRupture).doubleValue());
      double depth;
      if (mag < this.aveRupTopVersusMag.getMinX()) depth = this.defaultHypoDepth;
      else depth = aveRupTopVersusMag.getClosestY(mag);
      // location.setDepth(depth);
      location = new Location(location.getLatitude(), location.getLongitude(), depth);
      probEqkRupture.setPointSurface(location, dips.get(nthRupture).doubleValue());
    }

    // return the ProbEqkRupture
    return probEqkRupture;
  }
  /**
   * function to compute hazard curves and make the lat/lon files
   *
   * @param imtLogFlag
   * @param xValues
   * @param griddedSites
   * @param imr
   * @param eqkRupForecast
   * @param mapParametersInfo
   */
  private void calculate(
      boolean imtLogFlag,
      double[] xValues,
      SitesInGriddedRegion sites,
      ScalarIntensityMeasureRelationshipAPI imr,
      EqkRupForecast eqkRupForecast,
      String mapParametersInfo,
      String email) {
    Site site;
    this.xLogFlag = imtLogFlag;
    int numSites = sites.getRegion().getNodeCount();
    try {
      HazardCurveCalculator hazCurveCalc = new HazardCurveCalculator();
      // hazCurveCalc.showProgressBar(false);

      int numPoints = xValues.length;
      for (int j = 0; j < numSites; ++j) {
        site = sites.getSite(j);
        // make and initialize the haz function
        ArbitrarilyDiscretizedFunc hazFunction = new ArbitrarilyDiscretizedFunc();
        this.initX_Values(hazFunction, xValues);
        hazCurveCalc.getHazardCurve(hazFunction, site, imr, eqkRupForecast);
        String lat = decimalFormat.format(site.getLocation().getLatitude());
        String lon = decimalFormat.format(site.getLocation().getLongitude());

        hazFunction = this.toggleHazFuncLogValues(hazFunction, xValues);
        try {
          FileWriter fr = new FileWriter(DATASETS_PATH + newDir + "/" + lat + "_" + lon + ".txt");
          for (int i = 0; i < numPoints; ++i)
            fr.write(hazFunction.getX(i) + " " + hazFunction.getY(i) + "\n");
          fr.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    }

    // make the metadata.data and sites.data files
    try {
      FileWriter fr = new FileWriter(DATASETS_PATH + newDir + "/metadata.txt");
      fr.write(mapParametersInfo + "\n");
      fr.close();
      fr = new FileWriter(DATASETS_PATH + newDir + "/sites.txt");
      fr.write(
          sites.getRegion().getMinLat()
              + " "
              + sites.getRegion().getMaxLat()
              + " "
              + sites.getRegion().getSpacing()
              + "\n"
              + sites.getRegion().getMinLon()
              + " "
              + sites.getRegion().getMaxLon()
              + " "
              + sites.getRegion().getSpacing()
              + "\n");
      fr.close();
      if (email != null || !email.equals("")) {
        HazardMapCalcPostProcessing mapPostProcessing =
            new HazardMapCalcPostProcessing(
                numSites,
                email,
                newDir,
                java.util.Calendar.getInstance().getTime().toString().replaceAll(" ", "_"));
      }

    } catch (IOException ee) {
      ee.printStackTrace();
    }
  }