/**
   * This class is designed to be a stand-alone program to validate that the DataSet.properties file
   * contains valid information for all datasets listed by validDataSets in DataSet.properties.
   * Don't run this on the coastwatch computer.
   *
   * @param args is ignored
   */
  public static void main(String args[]) throws Exception {

    String2.log("ValidatDataSetProperties (testing DataSet.properties validDataSets");

    // find a browser properties file (e.g., CWBrowser.properties)
    String contextDirectory = SSR.getContextDirectory(); // with / separator and / at the end
    String[] propList =
        RegexFilenameFilter.list(
            contextDirectory + "WEB-INF/classes/gov/noaa/pfel/coastwatch/", ".+\\.properties");
    int which = -1;
    for (int i = 0; i < propList.length; i++) {
      if (!propList[i].equals("DataSet.properties")) {
        which = i;
        break;
      }
    }
    Test.ensureNotEqual(
        which,
        -1,
        String2.ERROR
            + ": No non-DataSet.properties properties files found in\n"
            + contextDirectory
            + "WEB-INF/classes/gov/noaa/pfel/coastwatch/.\n"
            + ".properties files="
            + String2.toCSSVString(propList));

    FileNameUtility fnu =
        new FileNameUtility(
            "gov.noaa.pfel.coastwatch." + File2.getNameNoExtension(propList[which]));
    ResourceBundle2 dataSetRB2 = new ResourceBundle2("gov.noaa.pfel.coastwatch.DataSet");
    String infoUrlBaseUrl = dataSetRB2.getString("infoUrlBaseUrl", null);
    String tDataSetList[] = String2.split(dataSetRB2.getString("validDataSets", null), '`');
    int nDataSets = tDataSetList.length;
    // Test.ensureEqual(nDataSets, 228, "nDataSets"); //useful to me, but Dave can't add dataset
    // without recompiling this
    String2.log("  testing " + nDataSets + " data sets");
    boolean excessivelyStrict = true;
    for (int i = OneOf.N_DUMMY_GRID_DATASETS;
        i < nDataSets;
        i++) { // "2" in order to skip 0=OneOf.NO_DATA, 1=BATHYMETRY
      String seven = tDataSetList[i];
      Test.ensureTrue(seven != null && seven.length() > 0, "  tDataSetList[" + i + "] is ''.");
      fnu.ensureValidDataSetProperties(seven, excessivelyStrict);
      String infoUrl = dataSetRB2.getString(seven + "InfoUrl", null);
      Test.ensureNotNull(infoUrl, seven + "InfoUrl is null.");
      SSR.getUrlResponse(
          infoUrlBaseUrl
              + infoUrl); // on all computers except coastwatch, all are accessible as urls
    }
    String2.log(
        "  ValidatDataSetProperties successfully tested n="
            + nDataSets
            + " last="
            + tDataSetList[nDataSets - 1]);
  }
示例#2
0
 /**
  * Saves an image as a non-transparent .gif or .png based on the fullImageName's extension. This
  * will overwrite an existing file. Gif's are saved with ImageMagick's convert (which does great
  * color reduction).
  *
  * @param bi
  * @param fullName with directory and extension
  * @throws Exception if trouble
  */
 public static void saveImage(BufferedImage bi, String fullName) throws Exception {
   String shortName =
       fullName.substring(0, fullName.length() - 4); // currently, all extensions are 4 char
   if (fullName.endsWith(".gif")) saveAsGif(bi, shortName);
   else if (fullName.endsWith(".png")) saveAsPng(bi, shortName);
   // else if (fullName.endsWith(".jpg"))
   //    saveAsJpg(bi, shortName);
   else
     Test.error(
         String2.ERROR
             + " in SgtUtil.saveImage: "
             + "Unsupported image type for fileName="
             + fullName);
 }
