signature:
public class CoordSysBuilder { /** * Assign explicit CoordinateSystem objects to variables .
 * @ param ncDataset why */
protected void assignCoordinateSystemsExplicit ( NetcdfDataset ncDataset ) { } }

implementation:
// look for explicit references to coord sys variables
for ( VarProcess vp : varList ) { if ( vp . coordSys != null && ! vp . isCoordinateTransform ) { StringTokenizer stoker = new StringTokenizer ( vp . coordSys ) ; while ( stoker . hasMoreTokens ( ) ) { String vname = stoker . nextToken ( ) ; VarProcess ap = findVarProcess ( vname , vp ) ; if ( ap == null ) { parseInfo . format ( "***Cant find Coordinate System variable %s referenced from var= %s%n" , vname , vp . v . getFullName ( ) ) ; userAdvice . format ( "***Cant find Coordinate System variable %s referenced from var= %s%n" , vname , vp . v . getFullName ( ) ) ; continue ; } if ( ap . cs == null ) { parseInfo . format ( "***Not a Coordinate System variable %s referenced from var= %s%n" , vname , vp . v . getFullName ( ) ) ; userAdvice . format ( "***Not a Coordinate System variable %s referenced from var= %s%n" , vname , vp . v . getFullName ( ) ) ; continue ; } VariableEnhanced ve = ( VariableEnhanced ) vp . v ; ve . addCoordinateSystem ( ap . cs ) ; } } } // look for explicit references from coord sys variables to data variables
for ( VarProcess csVar : varList ) { if ( ! csVar . isCoordinateSystem || ( csVar . coordSysFor == null ) ) continue ; // get list of dimensions from ' _ CoordinateSystemFor ' attribute
List < Dimension > dimList = new ArrayList < > ( 6 ) ; StringTokenizer stoker = new StringTokenizer ( csVar . coordSysFor ) ; while ( stoker . hasMoreTokens ( ) ) { String dname = stoker . nextToken ( ) ; Dimension dim = ncDataset . getRootGroup ( ) . findDimension ( dname ) ; if ( dim == null ) { parseInfo . format ( "***Cant find Dimension %s referenced from CoordSys var= %s%n" , dname , csVar . v . getFullName ( ) ) ; userAdvice . format ( "***Cant find Dimension %s referenced from CoordSys var= %s%n" , dname , csVar . v . getFullName ( ) ) ; } else dimList . add ( dim ) ; } // look for vars with those dimensions
for ( VarProcess vp : varList ) { if ( ! vp . hasCoordinateSystem ( ) && vp . isData ( ) && ( csVar . cs != null ) ) { VariableEnhanced ve = ( VariableEnhanced ) vp . v ; if ( CoordinateSystem . isSubset ( dimList , vp . v . getDimensionsAll ( ) ) && CoordinateSystem . isSubset ( vp . v . getDimensionsAll ( ) , dimList ) ) ve . addCoordinateSystem ( csVar . cs ) ; } } } // look for explicit listings of coordinate axes
for ( VarProcess vp : varList ) { VariableEnhanced ve = ( VariableEnhanced ) vp . v ; if ( ! vp . hasCoordinateSystem ( ) && ( vp . coordAxes != null ) && vp . isData ( ) ) { List < CoordinateAxis > dataAxesList = getAxes ( vp , vp . coordAxes , vp . v . getFullName ( ) ) ; if ( dataAxesList . size ( ) > 1 ) { String coordSysName = CoordinateSystem . makeName ( dataAxesList ) ; CoordinateSystem cs = ncDataset . findCoordinateSystem ( coordSysName ) ; if ( cs != null ) { ve . addCoordinateSystem ( cs ) ; parseInfo . format ( " assigned explicit CoordSystem '%s' for var= %s%n" , cs . getName ( ) , vp . v . getFullName ( ) ) ; } else { CoordinateSystem csnew = new CoordinateSystem ( ncDataset , dataAxesList , null ) ; ve . addCoordinateSystem ( csnew ) ; ncDataset . addCoordinateSystem ( csnew ) ; parseInfo . format ( " created explicit CoordSystem '%s' for var= %s%n" , csnew . getName ( ) , vp . v . getFullName ( ) ) ; } } } }


signature:
public class CoordSysBuilder { /** * Make implicit CoordinateSystem objects for variables that dont already have one , by using the
 * variables ' list of coordinate axes , and any coordinateVariables for it . Must be at least 2 axes .
 * All of a variable ' s _ Coordinate Variables _ plus any variables listed in a * _ _ CoordinateAxes _ * or * _ coordinates _ * attribute
 * will be made into an * _ implicit _ * Coordinate System .
 * If there are at least two axes , and the coordinate system uses all of the variable ' s dimensions ,
 * it will be asssigned to the data variable . */
protected void makeCoordinateSystemsImplicit ( NetcdfDataset ncDataset ) { } }

implementation:
for ( VarProcess vp : varList ) { if ( ! vp . hasCoordinateSystem ( ) && vp . maybeData ( ) ) { List < CoordinateAxis > dataAxesList = vp . findCoordinateAxes ( true ) ; if ( dataAxesList . size ( ) < 2 ) continue ; VariableEnhanced ve = ( VariableEnhanced ) vp . v ; String csName = CoordinateSystem . makeName ( dataAxesList ) ; CoordinateSystem cs = ncDataset . findCoordinateSystem ( csName ) ; if ( ( cs != null ) && cs . isComplete ( vp . v ) ) { // must be complete
ve . addCoordinateSystem ( cs ) ; parseInfo . format ( " assigned implicit CoordSystem '%s' for var= %s%n" , cs . getName ( ) , vp . v . getFullName ( ) ) ; } else { CoordinateSystem csnew = new CoordinateSystem ( ncDataset , dataAxesList , null ) ; csnew . setImplicit ( true ) ; if ( csnew . isComplete ( vp . v ) ) { ve . addCoordinateSystem ( csnew ) ; ncDataset . addCoordinateSystem ( csnew ) ; parseInfo . format ( " created implicit CoordSystem '%s' for var= %s%n" , csnew . getName ( ) , vp . v . getFullName ( ) ) ; } } } }


signature:
public class CoordSysBuilder { /** * If a variable still doesnt have a coordinate system , use hueristics to try to find one that was probably forgotten .
 * Examine existing CS . create a subset of axes that fits the variable . Choose the one with highest rank .
 * It must have X , Y or lat , lon . If so , add it .
 * @ param ncDataset need this to see if incomplete coordinate systems are allowed */
protected void makeCoordinateSystemsMaximal ( NetcdfDataset ncDataset ) { } }

implementation:
boolean requireCompleteCoordSys = ! ncDataset . getEnhanceMode ( ) . contains ( NetcdfDataset . Enhance . IncompleteCoordSystems ) ; for ( VarProcess vp : varList ) { VariableEnhanced ve = ( VariableEnhanced ) vp . v ; if ( vp . hasCoordinateSystem ( ) || ! vp . isData ( ) ) continue ; // look through all axes that fit
List < CoordinateAxis > axisList = new ArrayList < > ( ) ; List < CoordinateAxis > axes = ncDataset . getCoordinateAxes ( ) ; for ( CoordinateAxis axis : axes ) { if ( isCoordinateAxisForVariable ( axis , ve ) ) axisList . add ( axis ) ; } if ( axisList . size ( ) < 2 ) continue ; String csName = CoordinateSystem . makeName ( axisList ) ; CoordinateSystem cs = ncDataset . findCoordinateSystem ( csName ) ; boolean okToBuild = false ; // do coordinate systems need to be complete ?
// default enhance mode is yes , they must be complete
if ( requireCompleteCoordSys ) { if ( cs != null ) { // only build if coordinate system is complete
okToBuild = cs . isComplete ( ve ) ; } } else { // coordinate system can be incomplete , so we ' re ok to build if we find something
okToBuild = true ; } if ( cs != null && okToBuild ) { ve . addCoordinateSystem ( cs ) ; parseInfo . format ( " assigned maximal CoordSystem '%s' for var= %s%n" , cs . getName ( ) , ve . getFullName ( ) ) ; } else { CoordinateSystem csnew = new CoordinateSystem ( ncDataset , axisList , null ) ; // again , do coordinate systems need to be complete ?
// default enhance mode is yes , they must be complete
if ( requireCompleteCoordSys ) { // only build if new coordinate system is complete
okToBuild = csnew . isComplete ( ve ) ; } if ( okToBuild ) { csnew . setImplicit ( true ) ; ve . addCoordinateSystem ( csnew ) ; ncDataset . addCoordinateSystem ( csnew ) ; parseInfo . format ( " created maximal CoordSystem '%s' for var= %s%n" , csnew . getName ( ) , ve . getFullName ( ) ) ; } } }


signature:
public class CoordSysBuilder { /** * Does this axis " fit " this variable .
 * True if all of the dimensions in the axis also appear in the variable .
 * If char variable , last dimension is left out .
 * @ param axis check if this axis is ok for the given variable
 * @ param v the given variable
 * @ return true if all of the dimensions in the axis also appear in the variable . */
protected boolean isCoordinateAxisForVariable ( Variable axis , VariableEnhanced v ) { } }

implementation:
List < Dimension > varDims = v . getDimensionsAll ( ) ; List < Dimension > axisDims = axis . getDimensionsAll ( ) ; // a CHAR variable must really be a STRING , so leave out the last ( string length ) dimension
int checkDims = axisDims . size ( ) ; if ( axis . getDataType ( ) == DataType . CHAR ) checkDims -- ; for ( int i = 0 ; i < checkDims ; i ++ ) { Dimension axisDim = axisDims . get ( i ) ; if ( ! varDims . contains ( axisDim ) ) { return false ; } } return true ;


signature:
public class CoordSysBuilder { /** * Take all previously identified Coordinate Transforms and create a
 * CoordinateTransform object by calling CoordTransBuilder . makeCoordinateTransform ( ) .
 * @ param ncDataset why */
protected void makeCoordinateTransforms ( NetcdfDataset ncDataset ) { } }

implementation: for ( VarProcess vp : varList ) { if ( vp . isCoordinateTransform && vp . ct == null ) { vp . ct = CoordTransBuilder . makeCoordinateTransform ( vp . ds , vp . v , parseInfo , userAdvice ) ; } }


signature:
public class CoordSysBuilder { /** * Assign CoordinateTransform objects to Coordinate Systems .
 * @ param ncDataset why */
protected void assignCoordinateTransforms ( NetcdfDataset ncDataset ) { } }

implementation:
// look for explicit transform assignments on the coordinate systems
for ( VarProcess vp : varList ) { if ( vp . isCoordinateSystem && vp . coordTransforms != null ) { StringTokenizer stoker = new StringTokenizer ( vp . coordTransforms ) ; while ( stoker . hasMoreTokens ( ) ) { String vname = stoker . nextToken ( ) ; VarProcess ap = findVarProcess ( vname , vp ) ; if ( ap != null ) { if ( ap . ct != null ) { vp . addCoordinateTransform ( ap . ct ) ; parseInfo . format ( " assign explicit coordTransform %s to CoordSys= %s%n" , ap . ct , vp . cs ) ; } else { parseInfo . format ( "***Cant find coordTransform in %s referenced from var= %s%n" , vname , vp . v . getFullName ( ) ) ; userAdvice . format ( "***Cant find coordTransform in %s referenced from var= %s%n" , vname , vp . v . getFullName ( ) ) ; } } else { parseInfo . format ( "***Cant find coordTransform variable= %s referenced from var= %s%n" , vname , vp . v . getFullName ( ) ) ; userAdvice . format ( "***Cant find coordTransform variable= %s referenced from var= %s%n" , vname , vp . v . getFullName ( ) ) ; } } } } // look for explicit coordSys assignments on the coordinate transforms
for ( VarProcess vp : varList ) { if ( vp . isCoordinateTransform && ( vp . ct != null ) && ( vp . coordSys != null ) ) { StringTokenizer stoker = new StringTokenizer ( vp . coordSys ) ; while ( stoker . hasMoreTokens ( ) ) { String vname = stoker . nextToken ( ) ; VarProcess vcs = findVarProcess ( vname , vp ) ; if ( vcs == null ) { parseInfo . format ( "***Cant find coordSystem variable= %s referenced from var= %s%n" , vname , vp . v . getFullName ( ) ) ; userAdvice . format ( "***Cant find coordSystem variable= %s referenced from var= %s%n" , vname , vp . v . getFullName ( ) ) ; } else { vcs . addCoordinateTransform ( vp . ct ) ; parseInfo . format ( "***assign explicit coordTransform %s to CoordSys=  %s%n" , vp . ct , vp . cs ) ; } } } } // look for coordAxes assignments on the coordinate transforms
for ( VarProcess vp : varList ) { if ( vp . isCoordinateTransform && ( vp . ct != null ) && ( vp . coordAxes != null ) ) { List < CoordinateAxis > dataAxesList = vp . findCoordinateAxes ( false ) ; if ( dataAxesList . size ( ) > 0 ) { for ( CoordinateSystem cs : ncDataset . getCoordinateSystems ( ) ) { if ( cs . containsAxes ( dataAxesList ) ) { cs . addCoordinateTransform ( vp . ct ) ; parseInfo . format ( "***assign (implicit coordAxes) coordTransform %s to CoordSys=  %s%n" , vp . ct , cs ) ; } } } } } // look for coordAxisType assignments on the coordinate transforms
for ( VarProcess vp : varList ) { if ( vp . isCoordinateTransform && ( vp . ct != null ) && ( vp . coordAxisTypes != null ) ) { List < AxisType > axisTypesList = new ArrayList < > ( ) ; StringTokenizer stoker = new StringTokenizer ( vp . coordAxisTypes ) ; while ( stoker . hasMoreTokens ( ) ) { String name = stoker . nextToken ( ) ; AxisType atype ; if ( null != ( atype = AxisType . getType ( name ) ) ) axisTypesList . add ( atype ) ; } if ( axisTypesList . size ( ) > 0 ) { for ( CoordinateSystem cs : ncDataset . getCoordinateSystems ( ) ) { if ( cs . containsAxisTypes ( axisTypesList ) ) { cs . addCoordinateTransform ( vp . ct ) ; parseInfo . format ( "***assign (implicit coordAxisType) coordTransform %s to CoordSys=  %s%n" , vp . ct , cs ) ; } } } } }


