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/recipes/recipe.py
ADDED
|
@@ -0,0 +1,965 @@
|
|
|
1
|
+
from PYME.recipes.traits import HasTraits, List, Bool
|
|
2
|
+
from PYME.contrib import dispatch
|
|
3
|
+
from .base import ModuleBase, OutputModule
|
|
4
|
+
from PYME.recipes import base
|
|
5
|
+
from PYME.IO.image import ImageStack
|
|
6
|
+
from PYME.IO import tabular, csv_flavours
|
|
7
|
+
import time
|
|
8
|
+
|
|
9
|
+
import logging
|
|
10
|
+
logger = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
#custom error types
|
|
15
|
+
class RecipeError(Exception):
|
|
16
|
+
pass
|
|
17
|
+
class RecipeModuleNotFoundError(RecipeError):
|
|
18
|
+
pass
|
|
19
|
+
|
|
20
|
+
class RecipeExecutionError(RecipeError):
|
|
21
|
+
def __init__(self, msg, recipe=None):
|
|
22
|
+
Exception.__init__(self, msg)
|
|
23
|
+
|
|
24
|
+
self.recipe = recipe # keep a reference to the recipe so that handlers can get fancy with formatting if they want to
|
|
25
|
+
|
|
26
|
+
#def __getstate__(self):
|
|
27
|
+
#
|
|
28
|
+
# return {}
|
|
29
|
+
|
|
30
|
+
# make this pickle-able even when the recipe isn't (so you see the error when running from bakeshop)
|
|
31
|
+
def __reduce__(self):
|
|
32
|
+
return self.__class__, self.args
|
|
33
|
+
|
|
34
|
+
class Recipe(HasTraits):
|
|
35
|
+
modules = List()
|
|
36
|
+
execute_on_invalidation = Bool(False)
|
|
37
|
+
|
|
38
|
+
def __init__(self, *args, **kwargs):
|
|
39
|
+
HasTraits.__init__(self, *args, **kwargs)
|
|
40
|
+
|
|
41
|
+
self.namespace = {}
|
|
42
|
+
|
|
43
|
+
# we open hdf files and don't necessarily read their contents into memory - these need to be closed when we
|
|
44
|
+
# either delete the recipe, or clear the namespace
|
|
45
|
+
self._open_input_files = []
|
|
46
|
+
|
|
47
|
+
self.recipe_changed = dispatch.Signal()
|
|
48
|
+
self.recipe_executed = dispatch.Signal()
|
|
49
|
+
self.recipe_failed = dispatch.Signal()
|
|
50
|
+
|
|
51
|
+
self.failed = False
|
|
52
|
+
|
|
53
|
+
self._dg_sig = None
|
|
54
|
+
|
|
55
|
+
self._exec_times = {} #record module run times ...
|
|
56
|
+
|
|
57
|
+
def invalidate_data(self):
|
|
58
|
+
if self.execute_on_invalidation:
|
|
59
|
+
self.execute()
|
|
60
|
+
|
|
61
|
+
def clear(self):
|
|
62
|
+
self.namespace.clear()
|
|
63
|
+
|
|
64
|
+
def new_output_name(self, stub):
|
|
65
|
+
count = len([k for k in self.namespace.keys() if k.startswith(stub)])
|
|
66
|
+
|
|
67
|
+
if count == 0:
|
|
68
|
+
return stub
|
|
69
|
+
else:
|
|
70
|
+
return '%s_%d' % (stub, count)
|
|
71
|
+
|
|
72
|
+
def dependancyGraph(self):
|
|
73
|
+
dg = {}
|
|
74
|
+
|
|
75
|
+
#only add items to dependancy graph if they are not already in the namespace
|
|
76
|
+
#calculated_objects = namespace.keys()
|
|
77
|
+
|
|
78
|
+
for mod in self.modules:
|
|
79
|
+
#print mod
|
|
80
|
+
s = mod.inputs
|
|
81
|
+
|
|
82
|
+
try:
|
|
83
|
+
s.update(dg[mod])
|
|
84
|
+
except KeyError:
|
|
85
|
+
pass
|
|
86
|
+
|
|
87
|
+
dg[mod] = s
|
|
88
|
+
|
|
89
|
+
for op in mod.outputs:
|
|
90
|
+
#if not op in calculated_objects:
|
|
91
|
+
dg[op] = {mod, }
|
|
92
|
+
|
|
93
|
+
return dg
|
|
94
|
+
|
|
95
|
+
def reverseDependancyGraph(self):
|
|
96
|
+
dg = self.dependancyGraph()
|
|
97
|
+
|
|
98
|
+
rdg = {}
|
|
99
|
+
|
|
100
|
+
for k, vs in dg.items():
|
|
101
|
+
for v in vs:
|
|
102
|
+
vdeps = set()
|
|
103
|
+
try:
|
|
104
|
+
vdeps = rdg[v]
|
|
105
|
+
except KeyError:
|
|
106
|
+
pass
|
|
107
|
+
|
|
108
|
+
vdeps.add(k)
|
|
109
|
+
rdg[v] = vdeps
|
|
110
|
+
|
|
111
|
+
return rdg
|
|
112
|
+
|
|
113
|
+
def _getAllDownstream(self, rdg, keys):
|
|
114
|
+
"""get all the downstream items which depend on the given key"""
|
|
115
|
+
|
|
116
|
+
downstream = set()
|
|
117
|
+
|
|
118
|
+
next_level = set()
|
|
119
|
+
|
|
120
|
+
for k in keys:
|
|
121
|
+
try:
|
|
122
|
+
next_level.update(rdg[k])
|
|
123
|
+
except KeyError:
|
|
124
|
+
pass
|
|
125
|
+
|
|
126
|
+
if len(list(next_level)) > 0:
|
|
127
|
+
downstream.update(next_level)
|
|
128
|
+
|
|
129
|
+
downstream.update(self._getAllDownstream(rdg, list(next_level)))
|
|
130
|
+
|
|
131
|
+
return downstream
|
|
132
|
+
|
|
133
|
+
def upstream_inputs(self, keys):
|
|
134
|
+
dg = self.dependancyGraph()
|
|
135
|
+
|
|
136
|
+
def walk_upstream(keys):
|
|
137
|
+
upstream = set()
|
|
138
|
+
for k in keys:
|
|
139
|
+
u = dg.get(k, None)
|
|
140
|
+
if u is not None:
|
|
141
|
+
upstream.update(walk_upstream(list(u)))
|
|
142
|
+
|
|
143
|
+
return upstream
|
|
144
|
+
|
|
145
|
+
return list(walk_upstream(keys))
|
|
146
|
+
|
|
147
|
+
def downstream_outputs(self, keys):
|
|
148
|
+
rdg = self.reverseDependancyGraph()
|
|
149
|
+
return list(self._getAllDownstream(rdg, list(keys)))
|
|
150
|
+
|
|
151
|
+
def prune_dependencies_from_namespace(self, keys_to_prune, keep_passed_keys=False):
|
|
152
|
+
rdg = self.reverseDependancyGraph()
|
|
153
|
+
|
|
154
|
+
if keep_passed_keys:
|
|
155
|
+
downstream = list(self._getAllDownstream(rdg, list(keys_to_prune)))
|
|
156
|
+
else:
|
|
157
|
+
downstream = list(keys_to_prune) + list(self._getAllDownstream(rdg, list(keys_to_prune)))
|
|
158
|
+
|
|
159
|
+
#print downstream
|
|
160
|
+
|
|
161
|
+
for dsi in downstream:
|
|
162
|
+
try:
|
|
163
|
+
self.namespace.pop(dsi)
|
|
164
|
+
except KeyError:
|
|
165
|
+
#the output is not in our namespace, no need to prune
|
|
166
|
+
pass
|
|
167
|
+
except AttributeError:
|
|
168
|
+
#we might not have our namespace defined yet
|
|
169
|
+
pass
|
|
170
|
+
|
|
171
|
+
def resolveDependencies(self):
|
|
172
|
+
import toposort
|
|
173
|
+
#build dependancy graph
|
|
174
|
+
|
|
175
|
+
dg = self.dependancyGraph()
|
|
176
|
+
|
|
177
|
+
#solve the dependency tree
|
|
178
|
+
return toposort.toposort_flatten(dg, sort=False)
|
|
179
|
+
|
|
180
|
+
def execute(self, progress_callback=None, **kwargs):
|
|
181
|
+
"""
|
|
182
|
+
Execute the recipe. Recipe execution is lazy / incremental in that modules will only be executed if their outputs
|
|
183
|
+
are no longer in the namespace or their inputs have changed.
|
|
184
|
+
|
|
185
|
+
Parameters
|
|
186
|
+
----------
|
|
187
|
+
progress_callback : a function, progress_callback(recipe, module)
|
|
188
|
+
This function is called after the successful execution of each module in the recipe. To abort the recipe,
|
|
189
|
+
an exception may be raised in progress_callback.
|
|
190
|
+
kwargs : any values to set in the recipe namespace prior to executing.
|
|
191
|
+
|
|
192
|
+
Returns
|
|
193
|
+
-------
|
|
194
|
+
|
|
195
|
+
output : the value of the 'output' variable in the namespace if present, otherwise none. output is only used in
|
|
196
|
+
dh5view and ignored in recipe batch processing. It might well disappear completely in the future.
|
|
197
|
+
|
|
198
|
+
"""
|
|
199
|
+
#remove anything which is downstream from changed inputs
|
|
200
|
+
|
|
201
|
+
try:
|
|
202
|
+
logger.debug('recipe.execute()')
|
|
203
|
+
#print self.namespace.keys()
|
|
204
|
+
for k, v in kwargs.items():
|
|
205
|
+
#print k, v
|
|
206
|
+
try:
|
|
207
|
+
if not (self.namespace[k] == v):
|
|
208
|
+
#input has changed
|
|
209
|
+
# print('pruning: ', k) # possibly change these into logging/debug messages
|
|
210
|
+
self.prune_dependencies_from_namespace([k])
|
|
211
|
+
except KeyError:
|
|
212
|
+
#key wasn't in namespace previously
|
|
213
|
+
# print('KeyError') # possibly change these into logging/debug messages
|
|
214
|
+
pass
|
|
215
|
+
|
|
216
|
+
self.namespace.update(kwargs)
|
|
217
|
+
|
|
218
|
+
exec_order = self.resolveDependencies()
|
|
219
|
+
#logger.debug('exec_order: %s' % exec_order)
|
|
220
|
+
#logger.debug('.modules: %s' % self.modules)
|
|
221
|
+
#logger.debug('recipe instance: %s' % self)
|
|
222
|
+
|
|
223
|
+
self._last_error = None
|
|
224
|
+
|
|
225
|
+
#mark all modules which should execute as not having executed
|
|
226
|
+
for m in exec_order:
|
|
227
|
+
if isinstance(m, ModuleBase) and not m.outputs_in_namespace(self.namespace):
|
|
228
|
+
m._success = False
|
|
229
|
+
|
|
230
|
+
for m in exec_order:
|
|
231
|
+
#if isinstance(m, ModuleBase):
|
|
232
|
+
# logger.debug('Checking whether to execute: %s, %s, %s' % (m, m._success, m.outputs_in_namespace(self.namespace)))
|
|
233
|
+
if isinstance(m, ModuleBase) and not getattr(m, '_success', False):
|
|
234
|
+
try:
|
|
235
|
+
logger.debug('Executing %s' % m)
|
|
236
|
+
ts = time.time()
|
|
237
|
+
m.check_inputs(self.namespace)
|
|
238
|
+
m.execute(self.namespace)
|
|
239
|
+
self._exec_times[base.module_names[m.__class__]] = time.time() - ts
|
|
240
|
+
m._last_error = None
|
|
241
|
+
m._success = True
|
|
242
|
+
if progress_callback:
|
|
243
|
+
progress_callback(self, m)
|
|
244
|
+
except:
|
|
245
|
+
import traceback
|
|
246
|
+
logger.exception("Error in recipe module: %s" % m)
|
|
247
|
+
|
|
248
|
+
#record our error so that we can associate it with a module
|
|
249
|
+
m._last_error = traceback.format_exc()
|
|
250
|
+
self.failed = True
|
|
251
|
+
self._failing_module = m
|
|
252
|
+
self._last_error = m._last_error
|
|
253
|
+
|
|
254
|
+
# make sure we didn't leave any partial results
|
|
255
|
+
logger.debug('removing failed module dependencies')
|
|
256
|
+
self.prune_dependencies_from_namespace(m.outputs)
|
|
257
|
+
logger.debug('notifying failure')
|
|
258
|
+
self.recipe_failed.send_robust(self)
|
|
259
|
+
raise
|
|
260
|
+
|
|
261
|
+
if self.failed:
|
|
262
|
+
# make sure we update the GUI if we've fixed a broken recipe
|
|
263
|
+
# TODO - make make this a bit lighter weight - we shouldn't need to redraw the whole recipe just to change
|
|
264
|
+
# the shading of the module caption
|
|
265
|
+
self.recipe_changed.send_robust(self)
|
|
266
|
+
|
|
267
|
+
self.failed = False
|
|
268
|
+
self.recipe_executed.send_robust(self)
|
|
269
|
+
|
|
270
|
+
logger.debug('Module timings: %s' % self._exec_times )
|
|
271
|
+
|
|
272
|
+
# detect changes in recipe wiring
|
|
273
|
+
dg_sig = str(self.dependancyGraph())
|
|
274
|
+
if not self._dg_sig == dg_sig:
|
|
275
|
+
#print(dg_sig)
|
|
276
|
+
#print(self._dg_sig)
|
|
277
|
+
self._dg_sig = dg_sig
|
|
278
|
+
self.recipe_changed.send_robust(self)
|
|
279
|
+
|
|
280
|
+
if 'output' in self.namespace.keys():
|
|
281
|
+
return self.namespace['output']
|
|
282
|
+
except Exception as e:
|
|
283
|
+
raise RecipeExecutionError('Recipe execution failed in module %s' % self._failing_module._module_name, self ) from e
|
|
284
|
+
|
|
285
|
+
@classmethod
|
|
286
|
+
def fromMD(cls, md):
|
|
287
|
+
c = cls()
|
|
288
|
+
|
|
289
|
+
moduleNames = set([s.split('.')[0] for s in md.keys()])
|
|
290
|
+
|
|
291
|
+
mc = []
|
|
292
|
+
|
|
293
|
+
for mn in moduleNames:
|
|
294
|
+
mod = base.all_modules[mn]()
|
|
295
|
+
mod.set(**md[mn])
|
|
296
|
+
mc.append(mod)
|
|
297
|
+
|
|
298
|
+
#return cls(modules=mc)
|
|
299
|
+
c.modules = mc
|
|
300
|
+
|
|
301
|
+
return c
|
|
302
|
+
|
|
303
|
+
def get_cleaned_module_list(self):
|
|
304
|
+
# l = []
|
|
305
|
+
# for mod in self.modules:
|
|
306
|
+
# #l.append({mod.__class__.__name__: mod.get()})
|
|
307
|
+
|
|
308
|
+
# ct = mod.class_traits()
|
|
309
|
+
|
|
310
|
+
# mod_traits_cleaned = {}
|
|
311
|
+
# for k, v in mod.get().items():
|
|
312
|
+
# if not k.startswith('_'): #don't save private data - this is usually used for caching etc ..,
|
|
313
|
+
# try:
|
|
314
|
+
# if (not (v == ct[k].default)) or (k.startswith('input')) or (k.startswith('output')):
|
|
315
|
+
# #don't save defaults
|
|
316
|
+
# if isinstance(v, dict) and not type(v) == dict:
|
|
317
|
+
# v = dict(v)
|
|
318
|
+
# elif isinstance(v, list) and not type(v) == list:
|
|
319
|
+
# v = list(v)
|
|
320
|
+
# elif isinstance(v, set) and not type(v) == set:
|
|
321
|
+
# v = set(v)
|
|
322
|
+
|
|
323
|
+
# mod_traits_cleaned[k] = v
|
|
324
|
+
# except KeyError:
|
|
325
|
+
# # for some reason we have a trait that shouldn't be here
|
|
326
|
+
# pass
|
|
327
|
+
|
|
328
|
+
# l.append({base.module_names[mod.__class__]: mod_traits_cleaned})
|
|
329
|
+
|
|
330
|
+
# return l
|
|
331
|
+
return [m.cleaned_dict_repr() for m in self.modules]
|
|
332
|
+
|
|
333
|
+
def to_html(self, show_progress=True, show_errors=True):
|
|
334
|
+
import jinja2
|
|
335
|
+
import inspect
|
|
336
|
+
template = inspect.cleandoc('''\
|
|
337
|
+
{% for mod in modules %}
|
|
338
|
+
<div {% if mod._last_error %}style="border-style:solid;padding: 10px;border-color: darkred;" {% endif %}>
|
|
339
|
+
<pre style="font-size: 8pt;color: {% if mod._success %}darkgreen{% elif mod._last_error %}darkred{% else %}black{% endif %};"> {{ mod.toYAML() }} </pre>
|
|
340
|
+
{% if mod._last_error %}<pre style="font-size: 8pt;color:darkred">{{ mod._last_error}}</pre> {% endif %}
|
|
341
|
+
</div>
|
|
342
|
+
{% endfor %}
|
|
343
|
+
''')
|
|
344
|
+
|
|
345
|
+
return jinja2.Template(template).render(modules=self.modules, last_error=getattr(self, '_last_error', ''))
|
|
346
|
+
|
|
347
|
+
def toYAML(self):
|
|
348
|
+
import yaml
|
|
349
|
+
|
|
350
|
+
return yaml.dump(self.get_cleaned_module_list(), Dumper=base.MyDumper)
|
|
351
|
+
|
|
352
|
+
def save_yaml(self, uri):
|
|
353
|
+
"""
|
|
354
|
+
Save the recipe text to .yaml using the cluster-aware unified IO library
|
|
355
|
+
|
|
356
|
+
WARNING: Experimental - this was added as a quick hack to get web-based recipe editing working, and WILL LIKELY
|
|
357
|
+
BE REMOVED without deprecation once that moves to using a recipe-manager. Whilst arguably the least contentious
|
|
358
|
+
of the web-editor additions, it is unclear whether the saving logic (past dumping to YAML in the toYAML()
|
|
359
|
+
method) should reside within the recipe itself. As the recipe class is proxied into the browser, there are also
|
|
360
|
+
potential security implications here, particularly as this accepts both filenames and clusterURIs. As a
|
|
361
|
+
consequence, saving should probably be factored out into something which can operate in an appropriate sandbox
|
|
362
|
+
(the other option is to sandbox unifiedIO).
|
|
363
|
+
|
|
364
|
+
Parameters
|
|
365
|
+
----------
|
|
366
|
+
uri: str
|
|
367
|
+
A filename or PYME-CLUSTER:// URI
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
"""
|
|
371
|
+
from PYME.IO import unifiedIO
|
|
372
|
+
|
|
373
|
+
unifiedIO.write(uri, self.toYAML().encode())
|
|
374
|
+
|
|
375
|
+
def toJSON(self):
|
|
376
|
+
import json
|
|
377
|
+
return json.dumps(self.get_cleaned_module_list())
|
|
378
|
+
|
|
379
|
+
def _update_from_module_list(self, l):
|
|
380
|
+
"""
|
|
381
|
+
Update from a parsed yaml or json list of modules
|
|
382
|
+
|
|
383
|
+
It probably makes no sense to call this directly as the format is pretty wack - a
|
|
384
|
+
list of dictionarys each with a single entry, but that is how the yaml parses
|
|
385
|
+
|
|
386
|
+
Parameters
|
|
387
|
+
----------
|
|
388
|
+
l: list
|
|
389
|
+
List of modules as obtained from parsing a yaml recipe,
|
|
390
|
+
Each module is a dictionary mapping with a single e.g.
|
|
391
|
+
[{'Filtering.Filter': {'filters': {'probe': [-0.5, 0.5]}, 'input': 'localizations', 'output': 'filtered'}}]
|
|
392
|
+
|
|
393
|
+
Returns
|
|
394
|
+
-------
|
|
395
|
+
|
|
396
|
+
"""
|
|
397
|
+
# delete all outputs from the previous set of recipe modules
|
|
398
|
+
self.prune_dependencies_from_namespace(self.module_outputs)
|
|
399
|
+
|
|
400
|
+
mc = []
|
|
401
|
+
|
|
402
|
+
if l is None:
|
|
403
|
+
l = []
|
|
404
|
+
|
|
405
|
+
for mdd in l:
|
|
406
|
+
mn, md = list(mdd.items())[0]
|
|
407
|
+
try:
|
|
408
|
+
mod = base.all_modules[mn](self, **md)
|
|
409
|
+
except KeyError:
|
|
410
|
+
# still support loading old recipes which do not use hierarchical names
|
|
411
|
+
# also try and support modules which might have moved
|
|
412
|
+
try:
|
|
413
|
+
mod = base._legacy_modules[mn.split('.')[-1]](self, **md)
|
|
414
|
+
except KeyError:
|
|
415
|
+
raise RecipeModuleNotFoundError('No recipe module found with name "%s"\nThis could either be caused by a typo in the module name or a missing 3rd party plugin.' % mn) from None # Full traceback is probably unhelpful for people using modules
|
|
416
|
+
|
|
417
|
+
mc.append(mod)
|
|
418
|
+
|
|
419
|
+
self.modules = mc
|
|
420
|
+
|
|
421
|
+
self.recipe_changed.send_robust(self)
|
|
422
|
+
self.invalidate_data()
|
|
423
|
+
|
|
424
|
+
@classmethod
|
|
425
|
+
def _from_module_list(cls, l):
|
|
426
|
+
""" A factory method which contains the common logic for loading/creating from either
|
|
427
|
+
yaml or json. Do not call directly"""
|
|
428
|
+
c = cls()
|
|
429
|
+
c._update_from_module_list(l)
|
|
430
|
+
|
|
431
|
+
return c
|
|
432
|
+
|
|
433
|
+
@classmethod
|
|
434
|
+
def fromYAML(cls, data):
|
|
435
|
+
import yaml
|
|
436
|
+
|
|
437
|
+
l = yaml.safe_load(data)
|
|
438
|
+
return cls._from_module_list(l)
|
|
439
|
+
|
|
440
|
+
def update_from_yaml(self, data):
|
|
441
|
+
"""
|
|
442
|
+
Update from a yaml formatted recipe description
|
|
443
|
+
|
|
444
|
+
Parameters
|
|
445
|
+
----------
|
|
446
|
+
data: str
|
|
447
|
+
either yaml formatted text, or the path to a yaml file.
|
|
448
|
+
|
|
449
|
+
Returns
|
|
450
|
+
-------
|
|
451
|
+
None
|
|
452
|
+
|
|
453
|
+
"""
|
|
454
|
+
import os
|
|
455
|
+
import yaml
|
|
456
|
+
|
|
457
|
+
if os.path.isfile(data):
|
|
458
|
+
with open(data) as f:
|
|
459
|
+
data = f.read()
|
|
460
|
+
|
|
461
|
+
l = yaml.safe_load(data)
|
|
462
|
+
|
|
463
|
+
return self._update_from_module_list(l)
|
|
464
|
+
|
|
465
|
+
def update_from_file(self, filename):
|
|
466
|
+
"""
|
|
467
|
+
Update the contents of the recipe from a .yaml file
|
|
468
|
+
|
|
469
|
+
WARNING: This function will likely be REMOVED WITHOUT NOTICE. It is a quick hack to get the prototype web-based
|
|
470
|
+
recipe editor working, but will be surplus to requirements once we have a proper recipe manager in the web based
|
|
471
|
+
editor. It's logically obtuse to consider something the same recipe once you've completely replaced it with a
|
|
472
|
+
recipe that has been loaded from file. It is much more sensible to create a new recipe instance when loading
|
|
473
|
+
a recipe from file, and this is the recommended approach.
|
|
474
|
+
|
|
475
|
+
Parameters
|
|
476
|
+
----------
|
|
477
|
+
filename: str
|
|
478
|
+
filename or PYME-CLUSTER:// URI
|
|
479
|
+
|
|
480
|
+
"""
|
|
481
|
+
from PYME.IO import unifiedIO
|
|
482
|
+
|
|
483
|
+
self.update_from_yaml(unifiedIO.read(filename).decode())
|
|
484
|
+
|
|
485
|
+
@classmethod
|
|
486
|
+
def fromJSON(cls, data):
|
|
487
|
+
import json
|
|
488
|
+
return cls._from_module_list(json.loads(data))
|
|
489
|
+
|
|
490
|
+
def add_module(self, module):
|
|
491
|
+
self.modules.append(module)
|
|
492
|
+
self.recipe_changed.send_robust(self)
|
|
493
|
+
|
|
494
|
+
def add_modules_and_execute(self, modules, rollback_on_failure=True):
|
|
495
|
+
"""
|
|
496
|
+
Adds modules to the recipe and then execute the recipe. Added to make UI interaction in PYMEVis a bit nicer when
|
|
497
|
+
modules added from the menu fail, this function gives the option (enabled by default) of rolling back the
|
|
498
|
+
additions should execute fail.
|
|
499
|
+
|
|
500
|
+
Parameters
|
|
501
|
+
----------
|
|
502
|
+
modules : list
|
|
503
|
+
a list of modules to add
|
|
504
|
+
rollback_on_failure : bool
|
|
505
|
+
rollback and remove modules (and their outputs) if .execute() fails
|
|
506
|
+
|
|
507
|
+
"""
|
|
508
|
+
|
|
509
|
+
try:
|
|
510
|
+
for m in modules:
|
|
511
|
+
self.modules.append(m)
|
|
512
|
+
|
|
513
|
+
self.execute()
|
|
514
|
+
except:
|
|
515
|
+
if rollback_on_failure:
|
|
516
|
+
#do cleanup
|
|
517
|
+
|
|
518
|
+
#remove any outputs
|
|
519
|
+
for m in modules:
|
|
520
|
+
self.prune_dependencies_from_namespace(m.outputs)
|
|
521
|
+
|
|
522
|
+
#remove the modules themselves
|
|
523
|
+
for m in modules:
|
|
524
|
+
self.modules.remove(m)
|
|
525
|
+
|
|
526
|
+
raise
|
|
527
|
+
finally:
|
|
528
|
+
self.recipe_changed.send_robust(self)
|
|
529
|
+
|
|
530
|
+
def remove_module(self, m):
|
|
531
|
+
self.prune_dependencies_from_namespace(m.outputs)
|
|
532
|
+
self.modules.remove(m)
|
|
533
|
+
self.recipe_changed.send_robust(self)
|
|
534
|
+
|
|
535
|
+
@property
|
|
536
|
+
def inputs(self):
|
|
537
|
+
ip = set()
|
|
538
|
+
for mod in self.modules:
|
|
539
|
+
ip.update({k for k in mod.inputs if k.startswith('in')})
|
|
540
|
+
return ip
|
|
541
|
+
|
|
542
|
+
@property
|
|
543
|
+
def inferred_inputs(self):
|
|
544
|
+
'''Return a set of inputs which are not outputs of any module'''
|
|
545
|
+
ops = self.module_outputs
|
|
546
|
+
|
|
547
|
+
ip = set()
|
|
548
|
+
for mod in self.modules:
|
|
549
|
+
ip.update({k for k in mod.inputs if not k in ops})
|
|
550
|
+
|
|
551
|
+
return ip
|
|
552
|
+
|
|
553
|
+
@property
|
|
554
|
+
def inferred_data(self):
|
|
555
|
+
'''Return a set of recipe namespace residents which are not outputs of any module.
|
|
556
|
+
This reflects data which has been loaded from file, or otherwise injected into the namespace.
|
|
557
|
+
|
|
558
|
+
Used when serialising PYMEVis sessions.
|
|
559
|
+
'''
|
|
560
|
+
ops = self.module_outputs
|
|
561
|
+
data = {k for k in self.namespace.keys() if not k in ops}
|
|
562
|
+
|
|
563
|
+
return data
|
|
564
|
+
|
|
565
|
+
@property
|
|
566
|
+
def has_insaved_injections(self):
|
|
567
|
+
'''Return true if the recipe has any data which has been injected into the namespace (rather than loaded from file)
|
|
568
|
+
|
|
569
|
+
Indicates if a session can be serialised successfully.
|
|
570
|
+
#TODO - does this belong here on in session management/ the pipeline
|
|
571
|
+
'''
|
|
572
|
+
|
|
573
|
+
for d in self.inferred_data:
|
|
574
|
+
if not getattr(self.namespace[d], 'filename', None):
|
|
575
|
+
return True
|
|
576
|
+
|
|
577
|
+
return False
|
|
578
|
+
|
|
579
|
+
@property
|
|
580
|
+
def outputs(self):
|
|
581
|
+
op = set()
|
|
582
|
+
for mod in self.modules:
|
|
583
|
+
op.update({k for k in mod.outputs if k.startswith('out')})
|
|
584
|
+
return op
|
|
585
|
+
|
|
586
|
+
@property
|
|
587
|
+
def module_outputs(self):
|
|
588
|
+
op = set()
|
|
589
|
+
for mod in self.modules:
|
|
590
|
+
op.update(set(mod.outputs))
|
|
591
|
+
return op
|
|
592
|
+
|
|
593
|
+
@property
|
|
594
|
+
def file_inputs(self):
|
|
595
|
+
out = []
|
|
596
|
+
for mod in self.modules:
|
|
597
|
+
out += mod.file_inputs
|
|
598
|
+
|
|
599
|
+
return out
|
|
600
|
+
|
|
601
|
+
def save(self, context={}):
|
|
602
|
+
"""
|
|
603
|
+
Find all OutputModule instances and call their save methods with the recipe context
|
|
604
|
+
|
|
605
|
+
Parameters
|
|
606
|
+
----------
|
|
607
|
+
context : dict
|
|
608
|
+
A context dictionary used to substitute and create variable names.
|
|
609
|
+
|
|
610
|
+
"""
|
|
611
|
+
for mod in self.modules:
|
|
612
|
+
if isinstance(mod, OutputModule):
|
|
613
|
+
mod.save(self.namespace, context)
|
|
614
|
+
|
|
615
|
+
def gather_outputs(self, context={}):
|
|
616
|
+
"""
|
|
617
|
+
Find all OutputModule instances and call their generate methods with the recipe context
|
|
618
|
+
|
|
619
|
+
Parameters
|
|
620
|
+
----------
|
|
621
|
+
context : dict
|
|
622
|
+
A context dictionary used to substitute and create variable names.
|
|
623
|
+
|
|
624
|
+
"""
|
|
625
|
+
|
|
626
|
+
outputs = []
|
|
627
|
+
|
|
628
|
+
for mod in self.modules:
|
|
629
|
+
if isinstance(mod, OutputModule):
|
|
630
|
+
out = mod.generate(self.namespace, context)
|
|
631
|
+
|
|
632
|
+
if not out is None:
|
|
633
|
+
outputs.append(out)
|
|
634
|
+
|
|
635
|
+
return outputs
|
|
636
|
+
|
|
637
|
+
def _get_tables_from_hdf5(self, filename, extension=None, h5f=None, cache={}):
|
|
638
|
+
try:
|
|
639
|
+
return cache[filename]
|
|
640
|
+
except KeyError:
|
|
641
|
+
if h5f:
|
|
642
|
+
output = self.__get_tables_from_hdf5(h5f, filename, extension)
|
|
643
|
+
else:
|
|
644
|
+
import tables
|
|
645
|
+
from PYME.IO import h5rFile
|
|
646
|
+
from PYME.IO import unifiedIO
|
|
647
|
+
try:
|
|
648
|
+
with unifiedIO.local_or_temp_filename(filename) as fn, h5rFile.openH5R(fn, mode='r') as h5f:
|
|
649
|
+
output = self.__get_tables_from_hdf5(h5f._h5file, fn, extension)
|
|
650
|
+
except tables.exceptions.HDF5ExtError: # access issue likely due to multiple processes
|
|
651
|
+
if unifiedIO.is_cluster_uri(filename):
|
|
652
|
+
# try again, this time forcing access through the dataserver
|
|
653
|
+
# NOTE: it is unclear why this should work when local_or_temp_filename() doesn't
|
|
654
|
+
# as this still opens / copies the file independently, albeit in the same process as is doing the writing.
|
|
655
|
+
# The fact that this works is relying on one of a quirk of the GIL, a quirk in HDF5 locking, or the fact
|
|
656
|
+
# that copying the file to a stream is much faster than opening it with pytables. The copy vs pytables open
|
|
657
|
+
# scenario would match what has been observed with old style spooling analysis where copying a file
|
|
658
|
+
# prior to opening in VisGUI would work more reliably than opening directly. This retains, however,
|
|
659
|
+
# an inherent race condition so we risk replacing a predictable failure with a less frequent one.
|
|
660
|
+
# TODO - consider whether h5r_part might be a better choice.
|
|
661
|
+
# FIXME: (DB) I'm not comfortable with having this kind of special case retry logic here, and would
|
|
662
|
+
# much prefer if we could find an alternative workaround, refactor into something like h5rFile.open_robust(),
|
|
663
|
+
# or just let this fail). Leaving it for the meantime to get chained recipes working, but we should revisit.
|
|
664
|
+
from PYME.IO import clusterIO
|
|
665
|
+
relative_filename, server_filter = unifiedIO.split_cluster_url(filename)
|
|
666
|
+
file_as_bytes = clusterIO.get_file(relative_filename, serverfilter=server_filter,
|
|
667
|
+
local_short_circuit=False)
|
|
668
|
+
with tables.open_file('in-memory.h5', driver='H5FD_CORE', driver_core_image=file_as_bytes,
|
|
669
|
+
driver_core_backing_store=0) as h5f:
|
|
670
|
+
self.__get_tables_from_hdf5(h5f, filename, extension)
|
|
671
|
+
else:
|
|
672
|
+
#not a cluster file, doesn't make sense to retry with cluster. Propagate exception to user.
|
|
673
|
+
raise
|
|
674
|
+
except:
|
|
675
|
+
logger.exception('Error reading HDF file: %s' % filename)
|
|
676
|
+
raise IOError('Error reading %s' % filename)
|
|
677
|
+
|
|
678
|
+
for o in output.values():
|
|
679
|
+
o.filename = filename
|
|
680
|
+
|
|
681
|
+
cache[filename] = output
|
|
682
|
+
return output
|
|
683
|
+
|
|
684
|
+
|
|
685
|
+
def __get_tables_from_hdf5(self, h5f, filename, extension=None):
|
|
686
|
+
"""
|
|
687
|
+
Search through hdf5 file nodes and add them to the recipe namespace
|
|
688
|
+
|
|
689
|
+
Parameters
|
|
690
|
+
----------
|
|
691
|
+
key : str
|
|
692
|
+
base key name for loaded file components, if key is not the default 'input', each file node will be loaded into
|
|
693
|
+
recipe namespace with `key`_`node_name`.
|
|
694
|
+
h5f : file
|
|
695
|
+
open hdf5 file
|
|
696
|
+
filename : str
|
|
697
|
+
full filename
|
|
698
|
+
extension : str
|
|
699
|
+
file extension, used here mainly to toggle which PYME.IO.tabular source is used for table nodes.
|
|
700
|
+
"""
|
|
701
|
+
import tables
|
|
702
|
+
from PYME.IO import MetaDataHandler, tabular
|
|
703
|
+
import os
|
|
704
|
+
|
|
705
|
+
if extension is None:
|
|
706
|
+
extension = os.path.splitext(filename)[1]
|
|
707
|
+
|
|
708
|
+
output={}
|
|
709
|
+
|
|
710
|
+
#key_prefix = '' if key == 'input' else key + '_'
|
|
711
|
+
|
|
712
|
+
# Handle a 'MetaData' group as a special case
|
|
713
|
+
# TODO - find/implement a more portable way of handling metadata in HDF (e.g. as .json in a blob) so that
|
|
714
|
+
# non-python exporters have a chance of adding metadata
|
|
715
|
+
if 'MetaData' in h5f.root:
|
|
716
|
+
mdh = MetaDataHandler.NestedClassMDHandler(MetaDataHandler.HDFMDHandler(h5f))
|
|
717
|
+
else:
|
|
718
|
+
logger.warning('No metadata found, proceeding with empty metadata')
|
|
719
|
+
mdh = MetaDataHandler.NestedClassMDHandler()
|
|
720
|
+
|
|
721
|
+
events = None
|
|
722
|
+
# handle an 'Events' table as a special case (so that it can be attached to subsequently loaded tables)
|
|
723
|
+
# FIXME - this relies on a special /reserved table name and format and could raise name collision issues
|
|
724
|
+
# when importing 3rd party / generic HDF
|
|
725
|
+
# FIXME - do we really want to attach events (which will not get propagated through recipe modules)
|
|
726
|
+
if ('Events' in h5f.root):
|
|
727
|
+
if 'EventName' in h5f.root.Events.description._v_names:
|
|
728
|
+
# check that the event table is formatted as we expect
|
|
729
|
+
if ('StartTime' in mdh.keys()):
|
|
730
|
+
events = h5f.root.Events[:]
|
|
731
|
+
else:
|
|
732
|
+
logger.warning('Acquisition events found in .hdf, but no "StartTime" in metadata')
|
|
733
|
+
else:
|
|
734
|
+
logger.warning(
|
|
735
|
+
'Table called "Events" found in .hdf does not match the signature for acquisition events, ignoring')
|
|
736
|
+
|
|
737
|
+
for t in h5f.list_nodes('/'):
|
|
738
|
+
# FIXME - The following isinstance tests are not very safe (and badly broken in some cases e.g.
|
|
739
|
+
# PZF formatted image data, Image data which is not in an EArray, etc ...)
|
|
740
|
+
# Note that EArray is only used for streaming data!
|
|
741
|
+
# They should ideally be replaced with more comprehensive tests (potentially based on array or dataset
|
|
742
|
+
# dimensionality and/or data type) - i.e. duck typing. Our strategy for images in HDF should probably
|
|
743
|
+
# also be improved / clarified - can we use hdf attributes to hint at the data intent? How do we support
|
|
744
|
+
# > 3D data?
|
|
745
|
+
|
|
746
|
+
if getattr(t, 'name', None) == 'Events':
|
|
747
|
+
# NB: This assumes we've handled this in the special case earlier, and blocks anything in a 3rd party
|
|
748
|
+
# HDF events table from being seen.
|
|
749
|
+
# TODO - do we really want to have so much special case stuff in our generic hdf handling? Are we sure
|
|
750
|
+
# that events shouldn't be injected into the namespace (given that events do not propagate through recipe modules)?
|
|
751
|
+
continue
|
|
752
|
+
|
|
753
|
+
elif isinstance(t, tables.VLArray):
|
|
754
|
+
from PYME.IO.ragged import RaggedVLArray
|
|
755
|
+
|
|
756
|
+
rag = RaggedVLArray(h5f, t.name,
|
|
757
|
+
copy=True) #force an in-memory copy so we can close the hdf file properly
|
|
758
|
+
rag.mdh = mdh
|
|
759
|
+
if events is not None:
|
|
760
|
+
rag.events = events
|
|
761
|
+
|
|
762
|
+
#self.namespace[key_prefix + t.name] = rag
|
|
763
|
+
rag.query = f'table={t.name}' # add a query string so we can reload it
|
|
764
|
+
output[t.name] = rag
|
|
765
|
+
|
|
766
|
+
elif isinstance(t, tables.table.Table):
|
|
767
|
+
# pipe our table into h5r or hdf source depending on the extension
|
|
768
|
+
if extension == '.h5r':
|
|
769
|
+
if t.name == 'DriftResults':
|
|
770
|
+
tab = tabular.H5RDSource(h5f)
|
|
771
|
+
else:
|
|
772
|
+
tab = tabular.H5RSource(h5f, t.name)
|
|
773
|
+
else:
|
|
774
|
+
tab = tabular.HDFSource(h5f, t.name)
|
|
775
|
+
|
|
776
|
+
tab.mdh = mdh
|
|
777
|
+
if events is not None:
|
|
778
|
+
tab.events = events
|
|
779
|
+
|
|
780
|
+
#self.namespace[key_prefix + t.name] = tab
|
|
781
|
+
tab.query = f'table={t.name}' # add a query string so we can reload it
|
|
782
|
+
output[t.name] = tab
|
|
783
|
+
|
|
784
|
+
elif isinstance(t, tables.EArray):
|
|
785
|
+
logger.warning('Image data found in .hdf, attempting to load (this may not work). In general, use .h5 for hdf image data')
|
|
786
|
+
# load using ImageStack._loadh5
|
|
787
|
+
# FIXME - ._loadh5 will load events lazily, which isn't great if we got here after
|
|
788
|
+
# sending file over clusterIO inside of a context manager -> force it through since we already found it
|
|
789
|
+
im = ImageStack(filename=filename, mdh=mdh, events=events, haveGUI=False)
|
|
790
|
+
# assume image is the main table in the file and give it the named key
|
|
791
|
+
#self.namespace[key] = im
|
|
792
|
+
im.query = f'table={t.name}' # add a query string so we can reload it
|
|
793
|
+
output[t.name] = im
|
|
794
|
+
|
|
795
|
+
|
|
796
|
+
return output
|
|
797
|
+
|
|
798
|
+
def _inject_tables_from_hdf5(self, key, filename, extension, cache={}, h5f=None):
|
|
799
|
+
key_prefix = '' if key in ['input', '', None] else key + '_' # prefix for keys in the namespace
|
|
800
|
+
|
|
801
|
+
tables = self._get_tables_from_hdf5(filename, extension=extension, cache=cache, h5f=h5f)
|
|
802
|
+
self.namespace.update({key_prefix + k: v for k, v in tables.items()})
|
|
803
|
+
|
|
804
|
+
|
|
805
|
+
def load_inputs(self, inputs, metadata_defaults={}, raise_on_error=True):
|
|
806
|
+
"""
|
|
807
|
+
load inputs from a dictionary mapping keys to filenames
|
|
808
|
+
"""
|
|
809
|
+
cache={} #cache hdf5 files so we don't have to re-open them when we have multiple manually specified tables
|
|
810
|
+
|
|
811
|
+
for k, v in inputs.items():
|
|
812
|
+
if k == '__sim':
|
|
813
|
+
# skip the simulation flag
|
|
814
|
+
continue
|
|
815
|
+
|
|
816
|
+
try:
|
|
817
|
+
self._load_input(v, key=k, metadata_defaults=metadata_defaults, cache=cache)
|
|
818
|
+
except Exception as e:
|
|
819
|
+
if raise_on_error:
|
|
820
|
+
raise RecipeError('Error loading input %s from %s' % (k, v)) from e
|
|
821
|
+
else:
|
|
822
|
+
logger.exception('Error loading input %s from %s' % (k, v))
|
|
823
|
+
|
|
824
|
+
def _load_input(self, filename, key='input', metadata_defaults={}, cache={}, default_to_image=True, args={}):
|
|
825
|
+
"""
|
|
826
|
+
Load input data from a file and inject into namespace
|
|
827
|
+
"""
|
|
828
|
+
from PYME.IO import unifiedIO
|
|
829
|
+
import os
|
|
830
|
+
|
|
831
|
+
args = dict(args) # make a copy so we don't modify the original
|
|
832
|
+
|
|
833
|
+
if '?' in filename:
|
|
834
|
+
from urllib.parse import parse_qs
|
|
835
|
+
filename, query = filename.split('?')
|
|
836
|
+
args.update(parse_qs(query))
|
|
837
|
+
args = {k: v if len(v)>1 else v[0] for k, v in args.items()}
|
|
838
|
+
else:
|
|
839
|
+
query=None
|
|
840
|
+
|
|
841
|
+
extension = os.path.splitext(filename)[1]
|
|
842
|
+
if extension in ['.h5r', '.hdf']:
|
|
843
|
+
if 'table' in args:
|
|
844
|
+
# we have specified a specific table to load from the hdf5 file
|
|
845
|
+
self.namespace[key] = self._get_tables_from_hdf5(filename, extension, cache=cache)[args['table']]
|
|
846
|
+
else:
|
|
847
|
+
self._inject_tables_from_hdf5(key, filename, extension, cache=cache)
|
|
848
|
+
|
|
849
|
+
elif extension in ['.xls', '.xlsx']:
|
|
850
|
+
logger.error('loading .xls not supported yet')
|
|
851
|
+
raise NotImplementedError
|
|
852
|
+
elif extension == '.mat': #matlab file
|
|
853
|
+
with unifiedIO.local_or_temp_filename(filename) as fn:
|
|
854
|
+
if 'VarName' in args.keys():
|
|
855
|
+
#old style matlab import
|
|
856
|
+
ds = tabular.MatfileSource(fn, args['FieldNames'], args['VarName'])
|
|
857
|
+
ds.query = f'VarName={args["VarName"]}&FieldNames={args["FieldNames"]}'
|
|
858
|
+
else:
|
|
859
|
+
if args.get('Multichannel', False):
|
|
860
|
+
ds = tabular.MatfileMultiColumnSource(fn)
|
|
861
|
+
ds.query = 'Multichannel=True'
|
|
862
|
+
else:
|
|
863
|
+
ds = tabular.MatfileColumnSource(fn)
|
|
864
|
+
ds.query = ''
|
|
865
|
+
|
|
866
|
+
# check for column name mapping
|
|
867
|
+
field_names = args.get('FieldNames', None)
|
|
868
|
+
if field_names:
|
|
869
|
+
if ds.query:
|
|
870
|
+
ds.query += '&'
|
|
871
|
+
ds.query += '&'.join([f'FieldNames={fn}' for fn in field_names])
|
|
872
|
+
if field_names:
|
|
873
|
+
if args.get('Multichannel', False):
|
|
874
|
+
field_names.append('probe') # don't forget to copy this field over
|
|
875
|
+
ds = tabular.MappingFilter(ds, **{new_field : old_field for new_field, old_field in zip(field_names, ds.keys())})
|
|
876
|
+
|
|
877
|
+
ds.filename = filename
|
|
878
|
+
self.namespace[key] = ds
|
|
879
|
+
|
|
880
|
+
elif extension == '.h5ad':
|
|
881
|
+
with unifiedIO.local_or_temp_filename(filename) as fn:
|
|
882
|
+
ds = tabular.AnndataSource(filename)
|
|
883
|
+
|
|
884
|
+
ds.filename = filename
|
|
885
|
+
self.namespace[key] = ds
|
|
886
|
+
|
|
887
|
+
elif (not default_to_image) or (extension in csv_flavours.text_extensions):
|
|
888
|
+
with unifiedIO.local_or_temp_filename(filename) as fn:
|
|
889
|
+
# tab or csv formatted text file
|
|
890
|
+
text_options = args.get('text_options', None)
|
|
891
|
+
if text_options is None:
|
|
892
|
+
logger.info('Guessing text file format ...')
|
|
893
|
+
text_options = csv_flavours.guess_text_options(filename)
|
|
894
|
+
text_options.update(args) #override with any user specified options (as query string)
|
|
895
|
+
|
|
896
|
+
ds = tabular.TextfileSource(filename, **text_options)
|
|
897
|
+
|
|
898
|
+
from urllib.parse import urlencode
|
|
899
|
+
|
|
900
|
+
ds.query = urlencode(csv_flavours.strict_options(text_options), doseq=True)
|
|
901
|
+
ds.filename = filename
|
|
902
|
+
self.namespace[key] = ds
|
|
903
|
+
|
|
904
|
+
else: # assume it's an image
|
|
905
|
+
if query:
|
|
906
|
+
filename = filename + '?' + query #reconstruct the filename with the query string as this is processed by some imaghe types
|
|
907
|
+
im = ImageStack(filename=filename, haveGUI=False)
|
|
908
|
+
if im.mdh.get('voxelize.x', None) is None:
|
|
909
|
+
logger.error('No voxelsize metadata found for image %s, using defaults' % filename)
|
|
910
|
+
im.mdh.mergeEntriesFrom(metadata_defaults)
|
|
911
|
+
self.namespace[key] = im
|
|
912
|
+
|
|
913
|
+
@property
|
|
914
|
+
def pipeline_view(self):
|
|
915
|
+
import wx
|
|
916
|
+
if wx.GetApp() is None:
|
|
917
|
+
return None
|
|
918
|
+
else:
|
|
919
|
+
from traitsui.api import View, ListEditor, InstanceEditor, Item
|
|
920
|
+
#v = tu.View(tu.Item('modules', editor=tu.ListEditor(use_notebook=True, view='pipeline_view'), style='custom', show_label=False),
|
|
921
|
+
# buttons=['OK', 'Cancel'])
|
|
922
|
+
|
|
923
|
+
return View(Item('modules', editor=ListEditor(style='custom', editor=InstanceEditor(view='pipeline_view'),
|
|
924
|
+
mutable=False),
|
|
925
|
+
style='custom', show_label=False),
|
|
926
|
+
buttons=['OK'])
|
|
927
|
+
|
|
928
|
+
def to_svg(self):
|
|
929
|
+
from . import recipeLayout
|
|
930
|
+
return recipeLayout.to_svg(self.dependancyGraph())
|
|
931
|
+
|
|
932
|
+
def layout(self):
|
|
933
|
+
""" Added as a visualisation aid for the web-based recipe editor. Very much a work in progress and not
|
|
934
|
+
guaranteed to remain in it's current form.
|
|
935
|
+
|
|
936
|
+
TODO - does this logic belong here????
|
|
937
|
+
TODO - rename?? (potentially make it webui specific)???
|
|
938
|
+
TODO - potential issues on Py3 with how jigna treats namedtuple?
|
|
939
|
+
"""
|
|
940
|
+
from . import recipeLayout
|
|
941
|
+
#from collections import namedtuple
|
|
942
|
+
#layout_info = namedtuple('layout', ['node_positions', 'connecting_lines'])
|
|
943
|
+
#node = namedtuple('node', ['key', 'pos'])
|
|
944
|
+
class layout_info(object):
|
|
945
|
+
def __init__(self, node_positions, connecting_lines):
|
|
946
|
+
self.node_positions = node_positions
|
|
947
|
+
self.connecting_lines = connecting_lines
|
|
948
|
+
|
|
949
|
+
class node(object):
|
|
950
|
+
def __init__(self, key, pos):
|
|
951
|
+
self.key = key
|
|
952
|
+
self.pos = pos
|
|
953
|
+
|
|
954
|
+
node_positions, connecting_lines = recipeLayout.layout(self.dependancyGraph())
|
|
955
|
+
ret = layout_info([node(k, v) for k, v in node_positions.items()],
|
|
956
|
+
[(a.tolist(), b.tolist(), c) for a, b, c in connecting_lines])
|
|
957
|
+
#print (ret)
|
|
958
|
+
return ret
|
|
959
|
+
|
|
960
|
+
def _repr_mimebundle_(self):
|
|
961
|
+
""" Make us look pretty in Jupyter"""
|
|
962
|
+
try:
|
|
963
|
+
return {'text/svg+xml' : self.to_svg()}
|
|
964
|
+
except ModuleNotFoundError:
|
|
965
|
+
return {'text/plain' : repr(self) + '\nTo enable pretty formatting of recipes in jupyter, install the `svgwrite` module'}
|