示例#3
0
 /**
  * This creates a font and throws exception if font family not available
  *
  * @param fontFamily
  * @throws Exception if fontFamily not available
  */
 public static Font getFont(String fontFamily) {
   // minor or major failures return a default font ("Dialog"!)
   Font font = new Font(fontFamily, Font.PLAIN, 10); // Font.ITALIC
   if (!font.getFamily().equals(fontFamily))
     Test.error(
         String2.ERROR
             + " in SgtUtil.getFont: "
             + fontFamily
             + " not available.\n"
             + String2.javaInfo()
             + "\n"
             + "Fonts available: "
             + String2.noLongLinesAtSpace(
                 String2.toCSSVString(
                     GraphicsEnvironment.getLocalGraphicsEnvironment()
                         .getAvailableFontFamilyNames()),
                 80,
                 "  "));
   return font;
 }
示例#4
0
 for (int i = 0; i < n; i++) {
   int tRow = Math2.random(n);
   Test.ensureEqual(pt.readBinaryInt(3, tRow), tRow, "");
 }
示例#5
0
 for (int i = 0; i < n; i++) {
   int tRow = Math2.random(n);
   Test.ensureEqual(pt.readDouble(2, tRow), tRow, "");
 }
示例#6
0
  /**
   * This tests this class.
   *
   * @throws Throwable if trouble.
   */
  public static void test() throws Throwable {
    String2.log("\nPersistentTable.test()");
    verbose = true;
    reallyVerbose = true;
    int n;
    long time;

    // find longest FLOAT_LENGTH
    String s = ("" + Float.MIN_VALUE * -4f / 3f);
    int longest = s.length();
    String longestS = s;
    for (int i = 0; i < 1000; i++) {
      s = "" + ((float) Math.random() / -1e10f);
      if (s.length() > longest) {
        longest = s.length();
        longestS = s;
      }
    }
    String2.log("float longestS=" + longestS + " length=" + longest);
    Test.ensureTrue(longest <= 15, "");

    // find longest DOUBLE_LENGTH
    s = ("" + Double.MIN_VALUE * -4.0 / 3.0);
    longest = s.length();
    longestS = s;
    for (int i = 0; i < 1000; i++) {
      s = "" + (Math.random() / -1e150);
      if (s.length() > longest) {
        longest = s.length();
        longestS = s;
      }
    }
    String2.log("double longestS=" + longestS + " length=" + longest);
    Test.ensureTrue(longest <= 24, "");

    // make a new table
    String name = EDStatic.fullTestCacheDirectory + "testPersistentTable.txt";
    File2.delete(name);
    int widths[] = {
      BOOLEAN_LENGTH,
      BYTE_LENGTH,
      BINARY_BYTE_LENGTH,
      BINARY_CHAR_LENGTH,
      SHORT_LENGTH,
      BINARY_SHORT_LENGTH,
      INT_LENGTH,
      BINARY_INT_LENGTH,
      LONG_LENGTH,
      BINARY_LONG_LENGTH,
      FLOAT_LENGTH,
      BINARY_FLOAT_LENGTH,
      DOUBLE_LENGTH,
      BINARY_DOUBLE_LENGTH,
      20
    };

    PersistentTable pt = new PersistentTable(name, "rw", widths);
    Test.ensureEqual(pt.nRows(), 0, "");
    Test.ensureEqual(pt.addRows(2), 2, "");
    String testS = "Now is the time f\u0F22r all good countrymen to come ...";
    pt.writeBoolean(0, 0, true);
    pt.writeBoolean(0, 1, false);
    pt.writeByte(1, 0, Byte.MIN_VALUE);
    pt.writeByte(1, 1, Byte.MAX_VALUE);
    pt.writeBinaryByte(2, 0, Byte.MIN_VALUE);
    pt.writeBinaryByte(2, 1, Byte.MAX_VALUE);
    pt.writeBinaryChar(3, 0, ' '); // hard because read will trim it to ""
    pt.writeBinaryChar(3, 1, '\u0F22');
    pt.writeShort(4, 0, Short.MIN_VALUE);
    pt.writeShort(4, 1, Short.MAX_VALUE);
    pt.writeBinaryShort(5, 0, Short.MIN_VALUE);
    pt.writeBinaryShort(5, 1, Short.MAX_VALUE);
    pt.writeInt(6, 0, Integer.MIN_VALUE);
    pt.writeInt(6, 1, Integer.MAX_VALUE);
    pt.writeBinaryInt(7, 0, Integer.MIN_VALUE);
    pt.writeBinaryInt(7, 1, Integer.MAX_VALUE);
    pt.writeLong(8, 0, Long.MIN_VALUE);
    pt.writeLong(8, 1, Long.MAX_VALUE);
    pt.writeBinaryLong(9, 0, Long.MIN_VALUE);
    pt.writeBinaryLong(9, 1, Long.MAX_VALUE);
    pt.writeFloat(10, 0, -Float.MAX_VALUE);
    pt.writeFloat(10, 1, Float.NaN);
    pt.writeBinaryFloat(11, 0, -Float.MAX_VALUE);
    pt.writeBinaryFloat(11, 1, Float.NaN);
    pt.writeDouble(12, 0, -Double.MAX_VALUE);
    pt.writeDouble(12, 1, Double.NaN);
    pt.writeBinaryDouble(13, 0, -Double.MAX_VALUE);
    pt.writeBinaryDouble(13, 1, Double.NaN);
    pt.writeString(14, 0, "");
    pt.writeString(14, 1, testS);

    Test.ensureEqual(pt.readBoolean(0, 0), true, "");
    Test.ensureEqual(pt.readBoolean(0, 1), false, "");
    Test.ensureEqual(pt.readByte(1, 0), Byte.MIN_VALUE, "");
    Test.ensureEqual(pt.readByte(1, 1), Byte.MAX_VALUE, "");
    Test.ensureEqual(pt.readBinaryByte(2, 0), Byte.MIN_VALUE, "");
    Test.ensureEqual(pt.readBinaryByte(2, 1), Byte.MAX_VALUE, "");
    Test.ensureEqual(pt.readBinaryChar(3, 0), ' ', "");
    Test.ensureEqual(pt.readBinaryChar(3, 1), '\u0F22', "");
    Test.ensureEqual(pt.readShort(4, 0), Short.MIN_VALUE, "");
    Test.ensureEqual(pt.readShort(4, 1), Short.MAX_VALUE, "");
    Test.ensureEqual(pt.readBinaryShort(5, 0), Short.MIN_VALUE, "");
    Test.ensureEqual(pt.readBinaryShort(5, 1), Short.MAX_VALUE, "");
    Test.ensureEqual(pt.readInt(6, 0), Integer.MIN_VALUE, "");
    Test.ensureEqual(pt.readInt(6, 1), Integer.MAX_VALUE, "");
    Test.ensureEqual(pt.readBinaryInt(7, 0), Integer.MIN_VALUE, "");
    Test.ensureEqual(pt.readBinaryInt(7, 1), Integer.MAX_VALUE, "");
    Test.ensureEqual(pt.readLong(8, 0), Long.MIN_VALUE, "");
    Test.ensureEqual(pt.readLong(8, 1), Long.MAX_VALUE, "");
    Test.ensureEqual(pt.readBinaryLong(9, 0), Long.MIN_VALUE, "");
    Test.ensureEqual(pt.readBinaryLong(9, 1), Long.MAX_VALUE, "");
    Test.ensureEqual(pt.readFloat(10, 0), -Float.MAX_VALUE, "");
    Test.ensureEqual(pt.readFloat(10, 1), Float.NaN, "");
    Test.ensureEqual(pt.readBinaryFloat(11, 0), -Float.MAX_VALUE, "");
    Test.ensureEqual(pt.readBinaryFloat(11, 1), Float.NaN, "");
    Test.ensureEqual(pt.readDouble(12, 0), -Double.MAX_VALUE, "");
    Test.ensureEqual(pt.readDouble(12, 1), Double.NaN, "");
    Test.ensureEqual(pt.readBinaryDouble(13, 0), -Double.MAX_VALUE, "");
    Test.ensureEqual(pt.readBinaryDouble(13, 1), Double.NaN, "");
    Test.ensureEqual(pt.readString(14, 0), "", "");
    // only 18 char returned because one takes 3 bytes in UTF-8
    Test.ensureEqual(pt.readString(14, 1), testS.substring(0, 18), "");
    pt.close();

    // reopen the file   data still there?
    pt = new PersistentTable(name, "rw", widths);
    Test.ensureEqual(pt.nRows(), 2, "");
    Test.ensureEqual(pt.readBoolean(0, 0), true, "");
    Test.ensureEqual(pt.readBoolean(0, 1), false, "");
    Test.ensureEqual(pt.readByte(1, 0), Byte.MIN_VALUE, "");
    Test.ensureEqual(pt.readByte(1, 1), Byte.MAX_VALUE, "");
    Test.ensureEqual(pt.readBinaryByte(2, 0), Byte.MIN_VALUE, "");
    Test.ensureEqual(pt.readBinaryByte(2, 1), Byte.MAX_VALUE, "");
    Test.ensureEqual(pt.readBinaryChar(3, 0), ' ', "");
    Test.ensureEqual(pt.readBinaryChar(3, 1), '\u0F22', "");
    Test.ensureEqual(pt.readShort(4, 0), Short.MIN_VALUE, "");
    Test.ensureEqual(pt.readShort(4, 1), Short.MAX_VALUE, "");
    Test.ensureEqual(pt.readBinaryShort(5, 0), Short.MIN_VALUE, "");
    Test.ensureEqual(pt.readBinaryShort(5, 1), Short.MAX_VALUE, "");
    Test.ensureEqual(pt.readInt(6, 0), Integer.MIN_VALUE, "");
    Test.ensureEqual(pt.readInt(6, 1), Integer.MAX_VALUE, "");
    Test.ensureEqual(pt.readBinaryInt(7, 0), Integer.MIN_VALUE, "");
    Test.ensureEqual(pt.readBinaryInt(7, 1), Integer.MAX_VALUE, "");
    Test.ensureEqual(pt.readLong(8, 0), Long.MIN_VALUE, "");
    Test.ensureEqual(pt.readLong(8, 1), Long.MAX_VALUE, "");
    Test.ensureEqual(pt.readBinaryLong(9, 0), Long.MIN_VALUE, "");
    Test.ensureEqual(pt.readBinaryLong(9, 1), Long.MAX_VALUE, "");
    Test.ensureEqual(pt.readFloat(10, 0), -Float.MAX_VALUE, "");
    Test.ensureEqual(pt.readFloat(10, 1), Float.NaN, "");
    Test.ensureEqual(pt.readBinaryFloat(11, 0), -Float.MAX_VALUE, "");
    Test.ensureEqual(pt.readBinaryFloat(11, 1), Float.NaN, "");
    Test.ensureEqual(pt.readDouble(12, 0), -Double.MAX_VALUE, "");
    Test.ensureEqual(pt.readDouble(12, 1), Double.NaN, "");
    Test.ensureEqual(pt.readBinaryDouble(13, 0), -Double.MAX_VALUE, "");
    Test.ensureEqual(pt.readBinaryDouble(13, 1), Double.NaN, "");
    Test.ensureEqual(pt.readString(14, 0), "", "");
    // only 18 char returned because one takes 3 bytes in UTF-8
    Test.ensureEqual(pt.readString(14, 1), testS.substring(0, 18), "");
    pt.close();

    String modes[] = {"rw", "rw", "rws", "rwd"};
    n = 1000;
    for (int mode = 0; mode < modes.length; mode++) {
      File2.delete(name);
      pt =
          new PersistentTable(
              name,
              modes[mode],
              new int[] {80, BINARY_DOUBLE_LENGTH, DOUBLE_LENGTH, BINARY_INT_LENGTH, INT_LENGTH});
      pt.addRows(n);
      if (mode == 1) String2.log("*** Note: 2nd rw test uses flush()");

      // string speed test
      time = System.currentTimeMillis();
      long modeTime = System.currentTimeMillis();
      for (int i = 0; i < n; i++) pt.writeString(0, i, testS + i);
      if (mode == 1) pt.flush();
      time = System.currentTimeMillis();
      String2.log(
          "\n"
              + modes[mode]
              + " time to write "
              + n
              + " Strings="
              + (System.currentTimeMillis() - time)
              + "   ("
              + new int[] {0, 0, 0, 0}[mode]
              + "ms)"); // java 1.6 0,0,0,0

      for (int i = 0; i < n; i++) {
        int tRow = Math2.random(n);
        Test.ensureEqual(pt.readString(0, tRow), testS + tRow, "");
      }
      String2.log(
          modes[mode]
              + " time to read "
              + n
              + " Strings="
              + (System.currentTimeMillis() - time)
              + "   ("
              + new int[] {15, 16, 47, 15}[mode]
示例#7
0
  /** This tests SgtUtil. */
  public static void test() throws Exception {
    // test splitLine
    String2.log("\n*** SgtUtil.test");
    StringArray sa = new StringArray();

    // wide
    sa.clear();
    splitLine(38, sa, "This is a test of splitline.");
    Test.ensureEqual(sa.size(), 1, "");
    Test.ensureEqual(sa.get(0), "This is a test of splitline.", "");

    // narrow
    sa.clear();
    splitLine(12, sa, "This is a test of splitline.");
    Test.ensureEqual(sa.size(), 3, "");
    Test.ensureEqual(sa.get(0), "This is a ", "");
    Test.ensureEqual(sa.get(1), "test of ", "");
    Test.ensureEqual(sa.get(2), "splitline.", "");

    // narrow and can't split, so chop at limit
    sa.clear();
    splitLine(12, sa, "This1is2a3test4of5splitline.");
    Test.ensureEqual(sa.size(), 3, "");
    Test.ensureEqual(sa.get(0), "This1is2a3t", "");
    Test.ensureEqual(sa.get(1), "est4of5split", "");
    Test.ensureEqual(sa.get(2), "line.", "");

    // caps
    sa.clear();
    splitLine(12, sa, "THESE ARE a a REALLY WIDE.");
    Test.ensureEqual(sa.size(), 3, "");
    Test.ensureEqual(sa.get(0), "THESE ARE ", "");
    Test.ensureEqual(sa.get(1), "a a REALLY ", "");
    Test.ensureEqual(sa.get(2), "WIDE.", "");

    // test suggestPaletteRange
    Test.ensureEqual(
        suggestPaletteRange(.3, 8.9), new double[] {0, 10}, ""); // typical Rainbow Linear
    Test.ensureEqual(
        suggestPaletteRange(.11, 890), new double[] {.1, 1000}, ""); // typical Rainbow Log
    Test.ensureEqual(
        suggestPaletteRange(-7, 8),
        new double[] {-10, 10},
        ""); // typical BlueWhiteRed Linear symmetric

    // test suggestPalette
    Test.ensureEqual(
        suggestPalette(.3, 8.9), "WhiteRedBlack", ""); // small positive, large positive
    Test.ensureEqual(suggestPalette(300, 890), "Rainbow", ""); // typical Rainbow Log
    Test.ensureEqual(
        suggestPalette(-7, 8), "BlueWhiteRed", ""); // typical BlueWhiteRed Linear symmetric

    // test suggestPaletteScale
    Test.ensureEqual(suggestPaletteScale(.3, 8.9), "Linear", ""); // typical Rainbow Linear
    Test.ensureEqual(suggestPaletteScale(.11, 890), "Log", ""); // typical Rainbow Log
    Test.ensureEqual(
        suggestPaletteScale(-7, 8), "Linear", ""); // typical BlueWhiteRed Linear symmetric

    BufferedImage bi = ImageIO.read(new File(String2.unitTestDataDir + "graphs/erdBAssta5day.png"));
    long time = System.currentTimeMillis();
    Test.ensureEqual(findGraph(bi), new int[] {24, 334, 150, 21}, "");
    String2.log("findGraph time=" + (System.currentTimeMillis() - time));
  }
示例#8
0
  /** Constructor */
  public CWDataBrowser() throws Exception {
    super("gov.noaa.pfel.coastwatch.CWDataBrowser");
    constructorDateTime = Calendar2.getCurrentISODateTimeStringLocal();

    // addAttribute(new EmaLabel(this, "instructions"));
    addAttribute(dataSet = new EmaSelect(this, "dataSet"));
    addAttribute(region = new EmaSelect(this, "region"));
    addAttribute(timePeriod = new EmaSelect(this, "timePeriod"));
    addAttribute(date = new EmaSelect(this, "date"));
    addAttribute(formSubmitted = new EmaHidden(this, "formSubmitted"));
    addAttribute(submitForm = new EmaButton(this, "submitForm"));

    // one time things
    verbose = classRB2.getBoolean("verbose", false);

    // contextDirectory and logs (file will be in same dir as this class's source code, named
    // log.txt)
    contextDirectory = classRB2.getString("contextDirectory", "");
    int logPo = fullClassName.lastIndexOf('.');
    String logDir = String2.replaceAll(fullClassName.substring(0, logPo + 1), ".", "/");
    String2.setupLog(
        false,
        false,
        String2.getClassPath() + logDir + "log.txt", // with / separator
        true,
        String2.logFileDefaultMaxSize); // append?
    String2.log(
        "\n"
            + String2.makeString('*', 80)
            + "\nCWDataBrowser.constructor "
            + constructorDateTime
            + "\nlogFile="
            + String2.logFileName()
            + "\n"
            + String2.standardHelpAboutMessage());

    // get baseDataDirectory (for access within this program)
    baseDataDirectory = classRB2.getString("dataDirectory", null);
    Test.ensureNotNull(baseDataDirectory, "dataDirectory");

    // get dataServer (for web-based access to the data)
    dataServer = classRB2.getString("dataServer", null);
    Test.ensureNotNull(dataServer, "dataServer");

    // how often should reset be called?
    resetEveryNMillis = classRB2.getInt("resetEveryNMinutes", 10) * 60000; // millis/min

    // printTopNMostRequested
    printTopNMostRequested = classRB2.getInt("printTopNMostRequested", 50);

    // lookForAllUnusedDataFiles
    lookForAllUnusedDataFiles = classRB2.getBoolean("lookForAllUnusedDataFiles", false);

    // get the name of the file with the small regions map
    regionsImage = classRB2.getString("regionsImage", "");
    regionsImageTitle = classRB2.getString("regionsImage.title", "");
    regionsImageAlt = classRB2.getString("regionsImage.alt", "");

    // get title
    title = classRB2.getString("title.value", "");

    // get dataSet properties
    dataSetOptions = classRB2.getString("dataSet.options", null).split("\f");
    dataSetTitles = classRB2.getString("dataSet.title", null).split("\f");
    dataSetDirectories = classRB2.getString("dataSet.directories", null).split("\f");
    dataSetRegexs = classRB2.getString("dataSet.regexs", null).split("\f");
    if (dataSetRequests == null) dataSetRequests = new int[dataSetOptions.length];
    boolean trouble =
        dataSetOptions.length != (dataSetTitles.length - 1)
            || // 1 extra title (main)
            dataSetOptions.length != dataSetDirectories.length
            || dataSetOptions.length != dataSetRegexs.length;
    if (verbose || trouble)
      String2.log(
          "baseDataDirectory: "
              + baseDataDirectory
              + "\n"
              + "dataSetOptions: "
              + String2.toCSSVString(dataSetOptions)
              + "\n"
              + "dataSetTitles: "
              + String2.toNewlineString(dataSetTitles)
              + "\n"
              + "dataSetDirectories: "
              + String2.toCSSVString(dataSetDirectories)
              + "\n"
              + "dataSetRegexs: "
              + String2.toCSSVString(dataSetRegexs));
    if (trouble)
      throw new RuntimeException(
          String2.ERROR
              + ": CWDataBrowser.reset "
              + "nDataSetOptions "
              + dataSetOptions.length
              + " != nDataSetTitles "
              + dataSetTitles.length
              + " != nDataSetDirectories "
              + dataSetDirectories.length
              + " != nDataSetRegexs "
              + dataSetRegexs.length);

    // get region properties
    regionOptions = classRB2.getString("region.options", null).split("\f");
    regionTitles = classRB2.getString("region.title", null).split("\f");
    regionRegexs = classRB2.getString("region.regexs", null).split("\f");
    regionCoordinates = classRB2.getString("region.coordinates", null).split("\f");
    regionRequests = new int[regionOptions.length];
    trouble =
        regionOptions.length != (regionTitles.length - 1)
            || // 1 extra title (main)
            regionOptions.length != regionRegexs.length
            || regionOptions.length != regionCoordinates.length;
    if (verbose || trouble)
      String2.log(
          "regionOptions: "
              + String2.toCSSVString(regionOptions)
              + "\n"
              + "regionTitles: "
              + String2.toNewlineString(regionTitles)
              + "\n"
              + "regionRegexs: "
              + String2.toCSSVString(regionRegexs));
    if (trouble)
      throw new RuntimeException(
          String2.ERROR
              + ": CWDataBrowser.reset "
              + "nRegionOptions "
              + regionOptions.length
              + " != nRegionTitles "
              + regionTitles.length
              + " != nRegionRegexs "
              + regionRegexs.length
              + " != nRegionCoordinates "
              + regionCoordinates.length);

    // get timePeriod properties
    timePeriodOptions = classRB2.getString("timePeriod.options", null).split("\f");
    timePeriodTitles = classRB2.getString("timePeriod.title", null).split("\f");
    timePeriodDirectories = classRB2.getString("timePeriod.directories", null).split("\f");
    timePeriodRequests = new int[timePeriodOptions.length];
    trouble =
        timePeriodOptions.length != (timePeriodTitles.length - 1)
            || // 1 extra title (main)
            timePeriodOptions.length != timePeriodDirectories.length;
    if (verbose || trouble)
      String2.log(
          "timePeriodOptions: "
              + String2.toCSSVString(timePeriodOptions)
              + "\n"
              + "timePeriodTitles: "
              + String2.toNewlineString(timePeriodTitles)
              + "\n"
              + "timePeriodDirectories: "
              + String2.toCSSVString(timePeriodDirectories));
    if (trouble)
      throw new RuntimeException(
          String2.ERROR
              + ": CWDataBrowser.reset "
              + "nTimePeriodOptions "
              + timePeriodOptions.length
              + " != nTimePeriodTitles "
              + timePeriodTitles.length
              + " "
              + " != nTimePeriodDirectories "
              + timePeriodDirectories.length);

    // get 'get' properties
    // the first 'get' option must be .gif; a .gif file must be present before looking for others
    getOptions = classRB2.getString("get.options", null).split("\f");
    getTitles = classRB2.getString("get.title", null).split("\f");
    getDirectories = classRB2.getString("get.directories", null).split("\f");
    getRegexs = classRB2.getString("get.regexs", null).split("\f");
    getExtensions = classRB2.getString("get.extensions", null).split("\f");
    hereIs = classRB2.getString("hereIs", null);
    hereIsAlt = classRB2.getString("hereIsAlt", null);
    trouble =
        getOptions.length != (getTitles.length - 1)
            || // 1 extra title (main)
            getOptions.length != getDirectories.length
            || getOptions.length != getRegexs.length
            || getOptions.length != getExtensions.length;
    if (verbose || trouble)
      String2.log(
          "getOptions: "
              + String2.toCSSVString(getOptions)
              + "\n"
              + "getDirectories: "
              + String2.toCSSVString(getDirectories)
              + "\n"
              + "getExtensions: "
              + String2.toCSSVString(getExtensions)
              + "\n"
              + "getRegexs: "
              + String2.toCSSVString(getRegexs));
    if (trouble)
      throw new RuntimeException(
          String2.ERROR
              + ": CWDataBrowser.reset \n"
              + "nGetOptions "
              + getOptions.length
              + " != nGetTitles "
              + getTitles.length
              + " != nGetDirectories "
              + getDirectories.length
              + " != nGetRegexs "
              + getRegexs.length
              + " != nGetExtensions "
              + getExtensions.length);

    requestedFilesMap = new ConcurrentHashMap(128, 0.75f, 4); // thread-safe
    // EmaAttribute.verbose= true;

    // reset after attributes have been created
    runCWDataBrowserReset();
    resetThread.join();
    boolean ok = getDataFromReset(); // it should succeed first try
    if (!ok) throw new RuntimeException(String2.ERROR + " in CWDataBrowserReset.");
  }