signature:
public class CoordSysBuilder { /** * track coordinate variables */
protected void addCoordinateVariable ( Dimension dim , VarProcess vp ) { } }

implementation: List < VarProcess > list = coordVarMap . get ( dim ) ; if ( list == null ) { list = new ArrayList < > ( ) ; coordVarMap . put ( dim , list ) ; } if ( ! list . contains ( vp ) ) list . add ( vp ) ;


signature:
public class InvCatalogImpl { /** * Munge this catalog so the given dataset is the top catalog .
 * @ param ds make this top ; must be existing dataset in this catalog .
 * @ deprecated in favor of thredds . catalog . util . DeepCopyUtils . subsetCatalogOnDataset */
public void subset ( InvDataset ds ) { } }

implementation:
InvDatasetImpl dataset = ( InvDatasetImpl ) ds ; // Make all inherited metadata local .
dataset . transferMetadata ( dataset , true ) ; topDataset = dataset ; datasets . clear ( ) ; // throw away the rest
datasets . add ( topDataset ) ; // parent lookups need to be local
// InvService service = dataset . getServiceDefault ( ) ;
// if ( service ! = null ) LOOK
// dataset . serviceName = service . getName ( ) ;
dataset . dataType = dataset . getDataType ( ) ; // all properties need to be local
// LOOK dataset . setPropertiesLocal ( new ArrayList ( dataset . getProperties ( ) ) ) ;
// next part requires this before it
dataset . setCatalog ( this ) ; dataset . parent = null ; // any referenced services need to be local
List < InvService > services = new ArrayList < InvService > ( dataset . getServicesLocal ( ) ) ; findServices ( services , dataset ) ; dataset . setServicesLocal ( services ) ; finish ( ) ;


signature: public class InvCatalogImpl { void findServices ( List < InvService > result , InvDataset ds ) { } }

implementation:
if ( ds instanceof InvCatalogRef ) return ; // look for access elements with unresolved services
for ( InvAccess a : ds . getAccess ( ) ) { InvService s = a . getService ( ) ; InvDataset d = a . getDataset ( ) ; if ( null == d . findService ( s . getName ( ) ) && ! ( result . contains ( s ) ) ) result . add ( s ) ; } // recurse into nested datasets
for ( InvDataset nested : ds . getDatasets ( ) ) { findServices ( result , nested ) ; }


signature:
public class InvCatalogImpl { /** * Munge this catalog to remove any dataset that doesnt pass through the filter .
 * @ param filter remove datasets that dont pass this filter . */
public void filter ( DatasetFilter filter ) { } }

implementation: mark ( filter , topDataset ) ; delete ( topDataset ) ; this . filter = filter ;


signature:
public class InvCatalogImpl { /** * unread CatalogRefs are always kept . */
private boolean mark ( DatasetFilter filter , InvDatasetImpl ds ) { } }

implementation:
if ( ds instanceof InvCatalogRef ) { InvCatalogRef catRef = ( InvCatalogRef ) ds ; if ( ! catRef . isRead ( ) ) return false ; } // recurse into nested datasets first
boolean allMarked = true ; for ( InvDataset nested : ds . getDatasets ( ) ) { allMarked &= mark ( filter , ( InvDatasetImpl ) nested ) ; } if ( ! allMarked ) return false ; if ( filter . accept ( ds ) >= 0 ) return false ; // mark for deletion
ds . setMark ( true ) ; if ( debugFilter ) System . out . println ( " mark " + ds . getName ( ) ) ; return true ;


signature:
public class InvCatalogImpl { /** * remove marked datasets */
private void delete ( InvDatasetImpl ds ) { } }

implementation: if ( ds instanceof InvCatalogRef ) { InvCatalogRef catRef = ( InvCatalogRef ) ds ; if ( ! catRef . isRead ( ) ) return ; } Iterator iter = ds . getDatasets ( ) . iterator ( ) ; while ( iter . hasNext ( ) ) { InvDatasetImpl nested = ( InvDatasetImpl ) iter . next ( ) ; if ( nested . getMark ( ) ) { iter . remove ( ) ; if ( debugFilter ) System . out . println ( " remove " + nested . getName ( ) ) ; } else delete ( nested ) ; }


signature:
public class ErddapCalendar2 { /** * This converts a string " [ units ] since [ isoDate ] "
 * ( e . g . , " minutes since 1985-01-01 " ) into
 * a baseSeconds ( seconds since 1970-01-01 ) and a factor ( " minutes " returns 60 ) .
 * < br > So simplistically , epochSeconds = storedTime * factor + baseSeconds .
 * < br > Or simplistically , storedTime = ( epochSeconds - baseSeconds ) / factor .
 * < p > WARNING : don ' t use the equations above . Use unitsSinceToEpochSeconds or
 * epochSecondsToUnitsSince which correctly handle special cases .
 * @ param tsUnits e . g . , " minutes since 1985-01-01 " .
 * This may include hours , minutes , seconds , decimal , and Z or timezone offset ( default = Zulu ) .
 * @ return double [ ] { baseSeconds , factorToGetSeconds }
 * @ throws Exception if trouble ( tsUnits is null or invalid ) */
public static double [ ] getTimeBaseAndFactor ( String tsUnits ) throws Exception { } }

implementation: String errorInMethod = ErddapString2 . ERROR + " in Calendar2.getTimeBaseAndFactor(" + tsUnits + "):\n" ; if ( tsUnits == null ) { throw new NullPointerException ( errorInMethod + "tsUnits must be non-null." ) ; } int sincePo = tsUnits . toLowerCase ( ) . indexOf ( " since " ) ; if ( sincePo <= 0 ) throw new IllegalArgumentException ( errorInMethod + "units string doesn't contain \" since \"." ) ; double factorToGetSeconds = factorToGetSeconds ( tsUnits . substring ( 0 , sincePo ) ) ; GregorianCalendar baseGC = parseISODateTimeZulu ( tsUnits . substring ( sincePo + 7 ) ) ; double baseSeconds = baseGC . getTimeInMillis ( ) / 1000.0 ; return new double [ ] { baseSeconds , factorToGetSeconds } ;


signature:
public class ErddapCalendar2 { /** * This returns the factor to multiply by ' units ' data to get seconds
 * data ( e . g . , " minutes " returns 60 ) .
 * This is used for part of dealing with udunits - style " minutes since 1970-01-01 " - style
 * strings .
 * @ param units
 * @ return the factor to multiply by ' units ' data to get seconds data .
 * Since there is no exact value for months or years , this returns
 * special values of 30 * SECONDS _ PER _ DAY and 360 * SECONDS _ PER _ DAY , respectively .
 * @ throws Exception if trouble ( e . g . , units is null or not an expected value ) */
public static double factorToGetSeconds ( String units ) throws Exception { } }

implementation: units = units . trim ( ) . toLowerCase ( ) ; if ( units . equals ( "ms" ) || units . equals ( "msec" ) || units . equals ( "msecs" ) || units . equals ( "millis" ) || units . equals ( "millisec" ) || units . equals ( "millisecs" ) || units . equals ( "millisecond" ) || units . equals ( "milliseconds" ) ) return 0.001 ; if ( units . equals ( "s" ) || units . equals ( "sec" ) || units . equals ( "secs" ) || units . equals ( "second" ) || units . equals ( "seconds" ) ) return 1 ; if ( units . equals ( "m" ) || units . equals ( "min" ) || units . equals ( "mins" ) || units . equals ( "minute" ) || units . equals ( "minutes" ) ) return SECONDS_PER_MINUTE ; if ( units . equals ( "h" ) || units . equals ( "hr" ) || units . equals ( "hrs" ) || units . equals ( "hour" ) || units . equals ( "hours" ) ) return SECONDS_PER_HOUR ; if ( units . equals ( "d" ) || units . equals ( "day" ) || units . equals ( "days" ) ) return SECONDS_PER_DAY ; if ( units . equals ( "week" ) || units . equals ( "weeks" ) ) return 7 * SECONDS_PER_DAY ; if ( units . equals ( "mon" ) || units . equals ( "mons" ) || units . equals ( "month" ) || units . equals ( "months" ) ) return 30 * SECONDS_PER_DAY ; if ( units . equals ( "yr" ) || units . equals ( "yrs" ) || units . equals ( "year" ) || units . equals ( "years" ) ) return 360 * SECONDS_PER_DAY ; throw new RuntimeException ( ErddapString2 . ERROR + " in Calendar2.factorToGetSeconds: units=\"" + units + "\" is invalid." ) ;


signature:
public class ErddapCalendar2 { /** * This parses n int values from s and stores results in resultsN ( or leaves
 * items in resultsN untouched if no value available ) .
 * @ param s the date time string
 * @ param separatorN is the separators ( use " \ u0000 " to match any non - digit ) .
 * ( ± matches + or - and that becomes part of the number )
 * ( . matches . or , ( the European decimal point ) )
 * @ param resultsN should initially have the defaults and
 * will receive the results . If trouble , resultsN [ 0 ] will be Integer . MAX _ VALUE ,
 * so caller can throw exception with good error message . */
private static void parseN ( String s , char separatorN [ ] , int resultsN [ ] ) { } }

implementation:
// ensure s starts with a digit
if ( s == null ) s = "" ; s = s . trim ( ) ; int sLength = s . length ( ) ; if ( sLength < 1 || ! ( s . charAt ( 0 ) == '-' || ErddapString2 . isDigit ( s . charAt ( 0 ) ) ) ) { resultsN [ 0 ] = Integer . MAX_VALUE ; return ; } int po1 , po2 = - 1 ; // String2 . log ( " parseN " + s ) ;
// search for digits , non - digit . " 1970-01-01T00:00:00.000-01:00"
boolean mMode = s . charAt ( 0 ) == '-' ; // initial ' - ' is required and included when evaluating number
int nParts = separatorN . length ; for ( int part = 0 ; part < nParts ; part ++ ) { if ( po2 + 1 < sLength ) { // accumulate digits
po1 = po2 + 1 ; po2 = po1 ; if ( mMode ) { if ( po2 < sLength && s . charAt ( po2 ) == '-' ) po2 ++ ; else { resultsN [ 0 ] = Integer . MAX_VALUE ; return ; } } while ( po2 < sLength && ErddapString2 . isDigit ( s . charAt ( po2 ) ) ) po2 ++ ; // digit
// if no number , return ; we ' re done
if ( po2 == po1 ) return ; if ( part > 0 && separatorN [ part - 1 ] == '.' ) { resultsN [ part ] = ErddapMath2 . roundToInt ( 1000 * ErddapString2 . parseDouble ( "0." + s . substring ( po1 , po2 ) ) ) ; // String2 . log ( " millis = " + resultsN [ part ] ) ;
} else { resultsN [ part ] = ErddapString2 . parseInt ( s . substring ( po1 , po2 ) ) ; } // if invalid number , return trouble
if ( resultsN [ part ] == Integer . MAX_VALUE ) { resultsN [ 0 ] = Integer . MAX_VALUE ; return ; } // if no more source characters , we ' re done
if ( po2 >= sLength ) { // String2 . log ( " " + String2 . toCSSVString ( resultsN ) ) ;
return ; } // if invalid separator , stop trying to read more ; return trouble
mMode = false ; char ch = s . charAt ( po2 ) ; if ( ch == ',' ) ch = '.' ; if ( separatorN [ part ] == '\u0000' ) { } else if ( separatorN [ part ] == '±' ) { if ( ch == '+' ) { // do nothing
} else if ( ch == '-' ) { po2 -- ; // number starts with -
mMode = true ; } else { resultsN [ 0 ] = Integer . MAX_VALUE ; return ; } } else if ( ch != separatorN [ part ] ) { // if not exact match . . .
// if current part is ' : ' or ' . ' and not matched , try to skip forward to ' ± '
if ( ( separatorN [ part ] == ':' || separatorN [ part ] == '.' ) && part < nParts - 1 ) { int pmPart = ErddapString2 . indexOf ( separatorN , '±' , part + 1 ) ; if ( pmPart >= 0 ) { // String2 . log ( " jump to + / - " ) ;
part = pmPart ; if ( ch == '+' ) { // do nothing
} else if ( ch == '-' ) { po2 -- ; // number starts with -
mMode = true ; } else { resultsN [ 0 ] = Integer . MAX_VALUE ; return ; } continue ; } // if < 0 , fall through to failure
} resultsN [ 0 ] = Integer . MAX_VALUE ; return ; } } }


