private static Array getNcScalar(Number inNum, IObservationGroup.DataType dataType) {
   Array ret = null;
   switch (dataType) {
     case INT:
       ret = new ArrayInt.D0();
       ((ArrayInt.D0) ret).set(inNum.intValue());
       break;
     case LONG:
       ret = new ArrayLong.D0();
       ((ArrayLong.D0) ret).set(inNum.longValue());
       break;
     case FLOAT:
       ret = new ArrayFloat.D0();
       ((ArrayFloat.D0) ret).set(inNum.floatValue());
       break;
     case DOUBLE:
       ret = new ArrayDouble.D0();
       ((ArrayDouble.D0) ret).set(inNum.doubleValue());
       break;
   }
   return ret;
 }
  private void writeDataFinish() throws IOException {
    // finish global variables
    ArrayInt.D0 totalArray = new ArrayInt.D0();
    totalArray.set(profileIndex);
    try {
      ncfile.write(numProfilesTotalName, totalArray);
    } catch (InvalidRangeException e) {
      e.printStackTrace();
      throw new IllegalStateException(e);
    }

    // finish the station data
    int nstns = stnList.size();
    ArrayInt.D1 firstProfileArray = new ArrayInt.D1(nstns);
    ArrayInt.D1 numProfileArray = new ArrayInt.D1(nstns);
    ArrayInt.D1 nextProfileArray = new ArrayInt.D1(nprofiles);

    for (int i = 0; i < stnList.size(); i++) {
      ucar.unidata.geoloc.Station stn = stnList.get(i);
      StationTracker tracker = stationMap.get(stn.getName());

      numProfileArray.set(i, tracker.numChildren);

      int first = (tracker.link.size() > 0) ? tracker.link.get(0) : -1;
      firstProfileArray.set(i, first);

      if (tracker.link.size() > 0) {
        // construct forward link
        List<Integer> nextList = tracker.link;
        for (int j = 0; j < nextList.size() - 1; j++) {
          Integer curr = nextList.get(j);
          Integer next = nextList.get(j + 1);
          nextProfileArray.set(curr, next);
        }
        Integer curr = nextList.get(nextList.size() - 1);
        nextProfileArray.set(curr, -1);
      }
    }

    try {
      ncfile.write(firstProfileName, firstProfileArray);
      ncfile.write(numProfilesName, numProfileArray);
      ncfile.write(nextProfileName, nextProfileArray);

    } catch (InvalidRangeException e) {
      e.printStackTrace();
      throw new IllegalStateException(e);
    }

    // finish the profile data
    ArrayInt.D1 nextObsArray = new ArrayInt.D1(recno);
    ArrayInt.D1 firstObsArray = new ArrayInt.D1(nprofiles);
    ArrayInt.D1 numObsArray = new ArrayInt.D1(nprofiles);

    for (int i = 0; i < stnList.size(); i++) {
      ucar.unidata.geoloc.Station stn = stnList.get(i);
      StationTracker stnTracker = stationMap.get(stn.getName());

      Set<Date> dates = stnTracker.profileMap.keySet();
      for (Date date : dates) {
        ProfileTracker proTracker = stnTracker.profileMap.get(date);
        int trackerIndex = proTracker.parent_index;
        numObsArray.set(trackerIndex, proTracker.numChildren);

        int first = (proTracker.link.size() > 0) ? proTracker.link.get(0) : -1;
        firstObsArray.set(trackerIndex, first);

        if (proTracker.link.size() > 0) {
          // construct forward link
          List<Integer> nextList = proTracker.link;
          for (int j = 0; j < nextList.size() - 1; j++) {
            Integer curr = nextList.get(j);
            Integer next = nextList.get(j + 1);
            nextObsArray.set(curr, next);
          }
          Integer curr = nextList.get(nextList.size() - 1);
          nextObsArray.set(curr, -1);
        }
      }
    }

    try {
      ncfile.write(firstObsName, firstObsArray);
      ncfile.write(numObsName, numObsArray);
      ncfile.write(nextObsName, nextObsArray);

    } catch (InvalidRangeException e) {
      e.printStackTrace();
      throw new IllegalStateException(e);
    }

    // finish the obs data

    ncfile.updateAttribute(
        null, new Attribute("time_coverage_start", dateFormatter.toDateTimeStringISO(minDate)));
    ncfile.updateAttribute(
        null, new Attribute("time_coverage_end", dateFormatter.toDateTimeStringISO(maxDate)));
  }
  public static NetcdfDataset buildStation(IObservationGroup obsGroup) {
    if (obsGroup.getDepths().length > 1) {
      return buildStationProfile(obsGroup);
    }
    NetcdfDataset ncds = null;
    File temp = null;
    try {
      /* Instantiate an empty NetcdfDataset object from the template ncml */
      temp = File.createTempFile("ooi", ".ncml");
      ncds = getNcdsFromTemplate(temp, "station.ncml");

      Map<String, String> allAttributes = new HashMap<String, String>();
      allAttributes.putAll(obsGroup.getAttributes());

      /* Do the station Id */
      ArrayInt.D0 aid = new ArrayInt.D0();
      aid.set(obsGroup.getId());
      ncds.findVariable("stnId").setCachedData(aid);

      /* Do the times */
      Number[] times = obsGroup.getTimes();
      IObservationGroup.DataType tdt = obsGroup.getTimeDataType();
      ncds.findDimension("time").setLength(times.length);
      Variable tvar = ncds.findVariable("time");
      tvar.setDataType(getNcDataType(tdt));
      tvar.setCachedData(getNcArray(times, tdt));

      /* Do the lat & lon */
      IObservationGroup.DataType lldt = obsGroup.getLatLonDataType();
      DataType ncdtLl = getNcDataType(lldt);
      Variable laVar = ncds.findVariable("lat");
      laVar.setDataType(ncdtLl);
      laVar.setCachedData(getNcScalar(obsGroup.getLat(), lldt));
      Variable loVar = ncds.findVariable("lon");
      loVar.setDataType(ncdtLl);
      loVar.setCachedData(getNcScalar(obsGroup.getLon(), lldt));

      /* Do the depth */
      IObservationGroup.DataType ddt = obsGroup.getDepthDataType();
      VariableDS zVar =
          new VariableDS(
              ncds, null, null, "stnDepth", getNcDataType(ddt), "", "m", "station depth");
      zVar.addAttribute(new Attribute("positive", "down"));
      ncds.addVariable(null, zVar);
      Number depth = obsGroup.getDepths()[0];
      zVar.setCachedData(getNcScalar(obsGroup.getDepths()[0], ddt));

      /* Do the data variables */
      for (VariableParams dn : obsGroup.getDataNames()) {
        DataType ncdtData = getNcDataType(dn.getDataType());
        VariableDS dvar =
            new VariableDS(
                ncds,
                null,
                null,
                dn.getShortName(),
                ncdtData,
                "time",
                dn.getUnits(),
                dn.getDescription());
        dvar.addAttribute(new Attribute(CF.COORDINATES, "time lon lat"));
        dvar.addAttribute(new Attribute(CF.STANDARD_NAME, dn.getStandardName()));
        Array adata = Array.factory(ncdtData, new int[] {times.length});
        IndexIterator aii = adata.getIndexIterator();
        dvar.setCachedData(adata);
        ncds.addVariable(null, dvar);

        for (int ti = 0; ti < times.length; ti++) {
          putArrayData(aii, ncdtData, obsGroup.getData(dn, times[ti], depth));
        }
      }

      /* Add global attributes */
      for (String key : allAttributes.keySet()) {
        ncds.addAttribute(null, new Attribute(key, allAttributes.get(key)));
      }

    } catch (FileNotFoundException ex) {
      Logger.getLogger(NcdsFactory.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IOException ex) {
      Logger.getLogger(NcdsFactory.class.getName()).log(Level.SEVERE, null, ex);
    } finally {
      if (temp != null) {
        if (!temp.delete()) {
          temp.deleteOnExit();
        }
      }
      if (ncds != null) {
        ncds.finish();
      }
    }

    return ncds;
  }