timecraftjs

    2.0.0 • Public • Published

    TimeCraftJS

    TimeCraftJS

    npm version Node.js CI

    TimeCraftJS is a time conversion library that uses NAIF's CSPICE. It exposes functions to execute operations to convert SCET, ET, SCT, furnish Kernels, among others, on the client side. This avoid unnecessary trips to the backend and allows for important time operations to happen if network connectivity is not immediately available. Multiple variants of the built CSPICE library are provided, including a limited, low-memory "lite" version with lesser functionality which is loaded by default. See Constants section and init function description for more information on the options.

    Some basic kernels are provided in this repo for performing time conversions. More kernels for other missions can be found here.

    Quick Start

    Installation via NPM

    npm install timecraftjs

    Use with Webpack

    The compiled emscripten blob includes require( 'fs' ) which can cause Webpack to fail to compile for the web. In this case add the following options to the root of your Webpack config:

    node: {
        fs: "empty";
    }

    Time Conversion

    import { Spice } from "timecraftjs";
    
    const spiceInstance = await new Spice().init();
    
    // Load the kernels
    const kernelBuffers = await Promise.all([
        fetch("../kernels/lsk/naif0012.tls").then((res) => res.buffer()),
        fetch("../kernels/spk/de425s.bsp").then((res) => res.buffer()),
        fetch("../kernels/pck/pck00008.tpc").then((res) => res.buffer()),
    ]);
    
    // Load the kernels into Spice
    for (let i = 0; i < kernelBuffers.length; i++) {
        spiceInstance.loadKernel(kernelBuffers[i]);
    }
    
    // Time conversion!
    const utc = new Date().toISOString().slice(0, -1);
    
    const et = spiceInstance.utc2et(utc);
    
    const lst = spiceInstance.et2lst(et, 499, 0, "planetocentric");

    Loading a Metakernel

    import { Spice, parseMetakernel } from "timecraftjs";
    
    const spiceInstance = await new Spice().init();
    
    // load the kernel contents
    const metaKernel = await fetch(
        "../kernels/extras/mk/msl_chronos_v07.tm"
    ).then((res) => res.text());
    
    // parse the kernel
    const kernelPaths = parseMetakernel(metaKernel).paths;
    
    // load the kernels in the meta kernel
    const kernelPromises = kernelPaths.map((p) => {
        return fetch(p)
            .then((res) => res.buffer())
            .then((buffer) => spiceInstance.loadKernel(buffer));
    });
    
    await Promise.all(kernelPromises);
    
    // ready for time conversion!

    Using the Chronos Function

    spiceInstance.chronos("617885388.6646054", "-from et -to utc -fromtype SECONDS");

    Running the Example

    1. Clone the Repository
    git clone https://github.com/NASA-AMMOS/timecraftjs.git
    1. Run the following on the base directory:
    npm install
    npm start

    This will start a static server so you can visit the example page at localhost:9080/example/.

    Table Of Contents

    What Is TimeCraftJS?

    Included Files

    API

    Loading Kernels

    Recompiling cspice.js

    What Is TimeCraftJS?

    TimecraftJS is a time conversion library that uses NAIF's CSPICE. In order to accomplish this, we automatically converted the C source code into Javascript via Emscripten. In order for them to work in a much more user friendly and Javascript-like way, we have created wrapper functions that interact with the resulting simulated C program, allocating and deallocating memory as necessary. This project only includes wrappers for the functions relevant to time conversion and some light time calculations. This project is an offshoot of spice.js.

    A great deal below deals with the loading and furnishing of kernels. If you do not wish to do any time conversions involving specific spacecraft or planets, the default included kernels are sufficient and you may ignore these sections. The default kernels are enough to refer to most NAIF ID's, a planetary constants kernel, and a leap seconds kernel. See example-timecraftjs.html for a simple demo of TimeCraftJS working.

    Included Files

    This section lists the files included in this package and describes what each of them does. This section is mainly for people who wish to modify this package, if you simply wish to use it you can likely skip this section.

    src/cspice/*.js

    These files contain the emscripten-converted CSPICE source code. It is extremely large and should not be modified. Both a "full" and "lite" version of converted CSPICE is provided. See the Constants section for more information on the variants.

    src/spice.js

    This file contains the wrapper class that allows access to the functionality in cspice.js. The version of spice.js here is focused on time conversions, but the rest of the CSPICE functionality could be exposed if needed.

    API

    Constants

    Constants for use in the Spice.init function to intialize the library to use either a full or lite version of the SPICE library.

    ASM_SPICE_FULL

    Use this constant to load and use the full asm.js version of the SPICE library with full functionality. Run time memory requirement is around 100 MB.

    ASM_SPICE_LITE

    Use this constant to load and use an asm.js version of an unofficial "lite" version of the SPICE library with some missing functonality to improve memory requirements. Specifically all ek* functions have been removed and various internal constants have been lowered to reduce memory use. Not all NAIF kernels can be guaranteed to function when using this reduced memory of the package. If an error occurs due to overrunning memory use the "full" version, instead. Run time memory requirement is around 20 MB.

    Spice

    Class used to instantiate an instance of Spice. Multiple instances can be created to load different kernels if desired. init must be called before use.

    Note that due to the memory requirements of CSpice each instance of this class will take around 100MB of memory.

    .ready

    ready : Boolean

    Whether the class has been fully initialized after init has been called.

    .whenReady

    whenReady : Promise<this>

    Resolves when the class has been fully initialized after init has been called.

    .onStdOut

    onStdOut : ( log : String ) => void

    Callback that gets fired whenever CSpice logs to stdout. Defaults to log to console.

    .onStdErr

    onStdErr : ( log : String ) => void

    Callback that gets fired whenever CSpice logs to stderr. Defaults to log error to console.

    .module

    module : Object = null

    This is the raw Emscripten compiled module that is used to call CSpice functions and interact with the virtual file system. There is typically no need to use this object but unexposed CSpice functions can be called here using ccall.

    Module and FS are created by Emscripten to interact directly with the ported C code and with the simulated C file system. Avoid using them unless you have read the Interacting With Code and preamble.js sections of the Emscripten documentation.

    module is null until init has fully resolved.

    .init

    init( type : ( ASM_SPICE_LITE | ASM_SPICE_FULL ) = ASM_SPICE_LITE ) : Promise<this>

    Loads and initializes the CSpice module. The class is ready to use once the promise has resolved.

    The "type" parameter can be used to dictate which version of the compiled CSPICE module to use. See the Constants section for available options and more information. Defaults to using the "lite" version of the module.

    .loadKernel

    loadKernel( buffer : ArrayBuffer | Uint8Array, key : String = null ) : void

    Load the provided buffer into Spice as a kernel. The provided key can be used to unload the kernel using unloadKernel. Throws an error if the key has already been used. Details of kernel management can be found in the Kernel Management section of the SPICE docs.

    .unloadKernel

    unloadKernel( key : String ) : void

    Unload the kernel that was loaded with the given key. Throws an error if a kernel has not been loaded with the given key.

    .chronos

    chronos( inptim : String, cmdlin : String ) : String

    Wrapper for the CSpice command line utility that calls the cronos_ function internally. inptim is the input time to convert while cmdlin is the list of command line arguments as a string. See the chronos docs for more information.

    Spice Functions

    Most of the functions made available in this library are functions from CSPICE called in a more Javascript-like way. Please see differences between cspice and spice.js for specifics.

    While the ported C code technically contains all CSPICE functionality, the following functions have been exposed in this class. The CSPICE documentation for each of these functions is correct, but below you can see their more Javascript-like call format supported here. All documented CSpice function inputs are passed into the Javascript equivelants below while all outputs are returned as a dictionary indexed by parameter name or as a single value if there is only a single output.

    b1900()
    b1950()
    bodc2n( code )
    bodc2s( code )
    boddef( name, code )
    bodfnd( body, item )
    bodn2c( name )
    bods2c( name )
    bodvcd( bodyid, item, maxn )
    bodvrd( body, item, maxn )
    convrt( x, in_var, out )
    deltet( epoch, eptype )
    erract( op, action )
    errprt( op, list )
    et2lst( et, body, lon, type )
    et2utc( et, format, prec )
    etcal( et )
    failed()
    furnsh( kernelPaths )
    getmsg( options )
    j1900()
    j1950()
    j2000()
    j2100()
    jyear()
    ltime( etobs, obs, dir, targ )
    reset()
    scdecd( sc, sclkdp )
    sce2c( sc, et )
    sce2s( sc, et )
    sce2t( sc, et )
    scencd( sc, sclkch )
    scfmt( sc, ticks )
    scpart( sc )
    scs2e( sc, sclkch )
    sct2e( sc, sclkdp )
    sctiks( sc, clkstr )
    spd()
    spkpos( targ, et, ref, abcorr, obs )
    str2et( str )
    timdef( action, item, value )
    timout( et, pictur )
    tparse( string )
    tpictr( sample )
    tsetyr( year )
    tyear()
    unitim( epoch, insys, outsys )
    unload( file )
    utc2et( utcstr )
    

    Functions

    isMetakernel

    isMetakernel( contents : String | ArrayBuffer | Uint8Array ) : Boolean

    Takes the contents of a kernel file and returns true if it is a metakernal and false otherwise. This function looks for the KERNELS_TO_LOAD token in the file.

    parseMetakernel

    parseMetakernel( contents : String | ArrayBuffer | Uint8Array ) : { fields: Object, paths: Array<String> }

    Parses the contents of a metakernel .tm file and returns all the key value pairs in the file as fields and all preprocessed referenced metakernal paths as paths.

    Loading Kernels

    In order to load an read kernels the data must be loaded into the virtual Emscripten file system as a binary buffer.

    In the Browser

    Files must be downloaded asynchronously as array buffers before being loaded into the app.

    import { Spice } from "timecraftjs";
    
    const spiceInstance = await new Spice().init();
    const kernelBuffer = await fetch("../path/to/kernel").then((res) => res.buffer);
    spiceInstance.loadKernel(buffer);

    In Node

    In node files can be loaded from the filesystem directly.

    import fs from "fs";
    import { Spice } from "timecraftjs";
    
    const spiceInstance = await new Spice().init();
    const kernelBuffer = fs.readFileSync("../path/to/kernel");
    spiceInstance.loadKernel(buffer);

    Recompiling cspice.js

    The files in src/cspice/ are the massive Javascript files resulting from the automatic porting via Emscripten. As such, if CSPICE updates, these files will need to be recompiled. In order to recompile any of the JS CSPICE files, follow these steps:

    Setting Up Emscripten

    1. Download relevant toolkit from the NAIF website.
    2. Download emsdk to download and manage "emscripten" versions.
    3. Install the latest version of emscripten and source the emsdk environment variables from emsdk_env.sh.

    CSPICE Full (asm_full.js)

    The current version was created from the Mac/OSX 64 Bit Toolkit on April 12, 2021 with emscripten version 2.0.17.

    1. Unzip the CSPICE source folder and put the contents into the generation/cspice-full folder.
    2. Ensure the LITE_BUILD variable is set to False in generation/generate-cspice.sh.
    3. Run generation/generate-cspice.sh to generate the js library file in the folder.
    4. Move the newly generated asm_full.js file into the src/cspice folder.

    CSPICE Lite (asm_lite.js)

    INTERNAL ONLY

    The modified lite version of the CSPICE used was dervied from the latest version of CSPICE on April 27, 2021 with emscripten version 2.0.17. The CSPICE lite code only provides modified src/cspice functions so necessary chronos functionality is copied from the latest public version.

    1. Unzip the latest CSPICE source folder (see above) and put the contents into the generation/cspice-full folder.
    2. Unzip the CSPICE lite source folder and put the contents into the generation/cspice-lite folder. Modified CSPICE lite source available here (internal only).
    3. Ensure the LITE_BUILD variable is set to True in generation/generate-cspice.sh.
    4. Run generation/generate-cspice.sh to generate the js library file in the folder.
    5. Move the newly generated asm_lite.js file into the src/cspice folder.

    License

    Copyright 2020, by the California Institute of Technology. ALL RIGHTS RESERVED. United States Government Sponsorship acknowledged. Any commercial use must be negotiated with the Office of Technology Transfer at the California Institute of Technology. This software may be subject to U.S. export control laws. By accepting this software, the user agrees to comply with all applicable U.S. export laws and regulations. User has the responsibility to obtain export licenses, or other export authority as may be required before exporting such information to foreign countries or providing access to foreign persons.

    Install

    npm i timecraftjs

    DownloadsWeekly Downloads

    15

    Version

    2.0.0

    License

    Apache-2.0

    Unpacked Size

    9.78 MB

    Total Files

    15

    Last publish

    Collaborators

    • arintahmasian