python-microscopy 25.6.5__cp39-cp39-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- PYME/Acquire/ActionManager.py +450 -0
- PYME/Acquire/ExecTools.py +235 -0
- PYME/Acquire/Hardware/AAOptoelectronics/MDS.py +175 -0
- PYME/Acquire/Hardware/AAOptoelectronics/__init__.py +0 -0
- PYME/Acquire/Hardware/ARCoptix/__init__.py +0 -0
- PYME/Acquire/Hardware/ARCoptix/lcdriver.py +149 -0
- PYME/Acquire/Hardware/ARCoptix/lcserver32.py +123 -0
- PYME/Acquire/Hardware/AndorIXon/AndorCam.py +1095 -0
- PYME/Acquire/Hardware/AndorIXon/AndorControlFrame.py +312 -0
- PYME/Acquire/Hardware/AndorIXon/AndorIXon.py +737 -0
- PYME/Acquire/Hardware/AndorIXon/__init__.py +27 -0
- PYME/Acquire/Hardware/AndorNeo/AndorNeo.py +644 -0
- PYME/Acquire/Hardware/AndorNeo/AndorNeoControlFrame.py +161 -0
- PYME/Acquire/Hardware/AndorNeo/AndorZyla.py +761 -0
- PYME/Acquire/Hardware/AndorNeo/SDK3.py +307 -0
- PYME/Acquire/Hardware/AndorNeo/SDK3Cam.py +171 -0
- PYME/Acquire/Hardware/AndorNeo/ZylaControlPanel.py +105 -0
- PYME/Acquire/Hardware/AndorNeo/__init__.py +22 -0
- PYME/Acquire/Hardware/AndorNeo/parseAtdebug.py +46 -0
- PYME/Acquire/Hardware/AndorNeo/plotTimings.py +73 -0
- PYME/Acquire/Hardware/AndorNeo/testNeo.py +62 -0
- PYME/Acquire/Hardware/Camera.py +1199 -0
- PYME/Acquire/Hardware/CameraSkeleton.py +642 -0
- PYME/Acquire/Hardware/Coherent/OBIS.py +147 -0
- PYME/Acquire/Hardware/Coherent/Sapphire.py +162 -0
- PYME/Acquire/Hardware/Coherent/__init__.py +0 -0
- PYME/Acquire/Hardware/DMDGui.py +198 -0
- PYME/Acquire/Hardware/DigiData/DigiData.py +95 -0
- PYME/Acquire/Hardware/DigiData/DigiDataClient.py +30 -0
- PYME/Acquire/Hardware/DigiData/RemoteDigiData.py +51 -0
- PYME/Acquire/Hardware/DigiData/__init__.py +24 -0
- PYME/Acquire/Hardware/DigiData/axDD132x.py +348 -0
- PYME/Acquire/Hardware/EMCCDTheory.py +41 -0
- PYME/Acquire/Hardware/ExciterWheel.py +167 -0
- PYME/Acquire/Hardware/FilterWheel.py +184 -0
- PYME/Acquire/Hardware/FocCorr.py +106 -0
- PYME/Acquire/Hardware/FocCorrR.py +196 -0
- PYME/Acquire/Hardware/FrFilter.py +51 -0
- PYME/Acquire/Hardware/GCS/GCS_DLL.py +370 -0
- PYME/Acquire/Hardware/GCS/__init__.py +0 -0
- PYME/Acquire/Hardware/GCS/gcs.py +210 -0
- PYME/Acquire/Hardware/HamamatsuDCAM/HamamatsuDCAM.py +662 -0
- PYME/Acquire/Hardware/HamamatsuDCAM/HamamatsuORCA.py +602 -0
- PYME/Acquire/Hardware/HamamatsuDCAM/Hamamatsu_control_panel.py +54 -0
- PYME/Acquire/Hardware/HamamatsuDCAM/__init__.py +23 -0
- PYME/Acquire/Hardware/LaserControlFrame.py +160 -0
- PYME/Acquire/Hardware/MPBCommunications/MPBCW.py +132 -0
- PYME/Acquire/Hardware/MPBCommunications/__init__.py +0 -0
- PYME/Acquire/Hardware/Mercury/Mercury.py +269 -0
- PYME/Acquire/Hardware/Mercury/PI_Mercury_GCS_DLL.py +857 -0
- PYME/Acquire/Hardware/Mercury/__init__.py +22 -0
- PYME/Acquire/Hardware/Mercury/mercuryStepper.py +203 -0
- PYME/Acquire/Hardware/Mercury/mercuryStepperGCS.py +281 -0
- PYME/Acquire/Hardware/NikonTE2000.py +68 -0
- PYME/Acquire/Hardware/NikonTi.py +214 -0
- PYME/Acquire/Hardware/NikonTiGUI.py +81 -0
- PYME/Acquire/Hardware/OrielCornerstone.py +125 -0
- PYME/Acquire/Hardware/PM100USB.py +51 -0
- PYME/Acquire/Hardware/Piezos/__init__.py +22 -0
- PYME/Acquire/Hardware/Piezos/base_piezo.py +108 -0
- PYME/Acquire/Hardware/Piezos/offsetPiezo.py +162 -0
- PYME/Acquire/Hardware/Piezos/offsetPiezoREST.py +308 -0
- PYME/Acquire/Hardware/Piezos/piezo_c867.py +486 -0
- PYME/Acquire/Hardware/Piezos/piezo_e255.py +68 -0
- PYME/Acquire/Hardware/Piezos/piezo_e662.py +61 -0
- PYME/Acquire/Hardware/Piezos/piezo_e709.py +434 -0
- PYME/Acquire/Hardware/Piezos/piezo_e816.py +452 -0
- PYME/Acquire/Hardware/Piezos/piezo_e816_corr.py +70 -0
- PYME/Acquire/Hardware/Piezos/piezo_e816_dll.py +518 -0
- PYME/Acquire/Hardware/Piezos/piezo_e816b.py +70 -0
- PYME/Acquire/Hardware/Piezos/piezo_pipython_gcs.py +560 -0
- PYME/Acquire/Hardware/Piezos/piezo_test.py +55 -0
- PYME/Acquire/Hardware/Simulator/EmpiricalHist.py +273 -0
- PYME/Acquire/Hardware/Simulator/__init__.py +22 -0
- PYME/Acquire/Hardware/Simulator/dSimControl.py +961 -0
- PYME/Acquire/Hardware/Simulator/fakeCam.py +651 -0
- PYME/Acquire/Hardware/Simulator/fakePiezo.py +95 -0
- PYME/Acquire/Hardware/Simulator/fluor.py +336 -0
- PYME/Acquire/Hardware/Simulator/illuminate.cp39-win_amd64.dll.a +0 -0
- PYME/Acquire/Hardware/Simulator/illuminate.cp39-win_amd64.pyd +0 -0
- PYME/Acquire/Hardware/Simulator/illuminate.pyx +93 -0
- PYME/Acquire/Hardware/Simulator/lasersliders.py +90 -0
- PYME/Acquire/Hardware/Simulator/rend_im.py +446 -0
- PYME/Acquire/Hardware/Simulator/setup.py +69 -0
- PYME/Acquire/Hardware/Simulator/simcontrol.py +348 -0
- PYME/Acquire/Hardware/Simulator/simui_wx.py +794 -0
- PYME/Acquire/Hardware/Tango/__init__.py +0 -0
- PYME/Acquire/Hardware/Tango/marzhauser_tango.py +583 -0
- PYME/Acquire/Hardware/TiLightCrafter.py +388 -0
- PYME/Acquire/Hardware/__init__.py +22 -0
- PYME/Acquire/Hardware/aotf.py +271 -0
- PYME/Acquire/Hardware/arclampshutterpanel.py +71 -0
- PYME/Acquire/Hardware/cameraSoftwareBuffer.py +215 -0
- PYME/Acquire/Hardware/camera_noise.py +270 -0
- PYME/Acquire/Hardware/ccdAdjPanel.py +188 -0
- PYME/Acquire/Hardware/ccdCalibrator.py +161 -0
- PYME/Acquire/Hardware/cobaltLaser.py +108 -0
- PYME/Acquire/Hardware/cobaltLaser561.py +94 -0
- PYME/Acquire/Hardware/comports.py +26 -0
- PYME/Acquire/Hardware/driftTrackGUI.py +488 -0
- PYME/Acquire/Hardware/driftTracking.py +595 -0
- PYME/Acquire/Hardware/fakeShutters.py +52 -0
- PYME/Acquire/Hardware/focusKeys.py +204 -0
- PYME/Acquire/Hardware/focus_locks/__init__.py +0 -0
- PYME/Acquire/Hardware/focus_locks/reflection_focus_lock.py +684 -0
- PYME/Acquire/Hardware/frZStage.py +117 -0
- PYME/Acquire/Hardware/fw102.py +38 -0
- PYME/Acquire/Hardware/ids_peak_cam.py +561 -0
- PYME/Acquire/Hardware/ioslave.py +305 -0
- PYME/Acquire/Hardware/lasers.py +292 -0
- PYME/Acquire/Hardware/matchboxLaser.py +58 -0
- PYME/Acquire/Hardware/microscope_adapter.py +104 -0
- PYME/Acquire/Hardware/mpd_picosecond_delayer.py +395 -0
- PYME/Acquire/Hardware/multiview.py +287 -0
- PYME/Acquire/Hardware/olympusix81.py +59 -0
- PYME/Acquire/Hardware/pco/__init__.py +0 -0
- PYME/Acquire/Hardware/pco/pco_cam.py +348 -0
- PYME/Acquire/Hardware/pco/pco_edge_42_lt.py +34 -0
- PYME/Acquire/Hardware/pco/pco_sdk.py +1645 -0
- PYME/Acquire/Hardware/pco/pco_sdk_cam.py +518 -0
- PYME/Acquire/Hardware/pco/pco_sdk_cam_control_panel.py +54 -0
- PYME/Acquire/Hardware/phoxxLaser.py +199 -0
- PYME/Acquire/Hardware/phoxxLaserOLD.py +242 -0
- PYME/Acquire/Hardware/priorLumen.py +102 -0
- PYME/Acquire/Hardware/priorarclampshutter.py +52 -0
- PYME/Acquire/Hardware/setup.py +50 -0
- PYME/Acquire/Hardware/spacenav.py +148 -0
- PYME/Acquire/Hardware/splitter.py +394 -0
- PYME/Acquire/Hardware/thorlabsPiezo.py +98 -0
- PYME/Acquire/Hardware/thorlabs_cam.py +136 -0
- PYME/Acquire/Hardware/thorlabs_mff_flipper.py +400 -0
- PYME/Acquire/Hardware/toptica_ibeam.py +51 -0
- PYME/Acquire/Hardware/uc480/AndorControlFrame.py +308 -0
- PYME/Acquire/Hardware/uc480/__init__.py +27 -0
- PYME/Acquire/Hardware/uc480/uCam480.py +695 -0
- PYME/Acquire/Hardware/uc480/uc480.py +189 -0
- PYME/Acquire/Hardware/uc480/uc480Deprecated.py +87 -0
- PYME/Acquire/Hardware/uc480/uc480_h.py +767 -0
- PYME/Acquire/Hardware/uc480/uc480_h_gen.py +62 -0
- PYME/Acquire/Hardware/uc480/ucCamControlFrame.py +83 -0
- PYME/Acquire/Hardware/ueye.py +702 -0
- PYME/Acquire/PYMEAcquire.py +186 -0
- PYME/Acquire/Protocols/DMDMFM.py +74 -0
- PYME/Acquire/Protocols/__init__.py +22 -0
- PYME/Acquire/Protocols/darkCalibrate.py +56 -0
- PYME/Acquire/Protocols/dual671_470.py +45 -0
- PYME/Acquire/Protocols/dual671_488.py +46 -0
- PYME/Acquire/Protocols/gainCal.py +53 -0
- PYME/Acquire/Protocols/htsms-cal-psf.py +32 -0
- PYME/Acquire/Protocols/htsms-cal-registration.py +52 -0
- PYME/Acquire/Protocols/htsms-flow.py +29 -0
- PYME/Acquire/Protocols/htsms-staggered.py +31 -0
- PYME/Acquire/Protocols/htsms-tile.py +68 -0
- PYME/Acquire/Protocols/htsms-two-color.py +29 -0
- PYME/Acquire/Protocols/htsms-widefield.py +32 -0
- PYME/Acquire/Protocols/paint671.py +61 -0
- PYME/Acquire/Protocols/photoconversion.py +52 -0
- PYME/Acquire/Protocols/photoconversion2.py +55 -0
- PYME/Acquire/Protocols/prebleach488.py +70 -0
- PYME/Acquire/Protocols/prebleach490.py +69 -0
- PYME/Acquire/Protocols/prebleach561.py +72 -0
- PYME/Acquire/Protocols/prebleach561NeomEos2.py +70 -0
- PYME/Acquire/Protocols/prebleach561NeomEos2ND1.py +70 -0
- PYME/Acquire/Protocols/prebleach642.py +70 -0
- PYME/Acquire/Protocols/prebleach671.py +69 -0
- PYME/Acquire/Protocols/prebleach671ND1.py +58 -0
- PYME/Acquire/Protocols/prebleach671ND2.py +57 -0
- PYME/Acquire/Protocols/prebleach671Neo.py +69 -0
- PYME/Acquire/Protocols/recover671.py +62 -0
- PYME/Acquire/Protocols/sequence642_488.py +85 -0
- PYME/Acquire/Protocols/sequence642_561.py +87 -0
- PYME/Acquire/Protocols/shiftfield.py +198 -0
- PYME/Acquire/Protocols/simul488.py +59 -0
- PYME/Acquire/Protocols/simul642.py +63 -0
- PYME/Acquire/Protocols/simul642HTSMS.py +63 -0
- PYME/Acquire/Protocols/simulPA.py +37 -0
- PYME/Acquire/Protocols/simulSIM.py +76 -0
- PYME/Acquire/Protocols/simulStep.py +62 -0
- PYME/Acquire/Protocols/spdscan.py +178 -0
- PYME/Acquire/Protocols/standard470.py +45 -0
- PYME/Acquire/Protocols/standard488.py +47 -0
- PYME/Acquire/Protocols/standard671.py +48 -0
- PYME/Acquire/Protocols/standard671_no532.py +47 -0
- PYME/Acquire/Protocols/standardArclamp.py +46 -0
- PYME/Acquire/Protocols/strip_tile.py +204 -0
- PYME/Acquire/Protocols/tile.py +204 -0
- PYME/Acquire/Protocols/tile3D.py +192 -0
- PYME/Acquire/Protocols/tile671.py +190 -0
- PYME/Acquire/Protocols/tile_triggered.py +189 -0
- PYME/Acquire/Scripts/init.py +232 -0
- PYME/Acquire/Scripts/init_N1_Ti_Exeter_ZIx.py +374 -0
- PYME/Acquire/Scripts/init_N2_Ti_Zyla_lasers.py +290 -0
- PYME/Acquire/Scripts/init_Neo.py +266 -0
- PYME/Acquire/Scripts/init_NeoSim.py +159 -0
- PYME/Acquire/Scripts/init_TIRF.py +232 -0
- PYME/Acquire/Scripts/init_TIRF_Neo.py +242 -0
- PYME/Acquire/Scripts/init_TIRF_NeoO.py +241 -0
- PYME/Acquire/Scripts/init_TIRF_onecam.py +233 -0
- PYME/Acquire/Scripts/init_Ti.py +257 -0
- PYME/Acquire/Scripts/init_UOA_n.py +256 -0
- PYME/Acquire/Scripts/init_UOA_n2.py +246 -0
- PYME/Acquire/Scripts/init_Y1.py +249 -0
- PYME/Acquire/Scripts/init_Zyla.py +260 -0
- PYME/Acquire/Scripts/init_drift_tracking.py +80 -0
- PYME/Acquire/Scripts/init_emccd_basic.py +277 -0
- PYME/Acquire/Scripts/init_htsms.py +277 -0
- PYME/Acquire/Scripts/init_htsms_focus_lock.py +132 -0
- PYME/Acquire/Scripts/init_micrpi.py +45 -0
- PYME/Acquire/Scripts/init_orca.py +70 -0
- PYME/Acquire/Scripts/init_pco.py +49 -0
- PYME/Acquire/Scripts/init_rev.py +74 -0
- PYME/Acquire/Scripts/init_sim100.py +169 -0
- PYME/Acquire/Scripts/init_sim103.py +169 -0
- PYME/Acquire/Scripts/init_sim2.py +211 -0
- PYME/Acquire/Scripts/init_sim50.py +169 -0
- PYME/Acquire/Scripts/init_sim75.py +169 -0
- PYME/Acquire/Scripts/init_sim_drift_tracking.py +166 -0
- PYME/Acquire/Scripts/init_sim_htsms.py +224 -0
- PYME/Acquire/Scripts/init_sim_htsms_n.py +233 -0
- PYME/Acquire/Scripts/init_sim_main.py +229 -0
- PYME/Acquire/Scripts/init_sim_min.py +197 -0
- PYME/Acquire/Scripts/init_sim_rem.py +176 -0
- PYME/Acquire/Scripts/init_smi1.py +110 -0
- PYME/Acquire/Scripts/init_spectro.py +78 -0
- PYME/Acquire/Scripts/init_spim.py +116 -0
- PYME/Acquire/Scripts/init_thorcam.py +62 -0
- PYME/Acquire/Scripts/init_twophoton.py +112 -0
- PYME/Acquire/Scripts/init_uc480.py +262 -0
- PYME/Acquire/Scripts/init_ueye.py +261 -0
- PYME/Acquire/SpoolController.py +958 -0
- PYME/Acquire/Utils/MultiPointScanner.py +80 -0
- PYME/Acquire/Utils/__init__.py +13 -0
- PYME/Acquire/Utils/failsafe.py +157 -0
- PYME/Acquire/Utils/fastTiler.py +153 -0
- PYME/Acquire/Utils/pointScanner.py +496 -0
- PYME/Acquire/Utils/sarcSpacing.py +86 -0
- PYME/Acquire/Utils/strip_tiler.py +93 -0
- PYME/Acquire/Utils/tiler.py +464 -0
- PYME/Acquire/Utils/vibrationAnalysis.py +65 -0
- PYME/Acquire/__init__.py +44 -0
- PYME/Acquire/acquire_client.py +90 -0
- PYME/Acquire/acquire_server.py +316 -0
- PYME/Acquire/acquirebase.py +139 -0
- PYME/Acquire/acquiremainframe.py +716 -0
- PYME/Acquire/acquirewx.py +61 -0
- PYME/Acquire/acquisition_base.py +148 -0
- PYME/Acquire/actions.py +209 -0
- PYME/Acquire/autofocus.py +54 -0
- PYME/Acquire/eventLog.py +95 -0
- PYME/Acquire/event_loop.py +119 -0
- PYME/Acquire/frameWrangler.py +530 -0
- PYME/Acquire/htsms/__init__.py +8 -0
- PYME/Acquire/htsms/rule_ui.py +970 -0
- PYME/Acquire/htsms/rule_ui_v2.py +573 -0
- PYME/Acquire/htsms/tweeter.py +222 -0
- PYME/Acquire/microscope.py +1050 -0
- PYME/Acquire/positionTracker.py +181 -0
- PYME/Acquire/protocol.py +299 -0
- PYME/Acquire/protocol_acquisition.py +404 -0
- PYME/Acquire/sampleInformation.py +591 -0
- PYME/Acquire/sampleInformationDjangoDirect.py +446 -0
- PYME/Acquire/setup.py +52 -0
- PYME/Acquire/stackSettings.py +295 -0
- PYME/Acquire/stage_leveling.py +285 -0
- PYME/Acquire/ui/AnalysisSettingsUI.py +184 -0
- PYME/Acquire/ui/HDFSpoolFrame.py +584 -0
- PYME/Acquire/ui/__init__.py +0 -0
- PYME/Acquire/ui/actionUI.py +892 -0
- PYME/Acquire/ui/focus_lock_gui.py +149 -0
- PYME/Acquire/ui/intensity_trace.py +143 -0
- PYME/Acquire/ui/intsliders.py +222 -0
- PYME/Acquire/ui/lasersliders.py +329 -0
- PYME/Acquire/ui/mpd_picosecond_delay_panel.py +69 -0
- PYME/Acquire/ui/multiview_select.py +77 -0
- PYME/Acquire/ui/positionUI.py +519 -0
- PYME/Acquire/ui/preflight.py +58 -0
- PYME/Acquire/ui/scanner_panel.py +41 -0
- PYME/Acquire/ui/selectCameraPanel.py +46 -0
- PYME/Acquire/ui/seqdialog.py +501 -0
- PYME/Acquire/ui/splashScreen.py +175 -0
- PYME/Acquire/ui/spool_panel.py +830 -0
- PYME/Acquire/ui/tile_panel.py +556 -0
- PYME/Acquire/ui/tilesettingsui.py +91 -0
- PYME/Acquire/ui/voxelSizeDialog.py +149 -0
- PYME/Acquire/webui/__init__.py +36 -0
- PYME/Acquire/webui/ipy.py +361 -0
- PYME/Acquire/webui/static/css/pyme-bootstrap.css +9908 -0
- PYME/Acquire/webui/static/css/pymeacquire.css +85 -0
- PYME/Acquire/webui/static/js/pymeacquire.js +375 -0
- PYME/Acquire/webui/static/js/pzf.js +95 -0
- PYME/Acquire/webui/templates/PYMEAcquire.html +232 -0
- PYME/Acquire/webui/templates/login.html +84 -0
- PYME/Acquire/webui/templates/xtermpage.html +106 -0
- PYME/Acquire/xyztc.py +418 -0
- PYME/Acquire/zScanner.py +287 -0
- PYME/Analysis/BleachProfile/__init__.py +26 -0
- PYME/Analysis/BleachProfile/deMod.py +91 -0
- PYME/Analysis/BleachProfile/fitRecover.py +90 -0
- PYME/Analysis/BleachProfile/intensProf.py +519 -0
- PYME/Analysis/BleachProfile/kinModels.py +507 -0
- PYME/Analysis/BleachProfile/rawIntensity.py +227 -0
- PYME/Analysis/BleachProfile/rollins.py +555 -0
- PYME/Analysis/Colocalisation/__init__.py +27 -0
- PYME/Analysis/Colocalisation/colocScaleDep.py +126 -0
- PYME/Analysis/Colocalisation/correlationCoeffs.py +198 -0
- PYME/Analysis/Colocalisation/distColoc.py +110 -0
- PYME/Analysis/Colocalisation/edtColoc.py +191 -0
- PYME/Analysis/MetaData.py +278 -0
- PYME/Analysis/PSFEst/__init__.py +27 -0
- PYME/Analysis/PSFEst/dec.py +283 -0
- PYME/Analysis/PSFEst/extractImages.py +316 -0
- PYME/Analysis/PSFEst/fit_psf_zernikes.py +194 -0
- PYME/Analysis/PSFEst/psfQuality.py +225 -0
- PYME/Analysis/PSFGen/__init__.py +40 -0
- PYME/Analysis/PSFGen/fourier.py +138 -0
- PYME/Analysis/PSFGen/fourierHNA.py +1108 -0
- PYME/Analysis/PSFGen/fourierHNA2.py +979 -0
- PYME/Analysis/PSFGen/genCRBcurves.py +185 -0
- PYME/Analysis/PSFGen/nijboer_zernike.py +79 -0
- PYME/Analysis/PSFGen/ps_app.cp39-win_amd64.dll.a +0 -0
- PYME/Analysis/PSFGen/ps_app.cp39-win_amd64.pyd +0 -0
- PYME/Analysis/PSFGen/test_ps_app.py +24 -0
- PYME/Analysis/Tracking/__init__.py +3 -0
- PYME/Analysis/Tracking/msd.py +57 -0
- PYME/Analysis/Tracking/trackUtils.py +528 -0
- PYME/Analysis/Tracking/tracking.py +152 -0
- PYME/Analysis/__init__.py +30 -0
- PYME/Analysis/_fithelpers.py +161 -0
- PYME/Analysis/angleFilter.py +287 -0
- PYME/Analysis/annealThresh.py +157 -0
- PYME/Analysis/autoencoder_classifier.py +45 -0
- PYME/Analysis/binAvg.py +144 -0
- PYME/Analysis/composite.py +183 -0
- PYME/Analysis/cramerRao.py +259 -0
- PYME/Analysis/deTile.py +441 -0
- PYME/Analysis/density_filter.py +45 -0
- PYME/Analysis/distributed_pyramid.py +426 -0
- PYME/Analysis/fiducial_matching.py +220 -0
- PYME/Analysis/gen_sCMOS_maps.py +355 -0
- PYME/Analysis/graphing_filters.py +311 -0
- PYME/Analysis/implicitFilter.py +359 -0
- PYME/Analysis/keep_pairs.py +69 -0
- PYME/Analysis/optic_flow.py +108 -0
- PYME/Analysis/piecewise.py +36 -0
- PYME/Analysis/piecewiseMapping.py +304 -0
- PYME/Analysis/piezo_movement_correction.py +153 -0
- PYME/Analysis/points/DeClump/__init__.py +78 -0
- PYME/Analysis/points/DeClump/deClump.cp39-win_amd64.dll.a +0 -0
- PYME/Analysis/points/DeClump/deClump.cp39-win_amd64.pyd +0 -0
- PYME/Analysis/points/DeClump/deClumpGUI.py +87 -0
- PYME/Analysis/points/DeClump/pyDeClump.py +284 -0
- PYME/Analysis/points/DeClump/testClump.py +40 -0
- PYME/Analysis/points/DistHist/__init__.py +25 -0
- PYME/Analysis/points/DistHist/distHist.cp39-win_amd64.dll.a +0 -0
- PYME/Analysis/points/DistHist/distHist.cp39-win_amd64.pyd +0 -0
- PYME/Analysis/points/DistHist/distHistThreaded.py +71 -0
- PYME/Analysis/points/DistHist/setup.py +54 -0
- PYME/Analysis/points/EdgeDB/__init__.py +24 -0
- PYME/Analysis/points/EdgeDB/edgeDB.cp39-win_amd64.dll.a +0 -0
- PYME/Analysis/points/EdgeDB/edgeDB.cp39-win_amd64.pyd +0 -0
- PYME/Analysis/points/EdgeDB/edgeTest.py +66 -0
- PYME/Analysis/points/EdgeDB/edges.py +102 -0
- PYME/Analysis/points/EdgeDB/segment.py +75 -0
- PYME/Analysis/points/EdgeDB/setup.py +54 -0
- PYME/Analysis/points/QuadTree/QTrend.py +232 -0
- PYME/Analysis/points/QuadTree/__init__.py +25 -0
- PYME/Analysis/points/QuadTree/pointQT.py +227 -0
- PYME/Analysis/points/QuadTree/pointQTF.py +254 -0
- PYME/Analysis/points/QuadTree/qtUtils.py +36 -0
- PYME/Analysis/points/QuadTree/rendQT.py +118 -0
- PYME/Analysis/points/SoftRend/__init__.py +24 -0
- PYME/Analysis/points/SoftRend/setup.py +61 -0
- PYME/Analysis/points/SoftRend/testTetrahedra.py +41 -0
- PYME/Analysis/points/SoftRend/triRend.cp39-win_amd64.dll.a +0 -0
- PYME/Analysis/points/SoftRend/triRend.cp39-win_amd64.pyd +0 -0
- PYME/Analysis/points/__init__.py +3 -0
- PYME/Analysis/points/arcfit/__init__.py +1 -0
- PYME/Analysis/points/arcfit/arcmf.cp39-win_amd64.dll.a +0 -0
- PYME/Analysis/points/arcfit/arcmf.cp39-win_amd64.pyd +0 -0
- PYME/Analysis/points/arcfit/setup.py +51 -0
- PYME/Analysis/points/astigmatism/__init__.py +0 -0
- PYME/Analysis/points/astigmatism/astigTools.py +338 -0
- PYME/Analysis/points/astigmatism/astiglookup.cp39-win_amd64.dll.a +0 -0
- PYME/Analysis/points/astigmatism/astiglookup.cp39-win_amd64.pyd +0 -0
- PYME/Analysis/points/astigmatism/setup.py +54 -0
- PYME/Analysis/points/cluster_morphology.py +199 -0
- PYME/Analysis/points/coordinate_tools.py +278 -0
- PYME/Analysis/points/features/__init__.py +0 -0
- PYME/Analysis/points/features/metal.py +46 -0
- PYME/Analysis/points/features/shaders/vect_feat_3d.metal +49 -0
- PYME/Analysis/points/fiducials.py +142 -0
- PYME/Analysis/points/gen3DTriangs.py +796 -0
- PYME/Analysis/points/moments.py +143 -0
- PYME/Analysis/points/multiview.py +458 -0
- PYME/Analysis/points/objectMeasure.py +206 -0
- PYME/Analysis/points/qpaint.py +97 -0
- PYME/Analysis/points/rings.py +372 -0
- PYME/Analysis/points/ripleys.py +427 -0
- PYME/Analysis/points/segmentLL.py +134 -0
- PYME/Analysis/points/setup.py +56 -0
- PYME/Analysis/points/spherical_harmonics.py +909 -0
- PYME/Analysis/points/surfit.py +829 -0
- PYME/Analysis/points/tCluster.py +75 -0
- PYME/Analysis/points/traveling_salesperson/__init__.py +0 -0
- PYME/Analysis/points/traveling_salesperson/queue_opt.py +117 -0
- PYME/Analysis/points/traveling_salesperson/sectioned_two_opt.py +327 -0
- PYME/Analysis/points/traveling_salesperson/setup.py +40 -0
- PYME/Analysis/points/traveling_salesperson/sort.py +78 -0
- PYME/Analysis/points/traveling_salesperson/two_opt.py +189 -0
- PYME/Analysis/points/traveling_salesperson/two_opt_utils.cp39-win_amd64.dll.a +0 -0
- PYME/Analysis/points/traveling_salesperson/two_opt_utils.cp39-win_amd64.pyd +0 -0
- PYME/Analysis/points/traveling_salesperson/two_opt_utils.pyx +41 -0
- PYME/Analysis/points/twoColour.py +572 -0
- PYME/Analysis/points/twoColourPlot.py +107 -0
- PYME/Analysis/processLogger.py +129 -0
- PYME/Analysis/profile_extraction.py +72 -0
- PYME/Analysis/setup.py +60 -0
- PYME/Analysis/splitting.py +372 -0
- PYME/Analysis/svmSegment.py +214 -0
- PYME/Analysis/thresholding.py +192 -0
- PYME/Analysis/tile_pyramid.py +938 -0
- PYME/Analysis/widefieldify.py +54 -0
- PYME/DSView/DisplayOptionsPanel.py +503 -0
- PYME/DSView/LUT/__init__.py +33 -0
- PYME/DSView/LUT/lut.cp39-win_amd64.dll.a +0 -0
- PYME/DSView/LUT/lut.cp39-win_amd64.pyd +0 -0
- PYME/DSView/LUT/setup.py +54 -0
- PYME/DSView/OpenSequenceDialog.py +83 -0
- PYME/DSView/OverlaysPanel.py +111 -0
- PYME/DSView/__init__.py +32 -0
- PYME/DSView/arrayViewPanel.py +1035 -0
- PYME/DSView/displayOptions.py +453 -0
- PYME/DSView/displaySettingsPanel.py +271 -0
- PYME/DSView/dsviewer.py +542 -0
- PYME/DSView/eventLogViewer.py +805 -0
- PYME/DSView/fitInfo.py +486 -0
- PYME/DSView/htmlServe.py +72 -0
- PYME/DSView/logparser.py +100 -0
- PYME/DSView/modules/LMAnalysis.py +1053 -0
- PYME/DSView/modules/LMDisplay.py +194 -0
- PYME/DSView/modules/__init__.py +162 -0
- PYME/DSView/modules/_base.py +39 -0
- PYME/DSView/modules/annotation.py +725 -0
- PYME/DSView/modules/arrayView.py +71 -0
- PYME/DSView/modules/blobFinding.py +455 -0
- PYME/DSView/modules/blobMeasure.py +1093 -0
- PYME/DSView/modules/camera_maps.py +38 -0
- PYME/DSView/modules/coloc.py +414 -0
- PYME/DSView/modules/composite.py +715 -0
- PYME/DSView/modules/convnet.py +24 -0
- PYME/DSView/modules/cropping.py +133 -0
- PYME/DSView/modules/dark_and_flatfield.py +31 -0
- PYME/DSView/modules/deconvolution.py +499 -0
- PYME/DSView/modules/eventView.py +80 -0
- PYME/DSView/modules/extractBlobs.py +46 -0
- PYME/DSView/modules/fastGraphPanel.py +85 -0
- PYME/DSView/modules/filtering.py +335 -0
- PYME/DSView/modules/flowView.py +268 -0
- PYME/DSView/modules/fourierRingCorrelation.py +172 -0
- PYME/DSView/modules/gl_image_view.py +12 -0
- PYME/DSView/modules/graphViewPanel.py +272 -0
- PYME/DSView/modules/measure/__init__.py +1 -0
- PYME/DSView/modules/measure/filterPan.py +239 -0
- PYME/DSView/modules/metadataView.py +28 -0
- PYME/DSView/modules/multithreshold.py +98 -0
- PYME/DSView/modules/neuroglancer.py +129 -0
- PYME/DSView/modules/object_tagging.py +157 -0
- PYME/DSView/modules/particleTracking.py +463 -0
- PYME/DSView/modules/playback.py +256 -0
- PYME/DSView/modules/prebleachExtraction.py +75 -0
- PYME/DSView/modules/profileFitting.py +137 -0
- PYME/DSView/modules/profilePlotting.py +408 -0
- PYME/DSView/modules/projections.py +48 -0
- PYME/DSView/modules/psfExtraction.py +570 -0
- PYME/DSView/modules/psfGeneration.py +138 -0
- PYME/DSView/modules/psfTools.py +661 -0
- PYME/DSView/modules/pupilTools.py +204 -0
- PYME/DSView/modules/pupilView.py +139 -0
- PYME/DSView/modules/recipes.py +266 -0
- PYME/DSView/modules/redimension.py +75 -0
- PYME/DSView/modules/segmentation.py +192 -0
- PYME/DSView/modules/sheetView.py +24 -0
- PYME/DSView/modules/shell.py +39 -0
- PYME/DSView/modules/shiftfield_estimation.py +433 -0
- PYME/DSView/modules/sparkprepare.py +94 -0
- PYME/DSView/modules/splitter.py +148 -0
- PYME/DSView/modules/synchronise.py +64 -0
- PYME/DSView/modules/templates/astigCal.html +42 -0
- PYME/DSView/modules/templates/measureView.html +69 -0
- PYME/DSView/modules/templates/measureView2.html +48 -0
- PYME/DSView/modules/templates/measureView3.html +98 -0
- PYME/DSView/modules/templates/trackView.html +139 -0
- PYME/DSView/modules/templates/tracksOverview.html +21 -0
- PYME/DSView/modules/tiling.py +147 -0
- PYME/DSView/modules/unmixing.py +148 -0
- PYME/DSView/modules/vis3D.py +320 -0
- PYME/DSView/modules/visgui.py +163 -0
- PYME/DSView/modules/webview.py +14 -0
- PYME/DSView/overlays.py +295 -0
- PYME/DSView/scrolledImagePanel.py +188 -0
- PYME/DSView/setup.py +53 -0
- PYME/DSView/splashScreen.py +158 -0
- PYME/DSView/voxSizeDialog.py +84 -0
- PYME/Deconv/__init__.py +35 -0
- PYME/Deconv/beadGen.py +55 -0
- PYME/Deconv/dec.py +659 -0
- PYME/Deconv/decTask.py +65 -0
- PYME/Deconv/decThread.py +113 -0
- PYME/Deconv/dec_test.py +47 -0
- PYME/Deconv/deconvDialogs.py +417 -0
- PYME/Deconv/fftwWisdom.py +62 -0
- PYME/Deconv/richardsonLucy.py +141 -0
- PYME/Deconv/richardsonLucyMV.py +151 -0
- PYME/Deconv/richardsonLucyMVM.py +218 -0
- PYME/Deconv/test_block_dec.py +46 -0
- PYME/Deconv/tq_block_dec.py +331 -0
- PYME/Deconv/wiener.py +163 -0
- PYME/IO/DataSources/AlignDataSource.py +91 -0
- PYME/IO/DataSources/ArrayDataSource.py +260 -0
- PYME/IO/DataSources/BGSDataSource.py +353 -0
- PYME/IO/DataSources/BaseDataSource.py +457 -0
- PYME/IO/DataSources/BioformatsDataSource.py +178 -0
- PYME/IO/DataSources/BufferedDataSource.py +99 -0
- PYME/IO/DataSources/ClusterPZFDataSource.py +124 -0
- PYME/IO/DataSources/ConcatenatedDataSource.py +56 -0
- PYME/IO/DataSources/CropDataSource.py +243 -0
- PYME/IO/DataSources/DcimgDataSource.py +54 -0
- PYME/IO/DataSources/ElectronsPerSecondDataSource.py +61 -0
- PYME/IO/DataSources/FlatFieldDataSource.py +77 -0
- PYME/IO/DataSources/HDFDataSource.py +160 -0
- PYME/IO/DataSources/HTTPDataSource.py +80 -0
- PYME/IO/DataSources/ImageSeriesDataSource.py +123 -0
- PYME/IO/DataSources/MultiviewDataSource.py +99 -0
- PYME/IO/DataSources/OBFDataSource.py +67 -0
- PYME/IO/DataSources/RandomDataSource.py +23 -0
- PYME/IO/DataSources/SupertileDatasource.py +148 -0
- PYME/IO/DataSources/TQDataSource.py +41 -0
- PYME/IO/DataSources/TiffDataSource.py +193 -0
- PYME/IO/DataSources/TileDataSource.py +91 -0
- PYME/IO/DataSources/UnsplitDataSource.py +92 -0
- PYME/IO/DataSources/__init__.py +59 -0
- PYME/IO/FileUtils/IJLut.py +43 -0
- PYME/IO/FileUtils/RawToHdf5.py +105 -0
- PYME/IO/FileUtils/SPAD.py +54 -0
- PYME/IO/FileUtils/TiffSeqToHdf5.py +87 -0
- PYME/IO/FileUtils/__init__.py +24 -0
- PYME/IO/FileUtils/compHdf.py +39 -0
- PYME/IO/FileUtils/fileID.py +246 -0
- PYME/IO/FileUtils/fnlGen.py +40 -0
- PYME/IO/FileUtils/freeSpace.py +59 -0
- PYME/IO/FileUtils/h5-thumbnailer.py +85 -0
- PYME/IO/FileUtils/h5ExFrames.py +98 -0
- PYME/IO/FileUtils/h5ToTiffSeries.py +50 -0
- PYME/IO/FileUtils/h5r-thumbnailer.py +118 -0
- PYME/IO/FileUtils/h5rFormatDef.py +99 -0
- PYME/IO/FileUtils/h5rToTxt.py +77 -0
- PYME/IO/FileUtils/nameUtils.py +300 -0
- PYME/IO/FileUtils/obf_support.py +538 -0
- PYME/IO/FileUtils/ply.py +147 -0
- PYME/IO/FileUtils/readSpeckle.py +78 -0
- PYME/IO/FileUtils/readTiff.py +64 -0
- PYME/IO/FileUtils/saveTiffStack.py +137 -0
- PYME/IO/FileUtils/setup.py +36 -0
- PYME/IO/FileUtils/sf-thumbnailer.py +76 -0
- PYME/IO/FileUtils/stl.py +44 -0
- PYME/IO/FileUtils/thumbnailDatabase.py +104 -0
- PYME/IO/HTTPSpooler_v2.py +141 -0
- PYME/IO/MetaDataHandler.py +1072 -0
- PYME/IO/PZFFormat.py +375 -0
- PYME/IO/Spooler.py +279 -0
- PYME/IO/__init__.py +12 -0
- PYME/IO/acquisition_backends.py +353 -0
- PYME/IO/buffer_helpers.cp39-win_amd64.dll.a +0 -0
- PYME/IO/buffer_helpers.cp39-win_amd64.pyd +0 -0
- PYME/IO/buffer_helpers.pyx +190 -0
- PYME/IO/buffers.py +291 -0
- PYME/IO/clusterDuplication.py +204 -0
- PYME/IO/clusterExport.py +152 -0
- PYME/IO/clusterGlob.py +108 -0
- PYME/IO/clusterIO.py +1076 -0
- PYME/IO/clusterListing.py +232 -0
- PYME/IO/clusterResults.py +206 -0
- PYME/IO/clusterUpload.py +49 -0
- PYME/IO/cluster_directory.py +419 -0
- PYME/IO/cluster_streaming.py +216 -0
- PYME/IO/compatibility.py +12 -0
- PYME/IO/countdir/__init__.py +5 -0
- PYME/IO/countdir/setup.py +58 -0
- PYME/IO/csv_flavours.py +251 -0
- PYME/IO/dataExporter.py +470 -0
- PYME/IO/dataWrap.py +108 -0
- PYME/IO/dcimg.py +167 -0
- PYME/IO/events.py +161 -0
- PYME/IO/h5File.py +148 -0
- PYME/IO/h5rFile.py +323 -0
- PYME/IO/image.py +1447 -0
- PYME/IO/load_psf.py +26 -0
- PYME/IO/pyme_h5ls.py +58 -0
- PYME/IO/ragged.py +138 -0
- PYME/IO/rgb_image.py +94 -0
- PYME/IO/tabular.py +1338 -0
- PYME/IO/testClusterSpooling.py +199 -0
- PYME/IO/unifiedIO.py +301 -0
- PYME/LMVis/Extras/QPobjectSegment.py +220 -0
- PYME/LMVis/Extras/__init__.py +55 -0
- PYME/LMVis/Extras/animation.py +359 -0
- PYME/LMVis/Extras/annotation.py +78 -0
- PYME/LMVis/Extras/clusterAnalysis.py +460 -0
- PYME/LMVis/Extras/dockedPanel.py +69 -0
- PYME/LMVis/Extras/extra_layers.py +373 -0
- PYME/LMVis/Extras/fiducial.py +230 -0
- PYME/LMVis/Extras/flagZMotionArtifacts.py +60 -0
- PYME/LMVis/Extras/fusionUtils.py +9 -0
- PYME/LMVis/Extras/multiColourAnalysis.py +103 -0
- PYME/LMVis/Extras/multiviewMapping.py +489 -0
- PYME/LMVis/Extras/objectMeasurements.py +246 -0
- PYME/LMVis/Extras/particleTracking.py +272 -0
- PYME/LMVis/Extras/perFrameVariable.py +77 -0
- PYME/LMVis/Extras/photophysics.py +72 -0
- PYME/LMVis/Extras/pointSetGeneration.py +232 -0
- PYME/LMVis/Extras/pointwiseColoc.py +54 -0
- PYME/LMVis/Extras/saved_views.py +125 -0
- PYME/LMVis/Extras/scaleBox.py +115 -0
- PYME/LMVis/Extras/sequentialSpecies.py +125 -0
- PYME/LMVis/Extras/setBGImage.py +74 -0
- PYME/LMVis/Extras/shiftmapGenerator.py +138 -0
- PYME/LMVis/Extras/showShortcuts.py +69 -0
- PYME/LMVis/Extras/snapshot.py +135 -0
- PYME/LMVis/Extras/spherical_harmonics.py +98 -0
- PYME/LMVis/Extras/subsets.py +15 -0
- PYME/LMVis/Extras/surface_fitting.py +52 -0
- PYME/LMVis/Extras/temperaturePlot.py +53 -0
- PYME/LMVis/Extras/vibration.py +112 -0
- PYME/LMVis/VisGUI.py +506 -0
- PYME/LMVis/__init__.py +39 -0
- PYME/LMVis/colourFilterGUI.py +77 -0
- PYME/LMVis/colourPanel.py +491 -0
- PYME/LMVis/displayPane.py +462 -0
- PYME/LMVis/dyeRatios.py +116 -0
- PYME/LMVis/genImageDialog.py +298 -0
- PYME/LMVis/gl_offScreenHandler.py +134 -0
- PYME/LMVis/gl_render.py +1302 -0
- PYME/LMVis/gl_render3D.py +1453 -0
- PYME/LMVis/gl_render3D_shaders.py +1213 -0
- PYME/LMVis/glcanvas_core.py +1157 -0
- PYME/LMVis/imageView.py +752 -0
- PYME/LMVis/imageView2.py +372 -0
- PYME/LMVis/importTextDialog.py +342 -0
- PYME/LMVis/layer_panel.py +231 -0
- PYME/LMVis/layers/AxesOverlayLayer.py +126 -0
- PYME/LMVis/layers/LUTOverlayLayer.py +346 -0
- PYME/LMVis/layers/OverlayLayer.py +46 -0
- PYME/LMVis/layers/ScaleBarOverlayLayer.py +97 -0
- PYME/LMVis/layers/ScaleBoxOverlayLayer.py +181 -0
- PYME/LMVis/layers/SelectionOverlayLayer.py +124 -0
- PYME/LMVis/layers/__init__.py +53 -0
- PYME/LMVis/layers/base.py +319 -0
- PYME/LMVis/layers/image_layer.py +363 -0
- PYME/LMVis/layers/labels.py +186 -0
- PYME/LMVis/layers/layer_defaults.py +97 -0
- PYME/LMVis/layers/mesh.py +378 -0
- PYME/LMVis/layers/octree.py +194 -0
- PYME/LMVis/layers/pointcloud.py +372 -0
- PYME/LMVis/layers/quiver.py +271 -0
- PYME/LMVis/layers/text.py +250 -0
- PYME/LMVis/layers/tracks.py +309 -0
- PYME/LMVis/mv_math.py +78 -0
- PYME/LMVis/objectDarkMeasure.py +120 -0
- PYME/LMVis/pipeline.py +1227 -0
- PYME/LMVis/pipelineView.py +115 -0
- PYME/LMVis/pointSettingsPanel.py +135 -0
- PYME/LMVis/progGraph.py +59 -0
- PYME/LMVis/quadTreeSettings.py +90 -0
- PYME/LMVis/rendGauss.py +158 -0
- PYME/LMVis/renderers.py +576 -0
- PYME/LMVis/sessionpaths.py +136 -0
- PYME/LMVis/setup.py +39 -0
- PYME/LMVis/setup_exe.py +71 -0
- PYME/LMVis/shader_programs/DefaultShaderProgram.py +149 -0
- PYME/LMVis/shader_programs/GLProgram.py +119 -0
- PYME/LMVis/shader_programs/GouraudShaderProgram.py +157 -0
- PYME/LMVis/shader_programs/PointSpriteShaderProgram.py +163 -0
- PYME/LMVis/shader_programs/ShaderProgramFactory.py +54 -0
- PYME/LMVis/shader_programs/TesselShaderProgram.py +47 -0
- PYME/LMVis/shader_programs/WireFrameShaderProgram.py +50 -0
- PYME/LMVis/shader_programs/__init__.py +20 -0
- PYME/LMVis/shader_programs/oit_compositor.py +23 -0
- PYME/LMVis/shader_programs/shader_loader.py +84 -0
- PYME/LMVis/shader_programs/shader_program.py +168 -0
- PYME/LMVis/shader_programs/shaders/bigflatpoints_fs.glsl +16 -0
- PYME/LMVis/shader_programs/shaders/bigpoints_gs.glsl +40 -0
- PYME/LMVis/shader_programs/shaders/bigpointsprites_fs.glsl +20 -0
- PYME/LMVis/shader_programs/shaders/bigspheres_fs.glsl +53 -0
- PYME/LMVis/shader_programs/shaders/compose_fs.glsl +41 -0
- PYME/LMVis/shader_programs/shaders/compose_vs.glsl +25 -0
- PYME/LMVis/shader_programs/shaders/default_fs.glsl +27 -0
- PYME/LMVis/shader_programs/shaders/default_vs.glsl +88 -0
- PYME/LMVis/shader_programs/shaders/flatpoints_fs.glsl +27 -0
- PYME/LMVis/shader_programs/shaders/gouraud_flatpoints_fs.glsl +30 -0
- PYME/LMVis/shader_programs/shaders/gouraud_fs.glsl +26 -0
- PYME/LMVis/shader_programs/shaders/gouraud_oit_fs.glsl +68 -0
- PYME/LMVis/shader_programs/shaders/gouraud_vs.glsl +135 -0
- PYME/LMVis/shader_programs/shaders/image_fs.glsl +60 -0
- PYME/LMVis/shader_programs/shaders/image_vs.glsl +79 -0
- PYME/LMVis/shader_programs/shaders/phong_fs.glsl +43 -0
- PYME/LMVis/shader_programs/shaders/phong_vs.glsl +45 -0
- PYME/LMVis/shader_programs/shaders/pointsprites_fs.glsl +33 -0
- PYME/LMVis/shader_programs/shaders/pointsprites_vs.glsl +77 -0
- PYME/LMVis/shader_programs/shaders/spheres_fs.glsl +102 -0
- PYME/LMVis/shader_programs/shaders/tessel_fs.glsl +23 -0
- PYME/LMVis/shader_programs/shaders/tessel_vs.glsl +37 -0
- PYME/LMVis/shader_programs/shaders/text_fs.glsl +42 -0
- PYME/LMVis/shader_programs/shaders/text_vs.glsl +84 -0
- PYME/LMVis/shader_programs/shaders/widelines_fs.glsl +19 -0
- PYME/LMVis/shader_programs/shaders/widelines_gs.glsl +56 -0
- PYME/LMVis/shader_programs/shaders/widelines_vs.glsl +51 -0
- PYME/LMVis/statusLog.py +57 -0
- PYME/LMVis/triBlobs.py +142 -0
- PYME/LMVis/view_clipping_pane.py +429 -0
- PYME/LMVis/views.py +275 -0
- PYME/LMVis/visCore.py +1005 -0
- PYME/LMVis/visHelpers.py +880 -0
- PYME/LMVis/visHelpersMin.py +230 -0
- PYME/LMVis/workspaceTree.py +238 -0
- PYME/__init__.py +22 -0
- PYME/cluster/HTTPDataServer.py +1063 -0
- PYME/cluster/HTTPRulePusher.py +382 -0
- PYME/cluster/HTTPTaskPusher.py +377 -0
- PYME/cluster/PYMERuleNodeServer.py +192 -0
- PYME/cluster/PYMERuleServer.py +109 -0
- PYME/cluster/__init__.py +0 -0
- PYME/cluster/clusterUI/accounts/__init__.py +0 -0
- PYME/cluster/clusterUI/accounts/admin.py +85 -0
- PYME/cluster/clusterUI/accounts/forms.py +8 -0
- PYME/cluster/clusterUI/accounts/migrations/0001_initial.py +31 -0
- PYME/cluster/clusterUI/accounts/migrations/__init__.py +0 -0
- PYME/cluster/clusterUI/accounts/models.py +44 -0
- PYME/cluster/clusterUI/accounts/templates/accounts/user_form.html +13 -0
- PYME/cluster/clusterUI/accounts/templates/registration/initial_complete.html +6 -0
- PYME/cluster/clusterUI/accounts/templates/registration/initial_confirm.html +13 -0
- PYME/cluster/clusterUI/accounts/templates/registration/initial_done.html +7 -0
- PYME/cluster/clusterUI/accounts/templates/registration/verification.html +2 -0
- PYME/cluster/clusterUI/accounts/templates/registration/verification_subject.txt +1 -0
- PYME/cluster/clusterUI/accounts/urls.py +19 -0
- PYME/cluster/clusterUI/accounts/views.py +36 -0
- PYME/cluster/clusterUI/clusterUI/__init__.py +0 -0
- PYME/cluster/clusterUI/clusterUI/settings.py +147 -0
- PYME/cluster/clusterUI/clusterUI/urls.py +31 -0
- PYME/cluster/clusterUI/clusterUI/wsgi.py +16 -0
- PYME/cluster/clusterUI/clusterbrowser/__init__.py +0 -0
- PYME/cluster/clusterUI/clusterbrowser/admin.py +3 -0
- PYME/cluster/clusterUI/clusterbrowser/apps.py +7 -0
- PYME/cluster/clusterUI/clusterbrowser/migrations/__init__.py +0 -0
- PYME/cluster/clusterUI/clusterbrowser/models.py +5 -0
- PYME/cluster/clusterUI/clusterbrowser/templates/base.html +129 -0
- PYME/cluster/clusterUI/clusterbrowser/templates/clusterbrowser/dirlisting.html +231 -0
- PYME/cluster/clusterUI/clusterbrowser/templates/clusterbrowser/form_new_folder.html +18 -0
- PYME/cluster/clusterUI/clusterbrowser/templates/clusterbrowser/form_upload_file.html +17 -0
- PYME/cluster/clusterUI/clusterbrowser/templates/clusterbrowser/lightlisting.html +25 -0
- PYME/cluster/clusterUI/clusterbrowser/templates/registration/login.html +38 -0
- PYME/cluster/clusterUI/clusterbrowser/urls.py +10 -0
- PYME/cluster/clusterUI/clusterbrowser/views.py +148 -0
- PYME/cluster/clusterUI/clusterstatus/__init__.py +0 -0
- PYME/cluster/clusterUI/clusterstatus/admin.py +3 -0
- PYME/cluster/clusterUI/clusterstatus/apps.py +7 -0
- PYME/cluster/clusterUI/clusterstatus/migrations/__init__.py +0 -0
- PYME/cluster/clusterUI/clusterstatus/models.py +5 -0
- PYME/cluster/clusterUI/clusterstatus/templates/clusterstatus/load_content.html +29 -0
- PYME/cluster/clusterUI/clusterstatus/templates/clusterstatus/queue_info.html +28 -0
- PYME/cluster/clusterUI/clusterstatus/templates/clusterstatus/queue_info_content.html +50 -0
- PYME/cluster/clusterUI/clusterstatus/templates/clusterstatus/status_dash.html +29 -0
- PYME/cluster/clusterUI/clusterstatus/templates/clusterstatus/status_dash_content.html +90 -0
- PYME/cluster/clusterUI/clusterstatus/urls.py +9 -0
- PYME/cluster/clusterUI/clusterstatus/views.py +69 -0
- PYME/cluster/clusterUI/clusterui_tornado.py +117 -0
- PYME/cluster/clusterUI/deploy.py +62 -0
- PYME/cluster/clusterUI/localization/__init__.py +0 -0
- PYME/cluster/clusterUI/localization/admin.py +3 -0
- PYME/cluster/clusterUI/localization/apps.py +7 -0
- PYME/cluster/clusterUI/localization/migrations/__init__.py +0 -0
- PYME/cluster/clusterUI/localization/models.py +5 -0
- PYME/cluster/clusterUI/localization/templates/localization/settings_form.html +67 -0
- PYME/cluster/clusterUI/localization/urls.py +10 -0
- PYME/cluster/clusterUI/localization/views.py +170 -0
- PYME/cluster/clusterUI/manage.py +17 -0
- PYME/cluster/clusterUI/recipes/__init__.py +0 -0
- PYME/cluster/clusterUI/recipes/admin.py +3 -0
- PYME/cluster/clusterUI/recipes/migrations/__init__.py +0 -0
- PYME/cluster/clusterUI/recipes/models.py +3 -0
- PYME/cluster/clusterUI/recipes/templates/recipes/extra_inputs.html +35 -0
- PYME/cluster/clusterUI/recipes/templates/recipes/form_recipe.html +82 -0
- PYME/cluster/clusterUI/recipes/templates/recipes/input_list.html +7 -0
- PYME/cluster/clusterUI/recipes/templates/recipes/recipe_editor.html +28 -0
- PYME/cluster/clusterUI/recipes/templates/recipes/recipe_editor_common.html +46 -0
- PYME/cluster/clusterUI/recipes/templates/recipes/recipe_editrun.html +93 -0
- PYME/cluster/clusterUI/recipes/templates/recipes/recipe_standalone.html +100 -0
- PYME/cluster/clusterUI/recipes/templates/recipes/recipe_template.html +109 -0
- PYME/cluster/clusterUI/recipes/urls.py +17 -0
- PYME/cluster/clusterUI/recipes/views.py +109 -0
- PYME/cluster/cluster_of_one.py +200 -0
- PYME/cluster/dataserver_wsgi.py +615 -0
- PYME/cluster/distribution.py +71 -0
- PYME/cluster/rulenodeserver.py +487 -0
- PYME/cluster/rules.py +979 -0
- PYME/cluster/ruleserver.py +1106 -0
- PYME/cluster/status.py +101 -0
- PYME/cluster/taskWorkerHTTP.py +522 -0
- PYME/cluster/webdav.py +1102 -0
- PYME/config.py +659 -0
- PYME/contrib/TextCtrlAutoComplete.py +582 -0
- PYME/contrib/__init__.py +7 -0
- PYME/contrib/aniso/__init__.py +2 -0
- PYME/contrib/aniso/aniso.py +268 -0
- PYME/contrib/auiFloatBook.py +94 -0
- PYME/contrib/congrid.py +127 -0
- PYME/contrib/dispatch/__init__.py +19 -0
- PYME/contrib/dispatch/dispatcher.py +289 -0
- PYME/contrib/gohlke/__init__.py +1 -0
- PYME/contrib/gohlke/_tifffile.cp39-win_amd64.dll.a +0 -0
- PYME/contrib/gohlke/_tifffile.cp39-win_amd64.pyd +0 -0
- PYME/contrib/gohlke/czifile.py +1289 -0
- PYME/contrib/gohlke/fcsfiles.py +514 -0
- PYME/contrib/gohlke/setup.py +54 -0
- PYME/contrib/gohlke/tifffile.py +3095 -0
- PYME/contrib/listctrlMixins.py +896 -0
- PYME/contrib/lzw.py +838 -0
- PYME/contrib/pad/__init__.py +13 -0
- PYME/contrib/pad/info_pad.py +18 -0
- PYME/contrib/pad/pad.py +670 -0
- PYME/contrib/setup.py +38 -0
- PYME/contrib/wxPlotPanel.py +137 -0
- PYME/experimental/SimReconstruction.py +49 -0
- PYME/experimental/__init__.pxd +0 -0
- PYME/experimental/__init__.py +4 -0
- PYME/experimental/_octree.cp39-win_amd64.dll.a +0 -0
- PYME/experimental/_octree.cp39-win_amd64.pyd +0 -0
- PYME/experimental/_octree.pyx +477 -0
- PYME/experimental/_treap.cp39-win_amd64.dll.a +0 -0
- PYME/experimental/_treap.cp39-win_amd64.pyd +0 -0
- PYME/experimental/_treap.pyx +267 -0
- PYME/experimental/_triangle_mesh.cp39-win_amd64.dll.a +0 -0
- PYME/experimental/_triangle_mesh.cp39-win_amd64.pyd +0 -0
- PYME/experimental/_triangle_mesh.pxd +149 -0
- PYME/experimental/_triangle_mesh.pyx +2787 -0
- PYME/experimental/aqavg.py +40 -0
- PYME/experimental/dcimgFileChucker.py +375 -0
- PYME/experimental/dcimgSpoolShim.py +174 -0
- PYME/experimental/dcimg_chuck_test.py +78 -0
- PYME/experimental/dual_marching_cubes.py +801 -0
- PYME/experimental/dual_marching_cubes_v2.py +645 -0
- PYME/experimental/expectationMaximisation.py +298 -0
- PYME/experimental/func_octree.cp39-win_amd64.dll.a +0 -0
- PYME/experimental/func_octree.cp39-win_amd64.pyd +0 -0
- PYME/experimental/func_octree.pyx +381 -0
- PYME/experimental/fusionRadial.py +520 -0
- PYME/experimental/fusionUtils.py +522 -0
- PYME/experimental/isosurface.py +147 -0
- PYME/experimental/labview_spooling_hacks.py +48 -0
- PYME/experimental/marching_cubes.py +811 -0
- PYME/experimental/marching_tetrahedra.py +343 -0
- PYME/experimental/modified_marching_cubes.py +1245 -0
- PYME/experimental/music.py +25 -0
- PYME/experimental/octree.py +188 -0
- PYME/experimental/pSpaceMap.py +34 -0
- PYME/experimental/pointFitConfoc.py +112 -0
- PYME/experimental/scanner_control.py +107 -0
- PYME/experimental/setup.py +109 -0
- PYME/experimental/spark.py +31 -0
- PYME/experimental/tcHist.py +71 -0
- PYME/experimental/treap.py +262 -0
- PYME/experimental/triangle_mesh.py +2287 -0
- PYME/experimental/triangle_mesh_utils.cp39-win_amd64.dll.a +0 -0
- PYME/experimental/triangle_mesh_utils.cp39-win_amd64.pyd +0 -0
- PYME/experimental/triangle_utils.py +87 -0
- PYME/experimental/triangular_mesh.py +2255 -0
- PYME/experimental/zMotionArtifactUtils.py +55 -0
- PYME/localization/FitFactories/AstigGaussFitFR.py +175 -0
- PYME/localization/FitFactories/AstigGaussGPUFitFR.py +326 -0
- PYME/localization/FitFactories/BeadConvolvedAstigGaussFit.py +206 -0
- PYME/localization/FitFactories/ChecksumFR.py +82 -0
- PYME/localization/FitFactories/ChecksumGPUFR.py +213 -0
- PYME/localization/FitFactories/ChecksumMultifitSR.py +86 -0
- PYME/localization/FitFactories/ConfocCOIR.py +93 -0
- PYME/localization/FitFactories/Dumbell3DFitR.py +193 -0
- PYME/localization/FitFactories/DumbellFitR.py +163 -0
- PYME/localization/FitFactories/FFBase.py +403 -0
- PYME/localization/FitFactories/Gauss3DFitR.py +213 -0
- PYME/localization/FitFactories/GaussFitConstrR.py +177 -0
- PYME/localization/FitFactories/GaussMultifitLinesR.py +351 -0
- PYME/localization/FitFactories/GaussMultifitR.py +326 -0
- PYME/localization/FitFactories/GaussMultifitSR.py +373 -0
- PYME/localization/FitFactories/InterpFitR.py +236 -0
- PYME/localization/FitFactories/InterpFitWFR.py +111 -0
- PYME/localization/FitFactories/Interpolators/CSInterpolator.py +148 -0
- PYME/localization/FitFactories/Interpolators/CubeSInterpolatorP.py +121 -0
- PYME/localization/FitFactories/Interpolators/CubicSplineInterpolator.py +69 -0
- PYME/localization/FitFactories/Interpolators/LinearInterpolator.py +135 -0
- PYME/localization/FitFactories/Interpolators/LinearPInterpolatorP.py +95 -0
- PYME/localization/FitFactories/Interpolators/__init__.py +33 -0
- PYME/localization/FitFactories/Interpolators/baseInterpolator.py +202 -0
- PYME/localization/FitFactories/LatFitCOIR.py +82 -0
- PYME/localization/FitFactories/LatGaussFitFR.py +220 -0
- PYME/localization/FitFactories/LatObjFindFR.py +85 -0
- PYME/localization/FitFactories/LatPSFFitR.py +142 -0
- PYME/localization/FitFactories/MultiviewFitInterpNR.py +400 -0
- PYME/localization/FitFactories/PRInterpFitQR.py +192 -0
- PYME/localization/FitFactories/PRInterpFitR.py +223 -0
- PYME/localization/FitFactories/ROIExtractNR.py +93 -0
- PYME/localization/FitFactories/SpecGaussFitFR.py +174 -0
- PYME/localization/FitFactories/SplitterFitCOIR.py +142 -0
- PYME/localization/FitFactories/SplitterFitFNR.py +312 -0
- PYME/localization/FitFactories/SplitterFitFusionR.py +318 -0
- PYME/localization/FitFactories/SplitterFitInterpBNR.py +357 -0
- PYME/localization/FitFactories/SplitterFitInterpNR.py +343 -0
- PYME/localization/FitFactories/SplitterFitScavNR.py +352 -0
- PYME/localization/FitFactories/SplitterMultifitSR.py +410 -0
- PYME/localization/FitFactories/SplitterObjFindR.py +194 -0
- PYME/localization/FitFactories/SplitterROIExtractNR.py +91 -0
- PYME/localization/FitFactories/SplitterShiftEstFR.py +230 -0
- PYME/localization/FitFactories/__init__.py +103 -0
- PYME/localization/FitFactories/fitCommon.py +195 -0
- PYME/localization/FitFactories/zEstimators/__init__.py +29 -0
- PYME/localization/FitFactories/zEstimators/astigEstimator.py +173 -0
- PYME/localization/FitFactories/zEstimators/biplaneEstimator.py +209 -0
- PYME/localization/FitFactories/zEstimators/genericDualEstimator.py +232 -0
- PYME/localization/FitFactories/zEstimators/genericEstimator.py +224 -0
- PYME/localization/FitFactories/zEstimators/priEstimator.py +255 -0
- PYME/localization/MetaDataEdit.py +543 -0
- PYME/localization/Test/30_9_series_A_1.sf +0 -0
- PYME/localization/Test/PRI.md +45 -0
- PYME/localization/Test/PRI_qr.md +52 -0
- PYME/localization/Test/PRI_r.md +52 -0
- PYME/localization/Test/__init__.py +22 -0
- PYME/localization/Test/astig.md +50 -0
- PYME/localization/Test/astigCOI.md +50 -0
- PYME/localization/Test/astig_gauss.md +52 -0
- PYME/localization/Test/astig_pe.md +50 -0
- PYME/localization/Test/astig_splitter.md +66 -0
- PYME/localization/Test/astig_splitterCOI.md +67 -0
- PYME/localization/Test/astig_splitterQ.md +66 -0
- PYME/localization/Test/astig_theory.md +50 -0
- PYME/localization/Test/astig_theory.psf +0 -0
- PYME/localization/Test/astig_theory.tif +0 -0
- PYME/localization/Test/beads1.psf +0 -0
- PYME/localization/Test/beads1.tif +0 -0
- PYME/localization/Test/biplane_splitter.md +75 -0
- PYME/localization/Test/biplane_splitter2.md +103 -0
- PYME/localization/Test/biplane_splitter3.md +115 -0
- PYME/localization/Test/defoc.md +48 -0
- PYME/localization/Test/dumbell_3d.md +52 -0
- PYME/localization/Test/fitTestJig.py +172 -0
- PYME/localization/Test/fitTestJigSCMOS.py +487 -0
- PYME/localization/Test/fitTestJigWC.py +225 -0
- PYME/localization/Test/gauss.md +50 -0
- PYME/localization/Test/gaussCOI.md +50 -0
- PYME/localization/Test/pri_pe.md +50 -0
- PYME/localization/Test/pri_theory.md +51 -0
- PYME/localization/Test/pri_theory.psf +0 -0
- PYME/localization/Test/pri_theory.tif +0 -0
- PYME/localization/Test/psf_astig.psf +0 -0
- PYME/localization/Test/psf_astig.tif +0 -0
- PYME/localization/Test/psf_astig_bg_d.psf +0 -0
- PYME/localization/Test/psf_astig_bg_d.tif +0 -0
- PYME/localization/Test/psf_astig_pe.psf +0 -0
- PYME/localization/Test/psf_astig_pe.tif +0 -0
- PYME/localization/Test/psf_decon.psf +0 -0
- PYME/localization/Test/psf_decon.tif +0 -0
- PYME/localization/Test/psf_decon_pe.psf +0 -0
- PYME/localization/Test/psf_decon_pe.tif +0 -0
- PYME/localization/Test/psf_guess.psf +0 -0
- PYME/localization/Test/splitter.md +63 -0
- PYME/localization/Test/splitter_scav.md +63 -0
- PYME/localization/Test/test.psf +0 -0
- PYME/localization/Test/test.tif +0 -0
- PYME/localization/Test/test_decon.psf +0 -0
- PYME/localization/Test/test_decon.tif +0 -0
- PYME/localization/Test/test_pe.psf +0 -0
- PYME/localization/Test/test_pe.tif +0 -0
- PYME/localization/Test/wf_theory.psf +0 -0
- PYME/localization/Test/wf_theory2.psf +0 -0
- PYME/localization/__init__.py +17 -0
- PYME/localization/autopsf/__init__.py +1 -0
- PYME/localization/autopsf/autopsf.py +486 -0
- PYME/localization/autopsf/roifit.py +310 -0
- PYME/localization/cInterp/__init__.py +24 -0
- PYME/localization/cInterp/cInterp.cp39-win_amd64.dll.a +0 -0
- PYME/localization/cInterp/cInterp.cp39-win_amd64.pyd +0 -0
- PYME/localization/cInterp/setup.py +54 -0
- PYME/localization/cModels/__init__.py +24 -0
- PYME/localization/cModels/gauss_app.cp39-win_amd64.dll.a +0 -0
- PYME/localization/cModels/gauss_app.cp39-win_amd64.pyd +0 -0
- PYME/localization/ofind.py +444 -0
- PYME/localization/ofind3d.py +306 -0
- PYME/localization/ofind_nofilt.py +128 -0
- PYME/localization/ofind_pri.py +478 -0
- PYME/localization/ofind_split.py +399 -0
- PYME/localization/ofind_xcorr.py +351 -0
- PYME/localization/ofind_xcorr_fw.py +441 -0
- PYME/localization/remFitBuf.py +657 -0
- PYME/localization/setup.py +56 -0
- PYME/localization/splitting.py +240 -0
- PYME/localization/twist.py +60 -0
- PYME/misc/TiSettings.py +36 -0
- PYME/misc/TiffImagePlugin.py +838 -0
- PYME/misc/VolProj.py +144 -0
- PYME/misc/__init__.py +25 -0
- PYME/misc/aligned_array.py +10 -0
- PYME/misc/aniso.py +29 -0
- PYME/misc/big_sur_fix.py +20 -0
- PYME/misc/check_for_updates.py +139 -0
- PYME/misc/colormaps.py +199 -0
- PYME/misc/colorsys.py +201 -0
- PYME/misc/computerName.py +33 -0
- PYME/misc/coverslipGeometries.py +60 -0
- PYME/misc/cython_numpy_monkey.py +40 -0
- PYME/misc/depGraph.py +406 -0
- PYME/misc/dirSize.py +31 -0
- PYME/misc/diskCleanup.py +64 -0
- PYME/misc/djangoRecarray.py +57 -0
- PYME/misc/django_widgets.py +27 -0
- PYME/misc/editgrid.py +101 -0
- PYME/misc/eventSpy.py +122 -0
- PYME/misc/exceptions.py +30 -0
- PYME/misc/facsPlot.py +89 -0
- PYME/misc/fbpIcons.py +90 -0
- PYME/misc/fftw_compat.py +28 -0
- PYME/misc/findCycles.py +91 -0
- PYME/misc/fortran_interrupt_defeat.py +43 -0
- PYME/misc/glassModel.py +64 -0
- PYME/misc/hash32.py +41 -0
- PYME/misc/hillcurve.py +88 -0
- PYME/misc/hybrid_ns.py +84 -0
- PYME/misc/kdFit.py +72 -0
- PYME/misc/locate.py +10 -0
- PYME/misc/memUsage.py +65 -0
- PYME/misc/memmap.py +52 -0
- PYME/misc/mock_ctypes.py +28 -0
- PYME/misc/mock_traits.py +59 -0
- PYME/misc/mock_traitsui.py +29 -0
- PYME/misc/pyme_zeroconf.py +287 -0
- PYME/misc/pyro_tracebacks.py +32 -0
- PYME/misc/read_agf.py +605 -0
- PYME/misc/sffake.py +16 -0
- PYME/misc/snells.py +71 -0
- PYME/misc/sqlite_ns.py +132 -0
- PYME/misc/sqlitendarray.py +56 -0
- PYME/misc/taskDef.py +44 -0
- PYME/misc/tempDB.py +56 -0
- PYME/misc/wxThread.py +33 -0
- PYME/misc/zemax.py +259 -0
- PYME/misc/zernike.py +151 -0
- PYME/pyme_warnings.py +70 -0
- PYME/recipes/Recipes/STEDDeconvolution.yaml +14 -0
- PYME/recipes/Recipes/STEDMinistacks.yaml +15 -0
- PYME/recipes/Recipes/STED_COP3.yaml +25 -0
- PYME/recipes/Recipes/blobMeas.yaml +19 -0
- PYME/recipes/Recipes/blobMeas2.yaml +37 -0
- PYME/recipes/Recipes/blobMeasSR.yaml +66 -0
- PYME/recipes/Recipes/coloc.yaml +43 -0
- PYME/recipes/Recipes/coloc_roi_masked.yaml +46 -0
- PYME/recipes/Recipes/multiblob.yaml +38 -0
- PYME/recipes/Recipes/pre_particleTracking.yaml +30 -0
- PYME/recipes/Recipes/segmentAndMeasureLoci.yaml +41 -0
- PYME/recipes/__init__.py +6 -0
- PYME/recipes/acquisition.py +158 -0
- PYME/recipes/bakeshop.py +32 -0
- PYME/recipes/base.py +1393 -0
- PYME/recipes/batchProcess.py +147 -0
- PYME/recipes/filters.py +394 -0
- PYME/recipes/fudges.py +41 -0
- PYME/recipes/graphing.py +108 -0
- PYME/recipes/html_recipe_editor.py +90 -0
- PYME/recipes/localisations.py +1386 -0
- PYME/recipes/machine_learning.py +286 -0
- PYME/recipes/measurement.py +1062 -0
- PYME/recipes/modules.py +50 -0
- PYME/recipes/multiview.py +435 -0
- PYME/recipes/output.py +667 -0
- PYME/recipes/pointcloud.py +510 -0
- PYME/recipes/processing.py +2954 -0
- PYME/recipes/pyramid.py +206 -0
- PYME/recipes/recipe.py +965 -0
- PYME/recipes/recipeGui.py +1029 -0
- PYME/recipes/recipeLayout.py +499 -0
- PYME/recipes/runRecipe.py +140 -0
- PYME/recipes/setup.py +37 -0
- PYME/recipes/simulation.py +91 -0
- PYME/recipes/skfilters.py +143 -0
- PYME/recipes/surface_fitting.py +776 -0
- PYME/recipes/tablefilters.py +275 -0
- PYME/recipes/tracking.py +343 -0
- PYME/recipes/traits.py +157 -0
- PYME/recipes/vertical_recipe_display.py +373 -0
- PYME/resources/__init__.py +23 -0
- PYME/resources/config_template/distributor.yaml +14 -0
- PYME/resources/config_template/nodeserver.yaml +15 -0
- PYME/resources/icons/LUT.png +0 -0
- PYME/resources/icons/YSM_Shield.png +0 -0
- PYME/resources/icons/YSM_logo.png +0 -0
- PYME/resources/icons/arrow.png +0 -0
- PYME/resources/icons/crosshairs.png +0 -0
- PYME/resources/icons/line_select.png +0 -0
- PYME/resources/icons/logo_fmhs.png +0 -0
- PYME/resources/icons/media-playback-pause.png +0 -0
- PYME/resources/icons/media-playback-start.png +0 -0
- PYME/resources/icons/media-skip-backward.png +0 -0
- PYME/resources/icons/media-skip-forward.png +0 -0
- PYME/resources/icons/mesh.png +0 -0
- PYME/resources/icons/mesh.svg +28 -0
- PYME/resources/icons/pmacquire.icns +0 -0
- PYME/resources/icons/pmacquire.ico +0 -0
- PYME/resources/icons/pmanal.icns +0 -0
- PYME/resources/icons/pmanal.ico +0 -0
- PYME/resources/icons/pmvis.icns +0 -0
- PYME/resources/icons/pmvis.ico +0 -0
- PYME/resources/icons/points.png +0 -0
- PYME/resources/icons/points.svg +16 -0
- PYME/resources/icons/pymeLogo.png +0 -0
- PYME/resources/icons/rect_select.png +0 -0
- PYME/resources/icons/squiggle_select.png +0 -0
- PYME/resources/icons/text3800.icns +0 -0
- PYME/resources/icons/text3800.ico +0 -0
- PYME/resources/icons/text3800.png +0 -0
- PYME/resources/icons/text3800.tif +0 -0
- PYME/resources/icons/text5377.icns +0 -0
- PYME/resources/icons/text5377.ico +0 -0
- PYME/resources/icons/text5377.png +0 -0
- PYME/resources/icons/tracks.png +0 -0
- PYME/resources/icons/tracks.svg +19 -0
- PYME/resources/icons/view-front.png +0 -0
- PYME/resources/icons/view-home.png +0 -0
- PYME/resources/icons/view-right.png +0 -0
- PYME/resources/icons/view-top.png +0 -0
- PYME/resources/test_datasets/README.md +8 -0
- PYME/resources/test_datasets/t_im.tif +0 -0
- PYME/resources/test_datasets/test_csv.csv +4282 -0
- PYME/resources/test_datasets/test_hdf.hdf +0 -0
- PYME/resources/web/rule_inline.html +21 -0
- PYME/resources/web/ruleserver.html +75 -0
- PYME/resources/web/static/bootstrap.min.js +7 -0
- PYME/resources/web/static/cluster.css +137 -0
- PYME/resources/web/static/css/bootstrap-theme.css +587 -0
- PYME/resources/web/static/css/bootstrap-theme.min.css +6 -0
- PYME/resources/web/static/css/bootstrap.css +6757 -0
- PYME/resources/web/static/css/bootstrap.min.css +6 -0
- PYME/resources/web/static/css/flat_design_colors_full.css +306 -0
- PYME/resources/web/static/css/recipe_editor.css +106 -0
- PYME/resources/web/static/dashboard.css +106 -0
- PYME/resources/web/static/fileselector.js +77 -0
- PYME/resources/web/static/fonts/glyphicons-halflings-regular.eot +0 -0
- PYME/resources/web/static/fonts/glyphicons-halflings-regular.svg +288 -0
- PYME/resources/web/static/fonts/glyphicons-halflings-regular.ttf +0 -0
- PYME/resources/web/static/fonts/glyphicons-halflings-regular.woff +0 -0
- PYME/resources/web/static/fonts/glyphicons-halflings-regular.woff2 +0 -0
- PYME/resources/web/static/images/osd_flat/LICENSE.txt +116 -0
- PYME/resources/web/static/images/osd_flat/README.md +9 -0
- PYME/resources/web/static/images/osd_flat/fullpage_grouphover.png +0 -0
- PYME/resources/web/static/images/osd_flat/fullpage_hover.png +0 -0
- PYME/resources/web/static/images/osd_flat/fullpage_pressed.png +0 -0
- PYME/resources/web/static/images/osd_flat/fullpage_rest.png +0 -0
- PYME/resources/web/static/images/osd_flat/home_grouphover.png +0 -0
- PYME/resources/web/static/images/osd_flat/home_hover.png +0 -0
- PYME/resources/web/static/images/osd_flat/home_pressed.png +0 -0
- PYME/resources/web/static/images/osd_flat/home_rest.png +0 -0
- PYME/resources/web/static/images/osd_flat/next_grouphover.png +0 -0
- PYME/resources/web/static/images/osd_flat/next_hover.png +0 -0
- PYME/resources/web/static/images/osd_flat/next_pressed.png +0 -0
- PYME/resources/web/static/images/osd_flat/next_rest.png +0 -0
- PYME/resources/web/static/images/osd_flat/previous_grouphover.png +0 -0
- PYME/resources/web/static/images/osd_flat/previous_hover.png +0 -0
- PYME/resources/web/static/images/osd_flat/previous_pressed.png +0 -0
- PYME/resources/web/static/images/osd_flat/previous_rest.png +0 -0
- PYME/resources/web/static/images/osd_flat/rotateleft_grouphover.png +0 -0
- PYME/resources/web/static/images/osd_flat/rotateleft_hover.png +0 -0
- PYME/resources/web/static/images/osd_flat/rotateleft_pressed.png +0 -0
- PYME/resources/web/static/images/osd_flat/rotateleft_rest.png +0 -0
- PYME/resources/web/static/images/osd_flat/rotateright_grouphover.png +0 -0
- PYME/resources/web/static/images/osd_flat/rotateright_hover.png +0 -0
- PYME/resources/web/static/images/osd_flat/rotateright_pressed.png +0 -0
- PYME/resources/web/static/images/osd_flat/rotateright_rest.png +0 -0
- PYME/resources/web/static/images/osd_flat/zoomin_grouphover.png +0 -0
- PYME/resources/web/static/images/osd_flat/zoomin_hover.png +0 -0
- PYME/resources/web/static/images/osd_flat/zoomin_pressed.png +0 -0
- PYME/resources/web/static/images/osd_flat/zoomin_rest.png +0 -0
- PYME/resources/web/static/images/osd_flat/zoomout_grouphover.png +0 -0
- PYME/resources/web/static/images/osd_flat/zoomout_hover.png +0 -0
- PYME/resources/web/static/images/osd_flat/zoomout_pressed.png +0 -0
- PYME/resources/web/static/images/osd_flat/zoomout_rest.png +0 -0
- PYME/resources/web/static/jigna-vue-bare.js +1395 -0
- PYME/resources/web/static/jquery.min.js +2 -0
- PYME/resources/web/static/jstree.min.js +6 -0
- PYME/resources/web/static/openSeadragonGL.js +102 -0
- PYME/resources/web/static/openseadragon-svg-overlay.js +103 -0
- PYME/resources/web/static/openseadragon-viewerinputhook.min.js +6 -0
- PYME/resources/web/static/openseadragon.min.js +9 -0
- PYME/resources/web/static/recipe_editor.js +119 -0
- PYME/resources/web/static/shaders/fragment/lut.glsl +20 -0
- PYME/resources/web/static/shaders/fragment/none.glsl +17 -0
- PYME/resources/web/static/shaders/fragment/outline.glsl +43 -0
- PYME/resources/web/static/shaders/fragment/rect.glsl +7 -0
- PYME/resources/web/static/shaders/fragment/sobel3.glsl +71 -0
- PYME/resources/web/static/shaders/fragment/white.glsl +4 -0
- PYME/resources/web/static/shaders/vertex/rect.glsl +22 -0
- PYME/resources/web/static/shaders/vertex/square.glsl +9 -0
- PYME/resources/web/static/utils.js +3 -0
- PYME/resources/web/static/viaWebGL.js +217 -0
- PYME/setup.py +109 -0
- PYME/setup_exe.py +57 -0
- PYME/simulation/__init__.py +0 -0
- PYME/simulation/locify.py +319 -0
- PYME/simulation/pointsets.py +279 -0
- PYME/simulation/wormlike.py +99 -0
- PYME/simulation/wormlike2.py +198 -0
- PYME/simulation/wormlike3.py +197 -0
- PYME/simulation/wormlike_curled.py +104 -0
- PYME/tileviewer/__init__.py +0 -0
- PYME/tileviewer/templates/roi_list.html +12 -0
- PYME/tileviewer/templates/tileviewer.html +247 -0
- PYME/tileviewer/tileviewer.py +207 -0
- PYME/ui/AUIFrame.py +279 -0
- PYME/ui/MetadataTree.py +469 -0
- PYME/ui/__init__.py +4 -0
- PYME/ui/about_dlg.py +29 -0
- PYME/ui/autoFoldPanel.py +643 -0
- PYME/ui/cascading_layout.py +45 -0
- PYME/ui/crop_dialog.py +145 -0
- PYME/ui/custom_traits_editors.py +508 -0
- PYME/ui/editFilterDialog.py +80 -0
- PYME/ui/editList.py +40 -0
- PYME/ui/fastGraph.py +240 -0
- PYME/ui/filterPane.py +348 -0
- PYME/ui/histLimits.py +543 -0
- PYME/ui/layerFoldPanel.py +232 -0
- PYME/ui/manualFoldPanel.py +870 -0
- PYME/ui/mytimer.py +116 -0
- PYME/ui/patch_traitsui.py +151 -0
- PYME/ui/progress.py +160 -0
- PYME/ui/recArrayView.py +145 -0
- PYME/ui/selection.py +71 -0
- PYME/ui/shell.py +37 -0
- PYME/ui/traitsui_constants.py +91 -0
- PYME/ui/wx_compat.py +43 -0
- PYME/update_version.py +159 -0
- PYME/util/__init__.py +3 -0
- PYME/util/authenticate.py +164 -0
- PYME/util/execfile.py +21 -0
- PYME/util/fProfile/__init__.py +1 -0
- PYME/util/fProfile/convertProfile.py +117 -0
- PYME/util/fProfile/fProfile.py +162 -0
- PYME/util/fProfile/html/404.html +60 -0
- PYME/util/fProfile/html/css/main.css +258 -0
- PYME/util/fProfile/html/css/normalize.css +427 -0
- PYME/util/fProfile/html/css/normalize.min.css +1 -0
- PYME/util/fProfile/html/index.html +64 -0
- PYME/util/fProfile/html/js/main.js +492 -0
- PYME/util/fProfile/html/js/plugins.js +24 -0
- PYME/util/fProfile/html/js/vendor/crossfilter.min.js +1 -0
- PYME/util/fProfile/html/js/vendor/jquery-1.11.2.min.js +4 -0
- PYME/util/fProfile/html/js/vendor/modernizr-2.8.3.min.js +4 -0
- PYME/util/fProfile/html/js/vendor/tinycolor-min.js +4 -0
- PYME/util/fProfile/viewProfile.py +30 -0
- PYME/util/install_dependencies.py +95 -0
- PYME/util/log_verbosity.py +11 -0
- PYME/util/mProfile/__init__.py +1 -0
- PYME/util/mProfile/colorize_db_t.py +297 -0
- PYME/util/mProfile/mProfile.py +164 -0
- PYME/util/mProfile/p.py +101 -0
- PYME/util/mProfile/tProfile.py +165 -0
- PYME/util/pymelauncher.py +47 -0
- PYME/util/shmarray/__init__.py +0 -0
- PYME/util/shmarray/shmTest.py +74 -0
- PYME/util/shmarray/shmarray.py +165 -0
- PYME/util/webframework.py +365 -0
- PYME/version.py +65 -0
- python_microscopy-25.6.5.dist-info/METADATA +68 -0
- python_microscopy-25.6.5.dist-info/RECORD +1277 -0
- python_microscopy-25.6.5.dist-info/WHEEL +4 -0
PYME/IO/image.py
ADDED
|
@@ -0,0 +1,1447 @@
|
|
|
1
|
+
#!/usr/bin/python
|
|
2
|
+
##################
|
|
3
|
+
# image.py
|
|
4
|
+
#
|
|
5
|
+
# Copyright David Baddeley, 2011
|
|
6
|
+
# d.baddeley@auckland.ac.nz
|
|
7
|
+
#
|
|
8
|
+
# This program is free software: you can redistribute it and/or modify
|
|
9
|
+
# it under the terms of the GNU General Public License as published by
|
|
10
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
11
|
+
# (at your option) any later version.
|
|
12
|
+
#
|
|
13
|
+
# This program is distributed in the hope that it will be useful,
|
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16
|
+
# GNU General Public License for more details.
|
|
17
|
+
#
|
|
18
|
+
# You should have received a copy of the GNU General Public License
|
|
19
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
20
|
+
#
|
|
21
|
+
##################
|
|
22
|
+
#try:
|
|
23
|
+
# print 'trying to import javabridge & bioformats'
|
|
24
|
+
# import javabridge
|
|
25
|
+
# print 'imported javabridge'
|
|
26
|
+
# import bioformats
|
|
27
|
+
# print 'imported bioformats'
|
|
28
|
+
# javabridge.start_vm(class_path=bioformats.JARS, run_headless=True)
|
|
29
|
+
# print 'started java VM'
|
|
30
|
+
#except:
|
|
31
|
+
# pass
|
|
32
|
+
|
|
33
|
+
from __future__ import print_function
|
|
34
|
+
|
|
35
|
+
import logging
|
|
36
|
+
import os
|
|
37
|
+
import weakref
|
|
38
|
+
|
|
39
|
+
import numpy
|
|
40
|
+
from six import string_types
|
|
41
|
+
|
|
42
|
+
from PYME.Analysis import MetaData
|
|
43
|
+
from PYME.IO import MetaDataHandler
|
|
44
|
+
from PYME.IO import dataWrap
|
|
45
|
+
from PYME.IO.DataSources import BufferedDataSource, BaseDataSource, ConcatenatedDataSource
|
|
46
|
+
from PYME.IO.FileUtils.nameUtils import getRelFilename
|
|
47
|
+
from PYME.IO.compatibility import np_load_legacy
|
|
48
|
+
|
|
49
|
+
logger = logging.getLogger(__name__)
|
|
50
|
+
import warnings
|
|
51
|
+
import PYME.pyme_warnings
|
|
52
|
+
|
|
53
|
+
class PYMEDeprecationWarning(DeprecationWarning):
|
|
54
|
+
pass
|
|
55
|
+
|
|
56
|
+
warnings.simplefilter('once',PYMEDeprecationWarning)
|
|
57
|
+
|
|
58
|
+
#VS = namedtuple('VS', 'x,y,z')
|
|
59
|
+
#Alias for backwards compatibility
|
|
60
|
+
VS = MetaDataHandler.VoxelSize
|
|
61
|
+
|
|
62
|
+
class ImageBounds(object):
|
|
63
|
+
def __init__(self, x0, y0, x1, y1, z0=0, z1=0):
|
|
64
|
+
self.x0 = x0
|
|
65
|
+
self.y0 = y0
|
|
66
|
+
self.x1 = x1
|
|
67
|
+
self.y1 = y1
|
|
68
|
+
self.z0 = z0
|
|
69
|
+
self.z1 = z1
|
|
70
|
+
|
|
71
|
+
@classmethod
|
|
72
|
+
def estimateFromSource(cls, ds):
|
|
73
|
+
if 'z' in ds.keys():
|
|
74
|
+
return cls(ds['x'].min(), ds['y'].min(), ds['x'].max(), ds['y'].max(), ds['z'].min(), ds['z'].max())
|
|
75
|
+
else:
|
|
76
|
+
return cls(ds['x'].min(),ds['y'].min(),ds['x'].max(), ds['y'].max())
|
|
77
|
+
|
|
78
|
+
def width(self):
|
|
79
|
+
return self.x1 - self.x0
|
|
80
|
+
|
|
81
|
+
def height(self):
|
|
82
|
+
return self.y1 - self.y0
|
|
83
|
+
|
|
84
|
+
@property
|
|
85
|
+
def bounds(self):
|
|
86
|
+
return self.x0, self.y0, self.x1, self.y1, self.z0, self.z1
|
|
87
|
+
|
|
88
|
+
@classmethod
|
|
89
|
+
def extractFromMetadata(cls, mdh):
|
|
90
|
+
x0 = 0
|
|
91
|
+
y0 = 0
|
|
92
|
+
|
|
93
|
+
vx, vy, _ = mdh.voxelsize_nm
|
|
94
|
+
x1 = mdh['Camera.ROIWidth'] * vx
|
|
95
|
+
y1 = mdh['Camera.ROIHeight'] * vx
|
|
96
|
+
|
|
97
|
+
if 'Splitter' in mdh.getOrDefault('Analysis.FitModule', ''):
|
|
98
|
+
if 'Splitter.Channel0ROI' in mdh.getEntryNames():
|
|
99
|
+
rx0, ry0, rw, rh = mdh['Splitter.Channel0ROI']
|
|
100
|
+
x1 = rw * vx
|
|
101
|
+
y1 = rh * vx
|
|
102
|
+
else:
|
|
103
|
+
y1 = y1 / 2
|
|
104
|
+
|
|
105
|
+
return cls(x0, y0, x1, y1)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
@property
|
|
109
|
+
def extent(self):
|
|
110
|
+
# TODO - is this really needed / something we should do here?
|
|
111
|
+
return self.x1 - self.x0, self.y1 - self.y0, self.z1 - self.z0
|
|
112
|
+
|
|
113
|
+
def __repr__(self):
|
|
114
|
+
# FIXME - requires python >3.6
|
|
115
|
+
return f'ImageBounds(x0={self.x0}, y0={self.y0}, x1={self.x1}, y1={self.y1}, z0={self.z0}, z1 = {self.z1}) instance at 0x{id(self):0X}'
|
|
116
|
+
|
|
117
|
+
lastdir = ''
|
|
118
|
+
|
|
119
|
+
class _DefaultDict(dict):
|
|
120
|
+
"""dictionary which returns a default value (0) for items not in the list"""
|
|
121
|
+
def __init__(self, *args):
|
|
122
|
+
dict.__init__(self, *args)
|
|
123
|
+
|
|
124
|
+
def __getitem__(self, index):
|
|
125
|
+
try:
|
|
126
|
+
return dict.__getitem__(self, index)
|
|
127
|
+
except KeyError:
|
|
128
|
+
return 0
|
|
129
|
+
|
|
130
|
+
#keep track of open images - to allow compositing of images etc ... without
|
|
131
|
+
#relying on some GUI or global magic to keep track of windows
|
|
132
|
+
#use a weakref dictionary so that they still get garbage collected when they
|
|
133
|
+
#cease to be used elsewhere
|
|
134
|
+
openImages = weakref.WeakValueDictionary()
|
|
135
|
+
|
|
136
|
+
#this is going to determine the numbering of each new image - images are
|
|
137
|
+
#created with a stub name e.g. 'Untitled Image', or 'Filter result', followed
|
|
138
|
+
#by an incrementing index - this dictionary stores the current index for each
|
|
139
|
+
#stub. If a stub hasn't been used yet, the index defaults to zero.
|
|
140
|
+
nUntitled = _DefaultDict()
|
|
141
|
+
|
|
142
|
+
class FileSelectionError(Exception):
|
|
143
|
+
"""Custom error type to raise when we cancel file selection"""
|
|
144
|
+
pass
|
|
145
|
+
|
|
146
|
+
class ImageStack(object):
|
|
147
|
+
""" An Image Stack. This is the core PYME image type and wraps around the various different supported file formats.
|
|
148
|
+
|
|
149
|
+
This is a essentially a wrapper of the image data and any ascociated
|
|
150
|
+
metadata. The class can be given a ndarray like* data source, or
|
|
151
|
+
alternatively supports loading from file, or from a PYME task queue
|
|
152
|
+
URI, in which case individual slices will be fetched from the server
|
|
153
|
+
as required.
|
|
154
|
+
|
|
155
|
+
For details on the file type support, see the Load method.
|
|
156
|
+
|
|
157
|
+
You should provide one of the 'data' or 'filename' parmeters,
|
|
158
|
+
with all other parameters being optional.
|
|
159
|
+
|
|
160
|
+
Parameters
|
|
161
|
+
----------
|
|
162
|
+
data
|
|
163
|
+
Image data. Something that supports ndarray like slicing and exposes
|
|
164
|
+
a .shape parameter, something implementing the
|
|
165
|
+
PYME.IO.DataSources interface, or a list of either
|
|
166
|
+
of the above. Dimensionality can be between 1 and 4, with
|
|
167
|
+
the dimensions being interpreted as x, y, z/t, colour.
|
|
168
|
+
A mangled (will support slicing, but not necessarily other array
|
|
169
|
+
operations) version of the data will be stored as the .data
|
|
170
|
+
member of the class.
|
|
171
|
+
|
|
172
|
+
mdh : something derived from PYME.IO.MetaDataHandler.MDHandlerBase
|
|
173
|
+
Image metadata. If None, and empty one will be created.
|
|
174
|
+
|
|
175
|
+
filename : str
|
|
176
|
+
filename of the data to load (see Load), or PYME queue identifier
|
|
177
|
+
|
|
178
|
+
queueURI : str
|
|
179
|
+
PYRO URI of the task server. This exists to optionally speed up
|
|
180
|
+
loading from a queue by eliminating the PYRO nameserver
|
|
181
|
+
lookup. The queue name itself should be passed in the filename,
|
|
182
|
+
with a leading QUEUE://.
|
|
183
|
+
|
|
184
|
+
events : list / array
|
|
185
|
+
An array of time series events (TODO - more doc)
|
|
186
|
+
|
|
187
|
+
haveGUI : bool
|
|
188
|
+
Whether we have a wx GUI available, so that we can
|
|
189
|
+
display dialogs asking for, e.g. a file name if no
|
|
190
|
+
data or filename is supplied, or for missing metadata
|
|
191
|
+
entries
|
|
192
|
+
|
|
193
|
+
Attributes
|
|
194
|
+
----------
|
|
195
|
+
data : PYME.IO.DataSources data source.
|
|
196
|
+
This is an object which can be sliced as though it was a numpy array, and which yields a numpy array as a
|
|
197
|
+
result of the slicing. It differs from an array in that it loads data lazily (i.e. individual chunks might
|
|
198
|
+
still be on disk, and are only loaded and assembled into an array when sliced). Slicing is the only array
|
|
199
|
+
operation permitted.
|
|
200
|
+
|
|
201
|
+
mdh : PYME.IO.MetdataHandler metadata source
|
|
202
|
+
This contains image metadata. It behaves like a dictionary, and individual metadata entries can be accessed by key.
|
|
203
|
+
|
|
204
|
+
events : list/array
|
|
205
|
+
Any events which occured during image acquisition
|
|
206
|
+
|
|
207
|
+
voxelsize : 3-tuple (float)
|
|
208
|
+
The image voxel size in nm
|
|
209
|
+
|
|
210
|
+
pixelsize : float
|
|
211
|
+
The pixelsize in nm (shortcut for voxelsize[0])
|
|
212
|
+
|
|
213
|
+
names : list of str
|
|
214
|
+
The channel names
|
|
215
|
+
|
|
216
|
+
origin : tuple of float
|
|
217
|
+
position, in nm, of the top-left pixel in the image from the camera origin. Useful for lining up images taken
|
|
218
|
+
with different ROIs.
|
|
219
|
+
|
|
220
|
+
"""
|
|
221
|
+
def __init__(self, data = None, mdh = None, filename = None, queueURI = None, events = [], titleStub='Untitled Image', haveGUI=False, load_prompt=None):
|
|
222
|
+
|
|
223
|
+
global nUntitled
|
|
224
|
+
self._data = data #image data
|
|
225
|
+
self.mdh = mdh #metadata (a MetaDataHandler class)
|
|
226
|
+
self.events = events #events
|
|
227
|
+
|
|
228
|
+
self.queueURI = queueURI
|
|
229
|
+
|
|
230
|
+
if filename is not None and os.path.exists(filename): # is a real filename on disk, rather than a schemified one e.g. pyme-cluster://
|
|
231
|
+
# make the filename fully resolved rather than relative to the directory we launched from (if we launched with a partial filename)
|
|
232
|
+
# TODO: does this belong here, or should this logic be elsewhere
|
|
233
|
+
filename = os.path.abspath(filename)
|
|
234
|
+
|
|
235
|
+
self.filename = filename
|
|
236
|
+
|
|
237
|
+
self.haveGUI = haveGUI
|
|
238
|
+
|
|
239
|
+
#default 'mode' / image type - see PYME/DSView/modules/__init__.py
|
|
240
|
+
self.mode = 'default'
|
|
241
|
+
|
|
242
|
+
self.saved = False
|
|
243
|
+
self.volatile = False #is the data likely to change and need refreshing?
|
|
244
|
+
|
|
245
|
+
#support for specifying metadata as filename
|
|
246
|
+
if isinstance(mdh, string_types):#os.path.exists(mdh):
|
|
247
|
+
self.mdh = None
|
|
248
|
+
self._findAndParseMetadata(mdh)
|
|
249
|
+
|
|
250
|
+
if (data is None):
|
|
251
|
+
#if we've supplied data, use that, otherwise load from file
|
|
252
|
+
self.Load(filename, prompt=load_prompt, haveGUI=self.haveGUI)
|
|
253
|
+
|
|
254
|
+
#do the necessary munging to get the data in the format we want it
|
|
255
|
+
self.SetData(self._data)
|
|
256
|
+
|
|
257
|
+
#generate a placeholder filename / window title
|
|
258
|
+
if self.filename is None:
|
|
259
|
+
self.filename = '%s %d' % (titleStub, nUntitled[titleStub])
|
|
260
|
+
nUntitled[titleStub] += 1
|
|
261
|
+
|
|
262
|
+
self.seriesName = self.filename
|
|
263
|
+
|
|
264
|
+
#generate some empty metadata if we don't have any
|
|
265
|
+
if self.mdh is None:
|
|
266
|
+
self.mdh = MetaDataHandler.NestedClassMDHandler()
|
|
267
|
+
|
|
268
|
+
#hack to make spectral data behave right - doesn't really belong here
|
|
269
|
+
if 'Spectrum.Wavelengths' in self.mdh.getEntryNames():
|
|
270
|
+
self.xvals = self.mdh['Spectrum.Wavelengths']
|
|
271
|
+
self.xlabel = 'Wavelength [nm]'
|
|
272
|
+
|
|
273
|
+
#if we have 1D data, plot as graph rather than image
|
|
274
|
+
if self.data_xyztc.shape[1] == 1:
|
|
275
|
+
self.mode = 'graph'
|
|
276
|
+
|
|
277
|
+
#add ourselves to the list of open images
|
|
278
|
+
openImages[self.filename] = self
|
|
279
|
+
|
|
280
|
+
def SetData(self, data):
|
|
281
|
+
"""
|
|
282
|
+
Set / replace the data associated with the image. This is primarily used in the acquisition program when we want
|
|
283
|
+
a live view of constantly updating data. It is also used for the same purpose during deconvolution.
|
|
284
|
+
|
|
285
|
+
Parameters
|
|
286
|
+
----------
|
|
287
|
+
data : numpy array or PYME.IO.DataSources datasource
|
|
288
|
+
|
|
289
|
+
Returns
|
|
290
|
+
-------
|
|
291
|
+
|
|
292
|
+
"""
|
|
293
|
+
|
|
294
|
+
#the data does not need to be a numpy array - it could also be, eg., queue data
|
|
295
|
+
#on a remote server - wrap so that is is indexable like an array
|
|
296
|
+
self._data = dataWrap.Wrap(data)
|
|
297
|
+
|
|
298
|
+
if isinstance(self._data, BaseDataSource.XYZTCDataSource) or (self._data.ndim == 5):
|
|
299
|
+
# data is already 5D
|
|
300
|
+
self._data_xyztc = self._data
|
|
301
|
+
self._data_xytc = BaseDataSource.XYTCWrapper(self._data)
|
|
302
|
+
else:
|
|
303
|
+
self._data_xytc = self._data
|
|
304
|
+
# promote to 5D, currently assume series with > 100 frames along z/t dimension are time series,
|
|
305
|
+
# series with <= 100 frames are s-stacks
|
|
306
|
+
self._data_xyztc = BaseDataSource.XYZTCWrapper.auto_promote(self._data)
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
@property
|
|
310
|
+
def data(self):
|
|
311
|
+
"""
|
|
312
|
+
Compatiblity property for old style data access. Currently equivalent to data_xytc, + a deprecation warning.
|
|
313
|
+
|
|
314
|
+
The old behaviour is available as data_xytc
|
|
315
|
+
|
|
316
|
+
Might (eventually) change to data_xyztc once transition is complete
|
|
317
|
+
|
|
318
|
+
Returns
|
|
319
|
+
-------
|
|
320
|
+
|
|
321
|
+
"""
|
|
322
|
+
import warnings
|
|
323
|
+
warnings.warn(PYMEDeprecationWarning('This will either disappear or change function as we move to a 5D data model. Use the explicit .data_xytc instead, or even better, change to using the 5D model as image.data_xyztc or image.voxels'), stacklevel=2)
|
|
324
|
+
return self._data_xytc
|
|
325
|
+
|
|
326
|
+
@property
|
|
327
|
+
def data_xyztc(self):
|
|
328
|
+
"""
|
|
329
|
+
Provides voxel data in a form that is accessible as though it was a 5D array with X, Y, Z, T, C as the dimensions
|
|
330
|
+
|
|
331
|
+
Implemented as a property to facilitate transition from old 4D data model
|
|
332
|
+
|
|
333
|
+
Returns
|
|
334
|
+
-------
|
|
335
|
+
|
|
336
|
+
PYME.IO.DataSources.BaseDataSource.XYZTC data source (or class derived from this
|
|
337
|
+
|
|
338
|
+
"""
|
|
339
|
+
|
|
340
|
+
return self._data_xyztc
|
|
341
|
+
|
|
342
|
+
@property
|
|
343
|
+
def voxels(self):
|
|
344
|
+
"""
|
|
345
|
+
A shorter alias of data_xyztc
|
|
346
|
+
"""
|
|
347
|
+
return self.data_xyztc
|
|
348
|
+
|
|
349
|
+
@property
|
|
350
|
+
def data_xytc(self):
|
|
351
|
+
"""
|
|
352
|
+
Old-style data access with z & t dimensions flattened
|
|
353
|
+
|
|
354
|
+
Returns
|
|
355
|
+
-------
|
|
356
|
+
|
|
357
|
+
"""
|
|
358
|
+
|
|
359
|
+
return self._data_xytc
|
|
360
|
+
|
|
361
|
+
@property
|
|
362
|
+
def voxelsize(self):
|
|
363
|
+
"""Returns voxel size, in nm, as a 3-tuple. Expects metadata voxel size
|
|
364
|
+
to be in um"""
|
|
365
|
+
warnings.warn(DeprecationWarning('Use voxelsize_nm property instead'))
|
|
366
|
+
try:
|
|
367
|
+
return self.voxelsize_nm
|
|
368
|
+
except:
|
|
369
|
+
return (1,1,1)
|
|
370
|
+
|
|
371
|
+
@property
|
|
372
|
+
def voxelsize_nm(self):
|
|
373
|
+
""" alias of self.voxelsize for interface compatibilty with metadatahandler
|
|
374
|
+
|
|
375
|
+
differs from self.voxelsize in that we will propagate any exception generated if, e.g., 'voxelsize.x' is not
|
|
376
|
+
present in the metadata.
|
|
377
|
+
|
|
378
|
+
"""
|
|
379
|
+
return self.mdh.voxelsize_nm
|
|
380
|
+
|
|
381
|
+
@property
|
|
382
|
+
def pixelSize(self):
|
|
383
|
+
try:
|
|
384
|
+
return self.mdh.voxelsize_nm.x
|
|
385
|
+
except:
|
|
386
|
+
return 1
|
|
387
|
+
|
|
388
|
+
@pixelSize.setter
|
|
389
|
+
def pixelSize(self, value):
|
|
390
|
+
self.mdh['voxelsize.x'] = .001*value
|
|
391
|
+
self.mdh['voxelsize.y'] = .001*value
|
|
392
|
+
|
|
393
|
+
@property
|
|
394
|
+
def sliceSize(self):
|
|
395
|
+
try:
|
|
396
|
+
return 1e3*self.mdh['voxelsize.z']
|
|
397
|
+
except:
|
|
398
|
+
return 1
|
|
399
|
+
|
|
400
|
+
@sliceSize.setter
|
|
401
|
+
def sliceSize(self, value):
|
|
402
|
+
self.mdh['voxelsize.z'] = .001*value
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
@property
|
|
406
|
+
def names(self):
|
|
407
|
+
"""Return the names of the colour channels"""
|
|
408
|
+
try:
|
|
409
|
+
names = self.mdh['ChannelNames']
|
|
410
|
+
#make things play nice on py3
|
|
411
|
+
return [name.decode() if isinstance(name, bytes) else name for name in names]
|
|
412
|
+
|
|
413
|
+
except:
|
|
414
|
+
return ['Chan %d'% d for d in range(self.data_xyztc.shape[4])]
|
|
415
|
+
|
|
416
|
+
@names.setter
|
|
417
|
+
def names(self, value):
|
|
418
|
+
self.mdh['ChannelNames'] = value
|
|
419
|
+
|
|
420
|
+
@property
|
|
421
|
+
def imgBounds(self):
|
|
422
|
+
"""Return the bounds (or valid area) of the image in nm as (x0, y0, x1, y1, z0, z1)"""
|
|
423
|
+
try:
|
|
424
|
+
return ImageBounds(self.mdh['ImageBounds.x0'],self.mdh['ImageBounds.y0'],self.mdh['ImageBounds.x1'],self.mdh['ImageBounds.y1'],self.mdh['ImageBounds.z0'],self.mdh['ImageBounds.z1'])
|
|
425
|
+
except:
|
|
426
|
+
# if we don't have ImageBounds in the metadata, use origin and voxelsize to estimate
|
|
427
|
+
x0 = self.mdh.get('Origin.x', 0)
|
|
428
|
+
y0 = self.mdh.get('Origin.y', 0)
|
|
429
|
+
z0 = self.mdh.get('Origin.z', 0)
|
|
430
|
+
|
|
431
|
+
return ImageBounds(x0, y0, x0 + self.voxelsize_nm.x*self.voxels.shape[0], y0 + self.voxelsize_nm.y*self.voxels.shape[1],
|
|
432
|
+
z0, z0 + self.voxelsize_nm.z*self.voxels.shape[2])
|
|
433
|
+
|
|
434
|
+
@imgBounds.setter
|
|
435
|
+
def imgBounds(self, value):
|
|
436
|
+
self.mdh['ImageBounds.x0'] = value.x0
|
|
437
|
+
self.mdh['ImageBounds.y0'] = value.y0
|
|
438
|
+
self.mdh['ImageBounds.x1'] = value.x1
|
|
439
|
+
self.mdh['ImageBounds.y1'] = value.y1
|
|
440
|
+
self.mdh['ImageBounds.z0'] = value.z0
|
|
441
|
+
self.mdh['ImageBounds.z1'] = value.z1
|
|
442
|
+
|
|
443
|
+
# PEP8 alias
|
|
444
|
+
image_bounds = imgBounds
|
|
445
|
+
|
|
446
|
+
@property
|
|
447
|
+
def metadata(self):
|
|
448
|
+
return self.mdh
|
|
449
|
+
|
|
450
|
+
@property
|
|
451
|
+
def origin(self):
|
|
452
|
+
#the origin, in nm from the camera - used for overlaying with different ROIs
|
|
453
|
+
|
|
454
|
+
return MetaDataHandler.origin_nm(self.mdh, self.pixelSize)
|
|
455
|
+
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
|
|
459
|
+
def _loadQueue(self, filename):
|
|
460
|
+
"""Load data from a remote PYME.ParallelTasks.HDFTaskQueue queue using
|
|
461
|
+
Pyro.
|
|
462
|
+
|
|
463
|
+
Parameters
|
|
464
|
+
----------
|
|
465
|
+
|
|
466
|
+
filename : string
|
|
467
|
+
the name of the queue
|
|
468
|
+
|
|
469
|
+
"""
|
|
470
|
+
import Pyro.core
|
|
471
|
+
from PYME.IO.DataSources import TQDataSource
|
|
472
|
+
from PYME.misc.computerName import GetComputerName
|
|
473
|
+
compName = GetComputerName()
|
|
474
|
+
|
|
475
|
+
if self.queueURI is None:
|
|
476
|
+
#do a lookup
|
|
477
|
+
taskQueueName = 'TaskQueues.%s' % compName
|
|
478
|
+
|
|
479
|
+
try:
|
|
480
|
+
from PYME.misc import hybrid_ns
|
|
481
|
+
ns = hybrid_ns.getNS()
|
|
482
|
+
URI = ns.resolve(taskQueueName)
|
|
483
|
+
except:
|
|
484
|
+
URI = 'PYRONAME://' + taskQueueName
|
|
485
|
+
|
|
486
|
+
self.tq = Pyro.core.getProxyForURI(URI)
|
|
487
|
+
else:
|
|
488
|
+
self.tq = Pyro.core.getProxyForURI(self.queueURI)
|
|
489
|
+
|
|
490
|
+
self.seriesName = filename[len('QUEUE://'):]
|
|
491
|
+
|
|
492
|
+
self.dataSource = TQDataSource.DataSource(self.seriesName, self.tq)
|
|
493
|
+
self.SetData(self.dataSource) #this will get replaced with a wrapped version
|
|
494
|
+
|
|
495
|
+
self.mdh = MetaDataHandler.QueueMDHandler(self.tq, self.seriesName)
|
|
496
|
+
MetaData.fillInBlanks(self.mdh, self.dataSource)
|
|
497
|
+
|
|
498
|
+
#self.timer.WantNotification.append(self.dsRefresh)
|
|
499
|
+
|
|
500
|
+
self.events = self.dataSource.getEvents()
|
|
501
|
+
self.mode = 'LM'
|
|
502
|
+
|
|
503
|
+
def _loadh5(self, filename):
|
|
504
|
+
"""Load PYMEs semi-custom HDF5 image data format. Offloads all the
|
|
505
|
+
hard work to the HDFDataSource class"""
|
|
506
|
+
import tables
|
|
507
|
+
from PYME.IO.DataSources import HDFDataSource, BGSDataSource
|
|
508
|
+
from PYME.IO import tabular
|
|
509
|
+
|
|
510
|
+
self.dataSource = HDFDataSource.DataSource(filename, None)
|
|
511
|
+
#chain on a background subtraction data source, so we can easily do
|
|
512
|
+
#background subtraction in the GUI the same way as in the analysis
|
|
513
|
+
self.SetData(BGSDataSource.DataSource(self.dataSource)) #this will get replaced with a wrapped version
|
|
514
|
+
|
|
515
|
+
self.mdh = MetaDataHandler.NestedClassMDHandler(MetaData.TIRFDefault)
|
|
516
|
+
|
|
517
|
+
if self.dataSource.mdh is not None: #should be true the whole time
|
|
518
|
+
self.mdh.copyEntriesFrom(self.dataSource.mdh)
|
|
519
|
+
else:
|
|
520
|
+
PYME.pyme_warnings.warn("ERROR: No metadata fond in file ... Carrying on with defaults - no gaurantees it'll work well")
|
|
521
|
+
|
|
522
|
+
#attempt to estimate any missing parameters from the data itself
|
|
523
|
+
try:
|
|
524
|
+
MetaData.fillInBlanks(self.mdh, self.dataSource)
|
|
525
|
+
except:
|
|
526
|
+
logger.exception('Error attempting to populate missing metadata')
|
|
527
|
+
|
|
528
|
+
#calculate the name to use when we do batch analysis on this
|
|
529
|
+
#from PYME.IO.FileUtils.nameUtils import getRelFilename
|
|
530
|
+
self.seriesName = getRelFilename(filename)
|
|
531
|
+
|
|
532
|
+
#try and find a previously performed analysis
|
|
533
|
+
fns = filename.split(os.path.sep)
|
|
534
|
+
cand = os.path.sep.join(fns[:-2] + ['analysis',] + fns[-2:]) + 'r'
|
|
535
|
+
print(cand)
|
|
536
|
+
if False:#os.path.exists(cand):
|
|
537
|
+
h5Results = tables.open_file(cand)
|
|
538
|
+
|
|
539
|
+
if 'FitResults' in dir(h5Results.root):
|
|
540
|
+
self.fitResults = h5Results.root.FitResults[:]
|
|
541
|
+
self.resultsSource = tabular.H5RSource(h5Results)
|
|
542
|
+
|
|
543
|
+
self.resultsMdh = MetaData.TIRFDefault
|
|
544
|
+
self.resultsMdh.copyEntriesFrom(MetaDataHandler.HDFMDHandler(h5Results))
|
|
545
|
+
|
|
546
|
+
self.events = self.dataSource.getEvents()
|
|
547
|
+
|
|
548
|
+
self.mode = 'LM'
|
|
549
|
+
|
|
550
|
+
def _loadHTTP(self, filename):
|
|
551
|
+
"""Load PYMEs semi-custom HDF5 image data format. Offloads all the
|
|
552
|
+
hard work to the HDFDataSource class"""
|
|
553
|
+
from PYME.IO.DataSources import HTTPDataSource, BGSDataSource
|
|
554
|
+
#from PYME.LMVis import inpFilt
|
|
555
|
+
|
|
556
|
+
#open hdf5 file
|
|
557
|
+
self.dataSource = HTTPDataSource.DataSource(filename)
|
|
558
|
+
#chain on a background subtraction data source, so we can easily do
|
|
559
|
+
#background subtraction in the GUI the same way as in the analysis
|
|
560
|
+
self.SetData(BGSDataSource.DataSource(self.dataSource)) #this will get replaced with a wrapped version
|
|
561
|
+
|
|
562
|
+
#try: #should be true the whole time
|
|
563
|
+
self.mdh = MetaDataHandler.NestedClassMDHandler(MetaData.TIRFDefault)
|
|
564
|
+
self.mdh.copyEntriesFrom(self.dataSource.getMetadata())
|
|
565
|
+
#except:
|
|
566
|
+
# self.mdh = MetaData.TIRFDefault
|
|
567
|
+
# wx.MessageBox("Carrying on with defaults - no gaurantees it'll work well", 'ERROR: No metadata found in file ...', wx.OK)
|
|
568
|
+
# print("ERROR: No metadata fond in file ... Carrying on with defaults - no gaurantees it'll work well")
|
|
569
|
+
|
|
570
|
+
#attempt to estimate any missing parameters from the data itself
|
|
571
|
+
MetaData.fillInBlanks(self.mdh, self.dataSource)
|
|
572
|
+
|
|
573
|
+
#calculate the name to use when we do batch analysis on this
|
|
574
|
+
#from PYME.ParallelTasks.relativeFiles import getRelFilename
|
|
575
|
+
self.seriesName = filename
|
|
576
|
+
|
|
577
|
+
self.events = self.dataSource.getEvents()
|
|
578
|
+
|
|
579
|
+
self.mode='LM'
|
|
580
|
+
|
|
581
|
+
def _loadClusterPZF(self, filename):
|
|
582
|
+
"""Load PYMEs semi-custom HDF5 image data format. Offloads all the
|
|
583
|
+
hard work to the HDFDataSource class"""
|
|
584
|
+
|
|
585
|
+
from PYME.IO.DataSources import ClusterPZFDataSource, BGSDataSource
|
|
586
|
+
|
|
587
|
+
self.dataSource = ClusterPZFDataSource.DataSource(filename)
|
|
588
|
+
#chain on a background subtraction data source, so we can easily do
|
|
589
|
+
#background subtraction in the GUI the same way as in the analysis
|
|
590
|
+
self.SetData(BGSDataSource.DataSource(self.dataSource)) #this will get replaced with a wrapped version
|
|
591
|
+
|
|
592
|
+
#try: #should be true the whole time
|
|
593
|
+
self.mdh = MetaDataHandler.NestedClassMDHandler(MetaData.TIRFDefault)
|
|
594
|
+
self.mdh.copyEntriesFrom(self.dataSource.getMetadata())
|
|
595
|
+
|
|
596
|
+
#attempt to estimate any missing parameters from the data itself
|
|
597
|
+
MetaData.fillInBlanks(self.mdh, self.dataSource)
|
|
598
|
+
|
|
599
|
+
#calculate the name to use when we do batch analysis on this
|
|
600
|
+
#from PYME.ParallelTasks.relativeFiles import getRelFilename
|
|
601
|
+
self.seriesName = filename
|
|
602
|
+
|
|
603
|
+
self.events = self.dataSource.getEvents()
|
|
604
|
+
|
|
605
|
+
self.mode = 'LM'
|
|
606
|
+
|
|
607
|
+
def _loadPSF(self, filename):
|
|
608
|
+
"""Load PYME .psf data.
|
|
609
|
+
|
|
610
|
+
.psf files consist of a tuple containing the data and the voxelsize.
|
|
611
|
+
"""
|
|
612
|
+
from PYME.IO import unifiedIO
|
|
613
|
+
with unifiedIO.local_or_temp_filename(filename) as fn:
|
|
614
|
+
data, vox = np_load_legacy(fn)
|
|
615
|
+
|
|
616
|
+
self.SetData(data)
|
|
617
|
+
|
|
618
|
+
self.mdh = MetaDataHandler.NestedClassMDHandler(MetaData.ConfocDefault)
|
|
619
|
+
|
|
620
|
+
self.mdh.setEntry('voxelsize.x', vox.x)
|
|
621
|
+
self.mdh.setEntry('voxelsize.y', vox.y)
|
|
622
|
+
self.mdh.setEntry('voxelsize.z', vox.z)
|
|
623
|
+
|
|
624
|
+
|
|
625
|
+
#from PYME.ParallelTasks.relativeFiles import getRelFilename
|
|
626
|
+
self.seriesName = getRelFilename(filename)
|
|
627
|
+
|
|
628
|
+
self.mode = 'psf'
|
|
629
|
+
|
|
630
|
+
def _loadSF(self, filename):
|
|
631
|
+
self.mdh =MetaDataHandler.NestedClassMDHandler( MetaData.BareBones)
|
|
632
|
+
self.mdh.setEntry('chroma.ShiftFilename', filename)
|
|
633
|
+
dx, dy = np_load_legacy(filename)
|
|
634
|
+
|
|
635
|
+
self.mdh.setEntry('chroma.dx', dx)
|
|
636
|
+
self.mdh.setEntry('chroma.dy', dy)
|
|
637
|
+
|
|
638
|
+
#Completely guessing dimensions as it it not logged in the file
|
|
639
|
+
x = numpy.linspace(0, 256*70, 256)
|
|
640
|
+
y = numpy.linspace(0, 512*70, 512)
|
|
641
|
+
xs, ys = numpy.meshgrid(x, y)
|
|
642
|
+
data = [dx.ev(xs.ravel(), ys.ravel()).reshape(xs.shape)[::-1,:].T, dy.ev(xs.ravel(), ys.ravel()).reshape(xs.shape)[::-1,:].T]
|
|
643
|
+
|
|
644
|
+
self.SetData(data)
|
|
645
|
+
|
|
646
|
+
from PYME.Analysis.points import twoColourPlot
|
|
647
|
+
twoColourPlot.PlotShiftField2(dx, dy, [256, 512])
|
|
648
|
+
|
|
649
|
+
self.mode = 'default'
|
|
650
|
+
|
|
651
|
+
def _load_supertile(self, filename):
|
|
652
|
+
#strip leading supertile schema
|
|
653
|
+
if filename.upper().startswith('SUPERTILE:'):
|
|
654
|
+
filename = filename[10:]
|
|
655
|
+
|
|
656
|
+
self._load_tiles(filename)
|
|
657
|
+
|
|
658
|
+
def _load_tiles(self, filename):
|
|
659
|
+
from PYME.IO.DataSources import TileDataSource
|
|
660
|
+
|
|
661
|
+
filename = filename.rstrip(os.path.sep)
|
|
662
|
+
|
|
663
|
+
data = TileDataSource.DataSource(filename)
|
|
664
|
+
self.SetData(data)
|
|
665
|
+
self.mdh = data.mdh
|
|
666
|
+
self.seriesName = filename
|
|
667
|
+
self.mode = 'default'
|
|
668
|
+
|
|
669
|
+
# TODO - make this a property which refers to the datasource??
|
|
670
|
+
self.levels = data.levels
|
|
671
|
+
|
|
672
|
+
|
|
673
|
+
def _load_concatenated(self, filename):
|
|
674
|
+
from PYME.IO.DataSources import ConcatenatedDataSource
|
|
675
|
+
import glob
|
|
676
|
+
|
|
677
|
+
if filename.upper().startswith('CONCATENATED://'):
|
|
678
|
+
filename = filename[15:]
|
|
679
|
+
|
|
680
|
+
z, t, c = None, None, None
|
|
681
|
+
if filename[0] == ':':
|
|
682
|
+
# we are explicitly passing ztc dimensions as ?z=zval&t=tval&c=cval
|
|
683
|
+
split_string = filename[1:].split(':')
|
|
684
|
+
dim_string = split_string[0]
|
|
685
|
+
z, t, c = [int(s) for s in dim_string.split(',')]
|
|
686
|
+
filename = ''.join(split_string[1:])
|
|
687
|
+
|
|
688
|
+
if '?' in filename:
|
|
689
|
+
#we have a query string to pick the series
|
|
690
|
+
from six.moves import urllib
|
|
691
|
+
filename, query = filename.split('?')
|
|
692
|
+
|
|
693
|
+
try:
|
|
694
|
+
z = int(urllib.parse.parse_qs(query)['z'][0])
|
|
695
|
+
except KeyError:
|
|
696
|
+
z = 1
|
|
697
|
+
try:
|
|
698
|
+
t = int(urllib.parse.parse_qs(query)['t'][0])
|
|
699
|
+
except KeyError:
|
|
700
|
+
t = 1
|
|
701
|
+
try:
|
|
702
|
+
c = int(urllib.parse.parse_qs(query)['c'][0])
|
|
703
|
+
except KeyError:
|
|
704
|
+
c = 1
|
|
705
|
+
|
|
706
|
+
if ((z==1) and (t==1) and (c==1)):
|
|
707
|
+
#we have a query string but no dimensions specified
|
|
708
|
+
z, t, c = None, None, None
|
|
709
|
+
|
|
710
|
+
if filename.find(',') == -1:
|
|
711
|
+
# pattern-based
|
|
712
|
+
filenames = sorted(glob.glob(filename))
|
|
713
|
+
else:
|
|
714
|
+
# a user took the time to pass files individually,
|
|
715
|
+
# separated by commas
|
|
716
|
+
filenames = filename.split(',')
|
|
717
|
+
|
|
718
|
+
# rename, as it's not a great idea for seriesName to
|
|
719
|
+
# be full of commas
|
|
720
|
+
filename = '_'.join(filenames)
|
|
721
|
+
|
|
722
|
+
datasources = []
|
|
723
|
+
for fn in filenames:
|
|
724
|
+
image = ImageStack(filename=fn)
|
|
725
|
+
datasources.append(image.data_xyztc)
|
|
726
|
+
|
|
727
|
+
data = ConcatenatedDataSource.DataSource(datasources, size_z=z, size_t=t, size_c=c)
|
|
728
|
+
self.SetData(data)
|
|
729
|
+
self.seriesName = filename
|
|
730
|
+
self.mode = 'default'
|
|
731
|
+
|
|
732
|
+
def _loadNPY(self, filename):
|
|
733
|
+
"""Load numpy .npy data.
|
|
734
|
+
|
|
735
|
+
|
|
736
|
+
"""
|
|
737
|
+
from PYME.IO import unifiedIO
|
|
738
|
+
mdfn = self._findAndParseMetadata(filename)
|
|
739
|
+
|
|
740
|
+
with unifiedIO.local_or_temp_filename(filename) as fn:
|
|
741
|
+
data = numpy.load(fn,allow_pickle=True)
|
|
742
|
+
|
|
743
|
+
self.SetData(data)
|
|
744
|
+
|
|
745
|
+
#from PYME.ParallelTasks.relativeFiles import getRelFilename
|
|
746
|
+
self.seriesName = getRelFilename(filename)
|
|
747
|
+
|
|
748
|
+
self.mode = 'default'
|
|
749
|
+
|
|
750
|
+
def _loadPZF(self, filename):
|
|
751
|
+
"""Load .pzf data.
|
|
752
|
+
|
|
753
|
+
|
|
754
|
+
"""
|
|
755
|
+
from PYME.IO import unifiedIO
|
|
756
|
+
from PYME.IO import PZFFormat
|
|
757
|
+
mdfn = self._findAndParseMetadata(filename)
|
|
758
|
+
|
|
759
|
+
with unifiedIO.openFile(filename) as f:
|
|
760
|
+
data = PZFFormat.loads(f.read())[0]
|
|
761
|
+
|
|
762
|
+
self.SetData(data)
|
|
763
|
+
|
|
764
|
+
#from PYME.ParallelTasks.relativeFiles import getRelFilename
|
|
765
|
+
self.seriesName = getRelFilename(filename)
|
|
766
|
+
|
|
767
|
+
self.mode = 'default'
|
|
768
|
+
|
|
769
|
+
def _loadDBL(self, filename):
|
|
770
|
+
"""Load Bewersdorf custom STED data.
|
|
771
|
+
|
|
772
|
+
"""
|
|
773
|
+
mdfn = self._findAndParseMetadata(filename)
|
|
774
|
+
|
|
775
|
+
data = numpy.memmap(filename, dtype=self.mdh['DataType'], mode='r', offset=128, shape=(self.mdh['Camera.ROIWidth'],self.mdh['Camera.ROIHeight'],self.mdh['NumImages']), order='F')
|
|
776
|
+
self.SetData(data)
|
|
777
|
+
|
|
778
|
+
#from PYME.ParallelTasks.relativeFiles import getRelFilename
|
|
779
|
+
self.seriesName = getRelFilename(filename)
|
|
780
|
+
|
|
781
|
+
self.mode = 'default'
|
|
782
|
+
|
|
783
|
+
def _loadOBF(self, filename):
|
|
784
|
+
from PYME.IO.DataSources import OBFDataSource
|
|
785
|
+
from PYME.IO.FileUtils import obf_support
|
|
786
|
+
from PYME.IO.FileUtils.nameUtils import getFullExistingFilename, getRelFilename
|
|
787
|
+
import numpy as np
|
|
788
|
+
|
|
789
|
+
stack_number = None
|
|
790
|
+
|
|
791
|
+
if '?' in filename:
|
|
792
|
+
#we have a query string to pick the stack number
|
|
793
|
+
from six.moves import urllib
|
|
794
|
+
filename, query = filename.split('?')
|
|
795
|
+
|
|
796
|
+
try:
|
|
797
|
+
stack_number = int(urllib.parse.parse_qs(query)['stack'][0])
|
|
798
|
+
except KeyError:
|
|
799
|
+
pass
|
|
800
|
+
|
|
801
|
+
filename = getFullExistingFilename(filename)#convert relative path to full path
|
|
802
|
+
obf = obf_support.File(filename)
|
|
803
|
+
logger.debug('file: {}'.format(filename))
|
|
804
|
+
if len(obf.stacks) > 1 and stack_number is None and self.haveGUI:
|
|
805
|
+
import wx
|
|
806
|
+
options = ['%d: %s' % (ind, stack.name) for (ind, stack) in enumerate(obf.stacks)]
|
|
807
|
+
|
|
808
|
+
dlg = wx.SingleChoiceDialog(None, 'Stack', 'Select a stack', options)
|
|
809
|
+
if dlg.ShowModal() == wx.ID_OK:
|
|
810
|
+
stack_number = dlg.GetSelection()
|
|
811
|
+
|
|
812
|
+
data = OBFDataSource.DataSource(obf, stack_number)
|
|
813
|
+
self.SetData(data)
|
|
814
|
+
self.seriesName = getRelFilename(filename) + ': ' + data.stack.name
|
|
815
|
+
self.filename = self.seriesName
|
|
816
|
+
logger.debug(self.filename)
|
|
817
|
+
self.mdh = MetaDataHandler.NestedClassMDHandler(MetaData.BareBones)
|
|
818
|
+
voxel_sizes = data.stack.pixel_sizes
|
|
819
|
+
scales_factors = [d.scalefactor for d in data.stack.si_dimensions[:3]]
|
|
820
|
+
if not np.allclose(np.ones_like(scales_factors), scales_factors):
|
|
821
|
+
raise NotImplementedError('Scale factors other than 1 not yet supported for OBF metadata')
|
|
822
|
+
self.mdh['voxelsize.x'] = voxel_sizes[0] / 1E-6 # [m -> um]
|
|
823
|
+
self.mdh['voxelsize.y'] = voxel_sizes[1] / 1E-6 # [m -> um]
|
|
824
|
+
self.mdh['voxelsize.z'] = voxel_sizes[2] / 1E-6 # [m -> um]
|
|
825
|
+
|
|
826
|
+
|
|
827
|
+
|
|
828
|
+
def _findAndParseMetadata(self, filename):
|
|
829
|
+
"""Try and find and load a .xml or .md metadata file that might be ascociated
|
|
830
|
+
with a given image filename. See the relevant metadatahandler classes
|
|
831
|
+
for details."""
|
|
832
|
+
import xml.parsers.expat
|
|
833
|
+
from PYME.IO import unifiedIO
|
|
834
|
+
|
|
835
|
+
if not self.mdh is None:
|
|
836
|
+
return #we already have metadata (probably passed in on command line)
|
|
837
|
+
|
|
838
|
+
mdf = None
|
|
839
|
+
xmlfn = os.path.splitext(filename)[0] + '.xml'
|
|
840
|
+
xmlfnmc = os.path.splitext(filename)[0].split('__')[0] + '.xml'
|
|
841
|
+
if os.path.exists(xmlfn):
|
|
842
|
+
try:
|
|
843
|
+
self.mdh = MetaDataHandler.NestedClassMDHandler(MetaData.TIRFDefault)
|
|
844
|
+
self.mdh.copyEntriesFrom(MetaDataHandler.XMLMDHandler(xmlfn))
|
|
845
|
+
mdf = xmlfn
|
|
846
|
+
except xml.parsers.expat.ExpatError:
|
|
847
|
+
#fix for bug in which PYME .md was written with a .xml extension
|
|
848
|
+
self.mdh = MetaDataHandler.NestedClassMDHandler(MetaData.BareBones)
|
|
849
|
+
self.mdh.copyEntriesFrom(MetaDataHandler.SimpleMDHandler(xmlfn))
|
|
850
|
+
mdf = xmlfn
|
|
851
|
+
except IndexError:
|
|
852
|
+
# has an xml file, but lacks 'MetaData' section
|
|
853
|
+
logger.error('xml file %s is not valid PYME metadata')
|
|
854
|
+
|
|
855
|
+
elif os.path.exists(xmlfnmc): #this is a single colour channel of a pair
|
|
856
|
+
self.mdh = MetaDataHandler.NestedClassMDHandler(MetaData.TIRFDefault)
|
|
857
|
+
self.mdh.copyEntriesFrom(MetaDataHandler.XMLMDHandler(xmlfnmc))
|
|
858
|
+
mdf = xmlfnmc
|
|
859
|
+
else:
|
|
860
|
+
self.mdh = MetaDataHandler.NestedClassMDHandler(MetaData.BareBones)
|
|
861
|
+
|
|
862
|
+
#check for simple metadata (python code with an .md extension which
|
|
863
|
+
#fills a dictionary called md)
|
|
864
|
+
mdfn = os.path.splitext(filename)[0] + '.md'
|
|
865
|
+
jsonfn = os.path.splitext(filename)[0] + '.json'
|
|
866
|
+
if os.path.exists(mdfn):
|
|
867
|
+
self.mdh.copyEntriesFrom(MetaDataHandler.SimpleMDHandler(mdfn))
|
|
868
|
+
mdf = mdfn
|
|
869
|
+
elif os.path.exists(jsonfn):
|
|
870
|
+
import json
|
|
871
|
+
with open(jsonfn, 'r') as f:
|
|
872
|
+
mdd = json.load(f)
|
|
873
|
+
self.mdh.update(mdd)
|
|
874
|
+
elif filename.endswith('.lsm'):
|
|
875
|
+
#read lsm metadata
|
|
876
|
+
from PYME.contrib.gohlke.tifffile import TIFFfile
|
|
877
|
+
tf = TIFFfile(filename)
|
|
878
|
+
lsm_info = tf[0].cz_lsm_scan_information
|
|
879
|
+
self.mdh['voxelsize.x'] = lsm_info['line_spacing']
|
|
880
|
+
self.mdh['voxelsize.y'] = lsm_info['line_spacing']
|
|
881
|
+
self.mdh['voxelsize.z'] = lsm_info['plane_spacing']
|
|
882
|
+
|
|
883
|
+
def lsm_pop(basename, dic):
|
|
884
|
+
for k, v in dic.items():
|
|
885
|
+
if isinstance(v, list):
|
|
886
|
+
#print k, v
|
|
887
|
+
for i, l_i in enumerate(v):
|
|
888
|
+
#print i, l_i, basename
|
|
889
|
+
lsm_pop(basename + k + '.' + k[:-1] + '%i.' %i, l_i)
|
|
890
|
+
|
|
891
|
+
else:
|
|
892
|
+
self.mdh[basename + k] = v
|
|
893
|
+
|
|
894
|
+
lsm_pop('LSM.', lsm_info)
|
|
895
|
+
|
|
896
|
+
elif filename.endswith('.tif'):
|
|
897
|
+
#look for OME data...
|
|
898
|
+
from PYME.contrib.gohlke.tifffile import TIFFfile
|
|
899
|
+
tf = TIFFfile(filename)
|
|
900
|
+
|
|
901
|
+
if tf.is_ome:
|
|
902
|
+
try:
|
|
903
|
+
omemdh = MetaDataHandler.OMEXMLMDHandler(tf.pages[0].tags['image_description'].value)
|
|
904
|
+
|
|
905
|
+
self.mdh.copyEntriesFrom(omemdh)
|
|
906
|
+
except IndexError:
|
|
907
|
+
pass
|
|
908
|
+
|
|
909
|
+
elif filename.endswith('.dcimg'): #Bewersdorf lab Biplane
|
|
910
|
+
# FIXME load seriesXX.json for seriesXX_chunkXX.dcimg files more elegantly
|
|
911
|
+
jsonfn = filename[:-22] + '.json'
|
|
912
|
+
|
|
913
|
+
import json
|
|
914
|
+
try:
|
|
915
|
+
mdd = json.loads(unifiedIO.read(jsonfn))
|
|
916
|
+
self.mdh.update(mdd)
|
|
917
|
+
|
|
918
|
+
except IOError:
|
|
919
|
+
pass
|
|
920
|
+
|
|
921
|
+
elif filename.endswith('.dbl'): #imspector format, Bewersdorf lab STED
|
|
922
|
+
mdfn = filename[:-4] + '.txt'
|
|
923
|
+
entrydict = {}
|
|
924
|
+
|
|
925
|
+
try: #try to read in extra metadata if possible
|
|
926
|
+
with unifiedIO.openFile(mdfn, 'r') as mf:
|
|
927
|
+
for line in mf:
|
|
928
|
+
s = line.split(':')
|
|
929
|
+
if len(s) == 2:
|
|
930
|
+
entrydict[s[0]] = s[1]
|
|
931
|
+
|
|
932
|
+
except IOError:
|
|
933
|
+
pass
|
|
934
|
+
|
|
935
|
+
# vx, vy = entrydict['Pixel size (um)'].split('x')
|
|
936
|
+
# self.mdh['voxelsize.x'] = float(vx)
|
|
937
|
+
# self.mdh['voxelsize.y'] = float(vy)
|
|
938
|
+
# self.mdh['voxelsize.z'] = 0.2 #FIXME for stacks ...
|
|
939
|
+
#
|
|
940
|
+
# sx, sy = entrydict['Image format'].split('x')
|
|
941
|
+
# self.mdh['Camera.ROIWidth'] = int(sx)
|
|
942
|
+
# self.mdh['Camera.ROIHeight'] = int(sy)
|
|
943
|
+
#
|
|
944
|
+
# self.mdh['NumImages'] = int(entrydict['# Images'])
|
|
945
|
+
|
|
946
|
+
with unifiedIO.openFile(filename) as df:
|
|
947
|
+
s = df.read(8)
|
|
948
|
+
Z, X, Y, T = numpy.fromstring(s, '>u2')
|
|
949
|
+
s = df.read(16)
|
|
950
|
+
depth, width, height, elapsed = numpy.fromstring(s, '<f4')
|
|
951
|
+
s = df.read(1)
|
|
952
|
+
if ord(s) == 1:
|
|
953
|
+
self.mdh['DataType'] = '<f4'
|
|
954
|
+
else:
|
|
955
|
+
self.mdh['DataType'] = '<f8'
|
|
956
|
+
|
|
957
|
+
self.mdh['voxelsize.x'] = width/X
|
|
958
|
+
self.mdh['voxelsize.y'] = height/Y
|
|
959
|
+
self.mdh['voxelsize.z'] = depth
|
|
960
|
+
|
|
961
|
+
self.mdh['Camera.ROIWidth'] = X
|
|
962
|
+
self.mdh['Camera.ROIHeight'] = Y
|
|
963
|
+
self.mdh['NumImages'] = Z*T
|
|
964
|
+
|
|
965
|
+
def _sanitise_key(key):
|
|
966
|
+
k = key.replace('#', 'Num')
|
|
967
|
+
k = k.replace('(%)', '')
|
|
968
|
+
k = k.replace('(', '')
|
|
969
|
+
k = k.replace(')', '')
|
|
970
|
+
k = k.replace('.', '')
|
|
971
|
+
k = k.replace('/', '')
|
|
972
|
+
k = k.replace('?', '')
|
|
973
|
+
k = k.replace(' ', '')
|
|
974
|
+
if not k[0].isalpha():
|
|
975
|
+
k = 's' + k
|
|
976
|
+
return k
|
|
977
|
+
|
|
978
|
+
for k, v in entrydict.items():
|
|
979
|
+
self.mdh['STED.%s'%_sanitise_key(k)] = v
|
|
980
|
+
|
|
981
|
+
#else: #try bioformats
|
|
982
|
+
# OMEXML = bioformats.get_omexml_metadata(filename).encode('utf8')
|
|
983
|
+
# OMEmd = MetaDataHandler.OMEXMLMDHandler(OMEXML)
|
|
984
|
+
# self.mdh.copyEntriesFrom(OMEmd)
|
|
985
|
+
|
|
986
|
+
|
|
987
|
+
|
|
988
|
+
|
|
989
|
+
|
|
990
|
+
|
|
991
|
+
|
|
992
|
+
if self.haveGUI and not ('voxelsize.x' in self.mdh.keys() and 'voxelsize.y' in self.mdh.keys()):
|
|
993
|
+
from PYME.DSView.voxSizeDialog import VoxSizeDialog
|
|
994
|
+
|
|
995
|
+
dlg = VoxSizeDialog(None)
|
|
996
|
+
dlg.ShowModal()
|
|
997
|
+
|
|
998
|
+
self.mdh.setEntry('voxelsize.x', dlg.GetVoxX())
|
|
999
|
+
self.mdh.setEntry('voxelsize.y', dlg.GetVoxY())
|
|
1000
|
+
self.mdh.setEntry('voxelsize.z', dlg.GetVoxZ())
|
|
1001
|
+
|
|
1002
|
+
dlg.Destroy()
|
|
1003
|
+
|
|
1004
|
+
return mdf
|
|
1005
|
+
|
|
1006
|
+
def _loadTiff(self, filename):
|
|
1007
|
+
#from PYME.IO.FileUtils import readTiff
|
|
1008
|
+
from PYME.IO.DataSources import TiffDataSource, BGSDataSource
|
|
1009
|
+
|
|
1010
|
+
mdfn = self._findAndParseMetadata(filename)
|
|
1011
|
+
|
|
1012
|
+
self.dataSource = TiffDataSource.DataSource(filename, None)
|
|
1013
|
+
print(self.dataSource.shape)
|
|
1014
|
+
|
|
1015
|
+
if getattr(self.dataSource, 'RGB', False):
|
|
1016
|
+
PYME.pyme_warnings.warn('Detected an RGB TIFF.\n\nThese are typically screenshots, or other colour-mapped images and not generally suitable for quantitative analysis. Procced with caution (or preferably use the raw data instead).')
|
|
1017
|
+
|
|
1018
|
+
self.dataSource = BufferedDataSource.DataSource(self.dataSource, min(self.dataSource.getNumSlices(), 50))
|
|
1019
|
+
data = self.dataSource #this will get replaced with a wrapped version
|
|
1020
|
+
|
|
1021
|
+
if self.dataSource.getNumSlices() > 500: #this is likely to be a localization data set
|
|
1022
|
+
#background subtraction in the GUI the same way as in the analysis
|
|
1023
|
+
data = BGSDataSource.DataSource(self.dataSource) #this will get replaced with a wrapped version
|
|
1024
|
+
|
|
1025
|
+
#if we have a multi channel data set, try and pull in all the channels
|
|
1026
|
+
if 'ChannelFiles' in self.mdh.getEntryNames() and not len(self.mdh['ChannelFiles']) == data.shape[3]:
|
|
1027
|
+
try:
|
|
1028
|
+
from PYME.IO.dataWrap import ListWrapper
|
|
1029
|
+
#pull in all channels
|
|
1030
|
+
|
|
1031
|
+
chans = []
|
|
1032
|
+
|
|
1033
|
+
for cf in self.mdh.getEntry('ChannelFiles'):
|
|
1034
|
+
cfn = os.path.join(os.path.split(filename)[0], cf)
|
|
1035
|
+
|
|
1036
|
+
ds = TiffDataSource.DataSource(cfn, None)
|
|
1037
|
+
ds = BufferedDataSource.DataSource(ds, min(ds.getNumSlices(), 50))
|
|
1038
|
+
|
|
1039
|
+
chans.append(ds)
|
|
1040
|
+
|
|
1041
|
+
data = ListWrapper(chans) #this will get replaced with a wrapped version
|
|
1042
|
+
|
|
1043
|
+
self.filename = mdfn
|
|
1044
|
+
except:
|
|
1045
|
+
pass
|
|
1046
|
+
|
|
1047
|
+
elif 'ChannelNames' in self.mdh.getEntryNames() and len(self.mdh['ChannelNames']) == data.getNumSlices():
|
|
1048
|
+
from PYME.IO.dataWrap import ListWrapper
|
|
1049
|
+
chans = [numpy.atleast_3d(data.getSlice(i)) for i in range(len(self.mdh['ChannelNames']))]
|
|
1050
|
+
data = ListWrapper(chans)
|
|
1051
|
+
elif filename.endswith('.lsm') and 'LSM.images_number_channels' in self.mdh.keys() and self.mdh['LSM.images_number_channels'] > 1:
|
|
1052
|
+
from PYME.IO.dataWrap import ListWrapper
|
|
1053
|
+
nChans = self.mdh['LSM.images_number_channels']
|
|
1054
|
+
|
|
1055
|
+
chans = []
|
|
1056
|
+
|
|
1057
|
+
for n in range(nChans):
|
|
1058
|
+
ds = TiffDataSource.DataSource(filename, None, n)
|
|
1059
|
+
ds = BufferedDataSource.DataSource(ds, min(ds.getNumSlices(), 50))
|
|
1060
|
+
|
|
1061
|
+
chans.append(ds)
|
|
1062
|
+
|
|
1063
|
+
data = ListWrapper(chans)
|
|
1064
|
+
|
|
1065
|
+
|
|
1066
|
+
self.SetData(data)
|
|
1067
|
+
|
|
1068
|
+
#from PYME.ParallelTasks.relativeFiles import getRelFilename
|
|
1069
|
+
self.seriesName = getRelFilename(filename)
|
|
1070
|
+
|
|
1071
|
+
self.mode = 'default'
|
|
1072
|
+
|
|
1073
|
+
if self.mdh.getOrDefault('ImageType', '') == 'PSF':
|
|
1074
|
+
self.mode = 'psf'
|
|
1075
|
+
elif self.dataSource.getNumSlices() > 5000:
|
|
1076
|
+
#likely to want to localize this
|
|
1077
|
+
self.mode = 'LM'
|
|
1078
|
+
|
|
1079
|
+
|
|
1080
|
+
def _loadBioformats(self, filename):
|
|
1081
|
+
try:
|
|
1082
|
+
import bioformats
|
|
1083
|
+
except ImportError:
|
|
1084
|
+
logger.exception('Error importing bioformats - is the python-bioformats module installed?')
|
|
1085
|
+
raise
|
|
1086
|
+
|
|
1087
|
+
from PYME.IO.DataSources import BioformatsDataSource
|
|
1088
|
+
series_num = None
|
|
1089
|
+
|
|
1090
|
+
if '?' in filename:
|
|
1091
|
+
#we have a query string to pick the series
|
|
1092
|
+
from six.moves import urllib
|
|
1093
|
+
filename, query = filename.split('?')
|
|
1094
|
+
|
|
1095
|
+
try:
|
|
1096
|
+
series_num = int(urllib.parse.parse_qs(query)['series'][0])
|
|
1097
|
+
except KeyError:
|
|
1098
|
+
pass
|
|
1099
|
+
|
|
1100
|
+
#mdfn = self.FindAndParseMetadata(filename)
|
|
1101
|
+
print("Bioformats:loading data")
|
|
1102
|
+
bioformats_file = BioformatsDataSource.BioformatsFile(filename)
|
|
1103
|
+
if series_num is None and bioformats_file.series_count > 1:
|
|
1104
|
+
print('File has multiple series, need to pick one.')
|
|
1105
|
+
|
|
1106
|
+
if self.haveGUI:
|
|
1107
|
+
import wx
|
|
1108
|
+
dlg = wx.SingleChoiceDialog(None, 'Series', 'Select a series', bioformats_file.series_names)
|
|
1109
|
+
if dlg.ShowModal() == wx.ID_OK:
|
|
1110
|
+
series_num = dlg.GetSelection()
|
|
1111
|
+
else:
|
|
1112
|
+
logger.warning('No GUI, using 0th series.')
|
|
1113
|
+
|
|
1114
|
+
self.dataSource = BioformatsDataSource.DataSource(bioformats_file, series=series_num)
|
|
1115
|
+
self.mdh = MetaDataHandler.NestedClassMDHandler(MetaData.BareBones)
|
|
1116
|
+
|
|
1117
|
+
# NOTE: We are triple-loading metadata. BioformatsDataSource.BioformatsFile.rdr has metadata (hard to access),
|
|
1118
|
+
# BioformatsDataSource.BioformatsFile has metadata, and now we are loading the same metadata again here.
|
|
1119
|
+
print("Bioformats:loading metadata")
|
|
1120
|
+
OMEXML = bioformats.get_omexml_metadata(filename).encode('utf8')
|
|
1121
|
+
print("Bioformats:parsing metadata")
|
|
1122
|
+
OMEmd = MetaDataHandler.OMEXMLMDHandler(OMEXML)
|
|
1123
|
+
self.mdh.copyEntriesFrom(OMEmd)
|
|
1124
|
+
print("Bioformats:done")
|
|
1125
|
+
|
|
1126
|
+
#fix voxelsizes if not specified in OME metadata
|
|
1127
|
+
if self.haveGUI and ((self.mdh['voxelsize.x'] < 0) or (self.mdh['voxelsize.y'] < 0)):
|
|
1128
|
+
from PYME.DSView.voxSizeDialog import VoxSizeDialog
|
|
1129
|
+
|
|
1130
|
+
dlg = VoxSizeDialog(None)
|
|
1131
|
+
dlg.ShowModal()
|
|
1132
|
+
|
|
1133
|
+
self.mdh.setEntry('voxelsize.x', dlg.GetVoxX())
|
|
1134
|
+
self.mdh.setEntry('voxelsize.y', dlg.GetVoxY())
|
|
1135
|
+
self.mdh.setEntry('voxelsize.z', dlg.GetVoxZ())
|
|
1136
|
+
|
|
1137
|
+
dlg.Destroy()
|
|
1138
|
+
|
|
1139
|
+
|
|
1140
|
+
print(self.dataSource.shape)
|
|
1141
|
+
self.dataSource = BufferedDataSource.DataSource(self.dataSource, min(self.dataSource.getNumSlices(), 50))
|
|
1142
|
+
self.SetData(self.dataSource)
|
|
1143
|
+
|
|
1144
|
+
print(self.data.shape)
|
|
1145
|
+
|
|
1146
|
+
#from PYME.ParallelTasks.relativeFiles import getRelFilename
|
|
1147
|
+
self.seriesName = getRelFilename(filename)
|
|
1148
|
+
|
|
1149
|
+
self.mode = 'default'
|
|
1150
|
+
|
|
1151
|
+
def _loadDCIMG(self, filename):
|
|
1152
|
+
from PYME.IO.DataSources import DcimgDataSource, MultiviewDataSource
|
|
1153
|
+
|
|
1154
|
+
self._findAndParseMetadata(filename)
|
|
1155
|
+
|
|
1156
|
+
self.dataSource = DcimgDataSource.DataSource(filename)
|
|
1157
|
+
|
|
1158
|
+
if 'Multiview.NumROIs' in self.mdh.keys():
|
|
1159
|
+
self.dataSource = MultiviewDataSource.DataSource(self.dataSource, self.mdh)
|
|
1160
|
+
|
|
1161
|
+
self.SetData(self.dataSource)
|
|
1162
|
+
|
|
1163
|
+
self.seriesName = getRelFilename(filename)
|
|
1164
|
+
|
|
1165
|
+
self.mode = 'default'
|
|
1166
|
+
|
|
1167
|
+
|
|
1168
|
+
def _loadImageSeries(self, filename):
|
|
1169
|
+
#from PYME.IO.FileUtils import readTiff
|
|
1170
|
+
from PYME.IO.DataSources import ImageSeriesDataSource
|
|
1171
|
+
|
|
1172
|
+
self.dataSource = ImageSeriesDataSource.DataSource(filename, None)
|
|
1173
|
+
self.dataSource = BufferedDataSource.DataSource(self.dataSource, min(self.dataSource.getNumSlices(), 50))
|
|
1174
|
+
self.SetData(self.dataSource)
|
|
1175
|
+
#self.data = readTiff.read3DTiff(filename)
|
|
1176
|
+
|
|
1177
|
+
self._findAndParseMetadata(filename)
|
|
1178
|
+
|
|
1179
|
+
#from PYME.ParallelTasks.relativeFiles import getRelFilename
|
|
1180
|
+
self.seriesName = getRelFilename(filename)
|
|
1181
|
+
|
|
1182
|
+
self.mode = 'default'
|
|
1183
|
+
|
|
1184
|
+
def _load_zarr(self, filename):
|
|
1185
|
+
import zarr
|
|
1186
|
+
from PYME.IO.DataSources import ArrayDataSource
|
|
1187
|
+
from PYME.IO.DataSources import BaseDataSource
|
|
1188
|
+
|
|
1189
|
+
if '?' in filename:
|
|
1190
|
+
fn, arrayname = filename.split('?')
|
|
1191
|
+
else:
|
|
1192
|
+
fn = filename
|
|
1193
|
+
arrayname = None
|
|
1194
|
+
|
|
1195
|
+
z = zarr.open(fn, 'r')
|
|
1196
|
+
|
|
1197
|
+
# reopen using a caching store with 1GB cache size
|
|
1198
|
+
z = zarr.open(zarr.LRUStoreCache(z.store, int(1e9)), 'r')
|
|
1199
|
+
|
|
1200
|
+
# TODO - is this a standard OME-NGFF property?
|
|
1201
|
+
dims = z.attrs.get('_ARRAY_DIMENSIONS', ['x', 'y', 'z'])
|
|
1202
|
+
dimOrder = ''.join(dims).upper()
|
|
1203
|
+
print('dimOrder:', dimOrder)
|
|
1204
|
+
|
|
1205
|
+
# expand to full xyztc by apending missing dimensions
|
|
1206
|
+
for d in 'XYZTC':
|
|
1207
|
+
if (d not in dimOrder):
|
|
1208
|
+
dimOrder += d
|
|
1209
|
+
|
|
1210
|
+
print('dimOrder:', dimOrder)
|
|
1211
|
+
def array_ds(a):
|
|
1212
|
+
if dimOrder[:a.ndim] == 'XYZTC'[:a.ndim]:
|
|
1213
|
+
# array has the correct dimension ordering for the dimensions that count, we can use direct slicing
|
|
1214
|
+
return ArrayDataSource.XYZTCArrayDataSource(a)
|
|
1215
|
+
else:
|
|
1216
|
+
logger.warning(f'Zarr dimenision order, {dims}, is not XYZTC, performance might not be optimal')
|
|
1217
|
+
#TODO - better support for slicing on chunked data with non-standard order
|
|
1218
|
+
return ArrayDataSource.XYZTCArrayDataSource(a, dimOrder=dimOrder)
|
|
1219
|
+
|
|
1220
|
+
|
|
1221
|
+
if isinstance(z, zarr.Group):
|
|
1222
|
+
array_names = sorted(list(z.array_keys()))
|
|
1223
|
+
print('Zarr file contains multiple datasets: %s' % (array_names,))
|
|
1224
|
+
|
|
1225
|
+
if arrayname and (arrayname in array_names):
|
|
1226
|
+
a = array_ds(z[arrayname])
|
|
1227
|
+
else:
|
|
1228
|
+
a = array_ds(z[array_names[0]])
|
|
1229
|
+
|
|
1230
|
+
if ('0' in array_names) and ('1' in array_names):
|
|
1231
|
+
# hack to detect pyramid
|
|
1232
|
+
print('Detected pyramidal .zarr')
|
|
1233
|
+
self.is_pyramid = True
|
|
1234
|
+
|
|
1235
|
+
self.levels = [array_ds(z[n]) for n in array_names]
|
|
1236
|
+
a.levels = self.levels
|
|
1237
|
+
|
|
1238
|
+
else:
|
|
1239
|
+
a = array_ds(z)
|
|
1240
|
+
|
|
1241
|
+
logger.debug('Setting data')
|
|
1242
|
+
self.SetData(a)
|
|
1243
|
+
|
|
1244
|
+
self.seriesName = getRelFilename(fn)
|
|
1245
|
+
self.mode = 'default'
|
|
1246
|
+
|
|
1247
|
+
print('loaded zarr')
|
|
1248
|
+
|
|
1249
|
+
|
|
1250
|
+
def Load(self, filename=None, prompt=None, haveGUI = False):
|
|
1251
|
+
"""
|
|
1252
|
+
Load a file from disk / queue / cluster
|
|
1253
|
+
|
|
1254
|
+
NB: this is usually called from __init__. Call ImageStack(filename = filename) rather than calling this function directly.
|
|
1255
|
+
|
|
1256
|
+
Parameters
|
|
1257
|
+
----------
|
|
1258
|
+
filename : str [optional]
|
|
1259
|
+
filename or URI of data to load. Natively supported types are:
|
|
1260
|
+
- .tif
|
|
1261
|
+
- .h5 (PYME HDF5 format)
|
|
1262
|
+
- .npy (numpy array)
|
|
1263
|
+
- .psf (PYME PSF files)
|
|
1264
|
+
- .dbl (Bewersdorf STED files)
|
|
1265
|
+
- .dcimg (Hamamatsu .dcimg)
|
|
1266
|
+
- QUEUE:// (PYME task queue data)
|
|
1267
|
+
- PYME-CLUSTER:// (Data stored in our custom cluster file system)
|
|
1268
|
+
- .md (sequence of images with a type supported by PIL, described by a .md metadta file)
|
|
1269
|
+
|
|
1270
|
+
If the filename doesn't match one of these patterns, we fall back on bioformats, if available. This works
|
|
1271
|
+
well for most biological file formats, but can be fairly slow. At present, .tif is handled by our native
|
|
1272
|
+
handler (which falls back on the excellent Gohlke tiffile library) and .tiff is handled by bioformats.
|
|
1273
|
+
|
|
1274
|
+
If no filename is given, we display an open file dialog box.
|
|
1275
|
+
|
|
1276
|
+
Returns
|
|
1277
|
+
-------
|
|
1278
|
+
|
|
1279
|
+
"""
|
|
1280
|
+
print('filename == %s' % filename)
|
|
1281
|
+
if (filename is None or filename == ''):
|
|
1282
|
+
import wx #only introduce wx dependency here - so can be used non-interactively
|
|
1283
|
+
global lastdir
|
|
1284
|
+
|
|
1285
|
+
#fdialog = wx.FileDialog(None, 'Please select Data Stack to open ...',
|
|
1286
|
+
# wildcard='Image Data|*.h5;*.tif;*.lsm;*.kdf;*.md;*.psf;*.npy;*.dbl|All files|*.*', style=wx.OPEN, defaultDir = lastdir)
|
|
1287
|
+
#succ = fdialog.ShowModal()
|
|
1288
|
+
#if (succ == wx.ID_OK):
|
|
1289
|
+
# filename = fdialog.GetPath()
|
|
1290
|
+
# lastdir = fdialog.GetDirectory()
|
|
1291
|
+
#else:
|
|
1292
|
+
#print succ
|
|
1293
|
+
|
|
1294
|
+
if prompt is None:
|
|
1295
|
+
prompt = 'Please select Data Stack to open ...'
|
|
1296
|
+
|
|
1297
|
+
filename = wx.FileSelector(prompt,
|
|
1298
|
+
wildcard='Image Data|*.h5;*.tif;*.lsm;*.kdf;*.md;*.psf;*.npy;*.dbl|All files|*.*',
|
|
1299
|
+
default_path = lastdir)
|
|
1300
|
+
|
|
1301
|
+
if filename is None or filename == '':
|
|
1302
|
+
raise FileSelectionError('No file selected')
|
|
1303
|
+
pass
|
|
1304
|
+
else:
|
|
1305
|
+
lastdir = os.path.split(filename)[0]
|
|
1306
|
+
#print(succ, filename)
|
|
1307
|
+
|
|
1308
|
+
if not filename is None:
|
|
1309
|
+
if filename.startswith('QUEUE://'):
|
|
1310
|
+
self._loadQueue(filename)
|
|
1311
|
+
elif filename.startswith('http://'):
|
|
1312
|
+
self._loadHTTP(filename)
|
|
1313
|
+
elif (filename.startswith('PYME-CLUSTER://') or filename.startswith('pyme-cluster://')) and not (filename.split('.')[-1] in ['psf', 'sf', 'md', 'npy', 'tif', 'tiff', 'lsm', 'dcimg']):
|
|
1314
|
+
self._loadClusterPZF(filename)
|
|
1315
|
+
elif (filename.upper().startswith('SUPERTILE:')):
|
|
1316
|
+
self._load_supertile(filename)
|
|
1317
|
+
elif (filename.endswith('.tiles') or filename.endswith('.tiles/')):
|
|
1318
|
+
self._load_tiles(filename)
|
|
1319
|
+
elif (filename.upper().startswith('CONCATENATED://')):
|
|
1320
|
+
self._load_concatenated(filename)
|
|
1321
|
+
elif filename.endswith('.h5'):
|
|
1322
|
+
self._loadh5(filename)
|
|
1323
|
+
#elif filename.endswith('.kdf'):
|
|
1324
|
+
# self.LoadKdf(filename)
|
|
1325
|
+
elif filename.endswith('.psf'): #psf
|
|
1326
|
+
self._loadPSF(filename)
|
|
1327
|
+
elif filename.endswith('.sf'): #shift field
|
|
1328
|
+
self._loadSF(filename)
|
|
1329
|
+
elif filename.endswith('.md'): #treat this as being an image series
|
|
1330
|
+
self._loadImageSeries(filename)
|
|
1331
|
+
elif filename.endswith('.npy'): #treat this as being an image series
|
|
1332
|
+
self._loadNPY(filename)
|
|
1333
|
+
elif filename.endswith('.dbl'): #treat this as being an image series
|
|
1334
|
+
self._loadDBL(filename)
|
|
1335
|
+
elif '.obf' in os.path.splitext(filename)[1] or '.msr' in os.path.splitext(filename)[1]:
|
|
1336
|
+
self._loadOBF(filename)
|
|
1337
|
+
# hack to get around self.filename = filename below, otherwise if we open multiple
|
|
1338
|
+
# stacks from this same file we won't be able to make composite later
|
|
1339
|
+
filename = self.seriesName
|
|
1340
|
+
elif os.path.splitext(filename)[1] in ['.tif', '.lsm']: #try tiff
|
|
1341
|
+
self._loadTiff(filename)
|
|
1342
|
+
elif filename.endswith('.dcimg'):
|
|
1343
|
+
self._loadDCIMG(filename)
|
|
1344
|
+
elif filename.endswith('.pzf'):
|
|
1345
|
+
self._loadPZF(filename)
|
|
1346
|
+
elif '.zarr' in filename:
|
|
1347
|
+
# check for `in` rather than `endswith` as we use query notation for groups.
|
|
1348
|
+
self._load_zarr(filename)
|
|
1349
|
+
else: #try bioformats
|
|
1350
|
+
try:
|
|
1351
|
+
self._loadBioformats(filename)
|
|
1352
|
+
except (ImportError, RuntimeError):
|
|
1353
|
+
# We don't have bioformats - check to see if the file is in a format which we could also read
|
|
1354
|
+
# natively (.tiff). Complains loudly about having to do this as by convention the .tiff extension
|
|
1355
|
+
# is used to force bioformats loading of tiffs which we otherwise wouldn't understand.
|
|
1356
|
+
|
|
1357
|
+
if os.path.splitext(filename)[1] in ['.tiff']:
|
|
1358
|
+
PYME.pyme_warnings.warn("Bioformats could not be loaded, trying to load .tiff using native TIFF loader.\n\
|
|
1359
|
+
This might not work as expected as the .tiff format is typically used for TIFFs\
|
|
1360
|
+
which don\'t load properly using the native code.\n\
|
|
1361
|
+
Try installing python-bioformats as detailed in step 4 of the installation instructions \
|
|
1362
|
+
(http://python-microscopy.org/doc/Installation/InstallationWithAnaconda.html)")
|
|
1363
|
+
|
|
1364
|
+
self._loadTiff(filename)
|
|
1365
|
+
else:
|
|
1366
|
+
PYME.pyme_warnings.warn('No native support for file type, and Bioformats could not be loaded. \n\
|
|
1367
|
+
Try installing python-bioformats as detailed in step 4 of the installation instructions \
|
|
1368
|
+
(http://python-microscopy.org/doc/Installation/InstallationWithAnaconda.html')
|
|
1369
|
+
|
|
1370
|
+
raise RuntimeError('Cannot load file %s, no native handler and failed to import bioformats' % filename)
|
|
1371
|
+
|
|
1372
|
+
|
|
1373
|
+
|
|
1374
|
+
#self.SetTitle(filename)
|
|
1375
|
+
self.filename = filename
|
|
1376
|
+
self.saved = True
|
|
1377
|
+
|
|
1378
|
+
def Save(self, filename=None, crop=False, roi=None, progressCallback=None):
|
|
1379
|
+
warnings.warn(DeprecationWarning('The "Save" method is deprecated, please use "save" instead'))
|
|
1380
|
+
self.save(filename=filename, crop=crop, roi=roi, progressCallback=progressCallback)
|
|
1381
|
+
|
|
1382
|
+
def save(self, filename=None, crop=False, roi=None, progressCallback=None):
|
|
1383
|
+
"""
|
|
1384
|
+
Saves an image to file.
|
|
1385
|
+
|
|
1386
|
+
Parameters
|
|
1387
|
+
----------
|
|
1388
|
+
filename : str
|
|
1389
|
+
The filename to save to. File type is deduced by the extension. For supported data types, see PYME.IO.dataExporter.
|
|
1390
|
+
If no filename is given, we display a dialog box to ask.
|
|
1391
|
+
|
|
1392
|
+
crop : bool
|
|
1393
|
+
Do we want to crop the image? Note that this displays a cropping dialog box (ie needs a GUI) and requires
|
|
1394
|
+
that view be defined. TODO - remove GUI dependance
|
|
1395
|
+
|
|
1396
|
+
view : PYME.DSView.arrayViewPanel instance
|
|
1397
|
+
Our current view of the data. Used to get selection information to provide starting values for our crop region
|
|
1398
|
+
TODO - make this GUI independant by passing the selection / crop region to save.
|
|
1399
|
+
|
|
1400
|
+
Returns
|
|
1401
|
+
-------
|
|
1402
|
+
|
|
1403
|
+
"""
|
|
1404
|
+
from PYME.IO import dataExporter
|
|
1405
|
+
|
|
1406
|
+
ofn = self.filename
|
|
1407
|
+
|
|
1408
|
+
if crop:
|
|
1409
|
+
import warnings
|
|
1410
|
+
warnings.warn('The "crop" argument is deprecated, please use CropDataSource.crop_image(...).Save() instead')
|
|
1411
|
+
from PYME.ui.crop_dialog import CropExportData
|
|
1412
|
+
CropExportData(self.data_xyztc, roi, self.mdh, self.events, self.seriesName)
|
|
1413
|
+
else:
|
|
1414
|
+
if 'defaultExt' in dir(self):
|
|
1415
|
+
self.filename = dataExporter.ExportData(self.data_xyztc, self.mdh, self.events, defaultExt=self.defaultExt, filename=filename, progressCallback=progressCallback)
|
|
1416
|
+
else:
|
|
1417
|
+
self.filename = dataExporter.ExportData(self.data_xyztc, self.mdh, self.events, filename=filename, progressCallback=progressCallback)
|
|
1418
|
+
#self.SetTitle(fn)
|
|
1419
|
+
|
|
1420
|
+
if not (self.filename is None):
|
|
1421
|
+
self.saved = True
|
|
1422
|
+
|
|
1423
|
+
try:
|
|
1424
|
+
openImages.pop(ofn)
|
|
1425
|
+
except KeyError:
|
|
1426
|
+
# if the image does not already have a filename / is not in the list of exisiting images ignore and continue
|
|
1427
|
+
pass
|
|
1428
|
+
|
|
1429
|
+
openImages[self.filename] = self
|
|
1430
|
+
|
|
1431
|
+
else:
|
|
1432
|
+
self.filename = ofn
|
|
1433
|
+
|
|
1434
|
+
|
|
1435
|
+
def GeneratedImage(img, imgBounds, pixelSize, sliceSize, channelNames, mdh=None):
|
|
1436
|
+
"""Helper function for LMVis which creates an image and fills in a few
|
|
1437
|
+
metadata parameters"""
|
|
1438
|
+
image = ImageStack(img, mdh=mdh)
|
|
1439
|
+
image.pixelSize = pixelSize
|
|
1440
|
+
image.sliceSize = sliceSize
|
|
1441
|
+
image.imgBounds = imgBounds
|
|
1442
|
+
image.names = [c if c else 'Image' for c in channelNames]
|
|
1443
|
+
|
|
1444
|
+
return image
|
|
1445
|
+
|
|
1446
|
+
|
|
1447
|
+
|