WaBis

walter.bislins.ch

JavaScript: Al-Biruni Calculator with Refraction

This is the Javascript source code of the online calculator in the article Measuring Earths Radius like Al-Biruni taking Refraction into account.

#INCLUDE ControlPanel.inc

<jscript>

function ComputeMeanAndTolerance( func, means, tolerances ) {
  // uses the means[n] and tolerances[n] to generate all possible
  // variation[i] = means[i] +/- tolerances[i] and calls func(variation[i])
  // for each variation. From the results of func() the min and max
  // values are determined.
  //
  // Returns { exact:, mean:, tolerance: } value from all variantions, 
  // where mean = (max + min) / 2 and tolerance = (max - min) / 2.

  function getNMaskValues( nParam ) {
    return Math.pow( 3, nParam );
  }

  function makeVariation( mask, means, tolerances ) {
    // Uses mask to add or subtract tolerance[i] from means[i] 
    // to get all possible variations[n]. Increasing the mask
    // and call this function repeatedly to get all possible variations.
    // mask = 0 returns means[] without tolerances[] applied.
    // Call getNMaskValues() to calculate the max value+1 for mask.
    // 
    // mask = 0 -> [ m[0]     , m[1]     , ..., m[n] ]
    // mask = 1 -> [ m[0]-t[0], m[1]     , ..., m[n] ]
    // mask = 2 -> [ m[0]+t[0], m[1]     , ..., m[n] ]
    // mask = 3 -> [ m[0]     , m[1]-t[1], ..., m[n] ]
    // mask = 4 -> [ m[0]-t[0], m[1]-t[1], ..., m[n] ]
    // mask = 5 -> [ m[0]+t[0], m[1]-t[1], ..., m[n] ]
    // mask = 6 -> [ m[0]     , m[1]+t[1], ..., m[n] ]
    // mask = 7 -> [ m[0]-t[0], m[1]+t[1], ..., m[n] ]
    // mask = 8 -> [ m[0]+t[0], m[1]+t[1], ..., m[n] ]
    // and so on

    var variations = [];
    var nValues = means.length;
    for (var i = 0; i < nValues; i++) {
      variations[i] = means[i];
    }
    for (var i = 0; i < nValues; i++) {
      var maskBit = mask % 3;
      if (maskBit === 1) {
        variations[i] -= tolerances[i];
      } else if (maskBit === 2) {
        variations[i] += tolerances[i];
      }
      mask = Math.trunc( mask/3 );
      if (mask === 0) break;
    }
    return variations;
  }

  var exactValue = func( ...means );

  var minValue = exactValue;
  var maxValue = exactValue;
  var nMaskValues = getNMaskValues( means.length );
  for (var mask = 1; mask < nMaskValues; mask++) {
    var pars = makeVariation( mask, means, tolerances );
    var currentValue = func( ...pars );
    if (currentValue < minValue) minValue = currentValue;
    if (currentValue > maxValue) maxValue = currentValue;
  }
  var mean      = (minValue + maxValue) / 2;
  var tolerance = (maxValue - minValue) / 2;
  return { exact: exactValue, mean: mean, tolerance: tolerance };
}