signature:
public class ErddapCalendar2 { /** * This converts an ISO date time string ( [ - ] YYYY - MM - DDTHH : MM : SS . SSS ± ZZ : ZZ ) into
 * a GregorianCalendar object .
 * < br > It is lenient ; so Jan 32 is converted to Feb 1;
 * < br > The ' T ' may be any non - digit .
 * < br > The time zone can be omitted .
 * < br > The parts at the end of the time can be omitted .
 * < br > If there is no time , the end parts of the date can be omitted . Year is required .
 * < br > This tries hard to be tolerant of non - valid formats ( e . g . , " 1971-1-2 " , " 1971-01 " )
 * < br > As of 11/9/2006 , NO LONGER TRUE : If year is 0 . . 49 , it is assumed to be 2000 . . 2049.
 * < br > As of 11/9/2006 , NO LONGER TRUE : If year is 50 . . 99 , it is assumed to be 1950 . . 1999.
 * < br > If the string is too short , the end of " 1970-01-01T00:00:00.000Z " will be added ( effectively ) .
 * < br > If the string is too long , the excess will be ignored .
 * < br > If a required separator is incorrect , it is an error .
 * < br > If the date is improperly formatted , it returns null .
 * < br > Timezone " Z " or " " is treated as " - 00:00 " ( UTC / Zulu time )
 * < br > Timezones : e . g . , 2007-01-02T03:04:05-01:00 is same as 2007-01-02T04:04:05
 * @ param gc a GregorianCalendar object . The dateTime will be interpreted
 * as being in gc ' s time zone .
 * Timezone info is relative to the gc ' s time zone .
 * @ param s the dateTimeString in the ISO format ( YYYY - MM - DDTHH : MM : SS . SSS ± ZZ : ZZ
 * or - YYYY - MM - DDTHH : MM : SS . SSS ± ZZ : ZZ for years B . C . )
 * For years B . C . , use calendar2Year = 1 - BCYear .
 * Note that BCYears are 1 . . . , so 1 BC is calendar2Year 0 ( or 0000 ) ,
 * and 2 BC is calendar2Year - 1 ( or - 0001 ) .
 * This supports SS . SSS and SS , SSS ( which ISO 8601 prefers ! ) .
 * @ return the same GregorianCalendar object , but with the date info
 * @ throws RuntimeException if trouble ( e . g . , gc is null or s is null or
 * not at least # ) */
public static GregorianCalendar parseISODateTime ( GregorianCalendar gc , String s ) { } }

implementation:
if ( s == null ) s = "" ; boolean negative = s . startsWith ( "-" ) ; if ( negative ) s = s . substring ( 1 ) ; if ( s . length ( ) < 1 || ! ErddapString2 . isDigit ( s . charAt ( 0 ) ) ) throw new RuntimeException ( ErddapString2 . ERROR + " in parseISODateTime: for first character of dateTime='" + s + "' isn't a digit!" ) ; if ( gc == null ) throw new RuntimeException ( ErddapString2 . ERROR + " in parseISODateTime: gc is null!" ) ; // default ymdhmsmom year is the only required value
int ymdhmsmom [ ] = { Integer . MAX_VALUE , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 } ; // remove trailing Z or " UTC "
s = s . trim ( ) ; if ( Character . toLowerCase ( s . charAt ( s . length ( ) - 1 ) ) == 'z' ) s = s . substring ( 0 , s . length ( ) - 1 ) . trim ( ) ; if ( s . length ( ) >= 3 ) { String last3 = s . substring ( s . length ( ) - 3 ) . toLowerCase ( ) ; if ( last3 . equals ( "utc" ) || last3 . equals ( "gmt" ) ) s = s . substring ( 0 , s . length ( ) - 3 ) . trim ( ) ; } // if e . g . , 1970-01-01 00:00:00 0:00 , change ' ' to ' + ' ( first ' ' - > ' + ' is irrelevant )
s = ErddapString2 . replaceAll ( s , ' ' , '+' ) ; // separators ( \ u0000 = any non - digit )
char separator [ ] = { '-' , '-' , '\u0000' , ':' , ':' , '.' , '±' , ':' , '\u0000' } ; parseN ( s , separator , ymdhmsmom ) ; if ( ymdhmsmom [ 0 ] == Integer . MAX_VALUE ) throw new RuntimeException ( ErddapString2 . ERROR + " in parseISODateTime: dateTime='" + s + "' has an invalid format!" ) ; // do time zone adjustment
// String2 . log ( " # 7 = " + ymdhmsmom [ 7 ] + " # 8 = " + ymdhmsmom [ 8 ] ) ;
if ( ymdhmsmom [ 7 ] != 0 ) ymdhmsmom [ 3 ] -= ymdhmsmom [ 7 ] ; if ( ymdhmsmom [ 8 ] != 0 ) ymdhmsmom [ 4 ] -= ymdhmsmom [ 7 ] < 0 ? - ymdhmsmom [ 8 ] : ymdhmsmom [ 8 ] ; // set gc month - 1 since gc month is 0 . .
gc . set ( ( negative ? - 1 : 1 ) * ymdhmsmom [ 0 ] , ymdhmsmom [ 1 ] - 1 , ymdhmsmom [ 2 ] , ymdhmsmom [ 3 ] , ymdhmsmom [ 4 ] , ymdhmsmom [ 5 ] ) ; gc . set ( MILLISECOND , ymdhmsmom [ 6 ] ) ; gc . get ( YEAR ) ; // force recalculations
return gc ;


signature:
public class WriteT41_ncFlat { /** * main . */
public static void main ( String args [ ] ) throws Exception { } }

implementation:
// String fileIn = " C : / data / dt2 / point / bufr / IUA _ CWAO _ 20060202_12 . bufr " ;
// String fileIn = " C : / data / bufr / edition3 / idd / profiler / PROFILER _ 3 . bufr " ;
// String fileIn = " C : / data / bufr / edition3 / ecmwf / synop . bufr " ;
// String fileIn = " R : / testdata2 / bufr / edition3 / idd / profiler / PROFILER _ 1 . bufr " ;
String fileIn = "D:/mlode/bufr/cat.out" ; NetcdfDataset ncf = NetcdfDataset . openDataset ( fileIn ) ; System . out . println ( ncf . toString ( ) ) ; /* Structure s = ( Structure ) ncf . findVariable ( obsRecord ) ;
 StructureData sdata = s . readStructure ( 2 ) ;
 PrintWriter pw = new PrintWriter ( System . out ) ;
 NCdumpW . printStructureData ( pw , sdata ) ; */
new WriteT41_ncFlat ( ncf , "D:/mlode/bufr/cat2.nc" , true ) ; // Variable v = ncf . findVariable ( " recordIndex " ) ;
// NCdumpW . printArray ( v . read ( ) , " recordIndex " , pw , null ) ;
/* ucar . nc2 . Variable v ;
 v = ncf . findVariable ( " trajectory _ id " ) ;
 if ( v ! = null ) {
 Array data = v . read ( ) ;
 NCdump . printArray ( data , v . getName ( ) , System . out , null ) ;
 v = ncf . findVariable ( " station _ id " ) ;
 if ( v ! = null ) {
 Array data = v . read ( ) ;
 NCdump . printArray ( data , v . getName ( ) , System . out , null ) ;
 v = ncf . findVariable ( " firstChild " ) ;
 if ( v ! = null ) {
 Array data = v . read ( ) ;
 NCdump . printArray ( data , v . getName ( ) , System . out , null ) ;
 v = ncf . findVariable ( " numChildren " ) ;
 if ( v ! = null ) {
 Array data = v . read ( ) ;
 NCdump . printArray ( data , v . getName ( ) , System . out , null ) ;
 System . out . println ( ) ;
 v = ncf . findVariable ( " record " ) ;
 / / ucar . nc2 . Variable v = ncf . findVariable ( " Latitude " ) ;
 / / ucar . nc2 . Variable v = ncf . findVariable ( " time " ) ;
 / / System . out . println ( ) ;
 / / System . out . println ( v . toString ( ) ) ;
 if ( v instanceof Structure ) {
 Structure s = ( Structure ) v ;
 StructureDataIterator iter = s . getStructureIterator ( ) ;
 int count = 0;
 PrintWriter pw = new PrintWriter ( System . out ) ;
 while ( iter . hasNext ( ) ) {
 System . out . println ( " record " + count ) ;
 NCdumpW . printStructureData ( pw , iter . next ( ) ) ;
 count + + ;
 Array data = v . read ( ) ;
 NCdump . printArray ( data , " record " , System . out , null ) ;
 } else {
 Array data = v . read ( ) ;
 int [ ] length = data . getShape ( ) ;
 System . out . println ( ) ;
 System . out . println ( " v2 length = " + length [ 0 ] ) ;
 IndexIterator ii = data . getIndexIterator ( ) ;
 for ( ; ii . hasNext ( ) ; ) {
 System . out . println ( ii . getFloatNext ( ) ) ;
 ncf . close ( ) ; */


signature:
public class LoadCommon { /** * Static Methods */
static File findSystemTempDir ( String [ ] candidates ) { } }

implementation:
for ( String candidate : candidates ) { File f = new File ( candidate ) ; if ( f . exists ( ) && f . canRead ( ) && f . canWrite ( ) ) return f ; if ( f . mkdirs ( ) ) // Try to create the path
return f ; } // As a last resort use the java temp file mechanism
try { File tempfile = File . createTempFile ( "tmp" , "tmp" ) ; File tempdir = tempfile . getParentFile ( ) ; if ( ! tempdir . canWrite ( ) || ! tempdir . canRead ( ) ) return null ; return tempdir ; } catch ( IOException e ) { return null ; }


signature:
public class LoadCommon { /** * Servlet API ( Selected ) */
public void init ( ) throws ServletException { } }

implementation: try { if ( initialized ) return ; initialized = true ; logServerStartup . info ( getClass ( ) . getName ( ) + " initialization" ) ; System . setProperty ( "file.encoding" , "UTF-8" ) ; Field charset = Charset . class . getDeclaredField ( "defaultCharset" ) ; charset . setAccessible ( true ) ; charset . set ( null , null ) ; } catch ( Exception e ) { throw new ServletException ( e ) ; }


signature:
public class LoadCommon { /** * Invoked on first get so that everything is available ,
 * especially Spring stuff . */
public void initOnce ( HttpServletRequest req ) throws SendError { } }

implementation:
if ( once ) return ; once = true ; log . info ( getClass ( ) . getName ( ) + " GET initialization" ) ; if ( this . tdsContext == null ) throw new SendError ( HttpServletResponse . SC_INTERNAL_SERVER_ERROR , "Cannot find TDS Context" ) ; // Get server host + port name
StringBuilder buf = new StringBuilder ( ) ; buf . append ( req . getServerName ( ) ) ; int port = req . getServerPort ( ) ; if ( port > 0 ) { buf . append ( ":" ) ; buf . append ( port ) ; } this . server = buf . toString ( ) ; // Obtain servlet path info
String tmp = HTTPUtil . canonicalpath ( req . getContextPath ( ) ) ; this . threddsname = HTTPUtil . nullify ( HTTPUtil . relpath ( tmp ) ) ; tmp = HTTPUtil . canonicalpath ( req . getServletPath ( ) ) ; this . requestname = HTTPUtil . nullify ( HTTPUtil . relpath ( tmp ) ) ; if ( this . threddsname == null ) this . threddsname = DEFAULTSERVLETNAME ; // Get the upload dir
File updir = tdsContext . getUploadDir ( ) ; if ( updir == null ) { log . warn ( "No tds.upload.dir specified" ) ; this . uploaddir = null ; } else this . uploaddir = HTTPUtil . canonicalpath ( updir . getAbsolutePath ( ) ) ; // Get the download dir
File downdir = tdsContext . getDownloadDir ( ) ; if ( downdir == null ) { log . warn ( "No tds.download.dir specified" ) ; this . downloaddir = null ; } else this . downloaddir = HTTPUtil . canonicalpath ( downdir . getAbsolutePath ( ) ) ;


signature: public class LoadCommon { protected String inquire ( ) { } }

implementation:
Map < String , String > result = new HashMap < > ( ) ; // Return all known server key values
if ( this . downloaddir != null ) result . put ( "downloaddir" , this . downloaddir ) ; if ( this . uploaddir != null ) result . put ( "uploaddir" , this . uploaddir ) ; String sresult = mapToString ( result , true , "download" ) ; return sresult ;


signature:
public class BufrIosp2 { /** * for BufrMessageViewer */
public void open ( RandomAccessFile raf , NetcdfFile ncfile , Message single ) throws IOException { } }

implementation:
this . raf = raf ; protoMessage = single ; protoMessage . getRootDataDescriptor ( ) ; // construct the data descriptors , check for complete tables
if ( ! protoMessage . isTablesComplete ( ) ) throw new IllegalStateException ( "BUFR file has incomplete tables" ) ; BufrConfig config = BufrConfig . openFromMessage ( raf , protoMessage , null ) ; // this fills the netcdf object
Construct2 construct = new Construct2 ( protoMessage , config , ncfile ) ; obsStructure = construct . getObsStructure ( ) ; isSingle = true ; ncfile . finish ( ) ;


signature: public class BufrIosp2 { @ Override public String getDetailInfo ( ) { } }

implementation: Formatter ff = new Formatter ( ) ; ff . format ( "%s" , super . getDetailInfo ( ) ) ; protoMessage . dump ( ff ) ; ff . format ( "%n" ) ; config . show ( ff ) ; return ff . toString ( ) ;


signature:
public class Counters { /** * Add value to the named counter .
 * Add counter if it doesnt already exist .
 * @ return true if its a new value , not seen before . */
public boolean count ( String name , Comparable value ) { } }

implementation: Counter counter = map . get ( name ) ; if ( counter == null ) { counter = add ( name ) ; } return counter . count ( value ) ;


signature:
public class StandardPrefixDB { /** * Gets an instance of this database .
 * @ return An instance of this database .
 * @ throws PrefixDBException The instance couldn ' t be created . */
public static synchronized StandardPrefixDB instance ( ) throws PrefixDBException { } }

implementation: if ( instance == null ) { try { instance = new StandardPrefixDB ( ) ; } catch ( final Exception e ) { throw new PrefixDBException ( "Couldn't create standard prefix-database" , e ) ; } } return instance ;


signature:
public class StandardPrefixDB { /** * Adds a prefix to the database .
 * @ param name The name of the prefix .
 * @ param symbol The symbol for the prefix .
 * @ param definition The numeric value of the prefix .
 * @ throws PrefixExistsException Attempt to redefine an existing prefix . */
private void add ( final String name , final String symbol , final double definition ) throws PrefixExistsException { } }

implementation: addName ( name , definition ) ; addSymbol ( symbol , definition ) ;


signature:
public class StandardPrefixDB { /** * Tests this class . */
public static void main ( final String [ ] args ) throws Exception { } }

