From 1c58ce2d709fbdf54e1b65b10405830ef8f80030 Mon Sep 17 00:00:00 2001 From: CBroz1 Date: Tue, 8 Nov 2022 15:57:31 -0600 Subject: [PATCH 1/4] WIP add docs --- README.md | 45 +-- docs-parts/admin/5-blob-config_lang1.rst | 4 - docs-parts/admin/5-blob-config_lang2.rst | 1 - docs-parts/admin/5-blob-config_lang3.rst | 4 - docs-parts/admin/5-blob-config_lang4.rst | 4 - docs-parts/admin/5-blob-config_lang5.rst | 4 - .../computation/01-autopopulate_lang1.rst | 23 -- .../computation/01-autopopulate_lang2.rst | 4 - .../computation/01-autopopulate_lang3.rst | 3 - .../computation/01-autopopulate_lang4.rst | 28 -- docs-parts/computation/02-keysource_lang1.rst | 1 - docs-parts/computation/02-keysource_lang2.rst | 17 - .../computation/04-master-part_lang1.rst | 52 ---- .../computation/04-master-part_lang2.rst | 4 - .../computation/04-master-part_lang3.rst | 51 --- ...06-distributed-computing_kill_order_by.rst | 14 - .../06-distributed-computing_lang1.rst | 2 - .../06-distributed-computing_lang2.rst | 3 - .../06-distributed-computing_lang3.rst | 3 - .../06-distributed-computing_lang4.rst | 3 - .../06-distributed-computing_lang5.rst | 3 - docs-parts/concepts/04-Integrity_lang1.rst | 25 -- docs-parts/concepts/04-Integrity_lang2.rst | 28 -- docs-parts/concepts/04-Integrity_lang3.rst | 37 --- docs-parts/concepts/04-Integrity_lang4.rst | 34 -- .../definition/01-Creating-Schemas_lang1.rst | 60 ---- .../definition/02-Creating-Tables_lang1.rst | 42 --- .../definition/03-Table-Definition_lang1.rst | 17 - .../definition/03-Table-Definition_lang2.rst | 2 - .../definition/03-Table-Definition_lang3.rst | 4 - .../definition/03-Table-Definition_lang4.rst | 6 - .../definition/07-Primary-Key_lang1.rst | 4 - .../definition/10-Dependencies_lang1.rst | 4 - docs-parts/definition/11-ERD_lang1.rst | 20 -- docs-parts/definition/11-ERD_lang2.rst | 4 - docs-parts/definition/11-ERD_lang3.rst | 5 - docs-parts/definition/11-ERD_lang4.rst | 15 - docs-parts/definition/12-Example_lang1.rst | 48 --- .../definition/13-Lookup-Tables_lang1.rst | 21 -- docs-parts/definition/14-Drop_lang1.rst | 5 - docs-parts/definition/14-Drop_lang2.rst | 4 - .../existing/1-Loading-Classes_lang1.rst | 18 -- docs-parts/index_lang1.rst | 1 - docs-parts/intro/Releases_lang1.rst | 73 ----- docs-parts/manipulation/1-Insert_lang1.rst | 26 -- docs-parts/manipulation/1-Insert_lang2.rst | 9 - docs-parts/manipulation/2-Delete_lang1.rst | 1 - docs-parts/manipulation/2-Delete_lang2.rst | 13 - docs-parts/manipulation/2-Delete_lang3.rst | 4 - .../manipulation/3-Transactions_lang1.rst | 33 -- docs-parts/queries/01-Queries_lang1.rst | 5 - docs-parts/queries/01-Queries_lang2.rst | 5 - docs-parts/queries/01-Queries_lang3.rst | 7 - docs-parts/queries/01-Queries_lang4.rst | 10 - .../queries/02-Example-Schema_lang1.rst | 138 --------- docs-parts/queries/03-Fetch_lang1.rst | 130 -------- docs-parts/queries/04-Iteration_lang1.rst | 11 - docs-parts/queries/06-Restriction_lang1.rst | 7 - docs-parts/queries/06-Restriction_lang2.rst | 4 - docs-parts/queries/06-Restriction_lang3.rst | 8 - docs-parts/queries/06-Restriction_lang4.rst | 17 - docs-parts/queries/06-Restriction_lang5.rst | 11 - docs-parts/queries/06-Restriction_lang6.rst | 4 - docs-parts/queries/06-Restriction_lang7.rst | 0 docs-parts/queries/06-Restriction_lang8.rst | 4 - docs-parts/queries/08-Proj_lang1.rst | 3 - docs-parts/queries/08-Proj_lang2.rst | 4 - docs-parts/queries/08-Proj_lang3.rst | 4 - docs-parts/queries/08-Proj_lang4.rst | 4 - docs-parts/queries/09-Aggr_lang1.rst | 7 - .../queries/11-Universal-Sets_lang1.rst | 18 -- .../setup/01-Install-and-Connect_lang1.rst | 29 -- docs-parts/version_common.json | 3 - docs/.docker/Dockerfile | 15 + docs/.docker/apk_requirements.txt | 1 + docs/.docker/pip_requirements.txt | 6 + docs/.markdownlint.yaml | 20 ++ docs/README.md | 16 + docs/cspell.json | 31 ++ docs/mkdocs.yaml | 108 +++++++ .../.overrides/.icons/main/company-logo.svg | 21 ++ .../.icons/main/project-logo-black.svg | 22 ++ .../assets/images/project-logo-color.png | Bin 0 -> 82925 bytes .../.overrides/assets/stylesheets/extra.css | 64 ++++ docs/src/.overrides/partials/nav.html | 33 ++ docs/src/concepts/existing-pipelines.md | 27 ++ docs/src/getting-started/index.md | 293 ++++++++++++++++++ docs/src/images/shapes_pipeline.svg | 36 +++ docs/src/query-lang/common-commands.md | 154 +++++++++ docs/src/query-lang/iteration.md | 18 ++ docs/src/query-lang/operators.md | 148 +++++++++ docs/src/reproduce/make-method.md | 79 +++++ docs/src/reproduce/table-tiers.md | 202 ++++++++++++ docs/src/tutorials.md | 3 + 94 files changed, 1300 insertions(+), 1266 deletions(-) delete mode 100644 docs-parts/admin/5-blob-config_lang1.rst delete mode 100644 docs-parts/admin/5-blob-config_lang2.rst delete mode 100644 docs-parts/admin/5-blob-config_lang3.rst delete mode 100644 docs-parts/admin/5-blob-config_lang4.rst delete mode 100644 docs-parts/admin/5-blob-config_lang5.rst delete mode 100644 docs-parts/computation/01-autopopulate_lang1.rst delete mode 100644 docs-parts/computation/01-autopopulate_lang2.rst delete mode 100644 docs-parts/computation/01-autopopulate_lang3.rst delete mode 100644 docs-parts/computation/01-autopopulate_lang4.rst delete mode 100644 docs-parts/computation/02-keysource_lang1.rst delete mode 100644 docs-parts/computation/02-keysource_lang2.rst delete mode 100644 docs-parts/computation/04-master-part_lang1.rst delete mode 100644 docs-parts/computation/04-master-part_lang2.rst delete mode 100644 docs-parts/computation/04-master-part_lang3.rst delete mode 100644 docs-parts/computation/06-distributed-computing_kill_order_by.rst delete mode 100644 docs-parts/computation/06-distributed-computing_lang1.rst delete mode 100644 docs-parts/computation/06-distributed-computing_lang2.rst delete mode 100644 docs-parts/computation/06-distributed-computing_lang3.rst delete mode 100644 docs-parts/computation/06-distributed-computing_lang4.rst delete mode 100644 docs-parts/computation/06-distributed-computing_lang5.rst delete mode 100644 docs-parts/concepts/04-Integrity_lang1.rst delete mode 100644 docs-parts/concepts/04-Integrity_lang2.rst delete mode 100644 docs-parts/concepts/04-Integrity_lang3.rst delete mode 100644 docs-parts/concepts/04-Integrity_lang4.rst delete mode 100644 docs-parts/definition/01-Creating-Schemas_lang1.rst delete mode 100644 docs-parts/definition/02-Creating-Tables_lang1.rst delete mode 100644 docs-parts/definition/03-Table-Definition_lang1.rst delete mode 100644 docs-parts/definition/03-Table-Definition_lang2.rst delete mode 100644 docs-parts/definition/03-Table-Definition_lang3.rst delete mode 100644 docs-parts/definition/03-Table-Definition_lang4.rst delete mode 100644 docs-parts/definition/07-Primary-Key_lang1.rst delete mode 100644 docs-parts/definition/10-Dependencies_lang1.rst delete mode 100644 docs-parts/definition/11-ERD_lang1.rst delete mode 100644 docs-parts/definition/11-ERD_lang2.rst delete mode 100644 docs-parts/definition/11-ERD_lang3.rst delete mode 100644 docs-parts/definition/11-ERD_lang4.rst delete mode 100644 docs-parts/definition/12-Example_lang1.rst delete mode 100644 docs-parts/definition/13-Lookup-Tables_lang1.rst delete mode 100644 docs-parts/definition/14-Drop_lang1.rst delete mode 100644 docs-parts/definition/14-Drop_lang2.rst delete mode 100644 docs-parts/existing/1-Loading-Classes_lang1.rst delete mode 100644 docs-parts/index_lang1.rst delete mode 100644 docs-parts/intro/Releases_lang1.rst delete mode 100644 docs-parts/manipulation/1-Insert_lang1.rst delete mode 100644 docs-parts/manipulation/1-Insert_lang2.rst delete mode 100644 docs-parts/manipulation/2-Delete_lang1.rst delete mode 100644 docs-parts/manipulation/2-Delete_lang2.rst delete mode 100644 docs-parts/manipulation/2-Delete_lang3.rst delete mode 100644 docs-parts/manipulation/3-Transactions_lang1.rst delete mode 100644 docs-parts/queries/01-Queries_lang1.rst delete mode 100644 docs-parts/queries/01-Queries_lang2.rst delete mode 100644 docs-parts/queries/01-Queries_lang3.rst delete mode 100644 docs-parts/queries/01-Queries_lang4.rst delete mode 100644 docs-parts/queries/02-Example-Schema_lang1.rst delete mode 100644 docs-parts/queries/03-Fetch_lang1.rst delete mode 100644 docs-parts/queries/04-Iteration_lang1.rst delete mode 100644 docs-parts/queries/06-Restriction_lang1.rst delete mode 100644 docs-parts/queries/06-Restriction_lang2.rst delete mode 100644 docs-parts/queries/06-Restriction_lang3.rst delete mode 100644 docs-parts/queries/06-Restriction_lang4.rst delete mode 100644 docs-parts/queries/06-Restriction_lang5.rst delete mode 100644 docs-parts/queries/06-Restriction_lang6.rst delete mode 100644 docs-parts/queries/06-Restriction_lang7.rst delete mode 100644 docs-parts/queries/06-Restriction_lang8.rst delete mode 100644 docs-parts/queries/08-Proj_lang1.rst delete mode 100644 docs-parts/queries/08-Proj_lang2.rst delete mode 100644 docs-parts/queries/08-Proj_lang3.rst delete mode 100644 docs-parts/queries/08-Proj_lang4.rst delete mode 100644 docs-parts/queries/09-Aggr_lang1.rst delete mode 100644 docs-parts/queries/11-Universal-Sets_lang1.rst delete mode 100644 docs-parts/setup/01-Install-and-Connect_lang1.rst delete mode 100644 docs-parts/version_common.json create mode 100644 docs/.docker/Dockerfile create mode 100644 docs/.docker/apk_requirements.txt create mode 100644 docs/.docker/pip_requirements.txt create mode 100644 docs/.markdownlint.yaml create mode 100644 docs/README.md create mode 100644 docs/cspell.json create mode 100644 docs/mkdocs.yaml create mode 100644 docs/src/.overrides/.icons/main/company-logo.svg create mode 100644 docs/src/.overrides/.icons/main/project-logo-black.svg create mode 100644 docs/src/.overrides/assets/images/project-logo-color.png create mode 100644 docs/src/.overrides/assets/stylesheets/extra.css create mode 100644 docs/src/.overrides/partials/nav.html create mode 100644 docs/src/concepts/existing-pipelines.md create mode 100644 docs/src/getting-started/index.md create mode 100644 docs/src/images/shapes_pipeline.svg create mode 100644 docs/src/query-lang/common-commands.md create mode 100644 docs/src/query-lang/iteration.md create mode 100644 docs/src/query-lang/operators.md create mode 100644 docs/src/reproduce/make-method.md create mode 100644 docs/src/reproduce/table-tiers.md create mode 100644 docs/src/tutorials.md diff --git a/README.md b/README.md index c6c54f1a..00cc6c59 100644 --- a/README.md +++ b/README.md @@ -1,56 +1,17 @@ [![View DataJoint on File Exchange](https://www.mathworks.com/matlabcentral/images/matlab-file-exchange.svg)](https://www.mathworks.com/matlabcentral/fileexchange/63218-datajoint) # Welcome to DataJoint for MATLAB! + DataJoint for MATLAB is a high-level programming interface for relational databases designed to support data processing chains in science labs. DataJoint is built on the foundation of the relational data model and prescribes a consistent method for organizing, populating, and querying data. DataJoint was initially developed in 2009 by Dimitri Yatsenko in Andreas Tolias' Lab at Baylor College of Medicine for the distributed processing and management of large volumes of data streaming from regular experiments. Starting in 2011, DataJoint has been available as an open-source project adopted by other labs and improved through contributions from several developers. Presently, the primary developer of DataJoint open-source software is the company DataJoint (https://datajoint.com). Related resources are listed at https://datajoint.org. -## Installation -
-Click to expand details - -### (Recommended) Greater than R2016b - -1. Utilize MATLAB built-in GUI i.e. *Top Ribbon -> Add-Ons -> Get Add-Ons* -2. Search and Select `DataJoint` -3. Select *Add from GitHub* - -### Using GHToolbox (FileExchange Community Toolbox) - -1. Install *GHToolbox* using using an appropriate method in https://github.com/datajoint/GHToolbox -2. run: `ghtb.install('datajoint/datajoint-matlab')` - -### Less than R2016b - -1. Utilize MATLAB built-in GUI i.e. *Top Ribbon -> Add-Ons -> Get Add-Ons* -2. Search and Select `DataJoint` -3. Select *Download from GitHub* -4. Save `DataJoint.mltbx` locally -5. Navigate in MATLAB tree browser to saved toolbox file -6. Right-Click and Select *Install* -7. Select *Install* - -### From Source - -1. Download `DataJoint.mltbx` locally -2. Navigate in MATLAB tree browser to saved toolbox file -3. Right-Click and Select *Install* -4. Select *Install* - -
+For more information, please visit our [documentation](https://datajoint.com/docs/core/datajoint-matlab/). ## Config For help in utilizing `dj.config` (added in `3.4.0`), you may access the help via `help('dj.config')` or review it online [here](https://github.com/datajoint/datajoint-matlab/blob/c2bd6b3e195dfeef773d4e12bad5573c461193b0/%2Bdj/config.m#L2-L27). Formal documentation to follow. -## Documentation and Tutorials - -* https://datajoint.org -- start page -* https://docs.datajoint.org -- up-to-date documentation -* https://tutorials.datajoint.io -- step-by-step tutorials -* https://elements.datajoint.org -- catalog of example pipelines -* https://codebook.datajoint.io -- interactive online tutorials - ## Citation + If your work uses DataJoint for MATLAB, please cite the following Research Resource Identifier (RRID) and manuscript. @@ -105,4 +66,4 @@ MINIO_VER=RELEASE.2022-01-03T18-22-58Z * Shell into `datajoint-matlab_app_1` i.e. `docker exec -it datajoint-matlab_app_1 bash` * Launch Matlab with no GUI by runnning command `matlab -nodisplay` - \ No newline at end of file + diff --git a/docs-parts/admin/5-blob-config_lang1.rst b/docs-parts/admin/5-blob-config_lang1.rst deleted file mode 100644 index 15bf13b7..00000000 --- a/docs-parts/admin/5-blob-config_lang1.rst +++ /dev/null @@ -1,4 +0,0 @@ -.. note:: - - External storage is not yet implemented in MATLAB. - The feature will be added in an upcoming release: https://github.com/datajoint/datajoint-matlab/issues/143 diff --git a/docs-parts/admin/5-blob-config_lang2.rst b/docs-parts/admin/5-blob-config_lang2.rst deleted file mode 100644 index efae4392..00000000 --- a/docs-parts/admin/5-blob-config_lang2.rst +++ /dev/null @@ -1 +0,0 @@ -Use ``dj.config`` for configuration. diff --git a/docs-parts/admin/5-blob-config_lang3.rst b/docs-parts/admin/5-blob-config_lang3.rst deleted file mode 100644 index 974c5f07..00000000 --- a/docs-parts/admin/5-blob-config_lang3.rst +++ /dev/null @@ -1,4 +0,0 @@ -.. note:: - - The cache folder is not yet implemented in MATLAB. - The feature will be added in an upcoming release: https://github.com/datajoint/datajoint-matlab/issues/143 diff --git a/docs-parts/admin/5-blob-config_lang4.rst b/docs-parts/admin/5-blob-config_lang4.rst deleted file mode 100644 index 15bf13b7..00000000 --- a/docs-parts/admin/5-blob-config_lang4.rst +++ /dev/null @@ -1,4 +0,0 @@ -.. note:: - - External storage is not yet implemented in MATLAB. - The feature will be added in an upcoming release: https://github.com/datajoint/datajoint-matlab/issues/143 diff --git a/docs-parts/admin/5-blob-config_lang5.rst b/docs-parts/admin/5-blob-config_lang5.rst deleted file mode 100644 index 15bf13b7..00000000 --- a/docs-parts/admin/5-blob-config_lang5.rst +++ /dev/null @@ -1,4 +0,0 @@ -.. note:: - - External storage is not yet implemented in MATLAB. - The feature will be added in an upcoming release: https://github.com/datajoint/datajoint-matlab/issues/143 diff --git a/docs-parts/computation/01-autopopulate_lang1.rst b/docs-parts/computation/01-autopopulate_lang1.rst deleted file mode 100644 index 6ecbf940..00000000 --- a/docs-parts/computation/01-autopopulate_lang1.rst +++ /dev/null @@ -1,23 +0,0 @@ - -.. code-block:: MATLAB - - %{ - # Filtered image - -> test.Image - --- - filtered_image : longblob - %} - - classdef FilteredImage < dj.Computed - methods(Access=protected) - function make(self, key) - img = fetch1(test.Image & key, 'image'); - key.filtered_image = myfilter(img); - self.insert(key) - end - end - end - -.. note:: Currently matlab uses ``makeTuples`` rather than ``make``. This will be fixed in an upcoming release: https://github.com/datajoint/datajoint-matlab/issues/141 - -The ``make`` method receives one argument: the struct ``key`` containing the primary key value of an element of :ref:`key source ` to be worked on. diff --git a/docs-parts/computation/01-autopopulate_lang2.rst b/docs-parts/computation/01-autopopulate_lang2.rst deleted file mode 100644 index ea6e781e..00000000 --- a/docs-parts/computation/01-autopopulate_lang2.rst +++ /dev/null @@ -1,4 +0,0 @@ - -.. code-block:: matlab - - populate(test.FilteredImage) diff --git a/docs-parts/computation/01-autopopulate_lang3.rst b/docs-parts/computation/01-autopopulate_lang3.rst deleted file mode 100644 index 3f25bb5f..00000000 --- a/docs-parts/computation/01-autopopulate_lang3.rst +++ /dev/null @@ -1,3 +0,0 @@ -Behavior of the ``populate`` method depends on the number of output arguments requested in the function call. -When no output arguments are requested, errors will halt population. -With two output arguments (``failedKeys`` and ``errors``), ``populate`` will catch any encountered errors and return them along with the offending keys. diff --git a/docs-parts/computation/01-autopopulate_lang4.rst b/docs-parts/computation/01-autopopulate_lang4.rst deleted file mode 100644 index 851fed25..00000000 --- a/docs-parts/computation/01-autopopulate_lang4.rst +++ /dev/null @@ -1,28 +0,0 @@ -The function ``parpopulate`` works identically to ``populate`` except that it uses a job reservation mechanism to allow multiple processes to populate the same table in parallel without collision. -When running ``parpopulate`` for the first time, DataJoint will create a job reservation table and its class ``.Jobs`` with the following declaration: - -.. code-block:: matlab - - {% - # the job reservation table - table_name : varchar(255) # className of the table - key_hash : char(32) # key hash - --- - status : enum('reserved','error','ignore')# if tuple is missing, the job is available - key=null : blob # structure containing the key - error_message="" : varchar(1023) # error message returned if failed - error_stack=null : blob # error stack if failed - host="" : varchar(255) # system hostname - pid=0 : int unsigned # system process id - timestamp=CURRENT_TIMESTAMP : timestamp # automatic timestamp - %} - -A job is considered to be available when ``.Jobs`` contains no matching entry. - -For each ``make`` call, ``parpopulate`` sets the job status to ``reserved``. -When the job is completed, the record is removed. -If the job results in error, the job record is left in place with the status set to ``error`` and the error message and error stacks saved. -Consequently, jobs that ended in error during the last execution will not be attempted again until you delete the corresponding entities from ``.Jobs``. - -The primary key of the jobs table comprises the name of the class and a 32-character hash of the job's primary key. -However, the key is saved in a separate field for error debugging purposes. diff --git a/docs-parts/computation/02-keysource_lang1.rst b/docs-parts/computation/02-keysource_lang1.rst deleted file mode 100644 index 6db0f642..00000000 --- a/docs-parts/computation/02-keysource_lang1.rst +++ /dev/null @@ -1 +0,0 @@ -A custom key source can be configured by setting the ``keySource`` property within a table's ``classdef`` block, using MATLAB's `dependent properties `_ syntax. diff --git a/docs-parts/computation/02-keysource_lang2.rst b/docs-parts/computation/02-keysource_lang2.rst deleted file mode 100644 index e9d53ce0..00000000 --- a/docs-parts/computation/02-keysource_lang2.rst +++ /dev/null @@ -1,17 +0,0 @@ -.. code-block:: matlab - - %{ - -> Recording - --- - sample_rate : float - eeg_data : longblob - %} - classdef EEG < dj.Imported - - methods - function q = get.keySource(self) - q = ephys.Recording & 'recording_type = "EEG"' - end - end - - end diff --git a/docs-parts/computation/04-master-part_lang1.rst b/docs-parts/computation/04-master-part_lang1.rst deleted file mode 100644 index 0a28aea6..00000000 --- a/docs-parts/computation/04-master-part_lang1.rst +++ /dev/null @@ -1,52 +0,0 @@ - -In MATLAB, the master and part tables are declared in a separate ``classdef`` file. -The name of the part table must begin with the name of the master table. -The part table must declare the property ``master`` containing an object of the master. - -``+test/Segmentation.m`` - -.. code-block:: matlab - - %{ - # image segmentation - -> test.Image - %} - classdef Segmentation < dj.Computed - methods(Access=protected) - function make(self, key) - self.insert(key) - make(test.SegmentationRoi, key) - end - end - end - -``+test/SegmentationROI.m`` - -.. code-block:: matlab - - %{ - # Region of interest resulting from segmentation - -> test.Segmentation - roi : smallint # roi number - --- - roi_pixels : longblob # indices of pixels - roi_weights : longblob # weights of pixels - %} - - classdef SegmentationROI < dj.Part - properties(SetAccess=protected) - master = test.Segmentation - end - methods - function make(self, key) - image = fetch1(test.Image & key, 'image'); - [roi_pixels, roi_weighs] = mylib.segment(image); - for roi=1:length(roi_pixels) - entity = key; - entity.roi_pixels = roi_pixels{roi}; - entity.roi_weights = roi_weights{roi}; - self.insert(entity) - end - end - end - end diff --git a/docs-parts/computation/04-master-part_lang2.rst b/docs-parts/computation/04-master-part_lang2.rst deleted file mode 100644 index e0a49073..00000000 --- a/docs-parts/computation/04-master-part_lang2.rst +++ /dev/null @@ -1,4 +0,0 @@ - -.. code-block:: matlab - - populate(Segmentation) diff --git a/docs-parts/computation/04-master-part_lang3.rst b/docs-parts/computation/04-master-part_lang3.rst deleted file mode 100644 index 468e2d6d..00000000 --- a/docs-parts/computation/04-master-part_lang3.rst +++ /dev/null @@ -1,51 +0,0 @@ - -``+test/ArrayResponse.m`` - -.. code-block:: matlab - - %{ - -> Probe - array: int - %} - classdef ArrayResponse < dj.Computed - methods(Access=protected) - function make(self, key) - self.insert(key) - make(test.ArrayResponseElectrodeResponse, key) - end - end - end - -``+test/ArrayResponseElectrodeResponse.m`` - -.. code-block:: matlab - - %{ - -> test.ArrayResponse - electrode : int % electrode number on the probe - %} - classdef ArrayResponseElectrodeResponse < dj.Part - methods(SetAccess=protected) - function make(self, key) - self.insert(key) - end - end - end - -``+test/ArrayResponseChannelResponse.m`` - -.. code-block:: matlab - - %{ - -> test.ArrayResponseElectrodeResponse - channel: int - --- - response: longblob % response of a channel - %} - classdef ArrayResponseChannelResponse < dj.Part - methods(SetAccess=protected) - function make(self, key) - self.insert(key) - end - end - end diff --git a/docs-parts/computation/06-distributed-computing_kill_order_by.rst b/docs-parts/computation/06-distributed-computing_kill_order_by.rst deleted file mode 100644 index f9aed23a..00000000 --- a/docs-parts/computation/06-distributed-computing_kill_order_by.rst +++ /dev/null @@ -1,14 +0,0 @@ - -For example, to sort the output by hostname in descending order: - -.. code-block:: matlab - - - dj.kill('', dj.conn, 'host desc'); - - ID USER HOST DB COMMAND TIME STATE INFO TIME_MS ROWS_SENT ROWS_EXAMINED - +--+ +----+ +---------+ +--+ +-------+ +----+ +-----+ +----+ +-------+ +---------+ +-------------+ - 35 cat localhost:38772 Sleep 94 94040 0 0 - 36 cat localhost:36543 Sleep 68 68421 1 0 - - process to kill ('q'-quit, 'a'-all) > q diff --git a/docs-parts/computation/06-distributed-computing_lang1.rst b/docs-parts/computation/06-distributed-computing_lang1.rst deleted file mode 100644 index d1e5cae6..00000000 --- a/docs-parts/computation/06-distributed-computing_lang1.rst +++ /dev/null @@ -1,2 +0,0 @@ - -Job reservations are activated by replacing ``populate`` calls with identical ``parpopulate`` calls. diff --git a/docs-parts/computation/06-distributed-computing_lang2.rst b/docs-parts/computation/06-distributed-computing_lang2.rst deleted file mode 100644 index 0dbd34a4..00000000 --- a/docs-parts/computation/06-distributed-computing_lang2.rst +++ /dev/null @@ -1,3 +0,0 @@ - -.. todo: matlab - diff --git a/docs-parts/computation/06-distributed-computing_lang3.rst b/docs-parts/computation/06-distributed-computing_lang3.rst deleted file mode 100644 index 3eb23a59..00000000 --- a/docs-parts/computation/06-distributed-computing_lang3.rst +++ /dev/null @@ -1,3 +0,0 @@ - -.. todo: similarly, in matlab (blah) - diff --git a/docs-parts/computation/06-distributed-computing_lang4.rst b/docs-parts/computation/06-distributed-computing_lang4.rst deleted file mode 100644 index 3eb23a59..00000000 --- a/docs-parts/computation/06-distributed-computing_lang4.rst +++ /dev/null @@ -1,3 +0,0 @@ - -.. todo: similarly, in matlab (blah) - diff --git a/docs-parts/computation/06-distributed-computing_lang5.rst b/docs-parts/computation/06-distributed-computing_lang5.rst deleted file mode 100644 index 3eb23a59..00000000 --- a/docs-parts/computation/06-distributed-computing_lang5.rst +++ /dev/null @@ -1,3 +0,0 @@ - -.. todo: similarly, in matlab (blah) - diff --git a/docs-parts/concepts/04-Integrity_lang1.rst b/docs-parts/concepts/04-Integrity_lang1.rst deleted file mode 100644 index d3d4d495..00000000 --- a/docs-parts/concepts/04-Integrity_lang1.rst +++ /dev/null @@ -1,25 +0,0 @@ -``+test/Mouse.m`` - -.. code-block:: matlab - - %{ - mouse_name : varchar(64) - --- - mouse_dob : datetime - %} - - classdef Mouse < dj.Manual - end - -``+test/MouseDeath.m`` - -.. code-block:: matlab - - %{ - -> test.Mouse - --- - death_date : datetime - %} - - classdef MouseDeath < dj.Manual - end diff --git a/docs-parts/concepts/04-Integrity_lang2.rst b/docs-parts/concepts/04-Integrity_lang2.rst deleted file mode 100644 index ae0abdeb..00000000 --- a/docs-parts/concepts/04-Integrity_lang2.rst +++ /dev/null @@ -1,28 +0,0 @@ -``+test/EEGRecording.m`` - -.. code-block:: matlab - - %{ - -> test.Session - eeg_recording_id : int - --- - eeg_system : varchar(64) - num_channels : int - %} - - classdef EEGRecording < dj.Manual - end - -``+test/ChannelData.m`` - -.. code-block:: matlab - - %{ - -> test.EEGRecording - channel_idx : int - --- - channel_data : longblob - %} - - classdef ChannelData < dj.Imported - end diff --git a/docs-parts/concepts/04-Integrity_lang3.rst b/docs-parts/concepts/04-Integrity_lang3.rst deleted file mode 100644 index 065616c3..00000000 --- a/docs-parts/concepts/04-Integrity_lang3.rst +++ /dev/null @@ -1,37 +0,0 @@ -``+test/Mouse.m`` - -.. code-block:: matlab - - %{ - mouse_name : varchar(64) - --- - mouse_dob : datetime - %} - - classdef Mouse < dj.Manual - end - -``+test/SubjectGroup.m`` - -.. code-block:: matlab - - %{ - group_number : int - --- - group_name : varchar(64) - %} - - classdef SubjectGroup < dj.Manual - end - -``+test/SubjectGroupGroupMember.m`` - -.. code-block:: matlab - - %{ - -> test.SubjectGroup - -> test.Mouse - %} - - classdef SubjectGroupGroupMember < dj.Part - end diff --git a/docs-parts/concepts/04-Integrity_lang4.rst b/docs-parts/concepts/04-Integrity_lang4.rst deleted file mode 100644 index 104f5ec6..00000000 --- a/docs-parts/concepts/04-Integrity_lang4.rst +++ /dev/null @@ -1,34 +0,0 @@ -``+test/RecordingModality.m`` - -.. code-block:: matlab - - %{ - modality : varchar(64) - %} - - classdef RecordingModality < dj.Lookup - end - -``+test/MultimodalSession.m`` - -.. code-block:: matlab - - %{ - -> test.Session - modes : int - %} - - classdef MultimodalSession < dj.Manual - end - -``+test/MultimodalSessionSessionMode.m`` - -.. code-block:: matlab - - %{ - -> test.MultimodalSession - -> test.RecordingModality - %} - - classdef MultimodalSessionSessionMode < dj.Part - end diff --git a/docs-parts/definition/01-Creating-Schemas_lang1.rst b/docs-parts/definition/01-Creating-Schemas_lang1.rst deleted file mode 100644 index 2a8d91d2..00000000 --- a/docs-parts/definition/01-Creating-Schemas_lang1.rst +++ /dev/null @@ -1,60 +0,0 @@ - -A schema can be created either automatically using the ``dj.createSchema`` script or manually. -While ``dj.createSchema`` simplifies the process, the manual approach yields a better understanding of what actually takes place, so both approaches are listed below. - -Manual -^^^^^^^^^^^^ -**Step 1.** Create the database schema - -Use the following command to create a new schema on the database server: - -.. code-block:: matlab - - query(dj.conn, 'CREATE SCHEMA `alice_experiment`') - -Note that you must have create privileges for the schema name pattern (as described in :ref:`hosting`). -It is a common practice to grant all privileges to users for schemas that begin with the username, in addition to some shared schemas. -Thus the user ``alice`` would be able to perform any work in any schema that begins with ``alice_``. - -**Step 2.** Create the MATLAB package - -DataJoint organizes schemas as MATLAB **packages**. -If you are not familiar with packages, please review: - -* `How to work with MATLAB packages `_ -* `How to manage MATLAB's search paths `_ - -In your project directory, create the package folder, which must begin with a ``+`` sign. -For example, for the schema called ``experiment``, you would create the folder ``+experiment``. -Make sure that your project directory (the parent directory of your package folder) is added to the MATLAB search path. - -**Step 3.** Associate the package with the database schema - -This step tells DataJoint that all classes in the package folder ``+experiment`` will work with tables in the database schema ``alice_experiment``. -Each package corresponds to exactly one schema. -In some special cases, multiple packages may all relate to a single database schema, but in most cases there will be a one-to-one relationship between packages and schemas. - -In the ``+experiment`` folder, create the file ``getSchema.m`` with the following contents: - -.. code-block:: matlab - - function obj = getSchema - persistent OBJ - if isempty(OBJ) - OBJ = dj.Schema(dj.conn, 'experiment', 'alice_experiment'); - end - obj = OBJ; - end - -This function returns a persistent object of type ``dj.Schema``, establishing the link between the ``experiment`` package in MATLAB and the schema ``alice_experiment`` on the database server. - -Automatic -^^^^^^^^^^^^^ - -Alternatively, you can execute - -.. code-block:: matlab - - >> dj.createSchema - -This automated script will walk you through the steps 1--3 above and will create the schema, the package folder, and the ``getSchema`` function in that folder. diff --git a/docs-parts/definition/02-Creating-Tables_lang1.rst b/docs-parts/definition/02-Creating-Tables_lang1.rst deleted file mode 100644 index 6b46f467..00000000 --- a/docs-parts/definition/02-Creating-Tables_lang1.rst +++ /dev/null @@ -1,42 +0,0 @@ - -DataJoint provides the interactive script ``dj.new`` for creating a new table. -It will prompt to enter the new table's class name in the form ``package.ClassName``. -This will create the file ``+package/ClassName.m``. - -For example, define the table ``experiment.Person`` - -.. code-block:: matlab - - >> dj.new - Enter .: experiment.Person - - Choose table tier: - L=lookup - M=manual - I=imported - C=computed - P=part - (L/M/I/C/P) > M - -This will create the file ``+experiment/Person.m`` with the following contents: - -.. code-block:: matlab - - %{ - # my newest table - # add primary key here - ----- - # add additional attributes - %} - - classdef Person < dj.Manual - end - -While ``dj.new`` adds a little bit of convenience, some users may create the classes from scratch manually. - -Each newly created class must inherit from the DataJoint class corresponding to the correct :ref:`data tier `: ``dj.Lookup``, ``dj.Manual``, ``dj.Imported`` or ``dj.Computed``. - -The most important part of the table definition is the comment preceding the ``classdef``. -DataJoint will parse this comment to define the table. - -The class will become usable after you edit this comment as described in :ref:`definitions`. diff --git a/docs-parts/definition/03-Table-Definition_lang1.rst b/docs-parts/definition/03-Table-Definition_lang1.rst deleted file mode 100644 index 8016a84f..00000000 --- a/docs-parts/definition/03-Table-Definition_lang1.rst +++ /dev/null @@ -1,17 +0,0 @@ - -The table definition is contained in the first block comment in the class definition file. -Note that although it looks like a mere comment, the table definition is parsed by DataJoint. -This solution is thought to be convenient since MATLAB does not provide convenient syntax for multiline strings. - -.. code-block:: matlab - - %{ - # database users - username : varchar(20) # unique user name - --- - first_name : varchar(30) - last_name : varchar(30) - role : enum('admin', 'contributor', 'viewer') - %} - classdef User < dj.Manual - end diff --git a/docs-parts/definition/03-Table-Definition_lang2.rst b/docs-parts/definition/03-Table-Definition_lang2.rst deleted file mode 100644 index 760e1190..00000000 --- a/docs-parts/definition/03-Table-Definition_lang2.rst +++ /dev/null @@ -1,2 +0,0 @@ -Users do not need to do anything special to have the table created in the database. -The table is created upon the first attempt to use the class for manipulating its data (e.g. inserting or fetching entities). diff --git a/docs-parts/definition/03-Table-Definition_lang3.rst b/docs-parts/definition/03-Table-Definition_lang3.rst deleted file mode 100644 index f55743ac..00000000 --- a/docs-parts/definition/03-Table-Definition_lang3.rst +++ /dev/null @@ -1,4 +0,0 @@ - -.. code-block:: matlab - - s = describe(lab.User) diff --git a/docs-parts/definition/03-Table-Definition_lang4.rst b/docs-parts/definition/03-Table-Definition_lang4.rst deleted file mode 100644 index 7e92829a..00000000 --- a/docs-parts/definition/03-Table-Definition_lang4.rst +++ /dev/null @@ -1,6 +0,0 @@ - -Furthermore, DataJoint provides the ``syncDef`` method to update the ``classdef`` file definition string for the table with the definition in the actual table: - -.. code-block:: matlab - - syncDef(lab.User) % updates the table definition in file +lab/User.m diff --git a/docs-parts/definition/07-Primary-Key_lang1.rst b/docs-parts/definition/07-Primary-Key_lang1.rst deleted file mode 100644 index 9c358779..00000000 --- a/docs-parts/definition/07-Primary-Key_lang1.rst +++ /dev/null @@ -1,4 +0,0 @@ -.. code-block:: matlab - - key.scan_idx = fetch1(Scan & key, 'max(scan_idx)+1 -> next') - diff --git a/docs-parts/definition/10-Dependencies_lang1.rst b/docs-parts/definition/10-Dependencies_lang1.rst deleted file mode 100644 index 16a39c0f..00000000 --- a/docs-parts/definition/10-Dependencies_lang1.rst +++ /dev/null @@ -1,4 +0,0 @@ - -.. code-block:: matlab - - show(mp.BrainSlice) diff --git a/docs-parts/definition/11-ERD_lang1.rst b/docs-parts/definition/11-ERD_lang1.rst deleted file mode 100644 index 61f7e6e9..00000000 --- a/docs-parts/definition/11-ERD_lang1.rst +++ /dev/null @@ -1,20 +0,0 @@ - -The schema object for a package can be obtained using its ``getSchema`` function. -(See :ref:`schema`.) - -.. code-block:: matlab - - draw(dj.ERD(seq.getSchema)) % draw the ERD - -DataJoint provides shortcuts to plot ERD of a table neighborhood or a schema using the ``erd`` command: - -.. code-block:: matlab - - % plot the ERD of the stimulus schema - erd stimulus - - % plot the neighborhood of the stimulus.Trial table - erd stimulus.Trial - - % plot the stimulus and experiment schemas and the neighborhood of preprocess.Sync - erd stimulus experiment preprocess.Sync diff --git a/docs-parts/definition/11-ERD_lang2.rst b/docs-parts/definition/11-ERD_lang2.rst deleted file mode 100644 index e3174b1a..00000000 --- a/docs-parts/definition/11-ERD_lang2.rst +++ /dev/null @@ -1,4 +0,0 @@ - -.. code-block:: matlab - - draw(dj.ERD(seq.Genome)) diff --git a/docs-parts/definition/11-ERD_lang3.rst b/docs-parts/definition/11-ERD_lang3.rst deleted file mode 100644 index d286eeca..00000000 --- a/docs-parts/definition/11-ERD_lang3.rst +++ /dev/null @@ -1,5 +0,0 @@ - -.. code-block:: matlab - - % plot the ERD with tables Genome and Species from package +seq. - draw(dj.ERD(seq.Genome) + dj.ERD(seq.Species)) diff --git a/docs-parts/definition/11-ERD_lang4.rst b/docs-parts/definition/11-ERD_lang4.rst deleted file mode 100644 index cadca52d..00000000 --- a/docs-parts/definition/11-ERD_lang4.rst +++ /dev/null @@ -1,15 +0,0 @@ - -.. code-block:: matlab - - % Plot all the tables directly downstream from ``seq.Genome``: - draw(dj.ERD(seq.Genome)+1) - -.. code-block:: matlab - - % Plot all the tables directly upstream from ``seq.Genome``: - draw(dj.ERD(seq.Genome)-1) - -.. code-block:: matlab - - % Plot the local neighborhood of ``seq.Genome`` - draw(dj.ERD(seq.Genome)+1-1+1-1) diff --git a/docs-parts/definition/12-Example_lang1.rst b/docs-parts/definition/12-Example_lang1.rst deleted file mode 100644 index e0873eae..00000000 --- a/docs-parts/definition/12-Example_lang1.rst +++ /dev/null @@ -1,48 +0,0 @@ - -File ``+experiment/Animal.m`` - -.. code-block:: matlab - - %{ - # information about animal - animal_id : int # animal id assigned by the lab - --- - -> experiment.Species - date_of_birth=null : date # YYYY-MM-DD optional - sex='' : enum('M', 'F', '') # leave empty if unspecified - %} - classdef Animal < dj.Manual - end - -File ``+experiment/Session.m`` - -.. code-block:: matlab - - %{ - # Experiment Session - -> experiment.Animal - session : smallint # session number for the animal - --- - session_date : date # YYYY-MM-DD - -> experiment.User - -> experiment.Anesthesia - -> experiment.Rig - %} - classdef Session < dj.Manual - end - -File ``+experiment/Scan.m`` - -.. code-block:: matlab - - %{ - # Two-photon imaging scan - -> experiment.Session - scan : smallint # scan number within the session - --- - -> experiment.Lens - laser_wavelength : decimal(5,1) # um - laser_power : decimal(4,1) # mW - %} - classdef Scan < dj.Manual - end diff --git a/docs-parts/definition/13-Lookup-Tables_lang1.rst b/docs-parts/definition/13-Lookup-Tables_lang1.rst deleted file mode 100644 index a0bf40fb..00000000 --- a/docs-parts/definition/13-Lookup-Tables_lang1.rst +++ /dev/null @@ -1,21 +0,0 @@ - -File ``+lab/User.m`` - -.. code-block:: matlab - - %{ - # users in the lab - username : varchar(20) # user in the lab - --- - first_name : varchar(20) # user first name - last_name : varchar(20) # user last name - %} - classdef User < dj.Lookup - properties - contents = { - 'cajal' 'Santiago' 'Cajal' - 'hubel' 'David' 'Hubel' - 'wiesel' 'Torsten' 'Wiesel' - } - end - end diff --git a/docs-parts/definition/14-Drop_lang1.rst b/docs-parts/definition/14-Drop_lang1.rst deleted file mode 100644 index bad038b9..00000000 --- a/docs-parts/definition/14-Drop_lang1.rst +++ /dev/null @@ -1,5 +0,0 @@ - -.. code-block:: matlab - - % drop the Person table from the lab schema - drop(lab.Person) diff --git a/docs-parts/definition/14-Drop_lang2.rst b/docs-parts/definition/14-Drop_lang2.rst deleted file mode 100644 index 83bf221b..00000000 --- a/docs-parts/definition/14-Drop_lang2.rst +++ /dev/null @@ -1,4 +0,0 @@ -.. note:: - - This rule is currently not enforced in MATLAB, but calling ``drop`` directly on a part table will produce an error in the future. - See `issue #125 `_ on ``datajoint-matlab`` for more information. diff --git a/docs-parts/existing/1-Loading-Classes_lang1.rst b/docs-parts/existing/1-Loading-Classes_lang1.rst deleted file mode 100644 index f20fac2c..00000000 --- a/docs-parts/existing/1-Loading-Classes_lang1.rst +++ /dev/null @@ -1,18 +0,0 @@ - -Creating a virtual class -~~~~~~~~~~~~~~~~~~~~~~~~ - -To facilitate working with existing pipelines, DataJoint MATLAB creates a ``TableAccessor`` property in each schema object. -The ``TableAccessor`` property, a *virtual class generator*, is available as ``schema.v``, and allows listing and querying of the tables defined on the server without needing to create the MATLAB table definitions locally. -For example, creating a scratch ``experiment`` schema package and querying an existing ``my_experiment.Session`` table on the server can be done as follows: - -.. code-block:: matlab - - dj.createSchema('experiment', '/scratch', 'my_experiment') - addpath('/scratch') - experiment_schema = experiment.getSchema(); - experiment_schema.v.Session() & 'session_id=1234'; - -.. note:: - - You can view the available tables in a schema by using tab completion on the ``schema.v`` property. diff --git a/docs-parts/index_lang1.rst b/docs-parts/index_lang1.rst deleted file mode 100644 index b9609d41..00000000 --- a/docs-parts/index_lang1.rst +++ /dev/null @@ -1 +0,0 @@ -This is a detailed manual for active users of DataJoint in MATLAB. diff --git a/docs-parts/intro/Releases_lang1.rst b/docs-parts/intro/Releases_lang1.rst deleted file mode 100644 index da5c02cf..00000000 --- a/docs-parts/intro/Releases_lang1.rst +++ /dev/null @@ -1,73 +0,0 @@ -3.5.0 -- March 21, 2022 --------------------------- -* Bugfix: Cascading delete for renamed foreign keys (#379) PR #386 -* Minor: Add renaming the same attribute multiple times within a single projection PR #386 -* Minor: Add config for reading values with 32-bit dimensions (datajoint/mym#86) PR #395 - -3.4.3 -- May 28, 2021 --------------------------- -* Bugfix: `dj.config` omits default values when loading new config immediately after MATLAB boot (#359) PR #369 -* Bugfix: Regression error when using fetchn with a join (#361) PR #369 -* Bugfix: Cascading delete not functioning properly when using renamed foreign keys (#362) PR #369 -* Update NGINX reverse-proxy image use PR #369 -* Bugfix: Add support to curly brackets in comments (#365) PR #373 - -3.4.2 -- March 16, 2021 --------------------------- -* Bugfix: Fetchn with zero results throws an error (#353) PR #355 -* Bugfix: Syntax error in documentation for next auto_increment value (#352) PR #355 - -3.4.1 -- December 18, 2020 --------------------------- -* Bugfix: Error on accessing unmanaged Imported/Computed tables (#336) PR #338 -* Bugfix: Certain characters in attribute comment not escaped properly (#210, #335) PR #338 -* Bugfix: `dj.config.load(...)` after initial MATLAB boot throws invalid input error. PR #338 - -3.4.0 -- December 11, 2020 --------------------------- -* Minor: Add dj.config to be compatible with dj-python and removed dj.set (#186) #188 -* Minor: Add UUID DataJoint datatype (#180) PR #194 -* Minor: Add file external storage (#143) PR #197 -* Minor: Add S3 external storage (#88) PR #207 -* Minor: Improve dependency version compatibility handling (#228) PR #285 -* Minor: Add unique and nullable options for foreign keys (#110) PR #303 -* Minor: Add non-interactive option for dj.new (#69) #317 -* Minor: Add dj.kill_quick (#251) PR #314 -* Minor: Log connection ID, user in jobs table (#87, #275) PR #314 -* Bugfix: Handle empty password (#250) PR #279, #292 -* Bugfix: Disable GUI password if running headless (#278) PR #280, #292 -* Bugfix: Add order_by option to dj.kill output (#229) PR #248, #292 -* Bugfix: erd function missing from package (#307) PR #310 -* Bugfix: Error on extremely short table names (#311) PR #317 -* Bugfix: Incorrect return when fetchn of an external field (#269) PR #274 -* Bugfix: MATLAB crashes randomly on insert 8-byte string (#255) PR #257 -* Bugfix: Errors thrown when seeing unsupported DataJoint types (#254) PR #265 -* Bugfix: Fix SQL argument growth condition on blobs (#217) PR #220 -* Tests: Add R2016b tests (#233) PR #235 -* Tests: Convert testing framework from TravisCI to GitHub Actions (#320) PR #317 -* Tests: Increase test coverage - -3.3.2 -- October 15, 2020 -------------------------- -* Bugfix: Add blob validation for insert/update regarding sparse matrices which are not yet supported (#238) PR #241 -* Bugfix: Modify update to allow nullable updates for strings/date (#211) PR #213 -* Bugfix: createSchema had some issues with MySQL8 PR #213 -* Update tests -* Docs: Update example related to virtual class (#199) PR #261 -* Docs: Fix typos (#150, #151) PR #263, PR #262 -* Upgrade packaging and installation to utilize MATLAB Toolbox i.e. `DataJoint.mltbx` PR #285 - -3.3.1 -- October 31, 2019 -------------------------- -* Ability to create schema without GUI PR #155 -* Support secure connections with TLS (aka SSL) (#103) PR #157, mym-PR #11, #12, #13 -* Allow GUI-based password entry to avoid cleartext password from being captured in MATLAB log PR #159 -* Add detailed error message if DJ012 Python-native blobs detected (#170) mYm-PR #16 -* Add support for PAM connections via MariaDB's Dialog plugin (#168, #169) mYm-PR #14, #15 -* Minor improvements to reuse of connection if applicable PR #166, #167 -* Bugfixes (#152) - -3.2.2 -- February 5, 2019 -------------------------- - -`Previous release notes TBD` diff --git a/docs-parts/manipulation/1-Insert_lang1.rst b/docs-parts/manipulation/1-Insert_lang1.rst deleted file mode 100644 index 898abb23..00000000 --- a/docs-parts/manipulation/1-Insert_lang1.rst +++ /dev/null @@ -1,26 +0,0 @@ - -The ``insert`` method inserts any number of entities in the form of a structure array with field names corresponding to the attribute names. - -For example - -.. code-block:: matlab - - s.username = 'alice'; - s.first_name = 'Alice'; - s.last_name = 'Cooper'; - insert(lab.Person, s) - -Quick entry of multiple entities takes advantage of MATLAB's cell array notation: - -.. code-block:: matlab - - insert(lab.Person, { - 'alice' 'Alice' 'Cooper' - 'bob' 'Bob' 'Dylan' - 'carol' 'Carol' 'Douglas' - }) - -In this case, the values must match the order of the attributes in the table. - -The optional parameter ``command`` can be either ``'IGNORE'`` or ``'REPLACE'``. -Duplicates, unmatched attributes, or missing required attributes will cause insert errors, unless ``command`` is specified. diff --git a/docs-parts/manipulation/1-Insert_lang2.rst b/docs-parts/manipulation/1-Insert_lang2.rst deleted file mode 100644 index bdc12baf..00000000 --- a/docs-parts/manipulation/1-Insert_lang2.rst +++ /dev/null @@ -1,9 +0,0 @@ - -.. code-block:: matlab - - % Server-side inserts are faster... - phase_two.Protocol.insert(phase_one.Protocol) - - % ...than fetching before inserting - protocols = phase_one.Protocol.fetch(); - phase_two.Protocol.insert(protocols) diff --git a/docs-parts/manipulation/2-Delete_lang1.rst b/docs-parts/manipulation/2-Delete_lang1.rst deleted file mode 100644 index 37f65317..00000000 --- a/docs-parts/manipulation/2-Delete_lang1.rst +++ /dev/null @@ -1 +0,0 @@ -The ``del`` method deletes entities from a table and all dependent entries in dependent tables. diff --git a/docs-parts/manipulation/2-Delete_lang2.rst b/docs-parts/manipulation/2-Delete_lang2.rst deleted file mode 100644 index 6572d9d6..00000000 --- a/docs-parts/manipulation/2-Delete_lang2.rst +++ /dev/null @@ -1,13 +0,0 @@ - -Delete the entire contents of the table ``tuning.VonMises`` and all its dependents: - -.. code-block:: matlab - - % delete all entries from tuning.VonMises - del(tuning.VonMises) - - % delete entries from tuning.VonMises for mouse 1010 - del(tuning.VonMises & 'mouse=1010') - - % delete entries from tuning.VonMises except mouse 1010 - del(tuning.VonMises - 'mouse=1010') diff --git a/docs-parts/manipulation/2-Delete_lang3.rst b/docs-parts/manipulation/2-Delete_lang3.rst deleted file mode 100644 index 9def73be..00000000 --- a/docs-parts/manipulation/2-Delete_lang3.rst +++ /dev/null @@ -1,4 +0,0 @@ -.. note:: - - This rule is currently not enforced in MATLAB, but calling ``del`` directly on a part table will produce an error in the future. - See `issue #193 `_ on ``datajoint-matlab`` for more information. diff --git a/docs-parts/manipulation/3-Transactions_lang1.rst b/docs-parts/manipulation/3-Transactions_lang1.rst deleted file mode 100644 index 655f9741..00000000 --- a/docs-parts/manipulation/3-Transactions_lang1.rst +++ /dev/null @@ -1,33 +0,0 @@ -Transactions are formed using the methods ``startTransaction``, ``cancelTransaction``, and ``commitTransaction`` of a connection object. -A connection object may obtained from any table object. - -For example, the following code inserts matching entries for the master table ``Session`` and its part table ``SessionExperimenter``. - -.. code-block:: matlab - - % get the connection object - session = Session - connection = session.conn - - % insert Session and Session.Experimenter entries in a transaction - connection.startTransaction - try - key.subject_id = animal_id; - key.session_time = session_time; - - session_entry = key; - session_entry.brain_region = region; - insert(Session, session_entry) - - experimenter_entry = key; - experimenter_entry.experimenter = username; - insert(SessionExperimenter, experiment_entry) - connection.commitTransaction - catch - connection.cancelTransaction - end - - -Here, to external observers, both inserts will take effect together only upon exiting from the ``try-catch`` block or will not have any effect at all. -For example, if the second insert fails due to an error, the first insert will be rolled back. - diff --git a/docs-parts/queries/01-Queries_lang1.rst b/docs-parts/queries/01-Queries_lang1.rst deleted file mode 100644 index 3c193a26..00000000 --- a/docs-parts/queries/01-Queries_lang1.rst +++ /dev/null @@ -1,5 +0,0 @@ - -.. code-block:: matlab - - query = experiment.Session; - diff --git a/docs-parts/queries/01-Queries_lang2.rst b/docs-parts/queries/01-Queries_lang2.rst deleted file mode 100644 index 6d247c5b..00000000 --- a/docs-parts/queries/01-Queries_lang2.rst +++ /dev/null @@ -1,5 +0,0 @@ - -.. code-block:: matlab - - query = experiment.Session * experiment.Scan & 'animal_id = 102'; - diff --git a/docs-parts/queries/01-Queries_lang3.rst b/docs-parts/queries/01-Queries_lang3.rst deleted file mode 100644 index 1b81e5bd..00000000 --- a/docs-parts/queries/01-Queries_lang3.rst +++ /dev/null @@ -1,7 +0,0 @@ - -.. code-block:: matlab - - s = query.fetch() - -Here fetching from the ``query`` object produces the struct array ``s`` of the queried data. - diff --git a/docs-parts/queries/01-Queries_lang4.rst b/docs-parts/queries/01-Queries_lang4.rst deleted file mode 100644 index 8f3b7ee9..00000000 --- a/docs-parts/queries/01-Queries_lang4.rst +++ /dev/null @@ -1,10 +0,0 @@ - -The ``exists`` method applied to a query object evaluates to ``true`` if the query returns any entities and to ``false`` if the query result is empty. - -The ``count`` method applied to a query object determines the number of entities returned by the query. - -.. code-block:: matlab - - % number of ephys sessions since the start of 2018. - n = count(ephys.Session & 'session_date >= "2018-01-01"') - diff --git a/docs-parts/queries/02-Example-Schema_lang1.rst b/docs-parts/queries/02-Example-Schema_lang1.rst deleted file mode 100644 index 0945cef0..00000000 --- a/docs-parts/queries/02-Example-Schema_lang1.rst +++ /dev/null @@ -1,138 +0,0 @@ - -.. warning:: - Empty primary keys, such as in the ``CurrentTerm`` table, are not yet supported by DataJoint. - This feature will become available in a future release. - See `Issue #127 `_ for more information. - -File ``+university/Student.m`` - -.. code-block:: matlab - - %{ - student_id : int unsigned # university ID - --- - first_name : varchar(40) - last_name : varchar(40) - sex : enum('F', 'M', 'U') - date_of_birth : date - home_address : varchar(200) # street address - home_city : varchar(30) - home_state : char(2) # two-letter abbreviation - home_zipcode : char(10) - home_phone : varchar(14) - %} - classdef Student < dj.Manual - end - -File ``+university/Department.m`` - -.. code-block:: matlab - - %{ - dept : char(6) # abbreviated department name, e.g. BIOL - --- - dept_name : varchar(200) # full department name - dept_address : varchar(200) # mailing address - dept_phone : varchar(14) - %} - classdef Department < dj.Manual - end - -File ``+university/StudentMajor.m`` - -.. code-block:: matlab - - %{ - -> university.Student - --- - -> university.Department - declare_date : date # when student declared her major - %} - classdef StudentMajor < dj.Manual - end - -File ``+university/Course.m`` - -.. code-block:: matlab - - %{ - -> university.Department - course : int unsigned # course number, e.g. 1010 - --- - course_name : varchar(200) # e.g. "Cell Biology" - credits : decimal(3,1) # number of credits earned by completing the course - %} - classdef Course < dj.Manual - end - -File ``+university/Term.m`` - -.. code-block:: matlab - - %{ - term_year : year - term : enum('Spring', 'Summer', 'Fall') - %} - classdef Term < dj.Manual - end - -File ``+university/Section.m`` - -.. code-block:: matlab - - %{ - -> university.Course - -> university.Term - section : char(1) - --- - room : varchar(12) # building and room code - %} - classdef Section < dj.Manual - end - -File ``+university/CurrentTerm.m`` - -.. code-block:: matlab - - %{ - --- - -> university.Term - %} - classdef CurrentTerm < dj.Manual - end - -File ``+university/Enroll.m`` - -.. code-block:: matlab - - %{ - -> university.Section - -> university.Student - %} - classdef Enroll < dj.Manual - end - -File ``+university/LetterGrade.m`` - -.. code-block:: matlab - - %{ - grade : char(2) - --- - points : decimal(3,2) - %} - classdef LetterGrade < dj.Manual - end - -File ``+university/Grade.m`` - -.. code-block:: matlab - - %{ - -> university.Enroll - --- - -> university.LetterGrade - %} - classdef Grade < dj.Manual - end - diff --git a/docs-parts/queries/03-Fetch_lang1.rst b/docs-parts/queries/03-Fetch_lang1.rst deleted file mode 100644 index c1c0f857..00000000 --- a/docs-parts/queries/03-Fetch_lang1.rst +++ /dev/null @@ -1,130 +0,0 @@ - -DataJoint for MATLAB provides three distinct fetch methods: ``fetch``, ``fetch1``, and ``fetchn``. -The three methods differ by the type and number of their returned variables. - -``query.fetch`` returns the result in the form of an *n* ⨉ 1 `struct array `_ where *n* is the number of records matching the query expression. - -``query.fetch1`` and ``query.fetchn`` split the result into separate output arguments, one for each attribute of the query. - -The types of the variables returned by ``fetch1`` and ``fetchn`` depend on the :ref:`datatypes ` of the attributes. -``query.fetchn`` will enclose any attributes of char and blob types in `cell arrays `_ whereas ``query.fetch1`` will unpack them. - -MATLAB has two alternative forms of invoking a method on an object: using the dot notation or passing the object as the first argument. -The following two notations produce an equivalent result: - -.. code-block:: matlab - - result = query.fetch(query, 'attr1') - result = fetch(query, 'attr1') - -However, the dot syntax only works when the query object is already assigned to a variable. -The second syntax is more commonly used to avoid extra variables. - -For example, the two methods below are equivalent although the second method creates an extra variable. - -.. code-block:: matlab - - # Method 1 - result = fetch(university.Student, '*'); - - # Method 2 - query = university.Student; - result = query.fetch() - - -Fetch the primary key -~~~~~~~~~~~~~~~~~~~~~ - -Without any arguments, the ``fetch`` method retrieves the primary key values of the table in the form of a single column ``struct``. -The attribute names become the fieldnames of the ``struct``. - -.. code-block:: matlab - - keys = query.fetch; - keys = fetch(university.Student & university.StudentMajor); - -Note that MATLAB allows calling functions without the parentheses ``()``. - - -Fetch entire query -~~~~~~~~~~~~~~~~~~ - -With a single-quoted asterisk (``'*'``) as the input argument, the ``fetch`` command retrieves the entire result as a struct array. - -.. code-block:: matlab - - data = query.fetch('*'); - - data = fetch(university.Student & university.StudentMajor, '*'); - -In some cases, the amount of data returned by fetch can be quite large. -When ``query`` is a table object rather than a query expression, ``query.sizeOnDisk()`` reports the estimated size of the entire table. -It can be used to assess whether running ``query.fetch('*')`` would be wise. -Please note that it is only currently possible to query the size of entire tables stored directly in the database . - -As separate variables -~~~~~~~~~~~~~~~~~~~~~ - -The ``fetch1`` and ``fetchn`` methods are used to retrieve each attribute into a separate variable. -DataJoint needs two different methods to tell MATLAB whether the result should be in array or scalar form; for numerical fields it does not matter (because scalars are still matrices in MATLAB) but non-uniform collections of values must be enclosed in cell arrays. - -``query.fetch1`` is used when ``query`` contains exactly one entity, otherwise ``fetch1`` will raise an error. - -``query.fetchn`` returns an arbitrary number of elements with character arrays and blobs returned in the form of cell arrays, even when ``query`` happens to contain a single entity. - -.. code-block:: matlab - - % when tab has exactly one entity: - [name, img] = query.fetch1('name', 'image'); - - % when tab has any number of entities: - [names, imgs] = query.fetchn('name', 'image'); - - -Obtaining the primary key along with individual values -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -It is often convenient to know the primary key values corresponding to attribute values retrieved by ``fetchn``. -This can be done by adding a special input argument indicating the request and another output argument to receive the key values: - -.. code-block:: matlab - - % retrieve names, images, and corresponding primary key values: - [names, imgs, keys] = query.fetchn('name', 'image', 'KEY'); - -The resulting value of ``keys`` will be a column array of type ``struct``. -This mechanism is only implemented for ``fetchn``. - -Rename and calculate -~~~~~~~~~~~~~~~~~~~~ - -In DataJoint for MATLAB, all ``fetch`` methods have all the same capability as the :ref:`proj ` operator. -For example, renaming an attribute can be accomplished using the syntax below. - -.. code-block:: matlab - - [names, BMIs] = query.fetchn('name', 'weight/height/height -> bmi'); - -See :ref:`proj` for an in-depth description of projection. - -Sorting and limiting the results -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -To sort the result, add the additional ``ORDER BY`` argument in ``fetch`` and ``fetchn`` methods as the last argument. - -.. code-block:: matlab - - % retrieve field ``course_name`` from courses - % in the biology department, sorted by course number - notes = fetchn(university.Course & 'dept="BIOL"', 'course_name', ... - 'ORDER BY course'); - -The ORDER BY argument is passed directly to SQL and follows the same syntax as the `ORDER BY clause `_ - -Similarly, the LIMIT and OFFSET clauses can be used to limit the result to a subset of entities. -For example, to return the most advanced courses, one could do the following: - -.. code-block:: matlab - - s = fetch(university.Course, '*', 'ORDER BY course DESC LIMIT 5') - -The limit clause is passed directly to SQL and follows the same `rules `_ diff --git a/docs-parts/queries/04-Iteration_lang1.rst b/docs-parts/queries/04-Iteration_lang1.rst deleted file mode 100644 index b87045a9..00000000 --- a/docs-parts/queries/04-Iteration_lang1.rst +++ /dev/null @@ -1,11 +0,0 @@ - -In the simple example below, iteration is used to display the names and values of the primary key attributes of each entity in the simple table or table expression ``tab``. - -.. code-block:: matlab - - for key = tab.fetch()' - disp(key) - end - -Note that the results returned by ``fetch`` must be transposed. -MATLAB iterates across columns, so the single column ``struct`` returned by ``fetch`` must be transposed into a single row. diff --git a/docs-parts/queries/06-Restriction_lang1.rst b/docs-parts/queries/06-Restriction_lang1.rst deleted file mode 100644 index ba86fe7a..00000000 --- a/docs-parts/queries/06-Restriction_lang1.rst +++ /dev/null @@ -1,7 +0,0 @@ - -* another table -* a mapping, or ``struct`` -* an expression in a character string -* a collection of conditions as a ``struct`` or cell array -* a Boolean expression (``true`` or ``false``) -* a query expression diff --git a/docs-parts/queries/06-Restriction_lang2.rst b/docs-parts/queries/06-Restriction_lang2.rst deleted file mode 100644 index 40480683..00000000 --- a/docs-parts/queries/06-Restriction_lang2.rst +++ /dev/null @@ -1,4 +0,0 @@ - -.. code-block:: matlab - - ephys.Session & struct('session_dat', '2018-01-01') diff --git a/docs-parts/queries/06-Restriction_lang3.rst b/docs-parts/queries/06-Restriction_lang3.rst deleted file mode 100644 index 16b0238d..00000000 --- a/docs-parts/queries/06-Restriction_lang3.rst +++ /dev/null @@ -1,8 +0,0 @@ - -.. code-block:: matlab - - % All the sessions performed by Alice - ephys.Session & 'user = "Alice"' - - % All the experiments at least one minute long - ephys.Experiment & 'duration >= 60' diff --git a/docs-parts/queries/06-Restriction_lang4.rst b/docs-parts/queries/06-Restriction_lang4.rst deleted file mode 100644 index c8612401..00000000 --- a/docs-parts/queries/06-Restriction_lang4.rst +++ /dev/null @@ -1,17 +0,0 @@ - -.. warning:: - This section documents future intended behavior in MATLAB, which is contrary to current behavior. - DataJoint for MATLAB has an open `issue `_ tracking this change. - -A collection can be a cell array or structure array. -Cell arrays can contain collections of arbitrary restriction conditions. -Structure arrays are limited to collections of mappings, each having the same attributes. - -.. code-block:: matlab - - % a cell aray: - cond_cell = {'first_name = "Aaron"', 'last_name = "Aaronson"'} - - % a structure array: - cond_struct = struct('first_name', 'Aaron', 'last_name', 'Paul') - cond_struct(2) = struct('first_name', 'Rosie', 'last_name', 'Aaronson') diff --git a/docs-parts/queries/06-Restriction_lang5.rst b/docs-parts/queries/06-Restriction_lang5.rst deleted file mode 100644 index c715f6e7..00000000 --- a/docs-parts/queries/06-Restriction_lang5.rst +++ /dev/null @@ -1,11 +0,0 @@ - -.. code-block:: matlab - - university.Student() & {'first_name = "Aaron"', 'last_name = "Aaronson"'} - -.. figure:: ../_static/img/matlab_collection.png - :align: center - :alt: restriction by collection - - Restriction by a collection, returning any entities matching any condition in the collection. - diff --git a/docs-parts/queries/06-Restriction_lang6.rst b/docs-parts/queries/06-Restriction_lang6.rst deleted file mode 100644 index cdc65e77..00000000 --- a/docs-parts/queries/06-Restriction_lang6.rst +++ /dev/null @@ -1,4 +0,0 @@ - -``A & true`` and ``A - false`` are equivalent to ``A``. - -``A & false`` and ``A - true`` are empty. diff --git a/docs-parts/queries/06-Restriction_lang7.rst b/docs-parts/queries/06-Restriction_lang7.rst deleted file mode 100644 index e69de29b..00000000 diff --git a/docs-parts/queries/06-Restriction_lang8.rst b/docs-parts/queries/06-Restriction_lang8.rst deleted file mode 100644 index 5c581581..00000000 --- a/docs-parts/queries/06-Restriction_lang8.rst +++ /dev/null @@ -1,4 +0,0 @@ -.. code-block:: matlab - - query = ephys.Session & 'user = "Alice"' - ephys.Experiment & query diff --git a/docs-parts/queries/08-Proj_lang1.rst b/docs-parts/queries/08-Proj_lang1.rst deleted file mode 100644 index fa4005df..00000000 --- a/docs-parts/queries/08-Proj_lang1.rst +++ /dev/null @@ -1,3 +0,0 @@ - -Renaming is done using a string: -``tab('old_attr->new_attr')``. diff --git a/docs-parts/queries/08-Proj_lang2.rst b/docs-parts/queries/08-Proj_lang2.rst deleted file mode 100644 index aaa21642..00000000 --- a/docs-parts/queries/08-Proj_lang2.rst +++ /dev/null @@ -1,4 +0,0 @@ - -.. code-block:: matlab - - tab.proj('mouse->animal', 'stimulus') diff --git a/docs-parts/queries/08-Proj_lang3.rst b/docs-parts/queries/08-Proj_lang3.rst deleted file mode 100644 index 5f278d1d..00000000 --- a/docs-parts/queries/08-Proj_lang3.rst +++ /dev/null @@ -1,4 +0,0 @@ - -.. code-block:: matlab - - tab * tab.proj('cell->other') diff --git a/docs-parts/queries/08-Proj_lang4.rst b/docs-parts/queries/08-Proj_lang4.rst deleted file mode 100644 index 3dccf35a..00000000 --- a/docs-parts/queries/08-Proj_lang4.rst +++ /dev/null @@ -1,4 +0,0 @@ - -.. code-block:: matlab - - tab.proj('scan_z-surface_z -> depth') & 'depth > 500' diff --git a/docs-parts/queries/09-Aggr_lang1.rst b/docs-parts/queries/09-Aggr_lang1.rst deleted file mode 100644 index f522b52c..00000000 --- a/docs-parts/queries/09-Aggr_lang1.rst +++ /dev/null @@ -1,7 +0,0 @@ - -.. code-block:: matlab - - % Number of students in each course section - university.Section.aggr(university.Enroll, 'count(*)->n') - % Average grade in each course - university.Course.aggr(university.Grade * university.LetterGrade, 'avg(points)->avg_grade') diff --git a/docs-parts/queries/11-Universal-Sets_lang1.rst b/docs-parts/queries/11-Universal-Sets_lang1.rst deleted file mode 100644 index 1d6e0011..00000000 --- a/docs-parts/queries/11-Universal-Sets_lang1.rst +++ /dev/null @@ -1,18 +0,0 @@ -.. note:: - - ``dj.U`` is not yet implemented in MATLAB. - The feature will be added in an upcoming release: https://github.com/datajoint/datajoint-matlab/issues/144 - -.. code-block:: matlab - - % All home cities of students - dj.U('home_city', 'home_state') & university.Student - - % Total number of students from each city - aggr(dj.U('home_city', 'home_state'), university.Student, 'count(*)->n') - - % Total number of students from each state - aggr(U('home_state'), university.Student, 'count(*)->n') - - % Total number of students in the database - aggr(U(), university.Student, 'count(*)->n') diff --git a/docs-parts/setup/01-Install-and-Connect_lang1.rst b/docs-parts/setup/01-Install-and-Connect_lang1.rst deleted file mode 100644 index a4a6d5ce..00000000 --- a/docs-parts/setup/01-Install-and-Connect_lang1.rst +++ /dev/null @@ -1,29 +0,0 @@ - -1. Download the DataJoint MATLAB Toolbox from the `MATLAB Central FileExchange `_. -2. Open ``DataJoint.mltbx`` and follow installation instructions. -3. After installation, verify from MATLAB that you have the latest version of DataJoint (3.0.0 or above): - :: - - >> dj.version - DataJoint version 3.0.0 -4. At the MATLAB command prompt, assign the environment variables with the database credentials. - For example, if you are connection to the server ``alicelab.datajoint.io`` with username ``alice`` and password ``haha not my real password``, execute the following commands: - :: - - setenv DJ_USER alice - setenv DJ_HOST alicelab.datajoint.io - setenv DJ_PASS 'haha not my real password' - -You will need to execute these commands at the beginning of each DataJoint work session. -To automate this process, you might like to use the `startup.m `_ script. - -However, be careful not to share this file or commit it to a public directory (a common mistake), as it contains a your login credentials in plain text. -If you are not sure, it is better not to set ``DJ_PASS``, in which case DataJoint will prompt to enter the password when connecting to the database. - -To change the database password, use the following command - -:: - - >> dj.setPassword('my#cool!new*psswrd') - -And update your credentials in your startup script for the next session. diff --git a/docs-parts/version_common.json b/docs-parts/version_common.json deleted file mode 100644 index 5bef3068..00000000 --- a/docs-parts/version_common.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "comm_version": "v0.1" -} \ No newline at end of file diff --git a/docs/.docker/Dockerfile b/docs/.docker/Dockerfile new file mode 100644 index 00000000..e3acb0f4 --- /dev/null +++ b/docs/.docker/Dockerfile @@ -0,0 +1,15 @@ +FROM datajoint/miniconda3:4.10.3-py3.9-alpine +ARG PACKAGE +WORKDIR /main +COPY --chown=anaconda:anaconda ./docs/.docker/apk_requirements.txt ${APK_REQUIREMENTS} +COPY --chown=anaconda:anaconda ./docs/.docker/pip_requirements.txt ${PIP_REQUIREMENTS} +RUN \ + /entrypoint.sh echo "Dependencies installed" && \ + git config --global user.name "GitHub Action" && \ + git config --global user.email "action@github.com"&& \ + git config --global pull.rebase false && \ + git init +COPY --chown=anaconda:anaconda ./${PACKAGE} /main/${PACKAGE} +COPY --chown=anaconda:anaconda ./docs/mkdocs.yaml /main/docs/mkdocs.yaml +COPY --chown=anaconda:anaconda ./docs/src /main/docs/src +COPY --chown=anaconda:anaconda ./CHANGELOG.md /main/docs/src/about/changelog.md \ No newline at end of file diff --git a/docs/.docker/apk_requirements.txt b/docs/.docker/apk_requirements.txt new file mode 100644 index 00000000..5664e303 --- /dev/null +++ b/docs/.docker/apk_requirements.txt @@ -0,0 +1 @@ +git diff --git a/docs/.docker/pip_requirements.txt b/docs/.docker/pip_requirements.txt new file mode 100644 index 00000000..3e98f0c5 --- /dev/null +++ b/docs/.docker/pip_requirements.txt @@ -0,0 +1,6 @@ +mkdocs-material +mkdocs-redirects +mike +mdx-truly-sane-lists +mkdocs-literate-nav +mkdocs-exclude-search diff --git a/docs/.markdownlint.yaml b/docs/.markdownlint.yaml new file mode 100644 index 00000000..593bb1d7 --- /dev/null +++ b/docs/.markdownlint.yaml @@ -0,0 +1,20 @@ +# https://github.com/DavidAnson/markdownlint +# https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md +MD009: false # permit trailing spaces +MD013: + line_length: "88" # Line length limits + tables: false # disable for tables + headings: false # disable for headings + code_blocks: false # disable for code blocks +MD030: false # Number of spaces after a list +MD033: # HTML elements allowed + allowed_elements: + - "div" + - "span" + - "a" + - "br" + - "sup" + - "figure" +MD034: false # Bare URLs OK +MD031: false # Spacing w/code blocks. Conflicts with `??? Note` and code tab styling +MD046: false # Spacing w/code blocks. Conflicts with `??? Note` and code tab styling diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..a7da9542 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,16 @@ +# Docs Contributions + +Docs contributors should be aware of the following extensions, with the corresponding +settings files, that were used in developing these docs: + +- [MarkdownLinter](https://github.com/DavidAnson/markdownlint): + - `.markdownlint.yaml` establishes settings for various + [linter rules](https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md) + - `.vscode/settings.json` formatting on save to fix linting + +- [CSpell](https://github.com/streetsidesoftware/vscode-spell-checker): `cspell.json` +has various ignored words. + +- [ReWrap](https://github.com/stkb/Rewrap/): `.vscode/settings.json` allows toggling +automated hard wrapping for files at 88 characters. This can also be keymapped to be +performed on individual paragraphs, see documentation. diff --git a/docs/cspell.json b/docs/cspell.json new file mode 100644 index 00000000..eda71ee5 --- /dev/null +++ b/docs/cspell.json @@ -0,0 +1,31 @@ +// cSpell Settings +//https://github.com/streetsidesoftware/vscode-spell-checker +{ + "version": "0.2", // Version of the setting file. Always 0.2 + "language": "en", // language - current active spelling language + "enabledLanguageIds": [ + "markdown" + ], + // flagWords - list of words to be always considered incorrect + // This is useful for offensive words and common spelling errors. + // For example "hte" should be "the" + "flagWords": [], + "allowCompoundWords": true, + "ignorePaths": [ + "src/archive" + ], + "words": [ + "conda", + "linenums", + "repr", + "numpy", + "sess", + "cond", + "aggr", + "Aggr", + "cajal", + "Cajal", + "hubel", + "Hubel" + ] +} diff --git a/docs/mkdocs.yaml b/docs/mkdocs.yaml new file mode 100644 index 00000000..f54ef454 --- /dev/null +++ b/docs/mkdocs.yaml @@ -0,0 +1,108 @@ +# ---------------------- PROJECT SPECIFIC --------------------------- + +site_name: DataJoint Matlab +repo_url: https://github.com/datajoint/datajoint-matlab +repo_name: datajoint/datajoint-matlab +nav: + - DataJoint Matlab: getting-started/index.md + - Getting Started: getting-started/index.md + - Existing Pipelines: concepts/existing-pipelines.md + - Query Language: + - Common Commands: query-lang/common-commands.md + - Operators: query-lang/operators.md + - Iteration: query-lang/iteration.md + - Query Caching: query-lang/query-caching.md + - Reproducibility: + - Table Tiers: reproduce/table-tiers.md + - Make Method: reproduce/make-method.md + - Tutorials: tutorials.md + - Changelog: about/changelog.md + +# ---------------------------- STANDARD ----------------------------- + +edit_uri: ./edit/master/docs/src +docs_dir: ./src +theme: + font: + text: Roboto Slab + code: Source Code Pro + name: material + custom_dir: src/.overrides + icon: + logo: main/project-logo-black + favicon: assets/images/project-logo-color.png + features: + - toc.integrate + - content.code.annotate # Add codeblock annotations + palette: + - media: "(prefers-color-scheme: light)" + scheme: datajoint + toggle: + icon: material/brightness-7 + name: Switch to dark mode + - media: "(prefers-color-scheme: dark)" + scheme: slate + toggle: + icon: material/brightness-4 + name: Switch to light mode +plugins: + - search + - redirects: + redirect_maps: + "index.md": "getting-started/index.md" + - gen-files: + scripts: + - ./src/api/make_pages.py + - literate-nav: + nav_file: navigation.md + - exclude-search: + exclude: + - "*/navigation.md" + - "*/archive/*md" +markdown_extensions: + - attr_list + - toc: + permalink: true + - pymdownx.emoji: + emoji_index: !!python/name:materialx.emoji.twemoji + emoji_generator: !!python/name:materialx.emoji.to_svg + options: + custom_icons: + - .overrides/.icons + - mdx_truly_sane_lists + - pymdownx.tabbed: + alternate_style: true + - admonition + - pymdownx.details + - pymdownx.superfences: + custom_fences: + - name: mermaid + class: mermaid + format: !!python/name:pymdownx.superfences.fence_code_format +extra: + generator: false # Disable watermark + version: + provider: mike + social: + - icon: main/company-logo + link: https://www.datajoint.com/ + - icon: fontawesome/solid/ticket + link: https://support.djneuro.io/portal/en/home + - icon: fontawesome/brands/slack + link: https://datajoint.slack.com + - icon: fontawesome/brands/linkedin + link: https://www.linkedin.com/company/datajoint + - icon: fontawesome/brands/twitter + link: https://twitter.com/DataJointIO + - icon: fontawesome/brands/github + link: https://github.com/datajoint + - icon: fontawesome/brands/docker + link: https://hub.docker.com/u/datajoint + - icon: fontawesome/brands/python + link: https://pypi.org/user/datajointbot + - icon: fontawesome/brands/stack-overflow + link: https://stackoverflow.com/questions/tagged/datajoint + - icon: fontawesome/brands/youtube + link: https://www.youtube.com/channel/UCdeCuFOTCXlVMRzh6Wk-lGg +extra_css: + - assets/stylesheets/extra.css diff --git a/docs/src/.overrides/.icons/main/company-logo.svg b/docs/src/.overrides/.icons/main/company-logo.svg new file mode 100644 index 00000000..68c75c76 --- /dev/null +++ b/docs/src/.overrides/.icons/main/company-logo.svg @@ -0,0 +1,21 @@ + + www.datajoint.com + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/src/.overrides/.icons/main/project-logo-black.svg b/docs/src/.overrides/.icons/main/project-logo-black.svg new file mode 100644 index 00000000..76bebb11 --- /dev/null +++ b/docs/src/.overrides/.icons/main/project-logo-black.svg @@ -0,0 +1,22 @@ + + + + Asset 3 + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/src/.overrides/assets/images/project-logo-color.png b/docs/src/.overrides/assets/images/project-logo-color.png new file mode 100644 index 0000000000000000000000000000000000000000..d8117bbcbc777b3839813f9c2b252af3bb38ca70 GIT binary patch literal 82925 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

xXF?)GmMZeq6CK^^@TV{ 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 + + {% if config.repo_url %} +

+ {% include "partials/source.html" %} +
+ {% endif %} +
    + {% for nav_item in nav %} + {% set path = "__nav_" ~ loop.index %} + {% set level = 1 %} + {% include "partials/nav-item.html" %} + {% endfor %} +
+ \ No newline at end of file diff --git a/docs/src/concepts/existing-pipelines.md b/docs/src/concepts/existing-pipelines.md new file mode 100644 index 00000000..62fe4001 --- /dev/null +++ b/docs/src/concepts/existing-pipelines.md @@ -0,0 +1,27 @@ +# Existing Pipelines + +This section describes how to work with database schemas without access to the original +code that generated the schema. These situations often arise when the database is +created by another user who has not shared the generating code yet or when the database +schema is created from a programming language other than Matlab. + +## Creating a virtual class + +DataJoint MATLAB creates a `TableAccessor` property in each schema object. The +`TableAccessor` property, a *virtual class generator*, is available as `schema.v`, and +allows listing and querying of the tables defined on the server without needing to +create the MATLAB table definitions locally. For example, creating a scratch +`experiment` schema package and querying an existing `my_experiment.Session` table on +the server can be done as follows: + +``` matlab +dj.createSchema('experiment', '/scratch', 'my_experiment') +addpath('/scratch') +experiment_schema = experiment.getSchema(); +experiment_schema.v.Session() & 'session_id=1234'; +``` + +Note: You can view the available tables in a schema by using tab completion on +the `schema.v` property. + +To visualize an unfamiliar schema, see commands for generating [diagrams](../../getting-started/#diagram). diff --git a/docs/src/getting-started/index.md b/docs/src/getting-started/index.md new file mode 100644 index 00000000..f9887938 --- /dev/null +++ b/docs/src/getting-started/index.md @@ -0,0 +1,293 @@ +# Getting Started + +## Installation + +First, please install DataJoint via one of the following: + +=== "Matlab ≥ R2016b (recommended)" + + 1. Utilize MATLAB built-in GUI i.e. *Top Ribbon -> Add-Ons -> Get Add-Ons* + 2. Search and Select `DataJoint` + 3. Select *Add from GitHub* + +=== "GHToolbox" + + 1. Install *GHToolbox* using using an appropriate method in https://github.com/datajoint/GHToolbox + 2. run: `ghtb.install('datajoint/datajoint-matlab')` + +=== "Matlab < R2016" + + 1. Utilize MATLAB built-in GUI i.e. *Top Ribbon -> Add-Ons -> Get Add-Ons* + 2. Search and Select `DataJoint` + 3. Select *Download from GitHub* + 4. Save `DataJoint.mltbx` locally + 5. Navigate in MATLAB tree browser to saved toolbox file + 6. Right-Click and Select *Install* + 7. Select *Install* + +=== "From source" + + 1. Download `DataJoint.mltbx` locally + 2. Navigate in MATLAB tree browser to saved toolbox file + 3. Right-Click and Select *Install* + 4. Select *Install* + +After installing, that you have the latest version from Matlab: + +```matlab +>> dj.version +DataJoint version 3.5.0 +``` + +## Connection + +At the MATLAB command prompt, assign the environment variables with +the database credentials. For example, if you are connection to the +server `tutorial-db.datajoint.io` with username `alice` and password +`fake-password`, execute the following commands: + +```matlab +setenv DJ_USER alice +setenv DJ_HOST alicelab.datajoint.io +setenv DJ_PASS 'fake-password' +``` + +!!! note + + Although you may connect to any MySQL server of your choice, the DataJoint company + offers an online tutorial environment at `tutorial-db.datajoint.io`. Simply sign up + for a free[DataJoint account](https://accounts.datajoint.io). You will be granted + privileges to create schemas that are prefixed as `{user}_`. + +You will need to execute these commands at the beginning of each DataJoint work session. +To automate this process, you might add these items to the Matlab +[startup.m](https://www.mathworks.com/help/matlab/ref/startup.html) script. + +However, be careful not to share this file or commit it to a public directory (a common +mistake), as it contains a your login credentials in plain text. If you are not sure, +it is better not to set `DJ_PASS`, in which case DataJoint will prompt to enter the +password when connecting to the database. + +To change the database password, use the following command + +```matlab +>> dj.setPassword('my#cool!new*psswrd') +``` + +And update your credentials in your startup script for the next session. + +## Creating Schemas + +A schema can be created either automatically using the `dj.createSchema` +script or manually. While `dj.createSchema` simplifies the process, we'll also highlight +the manual approach to demonstrate each step. + +### Manual + +We can create the database schema using the following command: + +``` matlab +query(dj.conn, 'CREATE SCHEMA `{user}_my_schema`') +``` + +!!! Note "Server privileges" + + You must have create privileges for the schema name pattern. It is a common practice + to grant all privileges to users for schemas that begin with the username, in + addition to some shared schemas. Thus the user `alice` would be able to perform any + work in any schema that begins with `alice_`. + +Next, we can create the MATLAB package. + +DataJoint organizes schemas as MATLAB **packages**. If you are not +familiar with packages, please review: + +- [How to work with MATLAB packages](https://www.mathworks.com/help/matlab/matlab_oop/scoping-classes-with-packages.html) +- [How to manage MATLAB's search paths](https://www.mathworks.com/help/matlab/search-path.html) + +In your project directory, create the package folder, which must begin with a `+` sign. +For example, for the schema called `my_schema`, you would create the folder +`+my_schema`. Make sure that your project directory (the parent directory of your +package folder) is added to the MATLAB search path. + +Finally, we'll associate the package with the database schema. + +This step tells DataJoint that all classes in the package folder `+my_schema` will work +with tables in the database schema `{user}_my_schema`. Each package corresponds to +exactly one schema. In some special cases, multiple packages may all relate to a single +database schema, but in most cases there will be a one-to-one relationship between +packages and schemas. + +In the `+my_schema` folder, create the file `getSchema.m` with the +following contents: + +``` matlab +function obj = getSchema +persistent OBJ +if isempty(OBJ) + OBJ = dj.Schema(dj.conn, 'experiment', 'alice_experiment'); +end +obj = OBJ; +end +``` + +This function returns a persistent object of type `dj.Schema`, +establishing the link between the `my_schema` package in MATLAB and the +schema `{user}_my_schema` on the database server. + +## Automatic + +Alternatively, we can execute + +``` matlab +>> dj.createSchema +``` + +This automated script will walk you through the steps above and will create the schema, +the package folder, and the `getSchema` function in that folder. + +## Defining Tables + +DataJoint provides the interactive script `dj.new` for creating a new table. It will +prompt to enter the new table's class name in the form `package.ClassName`. This will +create the file `+package/ClassName.m`. + +For example, define the table `my_schema.Rectangle` + +``` matlab + >> dj.new + Enter .: my_schema.Rectangle + + Choose table tier: + L=lookup + M=manual + I=imported + C=computed + P=part + (L/M/I/C/P) > M +``` + +This will create the file `+my_schema.Rectangle.m` with the following +contents: + +``` matlab +%{ +# my newest table +# add primary key here +----- +# add additional attributes +%} +classdef Rectangle < dj.Manual +end +``` + +While `dj.new` adds a little bit of convenience, we can also create the classes from +scratch manually. Each newly created class must inherit from the DataJoint class +corresponding to the correct [data tier](../../reproduce/table-tiers): `dj.Lookup`, +`dj.Manual`, `dj.Imported` or `dj.Computed`. + +The most important part of the table definition is the comment preceding the `classdef`. +DataJoint will parse this comment to define the table. The class will become usable +after you edit this comment. For example: + +File `+my_schema/Rectangle.m` + +```matlab +%{ + shape_id: int + --- + shape_height: float + shape_width: float +%} +classdef Rectangle < dj.Manual +end +``` + +File `+my_schema/Area.m` + +```matlab +%{ + -> my_schema.Rectangle + --- + shape_area: float +%} +classdef Area < dj.Computed +end +``` + +The table definition is contained in the first block comment in the class definition +file. Note that although it looks like a mere comment, the table definition is parsed +by DataJoint. + +Users do not need to do anything special to have the table created in the database. The +table is created upon the first attempt to use the class for manipulating its data +(e.g. inserting or fetching entities). + +Furthermore, DataJoint provides the `syncDef` method to update the `classdef` file +definition string for the table with the definition in the actual table: + +``` matlab + syncDef(my_schema.Area) % updates the table definition in file +my_schema/Area.m +``` + +## Diagram + +### Display + +The diagram displays the relationship of the data model in the data pipeline. + +This can be done for an entire schema, or multiple schema: + +``` matlab +draw(dj.ERD(my_schema.getSchema)) +% OR +erd my_schema +erd my_schema my_other_schema +``` + +Or for individual or sets of tables: +```python +erd my_schema.Rectangle +draw(dj.ERD(my_schema.Rectangle) + dj.ERD(my_schema.Area)) +``` +### Customize + +Adding or substracting a number to a diagram object adds nodes downstream or upstream, +respectively, in the pipeline. + +``` python +draw(dj.ERD(my_schema.Rectangle)+1) # (1) +``` + +1. Plot all the tables directly downstream from `my_schema.Rectangle` + +```python +draw(dj.ERD(my_schema)-1+1) # (1) +``` + +1. Plot all tables directly downstream of those directly upstream of this schema. + +## Add data + +Let's add data for a rectangle: + +```matlab +insert(my_schema.Rectangle, {1, 2, 4}) +insert(my_schema.Rectangle, [{2, 2, 3},{3, 4, 2}]) +``` + +## Run computation + +Let's start the computations on our entity: `Area`. + +```python +populate(my_schema.Rectangle) +``` + +## Query + +Let's inspect the results. + +```python +Area & 'shape_area >= 8' +``` diff --git a/docs/src/images/shapes_pipeline.svg b/docs/src/images/shapes_pipeline.svg new file mode 100644 index 00000000..203b7b47 --- /dev/null +++ b/docs/src/images/shapes_pipeline.svg @@ -0,0 +1,36 @@ + + +%3 + + + +Area + + +Area + + + + + +Rectangle + + +Rectangle + + + + + +Rectangle->Area + + + + \ No newline at end of file diff --git a/docs/src/query-lang/common-commands.md b/docs/src/query-lang/common-commands.md new file mode 100644 index 00000000..67bad857 --- /dev/null +++ b/docs/src/query-lang/common-commands.md @@ -0,0 +1,154 @@ +XX - refer to existing table defintions +# Common Commands + + + +## Make + +See the article on [`make` methods](../../reproduce/make-method/) + +## Fetch + +DataJoint for MATLAB provides three distinct fetch methods: `fetch`, `fetch1`, and +`fetchn`. The three methods differ by the type and number of their returned variables. + +- `query.fetch` returns the result in the form of an *n* ⨉ 1 [struct array](https://www.mathworks.com/help/matlab/ref/struct.html) + where *n* is the number of records matching the query expression. + +- `query.fetch1` and `query.fetchn` split the result into separate output arguments, one + for each attribute of the query. + +The types of the variables returned by `fetch1` and `fetchn` depend on the datatypes of +the attributes. `query.fetchn` will enclose any attributes of char and blob types in +[cell arrays](https://www.mathworks.com/help/matlab/cell-arrays.html) whereas +`query.fetch1` will unpack them. + +MATLAB has two alternative forms of invoking a method on an object: using the dot +notation or passing the object as the first argument. The following two notations +produce an equivalent result: + +``` matlab +result = query.fetch(query, 'attr1') +result = fetch(query, 'attr1') +``` + +However, the dot syntax only works when the query object is already assigned to a +variable. The second syntax is more commonly used to avoid extra variables. + +For example, the two methods below are equivalent although the second +method creates an extra variable. + +``` matlab +result = fetch(university.Student, '*'); + +query = university.Student; +result = query.fetch() +``` + +### The primary key + +Without any arguments, the `fetch` method retrieves the primary key values of the table +in the form of a single column `struct`. The attribute names become the fieldnames of +the `struct`. + +``` matlab +keys = query.fetch; +keys = fetch(university.Student & university.StudentMajor); +``` + +Note that MATLAB allows calling functions without the parentheses `()`. + +### An entire query + +With a single-quoted asterisk (`'*'`) as the input argument, the `fetch` command +retrieves the entire result as a struct array. + +``` matlab +data = query.fetch('*'); +data = fetch(university.Student & university.StudentMajor, '*'); +``` + +??? Note "For very large tables..." + + In some cases, the amount of data returned by fetch can be quite large. When `query` + is a table object rather than a query expression, `query.sizeOnDisk()` reports the + estimated size of the entire table. It can be used to assess whether running + `query.fetch('*')` would be wise. Please note that it is only currently possible to + query the size of entire tables stored directly in the database . + +### Separate variables + +The `fetch1` and `fetchn` methods are used to retrieve each attribute into a separate +variable. DataJoint needs two different methods to tell MATLAB whether the result +should be in array or scalar form; for numerical fields it does not matter +(because scalars are still matrices in MATLAB) but non-uniform collections of values +must be enclosed in cell arrays. + +`query.fetch1` is used when `query` contains exactly one entity, otherwise `fetch1` will +raise an error. + +`query.fetchn` returns an arbitrary number of elements with character arrays and blobs +returned in the form of cell arrays, even when `query` happens to contain a single +entity. + +``` matlab +[name, img] = query.fetch1('name', 'image'); % (1) +[names, imgs] = query.fetchn('name', 'image'); % (2) +``` + +1. When the table has exactly one entity. +2. When the table has any number of entities: + +### The primary key and individual values + +It is often convenient to know the primary key values corresponding to attribute values +retrieved by `fetchn`. This can be done by adding a special input argument indicating +the request and another output argument to receive the key values: + +``` matlab +[names, imgs, keys] = query.fetchn('name', 'image', 'KEY'); +``` + +The resulting value of `keys` will be a column array of type `struct`. +This mechanism is only implemented for `fetchn`. + +### Rename and calculate + +In DataJoint for MATLAB, all `fetch` methods have all the same capability as the `proj +` operator. For example, renaming an attribute can be accomplished using the +syntax below. + +``` matlab +[names, BMIs] = query.fetchn('name', 'weight/height/height -> bmi'); +``` + +See [`proj`](../operators#proj) for an in-depth description of projection. + +### Sorting results + +To sort the result, add the additional `ORDER BY` argument in `fetch` and `fetchn` +methods as the last argument. + +The following command retrieves the field `course_name` from courses in the biology +department, sorted by course number. + +``` matlab +notes = fetchn(university.Course & 'dept="BIOL"', 'course_name', ... + 'ORDER BY course'); +``` + +The ORDER BY argument is passed directly to SQL and follows the same syntax as the +[ORDER BY clause](https://dev.mysql.com/doc/refman/5.7/en/order-by-optimization.html) + +Similarly, the LIMIT and OFFSET clauses can be used to limit the result to a subset of +entities. For example, to return the most advanced courses, one could do the +following: + +``` matlab +s = fetch(university.Course, '*', 'ORDER BY course DESC LIMIT 5') +``` + +The limit clause is passed directly to SQL and follows the same +[rules](https://dev.mysql.com/doc/refman/5.7/en/select.html) + + diff --git a/docs/src/query-lang/iteration.md b/docs/src/query-lang/iteration.md new file mode 100644 index 00000000..ef1c602a --- /dev/null +++ b/docs/src/query-lang/iteration.md @@ -0,0 +1,18 @@ +# Iteration + +The DataJoint model primarily handles data as sets, in the form of tables. However, it +can sometimes be useful to access or to perform actions such as visualization upon +individual entities sequentially. In DataJoint this is accomplished through iteration. + +In the simple example below, iteration is used to display the names and values of the +primary key attributes of each entity in the simple table or table expression `tab`. + +``` matlab +for key = tab.fetch()' + disp(key) +end +``` + +Note that the results returned by `fetch` must be transposed. MATLAB iterates across +columns, so the single column `struct` returned by `fetch` must be transposed into a +single row. diff --git a/docs/src/query-lang/operators.md b/docs/src/query-lang/operators.md new file mode 100644 index 00000000..7ff6c0fc --- /dev/null +++ b/docs/src/query-lang/operators.md @@ -0,0 +1,148 @@ +XX +# Operators + +The examples below will use the table definitions in [table tiers](../../reproduce/table-tiers). + + + +## Restriction + +`&` and `-` operators permit restriction. + +### By a mapping + +For a [Session table](../../reproduce/table-tiers#manual-tables), that has the attribute +`session_date`, we can restrict to sessions from January 1st, 2022: + +```matlab +Session & struct('session_date', '2018-01-01') +``` + +If there were any typos (e.g., using `sess_date` instead of `session_date`), our query +will return all of the entities of `Session`. + +### By a string + +Conditions may include arithmetic operations, functions, range tests, etc. Restriction +of table `A` by a string containing an attribute not found in table `A` produces an +error. + +```matlab +Session & 'user = "Alice"' # (1) +Session & 'session_date >= "2022-01-01"' # (2) +``` + +1. All the sessions performed by Alice +2. All of the sessions on or after January 1st, 2022 + +### By a collection + +When `cond` is a collection of conditions, the conditions are applied by logical +disjunction (logical OR). Restricting a table by a collection will return all entities +that meet *any* of the conditions in the collection. + +For example, if we restrict the `Session` table by a collection containing two +conditions, one for user and one for date, the query will return any sessions with a +matching user *or* date. + +```matlab +cond_cell = {'user = "Alice"', 'session_date = "2022-01-01"'} % (1) +cond_struct = struct('user', 'Alice', 'session_date', '2022-01-01') % (2) +cond_struct(2) = struct('user', 'Jerry', 'session_date', '2022-01-01') + +Session() & cond_struct % (3) +``` + +1. A cell array +2. A structure array +3. This command will show all the sessions that either Alice or Jerry conducted on the given day. + +### By a query + +Restriction by a query object is a generalization of restriction by a table. The example +below creates a query object corresponding to all the users named Alice. The `Session` +table is then restricted by the query object, returning all the sessions performed by +Alice. The `Experiment` table is then restricted by the query object, returning all the +experiments that are part of sessions performed by Alice. + +``` matlab +query = Session & 'user = "Alice"' +Experiment & query +``` + +## Proj + +Renaming an attribute in python can be done via keyword arguments: + +```matlab +table('old_attr->new_attr') +``` + +This can be done in the context of a table definition: + +``` matlab +%{ + # Experiment Session + -> experiment.Animal + session : smallint # session number for the animal + --- + session_date : date # YYYY-MM-DD + session_start_time : float # seconds relative to session_datetime + session_end_time : float # seconds relative to session_datetime + -> User.proj(experimenter='username') + -> User.proj(supervisor='username') +%} +classdef Session < dj.Manual +end +``` + +Or as part of a query + +```matlab +Session * Session.proj('session->other') +``` + +Projection can also be used to to compute new attributes from existing ones. + +```matlab +Session.proj('session_end_time-session_start_time -> duration') & 'duration > 10' +``` + +## Aggr + +For more complicated calculations, we can use aggregation. + +```matlab +Subject.aggr(Session,'count(*)->n') # (1) +Subject.aggr(Session,'avg(session_start_time)->average_start') # (2) +``` + +1. Number of sessions per subject. +2. Average `session_start_time` for each subject + + + +## Universal set + +!!! Warning + + `dj.U` is not yet implemented in MATLAB. The feature will be added in an + upcoming release. You can track progress with + [this GitHub issue](https://github.com/datajoint/datajoint-matlab/issues/144). + +Universal sets offer the complete list of combinations of attributes. + +```matlab +# All home cities of students +dj.U('laser_wavelength', 'laser_power') & Scan # (1) +dj.U('laser_wavelength', 'laser_power').aggr(Scan, 'count(*)->n') # (2) +dj.U().aggr(Session, 'max(session)->n') # (3) +``` + +1. All combinations of wavelength and power. +2. Total number of scans for each combination. +3. Largest session number. + +`dj.U()`, as shown in the last example above, is often useful for integer IDs. +For an example of this process, see the source code for +[Element Array Electrophysiology's `insert_new_params`](https://datajoint.com/docs/elements/element-array-ephys/latest/api/element_array_ephys/ephys_acute/#element_array_ephys.ephys_acute.ClusteringParamSet.insert_new_params). diff --git a/docs/src/reproduce/make-method.md b/docs/src/reproduce/make-method.md new file mode 100644 index 00000000..f3b08428 --- /dev/null +++ b/docs/src/reproduce/make-method.md @@ -0,0 +1,79 @@ +# Make Method + +Consider the following table definition from the article on +[table tiers](./table-tiers): + +```matlab +%{ Filtered image +-> test.Image +--- +filtered_image : longblob +%} + +classdef FilteredImage < dj.Computed + methods(Access=protected) + function makeTuples(self, key) + img = fetch1(test.Image & key, 'image'); + key.filtered_image = myfilter(img); + self.insert(key) + end + end +end +``` + +The `FilteredImage` table can be populated as + + +``` matlab +populate(test.FilteredImage) +``` + +Note that it is not necessary to specify which data needs to be computed. DataJoint will +call `make`, one-by-one, for every key in `Image` for which `FilteredImage` has not yet +been computed. + +The `make` method receives one argument: the dict `key` containing the primary key value +of an element of `key source` to be worked on. + +## Optional Arguments + +Behavior of the `populate` method depends on the number of output arguments requested in +the function call. When no output arguments are requested, errors will halt population. +With two output arguments(`failedKeys` and `errors`), `populate` will catch any +encountered errors and return them along with the offending keys. + +## Progress + +The function `parpopulate` works identically to `populate` except that it uses a job +reservation mechanism to allow multiple processes to populate the same table in +parallel without collision. When running `parpopulate` for the first time, DataJoint +will create a job reservation table and its class `.Jobs` with the following +declaration: + +``` matlab +{% + # the job reservation table + table_name : varchar(255) # className of the table + key_hash : char(32) # key hash + --- + status : enum('reserved','error','ignore')# if tuple is missing, the job is available + key=null : blob # structure containing the key + error_message="" : varchar(1023) # error message returned if failed + error_stack=null : blob # error stack if failed + host="" : varchar(255) # system hostname + pid=0 : int unsigned # system process id + timestamp=CURRENT_TIMESTAMP : timestamp # automatic timestamp +%} +``` + +A job is considered to be available when `.Jobs` contains no matching entry. + +For each `make` call, `parpopulate` sets the job status to `reserved`. When the job is +completed, the record is removed. If the job results in error, the job record is left +in place with the status set to `error` and the error message and error stacks saved. +Consequently, jobs that ended in error during the last execution will not be attempted +again until you delete the corresponding entities from `.Jobs`. + +The primary key of the jobs table comprises the name of the class and a 32-character +hash of the job's primary key. However, the key is saved in a separate field for error +debugging purposes. diff --git a/docs/src/reproduce/table-tiers.md b/docs/src/reproduce/table-tiers.md new file mode 100644 index 00000000..0ffe163e --- /dev/null +++ b/docs/src/reproduce/table-tiers.md @@ -0,0 +1,202 @@ +# Table Tiers + +To define a DataJoint table in Matlab: + +1. Define the table via multi-line comment. +2. Define a class inheriting from the appropriate DataJoint class: + `dj.Lookup`, `dj.Manual`, `dj.Imported` or `dj.Computed`. + +## Manual Tables + +The following code defines two manual tables, `Animal` and `Session`: + +File `+experiment/Animal.m` + +``` matlab +%{ + # information about animal + animal_id : int # animal id assigned by the lab + --- + -> experiment.Species + date_of_birth=null : date # YYYY-MM-DD optional + sex='' : enum('M', 'F', '') # leave empty if unspecified +%} +classdef Animal < dj.Manual +end +``` + +File `+experiment/Session.m` + +``` matlab +%{ + # Experiment Session + -> experiment.Animal + session : smallint # session number for the animal + --- + session_date : date # YYYY-MM-DD + session_start_time : float # seconds relative to session_datetime + session_end_time : float # seconds relative to session_datetime + -> [nullable] experiment.User +%} +classdef Session < dj.Manual +end +``` + +File `+experiment/Scan.m` XX WHERE? + +``` matlab +%{ + # Two-photon imaging scan + -> experiment.Session + scan : smallint # scan number within the session + --- + -> experiment.Lens + laser_wavelength : decimal(5,1) # um + laser_power : decimal(4,1) # mW +%} +classdef Scan < dj.Manual +end +``` + +Note that the notation to permit null entries differs for attributes versus foreign +key references. + +## Lookup Tables + +Lookup tables are commonly populated from their `contents` property. + +The table below is declared as a lookup table with its contents property +provided to generate entities. + +File `+lab/User.m` + +```matlab +%{ + # users in the lab + username : varchar(20) # user in the lab + --- + first_name : varchar(20) # user first name + last_name : varchar(20) # user last name +%} +classdef User < dj.Lookup + properties + contents = { + 'cajal' 'Santiago' 'Cajal' + 'hubel' 'David' 'Hubel' + 'wiesel' 'Torsten' 'Wiesel' + } + end +end +``` + +## Imported and Computed Tables + +Imported and Computed tables provide [`make` methods](./make-method) to determine how +they are populated, either from files or other tables. + +Imagine that there is a table `test.Image` that contains 2D grayscale images in its +`image` attribute. We can define the Computed table, `test.FilteredImage` that filters +the image in some way and saves the result in its `filtered_image` attribute. + +```matlab +%{ Filtered image +-> test.Image +--- +filtered_image : longblob +%} + +classdef FilteredImage < dj.Computed + methods(Access=protected) + function makeTuples(self, key) + img = fetch1(test.Image & key, 'image'); + key.filtered_image = myfilter(img); + self.insert(key) + end + end +end +``` + +??? Note "`makeTuples` vs. `make`" + + Currently matlab uses `makeTuples` rather than `make`. This will be + fixed in an upcoming release: + + + +## Part Tables + +The following code defines a Imported table with an associated part table. In MATLAB, the master and part tables are declared in a separate `classdef` file. The +name of the part table must begin with the name of the master table. The part table +must declare the property `master` containing an object of the master. + +```python +@schema +class Scan(dj.Imported): + definition = """ + # Two-photon imaging scan + -> Session + scan : smallint # scan number within the session + --- + -> Lens + laser_wavelength : decimal(5,1) # um + laser_power : decimal(4,1) # mW + """ + + class ScanField(dj.Part): + definition = """ + -> master + ROI: longblob # Region of interest + """ + + def make(self, key): + ... # (1) + self.insert1(key) + self.ScanField.insert1(ROI_information) +``` + + +`+image/Scan.m` + +``` matlab +%{ + # Two-photon imaging scan + -> Session + scan : smallint # scan number within the session + --- + -> Lens + laser_wavelength : decimal(5,1) # um + laser_power : decimal(4,1) # mW +%} +classdef Scan < dj.Computed + methods(Access=protected) + function make(self, key) + self.insert(key) + make(image.ScanField, key) + end + end +end +``` + +`+image/ScanField.m` + +``` matlab +%{ +# Region of interest resulting from segmentation +-> image.Scan +mask : smallint +--- +ROI : longblob # Region of interest +%} + +classdef ScanField < dj.Part + properties(SetAccess=protected) + master = image.Scan + end + methods + function make(self, key) + ... + self.insert(entity) + end + end +end +``` diff --git a/docs/src/tutorials.md b/docs/src/tutorials.md new file mode 100644 index 00000000..8b29d1af --- /dev/null +++ b/docs/src/tutorials.md @@ -0,0 +1,3 @@ +# Tutorials + +Coming soon! From 534b65cd407ff8282c2201f7dc44ea5a82e92853 Mon Sep 17 00:00:00 2001 From: CBroz1 Date: Wed, 9 Nov 2022 11:07:53 -0600 Subject: [PATCH 2/4] Docs edits, CICD wf --- .github/workflows/development.yaml | 19 +++++++++ CHANGELOG.md | 12 ++++++ README.md | 45 ++++++++++---------- docs/.docker/Dockerfile | 2 +- docs/cspell.json | 9 +++- docs/mkdocs.yaml | 8 +--- docs/src/changelog.md | 1 + docs/src/concepts/existing-pipelines.md | 6 ++- docs/src/getting-started/index.md | 25 +++++++---- docs/src/query-lang/common-commands.md | 36 ++++++++-------- docs/src/query-lang/operators.md | 19 ++++----- docs/src/reproduce/make-method.md | 5 +-- docs/src/reproduce/table-tiers.md | 56 ++++--------------------- 13 files changed, 120 insertions(+), 123 deletions(-) create mode 100644 CHANGELOG.md create mode 120000 docs/src/changelog.md diff --git a/.github/workflows/development.yaml b/.github/workflows/development.yaml index 6eef3970..39d2d61c 100644 --- a/.github/workflows/development.yaml +++ b/.github/workflows/development.yaml @@ -37,3 +37,22 @@ jobs: COMPOSE_HTTP_TIMEOUT: "120" run: | docker-compose -f LNX-docker-compose.yaml up --build --exit-code-from app + publish-docs: + if: | + github.event_name == 'push' && + startsWith(github.ref, 'refs/tags') + needs: test + runs-on: ubuntu-latest + env: + DOCKER_CLIENT_TIMEOUT: "120" + COMPOSE_HTTP_TIMEOUT: "120" + steps: + - uses: actions/checkout@v2 + - name: Deploy docs + run: | + export MODE=BUILD + export PACKAGE=datajoint + export UPSTREAM_REPO=https://github.com/${GITHUB_REPOSITORY}.git + export HOST_UID=$(id -u) + docker compose -f docs/docker-compose.yaml up --exit-code-from docs --build + git push origin gh-pages diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..aa03919b --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,12 @@ +# Changelog + +Observes [Semantic Versioning](https://semver.org/spec/v2.0.0.html) standard and +[Keep a Changelog](https://keepachangelog.com/en/1.0.0/) convention. + +## [3.5.0] - 2022-03-21 + ++ Bugfix: Cascading delete for renamed foreign keys (#379) PR #386 ++ Minor: Add renaming the same attribute multiple times within a single projection PR #386 ++ Minor: Add config for reading values with 32-bit dimensions (datajoint/mym#86) PR #395 + +[3.5.0]: https://github.com/datajoint/element-deeplabcut/releases/tag/3.5.0 diff --git a/README.md b/README.md index 00cc6c59..df30eacb 100644 --- a/README.md +++ b/README.md @@ -4,26 +4,25 @@ DataJoint for MATLAB is a high-level programming interface for relational databases designed to support data processing chains in science labs. DataJoint is built on the foundation of the relational data model and prescribes a consistent method for organizing, populating, and querying data. -DataJoint was initially developed in 2009 by Dimitri Yatsenko in Andreas Tolias' Lab at Baylor College of Medicine for the distributed processing and management of large volumes of data streaming from regular experiments. Starting in 2011, DataJoint has been available as an open-source project adopted by other labs and improved through contributions from several developers. -Presently, the primary developer of DataJoint open-source software is the company DataJoint (https://datajoint.com). Related resources are listed at https://datajoint.org. - -For more information, please visit our [documentation](https://datajoint.com/docs/core/datajoint-matlab/). - -## Config -For help in utilizing `dj.config` (added in `3.4.0`), you may access the help via `help('dj.config')` or review it online [here](https://github.com/datajoint/datajoint-matlab/blob/c2bd6b3e195dfeef773d4e12bad5573c461193b0/%2Bdj/config.m#L2-L27). Formal documentation to follow. +For more information, see our +[general](https://datajoint.com/docs/welcome/) and +[MATLAB](https://datajoint.com/docs/core/datajoint-matlab/) documentation pages. ## Citation + + If your work uses DataJoint for MATLAB, please cite the following Research Resource Identifier (RRID) and manuscript. + DataJoint ([RRID:SCR_014543](https://scicrunch.org/resolver/SCR_014543)) - DataJoint for MATLAB (version ``) + Yatsenko D, Reimer J, Ecker AS, Walker EY, Sinz F, Berens P, Hoenselaar A, Cotton RJ, Siapas AS, Tolias AS. DataJoint: managing big scientific data using MATLAB or Python. bioRxiv. 2015 Jan 1:031658. doi: https://doi.org/10.1101/031658 -## Running Tests Locally +## For Developers: Running Tests Locally +
Click to expand details -* Create an `.env` with desired development environment values e.g. ++ Create an `.env` with desired development environment values e.g. + ``` sh MATLAB_USER=rguzman MATLAB_LICENSE=IyBCRUd... # For image usage instructions see https://github.com/guzman-raphael/matlab, https://hub.docker.com/r/raphaelguzman/matlab @@ -34,11 +33,12 @@ MATLAB_GID=1000 MYSQL_TAG=5.7 MINIO_VER=RELEASE.2022-01-03T18-22-58Z ``` -* `cp local-docker-compose.yaml docker-compose.yaml` -* `docker-compose up` (Note configured `JUPYTER_PASSWORD`) -* Select a means of running MATLAB e.g. Jupyter Notebook, GUI, or Terminal (see bottom) -* Add `tests` directory to path e.g. in MATLAB, `addpath('tests')` -* Run desired tests. Some examples are as follows: + ++ `cp local-docker-compose.yaml docker-compose.yaml` ++ `docker-compose up` (Note configured `JUPYTER_PASSWORD`) ++ Select a means of running MATLAB e.g. Jupyter Notebook, GUI, or Terminal (see bottom) ++ Add `tests` directory to path e.g. in MATLAB, `addpath('tests')` ++ Run desired tests. Some examples are as follows: | Use Case | MATLAB Code | | ---------------------------- | ------------------------------------------------------------------------------ | @@ -47,23 +47,20 @@ MINIO_VER=RELEASE.2022-01-03T18-22-58Z | Run one specific test | `runtests('TestTls/TestTls_testInsecureConn')` | | Run tests based on test name | `import matlab.unittest.TestSuite;`
`import matlab.unittest.selectors.HasName;`
`import matlab.unittest.constraints.ContainsSubstring;`
`suite = TestSuite.fromClass(?Main, ... `
    `HasName(ContainsSubstring('Conn')));`
`run(suite)`| - ### Launch Jupyter Notebook -* Navigate to `localhost:8888` -* Input Jupyter password -* Launch a notebook i.e. `New > MATLAB` - ++ Navigate to `localhost:8888` ++ Input Jupyter password ++ Launch a notebook i.e. `New > MATLAB` ### Launch MATLAB GUI (supports remote interactive debugger) -* Shell into `datajoint-matlab_app_1` i.e. `docker exec -it datajoint-matlab_app_1 bash` -* Launch Matlab by runnning command `matlab` - ++ Shell into `datajoint-matlab_app_1` i.e. `docker exec -it datajoint-matlab_app_1 bash` ++ Launch Matlab by running command `matlab` ### Launch MATLAB Terminal -* Shell into `datajoint-matlab_app_1` i.e. `docker exec -it datajoint-matlab_app_1 bash` -* Launch Matlab with no GUI by runnning command `matlab -nodisplay` ++ Shell into `datajoint-matlab_app_1` i.e. `docker exec -it datajoint-matlab_app_1 bash` ++ Launch Matlab with no GUI by running command `matlab -nodisplay`
diff --git a/docs/.docker/Dockerfile b/docs/.docker/Dockerfile index e3acb0f4..649d256d 100644 --- a/docs/.docker/Dockerfile +++ b/docs/.docker/Dockerfile @@ -9,7 +9,7 @@ RUN \ git config --global user.email "action@github.com"&& \ git config --global pull.rebase false && \ git init -COPY --chown=anaconda:anaconda ./${PACKAGE} /main/${PACKAGE} +# COPY --chown=anaconda:anaconda ./${PACKAGE} /main/${PACKAGE} COPY --chown=anaconda:anaconda ./docs/mkdocs.yaml /main/docs/mkdocs.yaml COPY --chown=anaconda:anaconda ./docs/src /main/docs/src COPY --chown=anaconda:anaconda ./CHANGELOG.md /main/docs/src/about/changelog.md \ No newline at end of file diff --git a/docs/cspell.json b/docs/cspell.json index eda71ee5..cb29bedd 100644 --- a/docs/cspell.json +++ b/docs/cspell.json @@ -15,9 +15,16 @@ "src/archive" ], "words": [ - "conda", + "ghtb", + "disp", + "mltbx", + "setenv", + "isempty", + "fetchn", + "struct", "linenums", "repr", + "conda", "numpy", "sess", "cond", diff --git a/docs/mkdocs.yaml b/docs/mkdocs.yaml index f54ef454..e835c006 100644 --- a/docs/mkdocs.yaml +++ b/docs/mkdocs.yaml @@ -11,12 +11,11 @@ nav: - Common Commands: query-lang/common-commands.md - Operators: query-lang/operators.md - Iteration: query-lang/iteration.md - - Query Caching: query-lang/query-caching.md - Reproducibility: - Table Tiers: reproduce/table-tiers.md - Make Method: reproduce/make-method.md - - Tutorials: tutorials.md - - Changelog: about/changelog.md + # - Tutorials: tutorials.md # Commented out pending viable draft + - Changelog: changelog.md # ---------------------------- STANDARD ----------------------------- @@ -50,9 +49,6 @@ plugins: - redirects: redirect_maps: "index.md": "getting-started/index.md" - - gen-files: - scripts: - - ./src/api/make_pages.py - literate-nav: nav_file: navigation.md - exclude-search: diff --git a/docs/src/changelog.md b/docs/src/changelog.md new file mode 120000 index 00000000..699cc9e7 --- /dev/null +++ b/docs/src/changelog.md @@ -0,0 +1 @@ +../../CHANGELOG.md \ No newline at end of file diff --git a/docs/src/concepts/existing-pipelines.md b/docs/src/concepts/existing-pipelines.md index 62fe4001..8f98a178 100644 --- a/docs/src/concepts/existing-pipelines.md +++ b/docs/src/concepts/existing-pipelines.md @@ -21,7 +21,9 @@ experiment_schema = experiment.getSchema(); experiment_schema.v.Session() & 'session_id=1234'; ``` -Note: You can view the available tables in a schema by using tab completion on -the `schema.v` property. +???+ Note + + You can view the available tables in a schema by using tab completion on + the `schema.v` property. To visualize an unfamiliar schema, see commands for generating [diagrams](../../getting-started/#diagram). diff --git a/docs/src/getting-started/index.md b/docs/src/getting-started/index.md index f9887938..7514fc17 100644 --- a/docs/src/getting-started/index.md +++ b/docs/src/getting-started/index.md @@ -10,11 +10,6 @@ First, please install DataJoint via one of the following: 2. Search and Select `DataJoint` 3. Select *Add from GitHub* -=== "GHToolbox" - - 1. Install *GHToolbox* using using an appropriate method in https://github.com/datajoint/GHToolbox - 2. run: `ghtb.install('datajoint/datajoint-matlab')` - === "Matlab < R2016" 1. Utilize MATLAB built-in GUI i.e. *Top Ribbon -> Add-Ons -> Get Add-Ons* @@ -25,6 +20,11 @@ First, please install DataJoint via one of the following: 6. Right-Click and Select *Install* 7. Select *Install* +=== "GHToolbox" + + 1. Install *GHToolbox* using using an appropriate method in https://github.com/datajoint/GHToolbox + 2. run: `ghtb.install('datajoint/datajoint-matlab')` + === "From source" 1. Download `DataJoint.mltbx` locally @@ -48,7 +48,7 @@ server `tutorial-db.datajoint.io` with username `alice` and password ```matlab setenv DJ_USER alice -setenv DJ_HOST alicelab.datajoint.io +setenv DJ_HOST tutorial-db.datajoint.io setenv DJ_PASS 'fake-password' ``` @@ -56,7 +56,7 @@ setenv DJ_PASS 'fake-password' Although you may connect to any MySQL server of your choice, the DataJoint company offers an online tutorial environment at `tutorial-db.datajoint.io`. Simply sign up - for a free[DataJoint account](https://accounts.datajoint.io). You will be granted + for a free [DataJoint account](https://accounts.datajoint.io). You will be granted privileges to create schemas that are prefixed as `{user}_`. You will need to execute these commands at the beginning of each DataJoint work session. @@ -71,11 +71,15 @@ password when connecting to the database. To change the database password, use the following command ```matlab ->> dj.setPassword('my#cool!new*psswrd') +>> dj.setPassword('my#cool!new*password') ``` And update your credentials in your startup script for the next session. +For more information on various settings, access help via `help('dj.config')` or review +it online +[here](https://github.com/datajoint/datajoint-matlab/blob/c2bd6b3e195dfeef773d4e12bad5573c461193b0/%2Bdj/config.m#L2-L27). + ## Creating Schemas A schema can be created either automatically using the `dj.createSchema` @@ -90,7 +94,7 @@ We can create the database schema using the following command: query(dj.conn, 'CREATE SCHEMA `{user}_my_schema`') ``` -!!! Note "Server privileges" +??? Note "Server privileges" You must have create privileges for the schema name pattern. It is a common practice to grant all privileges to users for schemas that begin with the username, in @@ -250,6 +254,9 @@ Or for individual or sets of tables: erd my_schema.Rectangle draw(dj.ERD(my_schema.Rectangle) + dj.ERD(my_schema.Area)) ``` + +![Shapes Pipeline](../images/shapes_pipeline.svg) + ### Customize Adding or substracting a number to a diagram object adds nodes downstream or upstream, diff --git a/docs/src/query-lang/common-commands.md b/docs/src/query-lang/common-commands.md index 67bad857..b7916cdd 100644 --- a/docs/src/query-lang/common-commands.md +++ b/docs/src/query-lang/common-commands.md @@ -1,4 +1,3 @@ -XX - refer to existing table defintions # Common Commands @@ -39,9 +38,9 @@ For example, the two methods below are equivalent although the second method creates an extra variable. ``` matlab -result = fetch(university.Student, '*'); +result = fetch(my_schema.Rectangle, '*'); -query = university.Student; +query = my_schema.Rectangle; result = query.fetch() ``` @@ -53,7 +52,7 @@ the `struct`. ``` matlab keys = query.fetch; -keys = fetch(university.Student & university.StudentMajor); +keys = fetch(my_schema.Rectangle & my_schema.Area); ``` Note that MATLAB allows calling functions without the parentheses `()`. @@ -65,7 +64,7 @@ retrieves the entire result as a struct array. ``` matlab data = query.fetch('*'); -data = fetch(university.Student & university.StudentMajor, '*'); +data = fetch(my_schema.Rectangle & my_schema.Area, '*'); ``` ??? Note "For very large tables..." @@ -92,8 +91,8 @@ returned in the form of cell arrays, even when `query` happens to contain a sing entity. ``` matlab -[name, img] = query.fetch1('name', 'image'); % (1) -[names, imgs] = query.fetchn('name', 'image'); % (2) +[shape_id, height] = query.fetch1('shape_id', 'shape_height'); % (1) +[shape_ids, heights] = query.fetchn('shape_id', 'shape_height'); % (2) ``` 1. When the table has exactly one entity. @@ -106,7 +105,7 @@ retrieved by `fetchn`. This can be done by adding a special input argument indic the request and another output argument to receive the key values: ``` matlab -[names, imgs, keys] = query.fetchn('name', 'image', 'KEY'); +[shape_ids, heights, keys] = query.fetchn('shape_id', 'shape_height', 'KEY'); ``` The resulting value of `keys` will be a column array of type `struct`. @@ -114,12 +113,13 @@ This mechanism is only implemented for `fetchn`. ### Rename and calculate -In DataJoint for MATLAB, all `fetch` methods have all the same capability as the `proj -` operator. For example, renaming an attribute can be accomplished using the -syntax below. +In DataJoint for MATLAB, all `fetch` methods have all the same capability as the +[`proj` operator](../operators#proj). For example, renaming an attribute can be +accomplished using the syntax below. ``` matlab -[names, BMIs] = query.fetchn('name', 'weight/height/height -> bmi'); +[shape_ids, perimeter] = query.fetchn('shape_id', ... + '2*(shape_height+shape_width) -> perimeter'); ``` See [`proj`](../operators#proj) for an in-depth description of projection. @@ -129,23 +129,23 @@ See [`proj`](../operators#proj) for an in-depth description of projection. To sort the result, add the additional `ORDER BY` argument in `fetch` and `fetchn` methods as the last argument. -The following command retrieves the field `course_name` from courses in the biology -department, sorted by course number. +The following command retrieves the field `shape_id` from rectangles with height greater +than 2, sorted by width. ``` matlab -notes = fetchn(university.Course & 'dept="BIOL"', 'course_name', ... - 'ORDER BY course'); +notes = fetchn(my_schema.Rectangle & 'shape_height>2"', 'shape_id' ... + 'ORDER BY shape_width'); ``` The ORDER BY argument is passed directly to SQL and follows the same syntax as the [ORDER BY clause](https://dev.mysql.com/doc/refman/5.7/en/order-by-optimization.html) Similarly, the LIMIT and OFFSET clauses can be used to limit the result to a subset of -entities. For example, to return the most advanced courses, one could do the +entities. For example, to return the five rectangles with largest area, one could do the following: ``` matlab -s = fetch(university.Course, '*', 'ORDER BY course DESC LIMIT 5') +s = fetch(my_schema.Area, '*', 'ORDER BY shape_area DESC LIMIT 5') ``` The limit clause is passed directly to SQL and follows the same diff --git a/docs/src/query-lang/operators.md b/docs/src/query-lang/operators.md index 7ff6c0fc..fd785e74 100644 --- a/docs/src/query-lang/operators.md +++ b/docs/src/query-lang/operators.md @@ -1,4 +1,3 @@ -XX # Operators The examples below will use the table definitions in [table tiers](../../reproduce/table-tiers). @@ -28,8 +27,8 @@ of table `A` by a string containing an attribute not found in table `A` produces error. ```matlab -Session & 'user = "Alice"' # (1) -Session & 'session_date >= "2022-01-01"' # (2) +Session & 'user = "Alice"' % (1) +Session & 'session_date >= "2022-01-01"' % (2) ``` 1. All the sessions performed by Alice @@ -55,7 +54,8 @@ Session() & cond_struct % (3) 1. A cell array 2. A structure array -3. This command will show all the sessions that either Alice or Jerry conducted on the given day. +3. This command will show all the sessions that either Alice or Jerry conducted on the + given day. ### By a query @@ -113,8 +113,8 @@ Session.proj('session_end_time-session_start_time -> duration') & 'duration > 10 For more complicated calculations, we can use aggregation. ```matlab -Subject.aggr(Session,'count(*)->n') # (1) -Subject.aggr(Session,'avg(session_start_time)->average_start') # (2) +Subject.aggr(Session,'count(*)->n') % (1) +Subject.aggr(Session,'avg(session_start_time)->average_start') % (2) ``` 1. Number of sessions per subject. @@ -133,10 +133,9 @@ Subject.aggr(Session,'avg(session_start_time)->average_start') # (2) Universal sets offer the complete list of combinations of attributes. ```matlab -# All home cities of students -dj.U('laser_wavelength', 'laser_power') & Scan # (1) -dj.U('laser_wavelength', 'laser_power').aggr(Scan, 'count(*)->n') # (2) -dj.U().aggr(Session, 'max(session)->n') # (3) +dj.U('laser_wavelength', 'laser_power') & Scan % (1) +dj.U('laser_wavelength', 'laser_power').aggr(Scan, 'count(*)->n') % (2) +dj.U().aggr(Session, 'max(session)->n') % (3) ``` 1. All combinations of wavelength and power. diff --git a/docs/src/reproduce/make-method.md b/docs/src/reproduce/make-method.md index f3b08428..57056eeb 100644 --- a/docs/src/reproduce/make-method.md +++ b/docs/src/reproduce/make-method.md @@ -1,7 +1,7 @@ # Make Method Consider the following table definition from the article on -[table tiers](./table-tiers): +[table tiers](../table-tiers): ```matlab %{ Filtered image @@ -14,7 +14,7 @@ classdef FilteredImage < dj.Computed methods(Access=protected) function makeTuples(self, key) img = fetch1(test.Image & key, 'image'); - key.filtered_image = myfilter(img); + key.filtered_image = my_filter(img); self.insert(key) end end @@ -23,7 +23,6 @@ end The `FilteredImage` table can be populated as - ``` matlab populate(test.FilteredImage) ``` diff --git a/docs/src/reproduce/table-tiers.md b/docs/src/reproduce/table-tiers.md index 0ffe163e..aab832e3 100644 --- a/docs/src/reproduce/table-tiers.md +++ b/docs/src/reproduce/table-tiers.md @@ -42,22 +42,6 @@ classdef Session < dj.Manual end ``` -File `+experiment/Scan.m` XX WHERE? - -``` matlab -%{ - # Two-photon imaging scan - -> experiment.Session - scan : smallint # scan number within the session - --- - -> experiment.Lens - laser_wavelength : decimal(5,1) # um - laser_power : decimal(4,1) # mW -%} -classdef Scan < dj.Manual -end -``` - Note that the notation to permit null entries differs for attributes versus foreign key references. @@ -109,7 +93,7 @@ classdef FilteredImage < dj.Computed methods(Access=protected) function makeTuples(self, key) img = fetch1(test.Image & key, 'image'); - key.filtered_image = myfilter(img); + key.filtered_image = my_filter(img); self.insert(key) end end @@ -119,41 +103,15 @@ end ??? Note "`makeTuples` vs. `make`" Currently matlab uses `makeTuples` rather than `make`. This will be - fixed in an upcoming release: - - + fixed in an upcoming release. You can monitor the discussion + [here](https://github.com/datajoint/datajoint-matlab/issues/141) ## Part Tables -The following code defines a Imported table with an associated part table. In MATLAB, the master and part tables are declared in a separate `classdef` file. The -name of the part table must begin with the name of the master table. The part table -must declare the property `master` containing an object of the master. - -```python -@schema -class Scan(dj.Imported): - definition = """ - # Two-photon imaging scan - -> Session - scan : smallint # scan number within the session - --- - -> Lens - laser_wavelength : decimal(5,1) # um - laser_power : decimal(4,1) # mW - """ - - class ScanField(dj.Part): - definition = """ - -> master - ROI: longblob # Region of interest - """ - - def make(self, key): - ... # (1) - self.insert1(key) - self.ScanField.insert1(ROI_information) -``` - +The following code defines a Imported table with an associated part table. In MATLAB, +the master and part tables are declared in a separate `classdef` file. The name of the +part table must begin with the name of the master table. The part table must declare the +property `master` containing an object of the master. `+image/Scan.m` From 1862c5d4de63e5884992b87c7288f99c258c12fc Mon Sep 17 00:00:00 2001 From: CBroz1 Date: Wed, 9 Nov 2022 14:42:47 -0600 Subject: [PATCH 3/4] Update logo/styling --- docs/mkdocs.yaml | 22 ++++++--- .../.overrides/.icons/main/company-logo.svg | 32 +++++-------- .../.icons/main/project-logo-black.svg | 22 --------- .../assets/images/company-logo-blue.png | Bin 0 -> 41770 bytes .../assets/images/project-logo-color.png | Bin 82925 -> 0 bytes .../.overrides/assets/stylesheets/extra.css | 45 ++++++++++++++---- 6 files changed, 64 insertions(+), 57 deletions(-) delete mode 100644 docs/src/.overrides/.icons/main/project-logo-black.svg create mode 100644 docs/src/.overrides/assets/images/company-logo-blue.png delete mode 100644 docs/src/.overrides/assets/images/project-logo-color.png diff --git a/docs/mkdocs.yaml b/docs/mkdocs.yaml index e835c006..9bc27006 100644 --- a/docs/mkdocs.yaml +++ b/docs/mkdocs.yaml @@ -28,8 +28,8 @@ theme: name: material custom_dir: src/.overrides icon: - logo: main/project-logo-black - favicon: assets/images/project-logo-color.png + logo: main/company-logo + favicon: assets/images/company-logo-blue.png features: - toc.integrate - content.code.annotate # Add codeblock annotations @@ -77,28 +77,38 @@ markdown_extensions: format: !!python/name:pymdownx.superfences.fence_code_format extra: generator: false # Disable watermark + analytics: + provider: google + property: !ENV GOOGLE_ANALYTICS_KEY version: provider: mike social: - icon: main/company-logo - link: https://www.datajoint.com/ - - icon: fontawesome/solid/ticket - link: https://support.djneuro.io/portal/en/home + link: https://www.datajoint.com + name: DataJoint - icon: fontawesome/brands/slack link: https://datajoint.slack.com + name: Slack - icon: fontawesome/brands/linkedin link: https://www.linkedin.com/company/datajoint + name: LinkedIn - icon: fontawesome/brands/twitter - link: https://twitter.com/DataJointIO + link: https://twitter.com/datajoint + name: Twitter - icon: fontawesome/brands/github link: https://github.com/datajoint + name: GitHub - icon: fontawesome/brands/docker link: https://hub.docker.com/u/datajoint + name: DockerHub - icon: fontawesome/brands/python link: https://pypi.org/user/datajointbot + name: PyPI - icon: fontawesome/brands/stack-overflow link: https://stackoverflow.com/questions/tagged/datajoint + name: StackOverflow - icon: fontawesome/brands/youtube link: https://www.youtube.com/channel/UCdeCuFOTCXlVMRzh6Wk-lGg + name: YouTube extra_css: - assets/stylesheets/extra.css diff --git a/docs/src/.overrides/.icons/main/company-logo.svg b/docs/src/.overrides/.icons/main/company-logo.svg index 68c75c76..e876313c 100644 --- a/docs/src/.overrides/.icons/main/company-logo.svg +++ b/docs/src/.overrides/.icons/main/company-logo.svg @@ -1,21 +1,11 @@ - - www.datajoint.com - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + + diff --git a/docs/src/.overrides/.icons/main/project-logo-black.svg b/docs/src/.overrides/.icons/main/project-logo-black.svg deleted file mode 100644 index 76bebb11..00000000 --- a/docs/src/.overrides/.icons/main/project-logo-black.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - - Asset 3 - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/src/.overrides/assets/images/company-logo-blue.png b/docs/src/.overrides/assets/images/company-logo-blue.png new file mode 100644 index 0000000000000000000000000000000000000000..d15194b8db09a9fabae8da2cdb2f2a4d3c820a96 GIT binary patch literal 41770 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 literal 0 HcmV?d00001 diff --git a/docs/src/.overrides/assets/images/project-logo-color.png b/docs/src/.overrides/assets/images/project-logo-color.png deleted file mode 100644 index d8117bbcbc777b3839813f9c2b252af3bb38ca70..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 82925 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

xXF?)GmMZeq6CK^^@TV{ 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 Date: Fri, 2 Dec 2022 11:56:14 -0600 Subject: [PATCH 4/4] Add gh-action workflow; add vscode setting json codeblock --- .github/workflows/publish-docs.yaml | 22 ++++++++++++++++++++++ docs/README.md | 22 +++++++++++++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/publish-docs.yaml diff --git a/.github/workflows/publish-docs.yaml b/.github/workflows/publish-docs.yaml new file mode 100644 index 00000000..7f39245e --- /dev/null +++ b/.github/workflows/publish-docs.yaml @@ -0,0 +1,22 @@ +name: Publish Docs +on: + push: + tags: + - 'test*.*.*' + workflow_dispatch: +jobs: + publish-docs: + runs-on: ubuntu-latest + env: + DOCKER_CLIENT_TIMEOUT: "120" + COMPOSE_HTTP_TIMEOUT: "120" + steps: + - uses: actions/checkout@v2 + - name: Deploy docs + run: | + export MODE=BUILD + export PACKAGE=datajoint + export UPSTREAM_REPO=https://github.com/${GITHUB_REPOSITORY}.git + export HOST_UID=$(id -u) + docker compose -f docs/docker-compose.yaml up --exit-code-from docs --build + git push origin gh-pages diff --git a/docs/README.md b/docs/README.md index a7da9542..dd9689db 100644 --- a/docs/README.md +++ b/docs/README.md @@ -6,7 +6,27 @@ settings files, that were used in developing these docs: - [MarkdownLinter](https://github.com/DavidAnson/markdownlint): - `.markdownlint.yaml` establishes settings for various [linter rules](https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md) - - `.vscode/settings.json` formatting on save to fix linting + - `.vscode/settings.json` formatting settings + + ```json + { + "[markdown]" : { + "editor.rulers": [88], + "editor.formatOnPaste": true, + "editor.formatOnSave": true, + // https://github.com/stkb/Rewrap/ + // Toggle via command prompt per file + // Default paragraph rewrap key: alt+q or option+q + "rewrap.autoWrap.enabled": true, + "rewrap.wrappingColumn": 88 + }, + // https://github.com/DavidAnson/markdownlint + "editor.codeActionsOnSave": { + "source.fixAll.markdownlint":true + }, + "markdownlint.focusMode": 5, // ignore issues around the cursor + } + ``` - [CSpell](https://github.com/streetsidesoftware/vscode-spell-checker): `cspell.json` has various ignored words.