visad/src/main/java/ucar/nc2/iosp/grid/GridIndexToNC.java
private void makeDenseCoordSys(NetcdfFile ncfile, GridTableLookup lookup, CancelTask cancelTask) throws IOException {
    List<GridTimeCoord> timeCoords = new ArrayList<>();
    List<GridVertCoord> vertCoords = new ArrayList<>();
    List<GridEnsembleCoord> ensembleCoords = new ArrayList<>();

    Calendar calendar = Calendar.getInstance();
    calendar.setTimeZone(java.util.TimeZone.getTimeZone("GMT"));

    // loop over HorizCoordSys
    Collection<GridHorizCoordSys> hcset = hcsHash.values();
    for (GridHorizCoordSys hcs : hcset) {
      if ((cancelTask != null) && cancelTask.isCancel()) break;

      // loop over GridVariables in the HorizCoordSys
      // create the time and vertical coordinates
      List<GridVariable> gribvars = new ArrayList<>(hcs.varHash.values());
      for (GridVariable gv : gribvars) {
        if ((cancelTask != null) && cancelTask.isCancel()) break;

        List<GridRecord> recordList = gv.getRecords();
        GridRecord record = recordList.get(0);
        String vname = gv.makeLevelName(record, lookup);

        // look to see if vertical already exists
        GridVertCoord useVertCoord = null;
        for (GridVertCoord gvcs : vertCoords) {
          if (vname.equals(gvcs.getLevelName())) {
            if (gvcs.matchLevels(recordList)) {  // must have the same levels
              useVertCoord = gvcs;
            }
          }
        }
        if (useVertCoord == null) {  // nope, got to create it
          useVertCoord = makeGridVertCoord(recordList, vname, lookup, hcs);
          vertCoords.add(useVertCoord);
        }
        gv.setVertCoord(useVertCoord);
        // look to see if time coord already exists
        GridTimeCoord useTimeCoord = null;
        for (GridTimeCoord gtc : timeCoords) {
          if (gtc.matchTimes(recordList)) {  // must have the same time coords
            useTimeCoord = gtc;
            break;
          }
        }
        if (useTimeCoord == null) {  // nope, got to create it
          useTimeCoord = makeGridTimeCoord(recordList, ncfile.getLocation());
          timeCoords.add(useTimeCoord);
        }
        gv.setTimeCoord(useTimeCoord);

        if (gv.isEnsemble()) {
          GridEnsembleCoord useEnsembleCoord = addEnsembles(ensembleCoords, recordList);
          if (useEnsembleCoord != null)
            gv.setEnsembleCoord(useEnsembleCoord);
        }
      }

      // assign time coordinate names, add dimensions to file
      // reverse sort by length - give time dimensions unique names
      Collections.sort(timeCoords);
      int count = 0;
      for (GridTimeCoord tcs : timeCoords) {
        tcs.setSequence(count++);
        tcs.addDimensionsToNetcdfFile(ncfile, hcs.getGroup());
      }

      // add Ensemble dimensions, give Ensemble dimensions unique names
      int seqno = 0;
      for (GridEnsembleCoord gec : ensembleCoords) {
        gec.setSequence(seqno++);
        gec.addDimensionsToNetcdfFile(ncfile, hcs.getGroup());
      }

      // add x, y dimensions
      hcs.addDimensionsToNetcdfFile(ncfile);

      // add vertical dimensions, give them unique names
      Collections.sort(vertCoords);
      int vcIndex = 0;
      String listName = null;
      int start = 0;
      for (vcIndex = 0; vcIndex < vertCoords.size(); vcIndex++) {
        GridVertCoord gvcs = vertCoords.get(vcIndex);
        String vname = gvcs.getLevelName();
        if (listName == null) {
          listName = vname;  // initial
        }

        if (!vname.equals(listName)) {
          makeVerticalDimensions(vertCoords.subList(start, vcIndex), ncfile, hcs.getGroup());
          listName = vname;
          start = vcIndex;
        }
      }
      makeVerticalDimensions(vertCoords.subList(start, vcIndex), ncfile, hcs.getGroup());

      // create a variable for each entry, but check for other products with same simple name to disambiguate
      List<List<GridVariable>> products = new ArrayList<>(hcs.productHash.values());
      for (List<GridVariable> plist : products) {
        if ((cancelTask != null) && cancelTask.isCancel()) break;

        if (plist.size() == 1) {
          GridVariable pv = plist.get(0);
          String name = pv.getFirstRecord().cdmVariableName(lookup, false, false); // plain ole name
          Variable v = pv.makeVariable(ncfile, hcs.getGroup(), name, raf );
          ncfile.addVariable(hcs.getGroup(), v);

        } else {

          // collect them grouped by vertical coord
          Map<GridVertCoord,VertCollection> vcMap = new HashMap<>();
          for (GridVariable gv : plist) {
            VertCollection vc = vcMap.get(gv.getVertCoord());
            if (vc == null) {
              vc = new VertCollection(gv);
              vcMap.put(gv.getVertCoord(), vc);
            }
            vc.list.add(gv);
          }

          // sort by larger # vert levels
          List<VertCollection> vclist = new ArrayList<>(vcMap.values());
          Collections.sort(vclist);

          boolean firstVertCoord = true;
          for (VertCollection vc : vclist) {
            boolean hasMultipleLevels = vc.vc.getNLevels() > 1;
            boolean noLevelOk = firstVertCoord; //  && hasMultipleLevels;  LOOK turned off for now 9/15/10
            List<GridVariable> list = vc.list;
            if (list.size() == 1) {
              GridVariable gv = list.get(0);
              String name = gv.getFirstRecord().cdmVariableName(lookup, !noLevelOk, false);
              ncfile.addVariable(hcs.getGroup(), gv.makeVariable(ncfile, hcs.getGroup(), name, raf));

            } else {
              for (GridVariable gv : list) { // more than one - disambiguate by stat name
                String name = gv.getFirstRecord().cdmVariableName(lookup, !noLevelOk, true);
                ncfile.addVariable(hcs.getGroup(), gv.makeVariable(ncfile, hcs.getGroup(), name, raf));
              }
            }
            firstVertCoord = false;
          }

        } // multiple vertical levels

      } // create variable

      // add coordinate variables at the end
      for (GridTimeCoord tcs : timeCoords) {
        tcs.addToNetcdfFile(ncfile, hcs.getGroup());
      }

      for (GridEnsembleCoord ens : ensembleCoords) {
        ens.addToNetcdfFile(ncfile, hcs.getGroup());
      }

      hcs.addToNetcdfFile(ncfile);

      for (GridVertCoord gvcs : vertCoords) {
        gvcs.addToNetcdfFile(ncfile, hcs.getGroup());
      }

    } // loop over hcs
    // TODO: check this,  in ToolsUI it caused problems
    //for (GridVertCoord gvcs : vertCoords) {
    //  gvcs.empty();
    //}

  }