implementation: final PrefixDB db = StandardPrefixDB . instance ( ) ; System . out . println ( "db.getPrefixBySymbol(\"cm\") = \"" + db . getPrefixBySymbol ( "cm" ) + '"' ) ; System . out . println ( "db.getPrefixBySymbol(\"dm\") = \"" + db . getPrefixBySymbol ( "dm" ) + '"' ) ;


signature:
public class TableRowAbstract { /** * for other behavior , override this ; use compareXXX routines . */
public int compare ( TableRow other , int col ) { } }

implementation:
String s1 = getValueAt ( col ) . toString ( ) ; String s2 = other . getValueAt ( col ) . toString ( ) ; int ret = s1 . compareToIgnoreCase ( s2 ) ; // break ties
if ( ret == 0 ) return compareTie ( other , col ) ; return ret ;


signature:
public class TableRowAbstract { /** * for use by the subclass */
protected int compareBoolean ( TableRow other , int col , boolean b1 , boolean b2 ) { } }

implementation:
// break ties
if ( b1 == b2 ) return compareTie ( other , col ) ; return b1 ? 1 : - 1 ;


signature:
public class Dap4ParserImpl { /** * Parser specific methods */
DapGroup getGroupScope ( ) throws DapException { } }

implementation: DapGroup gscope = ( DapGroup ) searchScope ( DapSort . GROUP , DapSort . DATASET ) ; if ( gscope == null ) throw new DapException ( "Undefined Group Scope" ) ; return gscope ;


signature:
public class Dap4ParserImpl { /** * Attribute map utilities */
SaxEvent pull ( XMLAttributeMap map , String name ) { } }

implementation: SaxEvent event = map . remove ( name . toLowerCase ( ) ) ; return event ;


signature:
public class Dap4ParserImpl { /** * add any reserved xml attributes to a node unchanged */
void passReserved ( XMLAttributeMap map , DapNode node ) throws ParseException { } }

implementation: try { DapAttribute attr = null ; for ( Map . Entry < String , SaxEvent > entry : map . entrySet ( ) ) { SaxEvent event = entry . getValue ( ) ; String key = entry . getKey ( ) ; String value = event . value ; if ( isReserved ( key ) ) node . addXMLAttribute ( key , value ) ; } } catch ( DapException de ) { throw new ParseException ( de ) ; }


signature:
public class Dap4ParserImpl { /** * Attribute map utilities */
SaxEvent peek ( XMLAttributeMap map , String name ) { } }

implementation: SaxEvent event = map . get ( name . toLowerCase ( ) ) ; return event ;


signature:
public class Dap4ParserImpl { /** * Attribute construction */
DapAttribute makeAttribute ( DapSort sort , String name , DapType basetype , List < String > nslist , DapNode parent ) throws DapException { } }

implementation: DapAttribute attr = new DapAttribute ( name , basetype ) ; if ( sort == DapSort . ATTRIBUTE ) { attr . setBaseType ( basetype ) ; } parent . addAttribute ( attr ) ; attr . setNamespaceList ( nslist ) ; return attr ;


signature:
public class Dap4ParserImpl { /** * Abstract action definitions */
@ Override void enterdataset ( XMLAttributeMap attrs ) throws ParseException { } }

implementation:
this . debug = getDebugLevel ( ) > 0 ; // make sure we have the latest value
if ( debug ) report ( "enterdataset" ) ; SaxEvent name = pull ( attrs , "name" ) ; SaxEvent dapversion = pull ( attrs , "dapversion" ) ; SaxEvent dmrversion = pull ( attrs , "dmrversion" ) ; if ( isempty ( name ) ) throw new ParseException ( "Empty dataset name attribute" ) ; // convert and test version numbers
float ndapversion = DAPVERSION ; if ( dapversion != null ) try { ndapversion = Float . parseFloat ( dapversion . value ) ; } catch ( NumberFormatException nfe ) { ndapversion = DAPVERSION ; } if ( ndapversion != DAPVERSION ) throw new ParseException ( "Dataset dapVersion mismatch: " + dapversion . value ) ; float ndmrversion = DMRVERSION ; if ( dmrversion != null ) try { ndmrversion = Float . parseFloat ( dmrversion . value ) ; } catch ( NumberFormatException nfe ) { ndmrversion = DMRVERSION ; } if ( ndmrversion != DMRVERSION ) throw new ParseException ( "Dataset dmrVersion mismatch: " + dmrversion . value ) ; this . root = new DapDataset ( name . value ) ; this . root . setDapVersion ( Float . toString ( ndapversion ) ) ; this . root . setDMRVersion ( Float . toString ( ndmrversion ) ) ; this . root . setDataset ( this . root ) ; passReserved ( attrs , this . root ) ; scopestack . push ( this . root ) ;


signature:
public class Dap4ParserImpl { /** * This is called for < Value > . . . < / Value >
 * @ param value
 * @ throws ParseException */
@ Override void value ( String value ) throws ParseException { } }

implementation: if ( debug ) report ( "value" ) ; try { DapAttribute parent = ( DapAttribute ) getScope ( DapSort . ATTRIBUTE ) ; createvalue ( value , parent ) ; } catch ( DapException de ) { throw new ParseException ( de ) ; }


signature:
public class PointHorizSubsetTypeValidator { /** * / * ( non - Javadoc )
 * @ see javax . validation . ConstraintValidator # isValid ( java . lang . Object , javax . validation . ConstraintValidatorContext ) */
@ Override public boolean isValid ( NcssPointParamsBean params , ConstraintValidatorContext constraintValidatorContext ) { } }

implementation:
constraintValidatorContext . disableDefaultConstraintViolation ( ) ; boolean isValid = true ; boolean isStnRequest = params . hasLatLonPoint ( ) && params . hasStations ( ) ; boolean isPointRequest = params . hasLatLonPoint ( ) && ! params . hasStations ( ) ; // if no stn param is provided ignore all the others , it must be a point request
// if stn = = all - - > all stations
if ( ! isStnRequest && ! isPointRequest ) { isValid = false ; constraintValidatorContext . buildConstraintViolationWithTemplate ( "{thredds.server.ncSubset.validation.lat_or_lon_missing}" ) . addConstraintViolation ( ) ; } /* if ( params . getSubset ( ) ! = null & & ! params . getSubset ( ) . equals ( " stns " ) & & ! params . getSubset ( ) . equals ( " all " ) & & ! params . getSubset ( ) . equals ( " bb " ) ) {
 isValid = false ;
 constraintValidatorContext
 . buildConstraintViolationWithTemplate ( " { thredds . server . ncSubset . validation . subsettypeerror } " )
 . addConstraintViolation ( ) ;
 if ( params . getSubset ( ) ! = null & & params . getSubset ( ) . equals ( " stns " ) & & params . getStns ( ) = = null ) {
 isValid = false ;
 constraintValidatorContext
 . buildConstraintViolationWithTemplate ( " { thredds . server . ncSubset . validation . subsettypeerror . no _ stns _ param } " )
 . addConstraintViolation ( ) ;
 if ( params . getSubset ( ) ! = null & & params . getSubset ( ) . equals ( " bb " ) & & ( params . getNorth ( ) = = null | | params . getSouth ( ) = = null | | params . getEast ( ) = = null | | params . getWest ( ) = = null ) ) {
 isValid = false ;
 constraintValidatorContext
 . buildConstraintViolationWithTemplate ( " { thredds . server . ncSubset . validation . subsettypeerror . no _ bounding _ box } " )
 . addConstraintViolation ( ) ; */
return isValid ;


signature:
public class TimeParamsValidator { /** * Determine if a valid date range was specified
 * @ return true if there is a valid date range , false if not . */
private boolean hasValidDateRange ( String time_start , String time_end , String time_duration ) { } }

implementation:
// no range
if ( ( null == time_start ) && ( null == time_end ) && ( null == time_duration ) ) return false ; if ( ( null != time_start ) && ( null != time_end ) ) return true ; if ( ( null != time_start ) && ( null != time_duration ) ) return true ; if ( ( null != time_end ) && ( null != time_duration ) ) return true ; // misformed range
// errs . append ( " Must have 2 of 3 parameters : time _ start , time _ end , time _ duration \ n " ) ;
return false ;


signature:
public class SliceIterator { /** * Iterator interface extended */
@ Override public boolean hasNext ( ) { } }

implementation: switch ( state ) { case INITIAL : return ( slice . getFirst ( ) < slice . getStop ( ) ) ; case STARTED : return ( this . index < slice . getLast ( ) ) ; case DONE : } return false ;


signature:
public class AttributeTable { /** * Returns the < code > Attribute < / code > which matches name .
 * @ param clearname the name of the < code > Attribute < / code > to return .
 * @ return the < code > Attribute < / code > with the specified name , or null
 * if there is no matching < code > Attribute < / code > .
 * @ see Attribute */
public final Attribute getAttribute ( String clearname ) { } }

implementation:
// throws NoSuchAttributeException {
Attribute a = ( Attribute ) _attr . get ( clearname ) ; return ( a ) ;


signature:
public class AttributeTable { /** * Returns the < code > Attribute < / code > which matches name .
 * @ param clearname the name of the < code > Attribute < / code > to return .
 * @ return True if an Attribute with named ' name ' exists , False otherwise .
 * @ see Attribute */
public final boolean hasAttribute ( String clearname ) { } }

implementation: Attribute a = ( Attribute ) _attr . get ( clearname ) ; if ( a == null ) { return ( false ) ; } return ( true ) ;


signature:
public class AttributeTable { /** * Adds an attribute to the table . If the given name already
 * refers to an attribute , and the attribute has a vector value ,
 * the given value is appended to the attribute vector . Calling
 * this function repeatedly is the way to create an attribute
 * vector .
 * The function throws an exception if the attribute is a
 * container , or if the type of the input value does not match the
 * existing attribute ' s type and the < code > check < / code > parameter
 * is true . Use the < code > appendContainer < / code > method to add container
 * attributes .
 * @ param clearname The name of the attribute to add or modify .
 * @ param type The type code of the attribute to add or modify .
 * @ param value The value to add to the attribute table .
 * @ param check Check the validity of the attribute ' s value ?
 * @ throws AttributeExistsException thrown if an Attribute with the same
 * name , but a different type was previously defined .
 * @ throws AttributeBadValueException thrown if the value is not a legal
 * member of type
 * @ see AttributeTable # appendContainer ( String ) */
public final void appendAttribute ( String clearname , int type , String value , boolean check ) throws DASException { } }

implementation:
Attribute a = ( Attribute ) _attr . get ( clearname ) ; if ( a != null && ( type != a . getType ( ) ) ) { // type mismatch error
throw new AttributeExistsException ( "The Attribute `" + clearname + "' was previously defined with a different type." ) ; } else if ( a != null ) { a . appendValue ( value , check ) ; } else { a = new Attribute ( type , clearname , value , check ) ; _attr . put ( clearname , a ) ; }


signature:
public class AttributeTable { /** * Adds an attribute to the table . If the given name already
 * refers to an attribute , and the attribute has a vector value ,
 * the given value is appended to the attribute vector . Calling
 * this function repeatedly is the way to create an attribute
 * vector .
 * The function throws an exception if the attribute is a
 * container , or if the type of the input value does not match the
 * existing attribute ' s type . Use the < code > appendContainer < / code >
 * method to add container attributes .
 * @ param clearname The name of the attribute to add or modify .
 * @ param type The type code of the attribute to add or modify .
 * @ param value The value to add to the attribute table .
 * @ throws AttributeExistsException thrown if an Attribute with the same
 * name , but a different type was previously defined .
 * @ throws AttributeBadValueException thrown if the value is not a legal
 * member of type
 * @ see AttributeTable # appendContainer ( String ) */
public final void appendAttribute ( String clearname , int type , String value ) throws DASException { } }

implementation: appendAttribute ( clearname , type , value , true ) ;


signature:
public class AttributeTable { /** * Create and append an attribute container to the table .
 * A container is another < code > AttributeTable < / code > object .
 * @ param clearname the name of the container to add .
 * @ return A pointer to the new < code > AttributeTable < / code > object , or null
 * if a container by that name already exists . */
public final AttributeTable appendContainer ( String clearname ) { } }

implementation:
// return null if clearname already exists
// FIXME ! THIS SHOULD RETURN AN EXCEPTION !
if ( _attr . get ( clearname ) != null ) return null ; AttributeTable at = new AttributeTable ( clearname ) ; Attribute a = new Attribute ( clearname , at ) ; _attr . put ( clearname , a ) ; return at ;


signature:
public class AttributeTable { /** * Create and append an attribute container to the table .
 * A container is another < code > AttributeTable < / code > object .
 * @ param clearname the name of the container to add .
 * if a container by that name already exists . */
public final void addContainer ( String clearname , AttributeTable at ) throws AttributeExistsException { } }

implementation:
// return null if name already exists
if ( _attr . get ( clearname ) != null ) { throw new AttributeExistsException ( "The Attribute '" + clearname + "' already exists in the container '" + getEncodedName ( ) + "'" ) ; } Attribute a = new Attribute ( clearname , at ) ; _attr . put ( clearname , a ) ;


signature:
public class AttributeTable { /** * Add an alias to the current table .
 * This method is used by the DAS parser to build Aliases
 * for the DAS . And the DDSXMLParser to add them to the DDX
 * The new ( 9/26/02 ) DDS requires the use of < code >
 * addAlias ( String , String , String ) < / code > and is the preffered
 * way of representing the DAS information .
 * @ param alias The alias to insert into the attribute table .
 * @ param attributeName The normalized name of the attribute to which
 * the alias will refer .
 * @ throws NoSuchAttributeException thrown if the existing attribute
 * could not be found .
 * @ throws AttributeExistsException thrown if the new alias has the same
 * name as an existing attribute . */
public final void addAlias ( String alias , String attributeName ) throws NoSuchAttributeException , AttributeExistsException { } }

