Input: deserialize the Grib1Record object [CODESPLIT] private Grib1Record readRecord ( Grib1IndexProto . Grib1Record p ) { Grib1SectionIndicator is = new Grib1SectionIndicator ( p . getGribMessageStart ( ) , p . getGribMessageLength ( ) ) ; Grib1SectionProductDefinition pds = new Grib1SectionProductDefinition ( p . getPds ( ) . toByteArray ( ) ) ; Grib1SectionGridDefinition gds = pds . gdsExists ( ) ? gdsList . get ( p . getGdsIdx ( ) ) : new Grib1SectionGridDefinition ( pds ) ; Grib1SectionBitMap bms = pds . bmsExists ( ) ? new Grib1SectionBitMap ( p . getBmsPos ( ) ) : null ; Grib1SectionBinaryData dataSection = new Grib1SectionBinaryData ( p . getDataPos ( ) , p . getDataLen ( ) ) ; return new Grib1Record ( p . getHeader ( ) . toByteArray ( ) , is , gds , pds , bms , dataSection ) ; }


Input:
LOOK what about extending an index ?? [CODESPLIT] public boolean makeIndex ( String filename , RandomAccessFile dataRaf ) throws IOException { String idxPath = filename ; if ( ! idxPath . endsWith ( GBX9_IDX ) ) idxPath += GBX9_IDX ; File idxFile = GribIndexCache . getFileOrCache ( idxPath ) ; File idxFileTmp = GribIndexCache . getFileOrCache ( idxPath + ".tmp" ) ; RandomAccessFile raf = null ; try ( FileOutputStream fout = new FileOutputStream ( idxFileTmp ) ) { //// header message
 fout . write ( MAGIC_START . getBytes ( CDM . utf8Charset ) ) ; NcStream . writeVInt ( fout , version ) ; Map < Long , Integer > gdsMap = new HashMap <> ( ) ; gdsList = new ArrayList <> ( ) ; records = new ArrayList <> ( 200 ) ; Grib1IndexProto . Grib1Index . Builder rootBuilder = Grib1IndexProto . Grib1Index . newBuilder ( ) ; rootBuilder . setFilename ( filename ) ; if ( dataRaf == null ) { // open if dataRaf not already open
 raf = RandomAccessFile . acquire ( filename ) ; dataRaf = raf ; } Grib1RecordScanner scan = new Grib1RecordScanner ( dataRaf ) ; while ( scan . hasNext ( ) ) { Grib1Record r = scan . next ( ) ; if ( r == null ) break ; // done
 records . add ( r ) ; Grib1SectionGridDefinition gdss = r . getGDSsection ( ) ; Integer index = gdsMap . get ( gdss . calcCRC ( ) ) ; if ( gdss . getPredefinedGridDefinition ( ) >= 0 ) // skip predefined gds - they dont have raw bytes
 index = 0 ; else if ( index == null ) { gdsList . add ( gdss ) ; index = gdsList . size ( ) - 1 ; gdsMap . put ( gdss . calcCRC ( ) , index ) ; rootBuilder . addGdsList ( makeGdsProto ( gdss ) ) ; } rootBuilder . addRecords ( makeRecordProto ( r , index ) ) ; } if ( records . isEmpty ( ) ) throw new RuntimeException ( "No GRIB1 records found in " + dataRaf . getLocation ( ) ) ; ucar . nc2 . grib . grib1 . Grib1IndexProto . Grib1Index index = rootBuilder . build ( ) ; byte [ ] b = index . toByteArray ( ) ; NcStream . writeVInt ( fout , b . length ) ; // message size
 fout . write ( b ) ; // message  - all in one gulp
 logger . debug ( "  made gbx9 index for {} size={}" , filename , b . length ) ; return true ; } finally { if ( raf != null ) raf . close ( ) ; // only close if it was opened here
 // now switch
 RandomAccessFile . eject ( idxFile . getPath ( ) ) ; boolean deleteOk = ! idxFile . exists ( ) || idxFile . delete ( ) ; boolean renameOk = idxFileTmp . renameTo ( idxFile ) ; if ( ! deleteOk ) logger . error ( "  could not delete Grib1Index= {}" , idxFile . getPath ( ) ) ; if ( ! renameOk ) logger . error ( "  could not rename Grib1Index= {}" , idxFile . getPath ( ) ) ; } }


Input: This implementation requires a relative path . The relative path may not start with .. / or once normalized start with .. / . Here normalized means that . / and path / .. segments are removed e . g . dir1 / .. / .. / dir2 once normalized would be .. / dir2 . [CODESPLIT] public File getFile ( String path ) { File file ; for ( DescendantFileSource curLocator : chain ) { file = curLocator . getFile ( path ) ; if ( file != null ) return file ; } return null ; }