var AlBiruniModel = {

  Pressure:       1013.25, // mbar
  PressureAbsTol:       1, // mbar
  PressureRelTol:       0, // AbsTol/Mean in %

  TempC:             15.5,
  TempCAbsTol:       0.25,
  TempCRelTol:          0,

  TempGrad:      -0.01221, // °C/m
  TempGradAbsTol:  0.0005,
  TempGradRelTol:       0,

  RefrCoeff:         0.17,
  RefrCoeffAbsTol:   0.04,
  RefrCoeffRelTol:      0,

  LightCurve:           0,
  LightCurveAbsTol:     0,
  LightCurveRelTol:     0,

  LightRad:             0,
  LightRadAbsTol:       0,
  LightRadRelTol:       0,

  ObsHeight:          358, // m
  ObsHeightAbsTol:     12, // m
  ObsHeightRelTol:      0,

  DipAngle:          0.56667, // deg
  DipAngleAbsTol:    0.016667,
  DipAngleRelTol:       0,

  R:                    0, // m  
  RMean:                0, // m
  RAbsTol:              0, // m  
  RRelTol:              0,

  DistAB:               1000,
  DistABAbsTol:            5,
  DistABRelTol:            0,

  Alpha:                  45, // degrees
  AlphaAbsTol:          0.25,
  AlphaRelTol:             0,

  Beta:                14.75,
  BetaAbsTol:           0.25,
  BetaRelTol:              0,

  FeMntHeight:             0,
  FeMntHeightMean:         0,
  FeMntHeightAbsTol:       0,
  FeMntHeightRelTol:       0,

  GlobeMntHeight:          0,
  GlobeMntHeightMean:      0,
  GlobeMntHeightAbsTol:    0,
  GlobeMntHeightRelTol:    0,

  MntRefrCoeff:         0.13,
  MntRefrCoeffAbsTol:  0.026,
  MntRefrCoeffRelTol:      0,

  GlobeFlatDiff:           0,
  GlobeFlatDiffMean:       0,
  GlobeFlatDiffAbsTol:     0,
  GlobeFlatDiffrelTol:     0,

  UnitsType: 0,  // 0 -> m, 1 -> mi/ft, 2 -> ft
  LengthUnits: {
    Selection: '.UnitsType',
    Units: [ 'm', 'mi', 'ft' ],
    Mults: [ 1, 1609.344, 0.3048 ]
  },
  BigLengthUnits: {
    Selection: '.UnitsType',
    Units: [ 'km', 'mi', 'ft' ],
    Mults: [ 1000, 1609.344, 0.3048 ]
  },
  InvLengthUnits: {
    Selection: '.UnitsType',
    Units: [ 'm<sup>-1</sup>', 'mi<sup>-1</sup>', 'ft<sup>-1</sup>' ],
    Mults: [ 1, 1/1609.344, 1/0.3048 ],
    Digits:[ 6, 6, 6 ],
  },
  HeightUnits: {
    Selection: '.UnitsType',
    Units: [ 'm', 'ft', 'ft' ],
    Mults: [ 1, 0.3048, 0.3048 ]
  },
  GradientUnits: {
    Selection: '.UnitsType',
    Units: [ '°C/m', '°C/ft', '°C/ft' ],
    Mults: [ 1, 1/0.3048, 1/0.3048 ]
  },

  AngleFormat: 1, // 0 -> deg, 1 -> DM, 2 -> DMS
  AngleFormats: {
    Selection: '.AngleFormat',
    Units: [ '°', '', '' ],
    Formats: [ 'prec', 'dm', 'dms' ],
  },

  Comp_RefrCoeff_from_LightCurve: function( lightCurve ) {
    return lightCurve * 6371000;
  },

  Comp_LightCurve_from_RefrCoeff: function( refrCoeff ) {
    return refrCoeff / 6371000;
  },

  Comp_LightCurve_from_Pressure_TempC_TempGrad: function( pressure, tempC, tempGrad ) {
    return 7.895e-5 * pressure / Math.pow( tempC + 273.15, 2 ) * (0.0343 + tempGrad);
  },

  Comp_TempGrad_from_LightCurve_Pressure_TempC: function( lightCurve, pressure, tempC ) {
    var tempAbs = tempC + 273.15;
    return (lightCurve * tempAbs * tempAbs) / (7.895e-5 * pressure) - 0.0343;
  },

  Comp_LightRad_from_LightCurve: function( lightCurve ) {	
    return 1 / lightCurve;	
  },	
 	
  Comp_LightCurve_from_LightRad: function( lightRad ) {	
    return 1 / lightRad;	
  },	
 
  Comp_Pressure_from_ObsHeight: function( obsHeight ) {
    var g = 9.80665;
    var Rs = 287.058;
    var alpha = -0.0065;
    var Tref = 288.15;
    var Pref = 1013.25;
    var beta = g / Rs / alpha;
    var p = Pref * Math.pow( (Tref + alpha * obsHeight) / Tref, -beta );
    return p;
  },

  Comp_R_from_ObsHeight_DipAngle_LightCurve: function( obsHeight, dipAngleDeg, lightCurve ) {
    var cosDip = Math.cos( dipAngleDeg * Math.PI / 180 );
    return (obsHeight* cosDip - 0.5 * lightCurve * obsHeight * obsHeight) / (lightCurve * obsHeight + 1 - cosDip);
  },

  Comp_FeMntHeight_from_Alpha_Beta_DistAB: function( alpha, beta, distAB ) {
    var tanAlpha = Math.tan( alpha * Math.PI / 180 );
    var tanBeta  = Math.tan( beta  * Math.PI / 180 );
    var h = distAB * tanAlpha * tanBeta / (tanAlpha - tanBeta);
    return h;
  },

  Comp_GlobeMntHeight_from_Alpha_Beta_DistAB_MntRefrCoeff: function( alpha, beta, distAB, refrCoeff ) {
    // note: using the refracted curvature of earth CRrefr rather than the refracted radius of curvature R'
    // prevents divisions by zero for k = 1
    var R = 6371000;
    var CRrefr = (1 - refrCoeff) / R;
    var tanAlpha = Math.tan( alpha * Math.PI / 180 );
    var tanBeta  = Math.tan( beta  * Math.PI / 180 );
    var x = distAB * (tanBeta + 0.5 * distAB * CRrefr) / (tanAlpha - tanBeta - distAB * CRrefr);
    var h = x * tanAlpha + x*x * CRrefr / 2;
    return h;
  },

  Comp: function( resultName, argNames ) {
    var funcName = 'Comp_' + resultName + '_from';
    var means = [];
    var tols = [];
    var nArgs = argNames.length;
    for (var i = 0; i < nArgs; i++) {
      funcName += '_' + argNames[i];
      means[i] = this[argNames[i]];
      tols[i]  = this[argNames[i]+'AbsTol'];
    }
    var result = ComputeMeanAndTolerance( this[funcName], means, tols );
    this[resultName] = result.exact;
    this[resultName+'AbsTol'] = result.tolerance;
    this[resultName+'RelTol'] = 100 * Math.abs( result.tolerance / this[resultName] );
    return result.mean;
  },

  Update: function( field ) {

    function allNames( namesStr ) {
      // returns expanded namesStr to include all names + their tolerances
      // e.g. namesStr = 'DipAngle' -> 'DipAngle,DipAngleAbsTol,DipAngleRelTol'
      var names = namesStr.split( ',' );
      var all = [];
      for (var i = 0; i < names.length; i++) {
        all.push( names[i] );
        all.push( names[i]+'AbsTol' );
        all.push( names[i]+'RelTol' );
      }
      return all.join( ',' );
    }

    var fieldNames = [ 
      'Pressure'  , 'TempC'   , 'TempGrad' , 
      'LightCurve', 'LightRad', 'RefrCoeff', 
      'ObsHeight' , 'DipAngle', 'MntRefrCoeff',
      'Alpha'     , 'Beta'    , 'DistAB' 
    ];

    // convert relative tolerance entries to absolute tolerances

    if (xDef(field)) {
      for (var i = 0; i < fieldNames.length; i++) {
        if (ControlPanels.MatchesField( field, fieldNames[i]+'RelTol' )) {
          this[fieldNames[i]+'AbsTol'] = this[fieldNames[i]+'RelTol'] * Math.abs(this[fieldNames[i]]) / 100;
        }
      }
    }

    // if observer height is changed, calculate and set the pressure according the international standard atmosphere
    // the tolerances are kept untouched

    if (ControlPanels.MatchesField( field, 'ObsHeight' )) {
      this.Pressure = this.Comp_Pressure_from_ObsHeight( this.ObsHeight );
    }

    // when refraction coeff, light curvature or light radius is changes, compute temperature gradient from it
    // keeping pressure and absolute temperature constant

    if (xDef(field) && ControlPanels.MatchesField( field, allNames('RefrCoeff,LightCurve,LightRad') )) {

      if (ControlPanels.MatchesField( field, allNames('LightRad') )) {
        this.Comp( 'LightCurve', [ 'LightRad' ] );
        this.Comp( 'RefrCoeff', [ 'LightCurve' ] );
      }

      if (ControlPanels.MatchesField( field, allNames('LightCurve') )) {
        this.Comp( 'RefrCoeff', [ 'LightCurve' ] );
      }

      if (ControlPanels.MatchesField( field, allNames('RefrCoeff') )) {
        this.Comp( 'LightCurve', [ 'RefrCoeff' ] );
      }

      this.Comp( 'TempGrad', [ 'LightCurve', 'Pressure', 'TempC' ] );

    } else {

      this.Comp( 'LightCurve', [ 'Pressure', 'TempC', 'TempGrad' ] );
      this.Comp( 'RefrCoeff', [ 'LightCurve' ] );

    }

    this.Comp( 'LightRad', [ 'LightCurve' ] );
    this.RMean = this.Comp( 'R', [ 'ObsHeight', 'DipAngle', 'LightCurve' ] );

    this.FeMntHeightMean    = this.Comp( 'FeMntHeight', [ 'Alpha', 'Beta', 'DistAB' ] );
    this.GlobeMntHeightMean = this.Comp( 'GlobeMntHeight', [ 'Alpha', 'Beta', 'DistAB', 'MntRefrCoeff' ] );

    this.GlobeFlatDiff       = this.GlobeMntHeight       - this.FeMntHeight;
    this.GlobeFlatDiffMean   = this.GlobeMntHeightMean   - this.FeMntHeightMean;
    this.GlobeFlatDiffAbsTol = this.GlobeMntHeightAbsTol - this.FeMntHeightAbsTol;
    this.GlobeFlatDiffRelTol = this.GlobeMntHeightRelTol - this.FeMntHeightRelTol;

    // compute relative tolerances for all values

    for (var i = 0; i < fieldNames.length; i++) {
      this[fieldNames[i]+'RelTol'] = 100 * Math.abs( this[fieldNames[i]+'AbsTol'] / this[fieldNames[i]] );
    }

    ControlPanels.Update();
    
  },

};

