├── code ├── autoROI │ ├── .gitignore │ └── +autoROI │ │ ├── +batchtest │ │ └── readme.txt │ │ ├── removeCornerEdgeArtifacts.m │ │ ├── +evaluate │ │ ├── private │ │ │ └── plotSettings.m │ │ ├── getSummaryTable.m │ │ ├── printFileNamesAsDoubleColumnTable.m │ │ ├── areTestStructuresEqual.m │ │ └── report_auto_thresh_notes.m │ │ ├── overlayBoundingBoxes.m │ │ ├── +test │ │ ├── private │ │ │ └── handle_runDir.m │ │ ├── getAllFirstImages.m │ │ └── printNonPStack.m │ │ ├── overlayBoundingBox.m │ │ ├── +groundTruth │ │ ├── genBordersForAllInDir.m │ │ ├── stackToGroundTruth.m │ │ └── replaceRecipe.m │ │ ├── +autothresh │ │ ├── batchDir.m │ │ └── plot.m │ │ ├── +tools │ │ ├── reportRecipeName.m │ │ ├── fixMicsPix.m │ │ └── resizeAllInDir.m │ │ ├── genOverlapStack.m │ │ ├── +plotting │ │ └── bt_auto_compare.m │ │ ├── validateBoundingBox.m │ │ ├── rescaleAndFilterImage.m │ │ ├── obtainCleanBackgroundSD.m │ │ └── getSubImageUsingBoundingBox.m ├── +BakingTray │ ├── +settings │ │ ├── private │ │ │ ├── Do_Not_Edit │ │ │ ├── readme.txt │ │ │ └── defaultRecipe.m │ │ ├── devNotes.txt │ │ ├── installLocation.m │ │ ├── readDefaultRecipe.m │ │ ├── parseComPort.m │ │ └── settingsLocation.m │ ├── +yaml │ │ ├── Tests │ │ │ ├── Data │ │ │ │ ├── test_misc │ │ │ │ │ ├── spec_chars_utf8.yaml │ │ │ │ │ ├── miscellaneous.yaml │ │ │ │ │ ├── dos_CRLF.yaml │ │ │ │ │ ├── unix_LF.yaml │ │ │ │ │ └── bug6.yaml │ │ │ │ ├── test_import │ │ │ │ │ ├── file1.yaml │ │ │ │ │ ├── file3.yaml │ │ │ │ │ ├── file2.yaml │ │ │ │ │ ├── file4.yaml │ │ │ │ │ ├── import_def.yaml │ │ │ │ │ ├── import.mat │ │ │ │ │ ├── import_def.mat │ │ │ │ │ ├── import_nonex.yaml │ │ │ │ │ └── import.yaml │ │ │ │ ├── test_primitives │ │ │ │ │ ├── simple.yaml │ │ │ │ │ ├── whitespaces.yaml │ │ │ │ │ ├── time.yaml │ │ │ │ │ ├── time.mat │ │ │ │ │ ├── simple.mat │ │ │ │ │ ├── matrices.mat │ │ │ │ │ ├── indentation.mat │ │ │ │ │ ├── floating_points.mat │ │ │ │ │ ├── time_variants.mat │ │ │ │ │ ├── sequence_mapping.mat │ │ │ │ │ ├── usecase_struct_01.mat │ │ │ │ │ ├── floating_points.yaml │ │ │ │ │ ├── indentation.yaml │ │ │ │ │ ├── matrices.yaml │ │ │ │ │ ├── sequence_mapping.yaml │ │ │ │ │ └── time_variants.yaml │ │ │ │ └── test_inheritance │ │ │ │ │ ├── inheritance.mat │ │ │ │ │ ├── inheritance_loop.yaml │ │ │ │ │ ├── inheritance_multiple.mat │ │ │ │ │ ├── inheritance_multiple.yaml │ │ │ │ │ └── inheritance.yaml │ │ │ └── test_WriteYaml.m │ │ ├── kwd_parent.m │ │ ├── issingle.m │ │ ├── isord.m │ │ ├── external │ │ │ └── snakeyaml-1.9.jar │ │ ├── ismymatrix.m │ │ ├── isrowvector.m │ │ ├── iscolumnvector.m │ │ ├── extras │ │ │ ├── TimeVals2Cell.m │ │ │ └── GetYamlVals.m │ │ ├── merge_struct.m │ │ ├── README.md │ │ ├── MIT-license.txt │ │ ├── datadump.m │ │ ├── dosubstitution.m │ │ ├── ReadYaml.m │ │ └── deflateimports.m │ ├── +slack │ │ ├── private │ │ │ ├── README_JSONLAB.txt │ │ │ ├── http_createHeader.m │ │ │ ├── mergestruct.m │ │ │ ├── jsonopt.m │ │ │ └── varargin2struct.m │ │ └── notify.m │ ├── +gui │ │ ├── @prepare_view │ │ │ ├── icons │ │ │ │ ├── left_double_arrow.tiff │ │ │ │ └── left_single_arrow.tiff │ │ │ ├── positionNextToBakingTrayView.m │ │ │ ├── takeOneSlice.m │ │ │ ├── stopAllAxes.m │ │ │ ├── isSafeToMove.m │ │ │ ├── resetBladeIfNeeded.m │ │ │ ├── private │ │ │ │ └── hMover_KeyPress.m │ │ │ ├── toggleEnable.m │ │ │ ├── takeNslices.m │ │ │ └── autoTrim.m │ │ ├── @view │ │ │ ├── startChannelChooserGUI.m │ │ │ ├── startLaserGUI.m │ │ │ ├── displayMessage.m │ │ │ ├── startPrepareGUI.m │ │ │ ├── importFrameSizeSettings.m │ │ │ ├── updateRecipePropertyInRecipeClass.m │ │ │ ├── enableDisableThisView.m │ │ │ └── newSample.m │ │ ├── @acquisition_view │ │ │ ├── pause_callback.m │ │ │ ├── zoomOutToShowSlide.m │ │ │ ├── setDepthToView.m │ │ │ ├── overlayLastBoundingBoxes.m │ │ │ ├── setChannelToView.m │ │ │ ├── getThresholdAndOverlayGrid.m │ │ │ ├── overlayPointsOnImage.m │ │ │ ├── overlayStagePositionOnImage.m │ │ │ └── removeOverlays.m │ │ ├── newGenericGUIPanel.m │ │ ├── child_view.m │ │ └── newGenericGUIFigureWindow.m │ ├── +channelChooser │ │ ├── settings.yml │ │ ├── four_channels_settings.yml │ │ ├── loadEmissionSpectrum.m │ │ ├── readSettings.m │ │ └── loadExcitationSpectrum.m │ ├── @channelChooser │ │ ├── plotChanBand.m │ │ ├── plotEmissionSpectrum.m │ │ ├── plotExcitationSpectrum.m │ │ ├── excitation_spectra_2p │ │ │ └── README.txt │ │ └── determineChansToSave.m │ ├── +utils │ │ ├── centerFigureInScreen.m │ │ ├── clearSerial.m │ │ ├── listLaserCalib.m │ │ ├── wavelength2rgb.m │ │ ├── fitSigmoidToData.m │ │ ├── readSectionLogFile.m │ │ ├── returnDiskSpace.m │ │ └── readAcqLogFile.m │ ├── getObject.m │ └── +acq │ │ └── estimateFinishedTime.m ├── components │ ├── scanning │ │ ├── @SIBT │ │ │ ├── moveFastZTo.m │ │ │ ├── private │ │ │ │ ├── default_SIBT_settings.m │ │ │ │ └── default_frameSizes.yml │ │ │ └── applyLaserCalibration.m │ │ ├── +SIBT │ │ │ ├── closeAllHistogramWindows.m │ │ │ ├── get_hSI_from_base.m │ │ │ └── get_hSICtl_from_base.m │ │ ├── @dummyScanner │ │ │ ├── returnDefaultScanSettings.m │ │ │ └── createFigureWindow.m │ │ └── devNotes.txt │ ├── motion │ │ ├── dummy_linearstage.m │ │ ├── genericStage.m │ │ ├── genericPIstage.m │ │ ├── genericPriorstage.m │ │ ├── haydon43K4U.m │ │ ├── BSC201_Troubleshooting.txt │ │ ├── AVS_100_25.m │ │ ├── generic_AeroTechZJack.m │ │ └── DRV014.m │ ├── @recipe │ │ ├── setCurrentPositionAsFrontLeft.m │ │ ├── setCurrentPositionAsCuttingPosition.m │ │ ├── autoSetCutSize.m │ │ ├── recipe2struct.m │ │ ├── estimatedSizeOnDisk.m │ │ ├── setFrontLeftFromVentralMidLine.m │ │ ├── checkIfAcquisitionIsPossible.m │ │ └── devNotes.txt │ └── cutting │ │ └── dummyCutter.m ├── @BT │ ├── abortSlicing.m │ ├── tilesRemaining.m │ ├── reportAcquisitionSize.m │ ├── displayMessage.m │ ├── slack.m │ ├── checkAttachedStages.m │ ├── renewLaserConnection.m │ ├── applyLaserCalibrationToScanner.m │ ├── logPositionToPositionArray.m │ ├── preAllocateTileBuffer.m │ ├── attachScanner.m │ ├── attachCutter.m │ ├── defineSavePath.m │ ├── attachLaser.m │ ├── getThreshold.m │ └── convertStagePositionToImageCoords.m └── BTresources │ └── prettyTime.m ├── .gitignore ├── diagnostic ├── measuring_xy_accuracy │ ├── +mxy │ │ ├── @camera │ │ │ └── .gitignore │ │ ├── plotResults.m │ │ ├── focusNamedFig.m │ │ └── testBlockingMotion.m │ ├── analyseIm.m │ └── readme.txt ├── readme.txt ├── stage_motion_times │ ├── tilePositions.mat │ └── softwareTimedMotionTime.m ├── measureTilingAccuracy.m └── lookForDuplicateTilesInCache.m ├── SETTINGS ├── laser_calibration │ └── .gitignore └── .gitignore ├── SETTINGS_BACKUP └── .gitignore ├── addBTtopath.m ├── ExampleConfigFiles ├── SIBT_settings.yml ├── ScanImage │ └── README.txt ├── systemSettings.yml └── frameSizes.yml ├── tests ├── recipes │ ├── systemSettings.yml │ ├── workingRecipe.yml │ └── recipe_experiment_170408.yml └── readme.txt ├── ExampleCodeSnippets ├── readme.txt ├── AcquisitionAutoResume │ ├── abortOnFrame.m │ └── readme.md └── example_connect_Soloist.m └── Release_Announcements └── Release_21st_September_2021.txt /code/autoROI/.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | -------------------------------------------------------------------------------- /code/+BakingTray/+settings/private/Do_Not_Edit: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.stackdump 2 | *.asv 3 | *.DS_Store 4 | -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_misc/spec_chars_utf8.yaml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /diagnostic/measuring_xy_accuracy/+mxy/@camera/.gitignore: -------------------------------------------------------------------------------- 1 | *.asv 2 | -------------------------------------------------------------------------------- /SETTINGS/laser_calibration/.gitignore: -------------------------------------------------------------------------------- 1 | *.csv 2 | *.yml 3 | *.mat 4 | 5 | -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_import/file1.yaml: -------------------------------------------------------------------------------- 1 | f1a: 47 2 | f1b: 78 -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_import/file3.yaml: -------------------------------------------------------------------------------- 1 | f3a: 999 2 | f3b: 142 -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_import/file2.yaml: -------------------------------------------------------------------------------- 1 | f2a: 99 2 | f2b: 111 3 | -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_import/file4.yaml: -------------------------------------------------------------------------------- 1 | f4a: 123 2 | f4b: 456 3 | -------------------------------------------------------------------------------- /SETTINGS_BACKUP/.gitignore: -------------------------------------------------------------------------------- 1 | /componentSettings.m 2 | *~ 3 | *.csv 4 | *.yml 5 | /startup_bt.m 6 | -------------------------------------------------------------------------------- /SETTINGS/.gitignore: -------------------------------------------------------------------------------- 1 | /componentSettings.m 2 | *~ 3 | *.csv 4 | *.yml 5 | /startup_bt.m 6 | *.yml.BAK 7 | -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_primitives/simple.yaml: -------------------------------------------------------------------------------- 1 | - {name: John Smith, age: 33} 2 | - name: Mary Smith 3 | age: 27 -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_primitives/whitespaces.yaml: -------------------------------------------------------------------------------- 1 | YAML: 1.0 2 | Image file: 00032009.jpg 3 | Contours count: 8 -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/kwd_parent.m: -------------------------------------------------------------------------------- 1 | function result = kwd_parent() 2 | import BakingTray.yaml.*; 3 | result = 'parent'; 4 | end 5 | -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_primitives/time.yaml: -------------------------------------------------------------------------------- 1 | Data: 2 | B1_S_SW: 3 | [!!timestamp '2011-03-29T18:09:20.0000000+02:00', 23.80] -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/issingle.m: -------------------------------------------------------------------------------- 1 | function result = issingle(obj) 2 | import BakingTray.yaml.*; 3 | result = all(size(obj) == 1) ; 4 | end 5 | -------------------------------------------------------------------------------- /addBTtopath.m: -------------------------------------------------------------------------------- 1 | function addBTtopath 2 | %add BakingTray dirs to path (useful for testing) 3 | addpath(genpath(fullfile(pwd,'code'))); 4 | end 5 | -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/isord.m: -------------------------------------------------------------------------------- 1 | function result = isord(obj) 2 | import BakingTray.yaml.*; 3 | result = ~iscell(obj) && any(size(obj) > 1); 4 | end 5 | -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_import/import_def.yaml: -------------------------------------------------------------------------------- 1 | import: 2 | - file1.yaml 3 | - file2.yaml 4 | - file3.yaml 5 | - file4.yaml -------------------------------------------------------------------------------- /diagnostic/readme.txt: -------------------------------------------------------------------------------- 1 | The functions in this directory are for testing BakingTray or running diagnostics. 2 | They don't need to be added to the MATLAB path. -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/external/snakeyaml-1.9.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SWC-Advanced-Microscopy/BakingTray/HEAD/code/+BakingTray/+yaml/external/snakeyaml-1.9.jar -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/ismymatrix.m: -------------------------------------------------------------------------------- 1 | function result = ismymatrix(obj) 2 | import BakingTray.yaml.*; 3 | result = ndims(obj) == 2 && all(size(obj) > 1); 4 | end 5 | -------------------------------------------------------------------------------- /diagnostic/stage_motion_times/tilePositions.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SWC-Advanced-Microscopy/BakingTray/HEAD/diagnostic/stage_motion_times/tilePositions.mat -------------------------------------------------------------------------------- /code/+BakingTray/+slack/private/README_JSONLAB.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SWC-Advanced-Microscopy/BakingTray/HEAD/code/+BakingTray/+slack/private/README_JSONLAB.txt -------------------------------------------------------------------------------- /code/autoROI/+autoROI/+batchtest/readme.txt: -------------------------------------------------------------------------------- 1 | Functions in this directory are for testing the autoROI on a library of past data. 2 | They are not used during an acquisition. -------------------------------------------------------------------------------- /ExampleConfigFiles/SIBT_settings.yml: -------------------------------------------------------------------------------- 1 | tileAcq: {tileRotate: -1.0, tileFlipUD: true, tileFlipLR: false} 2 | hardware: {doResetTrippedPMT: false, fixedStageMotionTimeConstant: 0.0} 3 | -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_import/import.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SWC-Advanced-Microscopy/BakingTray/HEAD/code/+BakingTray/+yaml/Tests/Data/test_import/import.mat -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_primitives/time.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SWC-Advanced-Microscopy/BakingTray/HEAD/code/+BakingTray/+yaml/Tests/Data/test_primitives/time.mat -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_import/import_def.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SWC-Advanced-Microscopy/BakingTray/HEAD/code/+BakingTray/+yaml/Tests/Data/test_import/import_def.mat -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_misc/miscellaneous.yaml: -------------------------------------------------------------------------------- 1 | null: ~ 2 | true: y 3 | false: n 4 | string: '12345' 5 | foo: [] # see http://code.google.com/p/yamlmatlab/issues/detail?id=5 6 | -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_primitives/simple.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SWC-Advanced-Microscopy/BakingTray/HEAD/code/+BakingTray/+yaml/Tests/Data/test_primitives/simple.mat -------------------------------------------------------------------------------- /code/+BakingTray/+gui/@prepare_view/icons/left_double_arrow.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SWC-Advanced-Microscopy/BakingTray/HEAD/code/+BakingTray/+gui/@prepare_view/icons/left_double_arrow.tiff -------------------------------------------------------------------------------- /code/+BakingTray/+gui/@prepare_view/icons/left_single_arrow.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SWC-Advanced-Microscopy/BakingTray/HEAD/code/+BakingTray/+gui/@prepare_view/icons/left_single_arrow.tiff -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_primitives/matrices.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SWC-Advanced-Microscopy/BakingTray/HEAD/code/+BakingTray/+yaml/Tests/Data/test_primitives/matrices.mat -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_inheritance/inheritance.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SWC-Advanced-Microscopy/BakingTray/HEAD/code/+BakingTray/+yaml/Tests/Data/test_inheritance/inheritance.mat -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_primitives/indentation.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SWC-Advanced-Microscopy/BakingTray/HEAD/code/+BakingTray/+yaml/Tests/Data/test_primitives/indentation.mat -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/isrowvector.m: -------------------------------------------------------------------------------- 1 | function result = isrowvector(obj) 2 | import BakingTray.yaml.*; 3 | result = isvector(obj) && size(obj,1) == 1 && size(obj,2) > 1 && ndims(obj) == 2; 4 | end 5 | -------------------------------------------------------------------------------- /tests/recipes/systemSettings.yml: -------------------------------------------------------------------------------- 1 | SYSTEM: {ID: Knodelator, xySpeed: 100.0, objectiveZSettlingDelay: 0.05} 2 | SLICER: {approachSpeed: 25.0, vibrateRate: 60.0, postCutDelay: 6.0, postCutVibrate: 3.0} 3 | -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_inheritance/inheritance_loop.yaml: -------------------------------------------------------------------------------- 1 | # loop in inheritance 2 | students: 3 | s1: { name: jan, parent: students.s2} 4 | s2: { name: pepa, parent: students.s1} 5 | -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_primitives/floating_points.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SWC-Advanced-Microscopy/BakingTray/HEAD/code/+BakingTray/+yaml/Tests/Data/test_primitives/floating_points.mat -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_primitives/time_variants.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SWC-Advanced-Microscopy/BakingTray/HEAD/code/+BakingTray/+yaml/Tests/Data/test_primitives/time_variants.mat -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/iscolumnvector.m: -------------------------------------------------------------------------------- 1 | function result = iscolumnvector(obj) 2 | import BakingTray.yaml.*; 3 | result = isvector(obj) && size(obj,2) == 1 && size(obj,1) > 1 && ndims(obj) == 2; 4 | end 5 | -------------------------------------------------------------------------------- /ExampleCodeSnippets/readme.txt: -------------------------------------------------------------------------------- 1 | This directory if for standalone example functions used for demoing simple things or to aid debugging during setup. 2 | You will not need this code to run BakingTray. 3 | 4 | 5 | -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_primitives/sequence_mapping.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SWC-Advanced-Microscopy/BakingTray/HEAD/code/+BakingTray/+yaml/Tests/Data/test_primitives/sequence_mapping.mat -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_primitives/usecase_struct_01.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SWC-Advanced-Microscopy/BakingTray/HEAD/code/+BakingTray/+yaml/Tests/Data/test_primitives/usecase_struct_01.mat -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_inheritance/inheritance_multiple.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SWC-Advanced-Microscopy/BakingTray/HEAD/code/+BakingTray/+yaml/Tests/Data/test_inheritance/inheritance_multiple.mat -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_misc/dos_CRLF.yaml: -------------------------------------------------------------------------------- 1 | american: 2 | - Boston Red Sox 3 | - Detroit Tigers 4 | - New York Yankees 5 | national: 6 | - New York Mets 7 | - Chicago Cubs 8 | - Atlanta Braves 9 | -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_misc/unix_LF.yaml: -------------------------------------------------------------------------------- 1 | american: 2 | - Boston Red Sox 3 | - Detroit Tigers 4 | - New York Yankees 5 | national: 6 | - New York Mets 7 | - Chicago Cubs 8 | - Atlanta Braves 9 | -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_primitives/floating_points.yaml: -------------------------------------------------------------------------------- 1 | canonical: 1.23015e+3 2 | exponential: 12.3015e+02 3 | sexagecimal: 20:30.15 4 | fixed: 1230.15 5 | negative_infinity: -.inf 6 | not_a_number: .NaN 7 | -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_import/import_nonex.yaml: -------------------------------------------------------------------------------- 1 | import: 2 | - time_variants.yaml 3 | - inheritance.yaml 4 | - non-exists.yaml 5 | import: [matrices.yaml, sequence_mapping.yaml, non-ex.yaml] 6 | 7 | 8 | -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_primitives/indentation.yaml: -------------------------------------------------------------------------------- 1 | name: Mark McGwire 2 | accomplishment: > 3 | Mark set a major league 4 | home run record in 1998. 5 | stats: | 6 | 65 Home Runs 7 | 0.278 Batting Average 8 | -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_inheritance/inheritance_multiple.yaml: -------------------------------------------------------------------------------- 1 | a: 2 | v1: 10 3 | parent: [b,c] 4 | 5 | b: 6 | w1: 111 7 | parent: d 8 | 9 | c: 10 | w2: 798 11 | parent: d 12 | 13 | d: 14 | x: 113 15 | -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_primitives/matrices.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | Matrix1: [[1, 5],[1 , 3]] 3 | Matrix2: 4 | - [2 , 3] 5 | - [4 , 5] 6 | ColVect: 7 | - [1] 8 | - [2] 9 | RowVect: [1, 2] 10 | ... 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_misc/bug6.yaml: -------------------------------------------------------------------------------- 1 | # http://code.google.com/p/yamlmatlab/issues/detail?id=6 2 | # read-in this file in windows like environment 3 | test: 4 | - [16.0, 2.0, 3.0, 13.0] 5 | - [5.0, 11.0, 10.0, 8.0] 6 | - [9.0, 7.0, 6.0, 12.0] 7 | - [4.0, 14.0, 15.0, 1.0] 8 | 9 | -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_import/import.yaml: -------------------------------------------------------------------------------- 1 | - import: 2 | - ../test_primitives/time.yaml 3 | - ../test_inheritance/inheritance.yaml 4 | #- ..\test_primitives\time_variants.yaml 5 | - import: [../test_primitives/matrices.yaml, ../test_primitives/sequence_mapping.yaml] 6 | 7 | 8 | -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_primitives/sequence_mapping.yaml: -------------------------------------------------------------------------------- 1 | sequence: 2 | - 3 | name: Mark McGwire 4 | hr: 65 5 | avg: 0.278 6 | - 7 | name: Sammy Sosa 8 | hr: [63, 43] 9 | avg: 10 | - 0.288 11 | - 12 12 | -------------------------------------------------------------------------------- /code/+BakingTray/+gui/@view/startChannelChooserGUI.m: -------------------------------------------------------------------------------- 1 | function startChannelChooserGUI(obj,~,~) 2 | 3 | if isempty(obj.view_channelChooser) || ~isvalid(obj.view_channelChooser) 4 | obj.view_channelChooser=BakingTray.channelChooser(obj.model,obj); 5 | else 6 | figure(obj.view_channelChooser.hFig) 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /code/components/scanning/@SIBT/moveFastZTo.m: -------------------------------------------------------------------------------- 1 | function moveFastZTo(obj,targetPositionInMicrons) 2 | % Move the fast Z to an absolute position 3 | % 4 | % SIBT.moveFasZTo(targetPositionInMicrons) 5 | % 6 | % No feedback is provided. 7 | 8 | 9 | obj.hC.hFastZ.positionTarget = targetPositionInMicrons; 10 | -------------------------------------------------------------------------------- /code/autoROI/+autoROI/removeCornerEdgeArtifacts.m: -------------------------------------------------------------------------------- 1 | function im = removeCornerEdgeArtifacts(im) 2 | 3 | %The corner with the non-laid down tile can create artifacts 4 | %that mess up the auto-finder. We remove those here. 5 | 6 | 7 | m=medfilt2(im,[3,3]); 8 | BW = (im - m) > 500; 9 | mPix = median(im(:)); 10 | im(BW) = m(BW); 11 | 12 | -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_primitives/time_variants.yaml: -------------------------------------------------------------------------------- 1 | canonical: !!timestamp 2001-12-15T02:59:43.0Z 2 | iso8601: !!timestamp 2001-12-14t21:59:43.00-05:00 3 | spaced: !!timestamp 2001-12-14 21:59:43.00 -5 4 | date: !!timestamp 2002-12-14 5 | matrix: 6 | - [!!timestamp '2001-12-15T02:59:43.0Z', 1] 7 | - [!!timestamp '2001-12-15T03:59:43.0Z', 2] 8 | 9 | -------------------------------------------------------------------------------- /tests/recipes/workingRecipe.yml: -------------------------------------------------------------------------------- 1 | sample: {ID: sample, objectiveName: nikon 16x} 2 | mosaic: 3 | sectionStartNum: 1.0 4 | numSections: 1.0 5 | cuttingSpeed: 0.35 6 | cutSize: 22.0 7 | sliceThickness: 0.1 8 | numOpticalPlanes: 2.0 9 | overlapProportion: 0.07 10 | cuttingStartPoint: [] 11 | frontLeft: [] 12 | sampleSize: [0.0, 0.0] 13 | scanmode: tile 14 | -------------------------------------------------------------------------------- /code/+BakingTray/+slack/private/http_createHeader.m: -------------------------------------------------------------------------------- 1 | function header = http_createHeader(name,value) 2 | %http_createHeader Simple function for creating input header to urlread2 3 | % 4 | % header = http_createHeader(name,value) 5 | % 6 | % CODE: header = struct('name',name,'value',value); 7 | % 8 | % See Also: 9 | % urlread2 10 | 11 | header = struct('name',name,'value',value); -------------------------------------------------------------------------------- /code/components/motion/dummy_linearstage.m: -------------------------------------------------------------------------------- 1 | classdef dummy_linearstage < linearstage 2 | %% 3 | % dummy stage class 4 | 5 | properties (Hidden) 6 | speed 7 | end 8 | 9 | methods 10 | 11 | %Constructor 12 | function obj = dummy_linearstage 13 | obj.currentPosition=0; 14 | end %Constructor 15 | 16 | end %methods 17 | 18 | 19 | 20 | end -------------------------------------------------------------------------------- /ExampleConfigFiles/ScanImage/README.txt: -------------------------------------------------------------------------------- 1 | How to use the simulated ScanImage machine data file. 2 | 3 | 1) In NI MAX create the following simulated devices: 4 | PXIe-6115 (rename it "scan") 5 | PXIe-6341 (rename it "aux1") 6 | PCIe-6343 (rename it "pmt") 7 | 8 | 2) Copy "Machine_Data_File_LinScan_SIMULATED.m" into your ScanImage install directory 9 | 10 | 3) Start ScanImage and open the above MDF 11 | 12 | -------------------------------------------------------------------------------- /code/+BakingTray/+settings/private/readme.txt: -------------------------------------------------------------------------------- 1 | These files are used by BakingTray for inital set up and to 2 | set safe default values in case the copies in the SETTINGS 3 | folder have invalid values. Do not edit these files unless 4 | you *really* know what you're doing. 5 | 6 | 7 | These files are read by other functions. e.g. the componentSettings.m 8 | file is read by BakingTray.settings.readComponentSettings -------------------------------------------------------------------------------- /ExampleCodeSnippets/AcquisitionAutoResume/abortOnFrame.m: -------------------------------------------------------------------------------- 1 | function abortOnFrame(src,evt) 2 | persistent hSI 3 | 4 | frameToAbort = 300; 5 | 6 | if ~most.idioms.isValidObj(hSI) 7 | hSI = dabs.resources.ResourceStore.filterByNameStatic('ScanImage'); 8 | end 9 | 10 | if hSI.hStackManager.framesDone >= frameToAbort 11 | hSI.hScan2D.hAcq.errorOutAcquisition(); 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /code/+BakingTray/+channelChooser/settings.yml: -------------------------------------------------------------------------------- 1 | channelA: 2 | centre: 676 3 | width: 29 4 | name: 'Far Red' 5 | hardwareChanIndex: 1 6 | channelB: 7 | centre: 605 8 | width: 70 9 | name: 'Red' 10 | hardwareChanIndex: 2 11 | channelC: 12 | centre: 525 13 | width: 39 14 | name: 'Green' 15 | hardwareChanIndex: 3 16 | channelD: 17 | centre: 460 18 | width: 60 19 | name: 'Blue' 20 | hardwareChanIndex: 4 -------------------------------------------------------------------------------- /code/+BakingTray/+channelChooser/four_channels_settings.yml: -------------------------------------------------------------------------------- 1 | channelA: 2 | centre: 676 3 | width: 29 4 | name: 'Far Red' 5 | hardwareChanIndex: 1 6 | channelB: 7 | centre: 605 8 | width: 70 9 | name: 'Red' 10 | hardwareChanIndex: 2 11 | channelC: 12 | centre: 525 13 | width: 39 14 | name: 'Green' 15 | hardwareChanIndex: 3 16 | channelD: 17 | centre: 460 18 | width: 60 19 | name: 'Blue' 20 | hardwareChanIndex: 4 -------------------------------------------------------------------------------- /code/+BakingTray/@channelChooser/plotChanBand.m: -------------------------------------------------------------------------------- 1 | function a = plotChanBand(obj,chan) 2 | 3 | % Plot channel band in main figure. 4 | minL = chan.centre - (chan.width/2); 5 | maxL = chan.centre + (chan.width/2); 6 | 7 | 8 | r = BakingTray.utils.wavelength2rgb(chan.centre); 9 | 10 | a=area(obj.hAxesMain,[minL,minL,maxL,maxL],[0,1.1,1.1,0]); 11 | a.FaceColor=r.light; 12 | a.EdgeColor=r.dark; 13 | end 14 | 15 | -------------------------------------------------------------------------------- /code/components/motion/genericStage.m: -------------------------------------------------------------------------------- 1 | classdef genericStage < linearstage 2 | %% 3 | % genericStage stage class 4 | % 5 | % 6 | % All abstract methods should have doc text only in the abstract method class file. 7 | 8 | properties 9 | 10 | end 11 | 12 | methods 13 | 14 | %Constructor 15 | function obj = genericStage(obj) 16 | 17 | end %Constructor 18 | 19 | end %methods 20 | 21 | 22 | end 23 | -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/extras/TimeVals2Cell.m: -------------------------------------------------------------------------------- 1 | function s = TimeVals2Cell(time,datavalues,header) 2 | % creates a typical struct with field named by header. Values are cell of 3 | % date and vals. 4 | % synopsis: 5 | % s = TimeVals2Cell(time,datavalues,header) 6 | if ~iscell(header) 7 | header = {header}; 8 | end 9 | 10 | for i=1:numel(header) 11 | s.(header{i}) = [num2cell(DateTime(time)) num2cell(datavalues(:,i))]; 12 | end 13 | end -------------------------------------------------------------------------------- /code/autoROI/+autoROI/+evaluate/private/plotSettings.m: -------------------------------------------------------------------------------- 1 | function pltSettings = plotSettings 2 | % Defines common style elements so all plotting functions 3 | % share the same look. 4 | 5 | 6 | pltSettings.basePlotStyle = {'.-','color',[0.5,0.8,0.5],'markersize',9}; 7 | pltSettings.highlightProblemCases = {'or','markersize',7,'MarkerFaceColor',[0.5,0.8,0.5]}; 8 | pltSettings.highlightHighCoverage = {'og','markersize',7,'MarkerFaceColor',[0.5,0.8,0.5]}; -------------------------------------------------------------------------------- /code/components/motion/genericPIstage.m: -------------------------------------------------------------------------------- 1 | classdef genericPIstage < linearstage 2 | %% 3 | % Generic PI stage class 4 | % 5 | % 6 | % All abstract methods should have doc text only in the abstract method class file. 7 | 8 | properties 9 | 10 | end 11 | 12 | methods 13 | 14 | %Constructor 15 | function obj = genericPIstage(obj) 16 | obj.axisID = '1'; %This is the default for PI controllers with one axis only 17 | end %Constructor 18 | 19 | 20 | end %methods 21 | 22 | 23 | end 24 | -------------------------------------------------------------------------------- /code/+BakingTray/+gui/@prepare_view/positionNextToBakingTrayView.m: -------------------------------------------------------------------------------- 1 | function positionNextToBakingTrayView(obj) 2 | % Position the prepare window next to the main BakingTray window when it opens 3 | % 4 | % function BT.positionNextToBakingTrayView(obj) 5 | 6 | if isempty(obj.parentView) 7 | %Then the GUI wasn't started by pressing the button on the main BT view 8 | return 9 | end 10 | 11 | iptwindowalign(obj.parentView.hFig, 'right', obj.hFig, 'left'); 12 | 13 | end %positionNextToBakingTrayView 14 | -------------------------------------------------------------------------------- /code/components/@recipe/setCurrentPositionAsFrontLeft.m: -------------------------------------------------------------------------------- 1 | function setCurrentPositionAsFrontLeft(obj) 2 | % recipe.setCurrentPositionAsFrontLeft 3 | % 4 | % Store the current position as the front/left of the tile grid 5 | 6 | if isempty(obj.parent) 7 | fprintf('ERROR: recipe class has nothing bound to property "parent". Can not access BT\n') 8 | return 9 | end 10 | hBT=obj.parent; 11 | [x,y]=hBT.getXYpos; 12 | obj.FrontLeft.X = x; 13 | obj.FrontLeft.Y = y; 14 | end % setCurrentPositionAsFrontLeft 15 | -------------------------------------------------------------------------------- /code/components/motion/genericPriorstage.m: -------------------------------------------------------------------------------- 1 | classdef genericPriorstage < linearstage 2 | %% 3 | % Generic Prior stage class 4 | % 5 | % 6 | % All abstract methods should have doc text only in the abstract method class file. 7 | 8 | properties 9 | 10 | end 11 | 12 | methods 13 | 14 | %Constructor 15 | function obj = genericPriorstage(obj) 16 | obj.controllerUnitsInMM = 1E-4; % We multiply by this number to ensure units are in mm 17 | end %Constructor 18 | 19 | 20 | end %methods 21 | 22 | 23 | end 24 | -------------------------------------------------------------------------------- /code/components/motion/haydon43K4U.m: -------------------------------------------------------------------------------- 1 | classdef haydon43K4U < linearstage 2 | %% 3 | % haydon43K4U (all models) stage class 4 | % 5 | % All abstract methods should have doc text only in the abstract method class file. 6 | 7 | properties 8 | 9 | end 10 | 11 | methods 12 | 13 | %Constructor 14 | function obj = haydon43K4U(obj) 15 | obj.positionUnits='mm'; 16 | obj.axisID = ''; % We have just one axis on the controller and run in "single mode" 17 | end %Constructor 18 | 19 | 20 | 21 | 22 | end %methods 23 | 24 | 25 | end -------------------------------------------------------------------------------- /code/+BakingTray/+utils/centerFigureInScreen.m: -------------------------------------------------------------------------------- 1 | function centerFigureInScreen(figHandle) 2 | % BakingTray.utils.centerFigureInScreen(figHandle) 3 | % 4 | % Purpose 5 | % Centres window figHandle in the middle of the screen 6 | % 7 | % 8 | 9 | 10 | 11 | % Screen size of the primary display 12 | monitorSize = get(0,'ScreenSize'); 13 | 14 | 15 | figSize = get(figHandle,'Position'); 16 | 17 | 18 | % Set the corner loction 19 | figHandle.Position(1) = (monitorSize(3)/2) - (figSize(3)/2); 20 | figHandle.Position(2) = (monitorSize(4)/2) - (figSize(4)/2); -------------------------------------------------------------------------------- /code/+BakingTray/+gui/@view/startLaserGUI.m: -------------------------------------------------------------------------------- 1 | function startLaserGUI(obj,~,~) 2 | % Start the laser GUI 3 | 4 | %Present error dialog if no laser is connected (button should be disabled anyway) 5 | if ~obj.model.isLaserConnected 6 | warndlg('No laser connected to BakingTray','') 7 | return 8 | end 9 | 10 | %Only start GUI if one doesn't already exist 11 | if isempty(obj.view_laser) || ~isvalid(obj.view_laser) 12 | obj.view_laser=BakingTray.gui.laser_view(obj.model); 13 | else 14 | figure(obj.view_laser.hFig) % Raise and bring to focus laser GUI 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /code/autoROI/+autoROI/+evaluate/getSummaryTable.m: -------------------------------------------------------------------------------- 1 | function summaryTable = getSummaryTable(testDir) 2 | % Local helper function for getting the summary table. 3 | % Avoids boilerplate. 4 | 5 | 6 | summaryTable = []; 7 | 8 | if nargin<1 || isempty(testDir) 9 | testDir=pwd; 10 | end 11 | 12 | if ~exist(testDir,'dir') 13 | fprintf('The test directory %s does not exist.\n',testDir); 14 | return 15 | end 16 | 17 | fname = fullfile(testDir,'summary_table.mat'); 18 | 19 | if ~exist(fname,'file') 20 | fprintf('No summary_table.mat file found.\n'); 21 | 22 | return 23 | else 24 | load(fname) 25 | end 26 | 27 | -------------------------------------------------------------------------------- /code/+BakingTray/+channelChooser/loadEmissionSpectrum.m: -------------------------------------------------------------------------------- 1 | function tSpectrum = loadEmissionSpectrum(dye) 2 | % Load emission spectrum data from file and return 3 | % valid dyes are in "emission_spectra" directory 4 | % 5 | % 6 | 7 | % Get the path to the emission spectra 8 | tPath = fileparts(which('BakingTray.channelChooser')); 9 | tPath = fullfile(tPath,'emission_spectra',[lower(dye),'.txt']); 10 | 11 | 12 | if ~exist(tPath,'file') 13 | fprintf('%s finds no file at %s\n', mfilename, tPath) 14 | tSpectrum = []; 15 | return 16 | end 17 | 18 | 19 | tSpectrum = dlmread(tPath); 20 | -------------------------------------------------------------------------------- /code/@BT/abortSlicing.m: -------------------------------------------------------------------------------- 1 | function abortSlicing(obj) 2 | % Abort slicing of a section initiated by BT.sliceSample 3 | % 4 | % function BT.abortSlicing 5 | % 6 | % Purpose 7 | % Instantly aborts the cutting sequence: stops the motion of all three 8 | % axes and re-sets the stage speeds to their default values. 9 | % 10 | 11 | obj.abortSlice=true; %BT.sliceSample will look here to decide what to do when the stages stop 12 | 13 | try 14 | obj.stopZ; 15 | catch 16 | %pass 17 | end 18 | 19 | try 20 | obj.stopXY; 21 | catch 22 | %pass 23 | end 24 | 25 | 26 | end 27 | -------------------------------------------------------------------------------- /ExampleConfigFiles/systemSettings.yml: -------------------------------------------------------------------------------- 1 | SYSTEM: 2 | ID: slicerscope 3 | xySpeed: 35.0 4 | cutterSide: 1.0 5 | defaultFrontLeft: [12.5, 10.0] 6 | homeZjackOnZeroMove: 1.0 7 | dominantTilingDirection: y 8 | defaultSavePath: D:\ 9 | autoROIchannelOrder: [red, green, blue] 10 | bladeXposAtSlideEnd: 59.0 11 | slideFrontLeft: [24.0, 16.2] 12 | raisedZposition: 13.0 13 | raisedXposition: 20.5 14 | SLACK: {user: '@slicer', hook: 'https://hooks.slack.com/services/H7SFDSBG1/KLSSST595W/VXFgcYfdzW1Q3CPghHxRGpr6'} 15 | SLICER: {approachSpeed: 25.0, vibrateRate: 3200, postCutDelay: 6.0, postCutVibrate: 3.0, 16 | defaultYcutPos: 2.0} 17 | -------------------------------------------------------------------------------- /diagnostic/measuring_xy_accuracy/analyseIm.m: -------------------------------------------------------------------------------- 1 | function IN=analyseIm(IN) 2 | 3 | imStack = IN.imStack; 4 | 5 | 6 | imr = imresize(imStack,1); %does nothing 7 | fprintf('Processing stack with %d frames\n',size(imStack,3)) 8 | c = zeros(1,size(imStack,3)); 9 | for ii=1:size(imStack,3) 10 | if mod(ii,10)==0 11 | fprintf('Doing frame %d\n', ii) 12 | end 13 | 14 | 15 | r = regionprops(imr(:,:,ii)>75); 16 | [~,ind]=sort([r.Area],'descend'); 17 | r = r(ind(1)); 18 | c(ii) = r.Centroid(1); 19 | end 20 | 21 | IN.centroid = c; 22 | mxy.plotResults(IN) 23 | 24 | end 25 | 26 | -------------------------------------------------------------------------------- /code/components/scanning/+SIBT/closeAllHistogramWindows.m: -------------------------------------------------------------------------------- 1 | function closeAllHistogramWindows 2 | % Close all ScanImage histogram windows 3 | % 4 | % SIBT.closeAllHistogramWindows 5 | % 6 | % Purpose 7 | % Closes all ScanImage histogram windows that are open. 8 | % 9 | % Rob Campbell - SWC 2024 10 | 11 | 12 | hSICtl = SIBT.get_hSICtl_from_base; 13 | 14 | if isempty(hSICtl) 15 | return 16 | end 17 | 18 | 19 | auxWindowNames = {hSICtl.hAuxGUIs.Name}; 20 | 21 | histWindows = strmatch('Pixel Histogram', auxWindowNames); 22 | 23 | if ~isempty(histWindows) 24 | close(hSICtl.hAuxGUIs(histWindows)) 25 | end 26 | -------------------------------------------------------------------------------- /code/+BakingTray/@channelChooser/plotEmissionSpectrum.m: -------------------------------------------------------------------------------- 1 | function h = plotEmissionSpectrum(obj,dye) 2 | % Plot emission spectrum and return handle to plot object 3 | 4 | 5 | 6 | data = BakingTray.channelChooser.loadEmissionSpectrum(dye); 7 | 8 | 9 | h = plot(data(:,1),data(:,2),'-', ... 10 | 'Parent',obj.hAxesMain, ... 11 | 'LineWidth',2); 12 | 13 | [~,ind] = max(data(:,2)); 14 | 15 | 16 | peakL = data(ind,1); 17 | r = BakingTray.utils.wavelength2rgb(peakL); 18 | 19 | h.Color = r.regular; 20 | 21 | 22 | %text(peakL,peakL],[0.9,0.9], ... 23 | % sprintf('%s (%d nm)', dye,peakL), ... 24 | % 'Parent',obj.hAxesMain) 25 | -------------------------------------------------------------------------------- /code/+BakingTray/+channelChooser/readSettings.m: -------------------------------------------------------------------------------- 1 | function out = readSettings 2 | 3 | % TODO -- we might in future integrate into the system settings but for now let's 4 | % just do like this. 5 | 6 | 7 | % Get path to settings file 8 | t=which(['BakingTray.channelChooser.',mfilename]); 9 | 10 | setPath = fullfile(fileparts(t),'settings.yml'); 11 | 12 | if ~exist(setPath,'file') 13 | fprintf('CAN NOT FIND SETTINGS FILE AT %s \n', setPath) 14 | return 15 | end 16 | 17 | rawSettings=BakingTray.yaml.ReadYaml(setPath); 18 | 19 | 20 | f=fields(rawSettings); 21 | for ii=1:length(f) 22 | out(ii)=rawSettings.(f{ii}); 23 | end 24 | -------------------------------------------------------------------------------- /code/@BT/tilesRemaining.m: -------------------------------------------------------------------------------- 1 | function n=tilesRemaining(obj) 2 | % Return the number of tiles remaining in this section 3 | % 4 | % n=BT.tilesRemaining 5 | % 6 | % KNOWN BUG: 7 | % This will be innaccurate for the first tile. 8 | % Since the stage could move to the first position, the position is 9 | % logged, then the acquisition crashes, we report one completed tile. 10 | % Not important so we proceed. 11 | 12 | n=[]; 13 | if isempty(obj.positionArray) 14 | obj.logMessage(inputname(1),dbstack,6,'no position array. No acquisition running.') 15 | return 16 | end 17 | 18 | n = isnan(obj.positionArray(:,end)); 19 | n = sum(n); 20 | -------------------------------------------------------------------------------- /code/+BakingTray/+gui/@view/displayMessage.m: -------------------------------------------------------------------------------- 1 | function displayMessage(obj,~,~) 2 | % Callback that displays to a warning dialog box the contents of BT.messageString 3 | % 4 | % Purpose 5 | % General-purpose message display for BakingTray GUI. Displays 6 | % BT.messageString whenever that string is changed and is not empty. 7 | % This system does not have to be used for all messages. fprintf 8 | % directly from methods of BT is also fine. However, this method 9 | % provides greater flexibility. 10 | % 11 | % See also main BT class properties. 12 | 13 | if isempty(obj.model.messageString) 14 | return 15 | end 16 | 17 | warndlg(obj.model.messageString,'') 18 | -------------------------------------------------------------------------------- /code/+BakingTray/+gui/@prepare_view/takeOneSlice.m: -------------------------------------------------------------------------------- 1 | function takeOneSlice(obj,~,~) 2 | %Take a single slice off the block 3 | % 4 | % function BT.takeOneSlice(obj,~,~) 5 | % 6 | % 7 | 8 | if obj.model.allStagesReferenced == false 9 | obj.parentView.referenceStages; 10 | return 11 | end 12 | 13 | [cuttingPossible,msg]=obj.model.checkIfCuttingIsPossible; 14 | if ~cuttingPossible 15 | warndlg(msg,'') 16 | return 17 | end 18 | 19 | obj.resetBladeIfNeeded 20 | 21 | obj.model.sliceSample(obj.lastSliceThickness, obj.lastCuttingSpeed); 22 | 23 | % So the Z stage can not be moved by accident 24 | obj.lockZ 25 | end % takeOneSlice 26 | -------------------------------------------------------------------------------- /diagnostic/measuring_xy_accuracy/+mxy/plotResults.m: -------------------------------------------------------------------------------- 1 | function plotResults(IN) 2 | 3 | % Plot 4 | clf 5 | 6 | 7 | % Based on the step size we can figure out microns per pixel 8 | rangeInMicrons = range(cumsum(IN.seq)) * 1E3; 9 | c = IN.centroid; 10 | c = c - min(c); 11 | pixelsPerMicron = range(c) / rangeInMicrons; 12 | 13 | y = IN.centroid; 14 | y = y-mean(y(1:50)); %Subtract offset 15 | y = y / pixelsPerMicron; 16 | 17 | % x scale in seconds based on mean FPS of sequence 18 | x = 1:length(y); 19 | x = x/IN.fps; 20 | 21 | 22 | 23 | plot(x,y,'-b.') 24 | grid on 25 | 26 | 27 | xlabel('Time - seconds') 28 | ylim([min(y)-range(y)*0.01,max(y)+range(y)*0.01]) 29 | ylabel('Distance - microns') 30 | 31 | -------------------------------------------------------------------------------- /code/+BakingTray/@channelChooser/plotExcitationSpectrum.m: -------------------------------------------------------------------------------- 1 | function h = plotExcitationSpectrum(obj,dye) 2 | % Plot emission spectrum and return handle to plot object 3 | 4 | 5 | 6 | data = BakingTray.channelChooser.loadExcitationSpectrum(dye); 7 | 8 | if isempty(data) 9 | h = []; 10 | return 11 | end 12 | 13 | h = plot(data(:,1),data(:,3),'-', ... 14 | 'Parent',obj.hAxesExcite, ... 15 | 'LineWidth',2); 16 | 17 | [~,ind] = max(data(:,2)); 18 | 19 | 20 | peakL = data(ind,1); 21 | r = BakingTray.utils.wavelength2rgb(peakL); 22 | 23 | h.Color = r.regular; 24 | 25 | 26 | %text(peakL,peakL],[0.9,0.9], ... 27 | % sprintf('%s (%d nm)', dye,peakL), ... 28 | % 'Parent',obj.hAxesExcite) 29 | -------------------------------------------------------------------------------- /code/components/@recipe/setCurrentPositionAsCuttingPosition.m: -------------------------------------------------------------------------------- 1 | function setCurrentPositionAsCuttingPosition(obj) 2 | % recipe.setCurrentPositionAsCuttingPosition 3 | % 4 | % Store the current stage position as the position at which we will start cutting 5 | 6 | if isempty(obj.parent) 7 | fprintf('ERROR: recipe class has nothing bound to property "parent". Can not access BT\n') 8 | return 9 | end 10 | hBT=obj.parent; 11 | [x,y]=hBT.getXYpos; 12 | obj.CuttingStartPoint.X = x; 13 | 14 | % The y position is not set by the user but comes from a settings file. 15 | % This is set in the recipe at load time in the constructor 16 | 17 | % Automatically set the cut size 18 | obj.autoSetCutSize 19 | end % setCurrentPositionAsCuttingPosition 20 | -------------------------------------------------------------------------------- /diagnostic/measuring_xy_accuracy/readme.txt: -------------------------------------------------------------------------------- 1 | This folder contains code useful for assessing stage motion accuracy. Specifically, this is code written for measuring the performance of Zaber X-LRM100A stages. These stages are well priced but borderline in terms of speed. To assess how well they perform and how fast we can move the test bench has a camera that images a white dot painted on a piece of tape attached to the stage carriage. The CMOS camera can be set up to run at about 200 FPS whilst the dot is moved beneath it. This allows us to measure how long it takes to move and settle. We can then try things like running open loop or tweaking the PID loop. 2 | 3 | In this case we are using a Basler camera. The code for connecting to the stage and camera are therefore specific to the hardware we have locally. -------------------------------------------------------------------------------- /code/@BT/reportAcquisitionSize.m: -------------------------------------------------------------------------------- 1 | function varargout = reportAcquisitionSize(obj) 2 | % Report to screen the expected size of the acquisition along with disk space. 3 | % Optionally return the information as a string. 4 | % 5 | 6 | 7 | acqInGB = obj.recipe.estimatedSizeOnDisk; 8 | 9 | fprintf('Acquisition will take up %0.2g GB of disk space\n', acqInGB) 10 | 11 | volumeToWrite = strsplit(obj.sampleSavePath,filesep); 12 | volumeToWrite = volumeToWrite{1}; 13 | 14 | out = BakingTray.utils.returnDiskSpace(volumeToWrite); 15 | 16 | msg = sprintf('Writing to volume %s which has %d/%d GB free\n', ... 17 | volumeToWrite, round(out.freeGB), round(out.totalGB)); 18 | 19 | fprintf(msg) 20 | 21 | 22 | if nargout>0 23 | varargout{1} = msg; 24 | end 25 | -------------------------------------------------------------------------------- /diagnostic/measuring_xy_accuracy/+mxy/focusNamedFig.m: -------------------------------------------------------------------------------- 1 | function varargout=focusNamedFig(figTagName) 2 | % mxy.focusNamedFig(figTagName) 3 | % 4 | % Purpose 5 | % Brings to focus the figure with the tag name 'figTagName' 6 | % Creates the figure if it does not exist 7 | % 8 | % 9 | 10 | if nargin<1 || isempty(figTagName) 11 | fprintf('%s expects one input argument\n',mfilename) 12 | return 13 | end 14 | 15 | if ~ischar(figTagName) 16 | fprintf('%s expects figTagName to be a character array\n',mfilename) 17 | return 18 | end 19 | 20 | f=findobj('tag',figTagName); 21 | 22 | if isempty(f) 23 | hFig=figure; 24 | hFig.Tag=figTagName; 25 | else 26 | hFig=f; 27 | end 28 | 29 | figure(hFig) %bring to focus 30 | if nargout>0 31 | varargout{1}=hFig; 32 | end 33 | 34 | end -------------------------------------------------------------------------------- /diagnostic/measureTilingAccuracy.m: -------------------------------------------------------------------------------- 1 | function OUT=measureTilingAccuracy(hBT,pos,nTimes) 2 | % 3 | % Run through tile pattern, pos, nTimes and save 4 | % data to disk indicating where the stage went to 5 | % and where it should have gone 6 | 7 | if nargin<3 8 | nTimes=1; 9 | end 10 | nPos = length(pos); 11 | OUT = ones(length(pos)*nTimes,4); 12 | 13 | n=1; 14 | for NN = 1:nTimes 15 | 16 | if nTimes>1 17 | fprintf('Doing rep %d/%d\n',NN,nTimes) 18 | end 19 | 20 | hBT.moveXYto(pos(1,1),pos(1,2), true); 21 | pause(0.2) 22 | 23 | for ii=1:nPos 24 | hBT.moveXYto(pos(ii,1),pos(ii,2), true); 25 | [xP,yP]=hBT.getXYpos; 26 | OUT(n,1)=pos(ii,1); 27 | OUT(n,2)=pos(ii,2); 28 | OUT(n,3)=xP; 29 | OUT(n,4)=yP; 30 | n=n+1; 31 | end 32 | pause(0.2) 33 | end 34 | 35 | -------------------------------------------------------------------------------- /code/@BT/displayMessage.m: -------------------------------------------------------------------------------- 1 | function displayMessage(obj,~,~) 2 | % Callback that displays to the CLI the contents of BT.messageString 3 | % 4 | % Purpose 5 | % General-purpose message display for BakingTray. Displays 6 | % BT.messageString whenever that string is changed and is not empty. 7 | % This system does not have to be used for all messages. fprintf 8 | % directly from methods of BT is also fine. However, this method 9 | % provides greater flexibility and also allows messages to be broadcast 10 | % the view class and displayed as a warning dialog. That class too 11 | % monitors BT.messageString... 12 | 13 | if isempty(obj.messageString) 14 | return 15 | end 16 | 17 | 18 | fprintf(obj.messageString) 19 | 20 | if ~endsWith(obj.messageString,'\n') 21 | fprintf('\n') 22 | end 23 | -------------------------------------------------------------------------------- /ExampleCodeSnippets/example_connect_Soloist.m: -------------------------------------------------------------------------------- 1 | function SOLO = example_connect_Soloist 2 | % Example function showing how to connect to an AeroTech SoloistMP 3 | % 4 | % function SOLO = example_connect_Soloist 5 | % 6 | % Instructions 7 | % Edit the controller ID to match yours then: 8 | % SOLO = example_connect_Soloist; 9 | % SOLO.absoluteMove(10) 10 | % SOLO.axisPosition 11 | % etc: methods(SOLO) 12 | % You should have control over the device now 13 | % 14 | % delete(SOLO) %Closes the connection 15 | % 16 | % See also: buildMotionComponent, linearcontroller 17 | 18 | STAGE = generic_AeroTechZJack; 19 | STAGE.axisName='someName'; 20 | STAGE.maxPos = 35; % You may need to edit this 21 | SOLO = soloist(STAGE); 22 | 23 | controllerID.interface='ethernet'; 24 | controllerID.ID= '618277-1-1'; % <--- EDIT THIS WITH YOUR UNIT'S ID 25 | 26 | SOLO.connect(controllerID) 27 | -------------------------------------------------------------------------------- /code/+BakingTray/+settings/private/defaultRecipe.m: -------------------------------------------------------------------------------- 1 | function dRecipe=defaultRecipe 2 | % Return a default recipe which is used to populate the settings file if no recipe is in there 3 | % 4 | 5 | % The default recipe has reasonable values as the 6 | % defaults. 7 | 8 | 9 | dRecipe.sample.ID=''; 10 | dRecipe.sample.objectiveName='nikon 16x'; 11 | 12 | dRecipe.mosaic.sectionStartNum=1; 13 | dRecipe.mosaic.numSections=1; 14 | dRecipe.mosaic.cuttingSpeed=0.5; 15 | dRecipe.mosaic.cutSize=20; 16 | dRecipe.mosaic.sliceThickness=0.1; 17 | dRecipe.mosaic.numOpticalPlanes=2; 18 | dRecipe.mosaic.numOverlapZPlanes=0; 19 | dRecipe.mosaic.overlapProportion=0.05; 20 | dRecipe.mosaic.sampleSize.X=2; 21 | dRecipe.mosaic.sampleSize.Y=2; 22 | dRecipe.mosaic.scanmode='tiled: auto-ROI'; 23 | dRecipe.mosaic.tilesToRemove=-1; 24 | -------------------------------------------------------------------------------- /code/components/motion/BSC201_Troubleshooting.txt: -------------------------------------------------------------------------------- 1 | BSC201 Troubleshooting 2 | 3 | 4 | Q: Starting BakingTray crashes MATLAB when the BSC201_APT interface attempts to connect. 5 | A: Leave MATLAB closed and attempt to start the APT user utility. If this works, close it and then try MATLAB again. 6 | If this fails, cycle the power on the BSC-201 and and try MATLAB again. 7 | This error can happen if you reboot or power down the PC without cleanly disconnecting from the BSC-201. 8 | 9 | Q: The BSC-201 brings up a series of warning windows claiming it can't proceed but does not crash. It won't start. 10 | A: This is a very rare error. You might find that when the device is in this state, the APT user interface works but in MATLAB it still fails. Kinesis may fail to enter the settings. When this happened to me, I installed the latest Kinesis version and magically everything worked again. -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/extras/GetYamlVals.m: -------------------------------------------------------------------------------- 1 | function [vals, timeaxis] = GetYamlVals(yamldata) 2 | % this function converts data formatted in yaml style (cells containing timestamps and values) 3 | % into matlab user friendly matrices. 4 | 5 | % obtain number of samples 6 | n = max(size(yamldata)); 7 | 8 | if n 9 | if not(iscell(yamldata{1})) 10 | timeaxis = double(yamldata{1}); 11 | vals = cell2mat(yamldata(2:end)); 12 | else 13 | 14 | % create output matrices 15 | timeaxis = NaN*ones(n,1); 16 | if n % only if there are some elements of timeaxis 17 | vals = NaN*ones(n,numel(yamldata{1})-1); 18 | end 19 | for i=1:n 20 | timeaxis(i) = double(yamldata{i}{1}); 21 | vals(i,:) = cell2mat(yamldata{i}(2:end)); 22 | end 23 | end 24 | 25 | end 26 | 27 | end % end of function 28 | 29 | -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/merge_struct.m: -------------------------------------------------------------------------------- 1 | function result = merge_struct(p, s, donotmerge, deep) 2 | import BakingTray.yaml.*; 3 | if ~( isstruct(p) && isstruct(s) ) 4 | error('Only structures can be merged.'); 5 | end; 6 | if ~exist('donotmerge','var') 7 | donotmerge = {}; 8 | end 9 | if ~exist('deep','var') 10 | deep = 0; 11 | elseif strcmp(deep, 'deep') 12 | deep = 1; 13 | end; 14 | result = p; 15 | for i = fields(s)' 16 | fld = char(i); 17 | if any(cellfun(@(x)isequal(x, fld), donotmerge)) 18 | continue; 19 | end; 20 | if deep == 1 && isfield(result, fld) && isstruct(result.(fld)) && isstruct(s.(fld)) 21 | result.(fld) = merge_struct(result.(fld), s.(fld), donotmerge, deep); 22 | else 23 | result.(fld) = s.(fld); 24 | end; 25 | end; 26 | end 27 | -------------------------------------------------------------------------------- /code/@BT/slack.m: -------------------------------------------------------------------------------- 1 | function slack(obj,message) 2 | % Send Slack messge using Dylan Muir's SendSlackNotification 3 | % 4 | % BT.slack(message) 5 | % 6 | % If the message string is empty, nothing is sent. 7 | 8 | if isempty(message) 9 | return 10 | end 11 | 12 | SLACK = obj.recipe.SLACK; 13 | if isempty(SLACK) || isempty(SLACK.hook) 14 | msg = sprintf('No Slack hook defined. BT.slack will do nothing.\n'); 15 | obj.acqLogWriteLine(msg); 16 | return 17 | end 18 | 19 | try 20 | status = BakingTray.slack.SendSlackNotification(SLACK.hook,[SLACK.user,' ', message]); 21 | 22 | if ~strcmp(status,'ok') 23 | msg = ['Failed to send Slack message with error: ', status]; 24 | obj.acqLogWriteLine(msg); 25 | end 26 | catch ME 27 | obj.acqLogWriteLine(ME.message) 28 | end 29 | -------------------------------------------------------------------------------- /code/+BakingTray/+gui/@view/startPrepareGUI.m: -------------------------------------------------------------------------------- 1 | function startPrepareGUI(obj,~,~) 2 | %Do not start the prepare GUI if an acquisition in progress 3 | if obj.model.acquisitionInProgress 4 | warndlg('An acquisition is in progress. Can not start Sample Prepare GUI.','') 5 | return 6 | end 7 | 8 | %Do not start the prepare GUI unless all the required components are present 9 | msg = obj.model.checkForPrepareComponentsThatAreNotConnected; 10 | 11 | if ~isempty(msg) %We can't start because components are missing. Report which ones: 12 | msg = ['Can not start sample preparation:\n',msg]; 13 | warndlg(sprintf(msg),'') 14 | return 15 | end 16 | if isempty(obj.view_prepare) || ~isvalid(obj.view_prepare) 17 | obj.view_prepare=BakingTray.gui.prepare_view(obj.model,obj); 18 | else 19 | figure(obj.view_prepare.hFig) 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /code/components/scanning/+SIBT/get_hSI_from_base.m: -------------------------------------------------------------------------------- 1 | function hSI = get_hSI_from_base 2 | % Get the hSI ScanImage object from the base workspace 3 | % 4 | % hSI = SIBT.get_hSI_from_base 5 | % 6 | % Purpose 7 | % Return hSI from the base workspace as an output argument. 8 | % used by the SIBT class to interact with ScanImage. 9 | % 10 | % Rob Campbell - SWC 2024 11 | 12 | 13 | hSI = []; 14 | scanimageObjectName='hSI'; 15 | W = evalin('base','whos'); 16 | SIexists = ismember(scanimageObjectName,{W.name}); 17 | 18 | if ~SIexists 19 | fprintf('ScanImage not started. Can not connect to scanner.\n') 20 | return 21 | end 22 | 23 | hSI = evalin('base',scanimageObjectName); % get hSI from the base workspace 24 | 25 | if ~isa(hSI,'scanimage.SI') 26 | fprintf('%s -- hSI is not a ScanImage object.\n', mfilename) 27 | hSI = []; 28 | end 29 | -------------------------------------------------------------------------------- /code/+BakingTray/+gui/@acquisition_view/pause_callback.m: -------------------------------------------------------------------------------- 1 | function pause_callback(obj,~,~) 2 | % Run when the pause button is pressed 3 | % Pauses or resumes the acquisition according to the state of the observable property in scanner.acquisitionPaused 4 | % This will not pause cutting. It will only pause the system when it's acquiring data. If you press this during 5 | % cutting the acquisition of the next section will not begin until pause is disabled. 6 | if ~obj.model.acquisitionInProgress 7 | obj.updatePauseButtonState; 8 | return 9 | end 10 | 11 | if obj.model.scanner.acquisitionPaused 12 | %If acquisition is paused then we resume it 13 | obj.model.scanner.resumeAcquisition; 14 | elseif ~obj.model.scanner.acquisitionPaused 15 | %If acquisition is running then we pause it 16 | obj.model.scanner.pauseAcquisition; 17 | end 18 | 19 | end %pause_callback -------------------------------------------------------------------------------- /code/+BakingTray/+gui/newGenericGUIPanel.m: -------------------------------------------------------------------------------- 1 | function thisPanel = newGenericGUIPanel(Position,parentObj) 2 | % function thisPanel = newGenericGUIPanel(Position,parentObj) 3 | % 4 | % 5 | 6 | if ~isnumeric(Position) 7 | fprintf('ERROR: Input argument "Position" in function %s should be numeric\n', mfilename) 8 | return 9 | end 10 | 11 | if ~isvector(Position) 12 | fprintf('ERROR: Input argument "Position" in function %s should be a vector\n', mfilename) 13 | return 14 | end 15 | 16 | if length(Position)~=4 17 | fprintf('ERROR: Input argument "Position" in function %s should be a vector of length 4\n', mfilename) 18 | return 19 | end 20 | 21 | 22 | thisPanel = uipanel(... 23 | 'Parent', parentObj,... 24 | 'Units', 'pixels', ... 25 | 'Position', Position,... 26 | 'BackgroundColor', [1,1,1]*0.075,... 27 | 'HighlightColor', [0.5020 0.5020 0.5020],... 28 | 'ShadowColor', [0.3137 0.3137 0.3137]); -------------------------------------------------------------------------------- /code/+BakingTray/+slack/private/mergestruct.m: -------------------------------------------------------------------------------- 1 | function s=mergestruct(s1,s2) 2 | % 3 | % s=mergestruct(s1,s2) 4 | % 5 | % merge two struct objects into one 6 | % 7 | % authors:Qianqian Fang (fangq nmr.mgh.harvard.edu) 8 | % date: 2012/12/22 9 | % 10 | % input: 11 | % s1,s2: a struct object, s1 and s2 can not be arrays 12 | % 13 | % output: 14 | % s: the merged struct object. fields in s1 and s2 will be combined in s. 15 | % 16 | % license: 17 | % Simplified BSD License 18 | % 19 | % -- this function is part of jsonlab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) 20 | % 21 | 22 | if(~isstruct(s1) || ~isstruct(s2)) 23 | error('input parameters contain non-struct'); 24 | end 25 | if(length(s1)>1 || length(s2)>1) 26 | error('can not merge struct arrays'); 27 | end 28 | fn=fieldnames(s2); 29 | s=s1; 30 | for i=1:length(fn) 31 | s=setfield(s,fn{i},getfield(s2,fn{i})); 32 | end 33 | 34 | -------------------------------------------------------------------------------- /code/+BakingTray/+gui/@acquisition_view/zoomOutToShowSlide.m: -------------------------------------------------------------------------------- 1 | function zoomOutToShowSlide(obj,src,~) 2 | 3 | % Zoom out sufficiently to show the whole frosted area 4 | 5 | % All measurements in mm 6 | slideFrontLeft_X = obj.model.recipe.SYSTEM.slideFrontLeft{1}; 7 | slideFrontLeft_Y = obj.model.recipe.SYSTEM.slideFrontLeft{2}; 8 | 9 | % TODO -- probably these too should come from settings file 10 | slideWidth = 25; 11 | frostedWidth = 18*2; % Because people can put brains further along the slide 12 | 13 | border=4; 14 | 15 | x = [slideFrontLeft_X+border, slideFrontLeft_X-frostedWidth-border]; 16 | y = [slideFrontLeft_Y+border, slideFrontLeft_Y-slideWidth-border]; 17 | 18 | limsInPixelPos=obj.model.convertStagePositionToImageCoords([x(:),y(:)]); 19 | 20 | obj.imageAxes.YLim = limsInPixelPos(:,2); 21 | obj.imageAxes.XLim = limsInPixelPos(:,1); 22 | 23 | end 24 | -------------------------------------------------------------------------------- /code/components/scanning/@SIBT/private/default_SIBT_settings.m: -------------------------------------------------------------------------------- 1 | function settings=default_SIBT_settings 2 | % Return a set of default settings for the SIBT class to write to a file in the main settings directory 3 | % 4 | % 5 | % The following are applied to each tile before it is plotted to screen in the preview 6 | % settings.tileAcq.tileRotate=-1; 7 | % settings.tileAcq.tileFlipUD=false; 8 | % settings.tileAcq.tileFlipLR=false; 9 | % 10 | % 11 | % The following setting should be set to true if you have PMTs with a trip 12 | % circuit that tends to be activated by bright features in your sample 13 | % settings.hardware.doResetTrippedPMT = false; 14 | 15 | 16 | settings.tileAcq.tileRotate=-1; 17 | settings.tileAcq.tileFlipUD = false; 18 | settings.tileAcq.tileFlipLR = false; 19 | 20 | 21 | settings.hardware.doResetTrippedPMT = false; 22 | settings.hardware.fixedStageMotionTimeConstant = 0; 23 | -------------------------------------------------------------------------------- /code/+BakingTray/+gui/@prepare_view/stopAllAxes.m: -------------------------------------------------------------------------------- 1 | function stopAllAxes(obj,~,~) 2 | % Stop all motion axes when the user presses the stop button 3 | % 4 | %Do in try/catch so that if one fails the others still have a chance to stop 5 | %TODO: this is very rough and ready. 6 | 7 | if obj.model.isSlicing 8 | obj.model.abortSlicing 9 | return 10 | end 11 | 12 | msg='GUI received an indicator that the %s axis failed to stop or failed to respond to the stop command.\n'; 13 | try 14 | if ~obj.model.stopZ 15 | fprintf(msg,'Z') 16 | end 17 | catch ME 18 | %pass 19 | end 20 | 21 | try 22 | if ~obj.model.stopXY; 23 | fprintf(msg,'XY') 24 | end 25 | catch ME 26 | %pass 27 | end 28 | 29 | %Force update of positions to screen (TODO: HORRIBLE) 30 | pos=obj.model.getXYpos; 31 | pos=obj.model.getZpos; 32 | end %stopAllAxes -------------------------------------------------------------------------------- /code/components/scanning/@SIBT/private/default_frameSizes.yml: -------------------------------------------------------------------------------- 1 | setA: 2 | objective: OBJNAME 3 | pixelsPerLine: 256 4 | linesPerFrame: 256 5 | zoomFactor: 1.0 6 | nominalMicronsPerPixel: 1.2 7 | fastMult: 1 8 | slowMult: 1 9 | shiftSlow: 0 10 | shiftFast: 0 11 | spatialFillFrac: 0.8 12 | objRes: 50 13 | lensDistort: {rows: 0, cols: 0.0} 14 | affineMat: 15 | - [1, 0, 0] 16 | - [0, 1, 0] 17 | - [0, 0, 1] 18 | stitchingVoxelSize: {X: 1.23, Y: 1.23} 19 | setB: 20 | objective: OBJNAME 21 | pixelsPerLine: 256 22 | linesPerFrame: 256 23 | zoomFactor: 1.0 24 | nominalMicronsPerPixel: 2.4 25 | fastMult: 1 26 | slowMult: 1 27 | shiftSlow: 0 28 | shiftFast: 0 29 | spatialFillFrac: 0.8 30 | objRes: 50 31 | lensDistort: {rows: 0, cols: 0.0} 32 | affineMat: 33 | - [1, 0, 0] 34 | - [0, 1, 0] 35 | - [0, 0, 1] 36 | stitchingVoxelSize: {X: 2.46, Y: 2.46} 37 | -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/README.md: -------------------------------------------------------------------------------- 1 | yamlmatlab 2 | ---------- 3 | 4 | This is a github copy of https://code.google.com/p/yamlmatlab/ 5 | that has been packaged into +yaml namespace by Yauhen Yakimovich. 6 | 7 | 8 | Installation 9 | ------------ 10 | 11 | Just add the codes and all subfolders to Matlab path by 12 | 13 | ```matlab 14 | addpath(genpath('path/to/codes')); 15 | ``` 16 | 17 | 18 | Usage 19 | ----- 20 | 21 | Reading in: 22 | 23 | ```matlab 24 | yaml_file = 'test.yaml'; 25 | YamlStruct = yaml.ReadYaml(yaml_file); 26 | ``` 27 | 28 | Writing out 29 | 30 | ```matlab 31 | x.name='Martin'; 32 | yaml.WriteYaml('test.yaml',x) 33 | ``` 34 | 35 | 36 | Main authors 37 | ------------ 38 | 39 | * Jiri Cigler, Dept. of Control Engineering, CTU Prague http://support.dce.felk.cvut.cz/pub/ciglejir/ 40 | * Jan Siroky, Energocentrum PLUS, s.r.o. 41 | * Pavel Tomasko, student at Faculty of Electrical Engineering, CTU Prague and Institute of Chemical Technology, Prague. 42 | -------------------------------------------------------------------------------- /code/autoROI/+autoROI/+evaluate/printFileNamesAsDoubleColumnTable.m: -------------------------------------------------------------------------------- 1 | function printFileNamesAsDoubleColumnTable(fnames) 2 | % Print to screen the filenames in the cell array fnames as a double-column table 3 | % 4 | % This helper function is used by genComparisonTable and plotResults, amongst others 5 | 6 | maxLengthFname = max(cellfun(@length,{fnames{:}})); 7 | 8 | for ii= 1 : 2 : length(fnames)-mod(length(fnames),2); 9 | spacesToAdd = maxLengthFname-length(fnames{ii}) + 2; %The spaces between the two columns 10 | fprintf('%03d/%03d. %s%s%03d/%03d. %s\n', ... 11 | ii, length(fnames),fnames{ii}, ... 12 | repmat(' ',1,spacesToAdd), ... 13 | ii+1, length(fnames),fnames{ii+1} ) 14 | end 15 | 16 | % Print last name if we have an odd number of cases 17 | if mod(length(fnames),2) == 1 18 | fprintf('%03d/%03d. %s\n', ... 19 | length(fnames), length(fnames),fnames{end}) 20 | 21 | end -------------------------------------------------------------------------------- /code/autoROI/+autoROI/overlayBoundingBoxes.m: -------------------------------------------------------------------------------- 1 | function varargout = overlayBoundingBoxes(im,stats) 2 | % Overlay bounding box on current axes 3 | % 4 | % h=autoROI.overlayBoundingBoxes(im,stats) 5 | % 6 | % Purpose 7 | % Overlays all bounding boxes on top of image im using in a stats structure. 8 | % This function calls autoROI.overlayBoundingBox and is called by autoROI. 9 | % 10 | % Inputs 11 | % stats 12 | % 13 | % Rob Campbell - January 2020 14 | 15 | 16 | 17 | % Record hold state 18 | origHoldState = ishold; 19 | 20 | 21 | % Plot the bounding box 22 | hold on 23 | 24 | imagesc(im) 25 | 26 | colormap gray 27 | axis ij equal tight 28 | H=[]; 29 | for ii=1:length(stats) 30 | H(ii)=autoROI.overlayBoundingBox(stats(ii).BoundingBox); 31 | end 32 | 33 | drawnow 34 | 35 | % Return hold state to original value 36 | if ~origHoldState 37 | hold off 38 | end 39 | 40 | 41 | % Optionally return handle to plot object 42 | if nargout>0 43 | varargout{1}=H; 44 | end 45 | -------------------------------------------------------------------------------- /code/autoROI/+autoROI/+test/private/handle_runDir.m: -------------------------------------------------------------------------------- 1 | function pStack_list = handle_runDir(runDir) 2 | 3 | % Process the runDir argument for runOnAllInDir 4 | if ischar(runDir) 5 | % runDir should be a path to directory that contains pStack files. 6 | % Find those files and assign them to a dir structure. 7 | if ~exist(runDir,'dir') 8 | fprintf('%s is not a valid directory in the path\n', runDir) 9 | return 10 | end 11 | pStack_list = dir(fullfile(runDir, '/**/*_previewStack.mat')); 12 | 13 | if isempty(pStack_list) 14 | fprintf('Found no preview stacks in %s\n',runDir) 15 | return 16 | end 17 | elseif isstruct(runDir) 18 | % runDir is a directory structure containing paths to pStack files 19 | fprintf('%s is running analysis over %d files provided in dir structure\n', ... 20 | mfilename, length(runDir)) 21 | pStack_list = runDir; 22 | end 23 | -------------------------------------------------------------------------------- /tests/readme.txt: -------------------------------------------------------------------------------- 1 | This directory contains code for unit testing BakingTray. 2 | You do not need to add this directory to your path. 3 | 4 | To run the unit tests: 5 | 6 | >> runtests 7 | 8 | or 9 | 10 | >> table(runtests) 11 | 12 | To run specific tests: 13 | >> run(BT_build_tests); 14 | >> run(recipe_tests); 15 | 16 | 17 | What if there are failures? For example, say we see: 18 | 19 | Failure Summary: 20 | 21 | Name Failed Incomplete Reason(s) 22 | ============================================================================================= 23 | recipe_tests/checkTilePositions X Failed by verification. 24 | --------------------------------------------------------------------------------------------- 25 | recipe_tests/checkHandlingOfSystemSettingsLoad X Failed by verification. 26 | 27 | 28 | 29 | Run just one test: 30 | T=recipe_tests 31 | T.checkTilePositions 32 | 33 | -------------------------------------------------------------------------------- /code/components/motion/AVS_100_25.m: -------------------------------------------------------------------------------- 1 | classdef AVS_100_25 < linearstage 2 | %% 3 | % Aerotech AVS100 25 z-jack stage class 4 | % 5 | % 6 | % All abstract methods should have doc text only in the abstract method class file. 7 | 8 | properties 9 | % Define a few stage-specific properties here. These aren't hardware 10 | % limits, they are just things that seem to work well and keep 11 | % us within reasonable bounds. 12 | 13 | velocityCapMax=5 % Never any need to exceed 5 mm/s 14 | maxMoveVelocity=2 % 2mm/s seems safe 15 | 16 | end 17 | 18 | properties (Hidden) 19 | defaultAcceleration=30; % 20 | end 21 | methods 22 | 23 | %Constructor 24 | function obj = AVS_100_25(obj) 25 | % The following are defaults that can be changed by component settings file 26 | obj.minPos = 0; 27 | obj.maxPos = 25; 28 | end %Constructor 29 | 30 | 31 | end %methods 32 | 33 | 34 | end -------------------------------------------------------------------------------- /code/components/scanning/+SIBT/get_hSICtl_from_base.m: -------------------------------------------------------------------------------- 1 | function hSICtl = get_hSICtl_from_base 2 | % Get the hSICtl ScanImage object from the base workspace 3 | % 4 | % hSICtl = SIBT.get_hSICtl_from_base 5 | % 6 | % Purpose 7 | % Return hSICtl from the base workspace as an output argument. 8 | % used by the SIBT class to interact with ScanImage. 9 | % 10 | % Rob Campbell - SWC 2024 11 | 12 | 13 | hSICtl = []; 14 | scanimageObjectName='hSICtl'; 15 | W = evalin('base','whos'); 16 | SIexists = ismember(scanimageObjectName,{W.name}); 17 | 18 | if ~SIexists 19 | fprintf('ScanImage not started. Can not connect to scanner.\n') 20 | return 21 | end 22 | 23 | hSICtl = evalin('base',scanimageObjectName); % get hSICtl from the base workspace 24 | 25 | if ~isa(hSICtl,'scanimage.SIController') 26 | fprintf('%s -- hSICtl is not a scanimage.SIController object.\n', mfilename) 27 | hSICtl = []; 28 | end 29 | 30 | end 31 | -------------------------------------------------------------------------------- /code/+BakingTray/+slack/private/jsonopt.m: -------------------------------------------------------------------------------- 1 | function val=jsonopt(key,default,varargin) 2 | % 3 | % val=jsonopt(key,default,optstruct) 4 | % 5 | % setting options based on a struct. The struct can be produced 6 | % by varargin2struct from a list of 'param','value' pairs 7 | % 8 | % authors:Qianqian Fang (fangq nmr.mgh.harvard.edu) 9 | % 10 | % $Id: loadjson.m 371 2012-06-20 12:43:06Z fangq $ 11 | % 12 | % input: 13 | % key: a string with which one look up a value from a struct 14 | % default: if the key does not exist, return default 15 | % optstruct: a struct where each sub-field is a key 16 | % 17 | % output: 18 | % val: if key exists, val=optstruct.key; otherwise val=default 19 | % 20 | % license: 21 | % Simplified BSD License 22 | % 23 | % -- this function is part of jsonlab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) 24 | % 25 | 26 | val=default; 27 | if(nargin<=2) return; end 28 | opt=varargin{1}; 29 | if(isstruct(opt) && isfield(opt,key)) 30 | val=getfield(opt,key); 31 | end 32 | 33 | -------------------------------------------------------------------------------- /code/@BT/checkAttachedStages.m: -------------------------------------------------------------------------------- 1 | function success=checkAttachedStages(obj,ControllerObject,axisName) 2 | %Check that ControllerObject (which is a linearcontroller we want to attach) 3 | %has stages attached to it and is ready to go. 4 | %If all is good return true, otherwise return false. 5 | 6 | success=false; 7 | 8 | if ~isa(ControllerObject,'linearcontroller') 9 | DB=dbstack; 10 | obj.logMessage(inputname(1),DB(end),7,'ControllerObject is not a linearcontroller') 11 | stages=false; 12 | return 13 | end 14 | 15 | if ~(ControllerObject.isStageConnected) 16 | DB=dbstack; 17 | obj.logMessage(inputname(1),DB(end),7,'No stage attached to controller') 18 | stages=false; 19 | return 20 | end 21 | 22 | if ~ControllerObject.isAxisReady(axisName) 23 | DB=dbstack; 24 | obj.logMessage(inputname(1),DB(end),7,'Controller not ready') 25 | stages=false; 26 | return 27 | end 28 | 29 | success=true; 30 | end -------------------------------------------------------------------------------- /code/components/motion/generic_AeroTechZJack.m: -------------------------------------------------------------------------------- 1 | classdef generic_AeroTechZJack < linearstage 2 | %% 3 | % Aerotech generic z-jack stage class 4 | % 5 | % 6 | % All abstract methods should have doc text only in the abstract method class file. 7 | 8 | properties 9 | % Define a few stage-specific properties here. These aren't hardware 10 | % limits, they are just things that seem to work well and keep 11 | % us within reasonable bounds. 12 | 13 | velocityCapMax=5 % Never any need to exceed 5 mm/s 14 | maxMoveVelocity=2 % 2mm/s seems safe 15 | 16 | end 17 | 18 | properties (Hidden) 19 | defaultAcceleration=30; % 20 | end 21 | methods 22 | 23 | %Constructor 24 | function obj = generic_AeroTechZJack(obj) 25 | % The following are defaults that can be changed by component settings file 26 | obj.minPos = 0; 27 | obj.maxPos = 25; 28 | end %Constructor 29 | 30 | 31 | end %methods 32 | 33 | 34 | end -------------------------------------------------------------------------------- /diagnostic/measuring_xy_accuracy/+mxy/testBlockingMotion.m: -------------------------------------------------------------------------------- 1 | function testBlockingMotion(linStage,stepSize) 2 | % Measure how long blocking motions take if we use the controller's built-in code 3 | % 4 | % function testBlockingMotion(linStage,stepSize) 5 | % 6 | % step size in mm 7 | 8 | if nargin<2 9 | stepSize=1; 10 | end 11 | 12 | for ii=1:10 13 | blockRelMove(linStage,stepSize) 14 | stepSize = stepSize * -1; 15 | end 16 | 17 | 18 | function blockRelMove(linStage,stepSize) 19 | curPos = linStage.axisPosition; 20 | targetPos = curPos + stepSize; 21 | linStage.relativeMove(stepSize); 22 | tic 23 | while 1 24 | if linStage.isMoving 25 | curPos = linStage.axisPosition; 26 | delta=abs(curPos-targetPos); 27 | fprintf('Pos: %0.4f mm ; Delta: %0.4f mm\n',curPos, delta) 28 | if delta<0.002 %within a couple of microns 29 | break 30 | end 31 | else 32 | fprintf('\n') 33 | break 34 | end 35 | end 36 | toc -------------------------------------------------------------------------------- /code/autoROI/+autoROI/overlayBoundingBox.m: -------------------------------------------------------------------------------- 1 | function varargout = overlayBoundingBox(boundingBox) 2 | % Overlay bounding box on current axes 3 | % 4 | % h=autoROI.overlayBoundingBox(boundingBox) 5 | % 6 | % Purpose 7 | % Overlays a bounding box on the current axes. Optionally return the handle 8 | % to the plot object. Returns axis hold state to whatever it was originally. 9 | % 10 | % Inputs 11 | % boundingBox - vector of length 4. Same format as the regionprops BoundingBox: 12 | % [x, y, x_width, y_height] 13 | % 14 | % 15 | % Rob Campbell - November 2019 16 | 17 | 18 | 19 | % Record hold state 20 | origHoldState = ishold; 21 | 22 | 23 | % Plot the bounding box 24 | hold on 25 | 26 | b=boundingBox; 27 | x=[b(1), b(1)+b(3), b(1)+b(3), b(1), b(1)]; 28 | y=[b(2), b(2), b(2)+b(4), b(2)+b(4), b(2)]; 29 | h=plot(x,y,'-r','LineWidth',2); 30 | 31 | 32 | % Return hold state to original value 33 | if ~origHoldState 34 | hold off 35 | end 36 | 37 | 38 | % Optionally return handle to plot object 39 | if nargout>0 40 | varargout{1}=h; 41 | end 42 | -------------------------------------------------------------------------------- /code/@BT/renewLaserConnection.m: -------------------------------------------------------------------------------- 1 | function success=renewLaserConnection(obj) 2 | % Detach and re-connect the laser to BT 3 | % 4 | % function success=renewLaserConnection(obj) 5 | % 6 | % Outputs 7 | % success - Returns true if a BT hardware component was built successfully. 8 | % The component itself is placed in the BT object as a property, 9 | % so BT is a composite object. 10 | % 11 | % 12 | 13 | success=false; 14 | 15 | if ~isempty(obj.laser) 16 | currentCOM = obj.laser.controllerID; 17 | laserClass = class(obj.laser); 18 | end 19 | 20 | delete(obj.laser) 21 | 22 | %Build the component 23 | obj.laser=buildLaserComponent(laserClass, currentCOM); 24 | 25 | 26 | %Return false if the attachment failed 27 | if ~isempty(obj.laser) 28 | success=true; 29 | else 30 | %Add a link to the BT parent object to the component so this component can access 31 | %other attached components 32 | obj.laser.parent=obj; 33 | end 34 | 35 | end -------------------------------------------------------------------------------- /code/autoROI/+autoROI/+groundTruth/genBordersForAllInDir.m: -------------------------------------------------------------------------------- 1 | function genBordersForAllInDir(thresh) 2 | % Loop through all p-stack files in current directory and generate ground truth borders for all 3 | % 4 | % pStack = autoROI.groundTruth.genBordersForAllInDir(thresh) 5 | % 6 | % Purpose 7 | % Speeds up initial border making. You will still have to curate them, but it's less 8 | % human time to generate all automatcally then look a them. 9 | % 10 | % 11 | % Inputs 12 | % thresh - optional SD threshold to use. 13 | % 14 | 15 | if nargin==0; 16 | thresh=[]; 17 | end 18 | 19 | D = dir ('*_previewStack.mat'); 20 | 21 | if isempty(D) 22 | fprintf('No preview mat files found in %s\n', pwd); 23 | return 24 | end 25 | 26 | 27 | for ii=1:length(D) 28 | fname = D(ii).name; 29 | 30 | fprintf('Loading %s...\n', fname) 31 | load(fname) 32 | 33 | fprintf('Getting borders for %s\n', fname) 34 | pStack = autoROI.groundTruth.genGroundTruthBorders(pStack,thresh); 35 | 36 | fprintf('Saving %s...\n', fname) 37 | save('-v7.3',fname,'pStack') 38 | end -------------------------------------------------------------------------------- /code/+BakingTray/getObject.m: -------------------------------------------------------------------------------- 1 | function hBT = getObject(quiet) 2 | % Returns the BakingTray object from the base workspace regardless of its name 3 | % 4 | % Purpose 5 | % Used by methods to import BakingTray without requiring it to be passed as an input argument. 6 | % 7 | % Inputs 8 | % quiet - false by default. If true, print no messages to screen. 9 | % 10 | % Outputs 11 | % hBT - the BakingTray object. Returns empty if BT could not be found. 12 | % 13 | % 14 | % Rob Campbell - Basel 2016 15 | 16 | if nargin<1 17 | quiet=false; 18 | end 19 | 20 | W=evalin('base','whos'); 21 | 22 | varClasses = {W.class}; 23 | 24 | ind=strmatch('BT',varClasses); 25 | 26 | if isempty(ind) 27 | if ~quiet 28 | fprintf('No BakingTray object in base workspace\n') 29 | end 30 | hBT=[]; 31 | return 32 | end 33 | 34 | if length(ind)>1 35 | if ~quiet 36 | fprintf('More than one BakingTray object in base workspace\n') 37 | end 38 | hBT=[]; 39 | return 40 | end 41 | 42 | 43 | hBT=evalin('base',W(ind).name); 44 | -------------------------------------------------------------------------------- /code/+BakingTray/+gui/@acquisition_view/setDepthToView.m: -------------------------------------------------------------------------------- 1 | function setDepthToView(obj,~,~) 2 | % BakingTray.gui.acquisition_view.setDepthToView 3 | % 4 | % This callback runs when the user interacts with the depth popup. 5 | % The callback sets which depth will be displayed 6 | 7 | if obj.verbose, fprintf('In acquisition_view.setDepthToView callback\n'), end 8 | 9 | if isempty(obj.model.scanner.getChannelsToDisplay) 10 | %Don't do anything if no channels are being viewed 11 | return 12 | end 13 | if strcmp(obj.depthSelectPopup.Enable,'off') 14 | return 15 | end 16 | thisSelection = obj.depthSelectPopup.String{obj.depthSelectPopup.Value}; 17 | thisDepthIndex = str2double(regexprep(thisSelection,'\w+ ','')); 18 | 19 | if thisDepthIndex>size(obj.model.lastPreviewImageStack,3) 20 | %If the selected value is out of bounds default to the first depth 21 | thisDepthIndex=1; 22 | obj.depthSelectPopup.Value=1; 23 | end 24 | 25 | obj.depthToShow = thisDepthIndex; 26 | obj.updateSectionImage([],[],true); %force update 27 | end %setDepthToView -------------------------------------------------------------------------------- /code/components/@recipe/autoSetCutSize.m: -------------------------------------------------------------------------------- 1 | function autoSetCutSize(obj) 2 | % recipe.autoSetCutSize 3 | % 4 | % If the user has set the SYSTEM.bladeXposAtSlideEnd setting in the 5 | % systemSettings.yml then this method is able to use this to 6 | % set the cut size to a reasonable value. 7 | 8 | 9 | if isnan(obj.SYSTEM.bladeXposAtSlideEnd) 10 | % The setting has not been defined so we can not proceed 11 | return 12 | end 13 | 14 | if isnan(obj.CuttingStartPoint.X) 15 | % The cutting start point in X is a NaN. The user 16 | % has not set it so we can not proceed. 17 | return 18 | end 19 | 20 | 21 | % If the end of the agar block is up against the end of the slide, 22 | % then we know the width (cut size) exactly. If it's not we will end 23 | % up cutting a little more, but that's OK. Better than too little. 24 | % The user can always edit his value if needed. 25 | 26 | agarWidth = abs(obj.SYSTEM.bladeXposAtSlideEnd - obj.CuttingStartPoint.X); 27 | agarWidth = agarWidth + 2; % Add a bit in case the agar is right up against the slide end. 28 | 29 | obj.mosaic.cutSize = agarWidth; 30 | 31 | end % autoSetCutSize 32 | -------------------------------------------------------------------------------- /code/autoROI/+autoROI/+autothresh/batchDir.m: -------------------------------------------------------------------------------- 1 | function out = batchDir(runDir) 2 | % function [tThresh,stats] = autoROI.autoThresh.batchDir(runDir) 3 | % 4 | % Run on all in directory and retun a structure with the results 5 | 6 | 7 | 8 | 9 | 10 | pStack_list = dir(fullfile(runDir, '/**/*_previewStack.mat')); 11 | 12 | if isempty(pStack_list) 13 | fprintf('Found no preview stacks in %s\n',runDir) 14 | return 15 | end 16 | 17 | for ii=1:length(pStack_list) 18 | tFile = fullfile(pStack_list(ii).folder,pStack_list(ii).name); 19 | fprintf('\n\n\n **** %d/%d Loading %s ****\n\n', ii, length(pStack_list), tFile) 20 | pStack = pstack_loader(tFile); 21 | [~,nameWithoutExtension] = fileparts(pStack_list(ii).name); 22 | 23 | [out(ii).thresh,out(ii).stats]=autoROI.autothresh.run(pStack,false); 24 | 25 | out(ii).nameWithoutExtension=nameWithoutExtension; 26 | out(ii).fullPath=tFile; 27 | fprintf('\n **** %d/%d FINISHED %s ****\n\n', ii, length(pStack_list), tFile) 28 | pause 29 | end 30 | 31 | 32 | function pStack=pstack_loader(fname) 33 | load(fname) -------------------------------------------------------------------------------- /code/components/scanning/@dummyScanner/returnDefaultScanSettings.m: -------------------------------------------------------------------------------- 1 | function OUT = returnDefaultScanSettings(obj) 2 | %Where needed, the following settings are modified 3 | %when attachPreviewStack runs. 4 | OUT.pixelsPerLine=512; 5 | OUT.linesPerFrame=512; 6 | OUT.micronsBetweenOpticalPlanes=10; 7 | 8 | OUT.FOV_alongColsinMicrons=775; 9 | OUT.FOV_alongRowsinMicrons=775; 10 | 11 | OUT.micronsPerPixel_cols=OUT.FOV_alongColsinMicrons/OUT.pixelsPerLine; 12 | OUT.micronsPerPixel_rows=OUT.FOV_alongRowsinMicrons/OUT.linesPerFrame; 13 | 14 | OUT.framePeriodInSeconds = 0.5; 15 | OUT.pixelTimeInMicroSeconds = (OUT.framePeriodInSeconds * 1E6) / (OUT.pixelsPerLine * OUT.linesPerFrame); 16 | OUT.linePeriodInMicroseconds = OUT.pixelTimeInMicroSeconds * OUT.pixelsPerLine; 17 | OUT.bidirectionalScan = true; 18 | OUT.activeChannels = 1:4; 19 | OUT.beamPower= 10; %percent 20 | OUT.scannerType='simulated'; 21 | OUT.scannerID=obj.scannerID; 22 | OUT.slowMult = 1; 23 | OUT.fastMult = 1; 24 | OUT.zoomFactor =1; 25 | OUT.numOpticalSlices=obj.numOpticalPlanes; 26 | OUT.averageEveryNframes=obj.averageEveryNframes; 27 | end -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/MIT-license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 CTU in Prague and Energocentrum PLUS s.r.o. 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /code/+BakingTray/+gui/@prepare_view/isSafeToMove.m: -------------------------------------------------------------------------------- 1 | function [isSafeToMove,msg]=isSafeToMove(obj,axisToCheckIfMoving) 2 | % Confirm if it is safe for the prepare view to move an axis 3 | % 4 | % function [isSafeToMove,msg] = BakingTray.gui.prepare_view.isSafeToMove(obj,axisToCheckIfMoving) 5 | % 6 | % If supplied with no input args, returns false only if the system is cutting. 7 | % If supplied with two input args, the second is a linearstage class from one axis. 8 | % If this reports it's moving, the method returns false. Otherwise true. 9 | % 10 | % If msg is also returned then no warning dialog is popped up and we instead write to the command line. 11 | 12 | isSafeToMove=false; 13 | msg=''; 14 | if obj.model.isSlicing 15 | msg=sprintf('System is slicing. Can not move.\n'); 16 | elseif nargin>1 && axisToCheckIfMoving.isMoving 17 | msg=sprintf('Axis is already moving. Can not move.\n'); 18 | end 19 | 20 | if isempty(msg) 21 | isSafeToMove=true; 22 | else 23 | if nargin>1 24 | fprintf(msg); 25 | else 26 | warndlg(msg,'') 27 | end 28 | end 29 | 30 | end %safeToMove 31 | -------------------------------------------------------------------------------- /code/autoROI/+autoROI/+test/getAllFirstImages.m: -------------------------------------------------------------------------------- 1 | function varargout=getAllFirstImages(runDir) 2 | % Loop through all pStack files in a directory and return the first plane of each 3 | % 4 | % function out=getAllFirstImages(runDir) 5 | % 6 | % Inputs 7 | % runDir - Either: a) Directory in which to look for files and run. 8 | % Or: b) A dir structure with a list of files to process 9 | % 10 | % Outputs 11 | % out - structure of image results. Return file name and first plane 12 | 13 | 14 | % Handle arg using private function 15 | pStack_list = handle_runDir(runDir); 16 | 17 | out.fname=[]; 18 | out.im=[]; 19 | 20 | for ii=1:length(pStack_list) 21 | tFile = fullfile(pStack_list(ii).folder,pStack_list(ii).name); 22 | if ~exist(tFile,'file') 23 | fprintf('File %s does not exist. Skipping\n', tFile) 24 | continue 25 | end 26 | fprintf('Loading %s\n',tFile) 27 | load(tFile) 28 | 29 | out(ii).fname = tFile; 30 | out(ii).im =imresize(pStack.imStack(:,:,1),0.4,'nearest'); 31 | end 32 | 33 | 34 | if nargout>0 35 | varargout{1} = out; 36 | end -------------------------------------------------------------------------------- /code/+BakingTray/+yaml/Tests/Data/test_inheritance/inheritance.yaml: -------------------------------------------------------------------------------- 1 | cars: 2 | - color: blue 3 | label: JJ-XX-1500 4 | parent: 5 | - manufacturer.skoda 6 | - insurance.mandatory.Allianz 7 | - insurance.optional.Kooperativa 8 | 9 | ins_note: IMPORTANT_1 10 | info: {aaa: 2} 11 | 12 | - color: red 13 | label: DD-XX-1500 14 | ins_note: IMPORTANT_2 15 | parent : [ manufacturer.audi, insurance.mandatory.Allianz ] 16 | 17 | manufacturer: 18 | skoda: 19 | established: cca 1900 20 | place: MB 21 | info: 22 | aaa: 1 23 | bbb: 11 24 | audi: 25 | established: cca 1900 26 | place: Germany 27 | 28 | insurance: 29 | mandatory: 30 | Allianz: 31 | ins_price: 4000 32 | ins_unit : CZK 33 | Kooperativa: 34 | ins_price: 4100 35 | ins_unit : CZK 36 | ins_note : umfty dumf 37 | 38 | optional: 39 | CP: 40 | ins_price: 1000 CZK 41 | Kooperativa: 42 | ins_price: 1100 CZK 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /code/+BakingTray/@channelChooser/excitation_spectra_2p/README.txt: -------------------------------------------------------------------------------- 1 | 2 | Data format: 3 | Col 1 - wavelength 4 | Col 2 - the two photon absorption spectrum (aka 2PA cross section) 5 | Col 3 - the two-photon brightness (aka action cross section) 6 | 7 | 8 | NOTE: 9 | Currently we do not have excitation for spectra for some flurophores. To approximate them temporarily we use other spectra with roughly similar spectra. 10 | So we approximate Alexa647, for instance, with eBFP because this will give the 11 | same answer for optimal wavelength. The "fake" spectra and their sources are: 12 | 13 | Af647 - eBFP 14 | eYFP - eCFP 15 | DiO - eGFP 16 | DII - eCFP 17 | 18 | Acknowledgements 19 | 20 | These spectra are published in: 21 | (a) M. Drobizhev et al. Nat Meth., 2011, 8: 393-399; 22 | (b) R. S. Molina et al., J. Phys. Chem. Lett. 2017, 8:2548-2554. 23 | 24 | These spectra are measured using the Resource for Multiphoton Characterization of Genetically Encoded Probes at Montana State University, Bozeman, MT supported by NIH grant U24NS 109107. 25 | 26 | For characterization of other FPs or 2P relevant fluorophores with unpublished 2PEF spectra, please contact Mikhail Drobizhev at mikhail.drobijev@montana.edu -------------------------------------------------------------------------------- /code/+BakingTray/+gui/@prepare_view/resetBladeIfNeeded.m: -------------------------------------------------------------------------------- 1 | function resetBladeIfNeeded(obj) 2 | % Esnures sample is on the correct side of the blade during trimming 3 | % 4 | % resetBladeIfNeeded 5 | % 6 | % Purpose 7 | % Move to the cutting start point if sample is beyond blade. 8 | % This causes the blade to always return to this position when trimming 9 | % and it avoids user confusion in cases such as an abort of the cutting 10 | % that then leads to the blade returning to a location above the sample 11 | % 12 | % No inputs or outputs 13 | % 14 | % Called by takeNslices, takeOneSlice, and autoTrim 15 | 16 | 17 | startPoint = obj.model.recipe.CuttingStartPoint.X; %Cutting start point 18 | xPos = obj.model.getXpos; 19 | 20 | 21 | if obj.model.recipe.SYSTEM.cutterSide == 1 22 | % Blade to the right as looking at the rig 23 | if xPos > startPoint 24 | obj.model.moveXYto(obj.model.recipe.CuttingStartPoint.X-0.5,0,true) 25 | end 26 | 27 | elseif obj.model.recipe.SYSTEM.cutterSide == -1 28 | if xPos < startPoint 29 | obj.model.moveXYto(obj.model.recipe.CuttingStartPoint.X+0.5,0,true) 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /code/+BakingTray/+settings/devNotes.txt: -------------------------------------------------------------------------------- 1 | 2 | Developer notes: settings system 3 | Also see: recipe class 4 | 5 | There are two sorts of "settings": 6 | - "recipes" (scan settings files) and associated rig hardware descriptions, like the rig name and cutting paramaters. 7 | - The settings needed to connect to "components" (classes that are used to control the hardware). 8 | 9 | ** Recipes and scan settings 10 | Each acquisition is controlled by a "recipe" that is defined by a YAML file. 11 | The YAML file is read by readRecipe and defines two structures: sample and mosaic. 12 | These contain the settings which will be highly sample specific. 13 | 14 | Parameters that are specific to the rig are stored in: /SETTINGS/systemSettings.yml 15 | This file is not shipped with the repository but is created by readSystemSettings based on 16 | the information in default_BT_Settings.m which is in the private sub-directory in /+BakingTray/+settings 17 | 18 | Recipes are read by readRecipe, which ensures that a valid recipe is returned. Parameters that have 19 | implausible or dangerous values are coerced to values from the default recipe in the private sub-directory. 20 | 21 | 22 | 23 | ** Component settings 24 | TODO -------------------------------------------------------------------------------- /code/autoROI/+autoROI/+tools/reportRecipeName.m: -------------------------------------------------------------------------------- 1 | function reportrecipeName 2 | % Report the name of the sample in the recipe alongside the file name of the pStack file 3 | % 4 | % Purpose 5 | % Used to look for cases where the pStack file has the wrong recipe 6 | % Pulls all pStack files in the current directory and sub-dirs. 7 | % Run from directory in question. No inputs or outputs. Just prints to 8 | % screen. 9 | 10 | 11 | % Find all pStackf files 12 | runDir = pwd; 13 | pStack_list = dir(fullfile(runDir, '/**/*_previewStack.mat')); 14 | 15 | if isempty(pStack_list) 16 | fprintf('Found no preview stacks in %s\n',runDir) 17 | return 18 | end 19 | 20 | 21 | 22 | parfor ii=1:length(pStack_list) 23 | tFile = fullfile(pStack_list(ii).folder,pStack_list(ii).name); 24 | 25 | try 26 | pStack = pstack_loader(tFile); 27 | ID=pStack.recipe.sample.ID; 28 | 29 | fprintf('%s \t %s\n', tFile, ID) 30 | catch ME 31 | fprintf('RESIZE OF FILE %s FAILED!\n', tFile) 32 | end 33 | end 34 | 35 | 36 | % internal functions 37 | function pStack=pstack_loader(fname) 38 | load(fname) 39 | 40 | -------------------------------------------------------------------------------- /code/+BakingTray/+settings/installLocation.m: -------------------------------------------------------------------------------- 1 | function installPath = installLocation 2 | % Return install location of the BakingTray anatomy suite to the command line 3 | % 4 | % function installPath = BakingTray.settings.installLocation 5 | % 6 | % 7 | % Purpose 8 | % Return the full path to the install location of the BakingTray anatomy 9 | % suite to the command line. The path returned is root path of the whole 10 | % package, not the path to the code directory. i.e. it's the directory 11 | % that *contains* the code directory and readme file. 12 | % 13 | % Returns an empty string on error. 14 | % 15 | % Inputs 16 | % None 17 | % 18 | % Outputs 19 | % installPath - String defining path to install location. 20 | % Empty if something went wrong. 21 | % 22 | % 23 | % 24 | 25 | 26 | pth = which('BakingTray'); 27 | 28 | installPath = regexprep(pth,['code\',filesep,'BakingTray\.m'],''); %Strip the end of the path. 29 | 30 | if ~exist(installPath,'dir') 31 | fprintf(['Install location expected at %s but not found there\n'... 32 | 'Your BakingTray install might be broken'],installPath) 33 | installPath=[]; 34 | end 35 | 36 | -------------------------------------------------------------------------------- /code/+BakingTray/+settings/readDefaultRecipe.m: -------------------------------------------------------------------------------- 1 | function [thisRecipe,recipeFile] = readDefaultRecipe 2 | % Read the default recipe from the settings directory if missing, add one 3 | % 4 | % function thisRecipe = BakingTray.settings.readDefaultRecipe 5 | % 6 | % Purpose 7 | % The recipe is the set of parameters that describe how an acquisition will 8 | % proceed. This function loads a default recipe. Returns empty if thre is a 9 | % problem reading the file. 10 | % 11 | % 12 | % 13 | % Rob Campbell - Basel, 2017 14 | 15 | 16 | settingsDir = BakingTray.settings.settingsLocation; 17 | if isempty(settingsDir) 18 | return 19 | end 20 | 21 | if ~exist('settingsDir') 22 | BakingTray.settings.readSystemSettings; %get user to make the settings file first 23 | return 24 | end 25 | 26 | 27 | recipeFile = fullfile(settingsDir,'default_recipe.yml'); 28 | 29 | if ~exist(recipeFile,'file') 30 | fprintf('BakingTray.settings.readDefaultRecipe is creating a default recipe at %s\n', recipeFile); 31 | D=defaultRecipe; 32 | BakingTray.yaml.WriteYaml(recipeFile,D); 33 | end 34 | 35 | thisRecipe = BakingTray.settings.readRecipe(recipeFile); 36 | -------------------------------------------------------------------------------- /code/components/@recipe/recipe2struct.m: -------------------------------------------------------------------------------- 1 | function recipeStruct=recipe2struct(obj) 2 | % Convert recipe to a structure 3 | % 4 | % recipeStruct = recipe.writeFullRecipeForAcquisition 5 | % 6 | % Purpose 7 | % Turns all the public properties of the recipe class into a structure containing 8 | % their current values. Used by recipe.writeFullRecipeForAcquisition amongst others. 9 | % 10 | % Also see: 11 | % recipe.saveRecipe, recipe.writeFullRecipeForAcquisition 12 | 13 | theseFields = ['Acquisition';properties(obj)]; %Acquisition (which contains the acquisition start time) is hidden so is added explicitly here 14 | 15 | recipeStruct = struct; 16 | for ii=1:length(theseFields) 17 | 18 | % We have to manually add the NumTiles and TileStepSize fields because they're classes 19 | % and WriteYaml can't handle this. 20 | if isa(obj.(theseFields{ii}), theseFields{ii}) % sorry, I know it's naughty but can't help myself 21 | recipeStruct.(theseFields{ii}).X = obj.(theseFields{ii}).X; 22 | recipeStruct.(theseFields{ii}).Y = obj.(theseFields{ii}).Y; 23 | continue 24 | end 25 | 26 | recipeStruct.(theseFields{ii}) = obj.(theseFields{ii}); 27 | end 28 | -------------------------------------------------------------------------------- /code/autoROI/+autoROI/genOverlapStack.m: -------------------------------------------------------------------------------- 1 | function overlapStack = genOverlapStack(BoundingBoxes,imSize) 2 | % Generate a binary image stack where each plane contains a separate ROI 3 | % 4 | % function overlapStack = autoROI.genOverlapStack(BoundingBoxes,imSize) 5 | % 6 | % Purpose 7 | % Used to evalue whether there are overlapping ROIs and if so by how much. 8 | % See autoROI.mergeOverlapping 9 | % 10 | % Inputs 11 | % BoundingBoxes - a cell array of bounding boxes 12 | % imSize - x/y size of each frame. 13 | % 14 | % Outputs 15 | % overlapStack - Binary image of size [imSize,length(BoundingBoxes)] Each plane is one 16 | % bounding box. Ones are within the area and zeros outside. 17 | 18 | 19 | 20 | overlapStack = zeros([imSize,length(BoundingBoxes)]); 21 | 22 | % Fill in the blank "image" with the areas that are ROIs 23 | for ii=1:length(BoundingBoxes) 24 | tB = BoundingBoxes{ii}; 25 | eb = autoROI.validateBoundingBox(tB, imSize); 26 | overlapStack(eb(2):eb(2)+eb(4), eb(1):eb(1)+eb(3),ii) = 1; 27 | end 28 | 29 | % Just in case, delete any planes which happen to empty 30 | sP = squeeze(sum(overlapStack,[1,2])); 31 | overlapStack(:,:,sP==0) = []; 32 | -------------------------------------------------------------------------------- /code/+BakingTray/+slack/private/varargin2struct.m: -------------------------------------------------------------------------------- 1 | function opt=varargin2struct(varargin) 2 | % 3 | % opt=varargin2struct('param1',value1,'param2',value2,...) 4 | % or 5 | % opt=varargin2struct(...,optstruct,...) 6 | % 7 | % convert a series of input parameters into a structure 8 | % 9 | % authors:Qianqian Fang (fangq nmr.mgh.harvard.edu) 10 | % date: 2012/12/22 11 | % 12 | % input: 13 | % 'param', value: the input parameters should be pairs of a string and a value 14 | % optstruct: if a parameter is a struct, the fields will be merged to the output struct 15 | % 16 | % output: 17 | % opt: a struct where opt.param1=value1, opt.param2=value2 ... 18 | % 19 | % license: 20 | % Simplified BSD License 21 | % 22 | % -- this function is part of jsonlab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) 23 | % 24 | 25 | len=length(varargin); 26 | opt=struct; 27 | if(len==0) return; end 28 | i=1; 29 | while(i<=len) 30 | if(isstruct(varargin{i})) 31 | opt=mergestruct(opt,varargin{i}); 32 | elseif(ischar(varargin{i}) && i