Repository: shashwatak/satellite-js
Pull request #122: Added function `json2satrec` in `io.js`
Author: login: spacenewb
Labels: name: enhancement
Created: 2023-08-15T13:58:08Z | Merged: 2025-03-19T08:21:28Z

Added function `json2satrec` in `io.js` to initialise `sgp4init` object and build `satrec` object from OMM data in JSON format. Ref: [A New Way to Obtain GP Data (aka TLEs)](https://celestrak.org/NORAD/documentation/gp-data-formats.php).

This is the new way of distributing TLEs and would become the new standard soon. It is better to port our functions slowly for compatibility.

#105 


Diff:
diff --git a/src/constants.js b/src/constants.js
index de5f5b5..7bffd1f 100644
--- a/src/constants.js
+++ b/src/constants.js
@@ -13,3 +13,4 @@ export const j3 = -0.00000253881;
 export const j4 = -0.00000165597;
 export const j3oj2 = j3 / j2;
 export const x2o3 = 2.0 / 3.0;
+export const xpdotp = 1440.0 / (2.0 * pi); // 229.1831180523293;
\ No newline at end of file
diff --git a/src/index.js b/src/index.js
index 514becb..06456e0 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,7 +1,7 @@
 import * as constants from './constants';
 
 import { jday, invjday } from './ext';
-import twoline2satrec from './io';
+import { twoline2satrec, json2satrec} from './io';
 import { propagate, sgp4, gstime } from './propagation';
 
 import dopplerFactor from './dopplerFactor';
@@ -20,6 +20,8 @@ import {
   ecfToLookAngles,
 } from './transforms';
 
+import { sunPos } from './sun';
+
 export {
   constants,
 
@@ -27,6 +29,7 @@ export {
   propagate,
   sgp4,
   twoline2satrec,
+  json2satrec,
 
   gstime,
   jday,
@@ -46,4 +49,7 @@ export {
   eciToEcf,
   ecfToEci,
   ecfToLookAngles,
+
+  // Sun Position
+  sunPos,
 };
diff --git a/src/indexUmd.js b/src/indexUmd.js
index fa32177..21a9a7a 100644
--- a/src/indexUmd.js
+++ b/src/indexUmd.js
@@ -1,7 +1,7 @@
 import * as constants from './constants';
 
 import { jday, invjday } from './ext';
-import twoline2satrec from './io';
+import { twoline2satrec, json2satrec} from './io';
 import { propagate, sgp4, gstime } from './propagation';
 
 import dopplerFactor from './dopplerFactor';
@@ -27,6 +27,7 @@ export default {
   propagate,
   sgp4,
   twoline2satrec,
+  json2satrec,
 
   gstime,
   jday,
diff --git a/src/io.js b/src/io.js
index d7e6758..2bc132d 100644
--- a/src/io.js
+++ b/src/io.js
@@ -1,4 +1,4 @@
-import { pi, deg2rad } from './constants';
+import { deg2rad, xpdotp } from './constants';
 
 import { jday, days2mdhms } from './ext';
 
@@ -6,7 +6,7 @@ import sgp4init from './propagation/sgp4init';
 
 /* -----------------------------------------------------------------------------
  *
- *                           function twoline2rv
+ *                           function twoline2satrec
  *
  *  this function converts the two line element set character string data to
  *    variables and initializes the sgp4 variables. several intermediate varaibles
@@ -59,9 +59,8 @@ import sgp4init from './propagation/sgp4init';
  * to the algorithm.  If you want to turn some of these off and go
  * back into "afspc" mode, then set `afspc_mode` to `True`.
  */
-export default function twoline2satrec(longstr1, longstr2) {
+export function twoline2satrec(longstr1, longstr2) {
   const opsmode = 'i';
-  const xpdotp = 1440.0 / (2.0 * pi); // 229.1831180523293;
   let year = 0;
 
   const satrec = {};
@@ -146,3 +145,93 @@ export default function twoline2satrec(longstr1, longstr2) {
 
   return satrec;
 }
+
+/* -----------------------------------------------------------------------------
+ *
+ *                           function json2satrec
+ *
+ *  this function converts the OMM json data to variables and initializes the sgp4 
+ *    variables. several intermediate varaibles and quantities are determined. note 
+ *    that the result is a structure so multiple satellites can be processed 
+ *    simultaneously without having to reinitialize. the verification mode is an 
+ *    important option that permits quick checks of any changes to the underlying 
+ *    technical theory. this option works using a modified tle file in which the 
+ *    start, stop, and delta time values are included at the end of the second line
+ *    of data. this only works with the verification mode. the catalog mode simply 
+ *    propagates from -1440 to 1440 min from epoch and is useful when performing 
+ *    entire catalog runs.
+ *
+ *  author        : Hariharan Vitaladevuni                   18 Aug 2023
+ *                  Theodore Kruczek                         19 Aug 2023
+ *
+ *  inputs        :
+ *    jsonobj     - OMM json data
+ *    opsmode     - mode of operation afspc or improved 'a', 'i'. Default: 'i'.
+ *
+ *  outputs       :
+ *    satrec      - structure containing all the sgp4 satellite information
+ *
+ *  coupling      :
+ *    days2mdhms  - conversion of days to month, day, hour, minute, second
+ *    jday        - convert day month year hour minute second into julian date
+ *    sgp4init    - initialize the sgp4 variables
+ * 
+ *  warning       : the epoch date in OMM format is more accurate than TLE format!
+ *                  this will result in extremely close, but different 
+ *                  position/velocity values. Depending on your use case, it may
+ *                  be better to use twoline2satrec, but for the average user this
+ *                  will provide comparable results.
+ *
+ *  references    :
+ *    https://celestrak.org/NORAD/documentation/gp-data-formats.php
+ --------------------------------------------------------------------------- */
+export function json2satrec(jsonobj, opsmode = 'i') {
+  const satrec = {};
+  satrec.error = 0;
+
+  satrec.satnum = jsonobj.NORAD_CAT_ID.toString();
+
+  const epoch = new Date(jsonobj.EPOCH + 'Z');
+  const year = epoch.getUTCFullYear();
+
+  satrec.epochyr = Number(year.toString().slice(-2));
+  satrec.epochdays =
+    (epoch - new Date(Date.UTC(year, 0, 1, 0, 0, 0))) / (86400 * 1000) + 1;
+
+  satrec.ndot = jsonobj.MEAN_MOTION_DOT;
+  satrec.nddot = jsonobj.MEAN_MOTION_DDOT;
+  satrec.bstar = jsonobj.BSTAR;
+
+  satrec.inclo = jsonobj.INCLINATION * deg2rad;
+  satrec.nodeo = jsonobj.RA_OF_ASC_NODE * deg2rad;
+  satrec.ecco = jsonobj.ECCENTRICITY;
+  satrec.argpo = jsonobj.ARG_OF_PERICENTER * deg2rad;
+  satrec.mo = jsonobj.MEAN_ANOMALY * deg2rad;
+  satrec.no = jsonobj.MEAN_MOTION / xpdotp;
+
+  // ----------------------------------------------------------------
+  // find sgp4epoch time of element set
+  // remember that sgp4 uses units of days from 0 jan 1950 (sgp4epoch)
+  // and minutes from the epoch (time)
+  // ----------------------------------------------------------------
+  const mdhmsResult = days2mdhms(year, satrec.epochdays);
+
+  const { mon, day, hr, minute, sec } = mdhmsResult;
+  satrec.jdsatepoch = jday(year, mon, day, hr, minute, sec);
+
+  //  ---------------- initialize the orbit at sgp4epoch -------------------
+  sgp4init(satrec, {
+    opsmode,
+    satn: satrec.satnum,
+    epoch: satrec.jdsatepoch - 2433281.5,
+    xbstar: satrec.bstar,
+    xecco: satrec.ecco,
+    xargpo: satrec.argpo,
+    xinclo: satrec.inclo,
+    xmo: satrec.mo,
+    xno: satrec.no,
+    xnodeo: satrec.nodeo,
+  });
+
+  return satrec;
+}
diff --git a/src/sun.js b/src/sun.js
new file mode 100644
index 0000000..9bec6a5
--- /dev/null
+++ b/src/sun.js
@@ -0,0 +1,145 @@
+import { deg2rad, twoPi } from './constants';
+
+////////////////////////////////////////////////////////////////////////////////////
+/* Line by Line MATLAB-to-Javascript conversion of "sun.mat" from Vallado package */
+////////////////////////////////////////////////////////////////////////////////////
+/* -----------------------------------------------------------------------------
+ *
+ *                              function sunPos
+ *
+ *  this function calculates the geocentric equatorial position vector
+ *      the sun given the julian date.  this is the low precision formula and
+ *      is valid for years from 1950 to 2050.  accuaracy of apparent coordinates
+ *      is 0.01  degrees.  notice many of the calculations are performed in
+ *      degrees, and are not changed until later.  this is due to the fact that
+ *      the almanac uses degrees exclusively in their formulations.
+ * 
+ *  author        : david vallado                  719-573-2600    1 mar 2001
+ * 
+ *  inputs          description                       range / units
+ *      jd          - julian date                       days from 4713 bc
+ * 
+ *  outputs       :
+ *      rsun        - ijk position vector of the sun    au
+ *      rtasc       - right ascension                   rad
+ *      decl        - declination                       rad
+ * 
+ *  coupling      :
+ *      -
+ * 
+ *  references    :
+ *      VALLADO, DAVID A. (2022) ‘Computer software in MATLAB’, in Fundamentals of astrodynamics and applications. 5th edn.
+ *      Computer software in MATLAB: http://celestrak.org/software/vallado-sw.php 
+ *  --------------------------------------------------------------------------- */
+
+export function sunPos(jd) {
+  
+    // -------------------------  implementation   -----------------
+    // -------------------  initialize values   --------------------
+    const tut1 = ( jd - 2451545.0  ) / 36525.0;
+  
+    const meanlong = (280.460  + 36000.77 * tut1) % 360.0; //deg
+  
+    const ttdb = tut1; // is this declaration required instead of replacing `ttdb` with `tut1`
+ 
+    if (meananomaly < 0.0 ) {
+        const meananomaly = twoPi + ((357.5277233  + 35999.05034 * ttdb) * deg2rad) % twoPi; //rad;
+    } else {
+        const meananomaly = ((357.5277233  + 35999.05034 * ttdb) * deg2rad) % twoPi; //rad;
+    }
+  
+    const eclplong_raw = ((meanlong + 1.914666471 * Math.sin(meananomaly) + 0.019994643 * Math.sin(2.0 * meananomaly)) % 360.0) * deg2rad; //rad
+  
+    const obliquity = (23.439291 - 0.0130042 * ttdb) * deg2rad; //rad
+  
+    // --------- find magnitude of sun vector, and it's components ------
+    const magr = 1.000140612  - 0.016708617 * Math.cos( meananomaly ) - 0.000139589 * Math.cos( 2.0 * meananomaly ); // in au's
+  
+    const rsun = [
+        magr*Math.cos(eclplong_raw), 
+        magr*Math.cos(obliquity)*Math.sin(eclplong_raw), 
+        magr*Math.sin(obliquity)*Math.sin(eclplong_raw)
+    ];
+  
+    const rtasc_raw = Math.atan( Math.cos(obliquity) * Math.tan(eclplong_raw) );
+  
+    // --- check that rtasc is in the same quadrant as eclplong_raw ----
+    if ( eclplong_raw < 0.0  ) {
+        const eclplong = eclplong_raw + twoPi;    // make sure it's in 0 to 2pi range
+    } else {
+        const eclplong = eclplong_raw;
+    }
+
+    if ( Math.abs( eclplong_raw - rtasc_raw ) > pi*0.5  ) {
+        const rtasc = rtasc_raw + 0.5 *pi*Math.round( (eclplong_raw - rtasc_raw)/(0.5 *pi));
+    } else {
+        const rtasc = rtasc_raw;
+    }
+    
+    const decl = Math.asin( Math.sin(obliquity) * Math.sin(eclplong_raw) );
+  
+    return {rsun, rtasc, decl}
+  }
+  
+  
+  /* Original MATLAB code for Sun position from Vallado package (sun.mat)  */
+  /*
+  function [rsun,rtasc,decl] = sun ( jd );
+  
+          twopi      =     2.0*pi;
+          deg2rad    =     pi/180.0;
+          show = 'n';
+  
+          % -------------------------  implementation   -----------------
+          % -------------------  initialize values   --------------------
+          tut1= ( jd - 2451545.0  )/ 36525.0;
+  
+          if show == 'y'
+              fprintf(1,'tut1 %14.9f \n',tut1);
+          end
+  
+          meanlong= 280.460  + 36000.77*tut1;
+          meanlong= rem( meanlong,360.0  );  %deg
+  
+          ttdb= tut1;
+          meananomaly= 357.5277233  + 35999.05034 *ttdb;
+          meananomaly= rem( meananomaly*deg2rad,twopi );  %rad
+          if ( meananomaly < 0.0  )
+              meananomaly= twopi + meananomaly;
+          end
+  
+          eclplong_raw= meanlong + 1.914666471 *sin(meananomaly) ...
+                      + 0.019994643 *sin(2.0 *meananomaly); %deg
+          eclplong_raw= rem( eclplong_raw,360.0  );  %deg
+  
+          obliquity= 23.439291  - 0.0130042 *ttdb;  %deg
+  
+          eclplong_raw = eclplong_raw *deg2rad;
+          obliquity= obliquity *deg2rad;
+  
+          % --------- find magnitude of sun vector, )   components ------
+          magr= 1.000140612  - 0.016708617 *cos( meananomaly ) ...
+                                - 0.000139589 *cos( 2.0 *meananomaly );    % in au's
+  
+          rsun(1)= magr*cos( eclplong_raw );
+          rsun(2)= magr*cos(obliquity)*sin(eclplong_raw);
+          rsun(3)= magr*sin(obliquity)*sin(eclplong_raw);
+  
+          if show == 'y'
+              fprintf(1,'meanlon %11.6f meanan %11.6f eclplon %11.6f obli %11.6f \n', ...
+                      meanlong,meananomaly/deg2rad,eclplong_raw/deg2rad,obliquity/deg2rad);
+              fprintf(1,'rs %11.9f %11.9f %11.9f \n',rsun);
+              fprintf(1,'magr %14.7f \n',magr);
+          end
+  
+          rtasc= atan( cos(obliquity)*tan(eclplong_raw) );
+  
+          % --- check that rtasc is in the same quadrant as eclplong_raw ----
+          if ( eclplong_raw < 0.0  )
+              eclplong_raw= eclplong_raw + twopi;    % make sure it's in 0 to 2pi range
+          end
+          if ( abs( eclplong_raw-rtasc ) > pi*0.5  )
+              rtasc= rtasc + 0.5 *pi*round( (eclplong_raw-rtasc)/(0.5 *pi));
+          end
+          decl = asin( sin(obliquity)*sin(eclplong_raw) );
+  */
diff --git a/test/ext.test.js b/test/ext.test.js
index 55308d8..43fd9b6 100644
--- a/test/ext.test.js
+++ b/test/ext.test.js
@@ -1,7 +1,7 @@
 import compareVectors from './compareVectors';
 
 import { jday, invjday } from '../src/ext';
-import twoline2satrec from '../src/io';
+import { twoline2satrec } from '../src/io';
 import { propagate, gstime } from '../src/propagation';
 
 describe('Julian date / time', () => {
diff --git a/test/index.test.js b/test/index.test.js
index c67adb1..4d2f010 100644
--- a/test/index.test.js
+++ b/test/index.test.js
@@ -17,7 +17,7 @@ import {
 } from '../src/constants';
 
 import { jday, invjday } from '../src/ext';
-import twoline2satrec from '../src/io';
+import { twoline2satrec, json2satrec } from '../src/io';
 import { propagate, sgp4, gstime } from '../src/propagation';
 
 import dopplerFactor from '../src/dopplerFactor';
@@ -74,6 +74,7 @@ function checkTransforms(transforms) {
 function checkExports(namespace) {
   it('constants', () => checkConstants(namespace.constants));
   it('twoline2satrec', () => expect(namespace.twoline2satrec).toEqual(twoline2satrec));
+  it('json2satrec', () => expect(namespace.json2satrec).toEqual(json2satrec));
   it('propagate', () => expect(namespace.propagate).toEqual(propagate));
   it('sgp4', () => expect(namespace.sgp4).toEqual(sgp4));
   it('gstime', () => expect(namespace.gstime).toEqual(gstime));
diff --git a/test/io-edge.json b/test/io-edge.json
new file mode 100644
index 0000000..7703447
--- /dev/null
+++ b/test/io-edge.json
@@ -0,0 +1,34 @@
+[
+  {
+    "tleLine1": "1 00001U 57001B   21005.53831292 -.00000083  00000-0 -11575-3 0  9996",
+    "tleLine2": "2 00001  34.2508 325.6936 1846988 181.8107 177.4919 00.00000000227203",
+    "description": "Mean motion is zero and that is not allowed.",
+    "results": [{
+      "error": 2
+    }]
+  },
+  {
+    "tleLine1": "1 00002U 57001B   21005.53831292 -.00000083  00000-0 -11575-3 0  9996",
+    "tleLine2": "2 00002  34.2508 325.6936 1846988 181.8107 177.4919 00.00000001227203",
+    "description": "Eccentricity is way too high because mean motion is nearly zero.",
+    "results": [{
+      "error": 3
+    }]
+  },
+  {
+    "tleLine1": "1 00004U 57001B   21005.53831292 -.00000083  00000-0 -11575-3 0  9996",
+    "tleLine2": "2 00004  34.2508 325.6936 9999999 181.8107 177.4919 10.84863720227203",
+    "description": "Eccentricity is way too high.",
+    "results": [{
+      "error": 4
+    }]
+  },
+  {
+    "tleLine1": "1 00006U 57001B   21005.53831292 -.00000083  00000-0 -11575-3 0  9996",
+    "tleLine2": "2 00005  34.2508 325.6936 1846988 181.8107 177.4919 25.84863720227203",
+    "description": "Satellite should be decayed already.",
+    "results": [{
+      "error": 6
+    }]
+  }
+]
\ No newline at end of file
diff --git a/test/io.json b/test/io.json
index 01adcfa..7be8a0c 100644
--- a/test/io.json
+++ b/test/io.json
@@ -1,34 +1,65 @@
 [
-  {
-    "tleLine1": "1 00001U 57001B   21005.53831292 -.00000083  00000-0 -11575-3 0  9996",
-    "tleLine2": "2 00001  34.2508 325.6936 1846988 181.8107 177.4919 00.00000000227203",
-    "description": "Mean motion is zero and that is not allowed.",
-    "results": [{
-      "error": 2
-    }]
-  },
-  {
-    "tleLine1": "1 00002U 57001B   21005.53831292 -.00000083  00000-0 -11575-3 0  9996",
-    "tleLine2": "2 00002  34.2508 325.6936 1846988 181.8107 177.4919 00.00000001227203",
-    "description": "Eccentricity is way too high because mean motion is nearly zero.",
-    "results": [{
-      "error": 3
-    }]
-  },
-  {
-    "tleLine1": "1 00004U 57001B   21005.53831292 -.00000083  00000-0 -11575-3 0  9996",
-    "tleLine2": "2 00004  34.2508 325.6936 9999999 181.8107 177.4919 10.84863720227203",
-    "description": "Mean motion is zero and that is not allowed.",
-    "results": [{
-      "error": 4
-    }]
-  },
-  {
-    "tleLine1": "1 00006U 57001B   21005.53831292 -.00000083  00000-0 -11575-3 0  9996",
-    "tleLine2": "2 00005  34.2508 325.6936 1846988 181.8107 177.4919 25.84863720227203",
-    "description": "Satellite should be decayed already.",
-    "results": [{
-      "error": 6
-    }]
-  }
+    {
+        "tleLine1": "1 25544U 98067A   23231.51768399  .00014050  00000+0  25837-3 0  9996",
+        "tleLine2": "2 25544  51.6415  14.7889 0003559 325.3396 149.4637 15.49477580411611",
+        "OBJECT_NAME": "ISS (ZARYA)",
+        "OBJECT_ID": "1998-067A",
+        "EPOCH": "2023-08-19T12:25:27.896736",
+        "MEAN_MOTION": 15.4947758,
+        "ECCENTRICITY": 0.0003559,
+        "INCLINATION": 51.6415,
+        "RA_OF_ASC_NODE": 14.7889,
+        "ARG_OF_PERICENTER": 325.3396,
+        "MEAN_ANOMALY": 149.4637,
+        "EPHEMERIS_TYPE": 0,
+        "CLASSIFICATION_TYPE": "U",
+        "NORAD_CAT_ID": 25544,
+        "ELEMENT_SET_NO": 999,
+        "REV_AT_EPOCH": 41161,
+        "BSTAR": 0.00025837,
+        "MEAN_MOTION_DOT": 0.0001405,
+        "MEAN_MOTION_DDOT": 0
+    },
+    {
+        "tleLine1": "1 00005U 58002B   23230.80643200  .00000051  00000+0  62145-4 0  9990",
+        "tleLine2": "2 00005  34.2442 262.2777 1845847 161.4568 206.3458 10.85081473331065",
+        "OBJECT_NAME": "VANGUARD 1",
+        "OBJECT_ID": "1958-002B",
+        "EPOCH": "2023-08-18T19:21:15.724800",
+        "MEAN_MOTION": 10.85081473,
+        "ECCENTRICITY": 0.1845847,
+        "INCLINATION": 34.2442,
+        "RA_OF_ASC_NODE": 262.2777,
+        "ARG_OF_PERICENTER": 161.4568,
+        "MEAN_ANOMALY": 206.3458,
+        "EPHEMERIS_TYPE": 0,
+        "CLASSIFICATION_TYPE": "U",
+        "NORAD_CAT_ID": 5,
+        "ELEMENT_SET_NO": 999,
+        "REV_AT_EPOCH": 33106,
+        "BSTAR": 6.2145e-5,
+        "MEAN_MOTION_DOT": 5.1e-7,
+        "MEAN_MOTION_DDOT": 0
+    },
+    {
+        "tleLine1": "1 00012U 59001B   23230.77689364  .00000551  00000+0  33029-3 0  9998",
+        "tleLine2": "2 00012  32.8964 259.3305 1659877  44.2337 327.9558 11.45746962655202",
+        "OBJECT_NAME": "VANGUARD R\/B",
+        "OBJECT_ID": "1959-001B",
+        "EPOCH": "2023-08-18T18:38:43.610496",
+        "MEAN_MOTION": 11.45746962,
+        "ECCENTRICITY": 0.1659877,
+        "INCLINATION": 32.8964,
+        "RA_OF_ASC_NODE": 259.3305,
+        "ARG_OF_PERICENTER": 44.2337,
+        "MEAN_ANOMALY": 327.9558,
+        "EPHEMERIS_TYPE": 0,
+        "CLASSIFICATION_TYPE": "U",
+        "NORAD_CAT_ID": 12,
+        "ELEMENT_SET_NO": 999,
+        "REV_AT_EPOCH": 65520,
+        "BSTAR": 0.00033029,
+        "MEAN_MOTION_DOT": 5.51e-6,
+        "MEAN_MOTION_DDOT": 0
+    }
 ]
\ No newline at end of file
diff --git a/test/io.test.js b/test/io.test.js
index 3fd58d5..ae7e407 100644
--- a/test/io.test.js
+++ b/test/io.test.js
@@ -1,14 +1,38 @@
-import twoline2satrec from '../src/io';
-import badTleData from './io.json';
+import { twoline2satrec, json2satrec } from '../src/io';
+import badTleData from './io-edge.json';
+import goodData from './io.json';
 
 describe('Twoline', () => {
-  it('twoline to satellite record', () => {
-    badTleData.forEach((tleDataItem) => {
-      const satrec = twoline2satrec(tleDataItem.tleLine1, tleDataItem.tleLine2);
-      tleDataItem.results.forEach((expected) => {
-        // Fetching satellite record from incorrectly formatted TLE lines
-        expect(satrec.error).toEqual(expected.error);
-      });
+    it('should convert twoline to satellite record', () => {
+        badTleData.forEach((tleDataItem) => {
+            const satrec = twoline2satrec(tleDataItem.tleLine1, tleDataItem.tleLine2);
+            tleDataItem.results.forEach((expected) => {
+                // Fetching satellite record from incorrectly formatted TLE lines
+                expect(satrec.error).toEqual(expected.error);
+            });
+        });
     });
-  });
 });
+
+describe('OMM Format Conversion', () => {
+    goodData.forEach(jsonObj => {
+        const satrec = json2satrec(jsonObj);
+        const origSatrec = twoline2satrec(jsonObj.tleLine1, jsonObj.tleLine2);
+        for (const prop in origSatrec) {
+            it(`should have a valid ${prop} property`, () => {
+                switch (prop) {
+                    case 'epochdays':
+                    case 'jdsatepoch':
+                        expect(satrec[prop]).toBeCloseTo(origSatrec[prop], 7);
+                        break;
+                    case 'gsto':
+                        expect(satrec[prop]).toBeCloseTo(origSatrec[prop], 6);
+                        break;
+                    default:
+                        expect(satrec[prop]).toEqual(origSatrec[prop]);
+                        break;
+                }
+            });
+        }
+    });
+})
\ No newline at end of file
diff --git a/test/propagation/sgp4Catalog.test.js b/test/propagation/sgp4Catalog.test.js
index 73bb810..d9bec95 100644
--- a/test/propagation/sgp4Catalog.test.js
+++ b/test/propagation/sgp4Catalog.test.js
@@ -2,7 +2,7 @@ import path from 'path';
 import fs from 'fs';
 
 import sgp4 from '../../src/propagation/sgp4';
-import twoline2satrec from '../../src/io';
+import { twoline2satrec } from '../../src/io';
 
 const satellitesPerTestSuite = 500;
 


Reviews:
user: login: thkruz
body: Overall I think this is in the right direction. It needs a little polish. I will try to find some time to write tests in the near future, but if anyone else can it would be great. We need to validate that it makes the same satrec object as the main function.
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2023-08-17T02:38:46Z
user: login: spacenewb
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2023-08-18T12:32:39Z
user: login: spacenewb
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2023-08-18T12:46:28Z
user: login: spacenewb
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2023-08-18T12:47:10Z
user: login: thkruz
body: Two minor corrections and then the only thing left to do is the jest testing. I am going to write them right now as a PR into your develop branch (as soon as I figure out how to deconflict yours with shashwatak's).
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2023-08-19T17:01:22Z
user: login: thkruz
body: @ezze this looks good to me at this point. It provides a valid method for using OMM format without causing any degradation to the current baseline.
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2023-09-06T07:39:20Z
user: login: 1valdis
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-18T10:16:35Z
user: login: thkruz
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T11:00:26Z
user: login: 1valdis
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-18T11:09:41Z
user: login: 1valdis
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-18T20:09:36Z
user: login: thkruz
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T22:30:13Z

Review comments:
diff_hunk: @@ -146,3 +146,128 @@ export default function twoline2satrec(longstr1, longstr2) {
 
   return satrec;
 }
+
+/* -----------------------------------------------------------------------------
+ *
+ *                           function json2satrec
+ *
+ *  this function converts the OMM json data to variables and initializes the sgp4 
+ *    variables. several intermediate varaibles and quantities are determined. note 
+ *    that the result is a structure so multiple satellites can be processed 
+ *    simultaneously without having to reinitialize. the verification mode is an 
+ *    important option that permits quick checks of any changes to the underlying 
+ *    technical theory. this option works using a modified tle file in which the 
+ *    start, stop, and delta time values are included at the end of the second line
+ *    of data. this only works with the verification mode. the catalog mode simply 
+ *    propagates from -1440 to 1440 min from epoch and is useful when performing 
+ *    entire catalog runs.
+ *
+ *  author        : david vallado                  719-573-2600    1 mar 2001
path: src/io.js
user: login: thkruz
body: Update the author.
created_at: 2023-08-17T02:18:09Z
author_association: CONTRIBUTOR
diff_hunk: @@ -146,3 +146,128 @@ export default function twoline2satrec(longstr1, longstr2) {
 
   return satrec;
 }
+
+/* -----------------------------------------------------------------------------
+ *
+ *                           function json2satrec
+ *
+ *  this function converts the OMM json data to variables and initializes the sgp4 
+ *    variables. several intermediate varaibles and quantities are determined. note 
+ *    that the result is a structure so multiple satellites can be processed 
+ *    simultaneously without having to reinitialize. the verification mode is an 
+ *    important option that permits quick checks of any changes to the underlying 
+ *    technical theory. this option works using a modified tle file in which the 
+ *    start, stop, and delta time values are included at the end of the second line
+ *    of data. this only works with the verification mode. the catalog mode simply 
+ *    propagates from -1440 to 1440 min from epoch and is useful when performing 
+ *    entire catalog runs.
+ *
+ *  author        : david vallado                  719-573-2600    1 mar 2001
+ *
+ *  inputs        :
+ *    jsonobj     - OMM json data
+ *    typerun     - type of run                    verification 'v', catalog 'c',
+ *                                                 manual 'm'
+ *    typeinput   - type of manual input           mfe 'm', epoch 'e', dayofyr 'd'
path: src/io.js
user: login: thkruz
body: Only jsonobj variable is still used. You should remove reference to comments from the old function that no longer apply.
created_at: 2023-08-17T02:20:21Z
author_association: CONTRIBUTOR
diff_hunk: @@ -146,3 +146,128 @@ export default function twoline2satrec(longstr1, longstr2) {
 
   return satrec;
 }
+
+/* -----------------------------------------------------------------------------
+ *
+ *                           function json2satrec
+ *
+ *  this function converts the OMM json data to variables and initializes the sgp4 
+ *    variables. several intermediate varaibles and quantities are determined. note 
+ *    that the result is a structure so multiple satellites can be processed 
+ *    simultaneously without having to reinitialize. the verification mode is an 
+ *    important option that permits quick checks of any changes to the underlying 
+ *    technical theory. this option works using a modified tle file in which the 
+ *    start, stop, and delta time values are included at the end of the second line
+ *    of data. this only works with the verification mode. the catalog mode simply 
+ *    propagates from -1440 to 1440 min from epoch and is useful when performing 
+ *    entire catalog runs.
+ *
+ *  author        : david vallado                  719-573-2600    1 mar 2001
+ *
+ *  inputs        :
+ *    jsonobj     - OMM json data
+ *    typerun     - type of run                    verification 'v', catalog 'c',
+ *                                                 manual 'm'
+ *    typeinput   - type of manual input           mfe 'm', epoch 'e', dayofyr 'd'
+ *    opsmode     - mode of operation afspc or improved 'a', 'i'
+ *    whichconst  - which set of constants to use  72, 84
+ *
+ *  outputs       :
+ *    satrec      - structure containing all the sgp4 satellite information
+ *
+ *  coupling      :
+ *    getgravconst-
+ *    days2mdhms  - conversion of days to month, day, hour, minute, second
+ *    jday        - convert day month year hour minute second into julian date
+ *    sgp4init    - initialize the sgp4 variables
+ *
+ *  references    :
+ *    norad spacetrack report #3
path: src/io.js
user: login: thkruz
body: If you are going to keep references, I would add the reference to the omm format. Alternatively, just remove these old comments.
created_at: 2023-08-17T02:24:24Z
author_association: CONTRIBUTOR
diff_hunk: @@ -146,3 +146,128 @@ export default function twoline2satrec(longstr1, longstr2) {
 
   return satrec;
 }
+
+/* -----------------------------------------------------------------------------
+ *
+ *                           function json2satrec
+ *
+ *  this function converts the OMM json data to variables and initializes the sgp4 
+ *    variables. several intermediate varaibles and quantities are determined. note 
+ *    that the result is a structure so multiple satellites can be processed 
+ *    simultaneously without having to reinitialize. the verification mode is an 
+ *    important option that permits quick checks of any changes to the underlying 
+ *    technical theory. this option works using a modified tle file in which the 
+ *    start, stop, and delta time values are included at the end of the second line
+ *    of data. this only works with the verification mode. the catalog mode simply 
+ *    propagates from -1440 to 1440 min from epoch and is useful when performing 
+ *    entire catalog runs.
+ *
+ *  author        : david vallado                  719-573-2600    1 mar 2001
+ *
+ *  inputs        :
+ *    jsonobj     - OMM json data
+ *    typerun     - type of run                    verification 'v', catalog 'c',
+ *                                                 manual 'm'
+ *    typeinput   - type of manual input           mfe 'm', epoch 'e', dayofyr 'd'
+ *    opsmode     - mode of operation afspc or improved 'a', 'i'
+ *    whichconst  - which set of constants to use  72, 84
+ *
+ *  outputs       :
+ *    satrec      - structure containing all the sgp4 satellite information
+ *
+ *  coupling      :
+ *    getgravconst-
+ *    days2mdhms  - conversion of days to month, day, hour, minute, second
+ *    jday        - convert day month year hour minute second into julian date
+ *    sgp4init    - initialize the sgp4 variables
+ *
+ *  references    :
+ *    norad spacetrack report #3
+ *    vallado, crawford, hujsak, kelso  2006
+ --------------------------------------------------------------------------- */
+
+/**
+ * Return a Satellite imported from OMM JSON format data.
+ *
+ * Provide the OMM JSON format data as `jsonobj`,
+ * and select which standard set of gravitational constants you want
+ * by providing `gravity_constants`:
path: src/io.js
user: login: thkruz
body: Unclear if you can actually provide gravity constants or if this old comments too.
created_at: 2023-08-17T02:25:55Z
author_association: CONTRIBUTOR
diff_hunk: @@ -146,3 +146,128 @@ export default function twoline2satrec(longstr1, longstr2) {
 
   return satrec;
 }
+
+/* -----------------------------------------------------------------------------
+ *
+ *                           function json2satrec
+ *
+ *  this function converts the OMM json data to variables and initializes the sgp4 
+ *    variables. several intermediate varaibles and quantities are determined. note 
+ *    that the result is a structure so multiple satellites can be processed 
+ *    simultaneously without having to reinitialize. the verification mode is an 
+ *    important option that permits quick checks of any changes to the underlying 
+ *    technical theory. this option works using a modified tle file in which the 
+ *    start, stop, and delta time values are included at the end of the second line
+ *    of data. this only works with the verification mode. the catalog mode simply 
+ *    propagates from -1440 to 1440 min from epoch and is useful when performing 
+ *    entire catalog runs.
+ *
+ *  author        : david vallado                  719-573-2600    1 mar 2001
+ *
+ *  inputs        :
+ *    jsonobj     - OMM json data
+ *    typerun     - type of run                    verification 'v', catalog 'c',
+ *                                                 manual 'm'
+ *    typeinput   - type of manual input           mfe 'm', epoch 'e', dayofyr 'd'
+ *    opsmode     - mode of operation afspc or improved 'a', 'i'
+ *    whichconst  - which set of constants to use  72, 84
+ *
+ *  outputs       :
+ *    satrec      - structure containing all the sgp4 satellite information
+ *
+ *  coupling      :
+ *    getgravconst-
+ *    days2mdhms  - conversion of days to month, day, hour, minute, second
+ *    jday        - convert day month year hour minute second into julian date
+ *    sgp4init    - initialize the sgp4 variables
+ *
+ *  references    :
+ *    norad spacetrack report #3
+ *    vallado, crawford, hujsak, kelso  2006
+ --------------------------------------------------------------------------- */
+
+/**
+ * Return a Satellite imported from OMM JSON format data.
+ *
+ * Provide the OMM JSON format data as `jsonobj`,
+ * and select which standard set of gravitational constants you want
+ * by providing `gravity_constants`:
+ *
+ * `sgp4.propagation.wgs72` - Standard WGS 72 model
+ * `sgp4.propagation.wgs84` - More recent WGS 84 model
+ * `sgp4.propagation.wgs72old` - Legacy support for old SGP4 behavior
+ *
+ * Normally, computations are made using letious recent improvements
+ * to the algorithm.  If you want to turn some of these off and go
+ * back into "afspc" mode, then set `afspc_mode` to `True`.
path: src/io.js
user: login: thkruz
body: Improved mode is currently set no matter what. Comment should be updated or the option should be added as a parameter.
created_at: 2023-08-17T02:28:33Z
author_association: CONTRIBUTOR
diff_hunk: @@ -146,3 +146,128 @@ export default function twoline2satrec(longstr1, longstr2) {
 
   return satrec;
 }
+
+/* -----------------------------------------------------------------------------
+ *
+ *                           function json2satrec
+ *
+ *  this function converts the OMM json data to variables and initializes the sgp4 
+ *    variables. several intermediate varaibles and quantities are determined. note 
+ *    that the result is a structure so multiple satellites can be processed 
+ *    simultaneously without having to reinitialize. the verification mode is an 
+ *    important option that permits quick checks of any changes to the underlying 
+ *    technical theory. this option works using a modified tle file in which the 
+ *    start, stop, and delta time values are included at the end of the second line
+ *    of data. this only works with the verification mode. the catalog mode simply 
+ *    propagates from -1440 to 1440 min from epoch and is useful when performing 
+ *    entire catalog runs.
+ *
+ *  author        : david vallado                  719-573-2600    1 mar 2001
+ *
+ *  inputs        :
+ *    jsonobj     - OMM json data
+ *    typerun     - type of run                    verification 'v', catalog 'c',
+ *                                                 manual 'm'
+ *    typeinput   - type of manual input           mfe 'm', epoch 'e', dayofyr 'd'
+ *    opsmode     - mode of operation afspc or improved 'a', 'i'
+ *    whichconst  - which set of constants to use  72, 84
+ *
+ *  outputs       :
+ *    satrec      - structure containing all the sgp4 satellite information
+ *
+ *  coupling      :
+ *    getgravconst-
+ *    days2mdhms  - conversion of days to month, day, hour, minute, second
+ *    jday        - convert day month year hour minute second into julian date
+ *    sgp4init    - initialize the sgp4 variables
+ *
+ *  references    :
+ *    norad spacetrack report #3
+ *    vallado, crawford, hujsak, kelso  2006
+ --------------------------------------------------------------------------- */
+
+/**
+ * Return a Satellite imported from OMM JSON format data.
+ *
+ * Provide the OMM JSON format data as `jsonobj`,
+ * and select which standard set of gravitational constants you want
+ * by providing `gravity_constants`:
+ *
+ * `sgp4.propagation.wgs72` - Standard WGS 72 model
+ * `sgp4.propagation.wgs84` - More recent WGS 84 model
+ * `sgp4.propagation.wgs72old` - Legacy support for old SGP4 behavior
+ *
+ * Normally, computations are made using letious recent improvements
+ * to the algorithm.  If you want to turn some of these off and go
+ * back into "afspc" mode, then set `afspc_mode` to `True`.
+ */
+function json2satrec(jsonobj) {
+  const opsmode = 'i';
+  const xpdotp = 1440.0 / (2.0 * pi); // 229.1831180523293;
+  let year = 0;
+
+  const satrec = {};
+  satrec.error = 0;
+
+  satrec.satnum = jsonobj.NORAD_CAT_ID.toString();
+
+  var epoch = new Date(jsonobj.EPOCH + 'Z');
+  year = epoch.getUTCFullYear();
+
+  satrec.epochyr = Number(year.toString().slice(-2));
+  satrec.epochdays =
+    (epoch - new Date(Date.UTC(year, 0, 1, 0, 0, 0))) / (86400 * 1000) + 1;
+
+  satrec.ndot = jsonobj.MEAN_MOTION_DOT;
+  satrec.nddot = jsonobj.MEAN_MOTION_DDOT;
+  satrec.bstar = jsonobj.BSTAR;
+
+  satrec.inclo = jsonobj.INCLINATION;
+  satrec.nodeo = jsonobj.RA_OF_ASC_NODE;
+  satrec.ecco = jsonobj.ECCENTRICITY;
+  satrec.argpo = jsonobj.ARG_OF_PERICENTER;
+  satrec.mo = jsonobj.MEAN_ANOMALY;
+  satrec.no = jsonobj.MEAN_MOTION;
+
+  // ---- find no, ndot, nddot ----
+  satrec.no /= xpdotp; //   rad/min
+  // satrec.nddot= satrec.nddot * Math.pow(10.0, nexp);
+  // satrec.bstar= satrec.bstar * Math.pow(10.0, ibexp);
+
+  // ---- convert to sgp4 units ----
path: src/io.js
user: login: thkruz
body: Remove these legacy comments.
created_at: 2023-08-17T02:36:13Z
author_association: CONTRIBUTOR
diff_hunk: @@ -6,7 +6,7 @@ import sgp4init from './propagation/sgp4init';
 
 /* -----------------------------------------------------------------------------
  *
- *                           function twoline2rv
+ *                           function twoline2satrec
path: src/io.js
user: login: thkruz
body: Can you explain why you are updating the name? Did you update the comments above too?
created_at: 2023-08-17T02:38:01Z
author_association: CONTRIBUTOR
diff_hunk: @@ -6,7 +6,7 @@ import sgp4init from './propagation/sgp4init';
 
 /* -----------------------------------------------------------------------------
  *
- *                           function twoline2rv
+ *                           function twoline2satrec
path: src/io.js
user: login: spacenewb
body: Because classically, `rv` stands for satellite state vector: [rx, ry, rz, vx, vy, vz]. This represents the position and velocity in the x,y and z directions. But this function actually returns a `satrec` object. 

This is not the same as a satellite state vector. A `satrec` object is a dictionary containing all the `sgp4` satellite information [[sgp4io.cpp]](https://os.mbed.com/users/gradyhillhouse/code/SGP4_vallado/file/806c1dd6946c/sgp4io.cpp/).

I have not modified any other comments above. I figured that the old way on naming the function was not in-line with its modern interpretation of the term `rv` and `satrec`.
created_at: 2023-08-18T12:32:38Z
author_association: CONTRIBUTOR
diff_hunk: @@ -146,3 +146,128 @@ export default function twoline2satrec(longstr1, longstr2) {
 
   return satrec;
 }
+
+/* -----------------------------------------------------------------------------
+ *
+ *                           function json2satrec
+ *
+ *  this function converts the OMM json data to variables and initializes the sgp4 
+ *    variables. several intermediate varaibles and quantities are determined. note 
+ *    that the result is a structure so multiple satellites can be processed 
+ *    simultaneously without having to reinitialize. the verification mode is an 
+ *    important option that permits quick checks of any changes to the underlying 
+ *    technical theory. this option works using a modified tle file in which the 
+ *    start, stop, and delta time values are included at the end of the second line
+ *    of data. this only works with the verification mode. the catalog mode simply 
+ *    propagates from -1440 to 1440 min from epoch and is useful when performing 
+ *    entire catalog runs.
+ *
+ *  author        : david vallado                  719-573-2600    1 mar 2001
+ *
+ *  inputs        :
+ *    jsonobj     - OMM json data
+ *    typerun     - type of run                    verification 'v', catalog 'c',
+ *                                                 manual 'm'
+ *    typeinput   - type of manual input           mfe 'm', epoch 'e', dayofyr 'd'
+ *    opsmode     - mode of operation afspc or improved 'a', 'i'
+ *    whichconst  - which set of constants to use  72, 84
+ *
+ *  outputs       :
+ *    satrec      - structure containing all the sgp4 satellite information
+ *
+ *  coupling      :
+ *    getgravconst-
+ *    days2mdhms  - conversion of days to month, day, hour, minute, second
+ *    jday        - convert day month year hour minute second into julian date
+ *    sgp4init    - initialize the sgp4 variables
+ *
+ *  references    :
+ *    norad spacetrack report #3
+ *    vallado, crawford, hujsak, kelso  2006
+ --------------------------------------------------------------------------- */
+
+/**
+ * Return a Satellite imported from OMM JSON format data.
+ *
+ * Provide the OMM JSON format data as `jsonobj`,
+ * and select which standard set of gravitational constants you want
+ * by providing `gravity_constants`:
path: src/io.js
user: login: spacenewb
body: In this ported code, I cannot see the use of the gravity constants in any of the scorce code methods. Maybe this can be a new issue to be implemented.
created_at: 2023-08-18T12:46:27Z
author_association: CONTRIBUTOR
diff_hunk: @@ -146,3 +146,128 @@ export default function twoline2satrec(longstr1, longstr2) {
 
   return satrec;
 }
+
+/* -----------------------------------------------------------------------------
+ *
+ *                           function json2satrec
+ *
+ *  this function converts the OMM json data to variables and initializes the sgp4 
+ *    variables. several intermediate varaibles and quantities are determined. note 
+ *    that the result is a structure so multiple satellites can be processed 
+ *    simultaneously without having to reinitialize. the verification mode is an 
+ *    important option that permits quick checks of any changes to the underlying 
+ *    technical theory. this option works using a modified tle file in which the 
+ *    start, stop, and delta time values are included at the end of the second line
+ *    of data. this only works with the verification mode. the catalog mode simply 
+ *    propagates from -1440 to 1440 min from epoch and is useful when performing 
+ *    entire catalog runs.
+ *
+ *  author        : david vallado                  719-573-2600    1 mar 2001
+ *
+ *  inputs        :
+ *    jsonobj     - OMM json data
+ *    typerun     - type of run                    verification 'v', catalog 'c',
+ *                                                 manual 'm'
+ *    typeinput   - type of manual input           mfe 'm', epoch 'e', dayofyr 'd'
+ *    opsmode     - mode of operation afspc or improved 'a', 'i'
+ *    whichconst  - which set of constants to use  72, 84
+ *
+ *  outputs       :
+ *    satrec      - structure containing all the sgp4 satellite information
+ *
+ *  coupling      :
+ *    getgravconst-
+ *    days2mdhms  - conversion of days to month, day, hour, minute, second
+ *    jday        - convert day month year hour minute second into julian date
+ *    sgp4init    - initialize the sgp4 variables
+ *
+ *  references    :
+ *    norad spacetrack report #3
+ *    vallado, crawford, hujsak, kelso  2006
+ --------------------------------------------------------------------------- */
+
+/**
+ * Return a Satellite imported from OMM JSON format data.
+ *
+ * Provide the OMM JSON format data as `jsonobj`,
+ * and select which standard set of gravitational constants you want
+ * by providing `gravity_constants`:
+ *
+ * `sgp4.propagation.wgs72` - Standard WGS 72 model
+ * `sgp4.propagation.wgs84` - More recent WGS 84 model
+ * `sgp4.propagation.wgs72old` - Legacy support for old SGP4 behavior
+ *
+ * Normally, computations are made using letious recent improvements
+ * to the algorithm.  If you want to turn some of these off and go
+ * back into "afspc" mode, then set `afspc_mode` to `True`.
path: src/io.js
user: login: spacenewb
body: Changed that to accept `opsmode` as an input with default to 'i' (improved mode).
created_at: 2023-08-18T12:47:09Z
author_association: CONTRIBUTOR
diff_hunk: @@ -146,3 +146,102 @@ export default function twoline2satrec(longstr1, longstr2) {
 
   return satrec;
 }
+
+/* -----------------------------------------------------------------------------
+ *
+ *                           function json2satrec
+ *
+ *  this function converts the OMM json data to variables and initializes the sgp4 
+ *    variables. several intermediate varaibles and quantities are determined. note 
+ *    that the result is a structure so multiple satellites can be processed 
+ *    simultaneously without having to reinitialize. the verification mode is an 
+ *    important option that permits quick checks of any changes to the underlying 
+ *    technical theory. this option works using a modified tle file in which the 
+ *    start, stop, and delta time values are included at the end of the second line
+ *    of data. this only works with the verification mode. the catalog mode simply 
+ *    propagates from -1440 to 1440 min from epoch and is useful when performing 
+ *    entire catalog runs.
+ *
+ *  author        : Hariharan Vitaladevuni                   18 Aug 2023
+ *
+ *  inputs        :
+ *    jsonobj     - OMM json data
+ *    opsmode     - mode of operation afspc or improved 'a', 'i'. Default: 'i'.
+ *
+ *  outputs       :
+ *    satrec      - structure containing all the sgp4 satellite information
+ *
+ *  coupling      :
+ *    days2mdhms  - conversion of days to month, day, hour, minute, second
+ *    jday        - convert day month year hour minute second into julian date
+ *    sgp4init    - initialize the sgp4 variables
+ *
+ *  references    :
+ *    https://celestrak.org/NORAD/documentation/gp-data-formats.php
+ *    norad spacetrack report #3
+ *    vallado, crawford, hujsak, kelso  2006
+ --------------------------------------------------------------------------- */
+function json2satrec(jsonobj, opsmode='i') {
+  const opsmode = 'i';
path: src/io.js
user: login: thkruz
body: opsmode is passed as a parameter and defaulted to 'i'. This line of code would create a separate variable and cause the input parameter to be ignored. Please delete this line.
created_at: 2023-08-19T16:57:50Z
author_association: CONTRIBUTOR
diff_hunk: @@ -146,3 +146,102 @@ export default function twoline2satrec(longstr1, longstr2) {
 
   return satrec;
 }
+
+/* -----------------------------------------------------------------------------
+ *
+ *                           function json2satrec
+ *
+ *  this function converts the OMM json data to variables and initializes the sgp4 
+ *    variables. several intermediate varaibles and quantities are determined. note 
+ *    that the result is a structure so multiple satellites can be processed 
+ *    simultaneously without having to reinitialize. the verification mode is an 
+ *    important option that permits quick checks of any changes to the underlying 
+ *    technical theory. this option works using a modified tle file in which the 
+ *    start, stop, and delta time values are included at the end of the second line
+ *    of data. this only works with the verification mode. the catalog mode simply 
+ *    propagates from -1440 to 1440 min from epoch and is useful when performing 
+ *    entire catalog runs.
+ *
+ *  author        : Hariharan Vitaladevuni                   18 Aug 2023
+ *
+ *  inputs        :
+ *    jsonobj     - OMM json data
+ *    opsmode     - mode of operation afspc or improved 'a', 'i'. Default: 'i'.
+ *
+ *  outputs       :
+ *    satrec      - structure containing all the sgp4 satellite information
+ *
+ *  coupling      :
+ *    days2mdhms  - conversion of days to month, day, hour, minute, second
+ *    jday        - convert day month year hour minute second into julian date
+ *    sgp4init    - initialize the sgp4 variables
+ *
+ *  references    :
+ *    https://celestrak.org/NORAD/documentation/gp-data-formats.php
+ *    norad spacetrack report #3
+ *    vallado, crawford, hujsak, kelso  2006
+ --------------------------------------------------------------------------- */
+function json2satrec(jsonobj, opsmode='i') {
+  const opsmode = 'i';
+  const xpdotp = 1440.0 / (2.0 * pi); // 229.1831180523293;
+  let year = 0;
+
+  const satrec = {};
+  satrec.error = 0;
+
+  satrec.satnum = jsonobj.NORAD_CAT_ID.toString();
+
+  var epoch = new Date(jsonobj.EPOCH + 'Z');
path: src/io.js
user: login: thkruz
body: The use of var should be replaced with const.
created_at: 2023-08-19T16:59:28Z
author_association: CONTRIBUTOR
diff_hunk: @@ -146,3 +145,93 @@ export default function twoline2satrec(longstr1, longstr2) {
 
   return satrec;
 }
+
+/* -----------------------------------------------------------------------------
+ *
+ *                           function json2satrec
+ *
+ *  this function converts the OMM json data to variables and initializes the sgp4 
+ *    variables. several intermediate varaibles and quantities are determined. note 
+ *    that the result is a structure so multiple satellites can be processed 
+ *    simultaneously without having to reinitialize. the verification mode is an 
+ *    important option that permits quick checks of any changes to the underlying 
+ *    technical theory. this option works using a modified tle file in which the 
+ *    start, stop, and delta time values are included at the end of the second line
+ *    of data. this only works with the verification mode. the catalog mode simply 
+ *    propagates from -1440 to 1440 min from epoch and is useful when performing 
+ *    entire catalog runs.
+ *
+ *  author        : Hariharan Vitaladevuni                   18 Aug 2023
+ *                  Theodore Kruczek                         19 Aug 2023
+ *
+ *  inputs        :
+ *    jsonobj     - OMM json data
+ *    opsmode     - mode of operation afspc or improved 'a', 'i'. Default: 'i'.
+ *
+ *  outputs       :
+ *    satrec      - structure containing all the sgp4 satellite information
+ *
+ *  coupling      :
+ *    days2mdhms  - conversion of days to month, day, hour, minute, second
+ *    jday        - convert day month year hour minute second into julian date
+ *    sgp4init    - initialize the sgp4 variables
+ * 
+ *  warning       : the epoch date in OMM format is more accurate than TLE format!
+ *                  this will result in extremely close, but different 
+ *                  position/velocity values. Depending on your use case, it may
+ *                  be better to use twoline2satrec, but for the average user this
+ *                  will provide comparable results.
+ *
+ *  references    :
+ *    https://celestrak.org/NORAD/documentation/gp-data-formats.php
+ --------------------------------------------------------------------------- */
+export function json2satrec(jsonobj, opsmode = 'i') {
+  const satrec = {};
+  satrec.error = 0;
+
+  satrec.satnum = jsonobj.NORAD_CAT_ID.toString().padStart(5, '0');
path: src/io.js
user: login: 1valdis
body: Do we really need to pad this? TLE from Space-Track don't pad NORAD id with zeroes, for example.
created_at: 2025-03-18T10:15:33Z
author_association: COLLABORATOR
diff_hunk: @@ -146,3 +145,93 @@ export default function twoline2satrec(longstr1, longstr2) {
 
   return satrec;
 }
+
+/* -----------------------------------------------------------------------------
+ *
+ *                           function json2satrec
+ *
+ *  this function converts the OMM json data to variables and initializes the sgp4 
+ *    variables. several intermediate varaibles and quantities are determined. note 
+ *    that the result is a structure so multiple satellites can be processed 
+ *    simultaneously without having to reinitialize. the verification mode is an 
+ *    important option that permits quick checks of any changes to the underlying 
+ *    technical theory. this option works using a modified tle file in which the 
+ *    start, stop, and delta time values are included at the end of the second line
+ *    of data. this only works with the verification mode. the catalog mode simply 
+ *    propagates from -1440 to 1440 min from epoch and is useful when performing 
+ *    entire catalog runs.
+ *
+ *  author        : Hariharan Vitaladevuni                   18 Aug 2023
+ *                  Theodore Kruczek                         19 Aug 2023
+ *
+ *  inputs        :
+ *    jsonobj     - OMM json data
+ *    opsmode     - mode of operation afspc or improved 'a', 'i'. Default: 'i'.
+ *
+ *  outputs       :
+ *    satrec      - structure containing all the sgp4 satellite information
+ *
+ *  coupling      :
+ *    days2mdhms  - conversion of days to month, day, hour, minute, second
+ *    jday        - convert day month year hour minute second into julian date
+ *    sgp4init    - initialize the sgp4 variables
+ * 
+ *  warning       : the epoch date in OMM format is more accurate than TLE format!
+ *                  this will result in extremely close, but different 
+ *                  position/velocity values. Depending on your use case, it may
+ *                  be better to use twoline2satrec, but for the average user this
+ *                  will provide comparable results.
+ *
+ *  references    :
+ *    https://celestrak.org/NORAD/documentation/gp-data-formats.php
+ --------------------------------------------------------------------------- */
+export function json2satrec(jsonobj, opsmode = 'i') {
+  const satrec = {};
+  satrec.error = 0;
+
+  satrec.satnum = jsonobj.NORAD_CAT_ID.toString().padStart(5, '0');
path: src/io.js
user: login: thkruz
body: Given that we are now using 6 digit ids it is no longer relevant. Space-Track does in some cases and doesn't in other cases. They are inconsistent with their padding. Celestrak pads all ids with 0s. I was focusing on consistency, but you can remove it.
created_at: 2025-03-18T11:00:25Z
author_association: CONTRIBUTOR
diff_hunk: @@ -146,3 +145,93 @@ export default function twoline2satrec(longstr1, longstr2) {
 
   return satrec;
 }
+
+/* -----------------------------------------------------------------------------
+ *
+ *                           function json2satrec
+ *
+ *  this function converts the OMM json data to variables and initializes the sgp4 
+ *    variables. several intermediate varaibles and quantities are determined. note 
+ *    that the result is a structure so multiple satellites can be processed 
+ *    simultaneously without having to reinitialize. the verification mode is an 
+ *    important option that permits quick checks of any changes to the underlying 
+ *    technical theory. this option works using a modified tle file in which the 
+ *    start, stop, and delta time values are included at the end of the second line
+ *    of data. this only works with the verification mode. the catalog mode simply 
+ *    propagates from -1440 to 1440 min from epoch and is useful when performing 
+ *    entire catalog runs.
+ *
+ *  author        : Hariharan Vitaladevuni                   18 Aug 2023
+ *                  Theodore Kruczek                         19 Aug 2023
+ *
+ *  inputs        :
+ *    jsonobj     - OMM json data
+ *    opsmode     - mode of operation afspc or improved 'a', 'i'. Default: 'i'.
+ *
+ *  outputs       :
+ *    satrec      - structure containing all the sgp4 satellite information
+ *
+ *  coupling      :
+ *    days2mdhms  - conversion of days to month, day, hour, minute, second
+ *    jday        - convert day month year hour minute second into julian date
+ *    sgp4init    - initialize the sgp4 variables
+ * 
+ *  warning       : the epoch date in OMM format is more accurate than TLE format!
+ *                  this will result in extremely close, but different 
+ *                  position/velocity values. Depending on your use case, it may
+ *                  be better to use twoline2satrec, but for the average user this
+ *                  will provide comparable results.
+ *
+ *  references    :
+ *    https://celestrak.org/NORAD/documentation/gp-data-formats.php
+ --------------------------------------------------------------------------- */
+export function json2satrec(jsonobj, opsmode = 'i') {
+  const satrec = {};
+  satrec.error = 0;
+
+  satrec.satnum = jsonobj.NORAD_CAT_ID.toString().padStart(5, '0');
path: src/io.js
user: login: 1valdis
body: I'd prefer keeping that as originally provided in JSON, especially since it might be 5 digits at the time of PR, 6 digits now, 7 digits in a few more years etc. I think consistency is not in the scope of the library, but for the users to implement if they want that.
created_at: 2025-03-18T11:09:41Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,145 @@
+import { deg2rad, twoPi } from './constants';
+
+////////////////////////////////////////////////////////////////////////////////////
+/* Line by Line MATLAB-to-Javascript conversion of "sun.mat" from Vallado package */
+////////////////////////////////////////////////////////////////////////////////////
+/* -----------------------------------------------------------------------------
+ *
+ *                              function sunPos
+ *
+ *  this function calculates the geocentric equatorial position vector
+ *      the sun given the julian date.  this is the low precision formula and
+ *      is valid for years from 1950 to 2050.  accuaracy of apparent coordinates
+ *      is 0.01  degrees.  notice many of the calculations are performed in
+ *      degrees, and are not changed until later.  this is due to the fact that
+ *      the almanac uses degrees exclusively in their formulations.
+ * 
+ *  author        : david vallado                  719-573-2600    1 mar 2001
+ * 
+ *  inputs          description                       range / units
+ *      jd          - julian date                       days from 4713 bc
+ * 
+ *  outputs       :
+ *      rsun        - ijk position vector of the sun    au
+ *      rtasc       - right ascension                   rad
+ *      decl        - declination                       rad
+ * 
+ *  coupling      :
+ *      -
+ * 
+ *  references    :
+ *      VALLADO, DAVID A. (2022) ‘Computer software in MATLAB’, in Fundamentals of astrodynamics and applications. 5th edn.
+ *      Computer software in MATLAB: http://celestrak.org/software/vallado-sw.php 
+ *  --------------------------------------------------------------------------- */
+
+export function sunPos(jd) {
path: src/sun.js
user: login: 1valdis
body: Why is this function needed? Looks out of scope of the library, the pull request, and isn't used anywhere in the codebase.
created_at: 2025-03-18T20:09:36Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,145 @@
+import { deg2rad, twoPi } from './constants';
+
+////////////////////////////////////////////////////////////////////////////////////
+/* Line by Line MATLAB-to-Javascript conversion of "sun.mat" from Vallado package */
+////////////////////////////////////////////////////////////////////////////////////
+/* -----------------------------------------------------------------------------
+ *
+ *                              function sunPos
+ *
+ *  this function calculates the geocentric equatorial position vector
+ *      the sun given the julian date.  this is the low precision formula and
+ *      is valid for years from 1950 to 2050.  accuaracy of apparent coordinates
+ *      is 0.01  degrees.  notice many of the calculations are performed in
+ *      degrees, and are not changed until later.  this is due to the fact that
+ *      the almanac uses degrees exclusively in their formulations.
+ * 
+ *  author        : david vallado                  719-573-2600    1 mar 2001
+ * 
+ *  inputs          description                       range / units
+ *      jd          - julian date                       days from 4713 bc
+ * 
+ *  outputs       :
+ *      rsun        - ijk position vector of the sun    au
+ *      rtasc       - right ascension                   rad
+ *      decl        - declination                       rad
+ * 
+ *  coupling      :
+ *      -
+ * 
+ *  references    :
+ *      VALLADO, DAVID A. (2022) ‘Computer software in MATLAB’, in Fundamentals of astrodynamics and applications. 5th edn.
+ *      Computer software in MATLAB: http://celestrak.org/software/vallado-sw.php 
+ *  --------------------------------------------------------------------------- */
+
+export function sunPos(jd) {
path: src/sun.js
user: login: thkruz
body: It is used for calculating sun angles to determine if a satellite is illuminated. This is very useful for telescopes. I guess it depends on what you think the scope of the library is. "because it was in the original source code" was a good enough reason for me.
created_at: 2025-03-18T22:30:13Z
author_association: CONTRIBUTOR

PR comments:
user: login: thkruz
created_at: 2023-08-16T04:41:56Z
body: Thanks for taking the time to help future proof this library!

We need to add some unit tests for this new function. Might be smart to have at least a few that make sure it is getting the same answer as the original function. 

I'll take a look in the airport tomorrow, but the comment block on this looks incorrect. It mentions more input functions than are available. Additionally there are a lot of leftover comments from copying the original function - if we are modernizing the library there is no benefit of keeping old comments that don't apply. 
author_association: CONTRIBUTOR
user: login: spacenewb
created_at: 2023-08-18T13:00:12Z
body: > Overall I think this is in the right direction. It needs a little polish. I will try to find some time to write tests in the near future, but if anyone else can it would be great. We need to validate that it makes the same `satrec` object as the main function.

I did perform some basic tests, but I am not so proficient in JS, to write unit tests. But there seems to be a way to compare two objects using a method named `_.isEqual` from a library called `Lodash`. Everything seemed to be exactly the same except for the difference in the `satrec.epoch`. 

The old and the new methods seemed to vary in the 8th decimal place due to some floating point magic which was beyond my understanding as a non-CS background person. this translates to a difference in a couple of milliseconds.

If there are ways to check if these are within a certain tolerance while writing the tests, that would be optimal.
author_association: CONTRIBUTOR
user: login: thkruz
created_at: 2023-08-19T19:00:04Z
body: I opened a PR (https://github.com/spacenewb/satellite-js/pull/1) on your PR to incorporate the changes I suggested and add the testing.
author_association: CONTRIBUTOR
user: login: MarkoXR
created_at: 2025-02-07T17:56:02Z
body: It would be great to see this merged 🙏 
author_association: NONE
user: login: 1valdis
created_at: 2025-03-16T01:23:58Z
body: Would be nice to see a bit more active involvement of maintainers here👀
author_association: COLLABORATOR
user: login: thkruz
created_at: 2025-03-16T02:35:19Z
body: I do not think anyone is still maintaining this repo. I have other high priority projects and have removed myself from the list of maintainers to make that more clear.
author_association: CONTRIBUTOR
user: login: shashwatak
created_at: 2025-03-18T03:30:33Z
body: @spacenewb if you would like to be a maintainer of this project, please reply in this thread:
https://github.com/shashwatak/satellite-js/issues/137
author_association: OWNER
user: login: 1valdis
created_at: 2025-03-19T08:21:37Z
body: Thanks for the contribution! While this doesn't have types, I will add them myself later.
author_association: COLLABORATOR