private void makeDenseCoordSys(NetcdfFile ncfile, GridTableLookup lookup, CancelTask cancelTask) throws IOException {
    List<GridTimeCoord> timeCoords = new ArrayList<>();
    List<GridVertCoord> vertCoords = new ArrayList<>();
    List<GridEnsembleCoord> ensembleCoords = new ArrayList<>();

    Calendar calendar = Calendar.getInstance();
    calendar.setTimeZone(java.util.TimeZone.getTimeZone("GMT"));

    // loop over HorizCoordSys
    Collection<GridHorizCoordSys> hcset = hcsHash.values();
    for (GridHorizCoordSys hcs : hcset) {
      if ((cancelTask != null) && cancelTask.isCancel()) break;

      // loop over GridVariables in the HorizCoordSys
      // create the time and vertical coordinates
      List<GridVariable> gribvars = new ArrayList<>(hcs.varHash.values());
      for (GridVariable gv : gribvars) {
        if ((cancelTask != null) && cancelTask.isCancel()) break;

        List<GridRecord> recordList = gv.getRecords();
        GridRecord record = recordList.get(0);
        String vname = gv.makeLevelName(record, lookup);

        // look to see if vertical already exists
        GridVertCoord useVertCoord = null;
        for (GridVertCoord gvcs : vertCoords) {
          if (vname.equals(gvcs.getLevelName())) {
            if (gvcs.matchLevels(recordList)) {  // must have the same levels
              useVertCoord = gvcs;
            }
          }
        }
        if (useVertCoord == null) {  // nope, got to create it
          useVertCoord = makeGridVertCoord(recordList, vname, lookup, hcs);
          vertCoords.add(useVertCoord);
        }
        gv.setVertCoord(useVertCoord);
        // look to see if time coord already exists
        GridTimeCoord useTimeCoord = null;
        for (GridTimeCoord gtc : timeCoords) {
          if (gtc.matchTimes(recordList)) {  // must have the same time coords
            useTimeCoord = gtc;
            break;
          }
        }
        if (useTimeCoord == null) {  // nope, got to create it
          useTimeCoord = makeGridTimeCoord(recordList, ncfile.getLocation());
          timeCoords.add(useTimeCoord);
        }
        gv.setTimeCoord(useTimeCoord);

        if (gv.isEnsemble()) {
          GridEnsembleCoord useEnsembleCoord = addEnsembles(ensembleCoords, recordList);
          if (useEnsembleCoord != null)
            gv.setEnsembleCoord(useEnsembleCoord);
        }
      }

      // assign time coordinate names, add dimensions to file
      // reverse sort by length - give time dimensions unique names
      Collections.sort(timeCoords);
      int count = 0;
      for (GridTimeCoord tcs : timeCoords) {
        tcs.setSequence(count++);
        tcs.addDimensionsToNetcdfFile(ncfile, hcs.getGroup());
      }

      // add Ensemble dimensions, give Ensemble dimensions unique names
      int seqno = 0;
      for (GridEnsembleCoord gec : ensembleCoords) {
        gec.setSequence(seqno++);
        gec.addDimensionsToNetcdfFile(ncfile, hcs.getGroup());
      }

      // add x, y dimensions
      hcs.addDimensionsToNetcdfFile(ncfile);

      // add vertical dimensions, give them unique names
      Collections.sort(vertCoords);
      int vcIndex = 0;
      String listName = null;
      int start = 0;
      for (vcIndex = 0; vcIndex < vertCoords.size(); vcIndex++) {
        GridVertCoord gvcs = vertCoords.get(vcIndex);
        String vname = gvcs.getLevelName();
        if (listName == null) {
          listName = vname;  // initial
        }

        if (!vname.equals(listName)) {
          makeVerticalDimensions(vertCoords.subList(start, vcIndex), ncfile, hcs.getGroup());
          listName = vname;
          start = vcIndex;
        }
      }
      makeVerticalDimensions(vertCoords.subList(start, vcIndex), ncfile, hcs.getGroup());

      // create a variable for each entry, but check for other products with same simple name to disambiguate
      List<List<GridVariable>> products = new ArrayList<>(hcs.productHash.values());
      for (List<GridVariable> plist : products) {
        if ((cancelTask != null) && cancelTask.isCancel()) break;

        if (plist.size() == 1) {
          GridVariable pv = plist.get(0);
          String name = pv.getFirstRecord().cdmVariableName(lookup, false, false); // plain ole name
          Variable v = pv.makeVariable(ncfile, hcs.getGroup(), name, raf );
          ncfile.addVariable(hcs.getGroup(), v);

        } else {

          // collect them grouped by vertical coord
          Map<GridVertCoord,VertCollection> vcMap = new HashMap<>();
          for (GridVariable gv : plist) {
            VertCollection vc = vcMap.get(gv.getVertCoord());
            if (vc == null) {
              vc = new VertCollection(gv);
              vcMap.put(gv.getVertCoord(), vc);
            }
            vc.list.add(gv);
          }

          // sort by larger # vert levels
          List<VertCollection> vclist = new ArrayList<>(vcMap.values());
          Collections.sort(vclist);

          boolean firstVertCoord = true;
          for (VertCollection vc : vclist) {
            boolean hasMultipleLevels = vc.vc.getNLevels() > 1;
            boolean noLevelOk = firstVertCoord; //  && hasMultipleLevels;  LOOK turned off for now 9/15/10
            List<GridVariable> list = vc.list;
            if (list.size() == 1) {
              GridVariable gv = list.get(0);
              String name = gv.getFirstRecord().cdmVariableName(lookup, !noLevelOk, false);
              ncfile.addVariable(hcs.getGroup(), gv.makeVariable(ncfile, hcs.getGroup(), name, raf));

            } else {
              for (GridVariable gv : list) { // more than one - disambiguate by stat name
                String name = gv.getFirstRecord().cdmVariableName(lookup, !noLevelOk, true);
                ncfile.addVariable(hcs.getGroup(), gv.makeVariable(ncfile, hcs.getGroup(), name, raf));
              }
            }
            firstVertCoord = false;
          }

        } // multiple vertical levels

      } // create variable

      // add coordinate variables at the end
      for (GridTimeCoord tcs : timeCoords) {
        tcs.addToNetcdfFile(ncfile, hcs.getGroup());
      }

      for (GridEnsembleCoord ens : ensembleCoords) {
        ens.addToNetcdfFile(ncfile, hcs.getGroup());
      }

      hcs.addToNetcdfFile(ncfile);

      for (GridVertCoord gvcs : vertCoords) {
        gvcs.addToNetcdfFile(ncfile, hcs.getGroup());
      }

    } // loop over hcs
    // TODO: check this,  in ToolsUI it caused problems
    //for (GridVertCoord gvcs : vertCoords) {
    //  gvcs.empty();
    //}

  }