xOnLoad( AlBiruniModel.Update() );


ControlPanels.NewPanel( {
  Name: 'UnitsPanel',
  ModelRef: 'AlBiruniModel',
  NCols: 2,
  OnModelChange: function(field){ AlBiruniModel.Update(field); },

} ).AddHeader( {
  Text: 'Choose the Units and Angle Formats for the Calculators',
  ColSpan: 4,

} ).AddRadiobuttonField( {
  Name: 'UnitsType',
  Label: 'Lengths',
  ValueType: 'int',
  Items: [
    {
      Name: 'km/m (Metric)',
      Value: 0
    }, {
      Name: 'mi/ft (Imp)',
      Value: 1
    }, {
      Name: 'ft/ft (Imp)',
      Value: 2
    }
  ]

} ).AddRadiobuttonField( {
  Name: 'AngleFormat',
  Label: 'Angles',
  ValueType: 'int',
  Items: [
    {
      Name: 'deg.',
      Value: 0
    }, {
      Name: 'DM',
      Value: 1
    }, {
      Name: 'DMS',
      Value: 2
    }
  ]

} ).Render();


ControlPanels.NewPanel( { 
  Name: 'InputAlBiruniParametersPanel',
  ModelRef: 'AlBiruniModel',
  NCols: 3, 
  OnModelChange: function(field){ AlBiruniModel.Update(field) }, 
  Format: 'fix0', 
  Digits: 2,
  FormatTab: true,
  ReadOnly: false, 
  PanelFormat: 'InputNormalWidth'

} ).AddHeader( {
  Text: 'Measured Parameters',
  ColSpan: 3,

} ).AddHeader( {
  Text: 'Tolerances Absolute',
  ColSpan: 2,

} ).AddHeader( {
  Text: 'Tolerances Relative',
  ColSpan: 1,

} ).AddTextField( {
  Name: 'ObsHeight',
  Label: 'Observer Height h',
  UnitsData: 'HeightUnits',
  Inc: 10,
  LowerLimit: 0,
  UpperLimit: 11000,

} ).AddTextField( {
  Name: 'ObsHeightAbsTol',
  Label: '+/-',
  UnitsData: 'HeightUnits',
  Inc: 0.1,
  LowerLimit: 0,
  UpperLimit: 11000,

} ).AddTextField( {
  Name: 'ObsHeightRelTol',
  Label: '+/-',
  Units: '%',
  Inc: 1,
  LowerLimit: 0,
  UpperLimit: 100,

} ).AddTextField( {
  Name: 'DipAngle',
  Label: 'Dip Angle &alpha;',
  InputFormat: 'dms',
  Format: 'dms',
  UnitsData: 'AngleFormats',
  Digits: 4,
  Inc: 0.05,
  LowerLimit: -45,
  UpperLimit: 45,

} ).AddTextField( {
  Name: 'DipAngleAbsTol',
  Label: '+/-',
  InputFormat: 'dms',
  Format: 'dms',
  UnitsData: 'AngleFormats',
  Digits: 4,
  Inc: 0.005,
  LowerLimit: 0,
  UpperLimit: 45,

} ).AddTextField( {
  Name: 'DipAngleRelTol',
  Label: '+/-',
  Units: '%',
  Inc: 1,
  LowerLimit: 0,
  UpperLimit: 100,

} ).AddTextField( {
  Name: 'Pressure',
  Label: 'Pressure P',
  Units: 'mbar',
  Inc: 1,
  LowerLimit: 200,
  UpperLimit: 1200,

} ).AddTextField( {
  Name: 'PressureAbsTol',
  Label: '+/-',
  Units: 'mbar',
  Inc: 0.1,
  LowerLimit: 0,
  UpperLimit: 1200,

} ).AddTextField( {
  Name: 'PressureRelTol',
  Label: '+/-',
  Units: '%',
  Inc: 1,
  LowerLimit: 0,
  UpperLimit: 100,

} ).AddTextField( {
  Name: 'TempC',
  Label: 'Temperature T',
  Units: '°C',
  Inc: 1,
  LowerLimit: -100,
  UpperLimit: 100,

} ).AddTextField( {
  Name: 'TempCAbsTol',
  Label: '+/-',
  Units: '°C',
  Inc: 0.1,
  LowerLimit: 0,
  UpperLimit: 100,

} ).AddTextField( {
  Name: 'TempCRelTol',
  Label: '+/-',
  Units: '%',
  Inc: 1,
  LowerLimit: 0,
  UpperLimit: 100,

} ).AddTextField( {
  Name: 'TempGrad',
  Label: 'Gradient dT/dh',
  UnitsData: 'GradientUnits',
  Digits: 5,
  Inc: 0.0005,
  LowerLimit: -1,
  UpperLimit: 1,

} ).AddTextField( {
  Name: 'TempGradAbsTol',
  Label: '+/-',
  UnitsData: 'GradientUnits',
  Digits: 5,
  Inc: 0.00005,
  LowerLimit: 0,
  UpperLimit: 1,

} ).AddTextField( {
  Name: 'TempGradRelTol',
  Label: '+/-',
  Units: '%',
  Inc: 1,
  LowerLimit: 0,
  UpperLimit: 100,

} ).AddTextField( {
  Name: 'RefrCoeff',
  Label: 'Refraction k',
  Units: '',
  Digits: 3,
  Inc: 0.01,
  LowerLimit: -10,
  UpperLimit: 10,

} ).AddTextField( {
  Name: 'RefrCoeffAbsTol',
  Label: '+/-',
  Units: '',
  Digits: 3,
  Inc: 0.001,
  LowerLimit: 0,
  UpperLimit: 10,

} ).AddTextField( {
  Name: 'RefrCoeffRelTol',
  Label: '+/-',
  Units: '%',
  Inc: 1,
  LowerLimit: 0,
  UpperLimit: 100,

} ).AddTextField( {
  Name: 'LightRad',
  Label: 'Light Radius r',
  UnitsData: 'BigLengthUnits',
  Inc: 1000,

} ).AddTextField( {
  Name: 'LightRadAbsTol',
  Label: '+/-',
  UnitsData: 'BigLengthUnits',
  Inc: 100,
  LowerLimit: 0,

} ).AddTextField( {
  Name: 'LightRadRelTol',
  Label: '+/-',
  Units: '%',
  Inc: 1,
  LowerLimit: 0,
  UpperLimit: 100,

} ).AddTextField( {
  Name: 'LightCurve',
  Label: 'Light Curve c',
  UnitsData: 'InvLengthUnits',
  Format: 'sci',
  Inc: 1e-9,
  LowerLimit: -1e-6,
  UpperLimit: 1e-6,

} ).AddTextField( {
  Name: 'LightCurveAbsTol',
  Label: '+/-',
  UnitsData: 'InvLengthUnits',
  Format: 'sci',
  Inc: 1e-10,
  LowerLimit: 0,
  UpperLimit: 1e-6,

} ).AddTextField( {
  Name: 'LightCurveRelTol',
  Label: '+/-',
  Units: '%',
  Inc: 1,
  LowerLimit: 0,
  UpperLimit: 100,

} ).Render();


