Rules
Upload rules for lab data management.
This module provides rules for processing data uploads to the database. Rules handle validation, preprocessing, and storage of different data types.
Default rules included:
- UploadRule: Base rule for generic file uploads
- EphysRule: Rule for electrophysiology data (SpikeGLX)
- TwoPhotonRule: Rule for two-photon microscopy data (ScanImage/Scanbox)
- OnePhotonRule: Rule for one-photon imaging data (Widefield - labcams)
- MiniscopeRule: Rule for (UCLA) Miniscope imaging data
- FixedBrainRule: Rule for fixed tissue microscopy data
- ReplaceRule: Rule for replacing existing files
Custom rules can be added to the user_preferences.json configuration.
UploadRule
Base class for data upload and compression rules.
An UploadRule is responsible for processing one UploadJob from the
database queue. The lifecycle of a job is:
- Claim the job from
UploadJob(setsjob_waiting=0). - Verify MD5 checksums of the assigned source files.
- Call
_apply_rule()to transform files (e.g. compress to zarr/cbin). - Upload processed files to S3 via
_upload(). - Call
_post_upload()to insert derived schema rows (e.g.EphysRecording).
Subclasses override _apply_rule() and _post_upload(). The default
_apply_rule() passes files through unchanged (no compression).
| Parameters: |
|
|---|
| Attributes: |
|
|---|
See Also
labdata.rules.ephys.EphysRule : Compresses SpikeGLX recordings. labdata.rules.imaging.TwoPhotonRule : Compresses two-photon sbx files. labdata.rules.imaging.MiniscopeRule : Compresses miniscope AVI stacks.
Source code in labdata/rules/utils.py
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 | |
apply()
Execute the full upload pipeline for this job.
Claims the job, verifies checksums, runs _apply_rule(), uploads
to S3, and calls _post_upload(). Updates UploadJob status at
each stage. If any step fails the job status is set to FAILED and
the exception is logged to UploadJob.job_log.
| Returns: |
|
|---|
Source code in labdata/rules/utils.py
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | |
set_job_status(job_status='FAILED', job_waiting=0, **kwargs)
Update the status of this job in UploadJob.
| Parameters: |
|
|---|
Source code in labdata/rules/utils.py
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | |
FixedBrainRule
Bases: UploadRule
Upload rule for fixed whole-brain lightsheet imaging datasets.
Compresses multi-channel OME-TIFF stacks (organized one folder per channel)
into a single zarr.zip archive using zstd compression, then inserts
a FixedBrain schema row with spatial metadata parsed from the OME header.
The rule expects that each channel lives in a separate subfolder and that
files have a .ome.tif, .tif, .TIFF, or .TIF extension.
Source code in labdata/rules/imaging.py
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | |
parse_metadata(data)
Reads metadata from a MultifolderTiffStack
Source code in labdata/rules/imaging.py
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | |
EphysRule
Bases: UploadRule
Upload rule for extracellular electrophysiology datasets (SpikeGLX).
Compresses .ap.bin and .lf.bin raw binary files using
mtscomp into .cbin / .ch pairs, then calls
EphysRecording.add_spikeglx_recording() and
EphysRecording.add_nidq_events() in the post-upload step to populate
the electrophysiology schema tables.
Multiple probes are compressed in parallel (joblib.Parallel).
Source code in labdata/rules/ephys.py
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | |
TwoPhotonRule
Bases: UploadRule
Upload rule for two-photon imaging datasets acquired with Scanbox.
Reads .sbx files, extracts acquisition metadata (frame rate, planes,
pixel size, PMT gains, objective), compresses to zarr.zip with zstd,
then inserts TwoPhoton and TwoPhoton.Plane rows in the post-upload
step.
Source code in labdata/rules/imaging.py
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 | |
process_sbx(sbxfile)
Open a Scanbox .sbx file, compress it to zarr.zip, and record metadata.
Reads acquisition parameters from the Scanbox metadata (frame rate,
planes, channels, pixel size, PMT gains, objective) and stores them in
self.recording_metadata and self.planes_metadata for later
insertion into TwoPhoton by _post_upload().
| Parameters: |
|
|---|
| Returns: |
|
|---|
Source code in labdata/rules/imaging.py
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 | |
OnePhotonRule
Bases: UploadRule
Upload rule for widefield (one-photon) imaging datasets.
Reads raw binary .dat files written by the widefield acquisition system,
compresses them into zarr.zip with zstd, and calls
insert_widefield_dataset() in the post-upload step to populate the
Widefield schema table.
The filename must follow the convention
<name>_<nchannels>_<height>_<width>_<dtype>.dat so that shape and
dtype can be inferred automatically via mmap_wfield_binary().
Source code in labdata/rules/imaging.py
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | |
MiniscopeRule
Bases: UploadRule
Upload rule for miniscope calcium imaging datasets.
Concatenates a series of .avi video files (natural sort order) into a
single zarr.zip stack using zstd compression, then calls
insert_miniscope_dataset() in the post-upload step to populate the
Miniscope schema table with frame rate, gain, LED power, and timestamp
data from the accompanying metaData.json and timeStamps.csv files.
Source code in labdata/rules/imaging.py
264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 | |
process_upload_jobs(key=None, rule='all', n_jobs=8, job_host=None, force=False, prefs=None)
Process pending UploadJob entries using the appropriate upload rules.
Fetches all waiting jobs (or jobs matching key), resolves the correct
UploadRule subclass from rulesmap based on job_rule, and runs
each job in parallel.
Custom rules can be registered in prefs['upload_rules'] as
{rule_name: "ClassName"} mappings.
| Parameters: |
|
|---|
| Returns: |
|
|---|
Source code in labdata/rules/__init__.py
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | |
Auxiliary Functions
Upload rules for lab data management.
This module provides rules for processing data uploads to the database. Rules handle validation, preprocessing, and storage of different data types.
Default rules included:
- UploadRule: Base rule for generic file uploads
- EphysRule: Rule for electrophysiology data (SpikeGLX)
- TwoPhotonRule: Rule for two-photon microscopy data (ScanImage/Scanbox)
- OnePhotonRule: Rule for one-photon imaging data (Widefield - labcams)
- MiniscopeRule: Rule for (UCLA) Miniscope imaging data
- FixedBrainRule: Rule for fixed tissue microscopy data
- ReplaceRule: Rule for replacing existing files
Custom rules can be added to the user_preferences.json configuration.
MultifolderTiffStack
Bases: object
Virtual stack that reads multi-channel TIFF data organized in per-channel folders.
Provides a numpy-like interface (shape, __len__, __getitem__,
dtype) so it can be passed directly to compress_imaging_stack().
Each channel lives in a separate subfolder. Files within each folder are sorted naturally and treated as sequential frames.
| Parameters: |
|
|---|
| Attributes: |
|
|---|
Source code in labdata/rules/imaging.py
620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 | |
__init__(channel_folders, extensions=['.ome.tif', '.tif', '.TIFF'])
Simple class to access tiff files that are organized in a folders Each folder is a channel and contains multiple TIFF files.
This is the format of the lightsheet microscope for example. It is a place-holder class that should be modified to work for scanimage files also.
Source code in labdata/rules/imaging.py
645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 | |
get(idx)
Return a single frame (all channels) as a stacked numpy array.
| Parameters: |
|
|---|
| Returns: |
|
|---|
Source code in labdata/rules/imaging.py
687 688 689 690 691 692 693 694 695 696 697 698 699 700 | |
compress_imaging_stack(stack, filename, chunksize=256, compression='blosc2', clevel=6, shuffle=1, filters=[], zarr_format=2, scratch_path=None, check_dataset=True)
Compress an imaging stack to a zarr.zip archive.
Writes the stack to a temporary zarr directory, then zips it into a single
zarr.zip file. After writing, the output is read back and compared
chunk-by-chunk against the input to verify integrity.
| Parameters: |
|
|---|
| Returns: |
|
|---|
| Raises: |
|
|---|
Source code in labdata/rules/imaging.py
403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 | |
compress_ephys_file(filename, local_path=None, ext='.bin', n_jobs=DEFAULT_N_JOBS, check_after_compress=True, prefs=None)
Compress a SpikeGLX binary file using mtscomp.
Reads the paired .meta file to determine sampling rate and channel
count, then compresses the .bin into a .cbin (compressed binary)
and .ch (JSON codec descriptor) pair.
| Parameters: |
|
|---|
| Returns: |
|
|---|
| Raises: |
|
|---|
Source code in labdata/rules/ephys.py
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | |
extract_events_from_nidq(paths)
Extract digital events from a SpikeGLX NIDQ (or OneBox) binary file.
Unpacks each bit of the sync channel into onset/offset timestamps and
returns them in the format expected by DatasetEvents.Digital. Supports
both raw .bin and compressed .cbin files. For OneBox recordings
(.obx. in the filename) the second-to-last channel is also unpacked.
| Parameters: |
|
|---|
| Returns: |
|
|---|
| Raises: |
|
|---|
Source code in labdata/rules/ephys.py
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 | |
ephys_noise_statistics_from_file(filepath, channel_indices, gain, sampling_rate=30000, duration=60)
Compute per-channel noise statistics from a raw ephys binary file.
Reads two non-overlapping chunks (head and tail) of length duration
seconds from the file and returns peak-to-peak, min, max, median, and
median absolute deviation (MAD) for each channel.
Supports both raw .bin (SpikeGLX) and compressed .cbin (mtscomp)
formats.
| Parameters: |
|
|---|
| Returns: |
|
|---|
| Raises: |
|
|---|
Source code in labdata/rules/ephys.py
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | |
get_probe_configuration(meta)
Parse probe configuration from a SpikeGLX metadata file or dict.
| Parameters: |
|
|---|
| Returns: |
|
|---|
| Raises: |
|
|---|
Source code in labdata/rules/ephys.py
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | |
insert_miniscope_dataset(schema, key, local_paths=None, skip_duplicates=False)
Insert a miniscope dataset into the schema after files are uploaded.
Downloads (if needed) the zarr.zip stack plus the metaData.json,
timeStamps.csv, and optional headOrientation.csv files, then
inserts rows into Miniscope, DatasetEvents, and
DatasetEvents.Digital.
| Parameters: |
|
|---|
Source code in labdata/rules/imaging.py
314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 | |
mmap_wfield_binary(filename, mode='r', nframes=None, shape=None, dtype='uint16')
Loads frames from a binary file as a memory map. This is useful when the data does not fit to memory.
Inputs:
filename (str) : fileformat convention, file ends in _NCHANNELS_H_W_DTYPE.dat
mode (str) : memory map access mode (default 'r')
'r' | Open existing file for reading only.
'r+' | Open existing file for reading and writing.
nframes (int) : number of frames to read (default is None: the entire file)
offset (int) : offset frame number (default 0)
shape (list|tuple) : dimensions (NCHANNELS, HEIGHT, WIDTH) default is None
dtype (str) : datatype (default uint16)
Returns:
A memory mapped array with size (NFRAMES,NCHANNELS, HEIGHT, WIDTH).
Example: dat = mmap_dat(filename)
This is from wfield - jcouto
Source code in labdata/rules/imaging.py
573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 | |
read_ome_tif(file)
Read the first page of an OME-TIFF file as a numpy array.
| Parameters: |
|
|---|
| Returns: |
|
|---|
| Raises: |
|
|---|
Source code in labdata/rules/imaging.py
703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 | |
insert_widefield_dataset(schema, key, local_paths=None, skip_duplicates=False)
Insert a widefield imaging dataset into the schema after files are uploaded.
Reads the compressed zarr.zip stack and the accompanying labcams
.camlog file to extract frame rate, LED stimulus timing, and software
version, then inserts rows into Widefield, DatasetEvents, and
DatasetEvents.Digital.
| Parameters: |
|
|---|
Source code in labdata/rules/imaging.py
730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 | |