mosaic-behavior 0.17.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mosaic/__init__.py +1 -0
- mosaic/__main__.py +12 -0
- mosaic/agent/SKILL.md +285 -0
- mosaic/agent/__init__.py +403 -0
- mosaic/agent/mcp/__init__.py +9 -0
- mosaic/agent/mcp/_binding.py +460 -0
- mosaic/agent/mcp/config.py +106 -0
- mosaic/agent/mcp/local.py +1101 -0
- mosaic/agent/mcp/outputs.py +64 -0
- mosaic/agent/mcp/prompts.py +216 -0
- mosaic/agent/mcp/resources.py +437 -0
- mosaic/agent/mcp/server.py +91 -0
- mosaic/agent/mcp/spec.py +1349 -0
- mosaic/agent/mcp/summaries.py +310 -0
- mosaic/behavior/__init__.py +39 -0
- mosaic/behavior/feature_library/__init__.py +260 -0
- mosaic/behavior/feature_library/_identity_model_descriptions.py +50 -0
- mosaic/behavior/feature_library/_pair_filter_descriptions.py +16 -0
- mosaic/behavior/feature_library/_sampling_descriptions.py +21 -0
- mosaic/behavior/feature_library/approach_avoidance.py +629 -0
- mosaic/behavior/feature_library/arhmm.py +475 -0
- mosaic/behavior/feature_library/arhmm_model.py +1107 -0
- mosaic/behavior/feature_library/attention_target.py +251 -0
- mosaic/behavior/feature_library/body_scale.py +149 -0
- mosaic/behavior/feature_library/collective_math.py +377 -0
- mosaic/behavior/feature_library/collective_motion_metrics.py +699 -0
- mosaic/behavior/feature_library/dinov2_temporal_identity_model.py +501 -0
- mosaic/behavior/feature_library/external/__init__.py +29 -0
- mosaic/behavior/feature_library/external/kpms_protocol.py +146 -0
- mosaic/behavior/feature_library/external/kpms_server.py +494 -0
- mosaic/behavior/feature_library/external/runner_wire.py +452 -0
- mosaic/behavior/feature_library/external/vame_protocol.py +624 -0
- mosaic/behavior/feature_library/external/vame_runner.py +1212 -0
- mosaic/behavior/feature_library/extract_labeled_templates.py +743 -0
- mosaic/behavior/feature_library/extract_templates.py +456 -0
- mosaic/behavior/feature_library/feature_template__global.py +175 -0
- mosaic/behavior/feature_library/feature_template__per_sequence.py +211 -0
- mosaic/behavior/feature_library/feral_feature.py +2109 -0
- mosaic/behavior/feature_library/ffgroups.py +425 -0
- mosaic/behavior/feature_library/ffgroups_metrics.py +333 -0
- mosaic/behavior/feature_library/frame_aggregate.py +215 -0
- mosaic/behavior/feature_library/global_kmeans.py +324 -0
- mosaic/behavior/feature_library/global_scaler.py +219 -0
- mosaic/behavior/feature_library/global_tsne.py +489 -0
- mosaic/behavior/feature_library/global_ward.py +266 -0
- mosaic/behavior/feature_library/heading.py +219 -0
- mosaic/behavior/feature_library/helpers.py +339 -0
- mosaic/behavior/feature_library/id_tag_columns.py +195 -0
- mosaic/behavior/feature_library/identity_embedding_model.py +429 -0
- mosaic/behavior/feature_library/identity_model.py +470 -0
- mosaic/behavior/feature_library/kpms.py +744 -0
- mosaic/behavior/feature_library/lightning_action_feature.py +581 -0
- mosaic/behavior/feature_library/local_order_metrics.py +644 -0
- mosaic/behavior/feature_library/movement/__init__.py +17 -0
- mosaic/behavior/feature_library/movement/convert.py +272 -0
- mosaic/behavior/feature_library/movement/filter_interp.py +200 -0
- mosaic/behavior/feature_library/movement/smooth.py +199 -0
- mosaic/behavior/feature_library/nearestneighbor.py +206 -0
- mosaic/behavior/feature_library/nn_delta_bins.py +613 -0
- mosaic/behavior/feature_library/nn_delta_response.py +465 -0
- mosaic/behavior/feature_library/orientation_relative.py +297 -0
- mosaic/behavior/feature_library/pair_egocentric.py +427 -0
- mosaic/behavior/feature_library/pair_facing.py +353 -0
- mosaic/behavior/feature_library/pair_interaction_filter.py +510 -0
- mosaic/behavior/feature_library/pair_position.py +359 -0
- mosaic/behavior/feature_library/pair_wavelet.py +319 -0
- mosaic/behavior/feature_library/pairposedistancepca.py +394 -0
- mosaic/behavior/feature_library/registry.py +19 -0
- mosaic/behavior/feature_library/runner_client.py +477 -0
- mosaic/behavior/feature_library/scale_to_cm.py +366 -0
- mosaic/behavior/feature_library/social_motion_summary.py +625 -0
- mosaic/behavior/feature_library/speed_angvel.py +305 -0
- mosaic/behavior/feature_library/temporal_stacking.py +427 -0
- mosaic/behavior/feature_library/track_subsample.py +318 -0
- mosaic/behavior/feature_library/trajectory_smooth.py +277 -0
- mosaic/behavior/feature_library/types.py +144 -0
- mosaic/behavior/feature_library/vame_feature.py +1182 -0
- mosaic/behavior/feature_library/vame_sessions.py +703 -0
- mosaic/behavior/feature_library/xgboost_feature.py +491 -0
- mosaic/behavior/label_library/__init__.py +83 -0
- mosaic/behavior/label_library/_boris_descriptions.py +48 -0
- mosaic/behavior/label_library/boris_aggregated_csv.py +414 -0
- mosaic/behavior/label_library/boris_pandas_pickle.py +435 -0
- mosaic/behavior/label_library/calms21_behavior.py +172 -0
- mosaic/behavior/label_library/custom_label_template.py +507 -0
- mosaic/behavior/label_library/label_converter_template.py +265 -0
- mosaic/behavior/model_library/__init__.py +31 -0
- mosaic/behavior/model_library/dinov2_temporal_identity.py +523 -0
- mosaic/behavior/model_library/identity_classifier.py +504 -0
- mosaic/behavior/model_library/identity_common.py +347 -0
- mosaic/behavior/model_library/identity_embedding.py +350 -0
- mosaic/behavior/model_library/timm_backbone.py +336 -0
- mosaic/behavior/visualization_library/__init__.py +106 -0
- mosaic/behavior/visualization_library/_crop_descriptions.py +94 -0
- mosaic/behavior/visualization_library/data_loading.py +292 -0
- mosaic/behavior/visualization_library/egocentric_crop.py +949 -0
- mosaic/behavior/visualization_library/helpers.py +433 -0
- mosaic/behavior/visualization_library/interaction_crop.py +711 -0
- mosaic/behavior/visualization_library/overlay.py +941 -0
- mosaic/behavior/visualization_library/overlay_feature.py +321 -0
- mosaic/behavior/visualization_library/playback.py +324 -0
- mosaic/behavior/visualization_library/video_stream.py +214 -0
- mosaic/behavior/visualization_library/visual_spec.py +534 -0
- mosaic/cli/__init__.py +92 -0
- mosaic/cli/_context.py +98 -0
- mosaic/cli/_features.py +93 -0
- mosaic/cli/_io.py +206 -0
- mosaic/cli/_render.py +37 -0
- mosaic/cli/agent.py +249 -0
- mosaic/cli/cancel.py +103 -0
- mosaic/cli/convert_labels.py +62 -0
- mosaic/cli/convert_tracks.py +105 -0
- mosaic/cli/describe.py +97 -0
- mosaic/cli/features/__init__.py +18 -0
- mosaic/cli/features/describe.py +47 -0
- mosaic/cli/features/list.py +55 -0
- mosaic/cli/init.py +115 -0
- mosaic/cli/inventory.py +308 -0
- mosaic/cli/libraries.py +110 -0
- mosaic/cli/measure_tracks.py +227 -0
- mosaic/cli/models.py +78 -0
- mosaic/cli/pipeline.py +784 -0
- mosaic/cli/preview.py +134 -0
- mosaic/cli/prune_joined.py +126 -0
- mosaic/cli/prune_media.py +149 -0
- mosaic/cli/reconcile.py +128 -0
- mosaic/cli/reindex.py +89 -0
- mosaic/cli/release.py +134 -0
- mosaic/cli/reprobe_media.py +182 -0
- mosaic/cli/run.py +438 -0
- mosaic/cli/runs.py +207 -0
- mosaic/cli/scan.py +134 -0
- mosaic/cli/sequences.py +60 -0
- mosaic/cli/sources.py +399 -0
- mosaic/cli/status.py +78 -0
- mosaic/cli/sweep_tracking.py +133 -0
- mosaic/cli/tags.py +270 -0
- mosaic/cli/track.py +240 -0
- mosaic/cli/tracking/__init__.py +18 -0
- mosaic/cli/tracking/describe.py +31 -0
- mosaic/cli/tracking/list.py +38 -0
- mosaic/cli/upgrade_tracks.py +94 -0
- mosaic/core/__init__.py +72 -0
- mosaic/core/analysis.py +573 -0
- mosaic/core/annotations/__init__.py +35 -0
- mosaic/core/annotations/bbox.py +432 -0
- mosaic/core/annotations/model.py +344 -0
- mosaic/core/annotations/narrow.py +329 -0
- mosaic/core/annotations/pose_annotations.py +587 -0
- mosaic/core/annotations/projection.py +129 -0
- mosaic/core/annotations/readers/__init__.py +17 -0
- mosaic/core/annotations/readers/coco.py +250 -0
- mosaic/core/annotations/readers/cvat.py +124 -0
- mosaic/core/annotations/readers/yolo_pose.py +192 -0
- mosaic/core/annotations/split.py +183 -0
- mosaic/core/annotations/writers/__init__.py +11 -0
- mosaic/core/annotations/writers/coco.py +202 -0
- mosaic/core/dataset.py +7712 -0
- mosaic/core/dataset_discovery.py +202 -0
- mosaic/core/dataset_summary.py +226 -0
- mosaic/core/entry.py +115 -0
- mosaic/core/helpers.py +768 -0
- mosaic/core/individuals.py +83 -0
- mosaic/core/json_value.py +33 -0
- mosaic/core/kinematics.py +99 -0
- mosaic/core/label_converter.py +280 -0
- mosaic/core/manifest.py +1509 -0
- mosaic/core/media/__init__.py +98 -0
- mosaic/core/media/drift.py +126 -0
- mosaic/core/media/facts_columns.py +398 -0
- mosaic/core/media/imgstore_io.py +538 -0
- mosaic/core/media/imgstore_native.py +452 -0
- mosaic/core/media/preprocess/__init__.py +92 -0
- mosaic/core/media/preprocess/appearance.py +52 -0
- mosaic/core/media/preprocess/crop.py +127 -0
- mosaic/core/media/preprocess/frames.py +114 -0
- mosaic/core/media/preprocess/geometry.py +450 -0
- mosaic/core/media/preprocess/mask.py +96 -0
- mosaic/core/media/preprocess/registry.py +113 -0
- mosaic/core/media/preprocess/specs.py +33 -0
- mosaic/core/media/preprocess/steps.py +148 -0
- mosaic/core/media/probe_row.py +45 -0
- mosaic/core/media/prune.py +698 -0
- mosaic/core/media/prune_joined.py +297 -0
- mosaic/core/media/read_target.py +158 -0
- mosaic/core/media/rearrange.py +324 -0
- mosaic/core/media/reprobe.py +709 -0
- mosaic/core/media/store_rate.py +66 -0
- mosaic/core/media/timeline.py +220 -0
- mosaic/core/media/uniformity.py +247 -0
- mosaic/core/media/video_io.py +941 -0
- mosaic/core/narrowing.py +35 -0
- mosaic/core/params.py +375 -0
- mosaic/core/pipeline/__init__.py +129 -0
- mosaic/core/pipeline/_loaders.py +144 -0
- mosaic/core/pipeline/_utils.py +317 -0
- mosaic/core/pipeline/artifact_kinds.py +89 -0
- mosaic/core/pipeline/cancel.py +530 -0
- mosaic/core/pipeline/column_contract.py +885 -0
- mosaic/core/pipeline/composition.py +273 -0
- mosaic/core/pipeline/consumed_camera.py +76 -0
- mosaic/core/pipeline/dataset_indexes.py +299 -0
- mosaic/core/pipeline/delete_set.py +313 -0
- mosaic/core/pipeline/entry_claim.py +269 -0
- mosaic/core/pipeline/error_envelope.py +54 -0
- mosaic/core/pipeline/error_kind.py +80 -0
- mosaic/core/pipeline/file_digest.py +66 -0
- mosaic/core/pipeline/fit_scope.py +178 -0
- mosaic/core/pipeline/graph/__init__.py +747 -0
- mosaic/core/pipeline/graph/catalog_search.py +108 -0
- mosaic/core/pipeline/graph/claims.py +261 -0
- mosaic/core/pipeline/graph/columns.py +589 -0
- mosaic/core/pipeline/graph/compatibility.py +482 -0
- mosaic/core/pipeline/graph/digest.py +92 -0
- mosaic/core/pipeline/graph/driver_lease.py +524 -0
- mosaic/core/pipeline/graph/entry_errors.py +200 -0
- mosaic/core/pipeline/graph/failures.py +243 -0
- mosaic/core/pipeline/graph/lanes.py +108 -0
- mosaic/core/pipeline/graph/model.py +386 -0
- mosaic/core/pipeline/graph/plan.py +1268 -0
- mosaic/core/pipeline/graph/request.py +360 -0
- mosaic/core/pipeline/graph/resolve.py +1004 -0
- mosaic/core/pipeline/graph/rollup.py +187 -0
- mosaic/core/pipeline/graph/run.py +548 -0
- mosaic/core/pipeline/graph/scope.py +148 -0
- mosaic/core/pipeline/graph/serialize.py +147 -0
- mosaic/core/pipeline/graph/status.py +501 -0
- mosaic/core/pipeline/graph/step.py +763 -0
- mosaic/core/pipeline/graph/step_preflight.py +266 -0
- mosaic/core/pipeline/graph/storage.py +42 -0
- mosaic/core/pipeline/graph/store.py +298 -0
- mosaic/core/pipeline/graph/topo.py +164 -0
- mosaic/core/pipeline/graph/validate.py +1485 -0
- mosaic/core/pipeline/graph/wire.py +589 -0
- mosaic/core/pipeline/identity_scheme.py +167 -0
- mosaic/core/pipeline/index.py +326 -0
- mosaic/core/pipeline/index_csv.py +720 -0
- mosaic/core/pipeline/index_lock.py +377 -0
- mosaic/core/pipeline/inventory/__init__.py +145 -0
- mosaic/core/pipeline/inventory/_read.py +116 -0
- mosaic/core/pipeline/inventory/_runs.py +36 -0
- mosaic/core/pipeline/inventory/cache.py +202 -0
- mosaic/core/pipeline/inventory/contributors.py +79 -0
- mosaic/core/pipeline/inventory/label_series.py +97 -0
- mosaic/core/pipeline/inventory/media.py +363 -0
- mosaic/core/pipeline/inventory/model.py +473 -0
- mosaic/core/pipeline/inventory/params.py +427 -0
- mosaic/core/pipeline/inventory/scan.py +605 -0
- mosaic/core/pipeline/inventory/wire.py +671 -0
- mosaic/core/pipeline/iteration.py +64 -0
- mosaic/core/pipeline/job.py +391 -0
- mosaic/core/pipeline/joined_export.py +1160 -0
- mosaic/core/pipeline/label_series.py +188 -0
- mosaic/core/pipeline/label_series_index.py +679 -0
- mosaic/core/pipeline/labels_identity.py +164 -0
- mosaic/core/pipeline/labels_index.py +342 -0
- mosaic/core/pipeline/labels_migration.py +161 -0
- mosaic/core/pipeline/loading.py +453 -0
- mosaic/core/pipeline/manifest.py +1004 -0
- mosaic/core/pipeline/markers.py +628 -0
- mosaic/core/pipeline/media_index.py +391 -0
- mosaic/core/pipeline/media_input.py +143 -0
- mosaic/core/pipeline/models.py +77 -0
- mosaic/core/pipeline/op_identity.py +118 -0
- mosaic/core/pipeline/ops.py +746 -0
- mosaic/core/pipeline/parquet_reader.py +246 -0
- mosaic/core/pipeline/pipeline.py +942 -0
- mosaic/core/pipeline/placement.py +628 -0
- mosaic/core/pipeline/preprocess.py +1131 -0
- mosaic/core/pipeline/preprocess_index.py +260 -0
- mosaic/core/pipeline/preprocess_layout.py +120 -0
- mosaic/core/pipeline/preview.py +399 -0
- mosaic/core/pipeline/progress.py +245 -0
- mosaic/core/pipeline/promotion.py +366 -0
- mosaic/core/pipeline/provenance.py +408 -0
- mosaic/core/pipeline/reconcile.py +453 -0
- mosaic/core/pipeline/reconcile_features.py +640 -0
- mosaic/core/pipeline/reconcile_variants.py +423 -0
- mosaic/core/pipeline/refusal.py +142 -0
- mosaic/core/pipeline/resample_tracks.py +487 -0
- mosaic/core/pipeline/resolve.py +191 -0
- mosaic/core/pipeline/run.py +2069 -0
- mosaic/core/pipeline/run_log.py +34 -0
- mosaic/core/pipeline/scan_claim.py +85 -0
- mosaic/core/pipeline/sequence_index.py +494 -0
- mosaic/core/pipeline/store_export.py +638 -0
- mosaic/core/pipeline/stream_copy.py +201 -0
- mosaic/core/pipeline/subprocess_util.py +607 -0
- mosaic/core/pipeline/sweep.py +433 -0
- mosaic/core/pipeline/toolenv.py +613 -0
- mosaic/core/pipeline/track_universe.py +254 -0
- mosaic/core/pipeline/tracking_roots.py +703 -0
- mosaic/core/pipeline/tracks_axis.py +391 -0
- mosaic/core/pipeline/tracks_identity.py +449 -0
- mosaic/core/pipeline/tracks_index.py +1781 -0
- mosaic/core/pipeline/tracks_raw_index.py +351 -0
- mosaic/core/pipeline/transcode.py +720 -0
- mosaic/core/pipeline/types/__init__.py +107 -0
- mosaic/core/pipeline/types/artifacts.py +140 -0
- mosaic/core/pipeline/types/data_config.py +296 -0
- mosaic/core/pipeline/types/feature.py +219 -0
- mosaic/core/pipeline/types/inputs.py +137 -0
- mosaic/core/pipeline/types/labels.py +73 -0
- mosaic/core/pipeline/types/params.py +90 -0
- mosaic/core/pipeline/types/results.py +133 -0
- mosaic/core/pipeline/upgrade_tracks.py +224 -0
- mosaic/core/pipeline/variant_source.py +268 -0
- mosaic/core/pipeline/viz.py +446 -0
- mosaic/core/pipeline/writers.py +152 -0
- mosaic/core/pose_columns.py +366 -0
- mosaic/core/schema.py +411 -0
- mosaic/core/scope.py +339 -0
- mosaic/core/stored_paths.py +69 -0
- mosaic/core/strict_model.py +40 -0
- mosaic/core/track_converter.py +309 -0
- mosaic/core/track_library/__init__.py +44 -0
- mosaic/core/track_library/calms21.py +328 -0
- mosaic/core/track_library/deeplabcut.py +239 -0
- mosaic/core/track_library/helpers.py +59 -0
- mosaic/core/track_library/sleap.py +259 -0
- mosaic/core/track_library/track_converter_template.py +106 -0
- mosaic/core/track_library/trex.py +1011 -0
- mosaic/core/track_library/ultralytics_tracks.py +239 -0
- mosaic/core/typed_attribute.py +326 -0
- mosaic/lazy_exports.py +38 -0
- mosaic/media_probe_config.py +60 -0
- mosaic/optional_dependency.py +203 -0
- mosaic/runlog.py +1019 -0
- mosaic/tracking/__init__.py +118 -0
- mosaic/tracking/common/__init__.py +120 -0
- mosaic/tracking/common/bridge.py +397 -0
- mosaic/tracking/common/cooperative_cancel.py +101 -0
- mosaic/tracking/common/driver.py +267 -0
- mosaic/tracking/common/entry.py +246 -0
- mosaic/tracking/common/index.py +293 -0
- mosaic/tracking/common/mint.py +189 -0
- mosaic/tracking/common/params.py +148 -0
- mosaic/tracking/common/scope.py +503 -0
- mosaic/tracking/common/tool_input.py +887 -0
- mosaic/tracking/common/training_progress.py +173 -0
- mosaic/tracking/common/ultralytics_env.py +534 -0
- mosaic/tracking/external/__init__.py +21 -0
- mosaic/tracking/external/runner/__init__.py +8 -0
- mosaic/tracking/external/runner/ultralytics_protocol.py +1063 -0
- mosaic/tracking/external/runner/ultralytics_runner.py +1304 -0
- mosaic/tracking/frame_extraction/__init__.py +80 -0
- mosaic/tracking/frame_extraction/dataset_runs.py +1196 -0
- mosaic/tracking/frame_extraction/extraction.py +479 -0
- mosaic/tracking/frame_extraction/frame_runs.py +231 -0
- mosaic/tracking/frame_extraction/sampling.py +154 -0
- mosaic/tracking/inventory.py +68 -0
- mosaic/tracking/litpose/__init__.py +48 -0
- mosaic/tracking/litpose/dataset_runs.py +483 -0
- mosaic/tracking/litpose/labels.py +188 -0
- mosaic/tracking/litpose/params.py +77 -0
- mosaic/tracking/litpose/run.py +286 -0
- mosaic/tracking/litpose/templates/__init__.py +54 -0
- mosaic/tracking/litpose/templates/config_default.yaml +202 -0
- mosaic/tracking/litpose/training.py +383 -0
- mosaic/tracking/litpose/version.py +45 -0
- mosaic/tracking/model_refs.py +1132 -0
- mosaic/tracking/ops/__init__.py +7 -0
- mosaic/tracking/ops/_common.py +339 -0
- mosaic/tracking/ops/_train_descriptions.py +50 -0
- mosaic/tracking/ops/convert.py +314 -0
- mosaic/tracking/ops/delete_model.py +299 -0
- mosaic/tracking/ops/infer.py +1320 -0
- mosaic/tracking/ops/litpose.py +96 -0
- mosaic/tracking/ops/prepare.py +901 -0
- mosaic/tracking/ops/prepared_datasets.py +117 -0
- mosaic/tracking/ops/resample.py +335 -0
- mosaic/tracking/ops/sleap.py +102 -0
- mosaic/tracking/ops/train.py +1142 -0
- mosaic/tracking/ops/train_litpose.py +336 -0
- mosaic/tracking/ops/train_sleap.py +354 -0
- mosaic/tracking/ops/trained_models.py +232 -0
- mosaic/tracking/ops/trex.py +135 -0
- mosaic/tracking/ops/ultralytics.py +100 -0
- mosaic/tracking/pose_training/__init__.py +115 -0
- mosaic/tracking/pose_training/augmentation.py +316 -0
- mosaic/tracking/pose_training/converters/__init__.py +23 -0
- mosaic/tracking/pose_training/converters/base.py +107 -0
- mosaic/tracking/pose_training/converters/coco_keypoints.py +155 -0
- mosaic/tracking/pose_training/converters/coco_localizer.py +383 -0
- mosaic/tracking/pose_training/converters/coco_points.py +301 -0
- mosaic/tracking/pose_training/converters/cvat_localizer.py +286 -0
- mosaic/tracking/pose_training/converters/cvat_points.py +483 -0
- mosaic/tracking/pose_training/converters/emit.py +192 -0
- mosaic/tracking/pose_training/converters/lightning_pose.py +360 -0
- mosaic/tracking/pose_training/inference.py +489 -0
- mosaic/tracking/pose_training/localizer_inference.py +388 -0
- mosaic/tracking/pose_training/localizer_model.py +173 -0
- mosaic/tracking/pose_training/localizer_train.py +375 -0
- mosaic/tracking/pose_training/localizer_weights.py +273 -0
- mosaic/tracking/pose_training/prep.py +1086 -0
- mosaic/tracking/pose_training/repad.py +93 -0
- mosaic/tracking/pose_training/train.py +114 -0
- mosaic/tracking/pose_training/ultralytics_infer.py +254 -0
- mosaic/tracking/pose_training/ultralytics_train.py +308 -0
- mosaic/tracking/registration.py +56 -0
- mosaic/tracking/sleap/__init__.py +62 -0
- mosaic/tracking/sleap/dataset_runs.py +516 -0
- mosaic/tracking/sleap/labels.py +147 -0
- mosaic/tracking/sleap/params.py +210 -0
- mosaic/tracking/sleap/probe.py +257 -0
- mosaic/tracking/sleap/run.py +506 -0
- mosaic/tracking/sleap/training.py +443 -0
- mosaic/tracking/sleap/version.py +45 -0
- mosaic/tracking/training_provenance.py +378 -0
- mosaic/tracking/trex/__init__.py +74 -0
- mosaic/tracking/trex/conversion_cache.py +415 -0
- mosaic/tracking/trex/dataset_runs.py +1340 -0
- mosaic/tracking/trex/params.py +262 -0
- mosaic/tracking/trex/pv.py +148 -0
- mosaic/tracking/trex/run.py +704 -0
- mosaic/tracking/trex/settings.py +53 -0
- mosaic/tracking/trex/version.py +67 -0
- mosaic/tracking/ultralytics_track/__init__.py +75 -0
- mosaic/tracking/ultralytics_track/dataset_runs.py +660 -0
- mosaic/tracking/ultralytics_track/params.py +302 -0
- mosaic/tracking/ultralytics_track/run.py +407 -0
- mosaic/tracking/ultralytics_track/tracker_defaults.py +661 -0
- mosaic/tracking/ultralytics_track/version.py +34 -0
- mosaic/user_paths.py +70 -0
- mosaic/version.py +42 -0
- mosaic_behavior-0.17.0.dist-info/METADATA +219 -0
- mosaic_behavior-0.17.0.dist-info/RECORD +432 -0
- mosaic_behavior-0.17.0.dist-info/WHEEL +5 -0
- mosaic_behavior-0.17.0.dist-info/entry_points.txt +2 -0
- mosaic_behavior-0.17.0.dist-info/licenses/LICENSE +661 -0
- mosaic_behavior-0.17.0.dist-info/licenses/NOTICE +636 -0
- mosaic_behavior-0.17.0.dist-info/top_level.txt +1 -0
mosaic/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Mosaic, a behavior analysis toolkit."""
|
mosaic/__main__.py
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""``python -m mosaic``: the ``mosaic`` CLI, reached through the interpreter.
|
|
2
|
+
|
|
3
|
+
An agent or a script whose shell has no environment activated can run
|
|
4
|
+
``<python> -m mosaic`` where the ``mosaic`` script is not on ``$PATH``.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from mosaic.cli import app
|
|
10
|
+
|
|
11
|
+
if __name__ == "__main__":
|
|
12
|
+
app(prog_name="mosaic")
|
mosaic/agent/SKILL.md
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mosaic
|
|
3
|
+
description: >-
|
|
4
|
+
Use when code imports mosaic, when running the mosaic CLI, when editing a
|
|
5
|
+
dataset.yaml, or when working with tracks, features, pipelines, trackers or pose
|
|
6
|
+
models. Gives the workflow, where answers for the installed version live, and the
|
|
7
|
+
dataset rules.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Using mosaic in a project
|
|
11
|
+
|
|
12
|
+
You are working in the user's project, which uses mosaic (the `mosaic-behavior`
|
|
13
|
+
distribution, imported as `mosaic`) as a library and a CLI. This guide ships with the
|
|
14
|
+
installed mosaic and matches its version. The block after it names this installation's
|
|
15
|
+
`mosaic` executable, its Python interpreter and its documentation.
|
|
16
|
+
|
|
17
|
+
- **Do not modify mosaic's installed source**, including an editable install of a
|
|
18
|
+
clone. Extend mosaic from the user's project through its plugin seams: a feature, a
|
|
19
|
+
track converter, a label converter.
|
|
20
|
+
- **Report a defect upstream** at https://github.com/EcodylicScience/mosaic/issues with
|
|
21
|
+
the command, the full error and the `mosaic-behavior` version, which
|
|
22
|
+
`pip show mosaic-behavior` prints and `mosaic.version.installed_version()` returns. An empty
|
|
23
|
+
string there means mosaic is running from a source tree that is not installed, and
|
|
24
|
+
the report then needs that tree's commit. Work around it in the user's code
|
|
25
|
+
meanwhile.
|
|
26
|
+
|
|
27
|
+
## Mosaic in brief
|
|
28
|
+
|
|
29
|
+
Mosaic runs trackers (TRex, SLEAP, Lightning Pose, Ultralytics) or imports tracks other
|
|
30
|
+
tools made, standardizes every table to one schema, and computes **features** from it:
|
|
31
|
+
kinematic, social, collective-motion and spectral measures, embeddings and clusters,
|
|
32
|
+
supervised behavior classifiers, identity models and annotated videos. Before tracks
|
|
33
|
+
exist, it samples frames for annotation and trains pose models.
|
|
34
|
+
|
|
35
|
+
## The workflow end to end
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
mosaic init study --name "Experiment 1"
|
|
39
|
+
mosaic sources add -m study/dataset.yaml --kind media --path /data/day1 --extensions .mp4
|
|
40
|
+
mosaic scan -m study/dataset.yaml
|
|
41
|
+
mosaic track trex -m study/dataset.yaml --set track_max_individuals=4
|
|
42
|
+
mosaic run -m study/dataset.yaml --feature speed-angvel
|
|
43
|
+
mosaic inventory -m study/dataset.yaml
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
For tracks made elsewhere, skip `mosaic track`. Declare them as a `--kind tracks` source
|
|
47
|
+
with `--patterns` and `--src-format`, scan, then run `mosaic convert-tracks -m
|
|
48
|
+
study/dataset.yaml`. The same work from Python:
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
from mosaic.behavior.feature_library import SpeedAngvel
|
|
52
|
+
from mosaic.core.dataset import new_dataset_manifest, open_dataset
|
|
53
|
+
from mosaic.core.manifest import MediaScanSource, TracksScanSource
|
|
54
|
+
from mosaic.core.pipeline.inventory import inventory
|
|
55
|
+
from mosaic.tracking import run_trex
|
|
56
|
+
from mosaic.tracking.trex import TrexParams
|
|
57
|
+
|
|
58
|
+
ds = open_dataset(new_dataset_manifest("Experiment 1", "study"))
|
|
59
|
+
ds.add_scan_source(MediaScanSource(id="day1", path="/data/day1", extensions=(".mp4",)))
|
|
60
|
+
ds.scan_media()
|
|
61
|
+
run_trex(ds, TrexParams(track_max_individuals=4))
|
|
62
|
+
# For imported tracks, in place of run_trex:
|
|
63
|
+
# ds.add_scan_source(TracksScanSource(id="day1-tracks", path="/data/day1",
|
|
64
|
+
# patterns=("*.npz",), src_format="trex_npz"))
|
|
65
|
+
# ds.scan_tracks(); ds.convert_all_tracks()
|
|
66
|
+
result = ds.run_feature(SpeedAngvel())
|
|
67
|
+
inventory(ds)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Reopen a dataset with `open_dataset("study/dataset.yaml")`. The bare `Dataset(path)`
|
|
71
|
+
constructor reads nothing, and every accessor on it fails.
|
|
72
|
+
|
|
73
|
+
## Finding answers for this version
|
|
74
|
+
|
|
75
|
+
Prefer these sources, in this order, over memory and over the website. The website
|
|
76
|
+
follows mosaic's main branch, which may differ from this installation.
|
|
77
|
+
|
|
78
|
+
1. **The local docs**, when the block below names a directory. A pip install carries
|
|
79
|
+
no `docs/`, and the block then names the website instead. The directory, when it
|
|
80
|
+
exists, also says which file each site URL in this guide maps to.
|
|
81
|
+
2. **`mosaic --help`** and `mosaic <verb> --help`.
|
|
82
|
+
3. **The registries:** `mosaic features list`, `mosaic features describe <slug> --json`
|
|
83
|
+
(the parameter schema), `mosaic tracking list`, `mosaic tracking describe <kind>
|
|
84
|
+
--json`, and `mosaic pipeline catalog --json`, which also says why a feature is
|
|
85
|
+
unavailable here and what to install.
|
|
86
|
+
4. **The generated reference** (https://ecodylicscience.github.io/mosaic/reference/):
|
|
87
|
+
features with their class paths, ops, media steps, the CLI and the track formats.
|
|
88
|
+
5. **`help(obj)`** or the docstring in the source. No Python API reference is published.
|
|
89
|
+
|
|
90
|
+
When `mosaic` is not on `PATH`, run `<python> -m mosaic` with the interpreter below.
|
|
91
|
+
|
|
92
|
+
## Python entry points
|
|
93
|
+
|
|
94
|
+
- `mosaic.core.dataset`: `open_dataset`, `new_dataset_manifest`, and `Dataset`, whose
|
|
95
|
+
methods scan (`scan_media`, `scan_tracks`, `scan_labels`), convert
|
|
96
|
+
(`convert_all_tracks`, `convert_all_labels`), run (`run_feature`) and read
|
|
97
|
+
(`load_tracks`).
|
|
98
|
+
- `mosaic.core.manifest`: `MediaScanSource`, `TracksScanSource`, `LabelsScanSource`.
|
|
99
|
+
- `mosaic.core.scope`: `Scope`, which narrows a feature run or a pipeline.
|
|
100
|
+
- `mosaic.behavior.feature_library`: the feature classes, such as `SpeedAngvel`,
|
|
101
|
+
`HeadingFeature` and `ScaleToCm`. `Inputs` and `Result` from
|
|
102
|
+
`mosaic.core.pipeline.types` chain one feature onto another.
|
|
103
|
+
- `mosaic.tracking`: `run_trex`, `run_sleap`, `run_litpose`, `run_ultralytics` and
|
|
104
|
+
`extract_frames`. Each tracker's parameter model is in `mosaic.tracking.<tool>`.
|
|
105
|
+
- `mosaic.core.pipeline.inventory`: `inventory`. `mosaic.core.pipeline.graph`:
|
|
106
|
+
`load_recipe`, `plan_pipeline`, `run_pipeline`.
|
|
107
|
+
|
|
108
|
+
## Installation
|
|
109
|
+
|
|
110
|
+
Commands and environments are on https://ecodylicscience.github.io/mosaic/installation/.
|
|
111
|
+
|
|
112
|
+
- Mosaic installs from PyPI as `mosaic-behavior`, imported as `mosaic`. Never run
|
|
113
|
+
`pip install mosaic`, which is an unrelated project. `ffmpeg`, `av` and `py-opencv`
|
|
114
|
+
come from conda-forge before `pip install "mosaic-behavior[all]"`, which keeps one ffmpeg
|
|
115
|
+
build in the environment. On macOS use conda and do not add pip wheels of `av` or
|
|
116
|
+
OpenCV.
|
|
117
|
+
- An extra named in an older install command may be retired. pip only warns and
|
|
118
|
+
installs the base without it. Check the retired names on the installation page.
|
|
119
|
+
- Install the `feral` extra in a separate environment, since its exact pins downgrade
|
|
120
|
+
mosaic's dependencies.
|
|
121
|
+
- TRex, SLEAP, Lightning Pose, Ultralytics, POLO, keypoint-MoSeq and VAME each run in an
|
|
122
|
+
environment the user builds, and mosaic finds each through the variables the
|
|
123
|
+
installation page lists. The Ultralytics, POLO, keypoint-MoSeq and VAME environments
|
|
124
|
+
are built from files in the mosaic repository that a pip install does not carry, so
|
|
125
|
+
they need a clone. Do not install Ultralytics into mosaic's environment.
|
|
126
|
+
- Licenses differ. keypoint-MoSeq is for non-commercial research and academic use
|
|
127
|
+
only, and mosaic refuses to start it until the user sets the acceptance variable.
|
|
128
|
+
Setting it is the user's assertion. Ask, and do not set it yourself. TRex needs a
|
|
129
|
+
paid license for company use. Ultralytics is AGPL-3.0.
|
|
130
|
+
|
|
131
|
+
## Dataset files
|
|
132
|
+
|
|
133
|
+
A dataset is a directory with `dataset.yaml` and named roots
|
|
134
|
+
(https://ecodylicscience.github.io/mosaic/dataset/).
|
|
135
|
+
|
|
136
|
+
- The user's files go in `media_raw/`, `tracks_raw/` or `labels_raw/`, or stay where
|
|
137
|
+
they are as a declared source. Mosaic writes everything else.
|
|
138
|
+
- Do not write into `tracks/`, `labels/`, `features/`, `models/`, `media/` or
|
|
139
|
+
`_tracking/`. Produce outputs through `run_feature`, `mosaic run` and the ops, which
|
|
140
|
+
keep the indexes and run ids consistent.
|
|
141
|
+
- Do not hand-edit an `index.csv`, delete a `*.lock` file, or edit `.mosaic/`. Keep
|
|
142
|
+
`.mosaic/claims/`, the only record of which entries are known to fail.
|
|
143
|
+
- Change `dataset.yaml` with `mosaic sources`, `mosaic tags`, `mosaic notes` and
|
|
144
|
+
`mosaic libraries`, or the matching `Dataset` methods. A top-level key added by hand
|
|
145
|
+
survives. A newer `manifest_version` raises `ManifestVersionError`. Upgrade mosaic
|
|
146
|
+
then, and leave the version as it is.
|
|
147
|
+
- Derived and temporary folders cost only time to delete. Reclaim space with `mosaic
|
|
148
|
+
sweep-tracking`, `prune-media` and `prune-joined`. `mosaic reindex` drops index rows
|
|
149
|
+
whose files are gone. All four are dry runs until given `--apply`.
|
|
150
|
+
|
|
151
|
+
## Bringing data in
|
|
152
|
+
|
|
153
|
+
- An **entry** is a `(group, sequence)` pair. Neither name may contain `/`, `\` or NUL.
|
|
154
|
+
Join hierarchy levels with `__`, which `mosaic.core.helpers.parse_hierarchy` splits.
|
|
155
|
+
- `group` may be empty. It is a namespace, and it does not define analysis groups. To
|
|
156
|
+
run over an arbitrary set, pass `Scope(entries=[(group, sequence), ...])` or
|
|
157
|
+
`--entries group:sequence`. `groups` and `sequences` combine as a cross product.
|
|
158
|
+
- A scan replaces the rows its sources claim and keeps every other row. A files source
|
|
159
|
+
(`mosaic sources add --file ...`) claims only the paths it lists.
|
|
160
|
+
- A recording split into clips is one entry, with frames numbered across its clips.
|
|
161
|
+
Declare a continuous group only for parts of one recording kept as separate
|
|
162
|
+
sequences, following
|
|
163
|
+
https://ecodylicscience.github.io/mosaic/dataset/#declare-a-continuous-recording.
|
|
164
|
+
- Labels: https://ecodylicscience.github.io/mosaic/guides/analysis/import-labels/.
|
|
165
|
+
|
|
166
|
+
## Track tables
|
|
167
|
+
|
|
168
|
+
The rules are in https://ecodylicscience.github.io/mosaic/concepts/tracks/.
|
|
169
|
+
|
|
170
|
+
- Every spatial column is in **video pixels**, and `X`/`Y` are the **body center**, for
|
|
171
|
+
every tracker. For centimeters, record the scale with `ds.set_media_calibration(...)`
|
|
172
|
+
and run the `scale-to-cm` feature. Do not rescale a tracks table yourself.
|
|
173
|
+
- Velocity, speed and heading angle come from features. The `mosaic_v1` schema refuses
|
|
174
|
+
them in a tracks table. Run `speed-angvel`, or `heading` with its method chosen.
|
|
175
|
+
- Keypoints are optional. Features defined on keypoints refuse a table without them.
|
|
176
|
+
- `frame` counts media frames from 0 across an entry's clips (imgstore: `frame_index`).
|
|
177
|
+
- A format mosaic does not read needs a converter in the user's project:
|
|
178
|
+
https://ecodylicscience.github.io/mosaic/guides/tracking/write-a-converter/.
|
|
179
|
+
- Read raw `.h264` streams (Raspberry Pi) only through mosaic, which measures their
|
|
180
|
+
frame count. Other readers misjudge a bare stream.
|
|
181
|
+
- Run `mosaic upgrade-tracks` on TRex tables an older mosaic wrote in centimeters.
|
|
182
|
+
- TRex tables an older mosaic tracked are timed at TRex's whole-number frame rate, not
|
|
183
|
+
the media's measured one. Run `mosaic track trex` again with the same `--set`
|
|
184
|
+
values. It tracks from the cached conversion and publishes a retimed table under a
|
|
185
|
+
new variant.
|
|
186
|
+
|
|
187
|
+
## Running features
|
|
188
|
+
|
|
189
|
+
- A run is named `<version>-<10 hex>`, a hash of its parameters, inputs and frame range.
|
|
190
|
+
The same call again computes nothing. `--overwrite` (`overwrite=True`) recomputes. To
|
|
191
|
+
change a result, change its parameters. Editing output files breaks the cache.
|
|
192
|
+
- A tracks variant, op run or model is named `<kind>.<version>-<10 hex>`, such as
|
|
193
|
+
`convert-trex_npz.0.3-6bb5efbf05`. That string is what `tracks_run_id=`, `media=`,
|
|
194
|
+
`model=` and `data=` take.
|
|
195
|
+
- An entry with two tracks variants raises an error naming them. Pass `tracks_run_id=`
|
|
196
|
+
to `run_feature` (`--tracks-run-id` on `mosaic run`), or `run_id=` to `load_tracks`
|
|
197
|
+
and `drop_entries`. `""` names tables converted before mosaic recorded variants.
|
|
198
|
+
- A run that loses some entries finishes as `partial` and names them in
|
|
199
|
+
`result.failed_entries`. Check it before any global fit, since a fit over fewer
|
|
200
|
+
entries is a different result. Losing every entry raises.
|
|
201
|
+
- A global fit reads every numeric payload column of its input unless the `columns`
|
|
202
|
+
param of `extract-templates`, `extract-labeled-templates`, `arhmm` or
|
|
203
|
+
`temporal-stack` names the measurements to fit.
|
|
204
|
+
- Inputs combine at one entity level. Mosaic refuses to merge per-individual output
|
|
205
|
+
with per-pair output.
|
|
206
|
+
- A custom feature must be deterministic, with typed Pydantic parameters:
|
|
207
|
+
https://ecodylicscience.github.io/mosaic/guides/analysis/write-your-own-feature/.
|
|
208
|
+
|
|
209
|
+
## Trackers, pose models and annotations
|
|
210
|
+
|
|
211
|
+
Start at https://ecodylicscience.github.io/mosaic/guides/tracking/run-a-tracker/ and
|
|
212
|
+
https://ecodylicscience.github.io/mosaic/guides/tracking/train-a-pose-model/.
|
|
213
|
+
|
|
214
|
+
- Tracker settings are `--set key=value`, and `mosaic tracking describe <kind> --json`
|
|
215
|
+
lists them.
|
|
216
|
+
- TRex, SLEAP and Lightning Pose read one file. A multi-clip entry or an imgstore
|
|
217
|
+
needs `--kind export-joined` or `--kind export-store` first, and a run that needs one
|
|
218
|
+
stops and names the command. After an upgrade changes the join recipe, re-join and
|
|
219
|
+
then run `mosaic prune-joined --apply`.
|
|
220
|
+
- A media variant (a cropped, trimmed or re-encoded copy, from the `preprocess` op) is
|
|
221
|
+
tracked by passing its run id as `media` (`--set media=<run_id>`). Its tracks are
|
|
222
|
+
published in the source video's pixels and frames. Do not add crop offsets. A frame
|
|
223
|
+
window cannot be combined with `media`.
|
|
224
|
+
- Lightning Pose cannot decode AV1. Give it a variant made with `"codec": "h264"`.
|
|
225
|
+
- Frame extraction is `mosaic run --kind extract-frames`, or the function
|
|
226
|
+
`mosaic.tracking.extract_frames(ds, ...)`, which is not a `Dataset` method.
|
|
227
|
+
- Annotation revisions (`labels_raw/keypoints/<set>/rev<N>/`) are immutable. A changed
|
|
228
|
+
save becomes a new revision, and an edited revision is refused.
|
|
229
|
+
- Refer to a model by its run id. To use a model trained in another dataset, link that
|
|
230
|
+
dataset with `mosaic libraries add`. Do not pass a path into its `models/`.
|
|
231
|
+
`mosaic models provenance <run_id>` shows what a model was trained on.
|
|
232
|
+
- A hand-corrected track set becomes source data through `promote_correction`, as
|
|
233
|
+
https://ecodylicscience.github.io/mosaic/guides/tracking/import/ describes.
|
|
234
|
+
|
|
235
|
+
## Pipelines and inventory
|
|
236
|
+
|
|
237
|
+
- A recipe is a JSON file of steps
|
|
238
|
+
(https://ecodylicscience.github.io/mosaic/guides/pipelines/chain-steps/). Run
|
|
239
|
+
`mosaic pipeline validate`, then `plan`, then `run`. From Python,
|
|
240
|
+
`run_pipeline(ds, load_recipe("recipe.json"))`.
|
|
241
|
+
- Exit code 65 is a refusal, with a named reason (`"reason"` under `--json`). Python
|
|
242
|
+
raises `Refusal`, or `StepRefused` for a pipeline step. Fix the cause. Only
|
|
243
|
+
`coverage_shortfall` is answered with `--allow-partial` (`allow_partial=True`), and
|
|
244
|
+
only once the user accepts results over fewer entries. Details:
|
|
245
|
+
https://ecodylicscience.github.io/mosaic/concepts/pipelines/.
|
|
246
|
+
- `mosaic inventory` reports what exists, with coverage and a status such as
|
|
247
|
+
`partial` or `complete-but-drifted`. `mosaic runs` and `mosaic status` report
|
|
248
|
+
attempts.
|
|
249
|
+
|
|
250
|
+
## Mosaic's MCP tools
|
|
251
|
+
|
|
252
|
+
When your client offers mosaic's MCP tools (`mosaic agent serve`), use them for the
|
|
253
|
+
work they cover (https://ecodylicscience.github.io/mosaic/agents/).
|
|
254
|
+
|
|
255
|
+
- Validate a recipe with `validate_recipe`, then plan it with `plan_recipe`. Show the
|
|
256
|
+
user the plan, then pass its fingerprint to `submit_pipeline`.
|
|
257
|
+
- Set `confirm` only after the user agrees in the conversation to the conditions
|
|
258
|
+
that the refusal lists.
|
|
259
|
+
- The tools do not overwrite, delete, sweep, prune, reindex or change the manifest.
|
|
260
|
+
Propose the `mosaic` command and let the user run it.
|
|
261
|
+
|
|
262
|
+
## Pitfalls
|
|
263
|
+
|
|
264
|
+
- **`IndexLockUnsupported`**: the filesystem refuses file locks. Keep the dataset on a
|
|
265
|
+
disk that locks and declare the share as a source.
|
|
266
|
+
- **Several machines on one dataset**: a lock excludes other machines only when the
|
|
267
|
+
filesystem enforces it across them. A synced folder or an NFS volume mounted with
|
|
268
|
+
`nolock` does not. Write such a dataset from one machine at a time.
|
|
269
|
+
- **Mosaic is 0.x.** Interfaces, feature names and on-disk layouts may change. Record
|
|
270
|
+
the `mosaic-behavior` version with every result, read the changelog
|
|
271
|
+
(https://github.com/EcodylicScience/mosaic/blob/main/CHANGELOG.md) after an update,
|
|
272
|
+
and run `mosaic reconcile` if it says an identifier moved.
|
|
273
|
+
- **Two ffmpeg builds** in one environment crash a process at a different point each
|
|
274
|
+
run (`Trace/BPT trap: 5`). On macOS every import also warns that `AVFFrameReceiver`
|
|
275
|
+
is implemented twice, with or without a crash. Either symptom means the environment
|
|
276
|
+
needs rebuilding as the installation page says.
|
|
277
|
+
- **`scan_media` failures** usually mean `ffprobe` is not on `PATH`.
|
|
278
|
+
- **Ultralytics and POLO** need two separate environments, and the point ops refuse an
|
|
279
|
+
upstream Ultralytics build.
|
|
280
|
+
|
|
281
|
+
## Examples
|
|
282
|
+
|
|
283
|
+
The repository's `notebooks/` on GitHub are end-to-end examples that download their
|
|
284
|
+
data (https://ecodylicscience.github.io/mosaic/examples/). A pip install does not carry
|
|
285
|
+
them, so download one from the repository and run the copy in the user's project.
|