implementation:
// complain if alias name already exists in this AttributeTable .
if ( _attr . get ( alias ) != null ) { throw new AttributeExistsException ( "Could not alias `" + alias + "' to `" + attributeName + "'. " + "It is a duplicat name in this AttributeTable" ) ; } if ( Debug . isSet ( "AttributTable" ) ) { log . debug ( "Adding alias '" + alias + "' to AttributeTable '" + getClearName ( ) + "'" ) ; } Alias newAlias = new Alias ( alias , attributeName ) ; _attr . put ( alias , newAlias ) ;


signature:
public class AttributeTable { /** * Delete the attribute named < code > name < / code > . If the attribute has a
 * vector value , delete the < code > i < / code > ' th element of the vector .
 * @ param clearname The name of the attribute to delete . This can be an
 * attribute of any type , including containers .
 * @ param i If the named attribute is a vector , and < code > i < / code > is
 * non - negative , the < code > i < / code > ' th entry in the vector is deleted .
 * If < code > i < / code > equals - 1 , the entire attribute is deleted .
 * @ see AttributeTable # delAttribute ( String ) */
public final void delAttribute ( String clearname , int i ) throws DASException { } }

implementation:
if ( i == - 1 ) { // delete the whole attribute
_attr . remove ( clearname ) ; } else { Attribute a = ( Attribute ) _attr . get ( clearname ) ; if ( a != null ) { if ( a . isContainer ( ) ) { _attr . remove ( clearname ) ; // delete the entire container
} else { a . deleteValueAt ( i ) ; } } }


signature:
public class AttributeTable { /** * Print the attribute table on the given < code > PrintWriter < / code > .
 * @ param os the < code > PrintWriter < / code > to use for output .
 * @ param pad the number of spaces to indent each line . */
public void print ( PrintWriter os , String pad ) { } }

implementation: if ( Debug . isSet ( "AttributTable" ) ) os . println ( "Entered AttributeTable.print()" ) ; os . println ( pad + getEncodedName ( ) + " {" ) ; for ( Enumeration e = getNames ( ) ; e . hasMoreElements ( ) ; ) { String name = ( String ) e . nextElement ( ) ; Attribute a = getAttribute ( name ) ; if ( a != null ) a . print ( os , pad + "    " ) ; } os . println ( pad + "}" ) ; if ( Debug . isSet ( "AttributTable" ) ) os . println ( "Leaving AttributeTable.print()" ) ; os . flush ( ) ;


signature:
public class AttributeTable { /** * Print the attribute table on the given < code > OutputStream < / code > .
 * @ param os the < code > OutputStream < / code > to use for output .
 * @ param pad the number of spaces to indent each line . */
public final void print ( OutputStream os , String pad ) { } }

implementation: print ( new PrintWriter ( new BufferedWriter ( new OutputStreamWriter ( os , Util . UTF8 ) ) ) , pad ) ;


signature:
public class AttributeTable { /** * Returns a clone of this < code > AttributeTable < / code > .
 * See DAPNode . cloneDag ( )
 * @ param map track previously cloned nodes
 * @ return a clone of this < code > Attribute < / code > . */
public DAPNode cloneDAG ( CloneMap map ) throws CloneNotSupportedException { } }

implementation:
AttributeTable at = ( AttributeTable ) super . cloneDAG ( map ) ; at . _attr = new SortedTable ( ) ; for ( int i = 0 ; i < _attr . size ( ) ; i ++ ) { String key = ( String ) _attr . getKey ( i ) ; Attribute element = ( Attribute ) _attr . elementAt ( i ) ; // clone element ( don ' t clone key because it ' s a read - only String )
at . _attr . put ( key , ( Attribute ) cloneDAG ( map , element ) ) ; } return at ;


signature:
public class AfwaTables { /** * subcenters */
@ Override public String getSubCenterName ( int subcenter ) { } }

implementation: if ( subcenterMap == null ) subcenterMap = makeSubcenterMap ( ) ; return subcenterMap . get ( subcenter ) ;


signature:
public class AfwaTables { /** * gen process */
@ Override @ Nullable public String getGeneratingProcessName ( int genProcess ) { } }

implementation: if ( genProcessMap == null ) makeGenProcessMap ( ) ; return genProcessMap . get ( genProcess ) ;


signature:
public class AfwaTables { /** * / levels */
@ Override public Grib1ParamLevel getParamLevel ( Grib1SectionProductDefinition pds ) { } }

implementation: int levelType = pds . getLevelType ( ) ; int pds11 = pds . getLevelValue1 ( ) ; int pds12 = pds . getLevelValue2 ( ) ; int pds1112 = pds11 << 8 | pds12 ; switch ( levelType ) { case 210 : return new Grib1ParamLevel ( this , levelType , ( float ) pds1112 , GribNumbers . MISSING ) ; case 218 : return new Grib1ParamLevel ( this , levelType , ( float ) pds11 + 200 , ( float ) pds12 + 200 ) ; case 246 : return new Grib1ParamLevel ( this , levelType , ( float ) pds1112 , GribNumbers . MISSING ) ; default : return new Grib1ParamLevel ( this , pds ) ; }


signature:
public class LatLonPointNoNormalize { /** * Returns { @ code true } if this point is nearly equal to { @ code that } . The " near equality " of points is determined
 * using { @ link Misc # nearlyEquals ( double , double , double ) } , with the specified maxRelDiff .
 * @ param that the other point to check .
 * @ param maxRelDiff the maximum { @ link Misc # relativeDifference relative difference } the two points may have .
 * @ return { @ code true } if this point is nearly equal to { @ code that } . */
public boolean nearlyEquals ( LatLonPointNoNormalize that , double maxRelDiff ) { } }

implementation: return Misc . nearlyEquals ( this . getLatitude ( ) , that . getLatitude ( ) , maxRelDiff ) && Misc . nearlyEquals ( this . getLongitude ( ) , that . getLongitude ( ) , maxRelDiff ) ;


signature:
public class CrawlableDatasetUtils { /** * Given a relative path as an array of path segments ( see { @ link # getPathSegments ( String ) } ,
 * return the path relative to the first path segment .
 * I . e . , drop the first segmentRejoin the given path segments after dropping the first path segment .
 * @ param pathSegments a string array of a relative path as returned by getPathSegments ( )
 * @ return the path relative to the first path segment . */
public static String stepDownRelativePath ( String [ ] pathSegments ) { } }

implementation: if ( ! CrawlableDatasetUtils . isValidRelativePath ( pathSegments ) ) throw new IllegalArgumentException ( "Path segments not a valid relative path." ) ; if ( pathSegments . length < 2 ) throw new IllegalArgumentException ( "Number of path segments must be > 1." ) ; StringBuilder sb = new StringBuilder ( ) ; for ( int i = 1 ; i < pathSegments . length - 1 ; i ++ ) { sb . append ( pathSegments [ i ] ) . append ( "/" ) ; } sb . append ( pathSegments [ pathSegments . length - 1 ] ) ; return sb . toString ( ) ;


signature:
public class DSPRegistry { /** * Register a DSP , using its class string name .
 * @ param className Name of class that implements DSP .
 * @ throws IllegalAccessException if class is not accessible .
 * @ throws InstantiationException if class doesnt have a no - arg constructor .
 * @ throws ClassNotFoundException if class not found . */
synchronized public void register ( String className , boolean last ) throws DapException { } }

implementation: try { Class < ? extends DSP > klass = ( Class < ? extends DSP > ) loader . loadClass ( className ) ; register ( klass , last ) ; } catch ( ClassNotFoundException e ) { throw new DapException ( e ) ; }


signature:
public class DSPRegistry { /** * Register a DSP class .
 * @ param klass Class that implements DSP .
 * @ param last true = > insert at the end of the list ; otherwise front
 * @ throws IllegalAccessException if class is not accessible .
 * @ throws InstantiationException if class doesnt have a no - arg constructor .
 * @ throws ClassCastException if class doesnt implement DSP interface . */
synchronized public void register ( Class < ? extends DSP > klass , boolean last ) { } }

implementation:
// is this already defined ?
if ( registered ( klass ) ) return ; if ( last ) registry . add ( new Registration ( klass ) ) ; else registry . add ( 0 , new Registration ( klass ) ) ;


signature:
public class DSPRegistry { /** * See if a specific DSP is registered
 * @ param klass Class for which to search */
synchronized public boolean registered ( Class < ? extends DSP > klass ) { } }

implementation: for ( Registration r : registry ) { if ( r . dspclass == klass ) return true ; } return false ;


signature:
public class DSPRegistry { /** * Unregister dsp .
 * @ param klass Class for which to search */
synchronized public void unregister ( Class < ? extends DSP > klass ) { } }

implementation: for ( int i = 0 ; i < registry . size ( ) ; i ++ ) { if ( registry . get ( i ) . dspclass == klass ) { registry . remove ( i ) ; break ; } }


signature:
public class Grib2Tables { /** * Lazy instantiation . */
public static Grib2Tables factory ( int center , int subCenter , int masterVersion , int localVersion , int genProcessId ) { } }

implementation:
Grib2TablesId id = new Grib2TablesId ( center , subCenter , masterVersion , localVersion , genProcessId ) ; Grib2Tables cust = tables . get ( id ) ; if ( cust != null ) return cust ; // note that we match on id , so same Grib2Customizer may be mapped to multiple id ' s ( eg match on - 1)
Grib2TableConfig config = Grib2TableConfig . matchTable ( id ) ; cust = build ( config ) ; tables . put ( id , cust ) ; return cust ;


signature:
public class Grib2Tables { /** * Get the time interval in units of gr . getPDS ( ) . getTimeUnit ( )
 * @ param gr Grib record , must have pds that is a time interval .
 * @ return time interval in units of gr . getPDS ( ) . getTimeUnit ( ) */
@ Nullable public TimeCoordIntvDateValue getForecastTimeInterval ( Grib2Record gr ) { } }

implementation:
// note from Arthur Taylor ( degrib ) :
/* If there was a range I used :
 End of interval ( EI ) = ( bytes 36-42 show an " end of overall time interval " )
 C1 ) End of Interval = EI ;
 Begin of Interval = EI - range
 and if there was no interval then I used :
 C2 ) End of Interval = Begin of Interval = Ref + ForeT . */
if ( ! gr . getPDS ( ) . isTimeInterval ( ) ) return null ; Grib2Pds . PdsInterval pdsIntv = ( Grib2Pds . PdsInterval ) gr . getPDS ( ) ; int timeUnitOrg = gr . getPDS ( ) . getTimeUnit ( ) ; // calculate total " range "
int range = 0 ; for ( Grib2Pds . TimeInterval ti : pdsIntv . getTimeIntervals ( ) ) { if ( ti . timeRangeUnit == 255 ) continue ; if ( ( ti . timeRangeUnit != timeUnitOrg ) || ( ti . timeIncrementUnit != timeUnitOrg && ti . timeIncrementUnit != 255 && ti . timeIncrement != 0 ) ) { if ( ! timeUnitWarnWasSent ) { logger . warn ( "TimeInterval has different units timeUnit org=" + timeUnitOrg + " TimeInterval=" + ti . timeIncrementUnit ) ; timeUnitWarnWasSent = true ; // throw new RuntimeException ( " TimeInterval ( 2 ) has different units " ) ;
} } range += ti . timeRangeLength ; if ( ti . timeIncrementUnit != 255 ) range += ti . timeIncrement ; } CalendarPeriod unitPeriod = Grib2Utils . getCalendarPeriod ( convertTimeUnit ( timeUnitOrg ) ) ; if ( unitPeriod == null ) return null ; CalendarPeriod period = unitPeriod . multiply ( range ) ; // End of Interval as date
CalendarDate EI = pdsIntv . getIntervalTimeEnd ( ) ; if ( EI == CalendarDate . UNKNOWN ) { // all values were set to zero LOOK guessing !
return new TimeCoordIntvDateValue ( gr . getReferenceDate ( ) , period ) ; } else { return new TimeCoordIntvDateValue ( period , EI ) ; }


signature:
public class Grib2Tables { /** * Get interval size in units of hours .
 * Only use in GribVariable to decide on variable identity when intvMerge = false .
 * @ param pds must be a Grib2Pds . PdsInterval
 * @ return interval size in units of hours */
public double getForecastTimeIntervalSizeInHours ( Grib2Pds pds ) { } }

implementation:
Grib2Pds . PdsInterval pdsIntv = ( Grib2Pds . PdsInterval ) pds ; int timeUnitOrg = pds . getTimeUnit ( ) ; // calculate total " range " in units of timeUnit
int range = 0 ; for ( Grib2Pds . TimeInterval ti : pdsIntv . getTimeIntervals ( ) ) { if ( ti . timeRangeUnit == 255 ) continue ; if ( ( ti . timeRangeUnit != timeUnitOrg ) || ( ti . timeIncrementUnit != timeUnitOrg && ti . timeIncrementUnit != 255 && ti . timeIncrement != 0 ) ) { logger . warn ( "TimeInterval(2) has different units timeUnit org=" + timeUnitOrg + " TimeInterval=" + ti . timeIncrementUnit ) ; throw new RuntimeException ( "TimeInterval(2) has different units" ) ; } range += ti . timeRangeLength ; if ( ti . timeIncrementUnit != 255 ) range += ti . timeIncrement ; } // now convert that range to units of the requested period .
CalendarPeriod timeUnitPeriod = Grib2Utils . getCalendarPeriod ( convertTimeUnit ( timeUnitOrg ) ) ; if ( timeUnitPeriod == null ) return GribNumbers . UNDEFINEDD ; if ( timeUnitPeriod . equals ( CalendarPeriod . Hour ) ) return range ; double fac ; if ( timeUnitPeriod . getField ( ) == CalendarPeriod . Field . Month ) { fac = 30.0 * 24.0 ; // nominal hours in a month
} else if ( timeUnitPeriod . getField ( ) == CalendarPeriod . Field . Year ) { fac = 365.0 * 24.0 ; // nominal hours in a year
} else { fac = CalendarPeriod . Hour . getConvertFactor ( timeUnitPeriod ) ; } return fac * range ;