private void makeDenseCoordSys ( NetcdfFile ncfile , GridTableLookup lookup , CancelTask cancelTask ) throws IOException { List < GridTimeCoord > timeCoords = new ArrayList <> ( ) ; List < GridVertCoord > vertCoords = new ArrayList <> ( ) ; List < GridEnsembleCoord > ensembleCoords = new ArrayList <> ( ) ; Calendar calendar = Calendar . getInstance ( ) ; calendar . setTimeZone ( java . util . TimeZone . getTimeZone ( "GMT" ) ) ; // loop over HorizCoordSys Collection < GridHorizCoordSys > hcset = hcsHash . values ( ) ; for ( GridHorizCoordSys hcs : hcset ) { if ( ( cancelTask != null ) && cancelTask . isCancel ( ) ) break ; // loop over GridVariables in the HorizCoordSys // create the time and vertical coordinates List < GridVariable > gribvars = new ArrayList <> ( hcs . varHash . values ( ) ) ; for ( GridVariable gv : gribvars ) { if ( ( cancelTask != null ) && cancelTask . isCancel ( ) ) break ; List < GridRecord > recordList = gv . getRecords ( ) ; GridRecord record = recordList . get ( 0 ) ; String vname = gv . makeLevelName ( record , lookup ) ; // look to see if vertical already exists GridVertCoord useVertCoord = null ; for ( GridVertCoord gvcs : vertCoords ) { if ( vname . equals ( gvcs . getLevelName ( ) ) ) { if ( gvcs . matchLevels ( recordList ) ) { // must have the same levels useVertCoord = gvcs ; } } } if ( useVertCoord == null ) { // nope, got to create it useVertCoord = makeGridVertCoord ( recordList , vname , lookup , hcs ) ; vertCoords . add ( useVertCoord ) ; } gv . setVertCoord ( useVertCoord ) ; // look to see if time coord already exists GridTimeCoord useTimeCoord = null ; for ( GridTimeCoord gtc : timeCoords ) { if ( gtc . matchTimes ( recordList ) ) { // must have the same time coords useTimeCoord = gtc ; break ; } } if ( useTimeCoord == null ) { // nope, got to create it useTimeCoord = makeGridTimeCoord ( recordList , ncfile . getLocation ( ) ) ; timeCoords . add ( useTimeCoord ) ; } gv . setTimeCoord ( useTimeCoord ) ; if ( gv . isEnsemble ( ) ) { GridEnsembleCoord useEnsembleCoord = addEnsembles ( ensembleCoords , recordList ) ; if ( useEnsembleCoord != null ) gv . setEnsembleCoord ( useEnsembleCoord ) ; } } // assign time coordinate names, add dimensions to file // reverse sort by length - give time dimensions unique names Collections . sort ( timeCoords ) ; int count = 0 ; for ( GridTimeCoord tcs : timeCoords ) { tcs . setSequence ( count ++ ) ; tcs . addDimensionsToNetcdfFile ( ncfile , hcs . getGroup ( ) ) ; } // add Ensemble dimensions, give Ensemble dimensions unique names int seqno = 0 ; for ( GridEnsembleCoord gec : ensembleCoords ) { gec . setSequence ( seqno ++ ) ; gec . addDimensionsToNetcdfFile ( ncfile , hcs . getGroup ( ) ) ; } // add x, y dimensions hcs . addDimensionsToNetcdfFile ( ncfile ) ; // add vertical dimensions, give them unique names Collections . sort ( vertCoords ) ; int vcIndex = 0 ; String listName = null ; int start = 0 ; for ( vcIndex = 0 ; vcIndex < vertCoords . size ( ) ; vcIndex ++ ) { GridVertCoord gvcs = vertCoords . get ( vcIndex ) ; String vname = gvcs . getLevelName ( ) ; if ( listName == null ) { listName = vname ; // initial } if ( ! vname . equals ( listName ) ) { makeVerticalDimensions ( vertCoords . subList ( start , vcIndex ) , ncfile , hcs . getGroup ( ) ) ; listName = vname ; start = vcIndex ; } } makeVerticalDimensions ( vertCoords . subList ( start , vcIndex ) , ncfile , hcs . getGroup ( ) ) ; // create a variable for each entry, but check for other products with same simple name to disambiguate List < List < GridVariable > > products = new ArrayList <> ( hcs . productHash . values ( ) ) ; for ( List < GridVariable > plist : products ) { if ( ( cancelTask != null ) && cancelTask . isCancel ( ) ) break ; if ( plist . size ( ) == 1 ) { GridVariable pv = plist . get ( 0 ) ; String name = pv . getFirstRecord ( ) . cdmVariableName ( lookup , false , false ) ; // plain ole name Variable v = pv . makeVariable ( ncfile , hcs . getGroup ( ) , name , raf ) ; ncfile . addVariable ( hcs . getGroup ( ) , v ) ; } else { // collect them grouped by vertical coord Map < GridVertCoord , VertCollection > vcMap = new HashMap <> ( ) ; for ( GridVariable gv : plist ) { VertCollection vc = vcMap . get ( gv . getVertCoord ( ) ) ; if ( vc == null ) { vc = new VertCollection ( gv ) ; vcMap . put ( gv . getVertCoord ( ) , vc ) ; } vc . list . add ( gv ) ; } // sort by larger # vert levels List < VertCollection > vclist = new ArrayList <> ( vcMap . values ( ) ) ; Collections . sort ( vclist ) ; boolean firstVertCoord = true ; for ( VertCollection vc : vclist ) { boolean hasMultipleLevels = vc . vc . getNLevels ( ) > 1 ; boolean noLevelOk = firstVertCoord ; //  && hasMultipleLevels;  LOOK turned off for now 9/15/10 List < GridVariable > list = vc . list ; if ( list . size ( ) == 1 ) { GridVariable gv = list . get ( 0 ) ; String name = gv . getFirstRecord ( ) . cdmVariableName ( lookup , ! noLevelOk , false ) ; ncfile . addVariable ( hcs . getGroup ( ) , gv . makeVariable ( ncfile , hcs . getGroup ( ) , name , raf ) ) ; } else { for ( GridVariable gv : list ) { // more than one - disambiguate by stat name String name = gv . getFirstRecord ( ) . cdmVariableName ( lookup , ! noLevelOk , true ) ; ncfile . addVariable ( hcs . getGroup ( ) , gv . makeVariable ( ncfile , hcs . getGroup ( ) , name , raf ) ) ; } } firstVertCoord = false ; } } // multiple vertical levels } // create variable // add coordinate variables at the end for ( GridTimeCoord tcs : timeCoords ) { tcs . addToNetcdfFile ( ncfile , hcs . getGroup ( ) ) ; } for ( GridEnsembleCoord ens : ensembleCoords ) { ens . addToNetcdfFile ( ncfile , hcs . getGroup ( ) ) ; } hcs . addToNetcdfFile ( ncfile ) ; for ( GridVertCoord gvcs : vertCoords ) { gvcs . addToNetcdfFile ( ncfile , hcs . getGroup ( ) ) ; } } // loop over hcs // TODO: check this,  in ToolsUI it caused problems //for (GridVertCoord gvcs : vertCoords) { //  gvcs.empty(); //} }
Make coordinate system without missing data - means that we
have to make a coordinate axis for each unique set
of time or vertical levels.

@param ncfile     netCDF file
@param lookup     lookup  table
@param cancelTask cancel task
@throws IOException problem reading file
Make coordinate system without missing data - means that we have to make a coordinate axis for each unique set of time or vertical levels .