SpatioTemporal / pystare

The Python interface for the SpatioTemporal Adaptive Resolution Encoding (STARE), a unified indexing for geolocated data.
https://pystare.readthedocs.io/en/latest/
12 stars 2 forks source link

Install results in an import error when used #94

Open mbauer288 opened 2 years ago

mbauer288 commented 2 years ago

OS : Ubuntu 22.04 LTS Codename: jammy Kernel : 5.15.0-41-generic Python : 3.10.5

Attempt to install manually. No obvious errors until I import pystare, at which point it can't find libSTARE

ImportError: libSTARE.so.1: cannot open shared object file: No such file or directory

I needed to add a few things first to get here.

$ sudo apt -y install swig
$ pip install -U pytest

I installed STARE (also manually) into a local directory and it seems to have worked fine.

$ export STARE_INCLUDE_DIR="/home/mbauer/.local/include/STARE/"
$ export STARE_LIB_DIR="/home/mbauer/.local/OFF/"

The install procedure seems to work fine.

$ python setup.py build_ext --inplace 
    running build_ext
    building 'pystare._core' extension
    swigging pystare/PySTARE.i to pystare/PySTARE_wrap.cpp
    swig -python -c++ -o pystare/PySTARE_wrap.cpp pystare/PySTARE.i
    gcc -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/home/mbauer/.local/include/STARE/ -I/home/mbauer/mcms_dev/setup/.venv/lib/python3.10/site-packages/numpy/core/include -I/home/mbauer/mcms_dev/setup/.venv/include -I/home/mbauer/.pyenv/versions/3.10.5/include/python3.10 -c pystare/PySTARE.cpp -o build/temp.linux-x86_64-cpython-310/pystare/PySTARE.o -std=c++11
    ...
    Writing pystare-0.8.7+1.g6cdd14d/setup.cfg
    UPDATING pystare-0.8.7+1.g6cdd14d/pystare/_version.py
    set pystare-0.8.7+1.g6cdd14d/pystare/_version.py to '0.8.7+1.g6cdd14d'
    Creating tar archive
    removing 'pystare-0.8.7+1.g6cdd14d' (and everything under it)

$ python3 setup.py bdist_wheel
$ python3 setup.py sdist

However, the tests fail.

$ pytest --doctest-modules 
    ========================================================================= test session starts =========================================================================
    platform linux -- Python 3.10.5, pytest-7.1.2, pluggy-1.0.0
    rootdir: /home/mbauer/pystare, configfile: pytest.ini
    collected 0 items / 22 errors                                                                                                                                         

    =============================================================================== ERRORS ================================================================================
    ________________________________________________________________ ERROR collecting pystare/__init__.py _________________________________________________________________
    pystare/__init__.py:1: in <module>
        from pystare.spatial import *
    pystare/spatial.py:2: in <module>
        import pystare.core
    pystare/core.py:13: in <module>
        from . import _core
    E   ImportError: libSTARE.so.1: cannot open shared object file: No such file or directory
    ________________________________________________________________ ERROR collecting pystare/_version.py _________________________________________________________________

As does a simple import.

$ python 
    Python 3.10.5 (main, Jul 18 2022, 10:30:34) [GCC 11.2.0] on linux
    Type "help", "copyright", "credits" or "license" for more information.

    >>> import pystare

    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/home/mbauer/pystare/pystare/__init__.py", line 1, in <module>
        from pystare.spatial import *
      File "/home/mbauer/pystare/pystare/spatial.py", line 2, in <module>
        import pystare.core
      File "/home/mbauer/pystare/pystare/core.py", line 13, in <module>
        from . import _core
    ImportError: libSTARE.so.1: cannot open shared object file: No such file or directory

Mike

NiklasPhabian commented 2 years ago

ok. Something is off, we build pySTARE built against the static library. Where does your libSTARE.a live?

I build STARE e.g. with

cd STARE
mkdir build
cd build/
cmake -DSTARE_INSTALL_LIBDIR=lib -DBUILD_SHARED_LIBS=NO -DCMAKE_INSTALL_PREFIX:PATH=~/stare ..
make -j4 
make install 

Now I set the the environment vars:

export STARE_INCLUDE_DIR="/home/griessbaum/stare/include/STARE/"
export STARE_LIB_DIR="/home/griessbaum/stare/lib/"

(curious, that I cannot use the ~ shortcut. I should add an expanduser() to the setup.py to enable that)

Those two env variables should get picked up by the setup.py

I can then install pystare with

mkvirtualenv stare
pip3 install numpy
cd pystare/
python setup.py build_ext --inplace 
pip3 install -e .

And import and use it etc.

mbauer288 commented 2 years ago