signature:
public class Grib2Tables { /** * If this has a time interval coordinate , get time interval
 * @ param gr from this record
 * @ return time interval in units of pds . getTimeUnit ( ) , or null if not a time interval */
@ Nullable public int [ ] getForecastTimeIntervalOffset ( Grib2Record gr ) { } }

implementation: TimeCoordIntvDateValue tinvd = getForecastTimeInterval ( gr ) ; if ( tinvd == null ) return null ; Grib2Pds pds = gr . getPDS ( ) ; int unit = convertTimeUnit ( pds . getTimeUnit ( ) ) ; TimeCoordIntvValue tinv = tinvd . convertReferenceDate ( gr . getReferenceDate ( ) , Grib2Utils . getCalendarPeriod ( unit ) ) ; if ( tinv == null ) return null ; int [ ] result = new int [ 2 ] ; result [ 0 ] = tinv . getBounds1 ( ) ; result [ 1 ] = tinv . getBounds2 ( ) ; return result ;


signature:
public class Grib2Tables { /** * Unit of vertical coordinate .
 * from Grib2 code table 4.5.
 * Only levels with units get a dimension added
 * @ param code code from table 4.5
 * @ return level unit , default is empty unit string */
@ Override public VertCoordType getVertUnit ( int code ) { } }

implementation:
// VertCoordType ( int code , String desc , String abbrev , String units , String datum , boolean isPositiveUp , boolean isLayer )
switch ( code ) { case 11 : case 12 : return new VertCoordType ( code , "m" , null , true ) ; case 20 : return new VertCoordType ( code , "K" , null , false ) ; case 100 : return new VertCoordType ( code , "Pa" , null , false ) ; case 102 : return new VertCoordType ( code , "m" , "mean sea level" , true ) ; case 103 : return new VertCoordType ( code , "m" , "ground" , true ) ; case 104 : case 105 : return new VertCoordType ( code , "sigma" , null , false ) ; // positive ?
case 106 : return new VertCoordType ( code , "m" , "land surface" , false ) ; case 107 : return new VertCoordType ( code , "K" , null , true ) ; // positive ?
case 108 : return new VertCoordType ( code , "Pa" , "ground" , true ) ; case 109 : return new VertCoordType ( code , "K m2 kg-1 s-1" , null , true ) ; // positive ?
case 114 : return new VertCoordType ( code , "numeric" , null , false ) ; case 117 : return new VertCoordType ( code , "m" , null , true ) ; case 119 : return new VertCoordType ( code , "Pa" , null , false ) ; case 160 : return new VertCoordType ( code , "m" , "sea level" , false ) ; case 161 : return new VertCoordType ( code , "m" , "water surface" , false ) ; // LOOK NCEP specific
case 235 : return new VertCoordType ( code , "0.1 C" , null , true ) ; case 237 : return new VertCoordType ( code , "m" , null , true ) ; case 238 : return new VertCoordType ( code , "m" , null , true ) ; default : return new VertCoordType ( code , null , null , true ) ; }


signature:
public class DapDataset { /** * Compute inferred information */
public void finish ( ) { } }

implementation: if ( this . finished ) return ; if ( this . ce == null ) this . visiblenodes = nodelist ; else { this . visiblenodes = new ArrayList < DapNode > ( nodelist . size ( ) ) ; for ( int i = 0 ; i < nodelist . size ( ) ; i ++ ) { DapNode node = nodelist . get ( i ) ; if ( ce . references ( node ) ) visiblenodes . add ( node ) ; } } this . topvariables = new ArrayList < DapVariable > ( ) ; this . allvariables = new ArrayList < DapVariable > ( ) ; this . allgroups = new ArrayList < DapGroup > ( ) ; this . allenums = new ArrayList < DapEnumeration > ( ) ; this . allcompounds = new ArrayList < DapStructure > ( ) ; this . alldimensions = new ArrayList < DapDimension > ( ) ; finishR ( this ) ;


signature:
public class DapDataset { /** * Recursive helper
 * @ param node to walk */
protected void finishR ( DapNode node ) { } }

implementation:
if ( ce != null && ! ce . references ( node ) ) return ; switch ( node . getSort ( ) ) { case DIMENSION : this . alldimensions . add ( ( DapDimension ) node ) ; break ; case ENUMERATION : this . allenums . add ( ( DapEnumeration ) node ) ; break ; case SEQUENCE : case STRUCTURE : this . allcompounds . add ( ( DapStructure ) node ) ; break ; case VARIABLE : if ( node . isTopLevel ( ) ) this . topvariables . add ( ( DapVariable ) node ) ; this . allvariables . add ( ( DapVariable ) node ) ; break ; case GROUP : case DATASET : DapGroup g = ( DapGroup ) node ; this . allgroups . add ( g ) ; for ( DapNode subnode : g . getDecls ( ) ) { finishR ( subnode ) ; } break ; default : /* ignore */
break ; }


signature:
public class DapDataset { /** * Parse an FQN and use it to trace to a specific
 * object in a dataset . Note that this is quite
 * tricky in the face of backslash escapes .
 * Because of backslash escapes , we cannot
 * use the String . split function because it does appear to be
 * possible to write a regexp that handles preceding backslashes
 * correctly . Instead , we must parse character by character left to right .
 * Traversal into structs :
 * In theory , a map variable could point to a field of a structure .
 * However , in practice , this will not work because we would need a
 * specific instance of that field , which means including dimension
 * indices must be included starting from some top - level variable .
 * We choose , for now , to make that illegal until such time as there
 * is a well - defined meaning for this .
 * Note : this assumes the fqn is absolute ( i . e . starts with ' / ' ) .
 * @ param fqn the fully qualified name
 * @ param sortset the kind ( s ) of object we are looking for
 * @ return the matching Dap Node or null if not found */
public DapNode lookup ( String fqn , DapSort ... sortset ) throws DapException { } }

implementation:
fqn = fqn . trim ( ) ; if ( fqn == null ) return null ; if ( "" . equals ( fqn ) || "/" . equals ( fqn ) ) { return this ; } if ( fqn . charAt ( 0 ) == '/' ) fqn = fqn . substring ( 1 ) ; // remove leading /
// Check first for an atomic type
TypeSort ts = TypeSort . getTypeSort ( fqn ) ; if ( ts != null && ts . isAtomic ( ) ) { // see if we are looking for an atomic type
for ( DapSort ds : sortset ) { if ( ds == DapSort . ATOMICTYPE ) return DapType . lookup ( ts ) ; } } // Do not use split to be able to look for escaped ' / '
// Warning : elements of path are unescaped
List < String > path = DapUtil . backslashSplit ( fqn , '/' ) ; DapGroup current = dataset ; // Walk all but the last element to walk group path
for ( int i = 0 ; i < path . size ( ) - 1 ; i ++ ) { String groupname = Escape . backslashUnescape ( path . get ( i ) ) ; DapGroup g = ( DapGroup ) current . findInGroup ( groupname , DapSort . GROUP ) ; if ( g == null ) return null ; assert ( g . getSort ( ) == DapSort . GROUP ) ; current = ( DapGroup ) g ; } if ( ! ALLOWFIELDMAPS ) { String targetname = Escape . backslashUnescape ( path . get ( path . size ( ) - 1 ) ) ; return current . findInGroup ( targetname , sortset ) ; } else { // ALLOWFIELDMAPS )
// We need to handle the last segment of the group path
// to deal with struct walking using ' . ' . We need to obtain the last segment
// with escapes intact so we can spot ' . ' separators .
// Locate the last element in the last group
// Start by looking for any containing structure
String varpart = path . get ( path . size ( ) - 1 ) ; // Note that this still has escapes
// So that ' . ' parsing will be correct .
List < String > structpath = DapUtil . backslashSplit ( varpart , '.' ) ; String outer = Escape . backslashUnescape ( structpath . get ( 0 ) ) ; if ( structpath . size ( ) == 1 ) { return current . findInGroup ( outer , sortset ) ; } else { // It is apparently a structure field
// locate the outermost structure to start with
DapStructure currentstruct = ( DapStructure ) current . findInGroup ( outer , DapSort . STRUCTURE , DapSort . SEQUENCE ) ; if ( currentstruct == null ) return null ; // does not exist
// search for the innermost structure
String fieldname ; for ( int i = 1 ; i < structpath . size ( ) - 1 ; i ++ ) { fieldname = Escape . backslashUnescape ( structpath . get ( i ) ) ; DapVariable field = ( DapVariable ) currentstruct . findByName ( fieldname ) ; if ( field == null ) throw new DapException ( "No such field: " + fieldname ) ; if ( ! field . isCompound ( ) ) break ; currentstruct = ( DapStructure ) field . getBaseType ( ) ; } fieldname = Escape . backslashUnescape ( structpath . get ( structpath . size ( ) - 1 ) ) ; DapVariable field = currentstruct . findByName ( fieldname ) ; if ( field == null ) throw new DapException ( "No such field: " + fieldname ) ; if ( field . getSort ( ) . oneof ( sortset ) ) return ( field ) ; } } return null ;


signature:
public class DapDataset { /** * Sort the nodelist into prefix left to right order */
public void sort ( ) { } }

implementation:
List < DapNode > sorted = new ArrayList < DapNode > ( ) ; sortR ( this , sorted ) ; // Assign indices
for ( int i = 0 ; i < sorted . size ( ) ; i ++ ) { sorted . get ( i ) . setIndex ( i ) ; } this . nodelist = sorted ;


signature:
public class DapDataset { /** * Sort helper
 * @ param node the current node we are traversing */
public void sortR ( DapNode node , List < DapNode > sortlist ) { } }

implementation:
DapVariable var = null ; Map < String , DapAttribute > attrs = null ; sortlist . add ( node ) ; switch ( node . getSort ( ) ) { case DATASET : case GROUP : // Walk the decls in this group in order
// attributes , dimensions , enums , variables , groups
DapGroup group = ( DapGroup ) node ; attrs = group . getAttributes ( ) ; for ( Map . Entry < String , DapAttribute > entry : attrs . entrySet ( ) ) { sortR ( entry . getValue ( ) , sortlist ) ; } List < DapDimension > dims = group . getDimensions ( ) ; if ( dims != null ) for ( int i = 0 ; i < dims . size ( ) ; i ++ ) { sortR ( dims . get ( i ) , sortlist ) ; } List < DapEnumeration > enums = group . getEnums ( ) ; if ( enums != null ) for ( int i = 0 ; i < enums . size ( ) ; i ++ ) { sortR ( enums . get ( i ) , sortlist ) ; } List < DapVariable > vars = group . getVariables ( ) ; if ( vars != null ) for ( int i = 0 ; i < vars . size ( ) ; i ++ ) { sortR ( vars . get ( i ) , sortlist ) ; } List < DapGroup > groups = group . getGroups ( ) ; if ( groups != null ) for ( int i = 0 ; i < groups . size ( ) ; i ++ ) { sortR ( groups . get ( i ) , sortlist ) ; } break ; case VARIABLE : var = ( DapVariable ) node ; attrs = var . getAttributes ( ) ; if ( attrs != null ) for ( Map . Entry < String , DapAttribute > entry : attrs . entrySet ( ) ) { sortR ( entry . getValue ( ) , sortlist ) ; } List < DapMap > maps = var . getMaps ( ) ; if ( maps != null ) for ( int i = 0 ; i < maps . size ( ) ; i ++ ) { sortR ( maps . get ( i ) , sortlist ) ; } dims = var . getDimensions ( ) ; if ( dims != null ) for ( int i = 0 ; i < dims . size ( ) ; i ++ ) { sortR ( dims . get ( i ) , sortlist ) ; } break ; case ATTRIBUTE : attrs = node . getAttributes ( ) ; if ( attrs != null ) for ( String name : attrs . keySet ( ) ) { sortR ( attrs . get ( name ) , sortlist ) ; } break ; default : break ; }


signature:
public class EcmwfParamTableCompare { /** * Compare 2 tables , print report . */
public static void compareTables ( Grib2ParamTableInterface t1 , Grib2ParamTableInterface t2 , Formatter f ) { } }

implementation:
int extra = 0 ; int udunits = 0 ; int conflict = 0 ; f . format ( "%s%n" , t2 . getName ( ) ) ; for ( GribTables . Parameter p1 : t1 . getParameters ( ) ) { if ( t1 . getParameter ( p1 . getNumber ( ) ) == null ) { f . format ( " ERROR %s missing own parameter %d%n" , t1 . getShortName ( ) , p1 . getNumber ( ) ) ; } GribTables . Parameter p2 = t2 . getParameter ( p1 . getNumber ( ) ) ; if ( p2 == null ) { extra ++ ; if ( verbose ) { f . format ( "  %s missing %s%n" , t2 . getShortName ( ) , p1 ) ; } } else { if ( ! Util . equivilantName ( p1 . getName ( ) , p2 . getName ( ) ) ) { f . format ( "  p1=%10s %s%n" , p1 . getId ( ) , p1 . getName ( ) ) ; f . format ( "  p2=%10s %s%n" , p2 . getId ( ) , p2 . getName ( ) ) ; conflict ++ ; } if ( ! p1 . getUnit ( ) . equalsIgnoreCase ( p2 . getUnit ( ) ) ) { String cu1 = Util . cleanUnit ( p1 . getUnit ( ) ) ; String cu2 = Util . cleanUnit ( p2 . getUnit ( ) ) ; // eliminate common non - udunits
boolean isUnitless1 = Util . isUnitless ( cu1 ) ; boolean isUnitless2 = Util . isUnitless ( cu2 ) ; if ( isUnitless1 != isUnitless2 ) { f . format ( "  unitless for %10s %s != %s%n" , p1 . getId ( ) , cu1 , cu2 ) ; udunits ++ ; } else if ( ! isUnitless1 ) { try { SimpleUnit su1 = SimpleUnit . factoryWithExceptions ( cu1 ) ; if ( ! su1 . isCompatible ( cu2 ) ) { f . format ( "  incompatible for %10s %s (%s) != %s (org %s)%n" , p1 . getId ( ) , cu1 , su1 , cu2 , p2 . getUnit ( ) ) ; udunits ++ ; } } catch ( Exception e ) { f . format ( "  udunits cant parse=%10s %15s %15s%n" , p1 . getId ( ) , cu1 , cu2 ) ; } } } } } int missing = 0 ; for ( GribTables . Parameter p2 : t2 . getParameters ( ) ) { if ( t2 . getParameter ( p2 . getNumber ( ) ) == null ) { f . format ( " ERROR %s missing own parameter %d%n" , t2 . getShortName ( ) , p2 . getNumber ( ) ) ; } GribTables . Parameter p1 = t1 . getParameter ( p2 . getNumber ( ) ) ; if ( p1 == null ) { missing ++ ; f . format ( "  %s missing %s%n" , t1 . getShortName ( ) , p2 ) ; } } if ( conflict > 0 || udunits > 0 || missing > 0 ) { f . format ( " ***Conflicts=%d extra=%d udunits=%d missing=%s%n" , conflict , extra , udunits , missing ) ; }