ControlPanels.NewPanel( { 
  Name: 'OutputRadiusOfEarthPanel',
  ModelRef: 'AlBiruniModel',
  NCols: 4, 
  OnModelChange: function(field){ AlBiruniModel.Update(field) }, 
  FormatTab: true,
  Format: 'fix0', 
  Digits: 2,
  ReadOnly: true, 
  PanelFormat: 'InputSmallerWidth'

} ).AddHeader( {
  Text: 'Result',
  ColSpan: 1,

} ).AddHeader( {
  Text: 'Exact',
  ColSpan: 2,

} ).AddHeader( {
  Text: 'Mean',
  ColSpan: 2,

} ).AddHeader( {
  Text: 'Accuracy Absolute',
  ColSpan: 2,

} ).AddHeader( {
  Text: 'Accuracy Relative',
  ColSpan: 1,

} ).AddTextField( {
  Name: 'R',
  Label: 'Radius Earth R',
  UnitsData: 'BigLengthUnits',

} ).AddTextField( {
  Name: 'RMean',
  Label: '',
  UnitsData: 'BigLengthUnits',

} ).AddTextField( {
  Name: 'RAbsTol',
  Label: '+/-',
  UnitsData: 'BigLengthUnits',

} ).AddTextField( {
  Name: 'RRelTol',
  Label: '+/-',
  Units: '%',

} ).Render();