Thank you, I worked it out completely. I found a couple of probably out-of-date API examples/tests (search for ## NEEDS FIX?), but otherwise everything seems to work.


OS : Ubuntu 22.04 LTS Codename : jammy Kernel : 5.15.0-41-generic Architecture: x86_64

CPU : Intel i7-9700K @ 3.60GHz x 8 cores GPU : NVIDIA GeForce RTX 2080 SUPER RAM : 32 GB DDR4-2666 MHz (2 x 16 GB) HD: : 2.5 TB

Step 1: Install STARE (https://github.com/SpatioTemporal/STARE)

Step 1a: Install some dependencies.

    $ sudo apt update
    $ sudo apt autoremove
    $ sudo apt upgrade

    $ sudo apt -y install cmake
    $ sudo apt -y install g++
    $ sudo apt -y install graphviz
    $ sudo apt -y install doxygen
    $ sudo apt -y install swig

Step 1b: Clone STARE repo

    $ cd .ssh
    $ ssh-add mbauer288-GitHub
    $ ssh-add id_rsa

    $ cd 
    $ gh repo clone SpatioTemporal/STARE
    $ cd STARE

Step 1c: Set up a new virtual environment and activate it

    # Create a special virtual environment (python)
    $ pyenv virtualenv 3.10.5 mystare

    # Activate virtual environment
    $ pyenv activate mystare
    $ pyenv local mystare   

    # Check the Installation
    $ pyenv versions
          system
          3.9.13
          3.10.5
          3.10.5/envs/mystare
        * mystare (set by PYENV_VERSION environment variable)
    $ pyenv virtualenvs
          3.10.5/envs/mystare (created from /home/mbauer/.pyenv/versions/3.10.5)
        * mystare (created from /home/mbauer/.pyenv/versions/3.10.5)

    # Check the version of python to see if the correct version is being used.
    $ which python
        python is /home/mbauer/.pyenv/shims/python
    $ python -V
        Python 3.10.5
    $ type python
        python is /home/mbauer/.pyenv/shims/python
    $ pyenv which python
        /home/mbauer/.pyenv/versions/mystare/bin/python

 Step 1d: Install STARE

    $ mkdir build; cd build
    $ cmake ..
    $ make

    $ export CMAKE_INSTALL_PREFIX="/home/mbauer/.local"
    $ cmake -DSTARE_INSTALL_LIBDIR=lib -DBUILD_SHARED_LIBS=NO -DCMAKE_INSTALL_PREFIX:PATH=/home/mbauer/.local .. 
        -- The C compiler identification is GNU 11.2.0
        -- The CXX compiler identification is GNU 11.2.0
        -- Detecting C compiler ABI info
        -- Detecting C compiler ABI info - done
        -- Check for working C compiler: /usr/bin/cc - skipped
        -- Detecting C compile features
        -- Detecting C compile features - done
        -- Detecting CXX compiler ABI info
        -- Detecting CXX compiler ABI info - done
        -- Check for working CXX compiler: /usr/bin/c++ - skipped
        -- Detecting CXX compile features
        -- Detecting CXX compile features - done

        ------------ Running cmake for project STARE ------------

         CUTE_INCLUDE_DIR: /home/mbauer/STARE/external/CUTE/cute

         CUTE Testing Enabled

         Setting C_OPT_FLAGS, CXX_OPT_FLAGS to -O3 by default.

         Optimization settings.
         C_OPT_FLAGS:  -O3
         CXX_OPT_FLAGS -O3

        -- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY
        -- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY - Success
        -- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY
        -- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY - Success
        -- Performing Test COMPILER_HAS_DEPRECATED_ATTR
        -- Performing Test COMPILER_HAS_DEPRECATED_ATTR - Success
        -- Found Doxygen: /usr/bin/doxygen (found version "1.9.1") found components: doxygen dot 

         Adding tests...

        -- Configuring done
        -- Generating done
        -- Build files have been written to: /home/mbauer/STARE/buil       

    $ make -j4 
        [  4%] Building CXX object src/CMakeFiles/STARE.dir/EmbeddedLevelNameEncoding.cpp.o
        [  4%] Building CXX object src/CMakeFiles/STARE.dir/BitShiftNameEncoding.cpp.o
        [  8%] Building CXX object src/CMakeFiles/STARE.dir/HtmRange.cpp.o
        [  6%] Building CXX object src/CMakeFiles/STARE.dir/General.cpp.o
        [ 10%] Building CXX object src/CMakeFiles/STARE.dir/HtmRangeIterator.cpp.o
        [ 13%] Building CXX object src/CMakeFiles/STARE.dir/HtmRangeMultiLevel.cpp.o
        [ 15%] Building CXX object src/CMakeFiles/STARE.dir/HtmRangeMultiLevelIterator.cpp.o
        [ 17%] Building CXX object src/CMakeFiles/STARE.dir/Htmio.cpp.o
        [ 19%] Building CXX object src/CMakeFiles/STARE.dir/HstmRange.cpp.o
        [ 21%] Building CXX object src/CMakeFiles/STARE.dir/NameEncoding.cpp.o
        [ 23%] Building CXX object src/CMakeFiles/STARE.dir/RangeConvex.cpp.o
        [ 26%] Building CXX object src/CMakeFiles/STARE.dir/SkipList.cpp.o
        [ 28%] Building CXX object src/CMakeFiles/STARE.dir/SkipListElement.cpp.o
        [ 30%] Building CXX object src/CMakeFiles/STARE.dir/SpatialConstraint.cpp.o
        [ 32%] Building CXX object src/CMakeFiles/STARE.dir/SpatialDomain.cpp.o
        [ 34%] Building CXX object src/CMakeFiles/STARE.dir/SpatialEdge.cpp.o
        [ 36%] Building CXX object src/CMakeFiles/STARE.dir/SpatialException.cpp.o
        [ 39%] Building CXX object src/CMakeFiles/STARE.dir/SpatialGeneral.cpp.o
        [ 41%] Building CXX object src/CMakeFiles/STARE.dir/SpatialIndex.cpp.o
        [ 43%] Building CXX object src/CMakeFiles/STARE.dir/SpatialInterface.cpp.o
        [ 45%] Building CXX object src/CMakeFiles/STARE.dir/SpatiallyAdaptiveDataCover.cpp.o
        [ 47%] Building CXX object src/CMakeFiles/STARE.dir/SpatialVector.cpp.o
        [ 50%] Building CXX object src/CMakeFiles/STARE.dir/SpatialPolygon.cpp.o
        [ 52%] Building CXX object src/CMakeFiles/STARE.dir/SpatialRotation.cpp.o
        [ 54%] Building CXX object src/CMakeFiles/STARE.dir/STARE.cpp.o
        [ 56%] Building CXX object src/CMakeFiles/STARE.dir/SpatialRange.cpp.o
        [ 58%] Building CXX object src/CMakeFiles/STARE.dir/TemporalIndex.cpp.o
        [ 60%] Building CXX object src/CMakeFiles/STARE.dir/TemporalWordFormat1.cpp.o
        [ 63%] Building CXX object src/CMakeFiles/STARE.dir/VarStr.cpp.o
        [ 65%] Building C object src/CMakeFiles/STARE.dir/__/external/erfa-single-file/erfa.c.o
        [ 67%] Linking CXX static library libSTARE.a
        [ 67%] Built target STARE
        [ 73%] Building CXX object tests/CUTE/CMakeFiles/tests.dir/AdaptSpatialResolutionEstimates_test.cpp.o
        [ 73%] Building CXX object tests/CUTE/CMakeFiles/tests.dir/SpatialFailure_test.cpp.o
        [ 76%] Building CXX object tests/CUTE/CMakeFiles/tests.dir/SpatialIndex_test.cpp.o
        [ 76%] Building CXX object tests/CUTE/CMakeFiles/tests.dir/EmbeddedLevelNameEncoding_test.cpp.o
        [ 78%] Building CXX object tests/CUTE/CMakeFiles/tests.dir/SpatialInterface_test.cpp.o
        [ 80%] Building CXX object tests/CUTE/CMakeFiles/tests.dir/SpatialPolygon_test.cpp.o
        [ 82%] Building CXX object tests/CUTE/CMakeFiles/tests.dir/SpatialRange_test.cpp.o
        [ 84%] Building CXX object tests/CUTE/CMakeFiles/tests.dir/SpatialRotation_test.cpp.o
        [ 86%] Building CXX object tests/CUTE/CMakeFiles/tests.dir/SpatialVector_test.cpp.o
        [ 89%] Building CXX object tests/CUTE/CMakeFiles/tests.dir/SpatioTemporalUsage_test.cpp.o
        [ 91%] Building CXX object tests/CUTE/CMakeFiles/tests.dir/STARE_test.cpp.o
        [ 93%] Building CXX object tests/CUTE/CMakeFiles/tests.dir/STARE_Covers_test.cpp.o
        [ 95%] Building CXX object tests/CUTE/CMakeFiles/tests.dir/TemporalIndex_test.cpp.o
        [ 97%] Building CXX object tests/CUTE/CMakeFiles/tests.dir/Test.cpp.o
        [100%] Linking CXX executable tests
        [100%] Built target tests       

    Besides all the new files in /build this creates/modifies /home/mbauer/STARE/include/STARE.h

    $ make install
        [ 67%] Built target STARE
        [100%] Built target tests
        Install the project...
        -- Install configuration: ""
        -- Installing: /home/mbauer/.local/include/STARE/STARE.h
        -- Installing: /home/mbauer/.local/include/STARE/BitField.h
        -- Installing: /home/mbauer/.local/include/STARE/BitShiftNameEncoding.h
        -- Installing: /home/mbauer/.local/include/STARE/Convexio.h
        -- Installing: /home/mbauer/.local/include/STARE/EmbeddedLevelNameEncoding.h
        -- Installing: /home/mbauer/.local/include/STARE/General.h
        -- Installing: /home/mbauer/.local/include/STARE/HtmRange.h
        -- Installing: /home/mbauer/.local/include/STARE/HtmRangeIterator.h
        -- Installing: /home/mbauer/.local/include/STARE/HtmRangeMultiLevel.h
        -- Installing: /home/mbauer/.local/include/STARE/HtmRangeMultiLevelIterator.h
        -- Installing: /home/mbauer/.local/include/STARE/Htmio.h
        -- Installing: /home/mbauer/.local/include/STARE/HstmRange.h
        -- Installing: /home/mbauer/.local/include/STARE/KeyPair.h
        -- Installing: /home/mbauer/.local/include/STARE/NameEncoding.h
        -- Installing: /home/mbauer/.local/include/STARE/RangeConvex.h
        -- Installing: /home/mbauer/.local/include/STARE/RangeConvex.hxx
        -- Installing: /home/mbauer/.local/include/STARE/SkipList.h
        -- Installing: /home/mbauer/.local/include/STARE/SkipListElement.h
        -- Installing: /home/mbauer/.local/include/STARE/SpatialConstraint.h
        -- Installing: /home/mbauer/.local/include/STARE/SpatialConstraint.hxx
        -- Installing: /home/mbauer/.local/include/STARE/SpatialConvex.hxx
        -- Installing: /home/mbauer/.local/include/STARE/SpatialDomain.h
        -- Installing: /home/mbauer/.local/include/STARE/SpatialDomain.hxx
        -- Installing: /home/mbauer/.local/include/STARE/SpatialEdge.h
        -- Installing: /home/mbauer/.local/include/STARE/SpatialException.h
        -- Installing: /home/mbauer/.local/include/STARE/SpatialGeneral.h
        -- Installing: /home/mbauer/.local/include/STARE/SpatialIndex.h
        -- Installing: /home/mbauer/.local/include/STARE/SpatialIndex.hxx
        -- Installing: /home/mbauer/.local/include/STARE/SpatialInterface.h
        -- Installing: /home/mbauer/.local/include/STARE/SpatialInterface.hxx
        -- Installing: /home/mbauer/.local/include/STARE/SpatialPolygon.h
        -- Installing: /home/mbauer/.local/include/STARE/SpatialRange.h
        -- Installing: /home/mbauer/.local/include/STARE/SpatialSign.h
        -- Installing: /home/mbauer/.local/include/STARE/SpatialVector.h
        -- Installing: /home/mbauer/.local/include/STARE/SpatialVector.hxx
        -- Installing: /home/mbauer/.local/include/STARE/SpatialRotation.h
        -- Installing: /home/mbauer/.local/include/STARE/TemporalGeneral.h
        -- Installing: /home/mbauer/.local/include/STARE/TemporalIndex.h
        -- Installing: /home/mbauer/.local/include/STARE/TemporalIndex1.h
        -- Installing: /home/mbauer/.local/include/STARE/TemporalWordFormat1.h
        -- Installing: /home/mbauer/.local/include/STARE/VarCmp.h
        -- Installing: /home/mbauer/.local/include/STARE/VarStr.h
        -- Installing: /home/mbauer/.local/include/STARE/VarStr.hpp
        -- Installing: /home/mbauer/.local/include/STARE/VarStr.hxx
        -- Installing: /home/mbauer/.local/include/STARE/erfa.h
        -- Installing: /home/mbauer/.local/lib/libSTARE.a
        -- Up-to-date: /home/mbauer/.local/include/STARE
        -- Installing: /home/mbauer/.local/include/STARE/export.h
        -- Installing: /home/mbauer/.local/lib/cmake/STARE/STARE-static-targets.cmake
        -- Installing: /home/mbauer/.local/lib/cmake/STARE/STARE-static-targets-noconfig.cmake
        -- Installing: /home/mbauer/.local/lib/cmake/STARE/STAREConfig.cmake
        -- Installing: /home/mbauer/.local/lib/cmake/STARE/STAREConfigVersion.cmake

This creates
    /home/mbauer/.local/include/STARE/
        BitField.h 
        ...
        STARE.h
        ...
        VarStr.hxx
    /home/mbauer/.local/lib/
        cmake/  
        libSTARE.a

# Test build
$ ctest 
    Test project /home/mbauer/STARE/build
        Start 1: STARETests
    1/1 Test #1: STARETests .......................   Passed   37.42 sec

    100% tests passed, 0 tests failed out of 1

    Total Test time (real) =  37.42 sec

Add to .bashrc
    export STARE_SRC_HOME="/home/mbauer/STARE/"
    export STARE_INCLUDE_DIR="/home/mbauer/.local/include/STARE/"
    export STARE_LIB_DIR="/home/mbauer/.local/lib/"

Step 2: Install PySTARE (https://github.com/SpatioTemporal/pystare)

Step 1a: Clone PySTARE repo

    $ cd 
    $ gh repo clone SpatioTemporal/pystare
    $ cd pystare

Step 1b: Install some dependencies (be sure pyevn mystare being used). Some of these libraries are not strictly required.
    $ pip install numpy
    $ pip install -U pytest
    $ pip install sphinx-markdown-tables sphinx-automodapi myst_parser nbsphinx numpydoc pydata-sphinx-theme
    $ pip install astropy
    $ pip install jupyterlab
    $ pip install Cython
    $ pip install Cartopy 
    $ pip install cftime 
    $ pip install matplotlib
    $ pip install netCDF4 
    $ pip install pandas 
    $ pip install proj
    $ pip install pyproj
    $ pip install python-dateutil
    $ pip install pyshp 
    $ pip install scipy
    $ pip install Shapely
    $ pip install xarray 
    $ pip install geopandas
    $ pip install jupyter               

    $ sudo apt -y install pandoc

    # install pyhdf
    $ sudo apt -y install libhdf4-dev
    $ sudo apt -y install zlib1g-dev
    $ sudo apt -y install libjpeg-dev

    $ cd 
    $ gh repo clone fhs/pyhdf; cd pyhdf
    # Activate virtual environment
    $ pyenv activate mystare
    $ pyenv local mystare   

    $ export INCLUDE_DIRS="/usr/include/hdf/"
    $ export LIBRARY_DIRS="/usr/lib/"
    $ export SZIP=1

    Modify setup.py
        szip_installed=False

    python setup.py install -i $INCLUDE_DIRS
        ...
        adding license file 'AUTHORS'
        writing manifest file 'pyhdf.egg-info/SOURCES.txt'
        Copying pyhdf.egg-info to /home/mbauer/.pyenv/versions/mystare/lib/python3.10/site-packages/pyhdf-0.10.5-py3.10.egg-info
        running install_scripts
        running install_clib
        INFO: customize UnixCCompiler
        INFO: 
        ########### EXT COMPILER OPTIMIZATION ###########
        INFO: Platform      : 
          Architecture: x64
          Compiler    : gcc

        CPU baseline  : 
          Requested   : 'min'
          Enabled     : SSE SSE2 SSE3
          Flags       : -msse -msse2 -msse3
          Extra checks: none

        CPU dispatch  : 
          Requested   : 'max -xop -fma4'
          Enabled     : SSSE3 SSE41 POPCNT SSE42 AVX F16C FMA3 AVX2 AVX512F AVX512CD AVX512_KNL AVX512_KNM AVX512_SKX AVX512_CLX AVX512_CNL AVX512_ICL
          Generated   : none
        INFO: CCompilerOpt.cache_flush[857] : write cache to path -> /home/mbauer/pyhdf/build/temp.linux-x86_64-cpython-310/ccompiler_opt_cache_ext.py

  Step 1c: Install pystare

    $ export STARE_INCLUDE_DIR="/home/mbauer/.local/include/STARE/"
    $ export STARE_LIB_DIR="/home/mbauer/.local/lib/"

    $ python setup.py build_ext --inplace 
        running build_ext
        building 'pystare._core' extension
        swigging pystare/PySTARE.i to pystare/PySTARE_wrap.cpp
        swig -python -c++ -o pystare/PySTARE_wrap.cpp pystare/PySTARE.i
        creating build
        creating build/temp.linux-x86_64-cpython-310
        creating build/temp.linux-x86_64-cpython-310/pystare
        ...
        creating build/lib.linux-x86_64-cpython-310
        creating build/lib.linux-x86_64-cpython-310/pystare
        g++ -shared -L/home/mbauer/.pyenv/versions/3.10.5/lib -L/home/mbauer/.pyenv/versions/3.10.5/lib build/temp.linux-x86_64-cpython-310/pystare/PySTARE.o build/temp.linux-x86_64-cpython-310/pystare/PySTARE_wrap.o -L/home/mbauer/.local/lib/ -lSTARE -o build/lib.linux-x86_64-cpython-310/pystare/_core.cpython-310-x86_64-linux-gnu.so
        copying build/lib.linux-x86_64-cpython-310/pystare/_core.cpython-310-x86_64-linux-gnu.so -> pystare

    This creates
        /home/mbauer/.pyenv/versions/mystare/lib/python3.10/site-packages/pystare.egg-link

    $ pip install -e .
        Obtaining file:///home/mbauer/pystare
          Installing build dependencies ... done
          Checking if build backend supports build_editable ... done
          Getting requirements to build wheel ... done
          Preparing metadata (pyproject.toml) ... done
        Requirement already satisfied: numpy>=1.21.6 in /home/mbauer/.pyenv/versions/3.10.5/envs/mystare/lib/python3.10/site-packages (from pystare==0.8.8+3.g7848bd2) (1.23.1)
        Installing collected packages: pystare
          Running setup.py develop for pystare
        Successfully installed pystare-0.8.8+3.g7848bd2

    Test:
        $ pytest --doctest-modules 
            ================================================= test session starts ==================================================
            platform linux -- Python 3.10.5, pytest-7.1.2, pluggy-1.0.0
            rootdir: /home/mbauer/pystare, configfile: pytest.ini
            plugins: anyio-3.6.1
            collected 90 items                                                                                                     

            pystare/spatial.py ....................s                                                                         [ 23%]
            pystare/temporal.py ......................                                                                       [ 47%]
            tests/test_compress.py .                                                                                         [ 48%]
            tests/test_intersect_single_res.py .                                                                             [ 50%]
            tests/test_intersections.py ........                                                                             [ 58%]
            tests/test_spatial.py ..................                                                                         [ 78%]
            tests/test_srange.py .......                                                                                     [ 86%]
            tests/test_temporal.py ..........                                                                                [ 97%]
            tests/test_temporal_strings.py .                                                                                 [ 98%]
            tests/test_temporal_tai.py .                                                                                     [100%]

            ============================================ 89 passed, 1 skipped in 28.08s ============================================

        # Test Spatial (from README.md)
        $ python
            >>> import numpy
            >>> import pystare
            >>>     
            >>> 
            >>> lat = numpy.array([30,45,60], dtype=numpy.double)
            >>> lon = numpy.array([45,60,10], dtype=numpy.double)
            >>> 
            >>> indices = pystare.from_latlon(lat, lon, 12)
            >>> print('0 indices: ', [hex(i) for i in indices])
            0 indices:  ['0x399d1bcabd6f926c', '0x39c1ea506ef249cc', '0x3290c3321a355ccc']
            >>> 
            >>> lat, lon = pystare.to_latlon(indices)
            >>> print(lat, lon)
            [30.00000012 45.00000003 59.99999986] [44.99999991 60.00000013  9.9999999 ]
            >>> 
            >>> lat, lon, level = pystare.to_latlonlevel(indices)
            >>> print(lat, lon, level)
            [30.00000012 45.00000003 59.99999986] [44.99999991 60.00000013  9.9999999 ] [12 12 12]
            >>> 
            >>> level = pystare.to_level(indices)
            >>> print(level)
            [12 12 12]
            >>> 
            >>> area = pystare.to_area(indices)
            >>> print(area)
            [8.66507750e-08 8.74786654e-08 7.97819113e-08]

        # Test Temporal (from README.md)          ## NEEDS FIX?
        $ python        
            >>> import numpy
            >>> import pystare
            >>> 
            >>> datetime = numpy.array(['1970-01-01T00:00:00', 
            ...                         '2000-01-01T00:00:00', 
            ...                         '2002-02-03T13:56:03.172', 
            ...                         '2016-01-05T17:26:00.172'], dtype=numpy.datetime64)
            >>> print(datetime)
            ['1970-01-01T00:00:00.000' '2000-01-01T00:00:00.000'
             '2002-02-03T13:56:03.172' '2016-01-05T17:26:00.172']
            >>> print(datetime.astype(numpy.int64))
            [            0  946684800000 1012744563172 1452014760172]
            >>>     
            >>> index = pystare.from_utc(datetime.astype(numpy.int64), 6)
            Traceback (most recent call last):
              File "<stdin>", line 1, in <module>
            AttributeError: module 'pystare' has no attribute 'from_utc'

            >>> dir(pystare)
                ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__version__', '_core', '_version', 
                 'adapt_resolution_to_proximity', 'adapt_resolutions_shape', 'analyze_iso8601_string', 'cmp_spatial', 'cmp_temporal', 'coarsen', 'coarsest_resolution_finer_or_equal_ms', 
                 'core', 'cover_from_hull', 'cover_from_ring', 'datetime', 'exceptions', 'expand_intervals', 'force_3ms', 'forward_resolution', 'from_intervals', 'from_iso_strings', 
                 'from_julian_date', 'from_latlon', 'from_latlon_2d', 'from_lonlat', 'from_ms_since_epoch_utc', 'from_stare_timestrings', 'from_temporal_triple', 'from_utc_variable', 
                 'hex2int', 'int2bin', 'int2hex', 'intersect', 'intersection', 'intersects', 'iso_to_stare_timestrings', 'latlon2circular_cover', 'lon_wrap_180', 'lower_bound_ms', 
                 'lower_bound_tai', 'milliseconds_at_resolution', 'now', 'numpy', 'pystare', 're', 'reverse_resolution', 'set_forward_resolution', 'set_reverse_resolution', 
                 'set_temporal_resolutions_from_sorted', 'sid2circular_cover', 'spatial', 'spatial_clear_to_resolution', 'spatial_coerce_resolution', 'spatial_increment_from_level', 
                 'spatial_resolution', 'spatial_resolution_from_km', 'spatial_scale_km', 'spatial_terminator', 'spatial_terminator_mask', 'temporal', 'temporal_contains_instant', 
                 'temporal_overlap', 'temporal_overlap_tai', 'temporal_value_intersection_if_overlap', 'temporal_value_union_if_overlap', 'to_area', 'to_box_cover_from_latlon',
                  'to_compressed_range', 'to_hull_range', 'to_hull_range_from_latlon', 'to_julian_date', 'to_latlon', 'to_latlonlevel', 'to_level', 'to_ms_since_epoch_utc', 
                  'to_neighbors', 'to_nonconvex_hull_range_from_latlon', 'to_stare_timestring', 'to_temporal_triple_ms', 'to_temporal_triple_tai', 'to_vertices_latlon', 'triangulate', 
                  'triangulate_indices', 'upper_bound_ms', 'upper_bound_tai', 'validate_iso8601_string', 'validate_iso8601_strings', 'validate_stare_timestring', 'validate_stare_timestrings', 'warnings']

            Maybe fix based on tests/test_temporal.py  

                class MainTest:
                    def test_fromutc_a(self):
                        index = pystare.from_ms_since_epoch_utc(datetime.astype(numpy.int64), 6, 6)
                        # print(list(map(hex16,index)))
                        expected = numpy.array([0x1ec8000008000619, 0x1f40000020000619, 0x1f484ade232b0619, 0x1f800916a42b0619])
                        numpy.testing.assert_array_equal(index, expected)

                    def test_fromutc_b(self):
                        index = pystare.from_ms_since_epoch_utc(datetime.astype(numpy.int64), 27, 27)
                        # print(list(map(hex16,index)))
                        expected = numpy.array([0x1ec8000008001b6d, 0x1f40000020001b6d, 0x1f484ade232b1b6d, 0x1f800916a42b1b6d])
                        numpy.testing.assert_array_equal(index, expected)

                import numpy
                import pystare

                datetime = numpy.array(['1970-01-01T00:00:00', 
                                        '2000-01-01T00:00:00', 
                                        '2002-02-03T13:56:03.172', 
                                        '2016-01-05T17:26:00.172'], dtype=numpy.datetime64)
                print(datetime)
                print(datetime.astype(numpy.int64))

                # index = pystare.from_utc(datetime.astype(numpy.int64), 6)
                index = pystare.from_ms_since_epoch_utc(datetime.astype(numpy.int64), 6, 6)
                print([hex(i) for i in index])

                # index = pystare.from_utc(datetime.astype(numpy.int64), 27)
                index = pystare.from_ms_since_epoch_utc(datetime.astype(numpy.int64), 27, 27)
                print([hex(i) for i in index])

            >>> import numpy
            >>> import pystare
            >>> 
            >>> datetime = numpy.array(['1970-01-01T00:00:00', 
            ...                         '2000-01-01T00:00:00', 
            ...                         '2002-02-03T13:56:03.172', 
            ...                         '2016-01-05T17:26:00.172'], dtype=numpy.datetime64)
            >>> print(datetime)
            ['1970-01-01T00:00:00.000' '2000-01-01T00:00:00.000'
             '2002-02-03T13:56:03.172' '2016-01-05T17:26:00.172']
            >>> print(datetime.astype(numpy.int64))
            [            0  946684800000 1012744563172 1452014760172]
            >>>     
            >>> # index = pystare.from_utc(datetime.astype(numpy.int64), 6)
            >>> index = pystare.from_ms_since_epoch_utc(datetime.astype(numpy.int64), 6, 6)
            >>> print([hex(i) for i in index])
            ['0x1ec8000008000619', '0x1f40000020000619', '0x1f484ade232b0619', '0x1f800916a42b0619']
            >>> 
            >>> # index = pystare.from_utc(datetime.astype(numpy.int64), 27)
            >>> index = pystare.from_ms_since_epoch_utc(datetime.astype(numpy.int64), 27, 27)
            >>> print([hex(i) for i in index])
            ['0x1ec8000008001b6d', '0x1f40000020001b6d', '0x1f484ade232b1b6d', '0x1f800916a42b1b6d']

        $ cd tests
        $ python test_compress.py       
        $ python test_intersect_single_res.py  
        $ python test_srange.py    
        $ python test_temporal_strings.py
        $ python test_intersections.py  
        $ python test_spatial.py
        $ python test_temporal.py  
            Ran 10 tests in 0.023s
            OK
            ...
            all passed          
        $ python test_temporal_tai.py
            .
            ----------------------------------------------------------------------
            Ran 1 test in 0.003s

            OK

        # Try jupyter notebooks in examples/

            $ which jupyter-lab
                /home/mbauer/.pyenv/versions/mystare/bin/jupyter-lab

            $ python -m ipykernel install --user --name mystare --display-name "Python (mystare)"
                Installed kernelspec mystare in /home/mbauer/.local/share/jupyter/kernels/mystare

            $ jupyter --paths
                config:
                    /home/mbauer/.jupyter
                    /home/mbauer/.pyenv/versions/3.10.5/envs/mystare/etc/jupyter
                    /usr/local/etc/jupyter
                    /etc/jupyter
                data:
                    /home/mbauer/.local/share/jupyter
                    /home/mbauer/.pyenv/versions/3.10.5/envs/mystare/share/jupyter
                    /usr/local/share/jupyter
                    /usr/share/jupyter
                runtime:
                    /home/mbauer/.local/share/jupyter/runtime

             $ jupyter notebook
                example-viz-1.ipynb
                    Works
                example-viz-2.ipynb
                    Works                    
                example-viz-2a.ipynb
                    Works                    
                example-viz-3.ipynb         ## NEEDS FIX?
                    triangulating1...
                    triangulating1 done.
                    hull0:  1416
                    triangulating1...
                    triangulating1 done.
                    triangulating1...
                    triangulating1 done.

                    ---------------------------------------------------------------------------
                    AttributeError                            Traceback (most recent call last)
                    Input In [3], in <cell line: 24>()
                         21 triang2 = tri.Triangulation(lons2,lats2,intmat2)
                         23 # idx1  = ps.from_latlon(np.array([1.5],dtype=np.double),np.array([0.5],dtype=np.double),10)
                    ---> 24 cover = ps.to_circular_cover(1.5,0.5,0.25,13)
                         25 latco,lonco,latcco,loncco = ps.to_vertices_latlon(cover)
                         26 lons3,lats3,intmat3 = triangulate1(latco,lonco)

                    AttributeError: module 'pystare' has no attribute 'to_circular_cover'

                expand_intervals.ipynb
                    Works                    
                intersect_single_res.ipynb
                    Works                    
                spatial_conversions.ipynb
                     Works                   
                temporal.ipynb
                    Works                    

    # Generate documentation
        $ cd docs/
        $ make html
            Running Sphinx v5.1.1
            [autosummary] generating autosummary for: README.md, examples/index.rst, examples/notebooks/example-viz-1.ipynb, examples/notebooks/example-viz-2.ipynb, examples/notebooks/example-viz-2a.ipynb, examples/notebooks/example-viz-3.ipynb, examples/notebooks/expand_intervals.ipynb, examples/notebooks/intersect_single_res.ipynb, examples/notebooks/spatial_conversions.ipynb, examples/notebooks/temporal.ipynb, ..., reference/api2/pystare.temporal.to_temporal_triple_tai.rst, reference/api2/pystare.temporal.upper_bound_ms.rst, reference/api2/pystare.temporal.upper_bound_tai.rst, reference/api2/pystare.temporal.validate_iso8601_string.rst, reference/api2/pystare.temporal.validate_iso8601_strings.rst, reference/api2/pystare.temporal.validate_stare_timestring.rst, reference/api2/pystare.temporal.validate_stare_timestrings.rst, reference/spatial.rst, reference/temporal.rst, reference/temporal2.rst
            [automodsumm] reference/spatial.rst: found 39 automodsumm entries to generate
            [automodsumm] reference/temporal2.rst: found 38 automodsumm entries to generate
            myst v0.18.0: MdParserConfig(commonmark_only=False, gfm_only=False, enable_extensions=[], disable_syntax=[], all_links_external=False, url_schemes=('http', 'https', 'mailto', 'ftp'), ref_domains=None, highlight_code_blocks=True, number_code_blocks=[], title_to_header=False, heading_anchors=None, heading_slug_func=None, footnote_transition=True, words_per_minute=200, sub_delimiters=('{', '}'), linkify_fuzzy_links=True, dmath_allow_labels=True, dmath_allow_space=True, dmath_allow_digits=True, dmath_double_inline=False, update_mathjax=True, mathjax_classes='tex2jax_process|mathjax_process|math|output_area')
            building [mo]: targets for 0 po files that are out of date
            building [html]: targets for 121 source files that are out of date
            updating environment: [new config] 121 added, 0 changed, 0 removed
            ...
            lots of warnings and errors
            ...
            looking for now-outdated files... none found
            pickling environment... done
            checking consistency... done
            preparing documents... done
            writing output... [100%] reference/temporal2                                                                            
            generating indices... genindex done
            copying notebooks ... [100%] examples/notebooks/temporal.ipynb                                                          
            writing additional pages... search done
            copying images... [100%] ../build/doctrees/nbsphinx/examples_notebooks_spatial_conversions_9_0.svg                      
            copying static files... done
            copying extra files... done
            dumping search index in English (code: en)... done
            dumping object inventory... done
            build succeeded, 36 warnings.

            The HTML pages are in build/html.