signature:
public class PartitionCollectionImmutable { /** * stuff for Iosp */
RandomAccessFile getRaf ( int partno , int fileno ) throws IOException { } }

implementation: Partition part = getPartition ( partno ) ; try ( GribCollectionImmutable gc = part . getGribCollection ( ) ) { return gc . getDataRaf ( fileno ) ; }


signature:
public class PartitionCollectionImmutable { /** * debugging */
public String getFilename ( int partno , int fileno ) throws IOException { } }

implementation: Partition part = getPartition ( partno ) ; try ( GribCollectionImmutable gc = part . getGribCollection ( ) ) { return gc . getFilename ( fileno ) ; }


signature:
public class UAMIVServiceProvider { /** * Check if this is a valid file for this IOServiceProvider .
 * @ param raf RandomAccessFile
 * @ return true if valid . */
public boolean isValidFile ( RandomAccessFile raf ) throws IOException { } }

implementation: try { raf . order ( RandomAccessFile . BIG_ENDIAN ) ; raf . seek ( 0 ) ; raf . skipBytes ( 4 ) ; String test = raf . readString ( 40 ) ; return test . equals ( EMISSIONS ) || test . equals ( AVERAGE ) || test . equals ( AIRQUALITY ) || test . equals ( INSTANT ) ; } catch ( IOException ioe ) { return false ; }


signature:
public class UAMIVServiceProvider { /** * Open existing file , and populate ncfile with it .
 * @ param raf the file to work on , it has already passed the isValidFile ( ) test .
 * @ param ncfile add objects to this NetcdfFile
 * @ param cancelTask used to monito user cancellation ; may be null .
 * @ throws IOException */
public void open ( RandomAccessFile raf , NetcdfFile ncfile , CancelTask cancelTask ) throws IOException { } }

implementation:
/* * < b > open < / b > initializes the file meta data and creates all variables .
 * The meta - data and variable information is gathered from the UAM - IV
 * header . The header format is detailed in the CAMx User ' s
 * guide and copied here .
 * Header :
 * name , note , ione , nspec , ibdate , btime , iedate , etime
 * rdum , rdum , iutm , xorg , yorg , delx , dely , nx , ny , nz , idum , idum , rdum , rdum , rdum
 * ione , ione , nx , ny
 * ( mspec ( l ) , l = 1 , nspec )
 * name - Text string ( character * 4(10 ) array )
 * note - Text string containing file description ( character * 4(60 ) array )
 * ione - Dummy variable = 1
 * nspec - Number of species on file
 * ibdate - Beginning date ( YYJJJ )
 * btime - Beginning hour ( HHMM )
 * iedate - Ending date ( YYJJJ )
 * etime - Ending hour ( HHMM )
 * rdum - Dummy real variable
 * iutm - UTM zone ( ignored for other projections )
 * xorg - Grid x - origin at southwest corner of domain ( m or degrees longitude )
 * yorg - Grid y - origin at southwest corner of domain ( m or degrees latitude )
 * delx - Cell size in x - direction ( m or degrees longitude )
 * dely - Cell size in y - direction ( m or degrees longitude )
 * nx - Number of grid columns
 * ny - Number of grid rows
 * nz - Number of layers
 * idum - Dummy integer variable
 * mspec - Species names for nspec species ( character * 4(10 , nspec ) array )
 * time step is HHMMSS
 * the projection is :
 * LCC / / > : GDTYP = 2 ; / / int
 * First True Latitude ( Alpha ) : 30N / / > : P _ ALP = 30.0 ; / / double
 * Second True Latitude ( Beta ) : 60N / / > : P _ BET = 60.0 ; / / double
 * Central Longitude ( Gamma ) : 100W / / > : XCENT = - 100.0 ; / / double
 * Projection Origin : ( 100W , 40N ) / / > : YCENT = 40.0 ; / / double */
// Internalize raf and ncfile
super . open ( raf , ncfile , cancelTask ) ; // set raf to big endian and start at the beginning
raf . order ( RandomAccessFile . BIG_ENDIAN ) ; raf . seek ( 0 ) ; // Read first line of UAM - IV header
raf . skipBytes ( 4 ) ; // Skip record pad
String name = raf . readString ( 40 ) ; // read 40 name
String note = raf . readString ( 240 ) ; int itzone = raf . readInt ( ) ; // Read the time zone
int nspec = raf . readInt ( ) ; // Read number of species
int bdate = raf . readInt ( ) ; // get file start date
float btime = raf . readFloat ( ) ; // get file start time
int edate = raf . readInt ( ) ; // get file end date
float etime = raf . readFloat ( ) ; // get file end time
int btimei = ( int ) btime ; // convert btime to an integer
// CAMx times are sometimes provided as HH or HHMM .
// IOAPI times are always provided as HHMMSS .
// CAMx times less than 100 are HH and should be
// multipled by 100 to get HHMM . CAMx times less
// 10000 are HHMM and should be multipled by 100
// to get HHMMSS .
if ( btimei < 100 ) btimei = btimei * 100 ; if ( btimei < 10000 ) btimei = btimei * 100 ; /* * Dates are YYJJJ and are heuristically converted
 * to YYYYJJJ based on the following assumption :
 * YY < 70 are 2000
 * YY > = 70 are 1900 */
if ( bdate < 70000 ) { edate = edate + 2000000 ; bdate = bdate + 2000000 ; } else { edate = edate + 1900000 ; bdate = bdate + 1900000 ; } raf . skipBytes ( 4 ) ; // Skip record pad
// Read second line of UAM - IV header
raf . skipBytes ( 4 ) ; // Skip record pad
float plon = raf . readFloat ( ) ; // get polar longitude
float plat = raf . readFloat ( ) ; // get polar latitude
int iutm = raf . readInt ( ) ; // get utm
float xorg = raf . readFloat ( ) ; // get x origin in meters
float yorg = raf . readFloat ( ) ; // get y origin in meters
float delx = raf . readFloat ( ) ; // get x cell size in meters
float dely = raf . readFloat ( ) ; // get y cell size in meters
int nx = raf . readInt ( ) ; // get number of columns
int ny = raf . readInt ( ) ; // get number of rows
int nz = raf . readInt ( ) ; // get number of layers
// get projection number
// (0 : lat - lon ;
// 1 : Universal Transverse Mercator ;
// 2 : Lambert Conic Conformal ;
// 3 : Polar stereographic )
// These translate to IOAPI GDTYP3D values 1 , 5 , 2 , and 6 respectively
int iproj = raf . readInt ( ) ; int istag = raf . readInt ( ) ; // Read stagger indicator
float tlat1 = raf . readFloat ( ) ; // Read true latitude 1
float tlat2 = raf . readFloat ( ) ; // Read true latitude 2
raf . skipBytes ( 4 ) ; // Skip 1 dummies
raf . skipBytes ( 4 ) ; // Skip record pad
// Read third line of UAM - IV header
raf . skipBytes ( 4 ) ; // Skip record pad
raf . skipBytes ( 8 ) ; // Skip 2 dummies
int nx2 = raf . readInt ( ) ; // duplicate number of columns
int ny2 = raf . readInt ( ) ; // duplicate number of rows
raf . skipBytes ( 8 ) ; // Skip 2 dummies
nz = Math . max ( nz , 1 ) ; // number of layers ; Emissions files occasionally report 0 layers
/* * 1 ) Read each species name
 * 2 ) remove white space from the name
 * 3 ) store the names
 * 4 ) internalize them */
int count = 0 ; String [ ] spc_names = new String [ nspec ] ; while ( count < nspec ) { String spc = raf . readString ( 40 ) ; // 1 ) read species name
spc_names [ count ++ ] = spc . replace ( " " , "" ) ; // 2&3 ) store name without whitespace
} this . species_names = spc_names ; // 4 ) internalize names
raf . skipBytes ( 4 ) ; // Skip record pad
// Note this position ; it is the start of the data block
this . data_start = raf . getFilePointer ( ) ; // Note the number of float equivalents ( 4 byte chunks ) in data block
int data_length_float_equivalents = ( ( int ) raf . length ( ) - ( int ) data_start ) / 4 ; // Store 2D value size
this . n2dvals = nx * ny ; // Store 3D value size
this . n3dvals = nx * ny * nz ; // Store 2D binary data block size : include values ( nx * ny ) ,
// species name ( 10 ) , a dummy ( 1 ) and 2 record pads
int spc_2D_block = nx * ny + 10 + 2 + 1 ; // Store 3D binary data block size
this . spc_3D_block = spc_2D_block * nz ; // Store whole data block size ; includes date ( 6)
this . data_block = this . spc_3D_block * nspec + 6 ; // Store the number of times
int ntimes = data_length_float_equivalents / this . data_block ; // Add dimensions based on header values
ncfile . addDimension ( null , new Dimension ( "TSTEP" , ntimes , true ) ) ; ncfile . addDimension ( null , new Dimension ( "LAY" , nz , true ) ) ; ncfile . addDimension ( null , new Dimension ( "ROW" , ny , true ) ) ; ncfile . addDimension ( null , new Dimension ( "COL" , nx , true ) ) ; // Force sync of dimensions
ncfile . finish ( ) ; count = 0 ; /* * For each species , create a variable with long _ name ,
 * and var _ desc , and units . long _ name and var _ desc are
 * simply the species name . units is heuristically
 * determined from the name */
HashSet < String > AeroSpcs = new HashSet < > ( Arrays . asList ( "PSO4" , "PNO3" , "PNH4" , "PH2O" , "SOPA" , "SOPB" , "NA" , "PCL" , "POA" , "PEC" , "FPRM" , "FCRS" , "CPRM" , "CCRS" ) ) ; HashSet < String > LULC = new HashSet < > ( Arrays . asList ( "WATER" , "ICE" , "LAKE" , "ENEEDL" , "EBROAD" , "DNEEDL" , "DBROAD" , "TBROAD" , "DDECID" , "ESHRUB" , "DSHRUB" , "TSHRUB" , "SGRASS" , "LGRASS" , "CROPS" , "RICE" , "SUGAR" , "MAIZE" , "COTTON" , "ICROPS" , "URBAN" , "TUNDRA" , "SWAMP" , "DESERT" , "MWOOD" , "TFOREST" ) ) ; while ( count < nspec ) { String spc = spc_names [ count ++ ] ; Variable temp = ncfile . addVariable ( null , spc , DataType . FLOAT , "TSTEP LAY ROW COL" ) ; if ( spc . equals ( WINDX ) || spc . equals ( WINDY ) || spc . equals ( SPEED ) ) { temp . addAttribute ( new Attribute ( CDM . UNITS , "m/s" ) ) ; } else if ( spc . equals ( VERTDIFF ) ) { temp . addAttribute ( new Attribute ( CDM . UNITS , "m**2/s" ) ) ; } else if ( spc . equals ( TEMP ) ) { temp . addAttribute ( new Attribute ( CDM . UNITS , "K" ) ) ; } else if ( spc . equals ( PRESS ) ) { temp . addAttribute ( new Attribute ( CDM . UNITS , "hPa" ) ) ; } else if ( spc . equals ( HEIGHT ) || spc . equals ( PBL ) ) { temp . addAttribute ( new Attribute ( CDM . UNITS , "m" ) ) ; } else if ( spc . equals ( CLDWATER ) || spc . equals ( PRECIP ) || spc . equals ( RAIN ) ) { temp . addAttribute ( new Attribute ( CDM . UNITS , "g/m**3" ) ) ; } else if ( spc . equals ( CLDOD ) || spc . equals ( "CLOUDOD" ) ) { temp . addAttribute ( new Attribute ( CDM . UNITS , "none" ) ) ; } else if ( spc . equals ( "SNOWCOVER" ) ) { temp . addAttribute ( new Attribute ( CDM . UNITS , "yes/no" ) ) ; } else if ( spc . startsWith ( "SOA" ) || AeroSpcs . contains ( spc ) ) { if ( name . equals ( EMISSIONS ) ) { temp . addAttribute ( new Attribute ( CDM . UNITS , "g/time" ) ) ; } else { temp . addAttribute ( new Attribute ( CDM . UNITS , "ug/m**3" ) ) ; } } else if ( LULC . contains ( spc ) ) { temp . addAttribute ( new Attribute ( CDM . UNITS , "fraction" ) ) ; } else if ( spc . lastIndexOf ( "_" ) > - 1 ) { String tmpunit = spc . substring ( spc . lastIndexOf ( "_" ) + 1 ) ; tmpunit = tmpunit . trim ( ) ; switch ( tmpunit ) { case "M2pS" : tmpunit = "m**2/s" ; break ; case "MpS" : tmpunit = "m/s" ; break ; case "PPM" : tmpunit = "ppm" ; break ; case "MB" : tmpunit = "millibar" ; break ; case "GpM3" : tmpunit = "g/m**3" ; break ; case "M" : tmpunit = "m" ; break ; } temp . addAttribute ( new Attribute ( CDM . UNITS , tmpunit ) ) ; } else { if ( name . equals ( EMISSIONS ) ) { temp . addAttribute ( new Attribute ( CDM . UNITS , "mol/time" ) ) ; } else { temp . addAttribute ( new Attribute ( CDM . UNITS , "ppm" ) ) ; } } temp . addAttribute ( new Attribute ( CDM . LONG_NAME , spc ) ) ; temp . addAttribute ( new Attribute ( "var_desc" , spc ) ) ; } /* * Create 1 . . . n array of " sigma " values */
double [ ] sigma = new double [ nz + 1 ] ; count = 0 ; while ( count < nz + 1 ) { sigma [ count ++ ] = count ; } int [ ] size = new int [ 1 ] ; size [ 0 ] = nz + 1 ; Array sigma_arr = Array . factory ( DataType . DOUBLE , size , sigma ) ; /* * Add meta - data according to the IOAPI conventions
 * http : / / www . baronams . com / products / ioapi */
