package testslbmjava;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import gov.sandia.gnem.slbmjni.GridProfile;
import gov.sandia.gnem.slbmjni.GridWeight;
import gov.sandia.gnem.slbmjni.SLBMException;
import gov.sandia.gnem.slbmjni.SlbmInterface;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;

import org.junit.BeforeClass;
import org.junit.Test;

public class TestSLBMGeoTessLinear
{
    private static SlbmInterface slbm;

    private static SlbmInterface slbm2;

    private static int verbosity = 1;

    private static final double dtr = 3.1415926535897932384626 / 180.;
    private static final double rtd = 180. / 3.1415926535897932384626;

    @BeforeClass
    public static void setUpBeforeClass() throws Exception
    {
        // Load the c++ SLBM library libslbm.so into memory.
        System.loadLibrary("slbmjni");
        System.out.println("setUpBeforeClass()  slbmjni loaded");
        slbm = new SlbmInterface();

        System.out.println("SlbmInterface version " + slbm.getVersion());

        File here = new File(".");
        System.out.println("Running from directory "+here.getCanonicalPath());

        File modelsDir = new File(here, "models");
        if (!modelsDir.exists())
            throw new Exception("modelsDir does not exist "+modelsDir.getCanonicalPath());

        File modelFile = new File(modelsDir,"rstt.2.3");
        System.out.println("Load model from file "+modelFile.getCanonicalPath());
        slbm.loadVelocityModel(modelFile.getCanonicalPath());
        slbm.setInterpolatorType("linear");
        System.out.println("model loaded.");

        createGreatCircle(slbm, "Pn");
        slbm.initializeActiveNodes(28 * dtr, 80 * dtr, 32 * dtr, 105 * dtr);
    }

    private static boolean createGreatCircle(SlbmInterface slbm, String phase)
    {
        double rlat = 30. * dtr;
        double rlon = 90. * dtr;
        double rdepth = -1;
        double slat = 35. * dtr;
        double slon = 95. * dtr;
        double sdepth = 0.;

        try
        {
            slbm.createGreatCircle(phase, slat, slon, sdepth, rlat, rlon,
                    rdepth);
            return true;
        }
        catch (SLBMException e)
        {
            e.printStackTrace();
        }
        return false;
    }

    @Test
    public void testGetVersion()
    {
        if (verbosity > 0)
            System.out.println("testGetVersion()");
        assert (slbm.getVersion().equals("3.1.0"));
    }

    @Test
    public void testGetTessId()
    {
        if (verbosity > 0)
            System.out.println("testGetTessId()");

        // TODO

    }

    @Test
    public void testInitializeActiveNodes()
    {
        if (verbosity > 0)
            System.out.println("testInitializeActiveNodes()");
        slbm.initializeActiveNodes(28 * dtr, 80 * dtr, 32 * dtr, 105 * dtr);
        assertEquals(147, slbm.getNActiveNodes());
    }

    @Test
    public void testCreateGreatCircle() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testCreateGreatCircle()");

