static void doOne(
      String dir, String filename, int ngrids, int ncoordSys, int ncoordAxes, int nVertCooordAxes)
      throws Exception {
    System.out.println("test read GridDataset = " + dir + filename);
    ucar.nc2.dt.grid.GridDataset gridDs = GridDataset.open(dir + filename);

    int countGrids = gridDs.getGrids().size();
    int countCoordAxes = gridDs.getNetcdfDataset().getCoordinateAxes().size();
    int countCoordSys = gridDs.getNetcdfDataset().getCoordinateSystems().size();

    // count vertical axes
    int countVertCooordAxes = 0;
    List axes = gridDs.getNetcdfDataset().getCoordinateAxes();
    for (int i = 0; i < axes.size(); i++) {
      CoordinateAxis axis = (CoordinateAxis) axes.get(i);
      AxisType t = axis.getAxisType();
      if ((t == AxisType.GeoZ) || (t == AxisType.Height) || (t == AxisType.Pressure))
        countVertCooordAxes++;
    }

    Iterator iter = gridDs.getGridsets().iterator();
    while (iter.hasNext()) {
      GridDataset.Gridset gridset = (GridDataset.Gridset) iter.next();
      GridCoordSys gcs = gridset.getGeoCoordSys();
      // if (gcs.hasTimeAxis())
      //  System.out.println(" "+gcs.isDate()+" "+gcs.getName());
    }

    if (showCount) {
      System.out.println(" grids=" + countGrids + ((ngrids < 0) ? " *" : ""));
      System.out.println(" coordSys=" + countCoordSys + ((ncoordSys < 0) ? " *" : ""));
      System.out.println(" coordAxes=" + countCoordAxes + ((ncoordAxes < 0) ? " *" : ""));
      System.out.println(" vertAxes=" + countVertCooordAxes + ((nVertCooordAxes < 0) ? " *" : ""));
    }

    if (ngrids >= 0) assert ngrids == countGrids : "Grids " + ngrids + " != " + countGrids;
    // if (ncoordSys >= 0)
    //  assert ncoordSys == countCoordSys : "CoordSys " + ncoordSys + " != " + countCoordSys;
    // if (ncoordAxes >= 0)
    //  assert ncoordAxes == countCoordAxes : "CoordAxes " + ncoordAxes + " != " + countCoordAxes;
    if (nVertCooordAxes >= 0)
      assert nVertCooordAxes == countVertCooordAxes
          : "VertAxes " + nVertCooordAxes + " != " + countVertCooordAxes;

    gridDs.close();
  }
  @Test
  public void variableSectionChannelAndExecutor()
      throws IOException, InterruptedException, ExecutionException {

    Variable var = grid.getVariable().getOriginalVariable();
    DataType dType = var.getDataType();
    int[] varShape = var.getShape();

    gds.close();

    // Object that contains variable is not visible
    // N3header.Vinfo vinfo = (N3header.Vinfo) var.getSPobject();
    long varStartPos = 74827420;

    Path path = Paths.get(location);
    final int nThreads = Runtime.getRuntime().availableProcessors();
    final Set<StandardOpenOption> options = new TreeSet<>();
    options.add(StandardOpenOption.READ);
    ExecutorService taskExecutor = Executors.newFixedThreadPool(nThreads);

    long start = System.currentTimeMillis();
    // List<Future<ByteBuffer>> list = new ArrayList<>();
    List<Future<Future<Integer>>> list = new ArrayList<>();
    List<ByteBuffer> pool = new ArrayList<>();
    // CompletionService<ByteBuffer> resultPool = new ExecutorCompletionService<>(taskExecutor);

    try (AsynchronousFileChannel afc = AsynchronousFileChannel.open(path, options, taskExecutor)) {

      // int wantedBytes = 8*401*476;
      int wantedBytes = 93147496;

      for (int i = 0; i < 97; i++) {
        // for(int j=0; j<15; j++){
        ByteBuffer buffer =
            ByteBuffer.allocate(8 * 15 * 401 * 476); // one time and vertical level slice
        pool.add(buffer);
        Callable<Future<Integer>> worker =
            VariableSectionChannelReader.factory(afc, varStartPos, buffer);
        varStartPos += wantedBytes;

        // resultPool.submit(worker);
        Future<Future<Integer>> future = taskExecutor.submit(worker);
        list.add(future);
        // }

      }

      for (Future<Future<Integer>> future : list) {

        boolean done = future.get().isDone();
        System.out.println("Inner task done: " + done);
        done = future.isDone();
        System.out.println("Submitted task done: " + done);
      }

      taskExecutor.shutdown();

      taskExecutor.awaitTermination(10, TimeUnit.SECONDS);

      if (taskExecutor.isTerminated()) {
        System.out.println("Finally done!!");
      }

      long readBytes = 0;
      for (ByteBuffer b : pool) {
        // b.flip();
        // b.rewind();
        System.out.println(b.getDouble(0));
        readBytes += b.array().length;
      }
      System.out.println(readBytes + " read bytes in: " + (System.currentTimeMillis() - start));
    }
  }
 @After
 public void tearDown() throws IOException {
   gds.close();
   grid = null;
 }