ncfile . addAttribute ( null , new Attribute ( "VGLVLS" , sigma_arr ) ) ; ncfile . addAttribute ( null , new Attribute ( "SDATE" , bdate ) ) ; ncfile . addAttribute ( null , new Attribute ( "STIME" , btimei ) ) ; ncfile . addAttribute ( null , new Attribute ( "TSTEP" , 10000 ) ) ; ncfile . addAttribute ( null , new Attribute ( "NSTEPS" , ntimes ) ) ; ncfile . addAttribute ( null , new Attribute ( "NLAYS" , nz ) ) ; ncfile . addAttribute ( null , new Attribute ( "NROWS" , ny ) ) ; ncfile . addAttribute ( null , new Attribute ( "NCOLS" , nx ) ) ; ncfile . addAttribute ( null , new Attribute ( "XORIG" , ( double ) xorg ) ) ; ncfile . addAttribute ( null , new Attribute ( "YORIG" , ( double ) yorg ) ) ; ncfile . addAttribute ( null , new Attribute ( "XCELL" , ( double ) delx ) ) ; ncfile . addAttribute ( null , new Attribute ( "YCELL" , ( double ) dely ) ) ; /* * IOAPI Projection parameters are provided by a colocated camxproj . txt file ;
 * to do :
 * 1 ) needs earth radius
 * 2 ) needs better error checking */
Integer gdtyp = 2 ; Double p_alp = 20. ; Double p_bet = 60. ; Double p_gam = 0. ; Double xcent = - 95. ; Double ycent = 25. ; if ( ! ( ( iproj == 0 ) && ( tlat1 == 0 ) && ( tlat2 == 0 ) && ( plon == 0 ) && ( plat == 0 ) ) ) { xcent = ( double ) plon ; ycent = ( double ) plat ; if ( iproj == 0 ) { // Lat - Lon ( iproj = 0 ) has no additional information
gdtyp = 1 ; } else if ( iproj == 1 ) { // UTM uses only iutm
gdtyp = 5 ; p_alp = ( double ) iutm ; } else if ( iproj == 2 ) { gdtyp = 2 ; p_alp = ( double ) tlat1 ; p_bet = ( double ) tlat2 ; p_gam = ( double ) plon ; } else if ( iproj == 3 ) { gdtyp = 6 ; if ( plat == 90 ) { p_alp = 1. ; } else if ( plat == - 90 ) { p_alp = - 1. ; } p_bet = ( double ) tlat1 ; p_gam = ( double ) plon ; } else { gdtyp = 2 ; p_alp = 20. ; p_bet = 60. ; p_gam = 0. ; xcent = - 95. ; ycent = 25. ; } } String thisLine ; String projpath = raf . getLocation ( ) ; Boolean lgdtyp = false ; Boolean lp_alp = false ; Boolean lp_bet = false ; Boolean lp_gam = false ; Boolean lxcent = false ; Boolean lycent = false ; int lastIndex = projpath . lastIndexOf ( File . separator ) ; if ( lastIndex <= 0 ) lastIndex = projpath . lastIndexOf ( '/' ) ; if ( lastIndex > 0 ) projpath = projpath . substring ( 0 , lastIndex ) ; projpath = projpath + File . separator + "camxproj.txt" ; File paramFile = new File ( projpath ) ; if ( paramFile . exists ( ) ) { try ( BufferedReader br = new BufferedReader ( new InputStreamReader ( new FileInputStream ( paramFile ) , CDM . UTF8 ) ) ) { while ( ( thisLine = br . readLine ( ) ) != null ) { if ( thisLine . length ( ) == 0 ) continue ; if ( thisLine . charAt ( 0 ) == '#' ) continue ; String [ ] key_value = thisLine . split ( "=" ) ; switch ( key_value [ 0 ] ) { case "GDTYP" : gdtyp = Integer . parseInt ( key_value [ 1 ] ) ; lgdtyp = true ; break ; case "P_ALP" : p_alp = Double . parseDouble ( key_value [ 1 ] ) ; lp_alp = true ; break ; case "P_BET" : p_bet = Double . parseDouble ( key_value [ 1 ] ) ; lp_bet = true ; break ; case "P_GAM" : p_gam = Double . parseDouble ( key_value [ 1 ] ) ; lp_gam = true ; break ; case "YCENT" : ycent = Double . parseDouble ( key_value [ 1 ] ) ; lycent = true ; break ; case "XCENT" : xcent = Double . parseDouble ( key_value [ 1 ] ) ; lxcent = true ; break ; } } } if ( ! lgdtyp ) log . warn ( "GDTYP not found; using " + gdtyp . toString ( ) ) ; if ( ! lp_alp ) log . warn ( "P_ALP not found; using " + p_alp . toString ( ) ) ; if ( ! lp_bet ) log . warn ( "P_BET not found; using " + p_bet . toString ( ) ) ; if ( ! lp_gam ) log . warn ( "P_GAM not found; using " + p_gam . toString ( ) ) ; if ( ! lxcent ) log . warn ( "XCENT not found; using " + xcent . toString ( ) ) ; if ( ! lycent ) log . warn ( "YCENT not found; using " + ycent . toString ( ) ) ; } else { if ( log . isDebugEnabled ( ) ) log . debug ( "UAMIVServiceProvider: adding projection file" ) ; try ( FileOutputStream out = new FileOutputStream ( paramFile ) ) { OutputStreamWriter fout = new OutputStreamWriter ( out , CDM . utf8Charset ) ; BufferedWriter bw = new BufferedWriter ( fout ) ; bw . write ( "# Projection parameters are based on IOAPI.  For details, see www.baronams.com/products/ioapi/GRIDS.html" ) ; bw . newLine ( ) ; bw . write ( "GDTYP=" ) ; bw . write ( gdtyp . toString ( ) ) ; bw . newLine ( ) ; bw . write ( "P_ALP=" ) ; bw . write ( p_alp . toString ( ) ) ; bw . newLine ( ) ; bw . write ( "P_BET=" ) ; bw . write ( p_bet . toString ( ) ) ; bw . newLine ( ) ; bw . write ( "P_GAM=" ) ; bw . write ( p_gam . toString ( ) ) ; bw . newLine ( ) ; bw . write ( "XCENT=" ) ; bw . write ( xcent . toString ( ) ) ; bw . newLine ( ) ; bw . write ( "YCENT=" ) ; bw . write ( ycent . toString ( ) ) ; bw . newLine ( ) ; bw . flush ( ) ; bw . close ( ) ; } } ncfile . addAttribute ( null , new Attribute ( "GDTYP" , gdtyp ) ) ; ncfile . addAttribute ( null , new Attribute ( "P_ALP" , p_alp ) ) ; ncfile . addAttribute ( null , new Attribute ( "P_BET" , p_bet ) ) ; ncfile . addAttribute ( null , new Attribute ( "P_GAM" , p_gam ) ) ; ncfile . addAttribute ( null , new Attribute ( "XCENT" , xcent ) ) ; ncfile . addAttribute ( null , new Attribute ( "YCENT" , ycent ) ) ;


signature:
public class UAMIVServiceProvider { /** * Read data from a top level Variable and return a memory resident Array .
 * This Array has the same element type as the Variable , and the requested shape .
 * @ param v2 a top - level Variable
 * @ param wantSection List of type Range specifying the section of data to read .
 * There must be a Range for each Dimension in the variable , in order .
 * Note : no nulls .
 * @ return the requested data in a memory - resident Array
 * @ throws java . io . IOException
 * @ throws ucar . ma2 . InvalidRangeException
 * @ see ucar . ma2 . Range */
public ucar . ma2 . Array readData ( Variable v2 , Section wantSection ) throws IOException , InvalidRangeException { } }

implementation:
/* * < b > readData < / b > seeks and reads the data for each variable . The variable
 * data format is detailed in the CAMx User ' s guide and summarized here .
 * For each time :
 * ibdate , btime , iedate , etime
 * Loop from 1 to nspec species :
 * ione , mspec ( l ) , ( ( val ( i , j , l ) , i = 1 , nx ) , j = 1 , ny )
 * ione - Dummy variable = 1
 * nspec - Number of species on file
 * ibdate - Beginning date ( YYJJJ )
 * btime - Beginning hour ( HHMM )
 * iedate - Ending date ( YYJJJ )
 * etime - Ending hour ( HHMM )
 * mspec - Species names for nspec species ( character * 4(10 , nspec ) array )
 * val - Species l , layer k initial concentrations ( ppm for gases , ug / m3 for aerosols )
 * for nx grid columns and ny grid rows */
// CAMx UAM - IV Files are all big endian
raf . order ( RandomAccessFile . BIG_ENDIAN ) ; // Prepare an array for binary data
int size = ( int ) v2 . getSize ( ) ; float [ ] arr = new float [ size ] ; // Move to data block of file
raf . seek ( this . data_start ) ; /* * First record is stime , sdate , etime , edate
 * We are skipping the data , but checking
 * the consistency of the Fortran " unformatted "
 * data record */
int pad1 = raf . readInt ( ) ; raf . skipBytes ( 16 ) ; int pad2 = raf . readInt ( ) ; if ( pad1 != pad2 ) { throw new IOException ( "Asymmetric fortran buffer values: 1" ) ; } // Find species name / id associated with this variable
int spcid = - 1 ; String spc = "" ; while ( ! spc . equals ( v2 . getShortName ( ) ) ) { spc = this . species_names [ ++ spcid ] ; } /* * Skip data associated with species that are prior
 * in the data block */
raf . skipBytes ( this . spc_3D_block * spcid * 4 ) ; // Initialize count for indexing arr
int count = 0 ; while ( count < size ) { /* * Read species name and store the initial record pad .
 * Note : it might be good to compare
 * spc string to variable . getShortName */
if ( count == 0 ) { pad1 = raf . readInt ( ) ; int ione = raf . readInt ( ) ; spc = raf . readString ( 40 ) ; } /* * If we have read a 2D slice , read the final record pad
 * and compare to initial record pad . If everything is okay , proceed .
 * ( 1 ) skip to next 2D slice
 * ( 2 ) store initial pad
 * ( 3 ) read spc name
 * Note : it might be good to compare
 * spc string to variable . getShortName */
if ( ( count != 0 ) && ( ( count % this . n2dvals ) == 0 ) ) { pad2 = raf . readInt ( ) ; if ( pad1 != pad2 ) { // System . out . println ( pad1 ) ;
// System . out . println ( pad2 ) ;
throw new IOException ( "Asymmetric fortran buffer values: 2" ) ; } if ( ( count % this . n3dvals ) == 0 ) { raf . skipBytes ( ( this . data_block - this . spc_3D_block ) * 4 ) ; } pad1 = raf . readInt ( ) ; int ione = raf . readInt ( ) ; spc = raf . readString ( 40 ) ; } /* * Attempt to read a Float from the file */
try { arr [ count ++ ] = raf . readFloat ( ) ; } catch ( java . lang . ArrayIndexOutOfBoundsException io ) { throw new IOException ( io . getMessage ( ) ) ; } } // Convert java float [ ] to ma2 . Array
Array data = Array . factory ( DataType . FLOAT , v2 . getShape ( ) , arr ) ; // Subset the data based on the wantSection and return a 4D variable
return data . sectionNoReduce ( wantSection . getRanges ( ) ) ;


signature:
public class Evaluator { /** * Find first variable with given attribute name
 * @ param ds in this dataset
 * @ param attName attribute name , case insensitive
 * @ return first variable with given attribute name , or null */
static public VarAtt findVariableWithAttribute ( NetcdfDataset ds , String attName ) { } }

implementation:
for ( Variable v : ds . getVariables ( ) ) { Attribute att = v . findAttributeIgnoreCase ( attName ) ; if ( att != null ) return new VarAtt ( v , att ) ; } // descend into structures
for ( Variable v : ds . getVariables ( ) ) { if ( v instanceof Structure ) { Structure s = ( Structure ) v ; for ( Variable vs : s . getVariables ( ) ) { Attribute att = vs . findAttributeIgnoreCase ( attName ) ; if ( att != null ) return new VarAtt ( vs , att ) ; } } } return null ;


signature:
public class Evaluator { /** * Find first variable with given attribute name and value .
 * If not found , search one level into structures .
 * @ param ds in this dataset
 * @ param attName attribute name , case insensitive
 * @ param attValue attribute value , case sensitive
 * @ return first variable with given attribute name and value , or null */
static public Variable findVariableWithAttributeValue ( NetcdfDataset ds , String attName , String attValue ) { } }

implementation:
for ( Variable v : ds . getVariables ( ) ) { String haveValue = ds . findAttValueIgnoreCase ( v , attName , null ) ; if ( ( haveValue != null ) && haveValue . equals ( attValue ) ) return v ; } // descend into structures
for ( Variable v : ds . getVariables ( ) ) { if ( v instanceof Structure ) { Variable vn = findVariableWithAttributeValue ( ( Structure ) v , attName , attValue ) ; if ( null != vn ) return vn ; } } return null ;