//// Mountain Calculator Panel ////

ControlPanels.NewPanel( { 
  Name: 'InputMountainHeightParametersPanel',
  ModelRef: 'AlBiruniModel',
  NCols: 3, 
  OnModelChange: function(field){ AlBiruniModel.Update(field) }, 
  Format: 'fix0', 
  Digits: 2,
  FormatTab: true,
  ReadOnly: false, 
  PanelFormat: 'InputNormalWidth'

} ).AddHeader( {
  Text: 'Mountain Measurements',
  ColSpan: 3,

} ).AddHeader( {
  Text: 'Tolerances Absolute',
  ColSpan: 2,

} ).AddHeader( {
  Text: 'Tolerances Relative',
  ColSpan: 1,

} ).AddTextField( {
  Name: 'DistAB',
  Label: 'Distance AB',
  UnitsData: 'LengthUnits',
  Digits: 3,
  Inc: 10,
  LowerLimit: 0,
  UpperLimit: 11000,

} ).AddTextField( {
  Name: 'DistABAbsTol',
  Label: '+/-',
  UnitsData: 'LengthUnits',
  Digits: 3,
  Inc: 0.1,
  LowerLimit: 0,
  UpperLimit: 11000,

} ).AddTextField( {
  Name: 'DistABRelTol',
  Label: '+/-',
  Units: '%',
  Inc: 1,
  LowerLimit: 0,
  UpperLimit: 100,

} ).AddTextField( {
  Name: 'Alpha',
  Label: 'Angle &alpha; at A',
  InputFormat: 'dms',
  Format: 'dms',
  UnitsData: 'AngleFormats',
  Digits: 4,
  Inc: 1,
  LowerLimit: 0,
  UpperLimit: 90,

} ).AddTextField( {
  Name: 'AlphaAbsTol',
  Label: '+/-',
  InputFormat: 'dms',
  Format: 'dms',
  UnitsData: 'AngleFormats',
  Digits: 4,
  Inc: 0.005,
  LowerLimit: 0,
  UpperLimit: 45,

} ).AddTextField( {
  Name: 'AlphaRelTol',
  Label: '+/-',
  Units: '%',
  Inc: 1,
  LowerLimit: 0,
  UpperLimit: 100,

} ).AddTextField( {
  Name: 'Beta',
  Label: 'Angle &beta; at B',
  InputFormat: 'dms',
  Format: 'dms',
  UnitsData: 'AngleFormats',
  Digits: 4,
  Inc: 1,
  LowerLimit: 0,
  UpperLimit: 90,

} ).AddTextField( {
  Name: 'BetaAbsTol',
  Label: '+/-',
  InputFormat: 'dms',
  Format: 'dms',
  UnitsData: 'AngleFormats',
  Digits: 4,
  Inc: 0.005,
  LowerLimit: 0,
  UpperLimit: 45,

} ).AddTextField( {
  Name: 'BetaRelTol',
  Label: '+/-',
  Units: '%',
  Inc: 1,
  LowerLimit: 0,
  UpperLimit: 100,

} ).AddTextField( {
  Name: 'MntRefrCoeff',
  Label: 'Refraction k',
  Units: '',
  Digits: 3,
  Inc: 0.01,
  LowerLimit: -10,
  UpperLimit: 10,

} ).AddTextField( {
  Name: 'MntRefrCoeffAbsTol',
  Label: '+/-',
  Units: '',
  Digits: 3,
  Inc: 0.001,
  LowerLimit: 0,
  UpperLimit: 10,

} ).AddTextField( {
  Name: 'MntRefrCoeffRelTol',
  Label: '+/-',
  Units: '%',
  Inc: 1,
  LowerLimit: 0,
  UpperLimit: 100,

} ).Render();