        if (!createGreatCircle(slbm, "Pn"))
            fail("\ntestCreateGreatCircle() failed\n\n");
    }

    // @Test
    public void testClear()
    {
        if (verbosity > 0)
            System.out.println("testClear()");
        slbm.clear();
        try
        {
            slbm.getTravelTime();
            fail("\ntestClear() failed\n\n");
        }
        catch (SLBMException ex)
        {
        }
        createGreatCircle(slbm, "Pn");
    }

    @Test
    public void testToStringInt() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testToStringInt()");

        // depends on active nodes being set as follows:
        // slbm.initializeActiveNodes(28*dtr, 80*dtr, 32*dtr, 105*dtr);

        ArrayList<String> actual = getRecords(slbm.toString(6), false);

        ArrayList<String> expected = new ArrayList<String>(254);
        expected.add("");
        expected.add("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
        expected.add("Great Circle ");
        expected.add("");
        expected.add("   SLBM Version 3.1.0");
        expected.add("");
        expected.add("   Solution method = GreatCircle_Xn::computeTravelTimeCrust()");
        expected.add("");
        expected.add("   Earth radius varies as a function of latitude. ");
        expected.add("");
        expected.add("   Maximum allowed source-receiver separation = 15.0000 degrees.");
        expected.add("   Maximum allowed source depth = 200.0000 km.");
        expected.add("");
        expected.add("   Phase = Pn");
        expected.add("                    X, deg  X,moho, km      T, sec");
        expected.add("   Source   =       0.8371     92.1257     17.3312");
        expected.add("   Receiver =       0.9019     99.1967     18.8271");
        expected.add("   Mantle   =       4.7940    527.1237     65.1866");
        expected.add("   Total    =       6.5331    718.4460    101.2541");
        expected.add("");
        expected.add("   Average mantle velocity  =       8.1046");
        expected.add("   Path average velocity    =       8.0866");
        expected.add("   Path average gradient    =   0.00152780");
        expected.add("   C                        =   0.00034715");
        expected.add("   H                        =      12.0467");
        expected.add("   C*H                      =       0.0042");
        expected.add("   chMax                    =       0.2000");
        expected.add("   Average Moho depth       =      68.3652");
        expected.add("   Turning depth            =    6291.5709");
        expected.add("   Ray parameter            =     776.2564");
        expected.add("   Fraction Active          =       0.5758");
        expected.add("");
        expected.add("");
        expected.add("   Source Profile:");
        expected.add("");
        expected.add("                   Lat      Lon    Depth  R Earth        P   P crit");
        expected.add("   Location:   35.0000  95.0000    0.000  6371.14   776.26   781.18");
        expected.add("   Pierce Pt:  34.3711  94.3275   65.562");
        expected.add("");
        expected.add("   Model Layers:");
        expected.add("");
        expected.add("     # Layer             Vel      Top    Thick");
        expected.add("     1 water          1.5000  -4.8281   0.0000");
        expected.add("     2 sediment1      2.5003  -4.8281   0.0293");
        expected.add("     3 sediment2      2.1267  -4.7989   0.0000");
        expected.add("     4 sediment3      0.0000  -4.7989   0.0000");
        expected.add("     5 upper_crust    6.0897  -4.7989  24.0487");
        expected.add("     6 middle_crust   6.3117  19.2498  24.2331");
        expected.add("     8 lower_crust    7.1899  43.4829  22.0791");
        expected.add("     9 mantle         8.0719  65.5621");
        expected.add("");
        expected.add("");
        expected.add("   Applied Layers:");
        expected.add("");
        expected.add("     #     Vel      Top    Thick   i, deg   X, deg    X, km       TT");
        expected.add("     2  2.5003   0.0000  -4.7989  17.7361  0.00000   0.0000   0.0000");
        expected.add("     5  6.0897  -4.7989  24.0487  47.8517 -0.01379  -1.5348  -2.0150");
        expected.add("     6  6.3117  19.2498  24.2331  50.4748  0.22643  25.1029   3.8835");
        expected.add("     8  7.1899  43.4829  22.0791  61.8879  0.49314  54.4612   9.9334");
        expected.add("     9  8.0719  65.5621           83.5658  0.87101  95.8577  16.4911");
        expected.add("");
        expected.add("");
        expected.add("   Receiver Profile:");
        expected.add("");
        expected.add("                   Lat      Lon    Depth  R Earth        P   P crit");
        expected.add("   Location:   30.0000  90.0000   -1.000  6372.82   776.26   773.48");
        expected.add("   Pierce Pt:  30.7019  90.6585   71.168");
        expected.add("");
        expected.add("   Model Layers:");
        expected.add("");
        expected.add("     # Layer             Vel      Top    Thick");
        expected.add("     1 water          1.5000  -5.1589   0.0000");
        expected.add("     2 sediment1      2.4992  -5.1589   0.0524");
        expected.add("     3 sediment2      0.0000  -5.1065   0.0000");
        expected.add("     4 sediment3      0.0000  -5.1065   0.0000");
        expected.add("     5 upper_crust    5.9980  -5.1065  24.2412");
        expected.add("     6 middle_crust   6.3979  19.1347  26.0179");
        expected.add("     8 lower_crust    7.0976  45.1526  26.0158");
        expected.add("     9 mantle         8.1471  71.1684");
        expected.add("");
        expected.add("");
        expected.add("   Applied Layers:");
        expected.add("");
        expected.add("     #     Vel      Top    Thick   i, deg   X, deg    X, km       TT");
        expected.add("     2  2.4992  -1.0000  -4.1065  17.7202  0.00000   0.0000   0.0000");
        expected.add("     5  5.9980  -5.1065  24.2412  46.8877 -0.01174  -1.3069  -1.7243");
        expected.add("     6  6.3979  19.1347  26.0179  51.4122  0.22048  24.4502   4.1781");
        expected.add("     8  7.0976  45.1526  26.0158  60.5416  0.51398  56.7629  10.6827");
        expected.add("     9  8.1471  71.1684           90.0000  0.92932 102.2107  18.1009");
        expected.add("");
        expected.add("");
        expected.add("   Grid Node Weights:");
        expected.add("");
        expected.add("      grid_id   active_id         weight");
        expected.add("        12797          -1    11.69851252");
        expected.add("        12813          -1    86.93580889");
        expected.add("        12790          -1     8.75154146");
        expected.add("         3227          -1     0.58625478");
        expected.add("        12814         116    69.05614783");
        expected.add("        12815          -1    24.17312314");
        expected.add("         3228          97    82.34420704");
        expected.add("        12807          28    10.52945936");
        expected.add("        12809          30    86.74248447");
        expected.add("        12805         115     6.06228838");
        expected.add("        12810          31    60.56127073");
        expected.add("         3229           8    32.17586532");
        expected.add("        12811          32    47.50673466");
        expected.add("");
        expected.add("      Sum of weights = 527.12369858 km");
        expected.add("");
        expected.add("   Head wave Profiles:");
        expected.add("");
        expected.add("     #     Lat      Lon    Moho  R Earth     Vel      Grad       dx   Active");
        expected.add("     0  34.963   94.960  65.685  6371.15  8.0713  0.001365   0.0000      -");
        expected.add("     1  34.889   94.880  65.932  6371.18  8.0702  0.001386   0.0000      -");
        expected.add("     2  34.814   94.800  66.179  6371.21  8.0691  0.001408   0.0000      -");
        expected.add("     3  34.740   94.720  66.426  6371.23  8.0679  0.001429   0.0000      -");
        expected.add("     4  34.666   94.641  66.673  6371.26  8.0668  0.001450   0.0000      -");
        expected.add("     5  34.591   94.561  66.920  6371.28  8.0657  0.001471   0.0000      -");
        expected.add("     6  34.517   94.482  67.198  6371.31  8.0669  0.001496   0.0000      -");
        expected.add("     7  34.442   94.403  67.477  6371.34  8.0683  0.001520   0.0000      -");
        expected.add("     8  34.368   94.324  67.756  6371.36  8.0698  0.001544   0.0538    n");
        expected.add("     9  34.293   94.245  68.035  6371.39  8.0712  0.001569   0.0990    n");
        expected.add("    10  34.219   94.167  68.314  6371.41  8.0726  0.001593   0.0990    n");
        expected.add("    11  34.144   94.088  68.593  6371.44  8.0740  0.001617   0.0990    n");
        expected.add("    12  34.069   94.010  68.871  6371.46  8.0754  0.001642   0.0990    n");
        expected.add("    13  33.994   93.931  69.137  6371.49  8.0776  0.001671   0.0990    n");
        expected.add("    14  33.919   93.853  69.364  6371.52  8.0820  0.001711   0.0990    n");
        expected.add("    15  33.844   93.775  69.599  6371.54  8.0863  0.001742   0.0990    n");
        expected.add("    16  33.770   93.697  69.823  6371.57  8.0914  0.001777   0.0990    n");
        expected.add("    17  33.694   93.619  70.047  6371.59  8.0965  0.001812   0.0990    n");
        expected.add("    18  33.619   93.542  70.270  6371.62  8.1017  0.001848   0.0990    n");
        expected.add("    19  33.544   93.464  70.494  6371.65  8.1068  0.001883   0.0990    n");
        expected.add("    20  33.469   93.387  70.717  6371.67  8.1120  0.001919   0.0990    n");
        expected.add("    21  33.394   93.310  70.941  6371.70  8.1171  0.001954   0.0990    n");
        expected.add("    22  33.319   93.233  71.165  6371.72  8.1223  0.001989   0.0990    n");
        expected.add("    23  33.243   93.156  71.384  6371.75  8.1240  0.001980   0.0990    n");
        expected.add("    24  33.168   93.079  71.603  6371.77  8.1250  0.001962   0.0990    n");
        expected.add("    25  33.093   93.002  71.822  6371.80  8.1260  0.001944   0.0990    n");
        expected.add("    26  33.017   92.926  72.041  6371.83  8.1270  0.001926   0.0990    n");
        expected.add("    27  32.942   92.849  72.260  6371.85  8.1280  0.001909   0.0990    n");
        expected.add("    28  32.866   92.773  72.424  6371.88  8.1313  0.001899   0.0990     y");
        expected.add("    29  32.790   92.697  72.563  6371.90  8.1355  0.001893   0.0990     y");
        expected.add("    30  32.715   92.621  72.702  6371.93  8.1398  0.001887   0.0990     y");
        expected.add("    31  32.639   92.545  72.833  6371.95  8.1421  0.001870   0.0990     y");
        expected.add("    32  32.563   92.469  72.944  6371.98  8.1396  0.001826   0.0990     y");
        expected.add("    33  32.487   92.393  73.054  6372.00  8.1371  0.001783   0.0990     y");
        expected.add("    34  32.412   92.318  73.165  6372.03  8.1345  0.001739   0.0990     y");
        expected.add("    35  32.336   92.242  73.275  6372.06  8.1320  0.001696   0.0990     y");
        expected.add("    36  32.260   92.167  73.381  6372.08  8.1282  0.001651   0.0990     y");
        expected.add("    37  32.184   92.092  73.481  6372.11  8.1228  0.001603   0.0990     y");
        expected.add("    38  32.108   92.017  73.582  6372.13  8.1175  0.001556   0.0990     y");
        expected.add("    39  32.032   91.942  73.682  6372.16  8.1121  0.001508   0.0990     y");
        expected.add("    40  31.956   91.867  73.756  6372.18  8.1017  0.001453   0.0990     y");
        expected.add("    41  31.879   91.792  73.822  6372.21  8.0899  0.001394   0.0990     y");
        expected.add("    42  31.803   91.718  73.871  6372.23  8.0782  0.001335   0.0990     y");
        expected.add("    43  31.727   91.643  73.843  6372.26  8.0672  0.001274   0.0990     y");
        expected.add("    44  31.651   91.569  73.816  6372.28  8.0562  0.001212   0.0990     y");
        expected.add("    45  31.574   91.495  73.789  6372.31  8.0451  0.001150   0.0990     y");
        expected.add("    46  31.498   91.421  73.762  6372.34  8.0341  0.001088   0.0990     y");
        expected.add("    47  31.422   91.347  73.735  6372.36  8.0231  0.001027   0.0990     y");
        expected.add("    48  31.345   91.273  73.699  6372.39  8.0149  0.000974   0.0990     y");
        expected.add("    49  31.269   91.199  73.636  6372.41  8.0160  0.000951   0.0990     y");
        expected.add("    50  31.192   91.126  73.574  6372.44  8.0172  0.000929   0.0990     y");
        expected.add("    51  31.115   91.052  73.511  6372.46  8.0183  0.000906   0.0990     y");
        expected.add("    52  31.039   90.979  73.448  6372.49  8.0194  0.000883   0.0990     y");
        expected.add("    53  30.962   90.906  73.386  6372.51  8.0205  0.000860   0.0990     y");
        expected.add("    54  30.885   90.833  73.323  6372.54  8.0217  0.000838   0.0990     y");
        expected.add("    55  30.809   90.760  73.260  6372.56  8.0228  0.000815   0.0990     y");
        expected.add("    56  30.732   90.687  73.197  6372.59  8.0239  0.000792   0.0879     y");
        expected.add("    57  30.655   90.614  73.026  6372.61  8.0339  0.000806   0.0000      -");
        expected.add("    58  30.578   90.541  72.808  6372.64  8.0472  0.000834   0.0000      -");
        expected.add("    59  30.501   90.469  72.590  6372.66  8.0605  0.000863   0.0000      -");
        expected.add("    60  30.424   90.396  72.371  6372.69  8.0738  0.000891   0.0000      -");
        expected.add("    61  30.347   90.324  72.153  6372.71  8.0872  0.000919   0.0000      -");
        expected.add("    62  30.270   90.252  71.934  6372.74  8.1005  0.000948   0.0000      -");
        expected.add("    63  30.193   90.180  71.715  6372.76  8.1138  0.000976   0.0000      -");
        expected.add("    64  30.116   90.108  71.497  6372.79  8.1271  0.001004   0.0000      -");
        expected.add("    65  30.039   90.036  71.278  6372.81  8.1404  0.001033   0.0000      -");
        expected.add("");
        expected.add("");
        expected.add("   Head wave Profile Interpolation Coefficients:");
        expected.add("");
        expected.add("     #     id     coeff     id     coeff     id     coeff");
        expected.add("     0    819  0.591268  12797  0.120898  12790  0.287835");
        expected.add("     1    819  0.474266  12797  0.189740  12790  0.335994");
        expected.add("     2    819  0.357266  12797  0.258582  12790  0.384152");
        expected.add("     3    819  0.240266  12797  0.327424  12790  0.432310");
        expected.add("     4    819  0.123266  12797  0.396266  12790  0.480468");
        expected.add("     5    819  0.006265  12797  0.465108  12790  0.528627");
        expected.add("     6  12797  0.423226  12813  0.110714  12790  0.466060");
        expected.add("     7  12797  0.375081  12813  0.227690  12790  0.397229");
        expected.add("     8  12797  0.326935  12813  0.344667  12790  0.328398");
        expected.add("     9  12797  0.278790  12813  0.461644  12790  0.259566");
        expected.add("    10  12797  0.230643  12813  0.578622  12790  0.190734");
        expected.add("    11  12797  0.182496  12813  0.695602  12790  0.121901");
        expected.add("    12  12797  0.134348  12813  0.812585  12790  0.053067");
        expected.add("    13  12797  0.070429   3227  0.015772  12813  0.913799");
        expected.add("    14   3227  0.038073  12814  0.046523  12813  0.915405");
        expected.add("    15  12814  0.153381  12815  0.010037  12813  0.836582");
        expected.add("    16  12814  0.222171  12815  0.058139  12813  0.719690");
        expected.add("    17  12814  0.290959  12815  0.106240  12813  0.602801");
        expected.add("    18  12814  0.359746  12815  0.154340  12813  0.485914");
        expected.add("    19  12814  0.428532  12815  0.202440  12813  0.369028");
        expected.add("    20  12814  0.497318  12815  0.250539  12813  0.252143");
        expected.add("    21  12814  0.566104  12815  0.298639  12813  0.135257");
        expected.add("    22  12814  0.634891  12815  0.346739  12813  0.018370");
        expected.add("    23  12814  0.605149   3228  0.098537  12815  0.296314");
        expected.add("    24  12814  0.557035   3228  0.215446  12815  0.227519");
        expected.add("    25  12814  0.508921   3228  0.332355  12815  0.158724");
        expected.add("    26  12814  0.460807   3228  0.449265  12815  0.089928");
        expected.add("    27  12814  0.412692   3228  0.566177  12815  0.021131");
        expected.add("    28  12814  0.316908  12807  0.047693   3228  0.635399");
        expected.add("    29  12814  0.199993  12807  0.116529   3228  0.683478");
        expected.add("    30  12814  0.083078  12807  0.185365   3228  0.731558");
        expected.add("    31   3228  0.745769  12807  0.220285  12809  0.033946");
        expected.add("    32   3228  0.676829  12807  0.171939  12809  0.151232");
        expected.add("    33   3228  0.607890  12807  0.123594  12809  0.268516");
        expected.add("    34   3228  0.538950  12807  0.075248  12809  0.385801");
        expected.add("    35   3228  0.470011  12807  0.026903  12809  0.503086");
        expected.add("    36   3228  0.379631  12809  0.598939  12805  0.021430");
        expected.add("    37   3228  0.262352  12809  0.667901  12805  0.069747");
        expected.add("    38   3228  0.145072  12809  0.736863  12805  0.118065");
        expected.add("    39   3228  0.027791  12809  0.805826  12805  0.166382");
        expected.add("    40  12809  0.785305  12810  0.089473  12805  0.125222");
        expected.add("    41  12809  0.736995  12810  0.206731  12805  0.056274");
        expected.add("    42  12809  0.676009   3229  0.012676  12810  0.311315");
        expected.add("    43  12809  0.558744   3229  0.081633  12810  0.359623");
        expected.add("    44  12809  0.441480   3229  0.150590  12810  0.407931");
        expected.add("    45  12809  0.324217   3229  0.219545  12810  0.456238");
        expected.add("    46  12809  0.206955   3229  0.288501  12810  0.504545");
        expected.add("    47  12809  0.089692   3229  0.357456  12810  0.552852");
        expected.add("    48  12810  0.573583   3229  0.398824  12811  0.027593");
        expected.add("    49  12810  0.504607   3229  0.350444  12811  0.144949");
        expected.add("    50  12810  0.435631   3229  0.302064  12811  0.262305");
        expected.add("    51  12810  0.366656   3229  0.253685  12811  0.379660");
        expected.add("    52  12810  0.297680   3229  0.205305  12811  0.497016");
        expected.add("    53  12810  0.228703   3229  0.156925  12811  0.614373");
        expected.add("    54  12810  0.159725   3229  0.108543  12811  0.731732");
        expected.add("    55  12810  0.090746   3229  0.060161  12811  0.849093");
        expected.add("    56  12810  0.021764   3229  0.011777  12811  0.966458");
        expected.add("    57  12811  0.927534  20432  0.047220     57  0.025246");
        expected.add("    58  12811  0.826765  20432  0.116203     57  0.057032");
        expected.add("    59  12811  0.725998  20432  0.185185     57  0.088817");
        expected.add("    60  12811  0.625234  20432  0.254164     57  0.120601");
        expected.add("    61  12811  0.524471  20432  0.323143     57  0.152385");
        expected.add("    62  12811  0.423709  20432  0.392122     57  0.184169");
        expected.add("    63  12811  0.322948  20432  0.461100     57  0.215953");
        expected.add("    64  12811  0.222185  20432  0.530078     57  0.247736");
        expected.add("    65  12811  0.121422  20432  0.599057     57  0.279520");
        expected.add("");
        expected.add("");
        expected.add("Horizontal slowness = 765.2831 sec/radian");

//		for (int i=0; i<actual.size(); ++i)
//		System.out.printf("expected.add(\"%s\");%n", actual.get(i));
//
        assertEquals(expected.size(), actual.size());
        for (int i=0; i<expected.size(); ++i)
            assertEquals(expected.get(i), actual.get(i));
    }

    @Test
    public void testGetTravelTime() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetTravelTime()");
        assertEquals(101.2545, slbm.getTravelTime(), 1e-2);
    }

    @Test
    public void testGetPhase() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetPhase()");
        assertEquals("Pn", slbm.getPhase());
    }

    @Test
    public void testGetDistance() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetDistance()");
        assertEquals(6.53306, slbm.getDistance() * rtd, 1e-4);
    }

    @Test
    public void testGetSourceDistance() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetSourceDistance()");
        assertEquals(0.837102, slbm.getSourceDistance() * rtd, 1e-3);
    }

    @Test
    public void testGetReceiverDistance() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetReceiverDistance()");
        assertEquals(0.901937, slbm.getReceiverDistance() * rtd, 1e-3);
    }

    @Test
    public void testGetHeadwaveDistance() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetHeadwaveDistance()");
        assertEquals(4.79405, slbm.getHeadwaveDistance() * rtd, 1e-3);
    }

    @Test
    public void testGetHeadwaveDistanceKm() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetHeadwaveDistanceKm()");
        assertEquals(527.1236985, slbm.getHeadwaveDistanceKm(), 1e-1);
    }

    @Test
    public void testGetTravelTimeComponents() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetTravelTimeComponents()");
        double[] actual = getDoubles(slbm.getTravelTimeComponents(), false);
        double[] expected = new double[] { 101.254100, 17.331220, 18.827075,
                65.186551, -0.090746 };

        assertEquals(expected.length, actual.length);
        for (int i = 0; i < expected.length; ++i)
            assertEquals(expected[i], actual[i], 1e-1);
    }

    @Test
    public void testGetWeights() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetWeights()");
        GridWeight weights = slbm.getWeights();

        // for (int i=0; i<weights.node.length; ++i)
        // {
        // GridProfile node = slbm.getGridData(weights.node[i]);
        // System.out.printf("%10.4f %10.4f%n", node.lat*rtd, node.lon*rtd);
        // }

        ArrayList<String> actual = getRecords(weights.toString(), false);

        ArrayList<String> expected = new ArrayList<String>(16);
        expected.add("Grid Node Weights: ");
        expected.add("");
        expected.add("  Node     Weight");
        expected.add(" 13338    86.9359");
        expected.add(" 13341     8.7516");
        expected.add(" 13342    11.6986");
        expected.add("  3356     0.5863");
        expected.add(" 13339    69.0562");
        expected.add(" 13340    24.1731");
        expected.add("  3354    82.3442");
        expected.add(" 13344    10.5295");
        expected.add(" 13349    86.7425");
        expected.add(" 13348     6.0623");
        expected.add(" 13347    60.5613");
        expected.add("  3357    32.1759");
        expected.add(" 13350    47.5072");

        assertEquals(expected.size(), actual.size());
        for (int i=0; i<expected.size(); ++i)
            assertEquals(expected.get(i), actual.get(i));


        // the sum of the weights should be equal to the headwave distance
        // in km.
        assertEquals(weights.getSum(), slbm.getHeadwaveDistanceKm(), 1e-2);
    }

    @Test
    public void testGetWeightsSource() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetWeightsSource()");
        GridWeight weights = slbm.getWeightsSource();
        ArrayList<String> actual = getRecords(weights.toString(), false);

        ArrayList<String> expected = new ArrayList<String>(6);
        expected.add("Grid Node Weights: ");
        expected.add("");
        expected.add("  Node     Weight");
        expected.add("   846     0.6498");
        expected.add(" 13342     0.0865");
        expected.add(" 13341     0.2638");

        assertEquals(expected.size(), actual.size());
        for (int i = 0; i < expected.size(); ++i)
            assertEquals(expected.get(i), actual.get(i));

        // the sum of the weights should be equal to one (three corners of
        // triangle).
        assertEquals(1., weights.getSum(), 1e-2);
    }

    @Test
    public void testGetActiveNodeWeightsSource() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetActiveNodeWeightsSource()");
        ArrayList<String> actual = getRecords(
                slbm.getActiveNodeWeightsSource().toString(), false);
        ArrayList<String> expected = new ArrayList<String>(6);
        expected.add("Grid Node Weights: ");
        expected.add("");
        expected.add("  Node     Weight");
        expected.add("    -1     0.6498");
        expected.add("    -1     0.0865");
        expected.add("    -1     0.2638");

        assertEquals(expected.size(), actual.size());
        for (int i=0; i<expected.size(); ++i)
            assertEquals(expected.get(i), actual.get(i));
    }

    @Test
    public void testGetWeightsReceiver() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetWeightsReceiver()");
        GridWeight weights = slbm.getWeightsReceiver();
        ArrayList<String> actual = getRecords(weights.toString(), false);

        ArrayList<String> expected = new ArrayList<String>(6);
        expected.add("Grid Node Weights: ");
        expected.add("");
        expected.add("  Node     Weight");
        expected.add("    57     0.2954");
        expected.add(" 13350     0.0710");
        expected.add(" 20825     0.6335");

        assertEquals(expected.size(), actual.size());
        for (int i=0; i<expected.size(); ++i)
            assertEquals(expected.get(i), actual.get(i));

        // the sum of the weights should be equal to one (three corners of
        // triangle).
        assertEquals(1., weights.getSum(), 1e-2);
    }

    @Test
    public void testGetActiveNodeWeightsReceiver() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetActiveNodeWeightsReceiver()");
        GridWeight weights = slbm.getActiveNodeWeightsReceiver();
        ArrayList<String> actual = getRecords(weights.toString(), false);
        ArrayList<String> expected = new ArrayList<String>(6);
        expected.add("Grid Node Weights: ");
        expected.add("");
        expected.add("  Node     Weight");
        expected.add("     0     0.2954");
        expected.add("    46     0.0710");
        expected.add("    52     0.6335");

        assertEquals(expected.size(), actual.size());
        for (int i=0; i<expected.size(); ++i)
            assertEquals(expected.get(i), actual.get(i));

        // the sum of the weights should be equal to one (three corners of
        // triangle).
        assertEquals(1., weights.getSum(), 1e-2);
    }

    @Test
    public void testGetSourceNodeIds() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetSourceNodeIds()");
        int[] actual = getInts(slbm.getSourceNodeIds(), false);
        int[] expected = new int[] {846, 13342, 13341};

        assertEquals(expected.length, actual.length);
        for (int i=0; i<expected.length; ++i)
            assertEquals(expected[i], actual[i]);

    }

    @Test
    public void testGetSourceCoefficients() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetSourceCoefficients()");
        double[] actual = getDoubles(slbm.getSourceCoefficients(), false);
        double[] expected = new double[] { 0.649769, 0.086476, 0.263755 };

        assertEquals(expected.length, actual.length);
        for (int i = 0; i < expected.length; ++i)
            assertEquals(expected[i], actual[i], 1e-3);

        assertEquals(1.000000, getSum(actual), 1e-4);

    }

    @Test
    public void testGetReceiverNodeIds() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetReceiverNodeIds()");
        int[] actual = getInts(slbm.getReceiverNodeIds(), false);
        int[] expected = new int[] {57, 13350, 20825};

        assertEquals(expected.length, actual.length);
        for (int i=0; i<expected.length; ++i)
            assertEquals(expected[i], actual[i]);

    }

    @Test
    public void testGetReceiverCoefficients() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetReceiverCoefficients()");
        double[] actual = getDoubles(slbm.getReceiverCoefficients(), false);
        double[] expected = new double[] {0.295413, 0.071040, 0.633547};

        assertEquals(expected.length, actual.length);
        for (int i = 0; i < expected.length; ++i)
            assertEquals(expected[i], actual[i], 1e-3);

        assertEquals(1.000000, getSum(actual), 1e-4);

    }

    @Test
    public void testGetGridData() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetGridData()");
        ArrayList<String> actual = getRecords(slbm.getGridData(57).toString(), false);
        ArrayList<String> expected = new ArrayList<String>(18);
        expected.add("GridProfile:");
        expected.add("");
        expected.add("  Node ID  :         57");
        expected.add("  Latitude :    30.5474");
        expected.add("  Longitude:    89.5330");
        expected.add("");
        expected.add("     Depth        Thick      P Vel      S Vel");
        expected.add("   -5.522179     0.0000     1.5000     0.0000");
        expected.add("   -5.522179     0.1001     2.5013     1.1987");
        expected.add("   -5.422081     0.0000     0.0000     0.0000");
        expected.add("   -5.422081     0.0000     0.0000     0.0000");
        expected.add("   -5.422081    24.9502     6.0032     3.4582");
        expected.add("   19.528114     0.0000     6.4034     3.6960");
        expected.add("   19.528114    26.7808     6.1350     3.5024");
        expected.add("   46.308876    26.7813     7.1038     3.8958");
        expected.add("   73.090126                8.1063     4.5955");
        expected.add("               P Grad     S Grad");
        expected.add("             0.000720  -0.000055");

        assertEquals(expected.size(), actual.size());
        for (int i=0; i<expected.size(); ++i)
            assertEquals(expected.get(i), actual.get(i));

    }

    @Test
    public void testSetGridData() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testSetGridData()");

        GridProfile n0 = slbm.getGridData(57);

        GridProfile n = slbm.getGridData(57);

        for (int i=0; i<n.depth.length; ++i)
        {
            n.depth[i] += 1;
            n.velocity[SlbmInterface.PWAVE][i] += 0.1;
            n.velocity[SlbmInterface.SWAVE][i] -= 0.1;
        }

        slbm.setGridData(n);

        ArrayList<String> actual = getRecords(slbm.getGridData(57).toString(), false);
        ArrayList<String> expected = new ArrayList<String>(18);
        expected.add("GridProfile:");
        expected.add("");
        expected.add("  Node ID  :         57");
        expected.add("  Latitude :    30.5474");
        expected.add("  Longitude:    89.5330");
        expected.add("");
        expected.add("     Depth        Thick      P Vel      S Vel");
        expected.add("   -4.522179     0.0000     1.6000    -0.1000");
        expected.add("   -4.522179     0.1001     2.6013     1.0987");
        expected.add("   -4.422081     0.0000     0.1000    -0.1000");
        expected.add("   -4.422081     0.0000     0.1000    -0.1000");
        expected.add("   -4.422081    24.9502     6.1032     3.3582");
        expected.add("   20.528114     0.0000     6.5034     3.5960");
        expected.add("   20.528114    26.7808     6.2350     3.4024");
        expected.add("   47.308876    26.7813     7.2038     3.7958");
        expected.add("   74.090126                8.2063     4.4955");
        expected.add("               P Grad     S Grad");
        expected.add("             0.000720  -0.000055");

        assertEquals(expected.size(), actual.size());
        for (int i=0; i<expected.size(); ++i)
            assertEquals(expected.get(i), actual.get(i));

        slbm.setGridData(n0);
        actual = getRecords(slbm.getGridData(57).toString(), false);
        expected = new ArrayList<String>(18);
        expected.add("GridProfile:");
        expected.add("");
        expected.add("  Node ID  :         57");
        expected.add("  Latitude :    30.5474");
        expected.add("  Longitude:    89.5330");
        expected.add("");
        expected.add("     Depth        Thick      P Vel      S Vel");
        expected.add("   -5.522179     0.0000     1.5000     0.0000");
        expected.add("   -5.522179     0.1001     2.5013     1.1987");
        expected.add("   -5.422081     0.0000     0.0000     0.0000");
        expected.add("   -5.422081     0.0000     0.0000     0.0000");
        expected.add("   -5.422081    24.9502     6.0032     3.4582");
        expected.add("   19.528114     0.0000     6.4034     3.6960");
        expected.add("   19.528114    26.7808     6.1350     3.5024");
        expected.add("   46.308876    26.7813     7.1038     3.8958");
        expected.add("   73.090126                8.1063     4.5955");
        expected.add("               P Grad     S Grad");
        expected.add("             0.000720  -0.000055");

        assertEquals(expected.size(), actual.size());
        for (int i=0; i<expected.size(); ++i)
            assertEquals(expected.get(i), actual.get(i));

    }

    @Test
    public void testSetActiveNodeData()
    {
        if (verbosity > 0)
            System.out.println("testSetActiveNodeData()");
        // TODO
    }

    @Test
    public void testGetInterpolatedPoint() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetInterpolatedPoint()");
        ArrayList<String> actual = getRecords(
                slbm.getInterpolatedPoint(30 * dtr, 90 * dtr).toString(), false);
        ArrayList<String> expected = new ArrayList<String>(21);
        expected.add("QueryProfile: ");
        expected.add("   Latitude :    30.0000");
        expected.add("   Longitude:    90.0000");
        expected.add("");
        expected.add("     Depth        Thick      P Vel      S Vel");
        expected.add("   -5.159090     0.0000     1.5000     0.0000");
        expected.add("   -5.159090     0.0524     2.4992     1.1987");
        expected.add("   -5.106667     0.0000     0.0000     0.0000");
        expected.add("   -5.106667     0.0000     0.0000     0.0000");
        expected.add("   -5.106667    24.2415     5.9980     3.4849");
        expected.add("   19.134823     0.0000     6.3979     3.6959");
        expected.add("   19.134823    26.0179     6.1050     3.6127");
        expected.add("   45.152732    26.0158     7.0976     3.8957");
        expected.add("   71.168550                8.1471     4.8279");
        expected.add("               P Grad     S Grad");
        expected.add("               0.001047  -0.000052");
        expected.add("");
        expected.add("    NodeId      Coeff");
        expected.add("        57     0.2954");
        expected.add("     13350     0.0710");
        expected.add("     20825     0.6335");

        assertEquals(expected.size(), actual.size());
        for (int i = 0; i < expected.size(); ++i)
            assertEquals(expected.get(i), actual.get(i));
    }

    @Test
    public void testGetInterpolatedTransect() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetInterpolatedTransect()");
        ArrayList<Double> lats = new ArrayList<Double>();
        ArrayList<Double> lons = new ArrayList<Double>();

        lats.add(30. * dtr);
        lons.add(90. * dtr);
        lats.add(31. * dtr);
        lons.add(91. * dtr);
        lats.add(32. * dtr);
        lons.add(92. * dtr);
        lats.add(33. * dtr);
        lons.add(93. * dtr);
        ArrayList<String> actual = getRecords(
                slbm.getInterpolatedTransect(lats, lons).toString(), false);
        ArrayList<String> expected = new ArrayList<String>(89);
        expected.add("[QueryProfile: ");
        expected.add("   Latitude :    30.0000");
        expected.add("   Longitude:    90.0000");
        expected.add("");
        expected.add("     Depth        Thick      P Vel      S Vel");
        expected.add("   -5.159090     0.0000     1.5000     0.0000");
        expected.add("   -5.159090     0.0524     2.4992     1.1987");
        expected.add("   -5.106667     0.0000     0.0000     0.0000");
        expected.add("   -5.106667     0.0000     0.0000     0.0000");
        expected.add("   -5.106667    24.2415     5.9980     3.4849");
        expected.add("   19.134823     0.0000     6.3979     3.6959");
        expected.add("   19.134823    26.0179     6.1050     3.6127");
        expected.add("   45.152732    26.0158     7.0976     3.8957");
        expected.add("   71.168550                8.1471     4.8279");
        expected.add("               P Grad     S Grad");
        expected.add("               0.001047  -0.000052");
        expected.add("");
        expected.add("    NodeId      Coeff");
        expected.add("        57     0.2954");
        expected.add("     13350     0.0710");
        expected.add("     20825     0.6335");
        expected.add("");
        expected.add(", QueryProfile: ");
        expected.add("   Latitude :    31.0000");
        expected.add("   Longitude:    91.0000");
        expected.add("");
        expected.add("     Depth        Thick      P Vel      S Vel");
        expected.add("   -4.888615     0.0000     1.5000     0.0000");
        expected.add("   -4.888615     0.0933     2.4999     1.1954");
        expected.add("   -4.795268     0.0000     0.0000     0.0000");
        expected.add("   -4.795268     0.0000     0.0000     0.0000");
        expected.add("   -4.795268    24.8510     5.9998     3.4867");
        expected.add("   20.055776     0.0000     6.3997     3.6860");
        expected.add("   20.055776    26.6672     6.1550     3.5174");
        expected.add("   46.722969    26.6676     7.0997     3.8852");
        expected.add("   73.390585                8.0237     4.5132");
        expected.add("               P Grad     S Grad");
        expected.add("               0.000895   0.000024");
        expected.add("");
        expected.add("    NodeId      Coeff");
        expected.add("      3357     0.2336");
        expected.add("     13350     0.5117");
        expected.add("     13347     0.2548");
        expected.add("");
        expected.add(", QueryProfile: ");
        expected.add("   Latitude :    32.0000");
        expected.add("   Longitude:    92.0000");
        expected.add("");
        expected.add("     Depth        Thick      P Vel      S Vel");
        expected.add("   -4.894959     0.0000     1.5000     0.0000");
        expected.add("   -4.894959     0.0513     2.5001     1.2053");
        expected.add("   -4.843643     0.0000     0.0000     0.0000");
        expected.add("   -4.843643     0.0000     0.0000     0.0000");
        expected.add("   -4.843643    24.9525     6.0002     3.4483");
        expected.add("   20.108882     0.0000     6.4003     3.7163");
        expected.add("   20.108882    26.7736     6.1686     3.4781");
        expected.add("   46.882481    26.7786     7.1003     3.9172");
        expected.add("   73.661040                8.1185     4.6598");
        expected.add("               P Grad     S Grad");
        expected.add("               0.001541   0.000300");
        expected.add("");
        expected.add("    NodeId      Coeff");
        expected.add("      3354     0.0474");
        expected.add("     13349     0.8461");
        expected.add("     13348     0.1064");
        expected.add("");
        expected.add(", QueryProfile: ");
        expected.add("   Latitude :    33.0000");
        expected.add("   Longitude:    93.0000");
        expected.add("");
        expected.add("     Depth        Thick      P Vel      S Vel");
        expected.add("   -5.058974     0.0000     1.5000     0.0000");
        expected.add("   -5.058974     0.0853     2.5006     1.2030");
        expected.add("   -4.973709     0.0000     0.0000     0.0000");
        expected.add("   -4.973709     0.0000     0.0000     0.0000");
        expected.add("   -4.973709    24.4668     6.0014     3.4245");
        expected.add("   19.493116     0.0000     6.4015     3.7091");
        expected.add("   19.493116    26.2549     6.1649     3.4439");
        expected.add("   45.747999    26.2569     7.1016     3.9096");
        expected.add("   72.004913                8.1267     4.5723");
        expected.add("               P Grad     S Grad");
        expected.add("               0.001945   0.000435");
        expected.add("");
        expected.add("    NodeId      Coeff");
        expected.add("      3354     0.4057");
        expected.add("     13340     0.0633");
        expected.add("     13339     0.5309");
        expected.add("");
        expected.add("]");

        assertEquals(expected.size(), actual.size());
        for (int i=0; i<expected.size(); ++i)
            assertEquals(expected.get(i), actual.get(i));

    }

    @Test
    public void testGetGreatCircleData() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetGreatCircleData()");
        ArrayList<String> actual = getRecords(
                slbm.getGreatCircleData().toString(), false);

        ArrayList<String> expected = new ArrayList<String>(78);
        expected.add("Source/Receiver Profiles:");
        expected.add(" -4.8287   1.5000     -5.1596   1.5000");
        expected.add(" -4.8287   2.5003     -5.1596   2.4992");
        expected.add(" -4.7992   2.1267     -5.1072   0.0000");
        expected.add(" -4.7992   0.0000     -5.1072   0.0000");
        expected.add(" -4.7992   6.0897     -5.1072   5.9980");
        expected.add(" 19.2494   6.3117     19.1343   6.3979");
        expected.add(" 19.2494   6.2214     19.1343   6.1050");
        expected.add(" 43.4828   7.1899     45.1522   7.0976");
        expected.add(" 65.5619   8.0719     71.1680   8.1471");
        expected.add("");
        expected.add("Headwave velocities, gradients,  nodeIds and coefficients");
        expected.add("  8.0713  0.001365       846  0.591268     13342  0.120898     13341  0.287835");
        expected.add("  8.0702  0.001386       846  0.474266     13342  0.189740     13341  0.335994");
        expected.add("  8.0691  0.001408       846  0.357266     13342  0.258582     13341  0.384152");
        expected.add("  8.0679  0.001429       846  0.240266     13342  0.327424     13341  0.432310");
        expected.add("  8.0668  0.001450       846  0.123266     13342  0.396266     13341  0.480468");
        expected.add("  8.0657  0.001471       846  0.006265     13342  0.465108     13341  0.528627");
        expected.add("  8.0669  0.001496     13338  0.110714     13341  0.466060     13342  0.423226");
        expected.add("  8.0683  0.001520     13338  0.227690     13341  0.397229     13342  0.375081");
        expected.add("  8.0698  0.001544     13338  0.344667     13341  0.328398     13342  0.326935");
        expected.add("  8.0712  0.001569     13338  0.461644     13341  0.259566     13342  0.278790");
        expected.add("  8.0726  0.001593     13338  0.578622     13341  0.190734     13342  0.230643");
        expected.add("  8.0740  0.001617     13338  0.695602     13341  0.121901     13342  0.182496");
        expected.add("  8.0754  0.001642     13338  0.812585     13341  0.053067     13342  0.134348");
        expected.add("  8.0776  0.001671      3356  0.015772     13338  0.913799     13342  0.070429");
        expected.add("  8.0820  0.001711      3356  0.038073     13339  0.046523     13338  0.915405");
        expected.add("  8.0863  0.001742     13338  0.836582     13339  0.153381     13340  0.010037");
        expected.add("  8.0914  0.001777     13338  0.719690     13339  0.222171     13340  0.058139");
        expected.add("  8.0965  0.001812     13338  0.602801     13339  0.290959     13340  0.106240");
        expected.add("  8.1017  0.001848     13338  0.485914     13339  0.359746     13340  0.154340");
        expected.add("  8.1068  0.001883     13338  0.369028     13339  0.428532     13340  0.202440");
        expected.add("  8.1120  0.001919     13338  0.252143     13339  0.497318     13340  0.250539");
        expected.add("  8.1171  0.001954     13338  0.135257     13339  0.566104     13340  0.298639");
        expected.add("  8.1223  0.001989     13338  0.018370     13339  0.634891     13340  0.346739");
        expected.add("  8.1240  0.001980      3354  0.098537     13340  0.296314     13339  0.605149");
        expected.add("  8.1250  0.001962      3354  0.215446     13340  0.227519     13339  0.557035");
        expected.add("  8.1260  0.001944      3354  0.332355     13340  0.158724     13339  0.508921");
        expected.add("  8.1270  0.001926      3354  0.449265     13340  0.089928     13339  0.460807");
        expected.add("  8.1280  0.001909      3354  0.566177     13340  0.021131     13339  0.412692");
        expected.add("  8.1313  0.001899      3354  0.635399     13339  0.316909     13344  0.047693");
        expected.add("  8.1355  0.001893      3354  0.683478     13339  0.199993     13344  0.116529");
        expected.add("  8.1398  0.001887      3354  0.731558     13339  0.083078     13344  0.185365");
        expected.add("  8.1421  0.001870      3354  0.745769     13344  0.220285     13349  0.033946");
        expected.add("  8.1396  0.001826      3354  0.676829     13344  0.171939     13349  0.151232");
        expected.add("  8.1371  0.001783      3354  0.607890     13344  0.123594     13349  0.268516");
        expected.add("  8.1345  0.001739      3354  0.538950     13344  0.075248     13349  0.385801");
        expected.add("  8.1320  0.001696      3354  0.470011     13344  0.026903     13349  0.503086");
        expected.add("  8.1282  0.001651      3354  0.379631     13349  0.598939     13348  0.021430");
        expected.add("  8.1228  0.001603      3354  0.262352     13349  0.667901     13348  0.069747");
        expected.add("  8.1175  0.001556      3354  0.145072     13349  0.736863     13348  0.118065");
        expected.add("  8.1121  0.001508      3354  0.027791     13349  0.805826     13348  0.166382");
        expected.add("  8.1017  0.001453     13347  0.089473     13348  0.125222     13349  0.785305");
        expected.add("  8.0899  0.001394     13347  0.206731     13348  0.056274     13349  0.736995");
        expected.add("  8.0782  0.001335      3357  0.012676     13347  0.311315     13349  0.676009");
        expected.add("  8.0672  0.001274      3357  0.081633     13347  0.359623     13349  0.558744");
        expected.add("  8.0562  0.001212      3357  0.150590     13347  0.407931     13349  0.441480");
        expected.add("  8.0451  0.001150      3357  0.219545     13347  0.456238     13349  0.324217");
        expected.add("  8.0341  0.001088      3357  0.288501     13347  0.504545     13349  0.206955");
        expected.add("  8.0231  0.001027      3357  0.357456     13347  0.552852     13349  0.089692");
        expected.add("  8.0149  0.000974      3357  0.398824     13350  0.027593     13347  0.573583");
        expected.add("  8.0160  0.000951      3357  0.350444     13350  0.144949     13347  0.504607");
        expected.add("  8.0172  0.000929      3357  0.302064     13350  0.262305     13347  0.435631");
        expected.add("  8.0183  0.000906      3357  0.253685     13350  0.379660     13347  0.366656");
        expected.add("  8.0194  0.000883      3357  0.205305     13350  0.497016     13347  0.297680");
        expected.add("  8.0205  0.000860      3357  0.156925     13350  0.614373     13347  0.228703");
        expected.add("  8.0217  0.000838      3357  0.108543     13350  0.731732     13347  0.159725");
        expected.add("  8.0228  0.000815      3357  0.060161     13350  0.849093     13347  0.090746");
        expected.add("  8.0239  0.000792      3357  0.011777     13350  0.966458     13347  0.021764");
        expected.add("  8.0339  0.000806        57  0.025246     13350  0.927534     20825  0.047220");
        expected.add("  8.0472  0.000834        57  0.057032     13350  0.826765     20825  0.116203");
        expected.add("  8.0605  0.000863        57  0.088817     13350  0.725998     20825  0.185185");
        expected.add("  8.0738  0.000891        57  0.120601     13350  0.625234     20825  0.254164");
        expected.add("  8.0872  0.000919        57  0.152385     13350  0.524471     20825  0.323143");
        expected.add("  8.1005  0.000948        57  0.184169     13350  0.423709     20825  0.392122");
        expected.add("  8.1138  0.000976        57  0.215953     13350  0.322948     20825  0.461100");
        expected.add("  8.1271  0.001004        57  0.247736     13350  0.222185     20825  0.530078");
        expected.add("  8.1404  0.001033        57  0.279521     13350  0.121422     20825  0.599057");

        assertEquals(expected.size(), actual.size());
        for (int i=0; i<expected.size(); ++i)
            assertEquals(expected.get(i), actual.get(i));

    }

    @Test
    public void testGetGreatCircleLocations() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetGreatCircleLocations()");
        double[][] actual = slbm.getGreatCircleLocations();
        boolean choice = false;
        if (choice)
        {
            int n = actual[0].length;
            double[] lat = actual[0];
            double[] lon = actual[1];
            double[] depth = actual[2];
            System.out.printf("double[] lat = new double[%d];%n", n);
            System.out.printf("double[] lon = new double[%d];%n", n);
            System.out.printf("double[] depth = new double[%d];%n", n);
            for (int i = 0; i < n; ++i)
                System.out
                .printf("lat[%3d] = %9.4f; lon[%3d] = %9.4f; depth[%3d] = %9.4f;%n",
                        i, lat[i] * rtd, i, lon[i] * rtd, i, depth[i]);
        }
        else
        {
            double[] lat = new double[66];
            double[] lon = new double[66];
            double[] depth = new double[66];
            lat[  0] =   34.9629; lon[  0] =   94.9600; depth[  0] =   65.6854;
            lat[  1] =   34.8887; lon[  1] =   94.8800; depth[  1] =   65.9324;
            lat[  2] =   34.8145; lon[  2] =   94.8001; depth[  2] =   66.1794;
            lat[  3] =   34.7402; lon[  3] =   94.7204; depth[  3] =   66.4264;
            lat[  4] =   34.6658; lon[  4] =   94.6409; depth[  4] =   66.6734;
            lat[  5] =   34.5914; lon[  5] =   94.5615; depth[  5] =   66.9204;
            lat[  6] =   34.5170; lon[  6] =   94.4822; depth[  6] =   67.1977;
            lat[  7] =   34.4424; lon[  7] =   94.4031; depth[  7] =   67.4767;
            lat[  8] =   34.3679; lon[  8] =   94.3241; depth[  8] =   67.7557;
            lat[  9] =   34.2933; lon[  9] =   94.2453; depth[  9] =   68.0346;
            lat[ 10] =   34.2186; lon[ 10] =   94.1665; depth[ 10] =   68.3136;
            lat[ 11] =   34.1439; lon[ 11] =   94.0880; depth[ 11] =   68.5925;
            lat[ 12] =   34.0691; lon[ 12] =   94.0095; depth[ 12] =   68.8715;
            lat[ 13] =   33.9943; lon[ 13] =   93.9312; depth[ 13] =   69.1367;
            lat[ 14] =   33.9194; lon[ 14] =   93.8531; depth[ 14] =   69.3636;
            lat[ 15] =   33.8445; lon[ 15] =   93.7751; depth[ 15] =   69.5992;
            lat[ 16] =   33.7695; lon[ 16] =   93.6972; depth[ 16] =   69.8229;
            lat[ 17] =   33.6945; lon[ 17] =   93.6194; depth[ 17] =   70.0465;
            lat[ 18] =   33.6194; lon[ 18] =   93.5418; depth[ 18] =   70.2702;
            lat[ 19] =   33.5443; lon[ 19] =   93.4643; depth[ 19] =   70.4938;
            lat[ 20] =   33.4691; lon[ 20] =   93.3869; depth[ 20] =   70.7174;
            lat[ 21] =   33.3939; lon[ 21] =   93.3097; depth[ 21] =   70.9411;
            lat[ 22] =   33.3186; lon[ 22] =   93.2326; depth[ 22] =   71.1647;
            lat[ 23] =   33.2433; lon[ 23] =   93.1557; depth[ 23] =   71.3843;
            lat[ 24] =   33.1679; lon[ 24] =   93.0789; depth[ 24] =   71.6032;
            lat[ 25] =   33.0925; lon[ 25] =   93.0022; depth[ 25] =   71.8220;
            lat[ 26] =   33.0170; lon[ 26] =   92.9256; depth[ 26] =   72.0409;
            lat[ 27] =   32.9415; lon[ 27] =   92.8492; depth[ 27] =   72.2597;
            lat[ 28] =   32.8660; lon[ 28] =   92.7729; depth[ 28] =   72.4235;
            lat[ 29] =   32.7904; lon[ 29] =   92.6967; depth[ 29] =   72.5630;
            lat[ 30] =   32.7147; lon[ 30] =   92.6206; depth[ 30] =   72.7024;
            lat[ 31] =   32.6390; lon[ 31] =   92.5447; depth[ 31] =   72.8335;
            lat[ 32] =   32.5633; lon[ 32] =   92.4689; depth[ 32] =   72.9439;
            lat[ 33] =   32.4875; lon[ 33] =   92.3933; depth[ 33] =   73.0542;
            lat[ 34] =   32.4116; lon[ 34] =   92.3177; depth[ 34] =   73.1646;
            lat[ 35] =   32.3357; lon[ 35] =   92.2423; depth[ 35] =   73.2749;
            lat[ 36] =   32.2598; lon[ 36] =   92.1670; depth[ 36] =   73.3809;
            lat[ 37] =   32.1838; lon[ 37] =   92.0919; depth[ 37] =   73.4813;
            lat[ 38] =   32.1078; lon[ 38] =   92.0168; depth[ 38] =   73.5817;
            lat[ 39] =   32.0317; lon[ 39] =   91.9419; depth[ 39] =   73.6821;
            lat[ 40] =   31.9556; lon[ 40] =   91.8671; depth[ 40] =   73.7561;
            lat[ 41] =   31.8795; lon[ 41] =   91.7924; depth[ 41] =   73.8218;
            lat[ 42] =   31.8032; lon[ 42] =   91.7179; depth[ 42] =   73.8705;
            lat[ 43] =   31.7270; lon[ 43] =   91.6435; depth[ 43] =   73.8434;
            lat[ 44] =   31.6507; lon[ 44] =   91.5692; depth[ 44] =   73.8162;
            lat[ 45] =   31.5744; lon[ 45] =   91.4950; depth[ 45] =   73.7890;
            lat[ 46] =   31.4980; lon[ 46] =   91.4209; depth[ 46] =   73.7618;
            lat[ 47] =   31.4216; lon[ 47] =   91.3470; depth[ 47] =   73.7346;
            lat[ 48] =   31.3451; lon[ 48] =   91.2731; depth[ 48] =   73.6990;
            lat[ 49] =   31.2686; lon[ 49] =   91.1994; depth[ 49] =   73.6364;
            lat[ 50] =   31.1920; lon[ 50] =   91.1258; depth[ 50] =   73.5737;
            lat[ 51] =   31.1154; lon[ 51] =   91.0524; depth[ 51] =   73.5110;
            lat[ 52] =   31.0388; lon[ 52] =   90.9790; depth[ 52] =   73.4483;
            lat[ 53] =   30.9621; lon[ 53] =   90.9058; depth[ 53] =   73.3855;
            lat[ 54] =   30.8854; lon[ 54] =   90.8327; depth[ 54] =   73.3228;
            lat[ 55] =   30.8086; lon[ 55] =   90.7597; depth[ 55] =   73.2600;
            lat[ 56] =   30.7318; lon[ 56] =   90.6868; depth[ 56] =   73.1972;
            lat[ 57] =   30.6549; lon[ 57] =   90.6140; depth[ 57] =   73.0265;
            lat[ 58] =   30.5780; lon[ 58] =   90.5413; depth[ 58] =   72.8080;
            lat[ 59] =   30.5011; lon[ 59] =   90.4688; depth[ 59] =   72.5895;
            lat[ 60] =   30.4241; lon[ 60] =   90.3964; depth[ 60] =   72.3711;
            lat[ 61] =   30.3471; lon[ 61] =   90.3240; depth[ 61] =   72.1525;
            lat[ 62] =   30.2700; lon[ 62] =   90.2518; depth[ 62] =   71.9340;
            lat[ 63] =   30.1929; lon[ 63] =   90.1797; depth[ 63] =   71.7155;
            lat[ 64] =   30.1158; lon[ 64] =   90.1078; depth[ 64] =   71.4969;
            lat[ 65] =   30.0386; lon[ 65] =   90.0359; depth[ 65] =   71.2783;

            assertEquals(lat.length, actual[0].length);
            for (int i = 0; i < lat.length; ++i)
            {
                assertEquals(lat[i], actual[0][i] * rtd, 1e-4);
                assertEquals(lon[i], actual[1][i] * rtd, 1e-4);
                assertEquals(depth[i], actual[2][i], 1e-3);
            }
        }
    }

    @Test
    public void testGetGreatCirclePoints() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetGreatCirclePoints()");
        double[][] actual = slbm.getGreatCirclePoints(30 * dtr, 90 * dtr,
                35 * dtr, 95 * dtr, 66);
        boolean choice = false;
        if (choice)
        {
            int n = actual[0].length;
            double[] lat = actual[0];
            double[] lon = actual[1];
            System.out.printf("double[] lat = new double[%d];%n", n);
            System.out.printf("double[] lon = new double[%d];%n", n);
            for (int i = 0; i < n; ++i)
                System.out.printf("lat[%3d] = %9.4f; lon[%3d] = %9.4f;%n", i,
                        lat[i] * rtd, i, lon[i] * rtd);
        }
        else
        {
            double[] lat = new double[66];
            double[] lon = new double[66];
            lat[  0] =   30.0000; lon[  0] =   90.0000;
            lat[  1] =   30.0784; lon[  1] =   90.0729;
            lat[  2] =   30.1567; lon[  2] =   90.1460;
            lat[  3] =   30.2350; lon[  3] =   90.2191;
            lat[  4] =   30.3133; lon[  4] =   90.2924;
            lat[  5] =   30.3915; lon[  5] =   90.3658;
            lat[  6] =   30.4697; lon[  6] =   90.4393;
            lat[  7] =   30.5478; lon[  7] =   90.5129;
            lat[  8] =   30.6259; lon[  8] =   90.5866;
            lat[  9] =   30.7040; lon[  9] =   90.6604;
            lat[ 10] =   30.7820; lon[ 10] =   90.7344;
            lat[ 11] =   30.8600; lon[ 11] =   90.8085;
            lat[ 12] =   30.9379; lon[ 12] =   90.8827;
            lat[ 13] =   31.0158; lon[ 13] =   90.9570;
            lat[ 14] =   31.0936; lon[ 14] =   91.0315;
            lat[ 15] =   31.1714; lon[ 15] =   91.1060;
            lat[ 16] =   31.2491; lon[ 16] =   91.1807;
            lat[ 17] =   31.3268; lon[ 17] =   91.2555;
            lat[ 18] =   31.4045; lon[ 18] =   91.3305;
            lat[ 19] =   31.4821; lon[ 19] =   91.4055;
            lat[ 20] =   31.5597; lon[ 20] =   91.4807;
            lat[ 21] =   31.6372; lon[ 21] =   91.5560;
            lat[ 22] =   31.7147; lon[ 22] =   91.6314;
            lat[ 23] =   31.7921; lon[ 23] =   91.7070;
            lat[ 24] =   31.8695; lon[ 24] =   91.7827;
            lat[ 25] =   31.9468; lon[ 25] =   91.8585;
            lat[ 26] =   32.0241; lon[ 26] =   91.9344;
            lat[ 27] =   32.1014; lon[ 27] =   92.0105;
            lat[ 28] =   32.1786; lon[ 28] =   92.0867;
            lat[ 29] =   32.2557; lon[ 29] =   92.1630;
            lat[ 30] =   32.3328; lon[ 30] =   92.2394;
            lat[ 31] =   32.4099; lon[ 31] =   92.3160;
            lat[ 32] =   32.4869; lon[ 32] =   92.3927;
            lat[ 33] =   32.5638; lon[ 33] =   92.4695;
            lat[ 34] =   32.6408; lon[ 34] =   92.5465;
            lat[ 35] =   32.7176; lon[ 35] =   92.6236;
            lat[ 36] =   32.7944; lon[ 36] =   92.7008;
            lat[ 37] =   32.8712; lon[ 37] =   92.7781;
            lat[ 38] =   32.9479; lon[ 38] =   92.8556;
            lat[ 39] =   33.0246; lon[ 39] =   92.9333;
            lat[ 40] =   33.1012; lon[ 40] =   93.0110;
            lat[ 41] =   33.1778; lon[ 41] =   93.0889;
            lat[ 42] =   33.2543; lon[ 42] =   93.1669;
            lat[ 43] =   33.3308; lon[ 43] =   93.2451;
            lat[ 44] =   33.4072; lon[ 44] =   93.3234;
            lat[ 45] =   33.4836; lon[ 45] =   93.4018;
            lat[ 46] =   33.5599; lon[ 46] =   93.4804;
            lat[ 47] =   33.6362; lon[ 47] =   93.5591;
            lat[ 48] =   33.7124; lon[ 48] =   93.6379;
            lat[ 49] =   33.7885; lon[ 49] =   93.7169;
            lat[ 50] =   33.8647; lon[ 50] =   93.7960;
            lat[ 51] =   33.9407; lon[ 51] =   93.8753;
            lat[ 52] =   34.0167; lon[ 52] =   93.9547;
            lat[ 53] =   34.0927; lon[ 53] =   94.0343;
            lat[ 54] =   34.1686; lon[ 54] =   94.1139;
            lat[ 55] =   34.2444; lon[ 55] =   94.1938;
            lat[ 56] =   34.3202; lon[ 56] =   94.2737;
            lat[ 57] =   34.3960; lon[ 57] =   94.3539;
            lat[ 58] =   34.4717; lon[ 58] =   94.4341;
            lat[ 59] =   34.5473; lon[ 59] =   94.5145;
            lat[ 60] =   34.6229; lon[ 60] =   94.5951;
            lat[ 61] =   34.6984; lon[ 61] =   94.6758;
            lat[ 62] =   34.7739; lon[ 62] =   94.7566;
            lat[ 63] =   34.8493; lon[ 63] =   94.8376;
            lat[ 64] =   34.9247; lon[ 64] =   94.9187;
            lat[ 65] =   35.0000; lon[ 65] =   95.0000;

            assertEquals(lat.length, actual[0].length);
            for (int i = 0; i < lat.length; ++i)
            {
                assertEquals(lat[i], actual[0][i] * rtd, 1e-4);
                assertEquals(lon[i], actual[1][i] * rtd, 1e-4);
            }
        }
    }

    @Test
    public void testGetGreatCirclePointsOnCenters() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetGreatCirclePointsOnCenters()");
        double[][] actual = slbm.getGreatCirclePointsOnCenters(30 * dtr,
                90 * dtr, 35 * dtr, 95 * dtr, 66);
        boolean choice = false;
        if (choice)
        {
            int n = actual[0].length;
            double[] lat = actual[0];
            double[] lon = actual[1];
            System.out.printf("double[] lat = new double[%d];%n", n);
            System.out.printf("double[] lon = new double[%d];%n", n);
            for (int i = 0; i < n; ++i)
                System.out.printf("lat[%3d] = %9.4f; lon[%3d] = %9.4f;%n", i,
                        lat[i] * rtd, i, lon[i] * rtd);
        }
        else
        {
            double[] lat = new double[66];
            double[] lon = new double[66];
            lat[  0] =   30.0386; lon[  0] =   90.0359;
            lat[  1] =   30.1158; lon[  1] =   90.1078;
            lat[  2] =   30.1929; lon[  2] =   90.1797;
            lat[  3] =   30.2700; lon[  3] =   90.2518;
            lat[  4] =   30.3471; lon[  4] =   90.3240;
            lat[  5] =   30.4241; lon[  5] =   90.3964;
            lat[  6] =   30.5011; lon[  6] =   90.4688;
            lat[  7] =   30.5780; lon[  7] =   90.5413;
            lat[  8] =   30.6549; lon[  8] =   90.6140;
            lat[  9] =   30.7318; lon[  9] =   90.6868;
            lat[ 10] =   30.8086; lon[ 10] =   90.7597;
            lat[ 11] =   30.8854; lon[ 11] =   90.8327;
            lat[ 12] =   30.9621; lon[ 12] =   90.9058;
            lat[ 13] =   31.0388; lon[ 13] =   90.9790;
            lat[ 14] =   31.1154; lon[ 14] =   91.0524;
            lat[ 15] =   31.1920; lon[ 15] =   91.1258;
            lat[ 16] =   31.2686; lon[ 16] =   91.1994;
            lat[ 17] =   31.3451; lon[ 17] =   91.2731;
            lat[ 18] =   31.4216; lon[ 18] =   91.3470;
            lat[ 19] =   31.4980; lon[ 19] =   91.4209;
            lat[ 20] =   31.5744; lon[ 20] =   91.4950;
            lat[ 21] =   31.6507; lon[ 21] =   91.5692;
            lat[ 22] =   31.7270; lon[ 22] =   91.6435;
            lat[ 23] =   31.8032; lon[ 23] =   91.7179;
            lat[ 24] =   31.8795; lon[ 24] =   91.7924;
            lat[ 25] =   31.9556; lon[ 25] =   91.8671;
            lat[ 26] =   32.0317; lon[ 26] =   91.9419;
            lat[ 27] =   32.1078; lon[ 27] =   92.0168;
            lat[ 28] =   32.1838; lon[ 28] =   92.0919;
            lat[ 29] =   32.2598; lon[ 29] =   92.1670;
            lat[ 30] =   32.3357; lon[ 30] =   92.2423;
            lat[ 31] =   32.4116; lon[ 31] =   92.3177;
            lat[ 32] =   32.4875; lon[ 32] =   92.3933;
            lat[ 33] =   32.5633; lon[ 33] =   92.4689;
            lat[ 34] =   32.6390; lon[ 34] =   92.5447;
            lat[ 35] =   32.7147; lon[ 35] =   92.6206;
            lat[ 36] =   32.7904; lon[ 36] =   92.6967;
            lat[ 37] =   32.8660; lon[ 37] =   92.7729;
            lat[ 38] =   32.9415; lon[ 38] =   92.8492;
            lat[ 39] =   33.0170; lon[ 39] =   92.9256;
            lat[ 40] =   33.0925; lon[ 40] =   93.0022;
            lat[ 41] =   33.1679; lon[ 41] =   93.0789;
            lat[ 42] =   33.2433; lon[ 42] =   93.1557;
            lat[ 43] =   33.3186; lon[ 43] =   93.2326;
            lat[ 44] =   33.3939; lon[ 44] =   93.3097;
            lat[ 45] =   33.4691; lon[ 45] =   93.3869;
            lat[ 46] =   33.5443; lon[ 46] =   93.4643;
            lat[ 47] =   33.6194; lon[ 47] =   93.5418;
            lat[ 48] =   33.6945; lon[ 48] =   93.6194;
            lat[ 49] =   33.7695; lon[ 49] =   93.6972;
            lat[ 50] =   33.8445; lon[ 50] =   93.7751;
            lat[ 51] =   33.9194; lon[ 51] =   93.8531;
            lat[ 52] =   33.9943; lon[ 52] =   93.9312;
            lat[ 53] =   34.0691; lon[ 53] =   94.0095;
            lat[ 54] =   34.1439; lon[ 54] =   94.0880;
            lat[ 55] =   34.2186; lon[ 55] =   94.1665;
            lat[ 56] =   34.2933; lon[ 56] =   94.2453;
            lat[ 57] =   34.3679; lon[ 57] =   94.3241;
            lat[ 58] =   34.4424; lon[ 58] =   94.4031;
            lat[ 59] =   34.5170; lon[ 59] =   94.4822;
            lat[ 60] =   34.5914; lon[ 60] =   94.5615;
            lat[ 61] =   34.6658; lon[ 61] =   94.6409;
            lat[ 62] =   34.7402; lon[ 62] =   94.7204;
            lat[ 63] =   34.8145; lon[ 63] =   94.8001;
            lat[ 64] =   34.8887; lon[ 64] =   94.8800;
            lat[ 65] =   34.9629; lon[ 65] =   94.9600;

            assertEquals(lat.length, actual[0].length);
            for (int i = 0; i < lat.length; ++i)
            {
                assertEquals(lat[i], actual[0][i] * rtd, 1e-4);
                assertEquals(lon[i], actual[1][i] * rtd, 1e-4);
            }
        }
    }

    @Test
    public void testGetTravelTimeUncertainty() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetTravelTimeUncertainty()");
        assertEquals(1.249868, slbm.getTravelTimeUncertainty(), 1e-4);
    }

    @Test
    public void testGetTravelTimeUncertaintyStringDouble() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetTravelTimeUncertaintyStringDouble()");
        assertEquals(1.1975, slbm.getTravelTimeUncertainty("Pn", 5 * dtr), 1e-4);
        assertEquals(1.6370, slbm.getTravelTimeUncertainty("Sn", 5 * dtr), 1e-4);
        assertEquals(1.5000, slbm.getTravelTimeUncertainty("Pg", 1 * dtr), 1e-4);
        assertEquals(1.5260, slbm.getTravelTimeUncertainty("Lg", 1 * dtr), 1e-4);
    }

    @Test
    public void testGetZhaoParameters() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetZhaoParameters()");
        // System.out.println(slbm.getZhaoParameters());
        String expected = "Vm=8.0866  Gm=0.001528  H=12.047  C=0.000347149  Cm=0.000347569  udSign=0";
        String actual = slbm.getZhaoParameters().toString();
        assertEquals(expected, actual);
    }

    // @Test
    public void testGetPgLgComponents() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetPgLgComponents()");
        createGreatCircle(slbm, "Lg");
        double[] actual = getDoubles(slbm.getPgLgComponents(), false);
        createGreatCircle(slbm, "Pn");

        double[] expected = new double[] { 209.485360, 203.375499, 209.485360,
                0.276803, 0.286625, 6346.797398, 6351.891426 };

        assertEquals(expected.length, actual.length);
        for (int i = 0; i < expected.length; ++i)
            assertEquals(expected[i], actual[i], 1e-3);
    }

    @Test
    public void testGetNodeNeighbors() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetNodeNeighbors()");
        int[] actual = getInts(slbm.getNodeNeighbors(57), false);
        int[] expected = new int[] {13070, 13071, 13192, 13350, 20824, 20825};

        assertEquals(expected.length, actual.length);
        for (int i=0; i<expected.length; ++i)
            assertEquals(expected[i], actual[i]);

    }

    @Test
    public void testGetActiveNodeNeighbors() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetActiveNodeNeighbors()");
        // depends on slbm.initializeActiveNodes(28*dtr, 80*dtr, 32*dtr, 105*dtr);

        int activeNodeId = slbm.getActiveNodeId(57);

        int[] actual = getInts(slbm.getActiveNodeNeighbors(activeNodeId), false);

        int[] expected = new int[] {23, 24, 33, 46, 51, 52};

        assertEquals(expected.length, actual.length);
        for (int i=0; i<expected.length; ++i)
            assertEquals(expected[i], actual[i]);

        //		for (int e : expected)
        //		{
        //			GridProfile node = slbm.getActiveNodeData(e);
        //			System.out.printf("%10.4f %10.4f%n", node.lat*rtd, node.lon*rtd);
        //		}
    }

    @Test
    public void testGetNodeSeparation() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetNodeSeparation()");

        int[] nodes = slbm.getNodeNeighbors(57);
        assertEquals(6, nodes.length);

        for (int i : nodes)
            assertTrue(slbm.getNodeSeparation(57, i) * rtd < 1.5);
    }

    @Test
    public void testGetNodeAzimuth() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetNodeAzimuth()");

        //System.out.println(slbm.getNodeAzimuth(57, 819)*rtd);
        assertEquals(62.548568558829935, slbm.getNodeAzimuth(57, 819) * rtd, 1e-1);
    }

    @Test
    public void testGetNodeHitCount() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetNodeHitCount()");
        slbm.clearHitCount();
        assertEquals(0, slbm.getNodeHitCount(13338));
        slbm.getWeights();
        assertEquals(1, slbm.getNodeHitCount(13338));
        slbm.getWeights();
        assertEquals(2, slbm.getNodeHitCount(13338));
    }

    @Test
    public void testGetNActiveNodes() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetNActiveNodes()");

        assertEquals(147, slbm.getNActiveNodes());
    }

    @Test
    public void testGetGridNodeId() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetGridNodeId()");

        int gridNodeId = 57;
        int activeNodeId = slbm.getActiveNodeId(gridNodeId);

        //System.out.printf("Grid node id = %d activeNodeId = %d%n", gridNodeId, activeNodeId);

        assertEquals(gridNodeId, slbm.getGridNodeId(activeNodeId));
    }

    @Test
    public void testGetActiveNodeId()
    {
        if (verbosity > 0)
            System.out.println("testGetActiveNodeId()");
        int activeNodeId = 10;
        int gridNodeId = slbm.getGridNodeId(activeNodeId);

        //System.out.printf("Grid node id = %d activeNodeId = %d%n", gridNodeId, activeNodeId);

        assertEquals(activeNodeId, slbm.getActiveNodeId(gridNodeId));
    }

    @Test
    public void testGetActiveNodeWeights() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetActiveNodeWeights()");

        GridWeight weights = slbm.getActiveNodeWeights();

        // for (int i=0; i<weights.node.length; ++i)
        // {
        // GridProfile node = slbm.getGridData(weights.node[i]);
        // System.out.printf("%10.4f %10.4f%n", node.lat*rtd, node.lon*rtd);
        // }

        ArrayList<String> actual = getRecords(weights.toString(), false);

        ArrayList<String> expected = new ArrayList<String>(16);
        expected.add("Grid Node Weights: ");
        expected.add("");
        expected.add("  Node     Weight");
        expected.add("    -1    86.9359");
        expected.add("    -1     8.7516");
        expected.add("    -1    11.6986");
        expected.add("    -1     0.5863");
        expected.add("   123    69.0562");
        expected.add("    -1    24.1731");
        expected.add("    99    82.3442");
        expected.add("    43    10.5295");
        expected.add("    45    86.7425");
        expected.add("   125     6.0623");
        expected.add("    44    60.5613");
        expected.add("    12    32.1759");
        expected.add("    46    47.5072");

        assertEquals(expected.size(), actual.size());
        for (int i=0; i<expected.size(); ++i)
            assertEquals(expected.get(i), actual.get(i));

        // the sum of the weights should be equal to the headwave distance
        // in km.
        assertEquals(weights.getSum(), slbm.getHeadwaveDistanceKm(), 1e-2);
    }

    @Test
    public void testGetActiveNodeData() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetActiveNodeData()");

        ArrayList<String> actual = getRecords(slbm.getActiveNodeData(0).toString(), false);

        ArrayList<String> expected = new ArrayList<String>(18);
        expected.add("GridProfile:");
        expected.add("");
        expected.add("  Node ID  :          0");
        expected.add("  Latitude :    30.5474");
        expected.add("  Longitude:    89.5330");
        expected.add("");
        expected.add("     Depth        Thick      P Vel      S Vel");
        expected.add("   -5.522179     0.0000     1.5000     0.0000");
        expected.add("   -5.522179     0.1001     2.5013     1.1987");
        expected.add("   -5.422081     0.0000     0.0000     0.0000");
        expected.add("   -5.422081     0.0000     0.0000     0.0000");
        expected.add("   -5.422081    24.9502     6.0032     3.4582");
        expected.add("   19.528114     0.0000     6.4034     3.6960");
        expected.add("   19.528114    26.7808     6.1350     3.5024");
        expected.add("   46.308876    26.7813     7.1038     3.8958");
        expected.add("   73.090126                8.1063     4.5955");
        expected.add("               P Grad     S Grad");
        expected.add("             0.000720  -0.000055");

        assertEquals(expected.size(), actual.size());
        for (int i=0; i<expected.size(); ++i)
            assertEquals(expected.get(i), actual.get(i));

    }

    @Test
    public void testGetNGridNodes()
    {
        if (verbosity > 0)
            System.out.println("testGetNGridNodes()");

        assertEquals(40962, slbm.getNGridNodes());
    }

    @Test
    public void testGetNHeadWavePoints()
    {
        if (verbosity > 0)
            System.out.println("testGetNHeadWavePoints()");

        assertEquals(66, slbm.getNHeadWavePoints());
    }

    @Test
    public void testGetNodeNeighborInfo()
    {
        if (verbosity > 0)
            System.out.println("testGetNodeNeighborInfo()");

        ArrayList<String> actual = getRecords(slbm.getNodeNeighborInfo(57).toString(), false);

        Collections.sort(actual);

        ArrayList<String> expected = new ArrayList<String>(9);
        expected.add("  12811     0.9912    80.4139");
        expected.add("  12812     1.0258    11.9271");
        expected.add("  12872     1.1554   315.4646");
        expected.add("  12873     0.9912   260.4139");
        expected.add("  20432     1.0258   148.9007");
        expected.add("  20562     1.1554   205.3632");
        expected.add("  Neighbor    Distance    Azimuth");
        expected.add("  Node :      57");
        expected.add("QueryNeighborInfo: ");

//		for (int i=0; i<actual.size(); ++i)
//		System.out.printf("expected.add(\"%s\");%n", actual.get(i));

        assertEquals(expected.size(), actual.size());
        for (int i=0; i<expected.size(); ++i)
            assertEquals(expected.get(i), actual.get(i));

    }

    @Test
    public void testGetActiveNodeNeighborInfo()
    {
        if (verbosity > 0)
            System.out.println("testGetActiveNodeNeighborInfo()");

        ArrayList<String> actual = getRecords(slbm.getActiveNodeNeighborInfo(0).toString(), false);

        ArrayList<String> expected = new ArrayList<String>(9);
        expected.add("QueryNeighborInfo: ");
        expected.add("  Node :       0");
        expected.add("  Neighbor    Distance    Azimuth");
        expected.add("     23     1.0258    11.9271");
        expected.add("     24     1.1554   -44.5354");
        expected.add("     33     0.9912   -99.5861");
        expected.add("     46     0.9912    80.4139");
        expected.add("     51     1.1554  -154.6368");
        expected.add("     52     1.0258   148.9007");

        assertEquals(expected.size(), actual.size());
        for (int i=0; i<expected.size(); ++i)
            assertEquals(expected.get(i), actual.get(i));

    }

    @Test
    public void testGetCHMax()
    {
        if (verbosity > 0)
            System.out.println("testGetCHMax()");

        assertEquals(0.2, slbm.getCHMax(), 1e-6);

    }

    @Test
    public void testSetCHMax()
    {
        if (verbosity > 0)
            System.out.println("testSetCHMax()");

        slbm.setCHMax(0.3);
        assertEquals(0.3, slbm.getCHMax(), 1e-6);

        slbm.setCHMax(0.2);
        assertEquals(0.2, slbm.getCHMax(), 1e-6);

    }

    @Test
    public void testGetAverageMantleVelocity()
    {
        if (verbosity > 0)
            System.out.println("testGetAverageMantleVelocity()");

        //		System.out.printf("%1.6f  %1.6f%n",
        //				slbm.getAverageMantleVelocity(SlbmInterface.PWAVE),
        //				slbm.getAverageMantleVelocity(SlbmInterface.SWAVE));

        assertEquals(8.104615, slbm.getAverageMantleVelocity(SlbmInterface.PWAVE), 1e-6);
        assertEquals(4.435126, slbm.getAverageMantleVelocity(SlbmInterface.SWAVE), 1e-6);

    }

    @Test
    public void testSetAverageMantleVelocity()
    {
        if (verbosity > 0)
            System.out.println("testSetAverageMantleVelocity()");

        double p = slbm.getAverageMantleVelocity(SlbmInterface.PWAVE);
        double s = slbm.getAverageMantleVelocity(SlbmInterface.SWAVE);

        slbm.setAverageMantleVelocity(SlbmInterface.PWAVE, 200.);
        slbm.setAverageMantleVelocity(SlbmInterface.SWAVE, 100.);

        assertEquals(200., slbm.getAverageMantleVelocity(SlbmInterface.PWAVE), 1e-6);
        assertEquals(100., slbm.getAverageMantleVelocity(SlbmInterface.SWAVE), 1e-6);

        slbm.setAverageMantleVelocity(SlbmInterface.PWAVE, p);
        slbm.setAverageMantleVelocity(SlbmInterface.SWAVE, s);

        assertEquals(8.104615, slbm.getAverageMantleVelocity(SlbmInterface.PWAVE), 1e-6);
        assertEquals(4.435126, slbm.getAverageMantleVelocity(SlbmInterface.SWAVE), 1e-6);
    }

    @Test
    public void testGetFractionActive()
    {
        if (verbosity > 0)
            System.out.println("testGetFractionActive()");

        //System.out.printf("%1.6f%n", slbm.getFractionActive());
        assertEquals(0.575758, slbm.getFractionActive(), 1e-6);

    }

    @Test
    public void testSetMaxDistance()
    {
        if (verbosity > 0)
            System.out.println("testSetMaxDistance()");

        slbm.setMaxDistance(25. * dtr);
        assertEquals(25., slbm.getMaxDistance() * rtd, 1e-6);

        slbm.setMaxDistance(15. * dtr);
        assertEquals(15., slbm.getMaxDistance() *rtd, 1e-6);


    }

    @Test
    public void testGetMaxDistance()
    {
        if (verbosity > 0)
            System.out.println("testGetMaxDistance()");

        //System.out.printf("%1.6f%n", slbm.getMaxDistance()*rtd);
        assertEquals(15., slbm.getMaxDistance()*rtd, 1e-6);

    }

    @Test
    public void testSetMaxDepth()
    {
        if (verbosity > 0)
            System.out.println("testSetMaxDepth()");

        slbm.setMaxDepth(300.);
        assertEquals(300., slbm.getMaxDepth(), 1e-6);

        slbm.setMaxDepth(200.);
        assertEquals(200., slbm.getMaxDepth(), 1e-6);

    }

    @Test
    public void testGetMaxDepth()
    {
        if (verbosity > 0)
            System.out.println("testGetMaxDepth()");

        //System.out.printf("%1.6f%n", slbm.getMaxDepth());
        assertEquals(200., slbm.getMaxDepth(), 1e-6);

    }

    @Test
    public void testGet_dtt_dlat() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGet_dtt_dlat()");

        //System.out.printf("%1.6f%n", slbm.get_dtt_dlat());
        assertEquals(575.267789, slbm.get_dtt_dlat(), 1e-2);

    }

    @Test
    public void testGet_dtt_dlon() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGet_dtt_dlon()");

        //System.out.printf("%1.6f%n", slbm.get_dtt_dlon());
        assertEquals(508.128300, slbm.get_dtt_dlon(), 1e-2);

    }

    @Test
    public void testGet_dtt_ddepth() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGet_dtt_ddepth()");

        //System.out.printf("%1.6f%n", slbm.get_dtt_ddepth());
        assertEquals(-0.109810, slbm.get_dtt_ddepth(), 1e-2);

    }

    @Test
    public void testGetSlowness() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetSlowness()");

        //System.out.printf("%1.6f%n", slbm.getSlowness());
        assertEquals(765.283088, slbm.getSlowness(), 1e-2);

    }

    @Test
    public void testGetSlownessUncertainty() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetSlownessUncertainty()");

        //System.out.printf("%1.6f%n", slbm.getSlownessUncertainty());
        assertEquals(14.656260, slbm.getSlownessUncertainty(), 1e-2);

    }

    @Test
    public void testGetSlownessUncertaintyStringDouble() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetSlownessUncertaintyStringDouble()");

        //System.out.printf("%1.6f%n", slbm.getSlownessUncertainty("Pn", 6.*dtr));
        assertEquals(14.656260, slbm.getSlownessUncertainty("Pn", 6.*dtr), 1e-2);

    }

    @Test
    public void testMovePoint()
    {
        if (verbosity > 0)
            System.out.println("testMovePoint()");

        double[] point = slbm.movePoint(30*dtr, 60*dtr, 10*dtr, 60*dtr);
        point[0] *= rtd;
        point[1] *= rtd;
        //System.out.println(Arrays.toString(point));
        assertEquals(34.5988334793662, point[0], 1e-6);
        assertEquals(70.5037575698728, point[1], 1e-6);
    }

    @Test
    public void testGetDistAz()
    {
        if (verbosity > 0)
            System.out.println("testGetDistAz()");

        double[] distaz = slbm.getDistAz(30*dtr, 60*dtr, 34.5988334793662*dtr, 70.5037575698728 *dtr, -999.);
        distaz[0] *= rtd;
        distaz[1] *= rtd;
        //System.out.println(Arrays.toString(distaz));
        assertEquals(10., distaz[0], 1e-6);
        assertEquals(60., distaz[1], 1e-6);

    }

    @Test
    public void testGetPiercePointSource()
    {
        if (verbosity > 0)
            System.out.println("testGetPiercePointSource()");

        double[] actual = getDoubles(slbm.getPiercePointSource(), false);

        //System.out.printf("%10.4f %10.4f %10.4f%n", actual[0]*rtd, actual[1]*rtd, actual[2]);

        double[] expected = new double[] {0.599889, 1.646326, 67.743606};

        assertEquals(expected.length, actual.length);
        for (int i=0; i<expected.length; ++i)
            assertEquals(expected[i], actual[i], 1e-3);
    }

    @Test
    public void testGetPiercePointReceiver()
    {
        if (verbosity > 0)
            System.out.println("testGetPiercePointReceiver()");

        double[] actual = getDoubles(slbm.getPiercePointReceiver(), false);

        //System.out.printf("%10.4f %10.4f %10.4f%n", actual[0]*rtd, actual[1]*rtd, actual[2]);

        double[] expected = new double[] {0.535850, 1.582289, 73.160056};

        assertEquals(expected.length, actual.length);
        for (int i=0; i<expected.length; ++i)
            assertEquals(expected[i], actual[i], 1e-3);
    }

    @Test
    public void testGetDelDistance() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetDelDistance()");

        //System.out.printf("%1.6f radians%n", slbm.getDelDistance());
        assertEquals(0.001, slbm.getDelDistance(), 1e-6);

    }

    @Test
    public void testSetDelDistance() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testSetDelDistance()");

        slbm.setDelDistance(0.002);
        assertEquals(0.002, slbm.getDelDistance(), 1e-6);

        slbm.setDelDistance(0.001);
        assertEquals(0.001, slbm.getDelDistance(), 1e-6);

    }

    @Test
    public void testGetDelDepth() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testGetDelDepth()");

        //System.out.printf("%1.6f km%n", slbm.getDelDepth());
        assertEquals(0.1, slbm.getDelDepth(), 1e-6);

    }

    @Test
    public void testSetDelDepth() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testSetDelDepth()");

        slbm.setDelDepth(0.2);
        assertEquals(0.2, slbm.getDelDepth(), 1e-6);

        slbm.setDelDepth(0.1);
        assertEquals(0.1, slbm.getDelDepth(), 1e-6);

    }

    @Test
    public void testSetPathIncrement()
    {
        if (verbosity > 0)
            System.out.println("testSetPathIncrement()");

        double x = slbm.getPathIncrement();

        slbm.setPathIncrement(0.2*dtr);
        assertEquals(0.2, slbm.getPathIncrement()*rtd, 1e-6);

        slbm.setPathIncrement(x);
        assertEquals(0.1, slbm.getPathIncrement()*rtd, 1e-6);

    }

    @Test
    public void testGetPathIncrement()
    {
        if (verbosity > 0)
            System.out.println("testGetPathIncrement()");

        //System.out.printf("%1.6f%n", slbm.getPathIncrement()*rtd);
        assertEquals(0.1, slbm.getPathIncrement()*rtd, 1e-6);

    }

    @Test
    public void testSaveVelocityModelBinaryInSpecifiedDirectory() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testSaveVelocityModelBinary()");

        slbm.specifyOutputDirectory("rstt_specified_directory_java");
        slbm.saveVelocityModelBinary();

        SlbmInterface slbm2 = new SlbmInterface();

        slbm2.loadVelocityModel("rstt_specified_directory_java");

        createGreatCircle(slbm2, "Pn");

        assertEquals(101.25, slbm2.getTravelTime(), 1e-2);

        slbm2.close();
    }

    @Test
    public void testSaveVelocityModelBinaryFile() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testSaveVelocityModelBinaryFile()");

        try
        {
            slbm.saveVelocityModel("rstt_binary_file_java.geotess");

            SlbmInterface slbm2 = new SlbmInterface();

            slbm2.loadVelocityModel("rstt_binary_file_java.geotess");

            createGreatCircle(slbm2, "Pn");

            assertEquals(101.25, slbm2.getTravelTime(), 1e-2);

            slbm2.close();
        }
        catch (Exception e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @Test
    public void testSaveVelocityModelAsciiFile() throws SLBMException
    {
        if (verbosity > 0)
            System.out.println("testSaveVelocityModelAsciiFile()");

        slbm.saveVelocityModel("rstt_binary_file_java.ascii");

        SlbmInterface slbm2 = new SlbmInterface();

        slbm2.loadVelocityModel("rstt_binary_file_java.ascii");

        createGreatCircle(slbm2, "Pn");

        assertEquals(101.25, slbm2.getTravelTime(), 1e-2);

        slbm2.close();
    }











    private static ArrayList<String> getRecords(String s, boolean print)
    {
        ArrayList<String> records = new ArrayList<String>(1000);
        Scanner input = new Scanner(s);
        while (input.hasNext())
            records.add(input.nextLine());

        if (print)
        {
            System.out.println();
            System.out.printf("ArrayList<String> expected = new ArrayList<String>(%d);%n",
                    records.size());
            for (String x : records)
                System.out.printf("expected.add(\"%s\");%n", x);

            System.out.println();
            System.out .println("assertEquals(expected.size(), actual.size());");
            System.out.println("for (int i=0; i<expected.size(); ++i)");
            System.out .println("   assertEquals(expected.get(i), actual.get(i));");
            System.out.println();
        }
        return records;
    }

    private static int[] getInts(int[] values, boolean print)
    {
        if (print)
        {
            System.out.print("int[] expected = new int[] {");
            for (int i = 0; i < values.length; ++i)
                if (i == 0)
                    System.out.printf("%d", values[i]);
                else
                    System.out.printf(", %d", values[i]);
            System.out.println("};");
            System.out.println();
            System.out.println("assertEquals(expected.length, actual.length);");
            System.out.println("for (int i=0; i<expected.length; ++i)");
            System.out.println("   assertEquals(expected[i], actual[i]);");
            System.out.println();
        }
        return values;
    }

    private static double[] getDoubles(double[] values, boolean print)
    {
        if (print)
        {
            System.out.print("double[] expected = new double[] {");
            for (int i = 0; i < values.length; ++i)
            {
                if (i == 0)
                    System.out.printf("%1.6f", values[i]);
                else
                    System.out.printf(", %1.6f", values[i]);
            }
            System.out.println("};");
            System.out.println();
            System.out.println("assertEquals(expected.length, actual.length);");
            System.out.println("for (int i=0; i<expected.length; ++i)");
            System.out
            .println("   assertEquals(expected[i], actual[i], 1e-3);");
            System.out.println();
            System.out.printf("assertEquals(%1.6f, getSum(actual), 1e-4);%n",
                    getSum(values));
            System.out.println();
        }
        return values;
    }

    private static double getSum(double[] values)
    {
        double sum = 0;
        for (double d : values)
            sum += d;
        return sum;
    }

}
