{"id":15716368,"url":"https://github.com/NeuroJSON/jsonlab","last_synced_at":"2025-10-14T19:30:38.577Z","repository":{"id":21802337,"uuid":"25124906","full_name":"NeuroJSON/jsonlab","owner":"NeuroJSON","description":"JSONLab: compact, portable, robust JSON/binary-JSON encoder/decoder for MATLAB/Octave","archived":false,"fork":false,"pushed_at":"2025-08-31T02:16:34.000Z","size":1036,"stargazers_count":319,"open_issues_count":0,"forks_count":119,"subscribers_count":16,"default_branch":"master","last_synced_at":"2025-10-13T01:53:56.739Z","etag":null,"topics":["binary-data","binary-json","bjdata","data-exchange","decoding","encoding","hdf5","hierarchical-data","jmesh","jnifti","jsnirf","json","matlab","messagepack","neurojson","serialization","ubjson"],"latest_commit_sha":null,"homepage":"http://iso2mesh.sf.net/jsonlab","language":"MATLAB","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/NeuroJSON.png","metadata":{"files":{"readme":"README.rst","changelog":"ChangeLog.txt","contributing":null,"funding":null,"license":"LICENSE_BSD.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS.txt","dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2014-10-12T16:27:42.000Z","updated_at":"2025-10-03T22:35:34.000Z","dependencies_parsed_at":"2023-01-11T21:21:36.432Z","dependency_job_id":"dc52d9d6-78ae-4505-9352-957c76367742","html_url":"https://github.com/NeuroJSON/jsonlab","commit_stats":{"total_commits":510,"total_committers":15,"mean_commits":34.0,"dds":"0.38431372549019605","last_synced_commit":"fea26cd17ff4ecdca7038829d6fecc71156dd8d1"},"previous_names":["fangq/jsonlab"],"tags_count":20,"template":false,"template_full_name":null,"purl":"pkg:github/NeuroJSON/jsonlab","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NeuroJSON%2Fjsonlab","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NeuroJSON%2Fjsonlab/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NeuroJSON%2Fjsonlab/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NeuroJSON%2Fjsonlab/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NeuroJSON","download_url":"https://codeload.github.com/NeuroJSON/jsonlab/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NeuroJSON%2Fjsonlab/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279020650,"owners_count":26086898,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-14T02:00:06.444Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["binary-data","binary-json","bjdata","data-exchange","decoding","encoding","hdf5","hierarchical-data","jmesh","jnifti","jsnirf","json","matlab","messagepack","neurojson","serialization","ubjson"],"created_at":"2024-10-03T21:45:15.377Z","updated_at":"2025-10-14T19:30:38.228Z","avatar_url":"https://github.com/NeuroJSON.png","language":"MATLAB","readme":".. image:: https://neurojson.org/wiki/upload/neurojson_banner_long.png\n\n########################################################################################\n JSONLab: compact, portable, robust JSON/binary-JSON encoder/decoder for MATLAB/Octave\n########################################################################################\n\n* Copyright (c) 2011-2024  Qianqian Fang \u003cq.fang at neu.edu\u003e\n* License: BSD or GNU General Public License version 3 (GPL v3), see License*.txt\n* Version: 2.9.8 (Micronus Prime - Beta)\n* URL: https://neurojson.org/jsonlab\n* Download: https://neurojson.org/wiki/index.cgi?keywords=registration\u0026tool=jsonlab\u0026ref=github\n* User forum: https://github.com/orgs/NeuroJSON/discussions/categories/neurojson-json-format-specifications-and-parsers\n* JData Specification Version: V1 Draft-3 (https://neurojson.org/jdata/draft3)\n* Binary JData Specification Version: V1 Draft-2 (https://neurojson.org/bjdata/draft2)\n* JSON-Mmap Specification Version: V1 Draft-1 (https://neurojson.org/jsonmmap/draft1)\n* Compatibility: MATLAB R2008 or newer, GNU Octave 3.8 or newer\n* Acknowledgement: This project is supported by US National Institute of Health (NIH) \n  grant `U24-NS124027 \u003chttps://reporter.nih.gov/project-details/10308329\u003e`_\n\n.. image:: https://github.com/NeuroJSON/jsonlab/actions/workflows/run_test.yml/badge.svg\n    :target: https://github.com/NeuroJSON/jsonlab/actions/workflows/run_test.yml\n\n#################\nTable of Contents\n#################\n.. contents::\n  :local:\n  :depth: 3\n\n============\nWhat's New\n============\n\nWe are excited to announce that the JSONLab project, as the official reference library\nfor both `JData \u003chttps://neurojson.org/jdata/draft3\u003e`_ and `BJData \u003chttps://neurojson.org/bjdata/draft2\u003e`_\nspecifications, has been funded by the US National Institute of Health (NIH) as\npart of the NeuroJSON project (https://neurojson.org and https://neurojson.io).\n\nThe goal of the NeuroJSON project is to develop scalable, searchable, and\nreusable neuroimaging data formats and data sharing platforms. All data\nproduced from the NeuroJSON project will be using JSON/Binary JData formats as the\nunderlying serialization standards and the lightweight JData specification as\nlanguage-independent data annotation standard, all of which have been evolved \nfrom the over a decade development of JSONLab.\n\nJSONLab v2.9.8 - code named \"Micronus Prime - beta\" - is the beta-release of the next milestone (v3.0),\ncontaining a number of key feature enhancements and bug fixes. The major\nnew features include\n\n1. exporting JSON Memory-Map (``jsonget,jsonset``) for rapid disk-map like reading/writing of JSON/binary JSON files\n   and writing, implementing `JSON-Mmap spec v1 Draft 1 \u003chttps://github.com/NeuroJSON/jsonmmap\u003e`_\n2. supporting JSONPath query (``jsonpath``) to MATLAB data and JSON/binary JSON file and streams, including\n   deep-scan operators,\n3. (**breaking**) upgrading the supported BJData spec to `V1 Draft 2 \u003chttps://neurojson.org/bjdata/draft2\u003e`_\n   where the default numerical data byte order changed from Big-Endian to **Little-Endian**,\n4. adding initial support to JData `_DataLink_ \u003chttps://github.com/NeuroJSON/jdata/blob/master/JData_specification.md#data-referencing-and-links\u003e`_ \n   decoding to link multiple JSON/binary JSON files\n5. dynamically cache linked data files (``jsoncache``, ``jdlink``) to permit on-demand download and \n   processing of complex JSON-encoded datasets such as neuroimaging datasets hosted on https://neurojson.io\n6. support high-performance Blosc2 meta-compressor for storing large N-D array data,\n7. ``savejson/loadjson`` can use MATLAB/Octave built-in ``jsonencode/jsondecode`` using the ``BuiltinJSON`` option\n8. automatically switch from ``struct`` to ``containers.Map`` when encoded key-length exceeds 63\n9. provide fall-back zlib/gzip compression/decompression function (``octavezmat``) on Octave when ZMat is not installed\n10. include built-in ``.nii/.nii.gz/.jnii/.h5/.snirf/.tsv/.csv`` parsers to allow loadjd.m to read wide range of files\n11. include ``json2couch`` from jbids (https://github.com/NeuroJSON/jbids) to allow uploading json files to CouchDB server\n\nThere have been many major updates added to this release since the previous \nrelease v2.0 in June 2020. A list of the major changes are summarized below\n(with key features marked by \\*), including the support to BJData Draft-2 specification,\nnew interface functions ``savejd/loadjd``, and options to use MATLAB/Octave built-in\n``jsonencode/jsondecode`` functions. The ``octave-jsonlab`` package has also been\nincluded in the official distributions of Debian Bullseye and Ubuntu 21.04 or newer.\n\n- 2024-03-28 [b39c374] [feat] add json2couch from jbids toolbox\n- 2024-03-27*[2e43586] [feat] merge ``nii/jnii/hdf5/tsv`` reading functions self-contained\n- 2024-03-27 [b482c8f] [test] pass all tests on matlab R2010b\n- 2024-03-27 [2008934] [doc] additional documentations on decompression functions\n- 2024-03-27 [0a582fb] [doc] add documentations for jsonpath, jsoncache, jdlink, and maxlinklevel\n- 2024-03-27 [5dba1de] [bug] ``..`` searches deep level of struct, make jdlink work for Octave 4.2 and 5.2\n- 2024-03-27 [fea481e] [doc] add line-by-line comment on examples, add ``jsonset/jsonget``\n- 2024-03-26 [e1d386d] [feat] support saving dictionary to json and bjdata\n- 2024-03-26 [dfc744b] [feat] support caching data from any URL using hash, add ``NO_ZMAT`` flag\n- 2024-03-24 [22d297e] [doc] fix README.rst formatting issues\n- 2024-03-24 [7e27db5] [doc] update documentation, preparing for v2.9.8 release\n- 2024-03-24 [1227a0b] [format] reformat\n- 2024-03-24 [67f30ca] [feat] support using \\. or [] in JSONPath to escape dots in key names\n- 2024-03-24 [ee830cd] [bug] fix error_pos error when giving a non-existant input file\n- 2024-03-24 [d69686d] [feat] add jdlink to dynamically download and cache linked data\n- 2024-03-22 [772a1ef] [ci] fix octave failed test\n- 2024-03-22*[cff529a] [test] add jsonpath test, refine jsonpath syntax support\n- 2024-03-22 [22435e4] [bug] fix jsonpath handling of recursive deep scans\n- 2024-03-21 [c9f8a20] [bug] support deep scan in cell and struct, merge struct/containers.Map\n- 2024-03-21 [394394a] [bug] improve jsonpath cell with deep scan\n- 2024-03-20 [a599e71] [feat] add jsoncache to handle ``_DataLink_`` download cache, rename jsonpath\n- 2024-02-19*[4f2edeb] [feat] support .. jsonpath operator for deep scan\n- 2024-01-11 [c43a758] [bug] fix missing index_esc reset, add test for automap\n- 2024-01-11*[ef5b472] [feat] automatically switch to map object when key length \u003e 63\n- 2023-11-17 [ee24122] use sprintf to replace unescapejsonstring\n- 2023-11-12 [abe504f] [ci] test again on macos-12\n- 2023-11-12 [d2ff26a] [ci] install octave via conda on macos to avoid hanged install\n- 2023-11-07 [33263de] completely reformat m-files using miss_hit\n- 2023-11-07 [3ff781f] make octavezmat work on matlab\n- 2023-10-29 [ea4a4fd] make test script run on MATLAB R2010b\n- 2023-10-27 [ca91e07] use older matlab due to matlab-actions/run-command#43\n- 2023-10-27 [4bf8232] add NO_ZMAT flag, fix fread issue\n- 2023-10-27*[ce3c0a0] add fallback zlib/glib support on Octave via file-based zip/unzip\n- 2023-10-26 [7ab1b6e] fix error for expecting an ending object mark when count is given\n- 2023-09-08 [6dfa58e] Fix typos found by codespell\n- 2023-06-27 [7d7e7f7] fix typo of compression method\n- 2023-06-27*[c25dd0f] support blosc2 codecs in save and load data, upgrade jsave/jload\n- 2023-06-19 [b23181a] test root-level indentation\n- 2023-06-19 [5bfde65] add indentation test\n- 2023-06-19 [b267858] fix CI errors related to octave utf-8 handling\n- 2023-06-19 [1e93d07] avoid octave 6.4+ regexp non-utf8 error see discussions at octave bug thread: https://savannah.gnu.org/bugs/index.php?57107\n- 2023-06-15 [8f921ac] fix broken tests\n- 2023-06-11*[6cb5f12] allow linking binary jdata files inside json\n- 2023-06-10 [2d0649b] do not compress long string by default, read bjd from URI\n- 2023-06-10 [5135dea] saving JSON with UTF-8 encoding, fix #71\n- 2023-06-10*[a3c807f] add zstdencode and zstddecode via new version of zmat\n- 2023-06-07 [837c8b5] fix containers.Map indentiation bug with a single element\n- 2023-06-07 [747c99b] fix string indentation, add option EmptyArrayAsNull, fix #91\n- 2023-06-05*[cf57326] support blosc2 meta compressors\n- 2023-05-05 [d37a386] use {:} to expand varargin\n- 2023-04-23 [03311d2] remove README.txt, no longer used, fix #88\n- 2023-04-21 [49eceb0] Fix typo not found by codespell\n- 2023-04-21 [75b1fdc] Fix typos found by codespell\n- 2023-04-17 [8fea393] revert savejson change\n- 2023-04-17 [9554a44] Merge branch 'master' of github.com:NeuroJSON/jsonlab\n- 2023-04-17 [3c32aff] speed up string encoding and decoding\n- 2023-04-09*[8c8464f] rename jamm files to pmat - portable mat, will add jsonmmap\n- 2023-04-09 [aa1c2a4] drop ubuntu-18.04\n- 2023-04-08 [9173525] replace regexp to ismember due to octave bug 57107; test mac\n- 2023-04-08 [67065dc] fix matlab test\n- 2023-04-08 [8dcedad] use alternative test to avoid octave bug 57107\n- 2023-04-08*[9b6be7b] add github action based tests\n- 2023-02-24 [cb43ed1] add bug fix test section\n- 2023-02-24 [2412ebf] only simplify all-numeric or all-struct cells\n- 2023-02-23 [d4e77e1] add missing file extension\n- 2023-02-23 [408cc2e] fix loadjd and savejd file extension match, add jbids\n- 2023-02-22 [29bac9d] fix broken jdatahash\n- 2023-02-22*[69a7d01] add a portable data hash function\n- 2023-02-09 [0448eb1] preventing matlab 2022b converting string to unicode\n- 2022-11-21 [9ce91fc] handle empty struct with names, fix #85\n- 2022-11-20 [9687d17] accept string typed file name, close #84\n- 2022-08-12 [283e5f1] output data depends on nargout\n- 2022-08-08 [c729048] avoid conjugating complex numbers, fix #83\n- 2022-06-05*[fa35843] implementing JSON-Mmap spec draft 1, https://neurojson.org/jsonmmap/draft1\n- 2022-05-18 [8b74d30] make savejd work for saveh5 to save hdf5 files\n- 2022-04-19 [f1332e3] make banner image transparent background\n- 2022-04-19 [6cf82a6] fix issues found by dependency check\n- 2022-04-19 [94167bb] change neurojson urls to https\n- 2022-04-19 [c4c4da1] create Contents.m from matlab\n- 2022-04-19*[2278bb1] stop escaping / to \\/ in JSON string, see https://mondotondo.com/2010/12/29/the-solidus-issue/\n- 2022-04-01*[fb711bb] add loadjd and savejd as the unified JSON/binary JSON file interface\n- 2022-03-30 [4433a21] improve datalink uri handling to consider : inside uri\n- 2022-03-30 [6368409] make datalink URL query more robust\n- 2022-03-29 [dd9e9c6] when file suffix is missing, assume JSON feed\n- 2022-03-29*[07c58f3] initial support for ``_DataLink_`` of online/local file with JSONPath ref\n- 2022-03-29 [897b7ba] fix test for older octave\n- 2022-03-20 [bf03eff] force msgpack to use big-endian\n- 2022-03-13 [46bbfa9] support empty name key, which is valid in JSON, fix #79\n- 2022-03-12 [9ab040a] increase default float number digits from 10 to 16, fix #78\n- 2022-03-11 [485ea29] update error message on the valid root-level markers\n- 2022-02-23 [aa3913e] disable TFN marker in optimized header due to security risk and low benefit\n- 2022-02-23 [f2c3223] support SCH{[ markers in optimized container type\n- 2022-02-14 [540f95c] add optional preceding whitespace, explain format\n- 2022-02-13 [3dfa904] debugged and tested mmap, add mmapinclude and mmapexclude options\n- 2022-02-10*[6150ae1] handle uncompressed raw data (only base64 encoded) in jdatadecode\n- 2022-02-10 [88a59eb] give a warning when jdatadecode fails, but still return the raw data\n- 2022-02-03*[05edb7a] fast reading and writing json data record using mmap and jsonpath\n- 2022-02-02*[b0f0ebd] return disk-map or memory-map table in loadjson\n- 2022-02-01 [0888218] correct typos and add additional descriptions in README\n- 2022-02-01*[03133c7] fix row-major ('formatversion',1.8) ND array storage order, update demo outputs\n- 2022-02-01 [5998c70] revert variable name encoding to support unicode strings\n- 2022-01-31 [16454e7] test flexible whitespaces in 1D/2D arrays, test mixed array from string\n- 2022-01-31*[5c1ef15] accelerate fastarrayparser by 200%! jsonlab_speedtest cuts from 11s to 5.8s\n- 2022-01-30 [9b25e20] fix octave 3.8 error on travis, it does not support single\n- 2022-01-30 [5898f6e] add octave 5.2 to travis\n- 2022-01-30*[2e3344c] [bjdata:breaking] Upgrade ``savebj/loadbj`` to BJData v1-draft 2, use little-endian by default\n- 2022-01-30*[2e3344c] [bjdata:breaking] Fix optimized ND array element order (previously used column-major)\n- 2022-01-30*[2e3344c] optimize loadjson and loadbj speed\n- 2022-01-30*[2e3344c] add 'BuiltinJSON' option for ``savejson/loadjson`` to call ``jsonencode/jsondecode``\n- 2022-01-30*[2e3344c] more robust tests on ND array when parsing JSON numerical array construct\n- 2021-06-23 [632531f] fix inconsistency between singlet integer and float values, close #70\n- 2021-06-23 [f7d8226] prevent function calls when parsing array strings using eval, fix #75\n- 2021-06-23 [b1ae5fa] fix #73 as a regression to #22\n- 2021-11-22*[       ] octave-jsonlab is officially in Debian Testing/Bullseye\n- 2020-09-29 [d0cb3b8] Fix for loading objects.\n- 2020-07-26 [d0fb684] Add travis badge\n- 2020-07-25 [708c36c] drop octave 3.2\n- 2020-07-25 [436d84e] debug octave 3.2\n- 2020-07-25 [0ce96ec] remove windows and osx targets from travis-ci\n- 2020-07-25 [0d8baa4] fix ruby does not support error on windows\n- 2020-07-25*[faa7921] enable travis-ci for jsonlab\n- 2020-07-08 [321ab1a] add Debian and Ubuntu installation commands\n- 2020-07-08 [e686828] update author info\n- 2020-07-08*[ce40fdf] supports ND cell array, fix #66\n- 2020-07-07 [6a8ce93] fix string encoding over 399 characters, close #65\n- 2020-06-14 [5a58faf] fix DESCRIPTION date bug\n- 2020-06-14 [9d7e94c] match octave description file and upstream version number\n- 2020-06-14 [a5b6170] fix warning about ``lz4encode`` file name\n\n\nPlease note that the ``savejson/loadjson`` in both JSONLab v2.0-v3.0 are\ncompliant with JData Spec Draft 3; the ``savebj/loadbj`` in JSONLab v3.0 is\ncompatible to BJData spec Draft 2, which contains breaking feature changes\ncompared to those in JSONLab v2.0.\n\nThe BJData spec was derived from UBJSON spec Draft 12, with the \nfollowing breaking differences:\n\n- BJData adds 4 new numeric data types: ``uint16 [u]``, ``uint32 [m]``, ``uint64 [M]`` \n  and ``float16 [h]`` (supported in JSONLab v2.0 or newer)\n- BJData supports an optimized ND array container (supported in JSONLab since 2013)\n- BJData does not convert ``NaN/Inf/-Inf`` to ``null`` (supported in JSONLab since 2013)\n- BJData Draft 2 changes the default byte order to Little-Endian instead of Big-Endian (JSONLab 3.0 or later)\n- BJData only permits non-zero-fixed-length data types as the optimized array type, i.e. only ``UiuImlMLhdDC`` are allowed\n\nTo avoid using the new features, one should attach ``'UBJSON',1`` and ``'Endian','B'``\nin the ``savebj`` command as\n\n.. code-block::\n\n   savebj('',data,'FileName','myfile.bjd','UBJSON',1, 'Endian','B');\n\nTo read BJData data files generated by JSONLab v2.0, you should call\n\n.. code-block::\n\n   data=loadbj('my_old_data_file.bjd','Endian','B')\n\nYou are strongly encouraged to convert all pre-v2.9 JSONLab generated BJD or .pmat\nfiles using the new format.\n\n\n============\nIntroduction\n============\n\nJSONLab is an open-source JSON/UBJSON/MessagePack encoder and decoder written \ncompletely in the native MATLAB language. It can be used to convert most MATLAB \ndata structures (array, struct, cell, struct array, cell array, and objects) into \nJSON/UBJSON/MessagePack formatted strings and files, or to parse a \nJSON/UBJSON/MessagePack file into a MATLAB data structure. JSONLab supports both \nMATLAB and `GNU Octave \u003chttp://www.gnu.org/software/octave\u003e`_ (a free MATLAB clone).\n\nCompared to other MATLAB/Octave JSON parsers, JSONLab is uniquely lightweight, \nultra-portable, producing dependable outputs across a wide-range of MATLAB \n(tested on R2008) and Octave (tested on v3.8) versions. It also uniquely supports \nBinaryJData/UBJSON/MessagePack data files as binary-JSON-like formats, designed \nfor efficiency and flexibility with loss-less binary storage. As a parser written\ncompletely with the native MATLAB language, it is surprisingly fast when reading \nsmall-to-moderate sized JSON files (1-2 MB) with simple hierarchical structures,\nand is heavily optimized for reading JSON files containing large N-D arrays\n(known as the \"fast array parser\" in ``loadjson``).\n\nJSON (`JavaScript Object Notation \u003chttp://www.json.org/\u003e`_) is a highly portable, \nhuman-readable and `\"fat-free\" \u003chttp://en.wikipedia.org/wiki/JSON\u003e`_ text format \nto represent complex and hierarchical data, widely used for data-exchange in applications.\nUBJSON (`Universal Binary JSON \u003chttp://ubjson.org/\u003e`_) is a binary JSON format,  \ndesigned to specifically address the limitations of JSON, permitting the\nstorage of binary data with strongly typed data records, resulting in smaller\nfile sizes and fast encoding and decoding. MessagePack is another binary\nJSON-like data format widely used in data exchange in web/native applications.\nIt is slightly more compact than UBJSON, but is not directly readable compared\nto UBJSON.\n\nWe envision that both JSON and its binary counterparts will play important \nroles for storage, exchange and interoperation of large-scale scientific data\namong the wide-variety of tools. As container-formats, they offer both the \nflexibility and generality similar to other more sophisticated formats such \nas `HDF5 \u003chttp://www.hdfgroup.org/HDF5/whatishdf5.html\u003e`_, but are significantly \nsimpler with a much greater software ecosystem.\n\nTowards this goal, we have developed the JData Specification (http://github.com/NeuroJSON/jdata) \nto standardize serializations of complex scientific data structures, such as\nN-D arrays, sparse/complex-valued arrays, trees, maps, tables and graphs using\nJSON/binary JSON constructs. The text and binary formatted JData files are\nsyntactically compatible with JSON/UBJSON formats, and can be readily parsed \nusing existing JSON and UBJSON parsers. JSONLab is not just a parser and writer \nof JSON/UBJSON data files, but one that systematically converts complex scientific\ndata structures into human-readable and universally supported JSON forms using the\nstandardized JData data annotations.\n\n\n================\nInstallation\n================\n\nThe installation of JSONLab is no different from installing any other\nMATLAB toolbox. You only need to download/unzip the JSONLab package\nto a folder, and add the folder's path to MATLAB/Octave's path list\nby using the following command:\n\n.. code:: shell\n\n    addpath('/path/to/jsonlab');\n\nIf you want to add this path permanently, you can type ``pathtool``, \nbrowse to the JSONLab root folder and add to the list, then click \"Save\".\nThen, run ``rehash`` in MATLAB, and type ``which savejson``, if you see an \noutput, that means JSONLab is installed for MATLAB/Octave.\n\nIf you use MATLAB in a shared environment such as a Linux server, the\nbest way to add path is to type \n\n.. code:: shell\n\n   mkdir ~/matlab/\n   nano ~/matlab/startup.m\n\nand type ``addpath('/path/to/jsonlab')`` in this file, save and quit the editor.\nMATLAB will execute this file every time it starts. For Octave, the file\nyou need to edit is ``~/.octaverc``, where ``~`` is your home directory.\n\nTo use the data compression features, please download the ZMat toolbox from\nhttps://github.com/NeuroJSON/zmat/releases/latest and follow the instruction to\ninstall ZMat first. The ZMat toolbox is required when compression is used on \nMATLAB running in the ``-nojvm`` mode or GNU Octave, or 'lzma/lzip/lz4/lz4hc' \ncompression methods are specified. ZMat can also compress large arrays that \nMATLAB's Java-based compression API does not support.\n\n-------------------------------------\nInstall JSONLab on Fedora 24 or later\n-------------------------------------\n\nJSONLab has been available as an official Fedora package since 2015. You may\ninstall it directly using the below command\n\n.. code:: shell\n\n   sudo dnf install octave-jsonlab\n\nTo enable data compression/decompression, you need to install ``octave-zmat`` using\n\n.. code:: shell\n\n   sudo dnf install octave-zmat\n   \nThen open Octave, and type ``pkg load jsonlab`` to enable jsonlab toolbox.\n\n-------------------------\nInstall JSONLab on Debian\n-------------------------\n\nJSONLab is currently available on Debian Bullseye. To install, you may run\n\n.. code:: shell\n\n   sudo apt-get install octave-jsonlab\n\nOne can alternatively install ``matlab-jsonlab`` if MATLAB is available.\n\n-------------------------\nInstall JSONLab on Ubuntu\n-------------------------\n\nJSONLab is currently available on Ubuntu 21.04 or newer as package\n`octave-jsonlab`. To install, you may run\n\n.. code:: shell\n\n   sudo apt-get install octave-jsonlab\n\nFor older Ubuntu releases, one can add the below PPA\n\nhttps://launchpad.net/~fangq/+archive/ubuntu/ppa\n\nTo install, please run\n\n.. code:: shell\n\n   sudo add-apt-repository ppa:fangq/ppa\n   sudo apt-get update\n\nto add this PPA, and then use\n\n.. code:: shell\n\n   sudo apt-get install octave-jsonlab\n\nto install the toolbox. ``octave-zmat`` will be automatically installed.\n\n------------------------------\nInstall JSONLab on Arch Linux\n------------------------------\n\nJSONLab is also available on Arch Linux. You may install it using the below command\n\n.. code:: shell\n\n   sudo pikaur -S jsonlab\n\n================\nUsing JSONLab\n================\n\nJSONLab provides a pair of functions, ``loadjson`` -- a JSON parser, and ``savejson`` -- \na MATLAB-to-JSON encoder, to read/write the text-based JSON; it also provides\nthree equivalent pairs -- ``loadbj/savebj`` for binary JData, ``loadubjson/saveubjson``\nfor UBJSON and ``loadmsgpack/savemsgpack`` for MessagePack. The ``load*`` functions \nfor the 3 supported data formats share almost the same input parameter format, \nsimilarly for the 3 ``save*`` functions (``savejson/saveubjson/savemsgpack``).\nThese encoders and decoders are capable of processing/sharing almost all \ndata structures supported by MATLAB, thanks to ``jdataencode/jdatadecode`` - \na pair of in-memory data converters translating complex MATLAB data structures\nto their easy-to-serialized forms according to the JData specifications.\nThe detailed help information can be found in the ``Contents.m`` file.\n\nIn JSONLab 2.9.8 and later versions, a unified file loading and saving interface\nis provided for JSON, binary JSON and HDF5, including ``loadjd`` and ``savejd``\nfor reading and writing below files types:\n\n- JSON based files: ``.json``, ``.jdt`` (text JData file), ``.jmsh`` (text JMesh file),\n  ``.jnii`` (text JNIfTI file), ``.jnirs`` (text JSNIRF file)\n- BJData based files: ``.bjd``, ``.jdb`` (binary JData file), ``.bmsh`` (binary JMesh file),\n  ``.bnii`` (binary JNIfTI file), ``.bnirs`` (binary JSNIRF file), ``.pmat`` (MATLAB session file)\n- UBJSON based files: ``.ubj``\n- MessagePack based files: ``.msgpack``\n- HDF5 based files: ``.h5``, ``.hdf5``, ``.snirf`` (SNIRF fNIRS data files) - require `EasyH5 toolbox \u003chttps://github.com/NeuroJSON/easyh5\u003e`_\n\n\nIn the below section, we provide a few examples on how to us each of the \ncore functions for encoding/decoding JSON/Binary JSON/MessagePack data.\n\n----------\nsavejson.m\n----------\n\n.. code-block::\n\n       jsonmesh=struct('MeshNode',[0 0 0;1 0 0;0 1 0;1 1 0;0 0 1;1 0 1;0 1 1;1 1 1],... \n                'MeshElem',[1 2 4 8;1 3 4 8;1 2 6 8;1 5 6 8;1 5 7 8;1 3 7 8],...\n                'MeshSurf',[1 2 4;1 2 6;1 3 4;1 3 7;1 5 6;1 5 7;...\n                           2 8 4;2 8 6;3 8 4;3 8 7;5 8 6;5 8 7],...\n                'MeshCreator','FangQ','MeshTitle','T6 Cube',...\n                'SpecialData',[nan, inf, -inf]);\n\n       % convert any matlab variables to JSON (variable name is used as the root name)\n       savejson(jsonmesh)\n\n       % convert matlab variables to JSON with a root-name \"jmesh\"\n       savejson('jmesh',jsonmesh)\n\n       % an empty root-name directly embed the data in the root {}\n       % the compact=1 flag prints JSON without white-space in a single-line\n       savejson('',jsonmesh,'Compact',1)\n\n       % if 3 inputs are given, the 3rd parameter defines the output file name\n       savejson('jmesh',jsonmesh,'outputfile.json')\n\n       % param/value pairs can be provided after the 2nd input to customize outputs\n       % if you want to use params/values and save JSON to a file, you must use the 'filename' to set output file\n       savejson('',jsonmesh,'FileName','outputfile2.json','ArrayIndent',0,'FloatFormat','\\t%.5g')\n\n       % jsonlab utilizes JData annotations to encode complex/sparse ND-arrays\n       savejson('cpxrand',eye(5)+1i*magic(5))\n\n       % when setting 'BuiltinJSON' to 1, savejson calls jsonencode.m in MATLAB (R2016+)\n       % or Octave (v7+) to convert data to JSON; this is typically faster, but does not\n       % support all features native savejson offers\n       savejson('cpxrand',eye(5)+1i*magic(5), 'BuiltinJSON', 1)\n\n       % JData annotations also allows one to compress binary strongly-typed data and store in the JSON\n       % gzip/zlib are natively supported in MATLAB and Octave; using ZMat toolbox, one can use lz4, lzma, blosc2 etc compressors\n       savejson('ziparray',eye(10),'Compression','zlib','CompressArraySize',1)\n\n       % 'ArrayToStruct' flag forces all arrays to use the JData ND array annotations to preserve types\n       savejson('',jsonmesh,'ArrayToStruct',1)\n\n       % JData supports compact storage of special matrices using the '_ArrayShape_' annotation\n       savejson('',eye(10),'UseArrayShape',1)\n\n----------\nloadjson.m\n----------\n\n.. code-block::\n\n       % loadjson can directly parse a JSON string if it starts with \"[\" or \"{\", here is an empty object\n       loadjson('{}')\n\n       % loadjson can also parse complex JSON objects in a string form\n       dat=loadjson('{\"obj\":{\"string\":\"value\",\"array\":[1,2,3]}}')\n       \n       % if the input is a file name, loadjson reads the file and parse the data inside\n       dat=loadjson(['examples' filesep 'example1.json'])\n\n       % param/value pairs can be used following the 1st input to customize the parsing behavior\n       dat=loadjson(['examples' filesep 'example1.json'],'SimplifyCell',0)\n\n       % if a URL is provided, loadjson reads JSON data from the URL and return the parsed results,\n       % similar to webread, except loadjson calls jdatadecode to decode JData annotations\n       dat=loadjson('https://raw.githubusercontent.com/NeuroJSON/jsonlab/master/examples/example1.json')\n\n       % using the 'BuildinJSON' flag, one can use the built-in jsondecode.m in MATLAB (R2016+)\n       % or Octave (7.0+) to parse the JSON data for better speed, note that jsondecode encode\n       % key names differently compared to loadjson\n       dat=loadjson('{\"_obj\":{\"string\":\"value\",\"array\":[1,2,3]}}', 'builtinjson', 1)\n\n       % when the JSON data contains long key names, one can use 'UseMap' flag to\n       % request loadjson to store the data in a containers.Map instead of struct (key name limited to 63)\n       dat=loadjson('{\"obj\":{\"an object with a key longer than 63\":\"value\",\"array\":[1,2,3]}}', 'UseMap', 1)\n\n       % loadjson can further download the linked data pointed by _DataLink_ tag, and merge with the parent\n       dat=loadjson('{\"obj\":{\"_DataLink_\":\"https://raw.githubusercontent.com/NeuroJSON/jsonlab/master/examples/example1.json\"},\"array\":[1,2]}','maxlinklevel',1)\n\n       % a JSONPath can be attached to the URL to retrieve a sub element\n       dat=loadjson('{\"obj\":{\"_DataLink_\":\"https://raw.githubusercontent.com/NeuroJSON/jsonlab/master/examples/example1.json:$.address.city\"},\"array\":[1,2]}','maxlinklevel',1)\n\n       % loadjson can optionally return a JSON-memory-map object, which defines each JSON element's\n       % memory buffer offset and length to enable disk-map like fast read/write operations\n       [dat, mmap]=loadjson('{\"obj\":{\"key\":\"value\",\"array\":[1,2,3]}}')\n\n       % if set 'mmaponly' to 1, loadjson only returns the JSON-mmap structure\n       mmap=loadjson('{\"obj\":{\"key\":\"value\",\"array\":[1,2,3]}}', 'mmaponly', 1)\n\n--------\nsavebj.m\n--------\n\n.. code-block::\n\n       % savebj works almost exactly like savejson, except that the output is the more compact binary JSON\n       a={single(rand(2)), struct('va',1,'vb','string'), 1+2i};\n       savebj(a)\n\n       % customizing the root-name using the 1st input, and the 3rd input setting the output file\n       savebj('rootname',a,'testdata.ubj')\n\n       % enabling the 'debug' flag to allow printing binary JSON in text-form, helping users to run tests or troubleshoot\n       savebj('rootname',a, 'debug',1)\n\n       % like savejson, savebj also allow data compression for even more compact storage\n       savebj('zeros',zeros(100),'Compression','gzip')\n\n       % binary JSON does not need base64-encoding, therefore, the output can be ~33% smaller than text-based JSON\n       [length(savebj('magic',magic(100),'Compression','zlib')), length(savejson('magic',magic(100),'Compression','zlib'))]\n\n       % savebj can output other popular binary JSON formats, such as MessagePack or UBJSON\n       savebj('mesh',a,'FileName','meshdata.msgpk','MessagePack',1)  % same as calling savemsgpack\n       savebj('mesh',a,'FileName','meshdata.ubj','UBJSON',1)         % same as calling saveubjson\n\n--------\nloadbj.m\n--------\n\n.. code-block::\n\n       % similarly, loadbj does almost exactly the same as loadjson, but it parses binary JSON instead\n       obj=struct('string','value','array',single([1 2 3]),'empty',[],'magic',uint8(magic(5)));\n       ubjdata=savebj('obj',obj);\n\n       % loadbj can load a binary JSON (BJData - a derived format from UBJSON) object from a buffer\n       dat=loadbj(ubjdata)\n\n       % you can test if loadbj parsed object still matches the data saved using savebj\n       class(dat.obj.array)\n       isequaln(obj,dat.obj)\n\n       % similarly, savebj/loadbj can compress/decompress binary array data using various compressors\n       dat=loadbj(savebj('',eye(10),'Compression','zlib','CompressArraySize',1))\n\n       % if given a path to a binary JSON file (.jdb,.bnii,.pmat,.jmsh,...), it opens and parses the file\n       dat=loadbj('/path/to/a/binary_json.jdb');\n\n       % loadbj can directly load binary JSON data files from URL, here is a binary-JSON based NIfTI file\n       dat=loadbj('https://neurojson.org/io/stat.cgi?action=get\u0026db=abide\u0026doc=CMU_b\u0026file=0a429cb9101b733f594eefc1261d6985-zlib.bnii')\n\n       % similar to loadjson, loadbj can also return JSON-memory-map to permit disk-map\n       % like direct reading/writing of specific data elements\n       [dat, mmap]=loadbj(ubjdata)\n       mmap=loadbj(ubjdata, 'mmaponly', 1)\n\n-------------\njdataencode.m\n-------------\n\n.. code-block::\n\n       % jdataencode transforms complex MATLAB data structures (ND-array, sparse array, complex arrays,\n       % table, graph, containers.Map etc) into JSON-serializable forms using portable JData annotations\n       % here, we show how to save a complex-valued sparse array using JSON JData annotations\n       testdata = struct('a',rand(5)+1i*rand(5),'b',[],'c',sparse(5,5));\n       jd=jdataencode(testdata)\n       savejson('',jd)\n\n       % when setting 'annotatearray' to 1, jdataencode uses _ArrayType_/_ArraySize_/_ArrayData_\n       % JData tags to store ND array to preserve data types; use 'prefix' to customize variable name prefix\n       encodedmat=jdataencode(single(magic(5)),'annotatearray',1,'prefix','x')\n\n       % when setting 'usearrayshape' to 1, jdataencode can use _ArrayShape_ to encode special matrices\n       encodedtoeplitz=jdataencode(uint8(toeplitz([1,2,3,4],[1,5,6])),'usearrayshape',1)\n\n-------------\njdatadecode.m\n-------------\n\n.. code-block::\n\n       % jdatadecode does the opposite to jdataencode, it recognizes JData annotations and convert\n       % those back to MATLAB native data structures, such as ND-arrays, tables, graph etc\n       rawdata=struct('a',rand(5)+1i*rand(5),'b',[],'c',sparse(5,5));\n       jd=jdataencode(rawdata)\n       newjd=jdatadecode(jd)\n\n       % we can test that the decoded data are the same as the original\n       isequaln(newjd,rawdata)\n\n       % if one uses jsondecode to parse a JSON object, the output JData annotation name prefix is different\n       % jsondecode adds \"x_\" as prefix\n       rawdecode_builtin = jsondecode(savejson('',rawdata));\n       rawdecode_builtin.a\n       finaldecode=jdatadecode(rawdecode_builtin)\n\n       % in comparison, loadjson calls encodevarname.m, producing \"x0x5F_\" as prefix (hex for '_')\n       % encodevarname encoded names can be reversed to original decodevarname.m\n       rawdecode_jsonlab = loadjson(savejson('',rawdata), 'jdatadecode', 0);\n       rawdecode_jsonlab.a\n       finaldecode=jdatadecode(rawdecode_jsonlab)\n\n--------\nsavejd.m\n--------\n\n.. code-block::\n\n       % savejd is a unified interface for savejson/savebj/savemsgpack/saveh5 depending on the output file suffix\n       a={single(rand(2)), struct('va',1,'vb','string'), 1+2i};\n       savejd('', a, 'test.json')\n       savejd('', a, 'test.jdb')\n       savejd('', a, 'test.ubj')\n       savejd('', a, 'test.h5')\n\n--------\nloadjd.m\n--------\n\n.. code-block::\n\n       % loadjd is a unified interface for loadjson/loadbj/loadmsgpack/loadh5/load/loadjnifti depending on the input file suffix\n       % supported types include .json,.jnii,.jdt,.jmsh,.jnirs,.jbids,.bjd,.bnii,.jdb,.bmsh,.bnirs,.ubj,.msgpack,\n       % .h5,.hdf5,.snirf,.pmat,.nwb,.nii,.nii.gz,.tsv,.tsv.gz,.csv,.csv.gz,.mat,.bvec,.bval; input can be an URL\n       data = loadjd('test.json');\n       data = loadjd('test.jdb');\n       data = loadjd('test.ubj');\n       data = loadjd('test.h5');\n       data = loadjd('file:///path/to/test.jnii');\n       data = loadjd('https://neurojson.org/io/stat.cgi?action=get\u0026db=abide\u0026doc=CMU_b\u0026file=0a429cb9101b733f594eefc1261d6985-zlib.bnii');\n\n---------\njsonget.m\n---------\n\n.. code-block::\n\n       % loadjson/loadbj JSON-memory-map (mmap) output returned by loadjson or loadbj\n       % each mmap contains a pair of JSONPath and two numbers [offset, length] of the object in bytes in the buffer/file\n       jsonstr = '{\"obj\":{\"string\":\"value\",\"array\":[1,2,3]}}';\n       mmap=loadjson(jsonstr, 'mmaponly', 1)\n\n       % mmap = [ [\"$\",[1,42]], [\"$.obj\",[8,34]], [\"$.obj.string\",[18,7]], [\"$.obj.array\",[34,7]] ]\n       % this means there are 4 objects, root '$', with its content starting byte 1, with a length of 42 bytes;\n       % content of object '$.obj' starts byte 8, with a length of 34 bytes\n       mmap{:}\n\n       % using the above mmap, jsonget can return any raw data without needing to reparse jsonstr\n       % below command returns '[1,2,3]' as a string by following the offset/length data in mmap\n       jsonget(jsonstr, mmap, '$.obj.array')\n\n       % you can request multiple objects by giving multiple JSONPath keys\n       jsonget(jsonstr, mmap, '$.obj', '$.obj.string')\n\n       % you can request multiple objects by giving multiple JSONPath keys\n       jsonget(jsonstr, mmap, '$.obj', '$.obj.string')\n\n       % jsonget not only can fast reading a JSON string buffer, it can also do disk-map read of a file\n       mmap = loadjson('/path/to/data.json', 'mmaponly', 1);\n       jsonget('/path/to/data.json', mmap, '$.obj')\n\n---------\njsonset.m\n---------\n\n.. code-block::\n\n       % using JSON mmap, one can rapidly modify the content of JSON object pointed by a path\n       jsonstr = '{\"obj\":{\"string\":\"value\",\"array\":[1,2,3]}}';\n       mmap=loadjson(jsonstr, 'mmaponly', 1)\n\n       % we can rewrite object $.obj.array by changing its value '[1,2,3]' to a string \"test\"\n       % this returns the updated jsonstr as '{\"obj\":{\"string\":\"value\",\"array\":\"test\" }}'\n       % the new value of a key must not have longer bytes than the original value\n       jsonset(jsonstr, mmap, '$.obj.array', '\"test\"')\n\n       % one can change multiple JSON objects, below returns '{\"obj\":{\"string\":\"new\"  ,\"array\":[]     }}'\n       jsonset(jsonstr, mmap, '$.obj.string', '\"new\"', '$.obj.array', '[]')\n\n       % if mmap is parsed from a file, jsonset can perform disk-map like fast writing to modify the json content\n       mmap = loadjson('/path/to/data.json', 'mmaponly', 1);\n       jsonset('/path/to/data.json', mmap, '$.obj.string', '\"new\"', '$.obj.array', '[]')\n\n----------\njsonpath.m\n----------\n\n.. code-block::\n\n       % JSONPath is a widely supported standard to index/search a large struct, such as those loaded from a JSON file\n       % the jsonpath.m function implements a subset of the features\n       % the below command returns the value of obj.key subfield, which is \"value\"\n       obj = loadjson('{\"obj\":{\"key\":\"value1\",\"array\":[1,2,3],\"sub\":{\"key\":\"value2\",\"array\":[]}}}');\n       jsonpath(obj, '$.obj.key')\n\n       % using [] operator, one can also index array elements, index start from 0; the output below is 2\n       jsonpath(obj, '$.obj.array[1]')\n\n       % [] operator supports range, for example below commands yields [1,2]\n       jsonpath(obj, '$.obj.array[0:1]')\n\n       % a negative index in [] counting elements backwards, -1 means the last element\n       jsonpath(obj, '$.obj.array[-1]')\n\n       % jsonpath.m supports JSONPath's deep-scan operator '..', it traverses through the struct\n       % and find all keys following .., here the output is {\"value1\", \"value2\"}\n       jsonpath(obj, '$.obj..key')\n\n       % you can further concatenate JSONPath operators to select outputs from the earlier ones, this outputs {'value2'}\n       jsonpath(obj, '$.obj..key[1]')\n\n       % instead of .keyname, you can use [keyname], below command is the same as above\n       jsonpath(obj, '$[obj]..[key][1]')\n\n       % one can escape special char, such as \".\", in the key using special\\.key or [special.key]\n       jsonpath(obj, '$.obj.special\\.key.sub')\n\n\n-----------\njsoncache.m\n-----------\n\n.. code-block::\n\n       % the _DataLink_ annotation in the JData specification permits linking of external data files\n       % in a JSON file - to make downloading/parsing externally linked data files efficient, such as\n       % processing large neuroimaging datasets hosted on http://neurojson.io, we have developed a system\n       % to download files on-demand and cache those locally. jsoncache.m is responsible of searching\n       % the local cache folders, if found the requested file, it returns the path to the local cache;\n       % if not found, it returns a SHA-256 hash of the URL as the file name, and the possible cache folders\n       %\n       % When loading a file from URL, below is the order of cache file search paths, ranking in search order\n       %\n       %    global-variable NEUROJSON_CACHE | if defined, this path will be searched first\n       %    [pwd '/.neurojson']             | on all OSes\n       %    /home/USERNAME/.neurojson       | on all OSes (per-user)\n       %    /home/USERNAME/.cache/neurojson | if on Linux (per-user)\n       %    /var/cache/neurojson            | if on Linux (system wide)\n       %    /home/USERNAME/Library/neurojson| if on MacOS (per-user)\n       %    /Library/neurojson              | if on MacOS (system wide)\n       %    C:\\ProgramData\\neurojson        | if on Windows (system wide)\n       %\n       % When saving a file from a URL, under the root cache folder, subfolders can be created;\n       % if the URL is one of a standard NeuroJSON.io URLs as below\n       %\n       %    https://neurojson.org/io/stat.cgi?action=get\u0026db=DBNAME\u0026doc=DOCNAME\u0026file=sub-01/anat/datafile.nii.gz\n       %    https://neurojson.io:7777/DBNAME/DOCNAME\n       %    https://neurojson.io:7777/DBNAME/DOCNAME/datafile.suffix\n       %\n       % the file datafile.nii.gz will be downloaded to /home/USERNAME/.neurojson/io/DBNAME/DOCNAME/sub-01/anat/ folder\n       % if a URL does not follow the neurojson.io format, the cache folder has the below form\n       %\n       %    CACHEFOLDER{i}/domainname.com/XX/YY/XXYYZZZZ...\n       %\n       % where XXYYZZZZ.. is the SHA-256 hash of the full URL, XX is the first two digit, YY is the 3-4 digits\n\n       % below command searches CACHEFOLDER{i}/io/openneuro/ds000001/sub-01/anat/, and return the path/filename\n       [cachepath, filename] = jsoncache('https://neurojson.org/io/stat.cgi?action=get\u0026db=openneuro\u0026doc=ds000001\u0026file=sub-01/anat/sub-01_inplaneT2.nii.gz\u0026size=669578')\n\n       % this searches CACHEFOLDER{i}/raw.githubusercontent.com/55/d2, and the filename is 55d24a4bad6ecc3f5dc4d333be728e01c26b696ef7bc5dd0861b7fa672a28e8e.json\n       [cachepath, filename] = jsoncache('https://raw.githubusercontent.com/NeuroJSON/jsonlab/master/examples/example1.json')\n\n       % this searches cachefolder{i}/io/adhd200/Brown folder, and look for file Brown.json\n       [cachepath, filename] = jsoncache('https://neurojson.io:7777/adhd200/Brown')\n\n       % this searches cachefolder{i}/io/openneuro/ds003805 folder, and look for file ds003805.json\n       [cachepath, filename] = jsoncache('https://neurojson.io:7777/openneuro/ds003805')\n\n-----------\njdlink.m\n-----------\n\n.. code-block::\n\n       % jdlink dynamically downloads, caches and parses data files from one or multiple URLs\n       % jdlink calls jsoncache to scan cache folders first, if a cache copy exists, it loads the cache first\n\n       % here we download a dataset from NeuroJSON.io, containing many linked data files\n       data = loadjson('https://neurojson.io:7777/openneuro/ds000001');\n\n       % we now use jsonpath to scan all linked resources under subfolder \"anat\"\n       alllinks = jsonpath(data, '$..anat.._DataLink_')\n\n       % let's download all linked nifti files (total 4) for sub-01 and sub-02, and load the files as niidata\n       niidata = jdlink(alllinks, 'regex', 'sub-0[12]_.*\\.nii');\n\n       % if you just want to download/cache all files and do not want to parse the files, you can run\n       jdlink(alllinks);\n\n---------\nexamples\n---------\n\nUnder the ``examples`` folder, you can find several scripts to demonstrate the\nbasic utilities of JSONLab. Running the ``demo_jsonlab_basic.m`` script, you \nwill see the conversions from MATLAB data structure to JSON text and backward.\nIn ``jsonlab_selftest.m``, we load complex JSON files downloaded from the Internet\nand validate the ``loadjson/savejson`` functions for regression testing purposes.\nSimilarly, a ``demo_ubjson_basic.m`` script is provided to test the ``saveubjson``\nand ``loadubjson`` functions for various matlab data structures, and \n``demo_msgpack_basic.m`` is for testing ``savemsgpack`` and ``loadmsgpack``.\n\nPlease run these examples and understand how JSONLab works before you use\nit to process your data.\n\n------------\nunit testing\n------------\n\nUnder the ``test`` folder, you can find a script to test individual data types and\ninputs using various encoders and decoders. This unit testing script also serves as\na **specification validator** to the JSONLab functions and ensure that the outputs\nare compliant to the underlying specifications.\n\n========================================\nIn-memory data compression/decompression\n========================================\n\nJSONLab contains a set of functions to perform in-memory buffer data compression and\ndecompression\n\n----------------------------------------------------------------------------\nData Compression: {zlib,gzip,base64,lzma,lzip,lz4,lz4hc,zstd,blosc2}encode.m\n----------------------------------------------------------------------------\n\n.. code-block::\n\n      % MATLAB running with jvm provides zlib and gzip compression natively\n      % one can also install ZMat (https://github.com/NeuroJSON/zmat) to do zlib(.zip) or gzip (.gz) compression\n      output = zlibencode(diag([1,2,3,4]))\n      [output, info] = zlibencode(uint8(magic(8)))\n      outputbase64 = char(base64encode(output(:)))\n\n      % char, numeric and logical ND-arrays are acceptable inputs to the compression functions\n      [output, info] = gzipencode(uint8(magic(8)))\n\n      % setting a negative integer between -1 to -9 to set compression level: -9 being the highest\n      [output, info] = zlibencode(uint8(magic(8)), -9)\n\n      % other advanced compressions are supported but requires ZMat\n      % lzma offers the highest compression rate, but slow compresison speed\n      output = lzmaencode(uint8(magic(8)))\n\n      % lz4 offers the fastest compression speed, but slightly low compression ratio\n      output = lz4encode(peaks(10))\n      output = lz4hcencode(uint8(magic(8)))\n\n      % zstd has a good balanced speed/ratio, similar to zlib\n      output = zstdencode(peaks(10))\n      output = zstdencode(peaks(10), -9)\n\n-----------------------------------------------------------------------------\nData Deompression: {zlib,gzip,base64,lzma,lzip,lz4,lz4hc,zstd,blosc2}decode.m\n-----------------------------------------------------------------------------\n\n.. code-block::\n\n      % passing on a compressed byte-array buffer to *decode function decompresses the buffer\n      [compressed, info] = zlibencode(eye(10));\n\n      % the decompressed buffer is a byte-array\n      decompressd = zlibdecode(compressed);\n\n      % to fully recover the original data structure, one most use the info struct returned by the compressor\n      decompressd = zlibdecode(compressed, info)\n\n      % if one passes a zlib compressed buffer to a different decompressor, an error is reported\n      decompressd = gzipdecode(compressed, info)\n      outputbase64 = char(base64decode(base64encode('jsonlab test')))\n\n========================================\nUsing ``jsave/jload`` to share workspace\n========================================\n\nStarting from JSONLab v2.0, we provide a pair of functions, ``jsave/jload`` to store\nand retrieve variables from the current workspace, similar to the ``save/load`` \nfunctions in MATLAB and Octave. The files that ``jsave/jload`` reads/writes is by  \ndefault a binary JData file with a suffix ``.pmat``. The file size is comparable\n(can be smaller if use ``lzma`` compression) to ``.mat`` files. This feature\nis currently experimental.\n\nThe main benefits of using .pmat file to share matlab variables include\n\n* a ``.pmat`` file can be 50% smaller than a ``.mat`` file when using \n  ``jsave(..., \"compression\",\"lzma\")``; the only drawback is longer saving time.\n* a ``.pmat`` file can be readily read/opened among many programming environments, including \n  Python, JavaScript, Go, Java etc, where .mat file support is not generally available. \n  Parsers of ``.pmat`` files are largely compatible with BJData's parsers available at \n  https://neurojson.org/#software\n* a ``.pmat`` file is quasi-human-readable, one can see the internal data fields \n  even in a command line, for example using ``strings -n 2 file.pmat | astyle``, \n  making the binary data easy to be understood, shared and reused. \n* ``jsave/jload`` can also use MessagePack and JSON formats as the underlying \n  data storage format, addressing needs from a diverse set of applications. \n  MessagePack parsers are readily available at https://msgpack.org/\n\n----------\njsave.m\n----------\n\n.. code-block::\n\n      jsave    % save the current workspace to default.pmat\n      jsave mydata.pmat\n      jsave('mydata.pmat','vars',{'var1','var2'})\n      jsave('mydata.pmat','compression','lzma')\n      jsave('mydata.json','compression','gzip')\n\n----------\njload.m\n----------\n\n.. code-block::\n\n      jload    % load variables from default.pmat to the current workspace\n      jload mydata.pmat   % load variables from mydata.pmat\n      vars=jload('mydata.pmat','vars',{'var1','var2'}) % return vars.var1, vars.var2\n      jload('mydata.pmat','simplifycell',0)\n      jload('mydata.json')\n\n\n================================================\nSharing JSONLab created data files in Python\n================================================\n\nDespite the use of portable data annotation defined by the JData Specification, \nthe output JSON files created by JSONLab are 100% JSON compatible (with\nthe exception that long strings may be broken into multiple lines for better\nreadability). Therefore, JSONLab-created JSON files (``.json, .jnii, .jnirs`` etc) \ncan be readily read and written by nearly all existing JSON parsers, including\nthe built-in ``json`` module parser in Python.\n\nHowever, we strongly recommend one to use a lightweight ``jdata`` module, \ndeveloped by the same author, to perform the extra JData encoding and decoding\nand convert JSON data directly to convenient Python/Numpy data structures.\nThe ``jdata`` module can also directly read/write UBJSON/Binary JData outputs\nfrom JSONLab (``.bjd, .ubj, .bnii, .bnirs, .pmat`` etc). Using binary JData\nfiles are expected to produce much smaller file sizes and faster parsing,\nwhile maintaining excellent portability and generality.\n\nIn short, to conveniently read/write data files created by JSONLab into Python,\nwhether they are JSON based or binary JData/UBJSON based, one just need to download\nthe below two light-weight python modules:\n\n* **jdata**: PyPi: https://pypi.org/project/jdata/  ; Github: https://github.com/NeuroJSON/pyjdata\n* **bjdata** PyPi: https://pypi.org/project/bjdata/ ; Github: https://github.com/NeuroJSON/pybj\n\nTo install these modules on Python 2.x, please first check if your system has\n``pip`` and ``numpy``, if not, please install it by running (using Ubuntu/Debian as example)\n\n.. code-block:: shell\n\n      sudo apt-get install python-pip python3-pip python-numpy python3-numpy\n\nAfter the installation is done, one can then install the ``jdata`` and ``bjdata`` modules by\n\n.. code-block:: shell\n\n      pip install jdata --user\n      pip install bjdata --user\n\nTo install these modules for Python 3.x, please replace ``pip`` by ``pip3``.\nIf one prefers to install these modules globally for all users, simply\nexecute the above commands using \n\n.. code-block:: shell\n\n      sudo pip install jdata\n      sudo pip install bjdata\n\nThe above modules require built-in Python modules ``json`` and NumPy (``numpy``).\n\nOnce the necessary modules are installed, one can type ``python`` (or ``python3``), and run\n\n.. code-block::\n\n      import jdata as jd\n      import numpy as np\n\n      data1=jd.loadt('myfile.json');\n      data2=jd.loadb('myfile.bjd');\n      data3=jd.loadb('myfile.pmat');\n\nwhere ``jd.loadt()`` function loads a text-based JSON file, performs\nJData decoding and converts the enclosed data into Python ``dict``, ``list`` \nand ``numpy`` objects. Similarly, ``jd.loadb()`` function loads a binary \nJData/UBJSON file and performs similar conversions. One can directly call\n``jd.load()`` to open JSONLab (and derived toolboxes such as **jnifti**: \nhttps://github.com/NeuroJSON/jnifti or **jsnirf**: https://github.com/NeuroJSON/jsnirf) \ngenerated files based on their respective file suffix.\n\nSimilarly, the ``jd.savet()``, ``jd.saveb()`` and ``jd.save`` functions\ncan revert the direction and convert a Python/Numpy object into JData encoded\ndata structure and store as text-, binary- and suffix-determined output files,\nrespectively.\n\n=======================\nKnown Issues and TODOs\n=======================\n\nJSONLab has several known limitations. We are striving to make it more general\nand robust. Hopefully in a few future releases, the limitations become less.\n\nHere are the known issues:\n\n  * 3D or higher dimensional cell/struct-arrays will be converted to 2D arrays\n  * When processing names containing multi-byte characters, Octave and MATLAB \n    can give different field-names; you can use \n    ``feature('DefaultCharacterSet','latin1')`` in MATLAB to get consistent results\n  * ``savejson`` can only export the properties from MATLAB classes, but not the methods\n  * ``saveubjson`` converts a logical array into a ``uint8`` (``[U]``) array\n  * a special N-D array format, as defined in the JData specification, is \n    implemented in ``saveubjson``. You may use ``saveubjson(...,'NestArray',1)``\n    to create UBJSON Draft-12 compliant files \n  * ``loadubjson`` can not parse all UBJSON Specification (Draft 12) compliant \n    files, however, it can parse all UBJSON files produced by ``saveubjson``.\n\n==========================\nContribution and feedback\n==========================\n\nJSONLab is an open-source project. This means you can not only use it and modify\nit as you wish, but also you can contribute your changes back to JSONLab so\nthat everyone else can enjoy the improvement. For anyone who want to contribute,\nplease download JSONLab source code from its source code repositories by using the\nfollowing command:\n\n\n.. code:: shell\n\n      git clone https://github.com/NeuroJSON/jsonlab.git jsonlab\n\nor browsing the github site at\n\n      https://github.com/NeuroJSON/jsonlab\n\nPlease report any bugs or issues to the below URL:\n\n      https://github.com/NeuroJSON/jsonlab/issues\n\nSometimes, you may find it is necessary to modify JSONLab to achieve your \ngoals, or attempt to modify JSONLab functions to fix a bug that you have \nencountered. If you are happy with your changes and willing to share those\nchanges to the upstream author, you are recommended to create a pull-request\non github. \n\nTo create a pull-request, you first need to \"fork\" jsonlab on Github by \nclicking on the \"fork\" button on top-right of JSONLab's github page. Once you forked\njsonlab to your own directory, you should then implement the changes in your\nown fork. After thoroughly testing it and you are confident the modification \nis complete and effective, you can then click on the \"New pull request\" \nbutton, and on the left, select NeuroJSON/jsonlab as the \"base\". Then type\nin the description of the changes. You are responsible to format the code\nupdates using the same convention (tab-width: 8, indentation: 4 spaces) as\nthe upstream code.\n\nWe appreciate any suggestions and feedbacks from you. Please use the following\nuser forum to ask any question you may have regarding JSONLab:\n\n      https://github.com/orgs/NeuroJSON/discussions/categories/neurojson-json-format-specifications-and-parsers\n\n\n\n==========================\nAcknowledgement\n==========================\n\n----------\nloadjson.m\n----------\n\nThe ``loadjson.m`` function was significantly modified from the earlier parsers \n(BSD 3-clause licensed) written by the below authors\n\n* Nedialko Krouchev: http://www.mathworks.com/matlabcentral/fileexchange/25713\n    created on 2009/11/02\n* François Glineur: http://www.mathworks.com/matlabcentral/fileexchange/23393\n    created on  2009/03/22\n* Joel Feenstra:\n    http://www.mathworks.com/matlabcentral/fileexchange/20565\n    created on 2008/07/03\n\n-------------\nloadmsgpack.m\n-------------\n\n* Author: Bastian Bechtold\n* URL: https://github.com/bastibe/matlab-msgpack/blob/master/parsemsgpack.m\n* License: BSD 3-clause license\n\nCopyright (c) 2014,2016 Bastian Bechtold\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without modification, \nare permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this \n  list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice, \n  this list of conditions and the following disclaimer in the documentation \n  and/or other materials provided with the distribution.\n\n* Neither the name of the copyright holder nor the names of its contributors \n  may be used to endorse or promote products derived from this software without \n  specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n---------------------------------------------------------------------------------------\nzlibdecode.m, zlibencode.m, gzipencode.m, gzipdecode.m, base64encode.m, base64decode.m\n---------------------------------------------------------------------------------------\n\n* Author: Kota Yamaguchi\n* URL: https://www.mathworks.com/matlabcentral/fileexchange/39526-byte-encoding-utilities\n* License: BSD License, see below\n\nCopyright (c) 2012, Kota Yamaguchi\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n  and/or other materials provided with the distribution\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FNeuroJSON%2Fjsonlab","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FNeuroJSON%2Fjsonlab","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FNeuroJSON%2Fjsonlab/lists"}