ControlPanels.NewPanel( { 
  Name: 'OutputMountainHeightPanel',
  ModelRef: 'AlBiruniModel',
  NCols: 4, 
  OnModelChange: function(field){ AlBiruniModel.Update(field) }, 
  FormatTab: true,
  Format: 'fix0', 
  Digits: 3,
  ReadOnly: true, 
  PanelFormat: 'InputSmallerWidth'

} ).AddHeader( {
  Text: 'Mount. H',
  ColSpan: 1,

} ).AddHeader( {
  Text: 'Exact',
  ColSpan: 2,

} ).AddHeader( {
  Text: 'Mean',
  ColSpan: 2,

} ).AddHeader( {
  Text: 'Accuracy Absolute',
  ColSpan: 2,

} ).AddHeader( {
  Text: 'Accuracy Relative',
  ColSpan: 1,

} ).AddTextField( {
  Name: 'FeMntHeight',
  Label: 'Flat Earth',
  UnitsData: 'HeightUnits',

} ).AddTextField( {
  Name: 'FeMntHeightMean',
  Label: '',
  UnitsData: 'HeightUnits',

} ).AddTextField( {
  Name: 'FeMntHeightAbsTol',
  Label: '+/-',
  UnitsData: 'HeightUnits',

} ).AddTextField( {
  Name: 'FeMntHeightRelTol',
  Label: '+/-',
  Units: '%',

} ).AddTextField( {
  Name: 'GlobeMntHeight',
  Label: 'Globe Earth',
  UnitsData: 'HeightUnits',

} ).AddTextField( {
  Name: 'GlobeMntHeightMean',
  Label: '',
  UnitsData: 'HeightUnits',

} ).AddTextField( {
  Name: 'GlobeMntHeightAbsTol',
  Label: '+/-',
  UnitsData: 'HeightUnits',

} ).AddTextField( {
  Name: 'GlobeMntHeightRelTol',
  Label: '+/-',
  Units: '%',

} ).AddTextField( {
  Name: 'GlobeFlatDiff',
  Label: 'Globe - Flat',
  UnitsData: 'HeightUnits',

} ).AddTextField( {
  Name: 'GlobeFlatDiffMean',
  Label: '',
  UnitsData: 'HeightUnits',

} ).AddTextField( {
  Name: 'GlobeFlatDiffAbsTol',
  Label: '+/-',
  UnitsData: 'HeightUnits',

} ).AddTextField( {
  Name: 'GlobeFlatDiffRelTol',
  Label: '+/-',
  Units: '%',

} ).Render();

</jscript>

More Page Infos / Sitemap
Created Tuesday, August 1, 2023
Scroll to Top of Page
Changed Friday, September 1, 2023