Input: Do we think this is a M3IO file . [CODESPLIT] public static boolean isMine ( NetcdfFile ncfile ) { return ( null != ncfile . findGlobalAttribute ( "XORIG" ) ) && ( null != ncfile . findGlobalAttribute ( "YORIG" ) ) && ( null != ncfile . findGlobalAttribute ( "XCELL" ) ) && ( null != ncfile . findGlobalAttribute ( "YCELL" ) ) && ( null != ncfile . findGlobalAttribute ( "NCOLS" ) ) && ( null != ncfile . findGlobalAttribute ( "NROWS" ) ) ; // M3IOVGGridConvention - is this true for this class ?? // return ncFile.findGlobalAttribute( "VGLVLS" ) != null && isValidM3IOFile_( ncFile ); }


Input:
Intend to use EPSG system parameters [CODESPLIT] private CoordinateTransform makeUTMProjection ( NetcdfDataset ds ) { int zone = ( int ) findAttributeDouble ( ds , "P_ALP" ) ; double ycent = findAttributeDouble ( ds , "YCENT" ) ; //double lon0 = findAttributeDouble( "X_CENT"); //double lat0 = findAttributeDouble( "Y_CENT"); /**
     * Construct a UTM Projection.
     * @param zone - UTM zone
     * @param if ycent < 0, then isNorth = False
     */ boolean isNorth = true ; if ( ycent < 0 ) isNorth = false ; UtmProjection utm = new UtmProjection ( zone , isNorth ) ; return new ProjectionCT ( "UTM" , "EPSG" , utm ) ; }


Input: /////////////////////////////////////////////////////////////////////// [CODESPLIT] protected AxisType getAxisType ( NetcdfDataset ds , VariableEnhanced ve ) { Variable v = ( Variable ) ve ; String vname = v . getShortName ( ) ; if ( vname . equalsIgnoreCase ( "x" ) ) return AxisType . GeoX ; if ( vname . equalsIgnoreCase ( "y" ) ) return AxisType . GeoY ; if ( vname . equalsIgnoreCase ( "lat" ) ) return AxisType . Lat ; if ( vname . equalsIgnoreCase ( "lon" ) ) return AxisType . Lon ; if ( vname . equalsIgnoreCase ( "time" ) ) return AxisType . Time ; if ( vname . equalsIgnoreCase ( "level" ) ) return AxisType . GeoZ ; return null ; }


Input: Open the service provider for reading . [CODESPLIT] public void open ( RandomAccessFile raf , NetcdfFile ncfile , CancelTask cancelTask ) throws IOException { super . open ( raf , ncfile , cancelTask ) ; if ( areaReader == null ) areaReader = new AreaReader ( ) ; try { areaReader . init ( raf . getLocation ( ) , ncfile ) ; } catch ( Throwable e ) { close ( ) ; // try not to leak files throw new IOException ( e ) ; } finally { raf . close ( ) ; // avoid leaks } }


Input: Read the data for the variable [CODESPLIT] public Array readData ( Variable v2 , Section section ) throws IOException , InvalidRangeException { return areaReader . readVariable ( v2 , section ) ; }


Input: reacquire any resources like file handles [CODESPLIT] public void reacquire ( ) throws IOException { try { areaReader . af = new AreaFile ( location ) ; } catch ( Throwable e ) { throw new IOException ( e ) ; } }


Input: Is this date before the given date . if isPresent always false . [CODESPLIT] public boolean before ( Date d ) { if ( isPresent ( ) ) return false ; return date . isBefore ( CalendarDate . of ( d ) ) ; }


Input: Is this date before the given date . if d . isPresent always true else if this . isPresent false . [CODESPLIT] public boolean before ( DateType d ) { if ( d . isPresent ( ) ) return true ; if ( isPresent ( ) ) return false ; return date . isBefore ( d . getCalendarDate ( ) ) ; }


Input: Is this date after the given date . if isPresent always true . [CODESPLIT] public boolean after ( Date d ) { if ( isPresent ( ) ) return true ; return date . isAfter ( CalendarDate . of ( d ) ) ; }


Input: test [CODESPLIT] private static void doOne ( String s ) { try { System . out . println ( "\nString = (" + s + ")" ) ; DateType d = new DateType ( s , null , null ) ; System . out . println ( "DateType = (" + d . toString ( ) + ")" ) ; System . out . println ( "Date = (" + d . getDate ( ) + ")" ) ; } catch ( java . text . ParseException e ) { e . printStackTrace ( ) ; } }


Input: when we have a real catalog ( filename ! = CATSCAN ) [CODESPLIT] public ConfigCatalog getCatalog ( File baseDir , String matchRemaining , String filename , CatalogReader reader ) throws IOException { String relLocation = ( matchRemaining . length ( ) >= 1 ) ? location + "/" + matchRemaining : location ; File absLocation = new File ( baseDir , relLocation ) ; ConfigCatalog cc = reader . getFromAbsolutePath ( absLocation + "/" + filename ) ; if ( cc == null ) logger . warn ( "Cant find catalog from scan: " + absLocation + "/" + filename ) ; return cc ; }


Input: when we have a catalog built from a directory ( filename == CATSCAN ) [CODESPLIT] public CatalogBuilder makeCatalogFromDirectory ( File baseDir , String matchRemaining , URI baseURI ) throws IOException { String relLocation = ( matchRemaining . length ( ) >= 1 ) ? location + "/" + matchRemaining : location ; String name = ( matchRemaining . length ( ) >= 1 ) ? getName ( ) + "/" + matchRemaining : getName ( ) ; File absLocation = new File ( baseDir , relLocation ) ; // it must be a directory Path wantDir = absLocation . toPath ( ) ; if ( ! Files . exists ( wantDir ) ) throw new FileNotFoundException ( "Requested catalog does not exist =" + absLocation ) ; if ( ! Files . isDirectory ( wantDir ) ) throw new FileNotFoundException ( "Not a directory =" + absLocation ) ; // Setup and create catalog builder. CatalogBuilder catBuilder = new CatalogBuilder ( ) ; catBuilder . setBaseURI ( baseURI ) ; assert this . getParentCatalog ( ) != null ; DatasetBuilder top = new DatasetBuilder ( null ) ; top . transferMetadata ( this , true ) ; top . setName ( name ) ; top . put ( Dataset . Id , null ) ; // no id for top catBuilder . addDataset ( top ) ; // first look for catalogs try ( DirectoryStream < Path > ds = Files . newDirectoryStream ( wantDir , "*.xml" ) ) { for ( Path p : ds ) { if ( ! Files . isDirectory ( p ) ) { String pfilename = p . getFileName ( ) . toString ( ) ; String urlPath = pfilename ; //String path = dataDirComplete.length() == 0 ? filename : dataDirComplete + "/" + filename;  // reletive starting from current directory CatalogRefBuilder catref = new CatalogRefBuilder ( top ) ; catref . setTitle ( urlPath ) ; catref . setHref ( urlPath ) ; top . addDataset ( catref ) ; } } } // now look for directories try ( DirectoryStream < Path > ds = Files . newDirectoryStream ( wantDir ) ) { for ( Path dir : ds ) { if ( Files . isDirectory ( dir ) ) { String dfilename = dir . getFileName ( ) . toString ( ) ; String urlPath = ( matchRemaining . length ( ) >= 1 ) ? dfilename + "/" + matchRemaining : dfilename ; CatalogRefBuilder catref = new CatalogRefBuilder ( top ) ; catref . setTitle ( urlPath ) ; catref . setHref ( urlPath + "/" + CATSCAN ) ; catref . addToList ( Dataset . Properties , new Property ( "CatalogScan" , "true" ) ) ; top . addDataset ( catref ) ; } } } return catBuilder ; }


Input: Return the known CollectionType that matches the given name ( ignoring case ) or null if the name is unknown . [CODESPLIT] public static CollectionType findType ( String name ) { if ( name == null ) return null ; for ( CollectionType m : members ) { if ( m . name . equalsIgnoreCase ( name ) ) return m ; } return null ; }


Input: Return a CollectionType that matches the given name by either matching a known type ( ignoring case ) or creating an unknown type . [CODESPLIT] public static CollectionType getType ( String name ) { if ( name == null ) return null ; CollectionType type = findType ( name ) ; return type != null ? type : new CollectionType ( name , false ) ; }


Input: Set the i th value of the array . [CODESPLIT] public final void setValue ( int i , BaseType newVal ) { vals [ i ] = newVal ; BaseType parent = ( BaseType ) getTemplate ( ) . getParent ( ) ; vals [ i ] . setParent ( parent ) ; }


Input:
Reads data from a <code > DataInputStream< / code > . This method is only used on the client side of the OPeNDAP client / server connection . [CODESPLIT] public synchronized void deserialize ( DataInputStream source , ServerVersion sv , StatusUI statusUI ) throws IOException , EOFException , DataReadException { for ( int i = 0 ; i < vals . length ; i ++ ) { // create new variable from template
 vals [ i ] = ( BaseType ) getTemplate ( ) . clone ( ) ; ( ( ClientIO ) vals [ i ] ) . deserialize ( source , sv , statusUI ) ; if ( statusUI != null && statusUI . userCancelled ( ) ) throw new DataReadException ( "User cancelled" ) ; } }


Input:
Writes data to a <code > DataOutputStream< / code > . This method is used primarily by GUI clients which need to download OPeNDAP data manipulate it and then re - save it as a binary file . [CODESPLIT] public void externalize ( DataOutputStream sink ) throws IOException { for ( int i = 0 ; i < vals . length ; i ++ ) { // LogStream.out.println("\t\t\tI AM THE WALRUS!");
 ( ( ClientIO ) vals [ i ] ) . externalize ( sink ) ; } }


Input: Add a CoordinateSystem to the dataset . [CODESPLIT] public void addCoordinateSystem ( CoordinateSystem cs ) { if ( cs == null ) throw new RuntimeException ( "Attempted to add null CoordinateSystem to var " + forVar . getFullName ( ) ) ; if ( coordSys == null ) coordSys = new ArrayList <> ( 5 ) ; coordSys . add ( cs ) ; }


Input: Get the description of the Variable . Default is to look for attributes in this order : CDM . LONG_NAME description title standard_name . [CODESPLIT] public String getDescription ( ) { if ( ( desc == null ) && ( forVar != null ) ) { Attribute att = forVar . findAttributeIgnoreCase ( CDM . LONG_NAME ) ; if ( ( att != null ) && att . isString ( ) ) desc = att . getStringValue ( ) ; if ( desc == null ) { att = forVar . findAttributeIgnoreCase ( "description" ) ; if ( ( att != null ) && att . isString ( ) ) desc = att . getStringValue ( ) ; } if ( desc == null ) { att = forVar . findAttributeIgnoreCase ( CDM . TITLE ) ; if ( ( att != null ) && att . isString ( ) ) desc = att . getStringValue ( ) ; } if ( desc == null ) { att = forVar . findAttributeIgnoreCase ( CF . STANDARD_NAME ) ; if ( ( att != null ) && att . isString ( ) ) desc = att . getStringValue ( ) ; } } return ( desc == null ) ? null : desc . trim ( ) ; }


Input: Set the Unit String for this Variable . Default is to use the CDM . UNITS attribute . [CODESPLIT] public void setUnitsString ( String units ) { this . units = units ; forVar . addAttribute ( new Attribute ( CDM . UNITS , units ) ) ; }


Input: Get the Unit String for the Variable . May be set explicitly else look for attribute CDM . UNITS . [CODESPLIT] public String getUnitsString ( ) { String result = units ; if ( ( result == null ) && ( forVar != null ) ) { Attribute att = forVar . findAttribute ( CDM . UNITS ) ; if ( att == null ) att = forVar . findAttributeIgnoreCase ( CDM . UNITS ) ; if ( ( att != null ) && att . isString ( ) ) result = att . getStringValue ( ) ; } return ( result == null ) ? null : result . trim ( ) ; }


Input: called from TdsInit on spring - managed auto - wired bean [CODESPLIT] public synchronized void init ( ReadMode readMode , PreferencesExt prefs ) { if ( readMode == null ) readMode = defaultReadMode ; this . prefs = prefs ; trackerNumber = prefs . getLong ( "trackerNumber" , 1 ) ; numberCatalogs = prefs . getInt ( "numberCatalogs" , 10 ) ; nextCatId = prefs . getLong ( "nextCatId" , 1 ) ; makeDebugActions ( ) ; this . contentRootPath = this . tdsContext . getThreddsDirectory ( ) ; this . contextPath = tdsContext . getContextPath ( ) ; reread ( readMode , true ) ; }


Input: called from init () and from trigger controller [CODESPLIT] public synchronized boolean reread ( ReadMode readMode , boolean isStartup ) { readNow = System . currentTimeMillis ( ) ; logCatalogInit . info ( "=========================================================================================\n" + "ConfigCatalogInitialization readMode={} isStartup={}" , readMode , isStartup ) ; catPathMap = new HashSet <> ( ) ; fcNameMap = new HashMap <> ( ) ; if ( ccc != null ) ccc . invalidateAll ( ) ; // remove anything in cache if ( fcCache != null ) fcCache . invalidateAll ( ) ; // remove anything in cache if ( ! isStartup && readMode == ReadMode . always ) trackerNumber ++ ; // must write a new database if TDS is already running and rereading all if ( ! isDebugMode || this . datasetTracker == null ) this . datasetTracker = new DatasetTrackerChronicle ( trackerDir , maxDatasets , trackerNumber ) ; boolean databaseAlreadyExists = datasetTracker . exists ( ) ; // detect if tracker database exists if ( ! databaseAlreadyExists ) { readMode = ReadMode . always ; logCatalogInit . info ( "ConfigCatalogInitializion datasetTracker database does not exist, set readMode to=" + readMode ) ; } if ( this . callback == null ) this . callback = new StatCallback ( readMode ) ; // going to reread global services allowedServices . clearGlobalServices ( ) ; switch ( readMode ) { case always : // if the database already exists, we need to close it // before we reinit if ( databaseAlreadyExists ) { logCatalogInit . info ( "ConfigCatalogInitializion datasetTracker database already exists - closing it before reinitialization." ) ; try { this . datasetTracker . close ( ) ; } catch ( IOException e ) { logCatalogInit . error ( "There was an error closing the datasetTracker database." , e ) ; } this . datasetTracker . reinit ( ) ; } this . catalogTracker = new CatalogTracker ( trackerDir , true , numberCatalogs , nextCatId ) ; this . dataRootTracker = new DataRootTracker ( trackerDir , true , callback ) ; this . dataRootPathMatcher = new DataRootPathMatcher ( ccc , dataRootTracker ) ; // starting over readRootCatalogs ( readMode ) ; break ; case check : this . catalogTracker = new CatalogTracker ( trackerDir , false , numberCatalogs , nextCatId ) ; // use existing catalog list this . dataRootTracker = new DataRootTracker ( trackerDir , false , callback ) ; // use existing data roots this . dataRootPathMatcher = new DataRootPathMatcher ( ccc , dataRootTracker ) ; readRootCatalogs ( readMode ) ; // read just roots to get global services checkExistingCatalogs ( readMode ) ; break ; case triggerOnly : this . catalogTracker = new CatalogTracker ( trackerDir , false , numberCatalogs , nextCatId ) ; // use existing catalog list this . dataRootTracker = new DataRootTracker ( trackerDir , false , callback ) ; // use existing data roots this . dataRootPathMatcher = new DataRootPathMatcher ( ccc , dataRootTracker ) ; readRootCatalogs ( readMode ) ; // read just roots to get global services break ; } numberCatalogs = catalogTracker . size ( ) ; nextCatId = catalogTracker . getNextCatId ( ) ; if ( prefs != null ) { prefs . putLong ( "trackerNumber" , trackerNumber ) ; prefs . putLong ( "nextCatId" , nextCatId ) ; prefs . putInt ( "numberCatalogs" , numberCatalogs ) ; } callback . finish ( ) ; logCatalogInit . info ( "\nConfigCatalogInitializion stats\n" + callback ) ; try { datasetTracker . save ( ) ; catalogTracker . save ( ) ; dataRootTracker . save ( ) ; } catch ( IOException e ) { // e.printStackTrace(); logCatalogInit . error ( "datasetTracker.save() failed" , e ) ; } // heres where we may be doing a switcheroo in a running TDS if ( dataRootManager != null ) dataRootManager . setDataRootPathMatcher ( dataRootPathMatcher ) ; if ( datasetManager != null ) datasetManager . setDatasetTracker ( datasetTracker ) ; // cleanup old version of the database if ( ! isStartup && readMode == ReadMode . always ) { DatasetTrackerChronicle . cleanupBefore ( trackerDir , trackerNumber ) ; } long took = System . currentTimeMillis ( ) - readNow ; logCatalogInit . info ( "ConfigCatalogInitializion finished took={} msecs" , took ) ; // cleanup catPathMap = null ; fcNameMap = null ; catalogTracker = null ; return true ; // ok }


Input: catalogRelpath must be relative to rootDir [CODESPLIT] private void checkCatalogToRead ( ReadMode readMode , String catalogRelPath , boolean isRoot , long lastRead ) throws IOException { if ( exceedLimit ) return ; catalogRelPath = StringUtils . cleanPath ( catalogRelPath ) ; File catalogFile = new File ( this . contentRootPath , catalogRelPath ) ; if ( ! catalogFile . exists ( ) ) { catalogTracker . removeCatalog ( catalogRelPath ) ; logCatalogInit . error ( ERROR + "initCatalog(): Catalog [" + catalogRelPath + "] does not exist." ) ; return ; } long lastModified = catalogFile . lastModified ( ) ; if ( ! isRoot && readMode != ReadMode . always && lastModified < lastRead ) return ; // skip catalogs that havent changed if ( ! isRoot && readMode == ReadMode . triggerOnly ) return ; // skip non-root catalogs for trigger only if ( show ) System . out . printf ( "initCatalog %s%n" , catalogRelPath ) ; // make sure we havent already read it if ( catPathMap . contains ( catalogRelPath ) ) { logCatalogInit . error ( ERROR + "initCatalog(): Catalog [" + catalogRelPath + "] already seen, possible loop (skip)." ) ; return ; } catPathMap . add ( catalogRelPath ) ; Set < String > idSet = new HashSet <> ( ) ; // look for unique ids // if (logCatalogInit.isDebugEnabled()) logCatalogInit.debug("initCatalog {} -> {}", path, f.getAbsolutePath()); // read it ConfigCatalog cat = readCatalog ( catalogRelPath , catalogFile . getPath ( ) ) ; if ( cat == null ) { logCatalogInit . error ( ERROR + "initCatalog(): failed to read catalog <" + catalogFile . getPath ( ) + ">." ) ; return ; } long catId = catalogTracker . put ( new CatalogExt ( 0 , catalogRelPath , isRoot , readNow ) ) ; if ( isRoot ) { if ( ccc != null ) ccc . put ( catalogRelPath , cat ) ; allowedServices . addGlobalServices ( cat . getServices ( ) ) ; if ( readMode == ReadMode . triggerOnly ) return ; // thats all we need } if ( callback != null ) callback . hasCatalogRef ( cat ) ; // look for datasetRoots for ( DatasetRootConfig p : cat . getDatasetRoots ( ) ) dataRootPathMatcher . addRoot ( p , catalogRelPath , readMode == ReadMode . always ) ; // check for duplicates on complete reread if ( callback == null ) { // LOOK WTF? List < String > disallowedServices = allowedServices . getDisallowedServices ( cat . getServices ( ) ) ; if ( ! disallowedServices . isEmpty ( ) ) { allowedServices . getDisallowedServices ( cat . getServices ( ) ) ; logCatalogInit . error ( ERROR + "initCatalog(): declared services: " + Arrays . toString ( disallowedServices . toArray ( ) ) + " in catalog: " + catalogFile . getPath ( ) + " are disallowed in threddsConfig file" ) ; } } // look for dataRoots in datasetScans and featureCollections dataRootPathMatcher . extractDataRoots ( catalogRelPath , cat . getDatasetsLocal ( ) , readMode == ReadMode . always , fcNameMap ) ; // get the directory path, reletive to the rootDir int pos = catalogRelPath . lastIndexOf ( "/" ) ; String dirPath = ( pos > 0 ) ? catalogRelPath . substring ( 0 , pos + 1 ) : "" ; processDatasets ( catId , readMode , dirPath , cat . getDatasetsLocal ( ) , idSet ) ; // recurse // look for catalogScans for ( CatalogScan catScan : cat . getCatalogScans ( ) ) { if ( exceedLimit ) return ; Path relLocation = Paths . get ( dirPath , catScan . getLocation ( ) ) ; Path absLocation = Paths . get ( catalogFile . getParent ( ) , catScan . getLocation ( ) ) ; // if (catalogWatcher != null) catalogWatcher.registerAll(absLocation); readCatsInDirectory ( readMode , relLocation . toString ( ) , absLocation ) ; } }


Input: Does the actual work of reading a catalog . [CODESPLIT] private ConfigCatalog readCatalog ( String catalogRelPath , String catalogFullPath ) { URI uri ; try { // uri = new URI("file:" + StringUtil2.escape(catalogFullPath, "/:-_.")); // needed ? uri = new URI ( this . contextPath + "/catalog/" + catalogRelPath ) ; } catch ( URISyntaxException e ) { logCatalogInit . error ( ERROR + "readCatalog(): URISyntaxException=" + e . getMessage ( ) ) ; return null ; } ConfigCatalogBuilder builder = new ConfigCatalogBuilder ( ) ; try { // read the catalog logCatalogInit . info ( "-------readCatalog(): path=" + catalogRelPath ) ; ConfigCatalog cat = ( ConfigCatalog ) builder . buildFromLocation ( catalogFullPath , uri ) ; if ( builder . hasFatalError ( ) ) { logCatalogInit . error ( ERROR + "   invalid catalog -- " + builder . getErrorMessage ( ) ) ; return null ; } if ( builder . getErrorMessage ( ) . length ( ) > 0 ) logCatalogInit . debug ( builder . getErrorMessage ( ) ) ; return cat ; } catch ( Throwable t ) { logCatalogInit . error ( ERROR + "  Exception on catalog=" + catalogFullPath + " " + t . getMessage ( ) + "\n log=" + builder . getErrorMessage ( ) , t ) ; return null ; } }


Input: dirPath = the directory path reletive to the rootDir [CODESPLIT] private void processDatasets ( long catId , ReadMode readMode , String dirPath , List < Dataset > datasets , Set < String > idMap ) throws IOException { if ( exceedLimit ) return ; for ( Dataset ds : datasets ) { if ( datasetTracker . trackDataset ( catId , ds , callback ) ) countDatasets ++ ; if ( maxDatasetsProcess > 0 && countDatasets > maxDatasetsProcess ) exceedLimit = true ; // look for duplicate ids String id = ds . getID ( ) ; if ( id != null ) { if ( idMap . contains ( id ) ) { logCatalogInit . error ( ERROR + "Duplicate id on  '" + ds . getName ( ) + "' id= '" + id + "'" ) ; } else { idMap . add ( id ) ; } } if ( ( ds instanceof DatasetScan ) || ( ds instanceof FeatureCollectionRef ) ) continue ; if ( ds instanceof CatalogScan ) continue ; if ( ds instanceof CatalogRef ) { // follow catalog refs CatalogRef catref = ( CatalogRef ) ds ; String href = catref . getXlinkHref ( ) ; // if (logCatalogInit.isDebugEnabled()) logCatalogInit.debug("  catref.getXlinkHref=" + href); // Check that catRef is relative if ( ! href . startsWith ( "http:" ) ) { // Clean up relative URLs that start with "./" if ( href . startsWith ( "./" ) ) { href = href . substring ( 2 ) ; } String path ; String contextPathPlus = this . contextPath + "/" ; if ( href . startsWith ( contextPathPlus ) ) { path = href . substring ( contextPathPlus . length ( ) ) ; // absolute starting from content root } else if ( href . startsWith ( "/" ) ) { // Drop the catRef because it points to a non-TDS served catalog. logCatalogInit . error ( ERROR + "Skipping catalogRef <xlink:href=" + href + ">. Reference is relative to the server outside the context path [" + contextPathPlus + "]. " + "Parent catalog info: Name=\"" + catref . getParentCatalog ( ) . getName ( ) + "\"; Base URI=\"" + catref . getParentCatalog ( ) . getUriString ( ) + "\"; dirPath=\"" + dirPath + "\"." ) ; continue ; } else { path = dirPath + href ; // reletive starting from current directory } CatalogExt ext = catalogTracker . get ( path ) ; long lastRead = ( ext == null ) ? 0 : ext . getLastRead ( ) ; checkCatalogToRead ( readMode , path , false , lastRead ) ; } } else { // recurse through nested datasets processDatasets ( catId , readMode , dirPath , ds . getDatasetsLocal ( ) , idMap ) ; } } }


Input: dirPath is the directory relative to rootDir directory is absolute [CODESPLIT] private void readCatsInDirectory ( ReadMode readMode , String dirPath , Path directory ) throws IOException { if ( exceedLimit ) return ; // do any catalogs first try ( DirectoryStream < Path > ds = Files . newDirectoryStream ( directory , "*.xml" ) ) { for ( Path p : ds ) { if ( ! Files . isDirectory ( p ) ) { // path must be relative to rootDir String filename = p . getFileName ( ) . toString ( ) ; String path = dirPath . length ( ) == 0 ? filename : dirPath + "/" + filename ; // reletive starting from current directory CatalogExt ext = catalogTracker . get ( path ) ; long lastRead = ( ext == null ) ? 0 : ext . getLastRead ( ) ; checkCatalogToRead ( readMode , path , false , lastRead ) ; } } } // now recurse into the directory try ( DirectoryStream < Path > ds = Files . newDirectoryStream ( directory ) ) { for ( Path dir : ds ) { if ( Files . isDirectory ( dir ) ) { String dirPathChild = dirPath + "/" + dir . getFileName ( ) . toString ( ) ; // reletive starting from current directory readCatsInDirectory ( readMode , dirPathChild , dir ) ; } } } }


Input: ///////////////////////////////////////////////////////////////////////////////////////////////////////////// [CODESPLIT] public void makeDebugActions ( ) { DebugCommands . Category debugHandler = debugCommands . findCategory ( "Catalogs" ) ; DebugCommands . Action act ; act = new DebugCommands . Action ( "showCatalogExt" , "Show known catalogs" ) { public void doAction ( DebugCommands . Event e ) { e . pw . printf ( "numberCatalogs=%d nextCatId=%d%n" , numberCatalogs , nextCatId ) ; e . pw . printf ( "%nid  root  lastRead     path%n" ) ; CatalogTracker catalogTracker = new CatalogTracker ( trackerDir , false , numberCatalogs , 0 ) ; for ( CatalogExt cat : catalogTracker . getCatalogs ( ) ) { e . pw . printf ( "%3d: %5s %s %s%n" , cat . getCatId ( ) , cat . isRoot ( ) , CalendarDate . of ( cat . getLastRead ( ) ) , cat . getCatRelLocation ( ) ) ; } } } ; debugHandler . addAction ( act ) ; act = new DebugCommands . Action ( "showRoots" , "Show root catalogs" ) { public void doAction ( DebugCommands . Event e ) { StringBuilder sbuff = new StringBuilder ( ) ; synchronized ( ConfigCatalogInitialization . this ) { for ( String catPath : rootCatalogKeys ) { sbuff . append ( " catalog= " ) . append ( catPath ) . append ( "\n" ) ; //String filename = StringUtil2.unescape(cat.getUriString()); //sbuff.append(" from= ").append(filename).append("\n"); } } e . pw . println ( ) ; e . pw . println ( Escape . html ( sbuff . toString ( ) ) ) ; } } ; debugHandler . addAction ( act ) ; act = new DebugCommands . Action ( "showStats" , "Show catalog initialization stats" ) { public void doAction ( DebugCommands . Event e ) { if ( callback != null ) e . pw . printf ( "%n%s%n" , Escape . html ( callback . toString ( ) ) ) ; else e . pw . printf ( "N/A%n" ) ; } } ; debugHandler . addAction ( act ) ; }


Input: Test if point lies between two longitudes deal with wrapping . [CODESPLIT] static public boolean betweenLon ( double lon , double lonBeg , double lonEnd ) { lonBeg = lonNormal ( lonBeg , lon ) ; lonEnd = lonNormal ( lonEnd , lon ) ; return ( lon >= lonBeg ) && ( lon <= lonEnd ) ; }


Input: put longitude into the range [ start start + 360 ] deg [CODESPLIT] static public double lonNormalFrom ( double lon , double start ) { while ( lon < start ) lon += 360 ; while ( lon > start + 360 ) lon -= 360 ; return lon ; }


Input: Make a nicely formatted representation of a latitude eg 40 . 34N or 12 . 9S . [CODESPLIT] static public String latToString ( double lat , int ndec ) { boolean is_north = ( lat >= 0.0 ) ; if ( ! is_north ) lat = - lat ; String f = "%." + ndec + "f" ; Formatter latBuff = new Formatter ( ) ; latBuff . format ( f , lat ) ; latBuff . format ( "%s" , is_north ? "N" : "S" ) ; return latBuff . toString ( ) ; }


Input: Make a nicely formatted representation of a longitude eg 120 . 3W or 99 . 99E . [CODESPLIT] static public String lonToString ( double lon , int ndec ) { double wlon = lonNormal ( lon ) ; boolean is_east = ( wlon >= 0.0 ) ; if ( ! is_east ) wlon = - wlon ; String f = "%." + ndec + "f" ; Formatter latBuff = new Formatter ( ) ; latBuff . format ( f , wlon ) ; latBuff . format ( "%s" , is_east ? "E" : "W" ) ; return latBuff . toString ( ) ; }


Input: Compares this base quantity to another base quantity . [CODESPLIT] public int compareTo ( final BaseQuantity that ) { int comp ; if ( this == that ) { comp = 0 ; } else { comp = getName ( ) . compareToIgnoreCase ( that . getName ( ) ) ; if ( comp == 0 && getSymbol ( ) != null ) { comp = getSymbol ( ) . compareTo ( that . getSymbol ( ) ) ; } } return comp ; }


Input: Tests this class . [CODESPLIT] public static void main ( final String [ ] args ) { System . out . println ( "AMOUNT_OF_SUBSTANCE.getName() = " + AMOUNT_OF_SUBSTANCE . getName ( ) ) ; System . out . println ( "LUMINOUS_INTENSITY.getSymbol() = " + LUMINOUS_INTENSITY . getSymbol ( ) ) ; System . out . println ( "PLANE_ANGLE.getSymbol() = " + PLANE_ANGLE . getSymbol ( ) ) ; System . out . println ( "LENGTH.equals(LENGTH) = " + LENGTH . equals ( LENGTH ) ) ; System . out . println ( "LENGTH.equals(MASS) = " + LENGTH . equals ( MASS ) ) ; System . out . println ( "LENGTH.equals(PLANE_ANGLE) = " + LENGTH . equals ( PLANE_ANGLE ) ) ; System . out . println ( "PLANE_ANGLE.equals(PLANE_ANGLE) = " + PLANE_ANGLE . equals ( PLANE_ANGLE ) ) ; System . out . println ( "PLANE_ANGLE.equals(SOLID_ANGLE) = " + PLANE_ANGLE . equals ( SOLID_ANGLE ) ) ; System . out . println ( "LENGTH.compareTo(LENGTH) = " + LENGTH . compareTo ( LENGTH ) ) ; System . out . println ( "LENGTH.compareTo(MASS) = " + LENGTH . compareTo ( MASS ) ) ; System . out . println ( "LENGTH.compareTo(PLANE_ANGLE) = " + LENGTH . compareTo ( PLANE_ANGLE ) ) ; System . out . println ( "PLANE_ANGLE.compareTo(PLANE_ANGLE) = " + PLANE_ANGLE . compareTo ( PLANE_ANGLE ) ) ; System . out . println ( "PLANE_ANGLE.compareTo(SOLID_ANGLE) = " + PLANE_ANGLE . compareTo ( SOLID_ANGLE ) ) ; }


Input: Get the currently selected InvDataset . [CODESPLIT] public DatasetNode getSelectedDataset ( ) { InvCatalogTreeNode tnode = getSelectedNode ( ) ; return tnode == null ? null : tnode . ds ; }


Input: Set the currently selected InvDataset . [CODESPLIT] public void setSelectedDataset ( Dataset ds ) { if ( ds == null ) return ; TreePath path = makePath ( ds ) ; if ( path == null ) return ; tree . setSelectionPath ( path ) ; tree . scrollPathToVisible ( path ) ; }


Input: Create the TreePath corresponding to the given TreeNode . [CODESPLIT] TreePath makeTreePath ( TreeNode node ) { ArrayList < TreeNode > path = new ArrayList <> ( ) ; path . add ( node ) ; TreeNode parent = node . getParent ( ) ; while ( parent != null ) { path . add ( 0 , parent ) ; parent = parent . getParent ( ) ; } Object [ ] paths = path . toArray ( ) ; return new TreePath ( paths ) ; }


Input: Open all nodes of the tree . [CODESPLIT] public void openAll ( boolean includeCatref ) { if ( catalog == null ) return ; open ( ( InvCatalogTreeNode ) model . getRoot ( ) , includeCatref ) ; tree . repaint ( ) ; }


Input: Set the InvCatalog to display . The catalog is read asynchronously and displayed if successfully read . You must use a PropertyChangeEventListener to be notified if successful . [CODESPLIT] public void setCatalog ( String location ) { CatalogBuilder builder = new CatalogBuilder ( ) ; try { Catalog cat = builder . buildFromLocation ( location , null ) ; setCatalog ( cat ) ; } catch ( Exception ioe ) { JOptionPane . showMessageDialog ( this , "Error opening catalog location " + location + " err=" + builder . getErrorMessage ( ) ) ; } }


Input: Set the catalog to be displayed . If ok then a Catalog PropertyChangeEvent is sent . [CODESPLIT] public void setCatalog ( Catalog catalog ) { if ( catalog == null ) return ; String catalogName = catalog . getBaseURI ( ) . toString ( ) ; this . catalog = catalog ; // send catalog event setCatalogURL ( catalogName ) ; // display tree // this sends TreeNode events model = new InvCatalogTreeModel ( catalog ) ; tree . setModel ( model ) ; // debug if ( debugTree ) { System . out . println ( "*** catalog/showJTree =" ) ; showNode ( tree . getModel ( ) , tree . getModel ( ) . getRoot ( ) ) ; System . out . println ( "*** " ) ; } // look for a specific dataset int pos = catalogName . indexOf ( ' ' ) ; if ( pos >= 0 ) { String id = catalogName . substring ( pos + 1 ) ; Dataset dataset = catalog . findDatasetByID ( id ) ; if ( dataset != null ) { setSelectedDataset ( dataset ) ; firePropertyChangeEvent ( new PropertyChangeEvent ( this , "Selection" , null , dataset ) ) ; } } // send catalog event firePropertyChangeEvent ( new PropertyChangeEvent ( this , "Catalog" , null , catalogName ) ) ; }


Input: debug [CODESPLIT] private void showNode ( TreeModel tree , Object node ) { if ( node == null ) return ; InvCatalogTreeNode tnode = ( InvCatalogTreeNode ) node ; DatasetNode cp = tnode . ds ; System . out . println ( " node= " + cp . getName ( ) + " leaf= " + tree . isLeaf ( node ) ) ; for ( int i = 0 ; i < tree . getChildCount ( node ) ; i ++ ) showNode ( tree , tree . getChild ( node , i ) ) ; }


Input: debugging only [CODESPLIT] public void showInfo ( Formatter f , Grib1Customizer cust1 ) { //f.format("%nVariables%n"); //f.format("%n  %3s %3s %3s%n", "time", "vert", "ens"); GribRecordStats all = new GribRecordStats ( ) ; for ( VariableBag vb : gribvars ) { f . format ( "Variable %s (%d)%n" , Grib1Iosp . makeVariableName ( cust , gribConfig , vb . first . getPDSsection ( ) ) , vb . hashCode ( ) ) ; vb . coordND . showInfo ( f , all ) ; //f.format("  %3d %3d %3d %s records = %d density = %f hash=%d", vb.timeCoordIndex, vb.vertCoordIndex, vb.ensCoordIndex, //        vname, vb.atomList.size(), vb.recordMap.density(), vb.cdmHash); f . format ( "%n" ) ; } f . format ( "%n all= %s" , all . show ( ) ) ; }


Input: look for aliases . [CODESPLIT] @ Override protected void findCoordinateAxes ( NetcdfDataset ds ) { for ( VarProcess vp : varList ) { if ( vp . isCoordinateVariable ) continue ; Variable ncvar = vp . v ; if ( ! ( ncvar instanceof VariableDS ) ) continue ; // cant be a structure String dimName = findAlias ( ds , ncvar ) ; if ( dimName . length ( ) == 0 ) // none continue ; Dimension dim = ds . findDimension ( dimName ) ; if ( null != dim ) { vp . isCoordinateAxis = true ; parseInfo . format ( " Coordinate Axis added (GDV alias) = %s for dimension %s%n" , vp . v . getFullName ( ) , dimName ) ; } } super . findCoordinateAxes ( ds ) ; // desperado findCoordinateAxesForce ( ds ) ; }


Input: look for an coord_axis or coord_alias attribute [CODESPLIT] private String findAlias ( NetcdfDataset ds , Variable v ) { String alias = ds . findAttValueIgnoreCase ( v , "coord_axis" , null ) ; if ( alias == null ) alias = ds . findAttValueIgnoreCase ( v , "coord_alias" , "" ) ; return alias ; }


Input: bigendian [CODESPLIT] public final void writeInt ( int v ) throws IOException { write ( int3 ( v ) ) ; write ( int2 ( v ) ) ; write ( int1 ( v ) ) ; write ( int0 ( v ) ) ; }


Input: Writes an int in a variable - length format . Writes between one and five bytes . Smaller values take fewer bytes . Negative numbers are not supported . [CODESPLIT] public int writeVInt ( int i ) throws IOException { int count = 0 ; while ( ( i & ~ 0x7F ) != 0 ) { writeByte ( ( byte ) ( ( i & 0x7f ) | 0x80 ) ) ; i >>>= 7 ; count ++ ; } writeByte ( ( byte ) i ) ; return count + 1 ; }


Input: Writes an long in a variable - length format . Writes between one and nine ( ? ) bytes . Smaller values take fewer bytes . Negative numbers are not supported . [CODESPLIT] public int writeVLong ( long i ) throws IOException { int count = 0 ; while ( ( i & ~ 0x7F ) != 0 ) { writeByte ( ( byte ) ( ( i & 0x7f ) | 0x80 ) ) ; i >>>= 7 ; count ++ ; } writeByte ( ( byte ) i ) ; return count + 1 ; }


Input: Writes a string . ( vlen ) [ char ] [CODESPLIT] public int writeString ( String s ) throws IOException { int length = s . length ( ) ; int count = writeVInt ( length ) ; count += writeChars ( s , 0 , length ) ; return count ; }


Input: Writes a sequence of UTF - 8 encoded characters from a string . [CODESPLIT] public int writeChars ( String s , int start , int length ) throws IOException { final int end = start + length ; int count = 0 ; for ( int i = start ; i < end ; i ++ ) { final int code = ( int ) s . charAt ( i ) ; if ( code >= 0x01 && code <= 0x7F ) { writeByte ( ( byte ) code ) ; count ++ ; } else if ( ( ( code >= 0x80 ) && ( code <= 0x7FF ) ) || code == 0 ) { writeByte ( ( byte ) ( 0xC0 | ( code >> 6 ) ) ) ; writeByte ( ( byte ) ( 0x80 | ( code & 0x3F ) ) ) ; count += 2 ; } else { writeByte ( ( byte ) ( 0xE0 | ( code >>> 12 ) ) ) ; writeByte ( ( byte ) ( 0x80 | ( ( code >> 6 ) & 0x3F ) ) ) ; writeByte ( ( byte ) ( 0x80 | ( code & 0x3F ) ) ) ; count += 3 ; } } return count ; }


Input: private char [] chars ; [CODESPLIT] public String readString ( ) throws IOException { int length = readVInt ( ) ; // if (chars == null || length > chars.length) char [ ] chars = new char [ length ] ; readChars ( chars , 0 , length ) ; return new String ( chars , 0 , length ) ; }


Input: Reads UTF - 8 encoded characters into an array . [CODESPLIT] public void readChars ( char [ ] buffer , int start , int length ) throws IOException { final int end = start + length ; for ( int i = start ; i < end ; i ++ ) { byte b = readByte ( ) ; if ( ( b & 0x80 ) == 0 ) buffer [ i ] = ( char ) ( b & 0x7F ) ; else if ( ( b & 0xE0 ) != 0xE0 ) { buffer [ i ] = ( char ) ( ( ( b & 0x1F ) << 6 ) | ( readByte ( ) & 0x3F ) ) ; } else buffer [ i ] = ( char ) ( ( ( b & 0x0F ) << 12 ) | ( ( readByte ( ) & 0x3F ) << 6 ) | ( readByte ( ) & 0x3F ) ) ; } }


Input:
Read data from this record . [CODESPLIT] public void readData ( RandomAccessFile raf , Range gateRange , IndexIterator ii ) throws IOException { final int REC_SIZE = 6144 ; raf . seek ( offset ) ; byte [ ] data = new byte [ bins ] ; float [ ] dd = new float [ bins ] ; byte d ; int nb = 0 ; short a00 ; // raf.readFully(data);
 if ( dataRead > 0 ) { raf . seek ( offset ) ; for ( int i = 0 ; i < dataRead ; i ++ ) { d = raf . readByte ( ) ; dd [ i ] = SigmetIOServiceProvider . calcData ( SigmetIOServiceProvider . recHdr , getDataType ( ) , d ) ; nb ++ ; } } // System.out.println("this is az " + getAz());
 raf . seek ( offset1 ) ; int cur_len = offset1 ; while ( nb < ( int ) bins ) { // --- Check if the code=1 ("1" means an end of a ray)
 a00 = raf . readShort ( ) ; cur_len = cur_len + 2 ; if ( a00 == ( short ) 1 ) { for ( int uk = 0 ; uk < ( int ) bins ; uk ++ ) { dd [ uk ] = - 999.99f ; } break ; } if ( a00 < 0 ) { // -- This is data
 int nwords = a00 & 0x7fff ; int dataRead1 = nwords * 2 ; int pos = 0 ; if ( cur_len % REC_SIZE == 0 ) { pos = 0 ; break ; } raf . seek ( cur_len ) ; for ( int i = 0 ; i < dataRead1 ; i ++ ) { d = raf . readByte ( ) ; dd [ nb ] = SigmetIOServiceProvider . calcData ( SigmetIOServiceProvider . recHdr , getDataType ( ) , d ) ; nb = nb + 1 ; cur_len = cur_len + 1 ; if ( nb % REC_SIZE == 0 ) { pos = i + 1 ; break ; } } if ( pos > 0 ) { break ; } } else if ( a00 > 0 & a00 != 1 ) { int num_zero = a00 * 2 ; int dataRead1 = num_zero ; for ( int k = 0 ; k < dataRead1 ; k ++ ) { dd [ nb + k ] = SigmetIOServiceProvider . calcData ( SigmetIOServiceProvider . recHdr , getDataType ( ) , ( byte ) 0 ) ; } nb = nb + dataRead1 ; if ( cur_len % REC_SIZE == 0 ) { break ; } } } // ------ end of while for num_bins---------------------------------
 for ( int gateIdx : gateRange ) { if ( gateIdx >= bins ) ii . setFloatNext ( Float . NaN ) ; else ii . setFloatNext ( dd [ gateIdx ] ) ; } }


Input: we are running with only ncx index files no data [CODESPLIT] public static void setDebugFlags ( ucar . nc2 . util . DebugFlags debugFlag ) { debugRead = debugFlag . isSet ( "Grib/showRead" ) ; debugIndexOnly = debugFlag . isSet ( "Grib/indexOnly" ) ; debugIndexOnlyShow = debugFlag . isSet ( "Grib/indexOnlyShow" ) ; debugGbxIndexOnly = debugFlag . isSet ( "Grib/debugGbxIndexOnly" ) ; }


Input:
/ * <! -- C : / data / dt2 / station / ndbc . nc -- > <stationFeature > <stationId > : station < / stationId > <stationDesc > : description < / stationDesc > <coordAxis type = lat > lat< / coordAxis > <coordAxis type = lon > lon< / coordAxis > <coordAxis type = height > 0< / coordAxis > <table dim = time > <coordAxis type = time > time< / coordAxis > < / table > < / stationFeature > [CODESPLIT] public TableConfig getConfig ( FeatureType wantFeatureType , NetcdfDataset ds , Formatter errlog ) { Dimension obsDim = ds . getUnlimitedDimension ( ) ; if ( obsDim == null ) { CoordinateAxis axis = CoordSysEvaluator . findCoordByType ( ds , AxisType . Time ) ; if ( ( axis != null ) && axis . isScalar ( ) ) obsDim = axis . getDimension ( 0 ) ; } if ( obsDim == null ) { errlog . format ( "Must have an Observation dimension: unlimited dimension, or from Time Coordinate" ) ; return null ; } boolean hasStruct = Evaluator . hasNetcdf3RecordStructure ( ds ) ; // wants a Point
 if ( ( wantFeatureType == FeatureType . POINT ) ) { TableConfig nt = new TableConfig ( Table . Type . Structure , hasStruct ? "record" : obsDim . getShortName ( ) ) ; nt . structName = "record" ; nt . structureType = hasStruct ? TableConfig . StructureType . Structure : TableConfig . StructureType . PsuedoStructure ; nt . featureType = FeatureType . POINT ; CoordSysEvaluator . findCoords ( nt , ds , null ) ; return nt ; } // otherwise, make it a Station
 TableConfig nt = new TableConfig ( Table . Type . Top , "station" ) ; nt . featureType = FeatureType . STATION ; nt . lat = CoordSysEvaluator . findCoordNameByType ( ds , AxisType . Lat ) ; nt . lon = CoordSysEvaluator . findCoordNameByType ( ds , AxisType . Lon ) ; nt . stnId = ds . findAttValueIgnoreCase ( null , "station" , null ) ; nt . stnDesc = ds . findAttValueIgnoreCase ( null , "description" , null ) ; if ( nt . stnDesc == null ) nt . stnDesc = ds . findAttValueIgnoreCase ( null , "comment" , null ) ; TableConfig obs = new TableConfig ( Table . Type . Structure , hasStruct ? "record" : obsDim . getShortName ( ) ) ; obs . structName = "record" ; obs . structureType = hasStruct ? TableConfig . StructureType . Structure : TableConfig . StructureType . PsuedoStructure ; obs . dimName = obsDim . getShortName ( ) ; obs . time = CoordSysEvaluator . findCoordNameByType ( ds , AxisType . Time ) ; nt . addChild ( obs ) ; return nt ; }


Input: Get the 3D vertical coordinate array for this time step . [CODESPLIT] public ArrayDouble . D3 getCoordinateArray ( int timeIndex ) throws IOException , InvalidRangeException { Array ps = readArray ( psVar , timeIndex ) ; Index psIndex = ps . getIndex ( ) ; int nz = sigma . length ; int [ ] shape2D = ps . getShape ( ) ; int ny = shape2D [ 0 ] ; int nx = shape2D [ 1 ] ; ArrayDouble . D3 result = new ArrayDouble . D3 ( nz , ny , nx ) ; for ( int y = 0 ; y < ny ; y ++ ) { for ( int x = 0 ; x < nx ; x ++ ) { double psVal = ps . getDouble ( psIndex . set ( y , x ) ) ; for ( int z = 0 ; z < nz ; z ++ ) { result . set ( z , y , x , ptop + sigma [ z ] * ( psVal - ptop ) ) ; } } } return result ; }


Input: Get the 1D vertical coordinate array for this time step and point [CODESPLIT] public D1 getCoordinateArray1D ( int timeIndex , int xIndex , int yIndex ) throws IOException , InvalidRangeException { Array ps = readArray ( psVar , timeIndex ) ; Index psIndex = ps . getIndex ( ) ; int nz = sigma . length ; ArrayDouble . D1 result = new ArrayDouble . D1 ( nz ) ; double psVal = ps . getDouble ( psIndex . set ( yIndex , xIndex ) ) ; for ( int z = 0 ; z < nz ; z ++ ) { result . set ( z , ptop + sigma [ z ] * ( psVal - ptop ) ) ; } return result ; }


Input: Add a member . [CODESPLIT] public void addMember ( Member m ) { members . add ( m ) ; if ( memberHash != null ) memberHash . put ( m . getName ( ) , m ) ; }


Input: Remove the given member [CODESPLIT] public int hideMember ( Member m ) { if ( m == null ) return - 1 ; int index = members . indexOf ( m ) ; members . remove ( m ) ; if ( memberHash != null ) memberHash . remove ( m . getName ( ) ) ; return index ; }


Input: Get the names of the members . [CODESPLIT] public java . util . List < String > getMemberNames ( ) { List < String > memberNames = new ArrayList <> ( ) ; for ( Member m : members ) { memberNames . add ( m . getName ( ) ) ; } return memberNames ; }


Input: Find the member by its name . [CODESPLIT] public Member findMember ( String memberName ) { if ( memberName == null ) return null ; if ( memberHash == null ) { // delay making the hash table until needed int initial_capacity = ( int ) ( members . size ( ) / .75 ) + 1 ; memberHash = new HashMap <> ( initial_capacity ) ; for ( Member m : members ) memberHash . put ( m . getName ( ) , m ) ; } return memberHash . get ( memberName ) ; }


Input:
Read the bitmap array when needed return null if none . [CODESPLIT] @ Nullable public byte [ ] getBitmap ( RandomAccessFile raf ) throws IOException { if ( startingPosition <= 0 ) { throw new IllegalStateException ( "Grib1 Bit map has bad starting position" ) ; } raf . seek ( startingPosition ) ; // octet 1-3 (length of section)
 int length = GribNumbers . uint3 ( raf ) ; // octet 4 unused bits
 raf . read ( ) ; // unused
 // octets 5-6
 int bm = raf . readShort ( ) ; if ( bm != 0 ) { logger . warn ( "Grib1 Bit map section pre-defined (provided by center) bitmap number = {}" , bm ) ; return null ; } // not sure if length is set correctly when pre-define bitmap is used, so  wait until that to test
 // seeing a -1, bail out
 if ( length <= 6 || length > 10e6 ) { // look max  ??
 return null ; } // read the bits as integers
 int n = length - 6 ; byte [ ] data = new byte [ n ] ; raf . readFully ( data ) ; return data ; }


Input: Set the state from the last saved in the PreferencesExt . [CODESPLIT] public void restoreState ( PreferencesExt store ) { if ( store == null ) return ; int ncols = table . getColumnCount ( ) ; // stored column order int [ ] modelIndex = ( int [ ] ) store . getBean ( "ColumnOrder" , null ) ; if ( ( modelIndex != null ) && ( modelIndex . length == ncols ) ) { // what about invisible ?? // make invisible any not stored boolean [ ] visible = new boolean [ ncols ] ; for ( int aModelIndex : modelIndex ) if ( aModelIndex < ncols ) visible [ aModelIndex ] = true ; // modify popup menu for ( int i = 0 ; i < ncols ; i ++ ) if ( ! visible [ i ] ) { //System.out.println( colName[i]+" hide "+i); acts [ i ] . hideColumn ( ) ; acts [ i ] . putValue ( BAMutil . STATE , new Boolean ( false ) ) ; } // now set the header order TableColumnModel tcm = table . getColumnModel ( ) ; int n = Math . min ( modelIndex . length , table . getColumnCount ( ) ) ; for ( int i = 0 ; i < n ; i ++ ) { TableColumn tc = tcm . getColumn ( i ) ; tc . setModelIndex ( modelIndex [ i ] ) ; String name = model . getColumnName ( modelIndex [ i ] ) ; tc . setHeaderValue ( name ) ; tc . setIdentifier ( name ) ; if ( useThreads && ( modelIndex [ i ] == threadCol ) ) { threadHeaderRenderer = new ThreadHeaderRenderer ( threadCol ) ; tc . setHeaderRenderer ( threadHeaderRenderer ) ; } else tc . setHeaderRenderer ( new SortedHeaderRenderer ( name , modelIndex [ i ] ) ) ; } } // set the column widths Object colWidths = store . getBean ( "ColumnWidths" , null ) ; if ( colWidths == null ) return ; int [ ] size = ( int [ ] ) colWidths ; setColumnWidths ( size ) ; if ( debug ) { System . out . println ( " read widths = " ) ; for ( int aSize : size ) System . out . print ( " " + aSize ) ; System . out . println ( ) ; } boolean isThreadsOn = store . getBoolean ( "isThreadsOn" , false ) ; if ( useThreads ) { model . setThreadsOn ( isThreadsOn ) ; threadHeaderRenderer . setOn ( isThreadsOn ) ; } int colNo = store . getInt ( "SortOnCol" , 0 ) ; boolean reverse = store . getBoolean ( "SortReverse" , false ) ; model . setSortCol ( colNo ) ; model . setReverse ( reverse ) ; setSortCol ( colNo , reverse ) ; model . sort ( ) ; table . fireDataChanged ( ) ; } private void setColumnWidths  ( int [ ] sizes ) { TableColumnModel tcm = table . getColumnModel ( ) ; for ( int i = 0 ; i < table . getColumnCount ( ) ; i ++ ) { TableColumn tc = tcm . getColumn ( i ) ; int maxw = ( ( sizes == null ) || ( i >= sizes . length ) ) ? 10 : sizes [ i ] ; //     model.getPreferredWidthForColumn(tc) : sizes[i]; tc . setPreferredWidth ( maxw ) ; } //table.sizeColumnsToFit(0);     //  must be called due to a JTable bug } public void setColOn  ( int colno , boolean state , int pos ) { // System.out.println("setColOn "+colno+" "+state+" "+pos); acts [ colno ] . putValue ( BAMutil . STATE , new Boolean ( state ) ) ; if ( state ) acts [ colno ] . addAtPos ( pos ) ; else acts [ colno ] . hideColumn ( ) ; }


Input: Save state to the PreferencesExt . [CODESPLIT] public void saveState ( PreferencesExt store ) { if ( store == null ) return ; int ncols = table . getColumnCount ( ) ; int [ ] size = new int [ ncols ] ; int [ ] modelIndex = new int [ ncols ] ; TableColumnModel tcm = table . getColumnModel ( ) ; for ( int i = 0 ; i < ncols ; i ++ ) { TableColumn tc = tcm . getColumn ( i ) ; size [ i ] = tc . getWidth ( ) ; modelIndex [ i ] = tc . getModelIndex ( ) ; } store . putBeanObject ( "ColumnWidths" , size ) ; store . putBeanObject ( "ColumnOrder" , modelIndex ) ; store . putInt ( "SortOnCol" , model . getSortCol ( ) ) ; store . putBoolean ( "SortReverse" , model . getReverse ( ) ) ; store . putBoolean ( "isThreadsOn" , model . isThreadsOn ( ) ) ; if ( debug ) { System . out . println ( " store widths = " ) ; for ( int aSize : size ) System . out . print ( " " + aSize ) ; System . out . println ( ) ; } }


Input: Get the currently selected rows . [CODESPLIT] public Iterator getSelectedRows ( ) { TreePath [ ] paths = table . getSelectionPaths ( ) ; if ( ( paths == null ) || ( paths . length < 1 ) ) return null ; HashSet set = new HashSet ( 2 * paths . length ) ; for ( TreePath path : paths ) { model . addRowsToSetFromPath ( table . getTree ( ) , path , set ) ; } return set . iterator ( ) ; }


Input: Set the current selection to this row . [CODESPLIT] public void setSelectedRow ( int rowno ) { if ( ( rowno < 0 ) || ( rowno >= model . getRowCount ( ) ) ) return ; if ( debugSetPath ) System . out . println ( "TreeTableSorted setSelected " + rowno ) ; selectedRow = model . getRow ( rowno ) ; TreePath path = model . getPath ( selectedRow ) ; if ( path != null ) table . setSelectionPath ( path ) ; // for mysterious reasons, gotta do it again later invokeSetPath ( ) ; ensureRowIsVisible ( rowno ) ; }


Input: this array translates the column index to the model index [CODESPLIT] public int [ ] getModelIndex ( ) { int [ ] modelIndex = new int [ model . getColumnCount ( ) ] ; try { TableColumnModel tcm = table . getColumnModel ( ) ; for ( int i = 0 ; i < model . getColumnCount ( ) ; i ++ ) { TableColumn tc = tcm . getColumn ( i ) ; modelIndex [ i ] = tc . getModelIndex ( ) ; } } catch ( java . lang . ArrayIndexOutOfBoundsException e ) { //can happen when model size increases } return modelIndex ; }


Input: /////////////////////////////////////////////////////////////////////////////// [CODESPLIT] private void ensureRowIsVisible ( int nRow ) { Rectangle visibleRect = table . getCellRect ( nRow , 0 , true ) ; if ( debugSetPath ) System . out . println ( "----ensureRowIsVisible = " + visibleRect ) ; if ( visibleRect != null ) { visibleRect . x = scrollPane . getViewport ( ) . getViewPosition ( ) . x ; table . scrollRectToVisible ( visibleRect ) ; table . repaint ( ) ; } }


Input: / * Copy constructor . This makes a local copy of all the data in the from StrucureData . @param from copy from here [CODESPLIT] public void setMemberData ( StructureMembers . Member m , Array data ) { if ( data == null ) throw new IllegalArgumentException ( "data cant be null" ) ; memberData . put ( m , data ) ; }


Input: Get member data array of any type as an Array . [CODESPLIT] public Array getArray ( StructureMembers . Member m ) { if ( m == null ) throw new IllegalArgumentException ( "member is null" ) ; return memberData . get ( m ) ; }


Input: Get member data of type double . [CODESPLIT] public double getScalarDouble ( StructureMembers . Member m ) { Array data = getArray ( m ) ; return data . getDouble ( Index . scalarIndexImmutable ) ; }


Input: Get java double array for a member of type double . [CODESPLIT] public double [ ] getJavaArrayDouble ( StructureMembers . Member m ) { Array data = getArray ( m ) ; return ( double [ ] ) data . getStorage ( ) ; }


Input: Get member data of type float . [CODESPLIT] public float getScalarFloat ( StructureMembers . Member m ) { Array data = getArray ( m ) ; return data . getFloat ( Index . scalarIndexImmutable ) ; }


Input: Get java float array for a member of type float . [CODESPLIT] public float [ ] getJavaArrayFloat ( StructureMembers . Member m ) { Array data = getArray ( m ) ; return ( float [ ] ) data . getStorage ( ) ; }


Input: Get member data of type byte . [CODESPLIT] public byte getScalarByte ( StructureMembers . Member m ) { Array data = getArray ( m ) ; return data . getByte ( Index . scalarIndexImmutable ) ; }


Input: Get java byte array for a member of type byte . [CODESPLIT] public byte [ ] getJavaArrayByte ( StructureMembers . Member m ) { Array data = getArray ( m ) ; return ( byte [ ] ) data . getStorage ( ) ; }


Input: Get member data of type int . [CODESPLIT] public int getScalarInt ( StructureMembers . Member m ) { Array data = getArray ( m ) ; return data . getInt ( Index . scalarIndexImmutable ) ; }


Input: Get java int array for a member of type int . [CODESPLIT] public int [ ] getJavaArrayInt ( StructureMembers . Member m ) { Array data = getArray ( m ) ; return ( int [ ] ) data . getStorage ( ) ; }


Input: Get member data of type short . [CODESPLIT] public short getScalarShort ( StructureMembers . Member m ) { Array data = getArray ( m ) ; return data . getShort ( Index . scalarIndexImmutable ) ; }


Input: Get java short array for a member of type short . [CODESPLIT] public short [ ] getJavaArrayShort ( StructureMembers . Member m ) { Array data = getArray ( m ) ; return ( short [ ] ) data . getStorage ( ) ; }


Input: Get member data of type long . [CODESPLIT] public long getScalarLong ( StructureMembers . Member m ) { Array data = getArray ( m ) ; return data . getLong ( Index . scalarIndexImmutable ) ; }


Input: Get java long array for a member of type long . [CODESPLIT] public long [ ] getJavaArrayLong ( StructureMembers . Member m ) { Array data = getArray ( m ) ; return ( long [ ] ) data . getStorage ( ) ; }


Input: Get member data of type char . [CODESPLIT] public char getScalarChar ( StructureMembers . Member m ) { Array data = getArray ( m ) ; return data . getChar ( Index . scalarIndexImmutable ) ; }


Input: Get java char array for a member of type char . [CODESPLIT] public char [ ] getJavaArrayChar ( StructureMembers . Member m ) { Array data = getArray ( m ) ; return ( char [ ] ) data . getStorage ( ) ; }


Input: Get String value from rank 0 String or rank 1 char member array . [CODESPLIT] public String getScalarString ( StructureMembers . Member m ) { if ( m . getDataType ( ) == DataType . STRING ) { Array data = getArray ( m ) ; if ( data == null ) data = getArray ( m ) ; return ( String ) data . getObject ( 0 ) ; } else { char [ ] ba = getJavaArrayChar ( m ) ; int count = 0 ; while ( count < ba . length ) { if ( 0 == ba [ count ] ) break ; count ++ ; } return new String ( ba , 0 , count ) ; } }


Input: Get member data of type Structure . [CODESPLIT] public StructureData getScalarStructure ( StructureMembers . Member m ) { ArrayStructure data = ( ArrayStructure ) getArray ( m ) ; return data . getStructureData ( 0 ) ; }


Input: Write all harvestable datasets to DIF records that have at least the minimum metadata . Call isDatasetUseable () to find out . [CODESPLIT] public void writeDatasetEntries ( InvCatalogImpl cat , String fileDir , StringBuilder mess ) { this . fileDir = fileDir ; this . messBuffer = mess ; File dir = new File ( fileDir ) ; if ( ! dir . exists ( ) ) { boolean ret = dir . mkdirs ( ) ; assert ret ; } CatalogCrawler . Listener listener = new CatalogCrawler . Listener ( ) { public void getDataset ( InvDataset ds , Object context ) { doOneDataset ( ds ) ; } public boolean getCatalogRef ( InvCatalogRef dd , Object context ) { return true ; } } ; ByteArrayOutputStream bis = new ByteArrayOutputStream ( ) ; PrintWriter pw = new PrintWriter ( new OutputStreamWriter ( bis , CDM . utf8Charset ) ) ; CatalogCrawler crawler = new CatalogCrawler ( CatalogCrawler . USE_ALL , true , listener ) ; crawler . crawl ( cat , null , pw , null ) ; mess . append ( "\n*********************\n" ) ; mess . append ( new String ( bis . toByteArray ( ) , CDM . utf8Charset ) ) ; }


Input: Write a DIF record for a specific dataset [CODESPLIT] public void doOneDataset ( InvDataset ds ) { if ( debug ) System . out . println ( "doDataset " + ds . getName ( ) ) ; if ( isDatasetUseable ( ds , messBuffer ) ) { String id = StringUtil2 . replace ( ds . getID ( ) , "/" , "-" ) ; String fileOutName = fileDir + "/" + id + ".dif.xml" ; try { OutputStream out = new BufferedOutputStream ( new FileOutputStream ( fileOutName ) ) ; // writeOneEntry(ds, System.out, mess); writeOneEntry ( ds , out , messBuffer ) ; out . close ( ) ; messBuffer . append ( " OK on Write\n" ) ; } catch ( IOException ioe ) { messBuffer . append ( "DIFWriter failed on write " + ioe . getMessage ( ) + "\n" ) ; log . error ( "DIFWriter failed on write " + ioe . getMessage ( ) , ioe ) ; } } }


Input: See if a dataset is harvestable to a DIF record . [CODESPLIT] public boolean isDatasetUseable ( InvDataset ds , StringBuilder sbuff ) { boolean ok = true ; sbuff . append ( "Dataset " + ds . getName ( ) + " id = " + ds . getID ( ) + ": " ) ; if ( ! ds . isHarvest ( ) ) { ok = false ; sbuff . append ( "Dataset " + ds . getName ( ) + " id = " + ds . getID ( ) + " has harvest = false\n" ) ; } if ( ds . getName ( ) == null ) { ok = false ; sbuff . append ( " missing Name field\n" ) ; } if ( ds . getUniqueID ( ) == null ) { ok = false ; sbuff . append ( " missing ID field\n" ) ; } ThreddsMetadata . Variables vs = ds . getVariables ( "DIF" ) ; if ( ( vs == null ) || ( vs . getVariableList ( ) . size ( ) == 0 ) ) vs = ds . getVariables ( "GRIB-1" ) ; if ( ( vs == null ) || ( vs . getVariableList ( ) . size ( ) == 0 ) ) vs = ds . getVariables ( "GRIB-2" ) ; if ( ( vs == null ) || ( vs . getVariableList ( ) . size ( ) == 0 ) ) { ok = false ; sbuff . append ( " missing Variables with DIF or GRIB compatible vocabulary\n" ) ; } List list = ds . getPublishers ( ) ; if ( ( list == null ) || ( list . size ( ) == 0 ) ) { ok = false ; sbuff . append ( " must have publisher element that defines the data center\n" ) ; } String summary = ds . getDocumentation ( "summary" ) ; if ( summary == null ) { ok = false ; sbuff . append ( " must have documentation element of type summary\n" ) ; } sbuff . append ( " useable= " + ok + "\n" ) ; return ok ; }


Input: Utility routine to keep list of objects small . add fldValue to the fldName list in flds . fldValue may be a list or an object . if no list just keep the object without creating a list ( common case ) . otherwise add it to the existing list . [CODESPLIT] public static void addToList ( Map < String , Object > flds , String fldName , Object fldValue ) { if ( fldValue == null ) return ; Object prevVal = flds . get ( fldName ) ; if ( prevVal == null ) { flds . put ( fldName , fldValue ) ; return ; } List prevList ; if ( prevVal instanceof List ) { prevList = ( List ) prevVal ; } else { prevList = new ArrayList ( 5 ) ; prevList . add ( prevVal ) ; flds . put ( fldName , prevList ) ; } if ( fldValue instanceof List ) { prevList . addAll ( ( List ) fldValue ) ; } else { prevList . add ( fldValue ) ; } }


Input: make an immutable copy without changin DatasetBuilder [CODESPLIT] public Dataset copyDataset ( DatasetNode parent ) { return new Dataset ( parent , name , flds , accessBuilders , datasetBuilders ) ; }


Input: transfer all metadata optionally also inheritable metadata from parents [CODESPLIT] public void transferMetadata ( DatasetNode from , boolean parentsAlso ) { if ( parentsAlso ) { ThreddsMetadata inherit = getInheritableMetadata ( ) ; // make sure exists inheritMetadata ( from , inherit . getFlds ( ) ) ; } // local metadata for ( Map . Entry < String , Object > entry : from . getFldIterator ( ) ) { if ( parentsAlso && entry . getKey ( ) . equals ( Dataset . ThreddsMetadataInheritable ) ) continue ; // already did this if ( Dataset . listFlds . contains ( entry . getKey ( ) ) ) addToNewList ( flds , entry . getKey ( ) , entry . getValue ( ) ) ; else flds . put ( entry . getKey ( ) , entry . getValue ( ) ) ; } // tmi must be mutable, transfer if not ThreddsMetadata tmiOld = ( ThreddsMetadata ) get ( Dataset . ThreddsMetadataInheritable ) ; if ( tmiOld != null && tmiOld . isImmutable ( ) ) { ThreddsMetadata tmiNew = new ThreddsMetadata ( tmiOld ) ; flds . put ( Dataset . ThreddsMetadataInheritable , tmiNew ) ; } }


Input: place directly into flds ( not in this . tmi ) LOOK why not into tmi ?? LOOK put into tmi see what breaks! [CODESPLIT] public void transferInheritedMetadata ( DatasetNode from ) { ThreddsMetadata tmi = getInheritableMetadata ( ) ; inheritMetadata ( from , tmi . getFlds ( ) ) ; }


Input: get the inheritable ThreddsMetadata object . If doesnt exist create new empty one [CODESPLIT] public ThreddsMetadata getInheritableMetadata ( ) { ThreddsMetadata tmi = ( ThreddsMetadata ) get ( Dataset . ThreddsMetadataInheritable ) ; if ( tmi == null ) { tmi = new ThreddsMetadata ( ) ; put ( Dataset . ThreddsMetadataInheritable , tmi ) ; } return tmi ; }


Input: Add in a new product [CODESPLIT] void addProduct ( GridRecord record ) { records . add ( record ) ; if ( firstRecord == null ) { firstRecord = record ; } }


Input: / * is this a time interval variable [CODESPLIT] protected void addExtraAttributes ( GridParameter param , Variable v ) { int icf = hcs . getGds ( ) . getInt ( GridDefRecord . VECTOR_COMPONENT_FLAG ) ; String flag = GridCF . VectorComponentFlag . of ( icf ) ; v . addAttribute ( new Attribute ( GridDefRecord . VECTOR_COMPONENT_FLAG , flag ) ) ; }


Input: Make the netcdf variable . If vname is not already set use useName as name [CODESPLIT] Variable makeVariable ( NetcdfFile ncfile , Group g , String useName , RandomAccessFile raf ) { assert records . size ( ) > 0 : "no records for this variable" ; this . nlevels = getVertNlevels ( ) ; this . ntimes = tcs . getNTimes ( ) ; if ( vname == null ) { useName = StringUtil2 . replace ( useName , ' ' , "_" ) ; this . vname = useName ; } Variable v = new Variable ( ncfile , g , null , vname ) ; v . setDataType ( DataType . FLOAT ) ; Formatter dims = new Formatter ( ) ; if ( hasEnsemble ( ) ) { dims . format ( "ens " ) ; } dims . format ( "%s " , tcs . getName ( ) ) ; if ( getVertIsUsed ( ) ) { dims . format ( "%s " , getVertName ( ) ) ; hasVert = true ; } if ( hcs . isLatLon ( ) ) { dims . format ( "lat lon" ) ; } else { dims . format ( "y x" ) ; } v . setDimensions ( dims . toString ( ) ) ; // add attributes GridParameter param = lookup . getParameter ( firstRecord ) ; if ( param == null ) return null ; String unit = param . getUnit ( ) ; if ( unit == null ) unit = "" ; v . addAttribute ( new Attribute ( "units" , unit ) ) ; v . addAttribute ( new Attribute ( "long_name" , makeLongName ( ) ) ) ; v . addAttribute ( new Attribute ( "missing_value" , lookup . getFirstMissingValue ( ) ) ) ; if ( ! hcs . isLatLon ( ) ) { if ( GridServiceProvider . addLatLon ) v . addAttribute ( new Attribute ( "coordinates" , "lat lon" ) ) ; v . addAttribute ( new Attribute ( "grid_mapping" , hcs . getGridName ( ) ) ) ; } addExtraAttributes ( param , v ) ; v . setSPobject ( this ) ; int nrecs = ntimes * nlevels ; if ( hasEnsemble ( ) ) nrecs *= ecs . getNEnsembles ( ) ; recordTracker = new GridRecord [ nrecs ] ; if ( log . isDebugEnabled ( ) ) log . debug ( "Record Assignment for Variable " + getName ( ) ) ; boolean oneSent = false ; for ( GridRecord p : records ) { int level = getVertIndex ( p ) ; if ( ! getVertIsUsed ( ) && ( level > 0 ) ) { log . warn ( "inconsistent level encoding=" + level ) ; level = 0 ; // inconsistent level encoding ?? } int time = tcs . findIndex ( p ) ; // System.out.println("time="+time+" level="+level); if ( level < 0 ) { log . warn ( "LEVEL NOT FOUND record; level=" + level + " time= " + time + " for " + getName ( ) + " file=" + ncfile . getLocation ( ) + "\n" + "   " + getVertLevelName ( ) + " (type=" + p . getLevelType1 ( ) + "," + p . getLevelType2 ( ) + ")  value=" + p . getLevel1 ( ) + "," + p . getLevel2 ( ) + "\n" ) ; getVertIndex ( p ) ; // allow breakpoint continue ; } if ( time < 0 ) { log . warn ( "TIME NOT FOUND record; level=" + level + " time= " + time + " for " + getName ( ) + " file=" + ncfile . getLocation ( ) + "\n" + " validTime= " + p . getValidTime ( ) + "\n" ) ; tcs . findIndex ( p ) ; // allow breakpoint continue ; } oneSent = trackRecords ( time , level , p , raf , oneSent ) ; } // let all references to Index go, to reduce retained size LOOK records . clear ( ) ; return v ; }


Input: debugging [CODESPLIT] public void showRecord ( int recnum , Formatter f ) { if ( ( recnum < 0 ) || ( recnum > recordTracker . length - 1 ) ) { f . format ( "%d out of range [0,%d]%n" , recnum , recordTracker . length - 1 ) ; return ; } GridRecord gr = recordTracker [ recnum ] ; if ( hasEnsemble ( ) ) { // recnum = ens * (ntimes * nlevels) + (time * nlevels) + level int ens = recnum / ( nlevels * ntimes ) ; int tmp = recnum - ens * ( nlevels * ntimes ) ; int time = tmp / nlevels ; int level = tmp % nlevels ; f . format ( "recnum=%d (record hash=%d) ens=%d time=%s(%d) level=%f(%d)%n" , recnum , gr . hashCode ( ) , ens , tcs . getCoord ( time ) , time , vc . getCoord ( level ) , level ) ; } else { int time = recnum / nlevels ; int level = recnum % nlevels ; f . format ( "recnum=%d (record hash=%d) time=%s(%d) level=%f(%d)%n" , recnum , gr . hashCode ( ) , tcs . getCoord ( time ) , time , vc . getCoord ( level ) , level ) ; } }


Input: Dump out the missing data [CODESPLIT] public void showMissing ( Formatter f ) { //System.out.println("  " +name+" ntimes (across)= "+ ntimes+" nlevs (down)= "+ nlevels+":"); int count = 0 , total = 0 ; f . format ( "  %s%n" , name ) ; for ( int j = 0 ; j < nlevels ; j ++ ) { f . format ( "   " ) ; for ( int i = 0 ; i < ntimes ; i ++ ) { boolean missing = recordTracker [ i * nlevels + j ] == null ; f . format ( "%s" , missing ? "-" : "X" ) ; if ( missing ) count ++ ; total ++ ; } f . format ( "%n" ) ; } f . format ( "  MISSING= %d / %d for %s%n" , count , total , name ) ; }


Input: Dump out the missing data as a summary [CODESPLIT] public int showMissingSummary ( Formatter f ) { int count = 0 ; int total = recordTracker . length ; for ( int i = 0 ; i < total ; i ++ ) { if ( recordTracker [ i ] == null ) count ++ ; } f . format ( "  MISSING= %d / %d for %s%n" , count , total , name ) ; return count ; }


Input: Find the grid record for the time and level indices Canonical ordering is ens time level [CODESPLIT] public GridRecord findRecord ( int ens , int time , int level ) { if ( hasEnsemble ( ) ) { return recordTracker [ ens * ( ntimes * nlevels ) + ( time * nlevels ) + level ] ; } else { return recordTracker [ time * nlevels + level ] ; } }


Input: Dump this variable [CODESPLIT] public String dump ( ) { DateFormatter formatter = new DateFormatter ( ) ; Formatter sbuff = new Formatter ( ) ; sbuff . format ( "%s %d %n" , name , records . size ( ) ) ; for ( GridRecord record : records ) { sbuff . format ( " level = %d %f" , record . getLevelType1 ( ) , record . getLevel1 ( ) ) ; if ( null != record . getValidTime ( ) ) sbuff . format ( " time = %s" , formatter . toDateTimeString ( record . getValidTime ( ) ) ) ; sbuff . format ( "%n" ) ; } return sbuff . toString ( ) ; }


Input: Make a long name for the variable [CODESPLIT] protected String makeLongName ( ) { Formatter f = new Formatter ( ) ; GridParameter param = lookup . getParameter ( firstRecord ) ; if ( param == null ) return null ; f . format ( "%s" , param . getDescription ( ) ) ; String levelName = makeLevelName ( firstRecord , lookup ) ; if ( levelName . length ( ) != 0 ) f . format ( " @ %s" , levelName ) ; return f . toString ( ) ; }


Input: Register a class that implements a TypedDatasetFactoryIF . [CODESPLIT] static public void registerFactory ( FeatureType datatype , String className ) throws ClassNotFoundException { Class c = Class . forName ( className ) ; registerFactory ( datatype , c ) ; }


Input: Register a class that implements a TypedDatasetFactoryIF . [CODESPLIT] static public void registerFactory ( FeatureType datatype , Class c ) { if ( ! ( TypedDatasetFactoryIF . class . isAssignableFrom ( c ) ) ) throw new IllegalArgumentException ( "Class " + c . getName ( ) + " must implement TypedDatasetFactoryIF" ) ; // fail fast - check newInstance works Object instance ; try { instance = c . newInstance ( ) ; } catch ( InstantiationException e ) { throw new IllegalArgumentException ( "CoordTransBuilderIF Class " + c . getName ( ) + " cannot instantiate, probably need default Constructor" ) ; } catch ( IllegalAccessException e ) { throw new IllegalArgumentException ( "CoordTransBuilderIF Class " + c . getName ( ) + " is not accessible" ) ; } // user stuff gets put at top if ( userMode ) transformList . add ( 0 , new Factory ( datatype , c , ( TypedDatasetFactoryIF ) instance ) ) ; else transformList . add ( new Factory ( datatype , c , ( TypedDatasetFactoryIF ) instance ) ) ; }


Input: Open a dataset as a TypedDataset . [CODESPLIT] static public TypedDataset open ( FeatureType datatype , String location , ucar . nc2 . util . CancelTask task , StringBuilder errlog ) throws IOException { DatasetUrl durl = DatasetUrl . findDatasetUrl ( location ) ; NetcdfDataset ncd = NetcdfDataset . acquireDataset ( durl , true , task ) ; return open ( datatype , ncd , task , errlog ) ; }


Input: Open a dataset as a TypedDataset . [CODESPLIT] static public TypedDataset open ( FeatureType datatype , NetcdfDataset ncd , ucar . nc2 . util . CancelTask task , StringBuilder errlog ) throws IOException { // look for a Factory that claims this dataset Class useClass = null ; for ( Factory fac : transformList ) { if ( ( datatype != null ) && ( datatype != fac . datatype ) ) continue ; if ( fac . instance . isMine ( ncd ) ) { useClass = fac . c ; break ; } } // Factory not found if ( null == useClass ) { // POINT is also a STATION if ( datatype == FeatureType . POINT ) { return open ( FeatureType . STATION , ncd , task , errlog ) ; } // if explicitly requested, give em a GridDataset even if no Grids if ( datatype == FeatureType . GRID ) { return null ; // new ucar.nc2.dt.grid.GridDataset( ncd);   LOOK have to copy old  GridDataset to archive } if ( null == datatype ) { // if no datatype was requested, give em a GridDataset only if some Grids are found. ucar . nc2 . dt . grid . GridDataset gds = new ucar . nc2 . dt . grid . GridDataset ( ncd ) ; if ( gds . getGrids ( ) . size ( ) > 0 ) return null ; // gds;    LOOK have to copy old  GridDataset to archive } errlog . append ( "**Failed to find Datatype Factory for= " ) . append ( ncd . getLocation ( ) ) . append ( " datatype= " ) . append ( datatype ) . append ( "\n" ) ; return null ; } // get a new instance of the Factory class, for thread safety TypedDatasetFactoryIF builder = null ; try { builder = ( TypedDatasetFactoryIF ) useClass . newInstance ( ) ; } catch ( InstantiationException e ) { errlog . append ( e . getMessage ( ) ) . append ( "\n" ) ; } catch ( IllegalAccessException e ) { errlog . append ( e . getMessage ( ) ) . append ( "\n" ) ; } if ( null == builder ) { errlog . append ( "**Error on TypedDatasetFactory object from class= " ) . append ( useClass . getName ( ) ) . append ( "\n" ) ; return null ; } return builder . open ( ncd , task , errlog ) ; }


Input: wml2 : defaultPointMetadata [CODESPLIT] public static TVPDefaultMetadataPropertyType initDefaultPointMetadata ( TVPDefaultMetadataPropertyType defaultPointMetadata , VariableSimpleIF dataVar ) { // wml2:DefaultTVPMeasurementMetadata DefaultTVPMeasurementMetadataDocument defaultTVPMeasurementMetadataDoc = DefaultTVPMeasurementMetadataDocument . Factory . newInstance ( ) ; NcTVPMeasurementMetadataType . initDefaultTVPMeasurementMetadata ( defaultTVPMeasurementMetadataDoc . addNewDefaultTVPMeasurementMetadata ( ) , dataVar ) ; defaultPointMetadata . set ( defaultTVPMeasurementMetadataDoc ) ; return defaultPointMetadata ; }


Input:
Reads data from a <code > DataInputStream< / code > . This method is only used on the client side of the OPeNDAP client / server connection . [CODESPLIT] public synchronized void deserialize ( DataInputStream source , ServerVersion sv , StatusUI statusUI ) throws IOException , EOFException { // throw away first three bytes (padding)
 byte unused ; for ( int i = 0 ; i < 3 ; i ++ ) { unused = source . readByte ( ) ; } // read fourth byte
 val = source . readByte ( ) ; if ( statusUI != null ) statusUI . incrementByteCount ( 4 ) ; }


Input:
Writes data to a <code > DataOutputStream< / code > . This method is used primarily by GUI clients which need to download OPeNDAP data manipulate it and then re - save it as a binary file . [CODESPLIT] public void externalize ( DataOutputStream sink ) throws IOException { // print three null bytes (padding)
 for ( int i = 0 ; i < 3 ; i ++ ) { sink . writeByte ( 0 ) ; } sink . writeByte ( val ) ; }


Input: Spacing [CODESPLIT] public boolean isAscending ( ) { loadValuesIfNeeded ( ) ; switch ( spacing ) { case regularInterval : case regularPoint : return getResolution ( ) > 0 ; case irregularPoint : return values [ 0 ] <= values [ ncoords - 1 ] ; case contiguousInterval : return values [ 0 ] <= values [ ncoords ] ; case discontiguousInterval : return values [ 0 ] <= values [ 2 * ncoords - 1 ] ; } throw new IllegalStateException ( "unknown spacing" + spacing ) ; }


Input: CalendarDate double [ 2 ] or Double [CODESPLIT] public Object getCoordObject ( int index ) { if ( axisType == AxisType . RunTime ) return makeDate ( getCoordMidpoint ( index ) ) ; if ( isInterval ( ) ) return new double [ ] { getCoordEdge1 ( index ) , getCoordEdge2 ( index ) } ; return getCoordMidpoint ( index ) ; }


Input: only for longitude only for regular ( do we need a subclass for longitude 1D coords ?? [CODESPLIT] public Optional < CoverageCoordAxis > subsetByIntervals ( List < MAMath . MinMax > lonIntvs , int stride ) { if ( axisType != AxisType . Lon ) return Optional . empty ( "subsetByIntervals only for longitude" ) ; if ( ! isRegular ( ) ) return Optional . empty ( "subsetByIntervals only for regular longitude" ) ; CoordAxisHelper helper = new CoordAxisHelper ( this ) ; double start = Double . NaN ; boolean first = true ; List < RangeIterator > ranges = new ArrayList <> ( ) ; for ( MAMath . MinMax lonIntv : lonIntvs ) { if ( first ) start = lonIntv . min ; first = false ; Optional < RangeIterator > opt = helper . makeRange ( lonIntv . min , lonIntv . max , stride ) ; if ( ! opt . isPresent ( ) ) return Optional . empty ( opt . getErrorMessage ( ) ) ; ranges . add ( opt . get ( ) ) ; } try { RangeComposite compositeRange = new RangeComposite ( AxisType . Lon . toString ( ) , ranges ) ; int npts = compositeRange . length ( ) ; double end = start + npts * resolution ; CoverageCoordAxisBuilder builder = new CoverageCoordAxisBuilder ( this ) ; // copy builder . subset ( npts , start , end , resolution , null ) ; builder . setRange ( null ) ; builder . setCompositeRange ( compositeRange ) ; return Optional . of ( new CoverageCoordAxis1D ( builder ) ) ; } catch ( InvalidRangeException e ) { return Optional . empty ( e . getMessage ( ) ) ; } }


Input:
LOOK incomplete handling of subsetting params [CODESPLIT] protected Optional < CoverageCoordAxisBuilder > subsetBuilder ( SubsetParams params ) { if ( params == null ) return Optional . of ( new CoverageCoordAxisBuilder ( this ) ) ; CoordAxisHelper helper = new CoordAxisHelper ( this ) ; switch ( getAxisType ( ) ) { case GeoZ : case Pressure : case Height : Double dval = params . getVertCoord ( ) ; if ( dval != null ) return Optional . of ( helper . subsetClosest ( dval ) ) ; // use midpoint of interval LOOK may not always be unique double [ ] intv = params . getVertCoordIntv ( ) ; if ( intv != null ) return Optional . of ( helper . subsetClosest ( ( intv [ 0 ] + intv [ 1 ] ) / 2 ) ) ; double [ ] vertRange = params . getVertRange ( ) ; // used by WCS if ( vertRange != null ) return helper . subset ( vertRange [ 0 ] , vertRange [ 1 ] , 1 ) ; // default is all break ; case Ensemble : Double eval = params . getDouble ( SubsetParams . ensCoord ) ; if ( eval != null ) { return Optional . of ( helper . subsetClosest ( eval ) ) ; } // default is all break ; // x,y get seperately subsetted case GeoX : case GeoY : case Lat : case Lon : throw new IllegalArgumentException ( ) ; // return null; // LOOK heres a case where null is "correct" case Time : if ( params . isTrue ( SubsetParams . timePresent ) ) return Optional . of ( helper . subsetLatest ( ) ) ; CalendarDate date = ( CalendarDate ) params . get ( SubsetParams . time ) ; if ( date != null ) return Optional . of ( helper . subsetClosest ( date ) ) ; Integer stride = ( Integer ) params . get ( SubsetParams . timeStride ) ; if ( stride == null || stride < 0 ) stride = 1 ; CalendarDateRange dateRange = ( CalendarDateRange ) params . get ( SubsetParams . timeRange ) ; if ( dateRange != null ) return helper . subset ( dateRange , stride ) ; // If no time range or time point, a timeOffset can be used to specify the time point. /* CalendarDate timeOffsetDate = params.getTimeOffsetDate();
        if (timeOffsetDate != null) {
          return Optional.of(helper.subsetClosest(timeOffsetDate));
        } */ // A time offset or time offset interval starts from the rundate of the offset Double timeOffset = params . getTimeOffset ( ) ; CalendarDate runtime = params . getRunTime ( ) ; if ( timeOffset != null ) { if ( runtime != null ) { date = makeDateInTimeUnits ( runtime , timeOffset ) ; return Optional . of ( helper . subsetClosest ( date ) ) ; } else { return Optional . of ( helper . subsetClosest ( timeOffset ) ) ; } } // If a time interval is sent, search for match. double [ ] timeOffsetIntv = params . getTimeOffsetIntv ( ) ; if ( timeOffsetIntv != null && runtime != null ) { // double midOffset = (timeOffsetIntv[0] + timeOffsetIntv[1]) / 2; CalendarDate [ ] dateIntv = new CalendarDate [ 2 ] ; dateIntv [ 0 ] = makeDateInTimeUnits ( runtime , timeOffsetIntv [ 0 ] ) ; dateIntv [ 1 ] = makeDateInTimeUnits ( runtime , timeOffsetIntv [ 1 ] ) ; return Optional . of ( helper . subsetClosest ( dateIntv ) ) ; } if ( stride != 1 ) try { return Optional . of ( helper . subsetByIndex ( getRange ( ) . setStride ( stride ) ) ) ; } catch ( InvalidRangeException e ) { return Optional . empty ( e . getMessage ( ) ) ; } // default is all break ; case RunTime : CalendarDate rundate = ( CalendarDate ) params . get ( SubsetParams . runtime ) ; if ( rundate != null ) return Optional . of ( helper . subsetClosest ( rundate ) ) ; /*        CalendarDateRange rundateRange = (CalendarDateRange) params.get(SubsetParams.runtimeRange);
        if (rundateRange != null)
          return helper.subset(rundateRange, 1); */ if ( params . isTrue ( SubsetParams . runtimeAll ) ) break ; // default is latest return Optional . of ( helper . subsetLatest ( ) ) ; case TimeOffset : Double oval = params . getDouble ( SubsetParams . timeOffset ) ; if ( oval != null ) { return Optional . of ( helper . subsetClosest ( oval ) ) ; } // If a time interval is sent, search for match. timeOffsetIntv = params . getTimeOffsetIntv ( ) ; if ( timeOffsetIntv != null ) { return Optional . of ( helper . subsetClosest ( ( timeOffsetIntv [ 0 ] + timeOffsetIntv [ 1 ] ) / 2 ) ) ; } if ( params . isTrue ( SubsetParams . timeOffsetFirst ) ) { try { return Optional . of ( helper . subsetByIndex ( new Range ( 1 ) ) ) ; } catch ( InvalidRangeException e ) { return Optional . empty ( e . getMessage ( ) ) ; } } // default is all break ; } // otherwise return copy the original axis return Optional . of ( new CoverageCoordAxisBuilder ( this ) ) ; }


Input: Reads data from a <code > DataInputStream< / code > . This method is only used on the client side of the OPeNDAP client / server connection . [CODESPLIT] public synchronized void deserialize ( DataInputStream source , ServerVersion sv , StatusUI statusUI ) throws IOException , EOFException , DataReadException { for ( int i = 0 ; i < vals . length ; i ++ ) { vals [ i ] = source . readInt ( ) ; if ( statusUI != null ) { statusUI . incrementByteCount ( 4 ) ; if ( statusUI . userCancelled ( ) ) throw new DataReadException ( "User cancelled" ) ; } } }


Input: Writes data to a <code > DataOutputStream< / code > . This method is used primarily by GUI clients which need to download OPeNDAP data manipulate it and then re - save it as a binary file . [CODESPLIT] public void externalize ( DataOutputStream sink ) throws IOException { for ( int i = 0 ; i < vals . length ; i ++ ) { sink . writeInt ( vals [ i ] ) ; } }


Input: Figure out what kind of netcdf - related file we have . Constraint : leave raf read pointer to point just after the magic number . [CODESPLIT] static public int checkFileType ( ucar . unidata . io . RandomAccessFile raf ) throws IOException { int format = 0 ; byte [ ] magic = new byte [ MAGIC_NUMBER_LEN ] ; // If this is not an HDF5 file, then the magic number is at // position 0; If it is an HDF5 file, then we need to search // forward for it. // Look for the relevant leading tag raf . seek ( 0 ) ; if ( raf . readBytes ( magic , 0 , MAGIC_NUMBER_LEN ) < MAGIC_NUMBER_LEN ) return 0 ; // unknown // Some version of CDF int hdrlen = 0 ; hdrlen = CDF1HEAD . length ; // all CDF headers are assumed to be same length format = 0 ; if ( memequal ( CDF1HEAD , magic , CDF1HEAD . length ) ) format = NC_FORMAT_CLASSIC ; else if ( memequal ( CDF2HEAD , magic , CDF2HEAD . length ) ) format = NC_FORMAT_64BIT_OFFSET ; else if ( memequal ( CDF5HEAD , magic , CDF5HEAD . length ) ) format = NC_FORMAT_CDF5 ; else if ( memequal ( H4HEAD , magic , H4HEAD . length ) ) format = NC_FORMAT_HDF4 ; if ( format != 0 ) { raf . seek ( hdrlen ) ; return format ; } // For HDF5, we need to search forward format = 0 ; long filePos = 0 ; long size = raf . length ( ) ; while ( ( filePos < size - 8 ) && ( filePos < MAXHEADERPOS ) ) { boolean match ; raf . seek ( filePos ) ; if ( raf . readBytes ( magic , 0 , MAGIC_NUMBER_LEN ) < MAGIC_NUMBER_LEN ) return 0 ; // unknown // Test for HDF5 if ( memequal ( H5HEAD , magic , H5HEAD . length ) ) { format = NC_FORMAT_HDF5 ; break ; } filePos = ( filePos == 0 ) ? 512 : 2 * filePos ; } if ( format != 0 ) raf . seek ( filePos + H5HEAD . length ) ; return format ; }


Input: Not quite memcmp [CODESPLIT] static boolean memequal ( byte [ ] b1 , byte [ ] b2 , int len ) { if ( b1 == b2 ) return true ; if ( b1 == null || b2 == null ) return false ; if ( b1 . length < len || b2 . length < len ) return false ; for ( int i = 0 ; i < len ; i ++ ) { if ( b1 [ i ] != b2 [ i ] ) return false ; } return true ; }


Input: Returns a string representation of the variables value . This is really foreshadowing functionality for Server types but as it may come in useful for clients it is added here . Simple types ( example : DFloat32 ) will return a single value . DConstuctor and DVector types will be flattened . DStrings and DURL s will have double quotes around them . [CODESPLIT] public void toASCII ( PrintWriter pw , boolean addName , String rootName , boolean newLine ) { if ( _Debug ) { System . out . println ( "asciiArray.toASCII(" + addName + ",'" + rootName + "')  getName(): " + getEncodedName ( ) ) ; System . out . println ( "  PrimitiveVector size = " + getPrimitiveVector ( ) . getLength ( ) ) ; } if ( addName ) pw . print ( "\n" ) ; int dims = numDimensions ( ) ; int shape [ ] = new int [ dims ] ; int i = 0 ; for ( Enumeration e = getDimensions ( ) ; e . hasMoreElements ( ) ; ) { DArrayDimension d = ( DArrayDimension ) e . nextElement ( ) ; shape [ i ++ ] = d . getSize ( ) ; } if ( newLine ) pw . print ( "\n" ) ; }


Input:
Print an array . This is a private member function . [CODESPLIT] private int asciiArray ( PrintWriter os , boolean addName , String label , int index , int dims , int shape [ ] , int offset ) { //os.println("\n\n");
 //os.println("\tdims:   " + dims);
 //os.println("\toffset: " + offset);
 //os.println("\tshape["+offset+"]: " + shape[offset]);
 //os.println("\tindex: " + index);
 //os.println("\n");
 if ( dims == 1 ) { if ( addName ) os . print ( label ) ; for ( int i = 0 ; i < shape [ offset ] ; i ++ ) { PrimitiveVector pv = getPrimitiveVector ( ) ; if ( pv instanceof BaseTypePrimitiveVector ) { BaseType bt = ( ( BaseTypePrimitiveVector ) pv ) . getValue ( index ++ ) ; if ( i > 0 ) { if ( bt instanceof DString ) os . print ( ", " ) ; else os . println ( "" ) ; } ( ( toASCII ) bt ) . toASCII ( os , false , null , false ) ; } else { if ( i > 0 ) os . print ( ", " ) ; pv . printSingleVal ( os , index ++ ) ; } } if ( addName ) os . print ( "\n" ) ; return index ; } else { for ( int i = 0 ; i < shape [ offset ] ; i ++ ) { StringBuilder s = new StringBuilder ( ) ; s . append ( label ) ; s . append ( "[" ) ; s . append ( i ) ; s . append ( "]" ) ; if ( ( dims - 1 ) == 1 ) s . append ( ", " ) ; index = asciiArray ( os , addName , s . toString ( ) , index , dims - 1 , shape , offset + 1 ) ; } return index ; } }


Input: DSP Extensions [CODESPLIT] @ Override public void setContext ( DapContext context ) { this . context = context ; // Extract some things from the context Object o = this . context . get ( Dap4Util . DAP4ENDIANTAG ) ; if ( o != null ) setOrder ( ( ByteOrder ) o ) ; o = this . context . get ( Dap4Util . DAP4CSUMTAG ) ; if ( o != null ) setChecksumMode ( ChecksumMode . modeFor ( o . toString ( ) ) ) ; }


Input: It is common to want to parse a DMR text to a DapDataset so provide this utility . [CODESPLIT] protected DapDataset parseDMR ( String document ) throws DapException { // Parse the dmr Dap4Parser parser ; //if(USEDOM) parser = new DOM4Parser ( null ) ; //else //    parser = new DOM4Parser(new DefaultDMRFactory()); if ( PARSEDEBUG ) parser . setDebugLevel ( 1 ) ; try { if ( ! parser . parse ( document ) ) throw new DapException ( "DMR Parse failed" ) ; } catch ( SAXException se ) { throw new DapException ( se ) ; } if ( parser . getErrorResponse ( ) != null ) throw new DapException ( "Error Response Document not supported" ) ; DapDataset result = parser . getDMR ( ) ; processAttributes ( result ) ; return result ; }


Input: Walk the dataset tree and remove selected attributes such as _Unsigned [CODESPLIT] protected void processAttributes ( DapDataset dataset ) throws DapException { List < DapNode > nodes = dataset . getNodeList ( ) ; for ( DapNode node : nodes ) { switch ( node . getSort ( ) ) { case GROUP : case DATASET : case VARIABLE : Map < String , DapAttribute > attrs = node . getAttributes ( ) ; if ( attrs . size ( ) > 0 ) { List < DapAttribute > suppressed = new ArrayList <> ( ) ; for ( DapAttribute dattr : attrs . values ( ) ) { if ( suppress ( dattr . getShortName ( ) ) ) suppressed . add ( dattr ) ; } for ( DapAttribute dattr : suppressed ) { node . removeAttribute ( dattr ) ; } } break ; default : break ; /*ignore*/ } } // Try to extract the byte order getEndianAttribute ( dataset ) ; }


Input: Some attributes that are added by the NetcdfDataset need to be kept out of the DMR . This function defines that set . [CODESPLIT] protected boolean suppress ( String attrname ) { if ( attrname . startsWith ( "_Coord" ) ) return true ; if ( attrname . equals ( "_Unsigned" ) ) return true ; return false ; }


Input: Parse the given date string ( starting at the first numeric character ) using the given date format string ( as described in java . text . SimpleDateFormat ) and return a Date . [CODESPLIT] public static Date getDateUsingSimpleDateFormat ( String dateString , String dateFormatString ) { // Determine first numeric character in dateString and drop proceeding characters. int smallestIndex = dateString . length ( ) ; if ( smallestIndex == 0 ) return null ; for ( int i = 0 ; i < 10 ; i ++ ) { int curIndex = dateString . indexOf ( String . valueOf ( i ) ) ; if ( curIndex != - 1 && smallestIndex > curIndex ) smallestIndex = curIndex ; } return getDateUsingCompleteDateFormatWithOffset ( dateString , dateFormatString , smallestIndex ) ; }


Input: Parse the given date string starting at a position given by the offset of the demark character in the dateFormatString . The rest of the dateFormatString is the date format string ( as described in java . text . SimpleDateFormat ) . <pre > Example : dateString = wrfout_d01_2006 - 07 - 06_080000 . nc dateFormatString = wrfout_d01_#yyyy - MM - dd_HHmm < / pre > This simply counts over wrfout_d01_ number of chars in dateString then applies the remaining dateFormatString . [CODESPLIT] public static Date getDateUsingDemarkatedCount ( String dateString , String dateFormatString , char demark ) { // the position of the demark char is where to start parsing the dateString int pos1 = dateFormatString . indexOf ( demark ) ; // the rest of the dateFormatString is the SimpleDateFormat dateFormatString = dateFormatString . substring ( pos1 + 1 ) ; return getDateUsingCompleteDateFormatWithOffset ( dateString , dateFormatString , pos1 ) ; }


Input: Parse the given date string ( between the demarcation characters ) using the given date format string ( as described in java . text . SimpleDateFormat ) and return a Date . <pre > Example : dateString = / data / anything / 2006070611 / wrfout_d01_2006 - 07 - 06_080000 . nc dateFormatString = #wrfout_d01_#yyyy - MM - dd_HHmm would extract the date 2006 - 07 - 06T08 : 00 [CODESPLIT] public static Date getDateUsingDemarkatedMatch ( String dateString , String dateFormatString , char demark ) { // extract the match string int pos1 = dateFormatString . indexOf ( demark ) ; int pos2 = dateFormatString . indexOf ( demark , pos1 + 1 ) ; if ( ( pos1 < 0 ) || ( pos2 < 0 ) ) { logger . error ( "Must delineate Date between 2 '#' chars, dateFormatString = '" + dateFormatString + "'" , new Throwable ( ) ) ; return null ; } String match = dateFormatString . substring ( pos1 + 1 , pos2 ) ; int pos3 = dateString . indexOf ( match ) ; if ( pos3 < 0 ) return null ; if ( pos1 > 0 ) { // pos1 > 0, date is before the match: "yyyyMMddHH#/wrfout_d01_#" dateFormatString = dateFormatString . substring ( 0 , pos1 ) ; dateString = dateString . substring ( pos3 - dateFormatString . length ( ) , pos3 ) ; } else { // pos1 == 0, date is after the match: "#wrfout_d01_#yyyy-MM-dd_HHmm" dateFormatString = dateFormatString . substring ( pos2 + 1 ) ; dateString = dateString . substring ( pos3 + match . length ( ) ) ; } // any leading or trailing "." in the dateFormatString means trim int posDot1 = 0 ; while ( dateFormatString . charAt ( posDot1 ) == ' ' ) posDot1 ++ ; int posDot2 = dateFormatString . length ( ) ; while ( dateFormatString . charAt ( posDot2 - 1 ) == ' ' ) posDot2 -- ; if ( posDot1 != 0 || posDot2 != dateFormatString . length ( ) ) { dateFormatString = dateFormatString . substring ( posDot1 , posDot2 ) ; dateString = dateString . substring ( posDot1 , posDot2 ) ; } return getDateUsingCompleteDateFormatWithOffset ( dateString , dateFormatString , 0 ) ; }


Input: Parse the given date string ( starting at the given startIndex ) using the given date format string ( as described in java . text . SimpleDateFormat ) and return a Date . Assumes TimeZone is GMT . [CODESPLIT] public static Date getDateUsingCompleteDateFormatWithOffset ( String dateString , String dateFormatString , int startIndex ) { try { SimpleDateFormat dateFormat = new SimpleDateFormat ( dateFormatString , Locale . US ) ; dateFormat . setTimeZone ( TimeZone . getTimeZone ( "GMT" ) ) ; // We have to cut off the dateString, so that it doesnt grab extra characters. // eg  new SimpleDateFormat("yyyyMMdd_HH").parse("20061129_06") -> 2006-12-24T00:00:00Z (WRONG!) String s ; if ( startIndex + dateFormatString . length ( ) <= dateString . length ( ) ) s = dateString . substring ( startIndex , startIndex + dateFormatString . length ( ) ) ; else s = dateString ; Date result = dateFormat . parse ( s ) ; if ( result == null ) throw new RuntimeException ( "SimpleDateFormat bad =" + dateFormatString + " working on =" + s ) ; return result ; } catch ( ParseException e ) { throw new RuntimeException ( "SimpleDateFormat = " + dateFormatString + " fails on " + dateString + " ParseException:" + e . getMessage ( ) ) ; } catch ( IllegalArgumentException e ) { throw new RuntimeException ( "SimpleDateFormat = " + dateFormatString + " fails on " + dateString + " IllegalArgumentException:" + e . getMessage ( ) ) ; } }


Input: Use regular expression capture group replacement to construct a date string and return the Date that is obtained by parseing the constructed date string using the date format string yyyy - MM - dd T HH : mm . [CODESPLIT] public static Date getDateUsingRegExp ( String dateString , String matchPattern , String substitutionPattern ) { String dateFormatString = "yyyy-MM-dd'T'HH:mm" ; return getDateUsingRegExpAndDateFormat ( dateString , matchPattern , substitutionPattern , dateFormatString ) ; }


Input: The same as getDateUsingRegExp () except the date format string to be used must be specified . [CODESPLIT] public static Date getDateUsingRegExpAndDateFormat ( String dateString , String matchPattern , String substitutionPattern , String dateFormatString ) { // Match the given date string against the regular expression. java . util . regex . Pattern pattern = java . util . regex . Pattern . compile ( matchPattern ) ; java . util . regex . Matcher matcher = pattern . matcher ( dateString ) ; if ( ! matcher . matches ( ) ) { return null ; } // Build date string to use with date format string by // substituting the capture groups into the substitution pattern. StringBuffer dateStringFormatted = new StringBuffer ( ) ; matcher . appendReplacement ( dateStringFormatted , substitutionPattern ) ; if ( dateStringFormatted . length ( ) == 0 ) { return null ; } return getDateUsingCompleteDateFormat ( dateStringFormatted . toString ( ) , dateFormatString ) ; }


Input: Convert a LatLonPoint to projection coordinates [CODESPLIT] @ Override public ProjectionPoint latLonToProj ( LatLonPoint latlon , ProjectionPointImpl result ) { double fromLat = Math . toRadians ( latlon . getLatitude ( ) ) ; double theta = Math . toRadians ( latlon . getLongitude ( ) ) ; if ( projectionLongitude != 0 && ! Double . isNaN ( theta ) ) { theta = MapMath . normalizeLongitude ( theta - projectionLongitude ) ; } ProjectionPointImpl out = new ProjectionPointImpl ( ) ; project ( theta , fromLat , out ) ; result . setLocation ( totalScale * out . getX ( ) + falseEasting , totalScale * out . getY ( ) + falseNorthing ) ; return result ; }


Input:
Convert projection coordinates to a LatLonPoint Note : a new object is not created on each call for the return value . [CODESPLIT] @ Override public LatLonPoint projToLatLon ( ProjectionPoint world , LatLonPointImpl result ) { double fromX = ( world . getX ( ) - falseEasting ) / totalScale ; // assumes cartesian coords in km
 double fromY = ( world . getY ( ) - falseNorthing ) / totalScale ; ProjectionPointImpl pp = new ProjectionPointImpl ( ) ; projectInverse ( fromX , fromY , pp ) ; if ( pp . getX ( ) < - Math . PI ) { pp . setX ( - Math . PI ) ; } else if ( pp . getX ( ) > Math . PI ) { pp . setX ( Math . PI ) ; } if ( projectionLongitude != 0 && ! Double . isNaN ( pp . getX ( ) ) ) { pp . setX ( MapMath . normalizeLongitude ( pp . getX ( ) + projectionLongitude ) ) ; } result . setLatitude ( Math . toDegrees ( pp . getY ( ) ) ) ; result . setLongitude ( Math . toDegrees ( pp . getX ( ) ) ) ; return result ; }