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
|
@@ -0,0 +1,1063 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
This is a very simple HTTP server which allows data to be saved to the server using PUT
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
.. warning::
|
|
7
|
+
**Security warning**
|
|
8
|
+
|
|
9
|
+
The code as it stands lets any client write arbitrary data to the server.
|
|
10
|
+
The only concessions we make to security are:
|
|
11
|
+
|
|
12
|
+
a) Paths are vetted to make sure that they reside under our server root (i.e. no escape through .. etc)
|
|
13
|
+
b) We enforce a write-once scheme (if a file exists it can't be overridden)
|
|
14
|
+
|
|
15
|
+
This protects against people accidentally or maliciously altering data, or discovering
|
|
16
|
+
server settings, but leaves us open to denial of service type attacks in which
|
|
17
|
+
a malicious client could fill up our storage.
|
|
18
|
+
|
|
19
|
+
**THE CODE AS IT STANDS SHOULD ONLY BE USED ON A TRUSTED NETWORK**
|
|
20
|
+
|
|
21
|
+
TODO: Add some form of authentication. Needs to be low overhead (e.g. digest based)
|
|
22
|
+
"""
|
|
23
|
+
from PYME import config
|
|
24
|
+
from PYME.misc.computerName import GetComputerName
|
|
25
|
+
compName = GetComputerName()
|
|
26
|
+
import os
|
|
27
|
+
import html
|
|
28
|
+
import sys
|
|
29
|
+
|
|
30
|
+
import errno
|
|
31
|
+
def makedirs_safe(dir):
|
|
32
|
+
"""
|
|
33
|
+
A safe wrapper for makedirs, which won't throw an error if the directory already exists. This replicates the functionality
|
|
34
|
+
of the exists_ok flag in the python 3 version of os.makedirs, but should work with both pytion 2 and python 3.
|
|
35
|
+
|
|
36
|
+
Parameters
|
|
37
|
+
----------
|
|
38
|
+
dir : str, directory to be created
|
|
39
|
+
|
|
40
|
+
Returns
|
|
41
|
+
-------
|
|
42
|
+
|
|
43
|
+
"""
|
|
44
|
+
try:
|
|
45
|
+
os.makedirs(dir)
|
|
46
|
+
except OSError as e:
|
|
47
|
+
if e.errno != errno.EEXIST:
|
|
48
|
+
raise
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
#make sure we set up our logging before anyone elses does
|
|
52
|
+
import logging
|
|
53
|
+
import logging.handlers
|
|
54
|
+
dataserver_root = config.get('dataserver-root')
|
|
55
|
+
# if dataserver_root:
|
|
56
|
+
# log_dir = '%s/LOGS/%s' % (dataserver_root, compName)
|
|
57
|
+
# #if not os.path.exists(log_dir):
|
|
58
|
+
# # os.makedirs(log_dir)
|
|
59
|
+
# makedirs_safe(log_dir)
|
|
60
|
+
#
|
|
61
|
+
# log_file = '%s/LOGS/%s/PYMEDataServer.log' % (dataserver_root, compName)
|
|
62
|
+
#
|
|
63
|
+
# #logging.basicConfig(filename =log_file, level=logging.DEBUG, filemode='w')
|
|
64
|
+
# #logger = logging.getLogger('')
|
|
65
|
+
# logger = logging.getLogger('')
|
|
66
|
+
# logger.setLevel(logging.DEBUG)
|
|
67
|
+
# fh = logging.handlers.RotatingFileHandler(filename=log_file, mode='w', maxBytes=1e6, backupCount=1)
|
|
68
|
+
# logger.addHandler(fh)
|
|
69
|
+
# else:
|
|
70
|
+
logging.basicConfig(level=logging.DEBUG)
|
|
71
|
+
logger = logging.getLogger('')
|
|
72
|
+
|
|
73
|
+
#now do all the normal imports
|
|
74
|
+
|
|
75
|
+
#import SimpleHTTPServer
|
|
76
|
+
#import BaseHTTPServer
|
|
77
|
+
# noinspection PyCompatibility
|
|
78
|
+
import http.server
|
|
79
|
+
# noinspection PyCompatibility
|
|
80
|
+
from socketserver import ThreadingMixIn
|
|
81
|
+
|
|
82
|
+
from io import StringIO, BytesIO
|
|
83
|
+
import shutil
|
|
84
|
+
#import urllib
|
|
85
|
+
import sys
|
|
86
|
+
import ujson as json
|
|
87
|
+
import PYME.misc.pyme_zeroconf as pzc
|
|
88
|
+
from PYME.misc import sqlite_ns
|
|
89
|
+
|
|
90
|
+
try:
|
|
91
|
+
# noinspection PyCompatibility
|
|
92
|
+
import urlparse
|
|
93
|
+
except ImportError:
|
|
94
|
+
#py3
|
|
95
|
+
# noinspection PyCompatibility
|
|
96
|
+
from urllib import parse as urlparse
|
|
97
|
+
|
|
98
|
+
import requests
|
|
99
|
+
import socket
|
|
100
|
+
#import fcntl
|
|
101
|
+
import threading
|
|
102
|
+
import datetime
|
|
103
|
+
import time
|
|
104
|
+
from PYME.IO import h5File
|
|
105
|
+
from PYME.IO.FileUtils.nameUtils import get_service_name
|
|
106
|
+
#GPU status functions
|
|
107
|
+
try:
|
|
108
|
+
import pynvml
|
|
109
|
+
GPU_STATS=True
|
|
110
|
+
except ImportError:
|
|
111
|
+
GPU_STATS = False
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
compName = GetComputerName()
|
|
115
|
+
procName = compName + ' - PID:%d' % os.getpid()
|
|
116
|
+
|
|
117
|
+
LOG_REQUESTS = False#True
|
|
118
|
+
USE_DIR_CACHE = True
|
|
119
|
+
|
|
120
|
+
startTime = datetime.datetime.now()
|
|
121
|
+
#global_status = {}
|
|
122
|
+
|
|
123
|
+
status = {}
|
|
124
|
+
_net = {}
|
|
125
|
+
_last_update_time = time.time()
|
|
126
|
+
try:
|
|
127
|
+
import psutil
|
|
128
|
+
_net.update(psutil.net_io_counters(True))
|
|
129
|
+
except ImportError:
|
|
130
|
+
pass
|
|
131
|
+
|
|
132
|
+
def updateStatus():
|
|
133
|
+
global _last_update_time
|
|
134
|
+
from PYME.IO.FileUtils.freeSpace import disk_usage
|
|
135
|
+
|
|
136
|
+
#status = {}
|
|
137
|
+
#status.update(global_status)
|
|
138
|
+
|
|
139
|
+
total, used, free = disk_usage(os.getcwd())
|
|
140
|
+
status['Disk'] = {'total': total, 'used': used, 'free': free}
|
|
141
|
+
status['Uptime'] = str(datetime.datetime.now() - startTime)
|
|
142
|
+
|
|
143
|
+
try:
|
|
144
|
+
import psutil
|
|
145
|
+
|
|
146
|
+
ut = time.time()
|
|
147
|
+
|
|
148
|
+
status['CPUUsage'] = psutil.cpu_percent(interval=0, percpu=True)
|
|
149
|
+
status['MemUsage'] = psutil.virtual_memory()._asdict()
|
|
150
|
+
|
|
151
|
+
nets = psutil.net_io_counters(True)
|
|
152
|
+
dt = ut - _last_update_time
|
|
153
|
+
|
|
154
|
+
status['Network'] = {iface : {'send' : (nets[iface].bytes_sent - _net[iface].bytes_sent)/dt,
|
|
155
|
+
'recv' : (nets[iface].bytes_recv - _net[iface].bytes_recv)/dt} for iface in nets.keys()}
|
|
156
|
+
|
|
157
|
+
_net.update(nets)
|
|
158
|
+
_last_update_time = ut
|
|
159
|
+
except ImportError:
|
|
160
|
+
pass
|
|
161
|
+
|
|
162
|
+
if GPU_STATS:
|
|
163
|
+
handles = [pynvml.nvmlDeviceGetHandleByIndex(i) for i in range(pynvml.nvmlDeviceGetCount())]
|
|
164
|
+
gpu_usage = [pynvml.nvmlDeviceGetUtilizationRates(h) for h in handles]
|
|
165
|
+
status['GPUUsage'] = [float(gu.gpu) for gu in gpu_usage]
|
|
166
|
+
status['GPUMem'] = [float(gu.memory) for gu in gpu_usage]
|
|
167
|
+
|
|
168
|
+
class statusPoller(threading.Thread):
|
|
169
|
+
def __init__(self, *args, **kwargs):
|
|
170
|
+
self.poll = True
|
|
171
|
+
|
|
172
|
+
threading.Thread.__init__(self, *args, **kwargs)
|
|
173
|
+
self.daemon = True
|
|
174
|
+
|
|
175
|
+
def run(self):
|
|
176
|
+
while self.poll:
|
|
177
|
+
updateStatus()
|
|
178
|
+
time.sleep(1)
|
|
179
|
+
|
|
180
|
+
def stop(self):
|
|
181
|
+
self.poll = False
|
|
182
|
+
|
|
183
|
+
textfile_locks = {}
|
|
184
|
+
def getTextFileLock(filename):
|
|
185
|
+
try:
|
|
186
|
+
return textfile_locks[filename]
|
|
187
|
+
except KeyError:
|
|
188
|
+
textfile_locks[filename] = threading.Lock()
|
|
189
|
+
return textfile_locks[filename]
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
from collections import OrderedDict
|
|
193
|
+
|
|
194
|
+
class _LimitedSizeDict(OrderedDict):
|
|
195
|
+
def __init__(self, *args, **kwds):
|
|
196
|
+
self.size_limit = kwds.pop("size_limit", None)
|
|
197
|
+
OrderedDict.__init__(self, *args, **kwds)
|
|
198
|
+
self._check_size_limit()
|
|
199
|
+
|
|
200
|
+
def __setitem__(self, key, value):
|
|
201
|
+
OrderedDict.__setitem__(self, key, value)
|
|
202
|
+
self._check_size_limit()
|
|
203
|
+
|
|
204
|
+
def _check_size_limit(self):
|
|
205
|
+
if self.size_limit is not None:
|
|
206
|
+
while len(self) > self.size_limit:
|
|
207
|
+
self.popitem(last=False)
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
_dirCache = _LimitedSizeDict(size_limit=100)
|
|
211
|
+
_dirCacheTimeout = 1
|
|
212
|
+
|
|
213
|
+
#_listDirLock = threading.Lock()
|
|
214
|
+
|
|
215
|
+
from PYME.IO import clusterListing as cl
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
part_pyramids = {}
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
class PYMEHTTPRequestHandler(http.server.SimpleHTTPRequestHandler):
|
|
222
|
+
protocol_version = "HTTP/1.0"
|
|
223
|
+
bandwidthTesting = False
|
|
224
|
+
timeoutTesting = 0
|
|
225
|
+
logrequests = False
|
|
226
|
+
timeout=None
|
|
227
|
+
|
|
228
|
+
def __init__(self, *args, **kwargs):
|
|
229
|
+
self._path_cache = _LimitedSizeDict(size_limit=1000)
|
|
230
|
+
http.server.SimpleHTTPRequestHandler.__init__(self, *args, **kwargs)
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
def _aggregate_txt(self):
|
|
234
|
+
"""
|
|
235
|
+
support for results aggregation (append into a file). This 'method' does a dumb append to the file on disk,
|
|
236
|
+
meaning that it will require reasonably carefully formatted input (with, e.g., a trailing newlines on each
|
|
237
|
+
chunk if results are in .csv
|
|
238
|
+
This is mostly intended for output in csv or similar formats, where chunks can be 'cat'ed together.
|
|
239
|
+
|
|
240
|
+
NOTE: there is no guarantee of ordering, so the record format should contain enough information to re-order
|
|
241
|
+
the data if necessary
|
|
242
|
+
"""
|
|
243
|
+
path = self.translate_path(self.path.lstrip('/')[len('__aggregate_txt'):])
|
|
244
|
+
|
|
245
|
+
data = self._get_data()
|
|
246
|
+
|
|
247
|
+
#if self.headers['Content-Encoding'] == 'gzip':
|
|
248
|
+
# data = self._gzip_decompress(data)
|
|
249
|
+
|
|
250
|
+
dirname = os.path.dirname(path)
|
|
251
|
+
#if not os.path.exists(dirname):
|
|
252
|
+
# os.makedirs(dirname)
|
|
253
|
+
makedirs_safe(dirname)
|
|
254
|
+
|
|
255
|
+
if USE_DIR_CACHE and not os.path.exists(path):
|
|
256
|
+
# only update directory cache on initial creation to avoid lock thrashing. Use a placeholder size to indicate file is not complete
|
|
257
|
+
cl.dir_cache.update_cache(path, -1)
|
|
258
|
+
|
|
259
|
+
#append the contents of the put request
|
|
260
|
+
with getTextFileLock(path):
|
|
261
|
+
#lock so that we don't corrupt the data by writing from two different threads
|
|
262
|
+
#TODO ?? - keep a cache of open files
|
|
263
|
+
with open(path, 'ab') as f:
|
|
264
|
+
f.write(data)
|
|
265
|
+
|
|
266
|
+
self.send_response(200)
|
|
267
|
+
self.send_header("Content-Length", "0")
|
|
268
|
+
self.end_headers()
|
|
269
|
+
|
|
270
|
+
def _gzip_decompress(self, data):
|
|
271
|
+
import gzip
|
|
272
|
+
from io import BytesIO
|
|
273
|
+
zbuf = BytesIO(data)
|
|
274
|
+
zfile = gzip.GzipFile(mode='rb', fileobj=zbuf)#, compresslevel=9)
|
|
275
|
+
out = zfile.read()
|
|
276
|
+
zfile.close()
|
|
277
|
+
|
|
278
|
+
return out
|
|
279
|
+
|
|
280
|
+
def _get_data(self):
|
|
281
|
+
data = self.rfile.read(int(self.headers['Content-Length']))
|
|
282
|
+
|
|
283
|
+
if self.headers.get('Content-Encoding') == 'gzip':
|
|
284
|
+
data = self._gzip_decompress(data)
|
|
285
|
+
|
|
286
|
+
return data
|
|
287
|
+
|
|
288
|
+
def translate_path(self, path):
|
|
289
|
+
try:
|
|
290
|
+
return self._path_cache[path]
|
|
291
|
+
except KeyError:
|
|
292
|
+
self._path_cache[path] = http.server.SimpleHTTPRequestHandler.translate_path(self, path)
|
|
293
|
+
return self._path_cache[path]
|
|
294
|
+
|
|
295
|
+
def _aggregate_h5r(self):
|
|
296
|
+
"""
|
|
297
|
+
Support for results aggregation into an HDF5 file, using pytables.
|
|
298
|
+
We treat any path components after the .h5r as locations within the file (ie table names).
|
|
299
|
+
e.g. /path/to/data.h5r/<tablename>
|
|
300
|
+
A few special cases / Table names are accommodated:
|
|
301
|
+
|
|
302
|
+
MetaData: assumes we have sent PYME metadata in json format and saves to the file using the appropriate metadatahandler
|
|
303
|
+
No table name: assumes we have a fitResults object (as returned by remFitBuf and saves to the the appropriate tables (as HDF task queue would)
|
|
304
|
+
"""
|
|
305
|
+
import numpy as np
|
|
306
|
+
from io import BytesIO
|
|
307
|
+
from six.moves import cPickle
|
|
308
|
+
from PYME.IO import MetaDataHandler
|
|
309
|
+
from PYME.IO import h5rFile
|
|
310
|
+
|
|
311
|
+
# path = self.translate_path(self.path.lstrip('/')[len('__aggregate_h5r'):])
|
|
312
|
+
# filename, tablename = path.split('.h5r')
|
|
313
|
+
# filename += '.h5r'
|
|
314
|
+
|
|
315
|
+
# filename, tablename = self.path.lstrip('/')[len('__aggregate_h5r'):].split('.h5r')
|
|
316
|
+
# filename = self.translate_path(filename + '.h5r')
|
|
317
|
+
|
|
318
|
+
filename = self.path.lstrip('/')[len('__aggregate_h5r'):]
|
|
319
|
+
if '.h5r' in filename:
|
|
320
|
+
filename, tablename = filename.split('.h5r')
|
|
321
|
+
filename = self.translate_path(filename + '.h5r')
|
|
322
|
+
else:
|
|
323
|
+
filename, tablename = filename.split('.hdf')
|
|
324
|
+
filename = self.translate_path(filename + '.hdf')
|
|
325
|
+
|
|
326
|
+
data = self._get_data()
|
|
327
|
+
|
|
328
|
+
if not os.path.exists(filename):
|
|
329
|
+
dirname = os.path.dirname(filename)
|
|
330
|
+
#if not os.path.exists(dirname):
|
|
331
|
+
# os.makedirs(dirname)
|
|
332
|
+
makedirs_safe(dirname)
|
|
333
|
+
|
|
334
|
+
if USE_DIR_CACHE:
|
|
335
|
+
# only update directory cache on initial creation to avoid lock thrashing. Use a placeholder size to indicate file is not complete
|
|
336
|
+
cl.dir_cache.update_cache(filename, -1)
|
|
337
|
+
|
|
338
|
+
#logging.debug('opening h5r file')
|
|
339
|
+
with h5rFile.openH5R(filename, 'a') as h5f:
|
|
340
|
+
if tablename == '/MetaData':
|
|
341
|
+
mdh_in = MetaDataHandler.CachingMDHandler(json.loads(data))
|
|
342
|
+
h5f.updateMetadata(mdh_in)
|
|
343
|
+
elif tablename == '':
|
|
344
|
+
#legacy fitResults structure
|
|
345
|
+
fitResults = cPickle.loads(data)
|
|
346
|
+
h5f.fileFitResult(fitResults)
|
|
347
|
+
else:
|
|
348
|
+
try:
|
|
349
|
+
#pickle is much faster than numpy array format (despite the array format being simpler)
|
|
350
|
+
#reluctanltly use pickles
|
|
351
|
+
data = cPickle.loads(data)
|
|
352
|
+
except cPickle.UnpicklingError:
|
|
353
|
+
try:
|
|
354
|
+
#try to read data as if it was numpy binary formatted
|
|
355
|
+
data = np.load(BytesIO(data))
|
|
356
|
+
except IOError:
|
|
357
|
+
#it's not numpy formatted - try json
|
|
358
|
+
import pandas as pd
|
|
359
|
+
#FIXME!! - this will work, but will likely be really slow!
|
|
360
|
+
data = pd.read_json(data).to_records(False)
|
|
361
|
+
|
|
362
|
+
#logging.debug('adding data to table')
|
|
363
|
+
h5f.appendToTable(tablename.lstrip('/'), data)
|
|
364
|
+
#logging.debug('added data to table')
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
self.send_response(200)
|
|
368
|
+
self.send_header("Content-Length", "0")
|
|
369
|
+
self.end_headers()
|
|
370
|
+
return
|
|
371
|
+
|
|
372
|
+
def _do_part_pyramid(self):
|
|
373
|
+
from PYME.Analysis.distributed_pyramid import PartialPyramid
|
|
374
|
+
data = self._get_data()
|
|
375
|
+
|
|
376
|
+
#logger.debug('__pyramid: path- %s, len(data) - %d' % (self.path, len(data)))
|
|
377
|
+
|
|
378
|
+
parsed = urlparse.urlparse(self.path.lstrip('/'))
|
|
379
|
+
path = parsed.path
|
|
380
|
+
query = urlparse.parse_qs(parsed.query)
|
|
381
|
+
|
|
382
|
+
parts = path.split('/')
|
|
383
|
+
endpoint = parts[0]
|
|
384
|
+
path = '/'.join(parts[1:])
|
|
385
|
+
|
|
386
|
+
if endpoint == '__pyramid_create':
|
|
387
|
+
disk_path = self.translate_path(path)
|
|
388
|
+
|
|
389
|
+
part_pyramids[path] = PartialPyramid.from_request(disk_path, data)
|
|
390
|
+
logger.debug("Created PartialPyramid for {}".format(path))
|
|
391
|
+
|
|
392
|
+
elif endpoint == '__pyramid_update_tile':
|
|
393
|
+
assert path in part_pyramids, "PartialPyramid for {} not initialized yet".format(path)
|
|
394
|
+
logger.debug('update tile: %s' % query)
|
|
395
|
+
part_pyramids[path].queue_base_tile_update(data, query)
|
|
396
|
+
|
|
397
|
+
elif endpoint == '__pyramid_finish':
|
|
398
|
+
logger.debug('Finalising pyramid')
|
|
399
|
+
part_pyramids[path].finalise()
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
self.send_response(200)
|
|
403
|
+
self.send_header("Content-Length", "0")
|
|
404
|
+
self.end_headers()
|
|
405
|
+
|
|
406
|
+
def _aggregate_h5(self):
|
|
407
|
+
"""
|
|
408
|
+
Support for results aggregation into an HDF5 file, using pytables.
|
|
409
|
+
We treat any path components after the .h5r as locations within the file (ie table names).
|
|
410
|
+
e.g. /path/to/data.h5r/<tablename>
|
|
411
|
+
A few special cases / Table names are accommodated:
|
|
412
|
+
|
|
413
|
+
MetaData: assumes we have sent PYME metadata in json format and saves to the file using the appropriate metadatahandler
|
|
414
|
+
No table name: assumes we have a fitResults object (as returned by remFitBuf and saves to the the appropriate tables (as HDF task queue would)
|
|
415
|
+
"""
|
|
416
|
+
import numpy as np
|
|
417
|
+
from io import BytesIO
|
|
418
|
+
#from six.moves import cPickle
|
|
419
|
+
from PYME.IO import MetaDataHandler
|
|
420
|
+
from PYME.IO import h5File
|
|
421
|
+
|
|
422
|
+
#path = self.translate_path()
|
|
423
|
+
filename, tablename = self.path.lstrip('/')[len('__aggregate_h5'):].split('.h5')
|
|
424
|
+
filename = self.translate_path(filename + '.h5')
|
|
425
|
+
|
|
426
|
+
data = self._get_data()
|
|
427
|
+
|
|
428
|
+
dirname = os.path.dirname(filename)
|
|
429
|
+
#if not os.path.exists(dirname):
|
|
430
|
+
# os.makedirs(dirname)
|
|
431
|
+
makedirs_safe(dirname)
|
|
432
|
+
|
|
433
|
+
if USE_DIR_CACHE and not os.path.exists(filename):
|
|
434
|
+
# only update directory cache on initial creation to avoid lock thrashing. Use a placeholder size to indicate file is not complete
|
|
435
|
+
cl.dir_cache.update_cache(filename, -1)
|
|
436
|
+
|
|
437
|
+
#logging.debug('opening h5r file')
|
|
438
|
+
with h5File.openH5(filename, 'a') as h5f:
|
|
439
|
+
tablename = tablename.lstrip('/')
|
|
440
|
+
h5f.put_file(tablename, data)
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
self.send_response(200)
|
|
444
|
+
self.send_header("Content-Length", "0")
|
|
445
|
+
self.end_headers()
|
|
446
|
+
return
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
def _doAggregate(self):
|
|
450
|
+
# TODO - add authentication/checks for aggregation. Files which still allow appends should not be duplicated.
|
|
451
|
+
if self.path.lstrip('/').startswith('__aggregate_txt'):
|
|
452
|
+
self._aggregate_txt()
|
|
453
|
+
elif self.path.lstrip('/').startswith('__aggregate_h5r'):
|
|
454
|
+
self._aggregate_h5r()
|
|
455
|
+
elif self.path.lstrip('/').startswith('__aggregate_h5'):
|
|
456
|
+
self._aggregate_h5()
|
|
457
|
+
|
|
458
|
+
return
|
|
459
|
+
|
|
460
|
+
def do_PUT(self):
|
|
461
|
+
if self.timeoutTesting:
|
|
462
|
+
#exp = time.time() + float(self.timeoutTesting)
|
|
463
|
+
#while time.time() < exp:
|
|
464
|
+
# y = pow(5, 7)
|
|
465
|
+
time.sleep(float(self.timeoutTesting)) #wait 10 seconds to force a timeout on the clients
|
|
466
|
+
#print('waited ... ')
|
|
467
|
+
|
|
468
|
+
if self.bandwidthTesting:
|
|
469
|
+
#just read file and dump contents
|
|
470
|
+
r = self.rfile.read(int(self.headers['Content-Length']))
|
|
471
|
+
self.send_response(200)
|
|
472
|
+
self.send_header("Content-Length", "0")
|
|
473
|
+
self.end_headers()
|
|
474
|
+
return
|
|
475
|
+
|
|
476
|
+
if self.path.lstrip('/').startswith('__aggregate'):
|
|
477
|
+
#paths starting with __aggregate are special, and trigger appends to an existing file rather than creation
|
|
478
|
+
#of a new file.
|
|
479
|
+
self._doAggregate()
|
|
480
|
+
return
|
|
481
|
+
|
|
482
|
+
if self.path.lstrip('/').startswith('__pyramid'):
|
|
483
|
+
#paths starting with __part_pyramid are special, and trigger operations on PartialPyramids rather than creation
|
|
484
|
+
#of a new file.
|
|
485
|
+
self._do_part_pyramid()
|
|
486
|
+
return
|
|
487
|
+
|
|
488
|
+
|
|
489
|
+
|
|
490
|
+
path = self.translate_path(self.path)
|
|
491
|
+
# move up here to make sure we actually get the data (and clear it from our queue, even if we are going to, e.g.
|
|
492
|
+
# 405 it later)
|
|
493
|
+
data = self._get_data()
|
|
494
|
+
|
|
495
|
+
if os.path.exists(path):
|
|
496
|
+
#Do not overwrite - we use write-once semantics
|
|
497
|
+
self.send_error(405, "File already exists %s" % path)
|
|
498
|
+
|
|
499
|
+
|
|
500
|
+
|
|
501
|
+
#self.end_headers()
|
|
502
|
+
return None
|
|
503
|
+
else:
|
|
504
|
+
dir, file = os.path.split(path)
|
|
505
|
+
#if not os.path.exists(dir):
|
|
506
|
+
# os.makedirs(dir)
|
|
507
|
+
makedirs_safe(dir)
|
|
508
|
+
|
|
509
|
+
query = urlparse.parse_qs(urlparse.urlparse(self.path).query)
|
|
510
|
+
|
|
511
|
+
if file == '':
|
|
512
|
+
#we're just making a directory
|
|
513
|
+
pass
|
|
514
|
+
elif 'MirrorSource' in query.keys():
|
|
515
|
+
#File content is not in message content. This computer should
|
|
516
|
+
#fetch the results from another computer in the cluster instead
|
|
517
|
+
#used for online duplication
|
|
518
|
+
|
|
519
|
+
r = requests.get(query['MirrorSource'][0], timeout=.1)
|
|
520
|
+
|
|
521
|
+
with open(path, 'wb') as f:
|
|
522
|
+
f.write(r.content)
|
|
523
|
+
|
|
524
|
+
#set the file to read-only (reflecting our write-once semantics
|
|
525
|
+
os.chmod(path, 0o440)
|
|
526
|
+
|
|
527
|
+
if USE_DIR_CACHE:
|
|
528
|
+
cl.dir_cache.update_cache(path, len(r.content))
|
|
529
|
+
|
|
530
|
+
else:
|
|
531
|
+
#the standard case - use the contents of the put request
|
|
532
|
+
with open(path, 'wb') as f:
|
|
533
|
+
#shutil.copyfileobj(self.rfile, f, int(self.headers['Content-Length']))
|
|
534
|
+
f.write(data)
|
|
535
|
+
|
|
536
|
+
#set the file to read-only (reflecting our write-once semantics
|
|
537
|
+
os.chmod(path, 0o440)
|
|
538
|
+
|
|
539
|
+
if USE_DIR_CACHE:
|
|
540
|
+
cl.dir_cache.update_cache(path, len(data))
|
|
541
|
+
|
|
542
|
+
self.send_response(200)
|
|
543
|
+
self.send_header("Content-Length", "0")
|
|
544
|
+
self.end_headers()
|
|
545
|
+
return
|
|
546
|
+
|
|
547
|
+
def do_GET(self):
|
|
548
|
+
"""Serve a GET request."""
|
|
549
|
+
if self.timeoutTesting:
|
|
550
|
+
time.sleep(float(self.timeoutTesting)) #wait 10 seconds to force a timeout on the clients
|
|
551
|
+
|
|
552
|
+
f = self.send_head()
|
|
553
|
+
if f:
|
|
554
|
+
try:
|
|
555
|
+
self.copyfile(f, self.wfile)
|
|
556
|
+
finally:
|
|
557
|
+
f.close()
|
|
558
|
+
|
|
559
|
+
def get_status(self):
|
|
560
|
+
f = BytesIO()
|
|
561
|
+
f.write(json.dumps(status).encode())
|
|
562
|
+
length = f.tell()
|
|
563
|
+
f.seek(0)
|
|
564
|
+
self.send_response(200)
|
|
565
|
+
encoding = sys.getfilesystemencoding()
|
|
566
|
+
self.send_header("Content-type", "application/json; charset=%s" % encoding)
|
|
567
|
+
self.send_header("Content-Length", str(length))
|
|
568
|
+
self.end_headers()
|
|
569
|
+
return f
|
|
570
|
+
|
|
571
|
+
def get_glob(self):
|
|
572
|
+
import glob
|
|
573
|
+
query = urlparse.parse_qs(urlparse.urlparse(self.path).query)
|
|
574
|
+
pattern = query['pattern'][0]
|
|
575
|
+
|
|
576
|
+
logger.debug('glob: pattern = %s' % pattern)
|
|
577
|
+
matches = glob.glob(pattern)
|
|
578
|
+
|
|
579
|
+
f = BytesIO()
|
|
580
|
+
f.write(json.dumps(matches).encode())
|
|
581
|
+
length = f.tell()
|
|
582
|
+
f.seek(0)
|
|
583
|
+
self.send_response(200)
|
|
584
|
+
encoding = sys.getfilesystemencoding()
|
|
585
|
+
self.send_header("Content-type", "application/json; charset=%s" % encoding)
|
|
586
|
+
self.send_header("Content-Length", str(length))
|
|
587
|
+
self.end_headers()
|
|
588
|
+
return f
|
|
589
|
+
|
|
590
|
+
def send_head(self):
|
|
591
|
+
"""Common code for GET and HEAD commands.
|
|
592
|
+
|
|
593
|
+
This sends the response code and MIME headers.
|
|
594
|
+
|
|
595
|
+
Return value is either a file object (which has to be copied
|
|
596
|
+
to the outputfile by the caller unless the command was HEAD,
|
|
597
|
+
and must be closed by the caller under all circumstances), or
|
|
598
|
+
None, in which case the caller has nothing further to do.
|
|
599
|
+
|
|
600
|
+
"""
|
|
601
|
+
path = self.translate_path(self.path)
|
|
602
|
+
f = None
|
|
603
|
+
|
|
604
|
+
if self.path.lstrip('/') == '__status':
|
|
605
|
+
return self.get_status()
|
|
606
|
+
|
|
607
|
+
if self.path.lstrip('/').startswith('__glob'):
|
|
608
|
+
return self.get_glob()
|
|
609
|
+
|
|
610
|
+
if os.path.isdir(path):
|
|
611
|
+
parts = urlparse.urlsplit(self.path)
|
|
612
|
+
if not parts.path.endswith('/'):
|
|
613
|
+
# redirect browser - doing basically what apache does
|
|
614
|
+
self.send_response(301)
|
|
615
|
+
new_parts = (parts[0], parts[1], parts[2] + '/',
|
|
616
|
+
parts[3], parts[4])
|
|
617
|
+
new_url = urlparse.urlunsplit(new_parts)
|
|
618
|
+
self.send_header("Content-Length", "0") # we need to set this
|
|
619
|
+
self.send_header("Location", new_url)
|
|
620
|
+
self.end_headers()
|
|
621
|
+
return None
|
|
622
|
+
for index in "index.html", "index.htm":
|
|
623
|
+
index = os.path.join(path, index)
|
|
624
|
+
if os.path.exists(index):
|
|
625
|
+
path = index
|
|
626
|
+
break
|
|
627
|
+
else:
|
|
628
|
+
return self.list_directory(path)
|
|
629
|
+
|
|
630
|
+
|
|
631
|
+
|
|
632
|
+
if '.h5/' in self.path:
|
|
633
|
+
#special case - allow .h5 files to be treated as a directory
|
|
634
|
+
if self.path.endswith('.h5/'):
|
|
635
|
+
return self.list_h5(path)
|
|
636
|
+
else:
|
|
637
|
+
return self.get_h5_part(path)
|
|
638
|
+
elif '.h5r/' in self.path or '.hdf/' in self.path:
|
|
639
|
+
# throw the query back on to our fully resolved path
|
|
640
|
+
return self.get_tabular_part(path + '?' + urlparse.urlparse(self.path).query)
|
|
641
|
+
|
|
642
|
+
ctype = self.guess_type(path)
|
|
643
|
+
try:
|
|
644
|
+
# Always read in binary mode. Opening files in text mode may cause
|
|
645
|
+
# newline translations, making the actual size of the content
|
|
646
|
+
# transmitted *less* than the content-length!
|
|
647
|
+
f = open(path, 'rb')
|
|
648
|
+
except IOError:
|
|
649
|
+
self.send_error(404, "File not found - %s, [%s]" % (self.path, path))
|
|
650
|
+
return None
|
|
651
|
+
try:
|
|
652
|
+
self.send_response(200)
|
|
653
|
+
self.send_header("Content-type", ctype)
|
|
654
|
+
fs = os.fstat(f.fileno())
|
|
655
|
+
self.send_header("Content-Length", str(fs[6]))
|
|
656
|
+
self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
|
|
657
|
+
self.end_headers()
|
|
658
|
+
return f
|
|
659
|
+
except:
|
|
660
|
+
f.close()
|
|
661
|
+
raise
|
|
662
|
+
|
|
663
|
+
def _string_to_file(self, str):
|
|
664
|
+
f = BytesIO()
|
|
665
|
+
if not isinstance(str, bytes):
|
|
666
|
+
str = str.encode()
|
|
667
|
+
f.write(str)
|
|
668
|
+
length = f.tell()
|
|
669
|
+
f.seek(0)
|
|
670
|
+
|
|
671
|
+
return f, length
|
|
672
|
+
|
|
673
|
+
def list_directory(self, path):
|
|
674
|
+
"""Helper to produce a directory listing (absent index.html).
|
|
675
|
+
|
|
676
|
+
Return value is either a file object, or None (indicating an
|
|
677
|
+
error). In either case, the headers are sent, making the
|
|
678
|
+
interface the same as for send_head().
|
|
679
|
+
|
|
680
|
+
"""
|
|
681
|
+
from PYME.IO import clusterListing as cl
|
|
682
|
+
curTime = time.time()
|
|
683
|
+
|
|
684
|
+
with cl.dir_cache.dir_lock(path):
|
|
685
|
+
# if dir is in already in cache, return
|
|
686
|
+
try:
|
|
687
|
+
js_dir, expiry = _dirCache[path]
|
|
688
|
+
if expiry < curTime:
|
|
689
|
+
try:
|
|
690
|
+
# remove directory entry from cache as it's expired.
|
|
691
|
+
_dirCache.pop(path)
|
|
692
|
+
except KeyError:
|
|
693
|
+
pass
|
|
694
|
+
|
|
695
|
+
raise KeyError('Entry expired')
|
|
696
|
+
|
|
697
|
+
except KeyError:
|
|
698
|
+
try:
|
|
699
|
+
if USE_DIR_CACHE:
|
|
700
|
+
l2 = cl.dir_cache.list_directory(path)
|
|
701
|
+
else:
|
|
702
|
+
l2 = cl.list_directory(path)
|
|
703
|
+
except os.error:
|
|
704
|
+
self.send_error(404, "No permission to list directory")
|
|
705
|
+
return None
|
|
706
|
+
|
|
707
|
+
js_dir = json.dumps(l2)
|
|
708
|
+
_dirCache[path] = (js_dir, time.time() + _dirCacheTimeout)
|
|
709
|
+
|
|
710
|
+
f, length = self._string_to_file(js_dir)
|
|
711
|
+
|
|
712
|
+
self.send_response(200)
|
|
713
|
+
encoding = sys.getfilesystemencoding()
|
|
714
|
+
self.send_header("Content-type", "application/json; charset=%s" % encoding)
|
|
715
|
+
self.send_header("Content-Length", str(length))
|
|
716
|
+
self.end_headers()
|
|
717
|
+
return f
|
|
718
|
+
|
|
719
|
+
def list_h5(self, path):
|
|
720
|
+
from PYME.IO import h5File
|
|
721
|
+
try:
|
|
722
|
+
with h5File.openH5(path.rstrip('/').rstrip('\\')) as h5f:
|
|
723
|
+
f, length = self._string_to_file(json.dumps(h5f.get_listing()))
|
|
724
|
+
|
|
725
|
+
self.send_response(200)
|
|
726
|
+
encoding = sys.getfilesystemencoding()
|
|
727
|
+
self.send_header("Content-type", "application/json; charset=%s" % encoding)
|
|
728
|
+
self.send_header("Content-Length", str(length))
|
|
729
|
+
self.end_headers()
|
|
730
|
+
return f
|
|
731
|
+
|
|
732
|
+
except IOError:
|
|
733
|
+
self.send_error(404, "File not found - %s, [%s]" % (self.path, path))
|
|
734
|
+
return None
|
|
735
|
+
|
|
736
|
+
def get_h5_part(self, path):
|
|
737
|
+
from PYME.IO import h5File
|
|
738
|
+
ctype = self.guess_type(path)
|
|
739
|
+
try:
|
|
740
|
+
filename, part = path.split('.h5')
|
|
741
|
+
part = part.lstrip('/').lstrip('\\')
|
|
742
|
+
|
|
743
|
+
with h5File.openH5(filename + '.h5') as h5f:
|
|
744
|
+
f, length = self._string_to_file(h5f.get_file(part))
|
|
745
|
+
|
|
746
|
+
self.send_response(200)
|
|
747
|
+
self.send_header("Content-type", ctype)
|
|
748
|
+
self.send_header("Content-Length", length)
|
|
749
|
+
#self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
|
|
750
|
+
self.end_headers()
|
|
751
|
+
return f
|
|
752
|
+
|
|
753
|
+
|
|
754
|
+
except IOError:
|
|
755
|
+
self.send_error(404, "File not found - %s, [%s]" % (self.path, path))
|
|
756
|
+
return None
|
|
757
|
+
|
|
758
|
+
def get_tabular_part(self, path):
|
|
759
|
+
"""
|
|
760
|
+
|
|
761
|
+
Parameters
|
|
762
|
+
----------
|
|
763
|
+
path: str
|
|
764
|
+
OS-translated path to an hdf or h5r file on the dataserver computer.
|
|
765
|
+
Append the part of the file to read after the file extension, e.g.
|
|
766
|
+
.h5r/Events. Return format (for arrays) can additionally be
|
|
767
|
+
specified, as can slices
|
|
768
|
+
using the following syntax: test.h5r/FitResults.json?from=0&to=100.
|
|
769
|
+
Supported array formats include json and npy.
|
|
770
|
+
|
|
771
|
+
Returns
|
|
772
|
+
-------
|
|
773
|
+
f: BytesIO
|
|
774
|
+
Requested part of the file encoded as bytes
|
|
775
|
+
|
|
776
|
+
"""
|
|
777
|
+
from PYME.IO import h5rFile, clusterResults
|
|
778
|
+
|
|
779
|
+
# parse path
|
|
780
|
+
ext = '.h5r' if '.h5r' in path else '.hdf'
|
|
781
|
+
# TODO - should we just use the the untranslated path?
|
|
782
|
+
filename, details = path.split(ext + os.sep)
|
|
783
|
+
filename = filename + ext # path to file on dataserver disk
|
|
784
|
+
query = urlparse.urlparse(details).query
|
|
785
|
+
details = details.strip('?' + query)
|
|
786
|
+
if '.' in details:
|
|
787
|
+
part, return_type = details.split('.')
|
|
788
|
+
else:
|
|
789
|
+
part, return_type = details, ''
|
|
790
|
+
|
|
791
|
+
|
|
792
|
+
try:
|
|
793
|
+
with h5rFile.openH5R(filename) as h5f:
|
|
794
|
+
if part == 'Metadata':
|
|
795
|
+
wire_data, output_format = clusterResults.format_results(h5f.mdh, return_type)
|
|
796
|
+
else:
|
|
797
|
+
# figure out if we have any slicing to do
|
|
798
|
+
query = urlparse.parse_qs(query)
|
|
799
|
+
start = int(query.get('from', [0])[0])
|
|
800
|
+
end = None if 'to' not in query.keys() else int(query['to'][0])
|
|
801
|
+
wire_data, output_format = clusterResults.format_results(h5f.getTableData(part, slice(start, end)),
|
|
802
|
+
'.' + return_type)
|
|
803
|
+
|
|
804
|
+
f, length = self._string_to_file(wire_data)
|
|
805
|
+
self.send_response(200)
|
|
806
|
+
self.send_header("Content-Type", output_format if output_format else 'application/octet-stream')
|
|
807
|
+
self.send_header("Content-Length", length)
|
|
808
|
+
#self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
|
|
809
|
+
self.end_headers()
|
|
810
|
+
return f
|
|
811
|
+
|
|
812
|
+
except IOError:
|
|
813
|
+
self.send_error(404, "File not found - %s, [%s]" % (self.path, path))
|
|
814
|
+
|
|
815
|
+
|
|
816
|
+
|
|
817
|
+
def log_request(self, code='-', size='-'):
|
|
818
|
+
"""Log an accepted request.
|
|
819
|
+
|
|
820
|
+
This is called by send_response().
|
|
821
|
+
|
|
822
|
+
"""
|
|
823
|
+
if self.logrequests:
|
|
824
|
+
self.log_message('"%s" %s %s', self.requestline, str(code), str(size))
|
|
825
|
+
|
|
826
|
+
def log_error(self, format, *args):
|
|
827
|
+
"""Log an error.
|
|
828
|
+
|
|
829
|
+
This is called when a request cannot be fulfilled. By
|
|
830
|
+
default it passes the message on to log_message().
|
|
831
|
+
|
|
832
|
+
Arguments are the same as for log_message().
|
|
833
|
+
|
|
834
|
+
XXX This should go to the separate error log.
|
|
835
|
+
|
|
836
|
+
"""
|
|
837
|
+
logger.error("%s - - [%s] %s\n" %
|
|
838
|
+
(self.client_address[0],
|
|
839
|
+
self.log_date_time_string(),
|
|
840
|
+
format % args))
|
|
841
|
+
logger.debug("raw_requestline: %s" % self.raw_requestline)
|
|
842
|
+
|
|
843
|
+
#self.log_message(format, *args)
|
|
844
|
+
|
|
845
|
+
def log_message(self, format, *args):
|
|
846
|
+
"""Log an arbitrary message.
|
|
847
|
+
|
|
848
|
+
This is used by all other logging functions. Override
|
|
849
|
+
it if you have specific logging wishes.
|
|
850
|
+
|
|
851
|
+
The first argument, FORMAT, is a format string for the
|
|
852
|
+
message to be logged. If the format string contains
|
|
853
|
+
any % escapes requiring parameters, they should be
|
|
854
|
+
specified as subsequent arguments (it's just like
|
|
855
|
+
printf!).
|
|
856
|
+
|
|
857
|
+
The client ip address and current date/time are prefixed to every
|
|
858
|
+
message.
|
|
859
|
+
|
|
860
|
+
"""
|
|
861
|
+
|
|
862
|
+
logger.info("%s - - [%s] %s\n" %
|
|
863
|
+
(self.client_address[0],
|
|
864
|
+
self.log_date_time_string(),
|
|
865
|
+
format % args))
|
|
866
|
+
|
|
867
|
+
#sys.stderr.write("%s - - [%s] %s\n" %
|
|
868
|
+
# (self.client_address[0],
|
|
869
|
+
# self.log_date_time_string(),
|
|
870
|
+
# format % args))
|
|
871
|
+
|
|
872
|
+
def send_error(self, code, message=None):
|
|
873
|
+
"""Send and log an error reply.
|
|
874
|
+
|
|
875
|
+
Arguments are the error code, and a detailed message.
|
|
876
|
+
The detailed message defaults to the short entry matching the
|
|
877
|
+
response code.
|
|
878
|
+
|
|
879
|
+
This sends an error response (so it must be called before any
|
|
880
|
+
output has been generated), logs the error, and finally sends
|
|
881
|
+
a piece of HTML explaining the error to the user.
|
|
882
|
+
|
|
883
|
+
"""
|
|
884
|
+
|
|
885
|
+
try:
|
|
886
|
+
short, long = self.responses[code]
|
|
887
|
+
except KeyError:
|
|
888
|
+
short, long = '???', '???'
|
|
889
|
+
if message is None:
|
|
890
|
+
message = short
|
|
891
|
+
explain = long
|
|
892
|
+
self.log_error("code %d, message %s", code, message)
|
|
893
|
+
self.send_response(code, message)
|
|
894
|
+
#self.send_header('Connection', 'close')
|
|
895
|
+
|
|
896
|
+
# Message body is omitted for cases described in:
|
|
897
|
+
# - RFC7230: 3.3. 1xx, 204(No Content), 304(Not Modified)
|
|
898
|
+
# - RFC7231: 6.3.6. 205(Reset Content)
|
|
899
|
+
content = None
|
|
900
|
+
if code >= 200 and code not in (204, 205, 304):
|
|
901
|
+
# HTML encode to prevent Cross Site Scripting attacks
|
|
902
|
+
# (see bug #1100201)
|
|
903
|
+
content = (self.error_message_format % {
|
|
904
|
+
'code': code,
|
|
905
|
+
'message': html.escape(message),
|
|
906
|
+
'explain': explain
|
|
907
|
+
}).encode()
|
|
908
|
+
self.send_header("Content-Type", self.error_content_type)
|
|
909
|
+
self.send_header("Content-Length", str(len(content)))
|
|
910
|
+
|
|
911
|
+
self.end_headers()
|
|
912
|
+
|
|
913
|
+
if self.command != 'HEAD' and content:
|
|
914
|
+
self.wfile.write(content)
|
|
915
|
+
|
|
916
|
+
|
|
917
|
+
class ThreadedHTTPServer(ThreadingMixIn, http.server.HTTPServer):
|
|
918
|
+
"""Handle requests in a separate thread."""
|
|
919
|
+
|
|
920
|
+
|
|
921
|
+
def main(protocol="HTTP/1.0"):
|
|
922
|
+
global GPU_STATS
|
|
923
|
+
"""Test the HTTP request handler class.
|
|
924
|
+
|
|
925
|
+
This runs an HTTP server on port 8000 (or the first command line
|
|
926
|
+
argument).
|
|
927
|
+
|
|
928
|
+
"""
|
|
929
|
+
from optparse import OptionParser
|
|
930
|
+
|
|
931
|
+
op = OptionParser(usage='usage: %s [options]' % sys.argv[0])
|
|
932
|
+
|
|
933
|
+
#NOTE - currently squatting on port 15348 for testing - TODO can we use an ephemeral port?
|
|
934
|
+
op.add_option('-p', '--port', dest='port', default=config.get('dataserver-port', 15348),
|
|
935
|
+
help="port number to serve on (default: 15348, see also 'dataserver-port' config entry)")
|
|
936
|
+
op.add_option('-t', '--test', dest='test', help="Set up for bandwidth test (don't save files)", action="store_true", default=False)
|
|
937
|
+
op.add_option('-v', '--protocol', dest='protocol', help="HTTP protocol version", default="1.1")
|
|
938
|
+
op.add_option('-l', '--log-requests', dest='log_requests', help="Display http request info", default=False, action="store_true")
|
|
939
|
+
default_root = config.get('dataserver-root', os.curdir)
|
|
940
|
+
op.add_option('-r', '--root', dest='root', help="Root directory of virtual filesystem (default %s, see also 'dataserver-root' config entry)" % dataserver_root, default=default_root)
|
|
941
|
+
op.add_option('-k', '--profile', dest='profile', help="Enable profiling", default=False, action="store_true")
|
|
942
|
+
op.add_option('--thread-profile', dest='thread_profile', help="Enable thread profiling", default=False, action="store_true")
|
|
943
|
+
default_server_filter = config.get('dataserver-filter', compName)
|
|
944
|
+
op.add_option('-f', '--server-filter', dest='server_filter', help='Add a serverfilter for distinguishing between different clusters', default=default_server_filter)
|
|
945
|
+
op.add_option('--timeout-test', dest='timeout_test', help='deliberately make requests timeout for testing error handling in calling modules', default=0)
|
|
946
|
+
op.add_option('-a', '--advertisements', dest='advertisements', choices=['zeroconf', 'local'], default='zeroconf',
|
|
947
|
+
help='Optionally restrict advertisements to local machine')
|
|
948
|
+
|
|
949
|
+
|
|
950
|
+
options, args = op.parse_args()
|
|
951
|
+
if options.profile:
|
|
952
|
+
from PYME.util import mProfile
|
|
953
|
+
mProfile.profileOn(['HTTPDataServer.py','clusterListing.py'])
|
|
954
|
+
|
|
955
|
+
profileOutDir = options.root + '/LOGS/%s/mProf' % compName
|
|
956
|
+
|
|
957
|
+
if options.thread_profile:
|
|
958
|
+
from PYME.util import fProfile
|
|
959
|
+
|
|
960
|
+
tp = fProfile.ThreadProfiler()
|
|
961
|
+
#tp.profile_on(subs=['PYME/', 'http/server', 'socketserver'],outfile=options.root + '/LOGS/%s/tProf/dataserver.txt' % compName)
|
|
962
|
+
tp.profile_on(subs=['PYME/', ],
|
|
963
|
+
outfile=options.root + '/LOGS/%s/tProf/dataserver.txt' % compName)
|
|
964
|
+
|
|
965
|
+
# setup logging to file
|
|
966
|
+
log_dir = '%s/LOGS/%s' % (options.root, compName)
|
|
967
|
+
makedirs_safe(log_dir)
|
|
968
|
+
|
|
969
|
+
log_file = '%s/LOGS/%s/PYMEDataServer.log' % (options.root, compName)
|
|
970
|
+
fh = logging.handlers.RotatingFileHandler(filename=log_file, mode='w', maxBytes=1e6, backupCount=1)
|
|
971
|
+
logger.addHandler(fh)
|
|
972
|
+
|
|
973
|
+
|
|
974
|
+
logger.info('========================================\nPYMEDataServer, running on python %s\n' % sys.version)
|
|
975
|
+
|
|
976
|
+
#change to the dataserver root if given'
|
|
977
|
+
logger.info('Serving from directory: %s' % options.root)
|
|
978
|
+
os.chdir(options.root)
|
|
979
|
+
|
|
980
|
+
if options.advertisements == 'local':
|
|
981
|
+
# preference is to avoid zeroconf on clusterofone due to poor
|
|
982
|
+
# performance on crowded networks
|
|
983
|
+
if config.get('clusterIO-hybridns', True):
|
|
984
|
+
ns = sqlite_ns.getNS('_pyme-http')
|
|
985
|
+
else:
|
|
986
|
+
# if we aren't using the hybridns, we are using zeroconf in clusterIO
|
|
987
|
+
# TODO - warn that we might run into performance issues???
|
|
988
|
+
ns = pzc.getNS('_pyme-http')
|
|
989
|
+
server_address = ('127.0.0.1', int(options.port))
|
|
990
|
+
ip_addr = '127.0.0.1'
|
|
991
|
+
else:
|
|
992
|
+
#default
|
|
993
|
+
ns = pzc.getNS('_pyme-http')
|
|
994
|
+
server_address = ('', int(options.port))
|
|
995
|
+
|
|
996
|
+
try:
|
|
997
|
+
ip_addr = socket.gethostbyname(socket.gethostname())
|
|
998
|
+
except:
|
|
999
|
+
ip_addr = socket.gethostbyname(socket.gethostname() + '.local')
|
|
1000
|
+
|
|
1001
|
+
PYMEHTTPRequestHandler.protocol_version = 'HTTP/%s' % options.protocol
|
|
1002
|
+
PYMEHTTPRequestHandler.bandwidthTesting = options.test
|
|
1003
|
+
PYMEHTTPRequestHandler.timeoutTesting = options.timeout_test
|
|
1004
|
+
PYMEHTTPRequestHandler.logrequests = options.log_requests
|
|
1005
|
+
|
|
1006
|
+
httpd = ThreadedHTTPServer(server_address, PYMEHTTPRequestHandler)
|
|
1007
|
+
#httpd = http.server.HTTPServer(server_address, PYMEHTTPRequestHandler)
|
|
1008
|
+
httpd.daemon_threads = True
|
|
1009
|
+
|
|
1010
|
+
#get the actual adress (port) we bound to
|
|
1011
|
+
sa = httpd.socket.getsockname()
|
|
1012
|
+
service_name = get_service_name('PYMEDataServer [%s]' % options.server_filter)
|
|
1013
|
+
ns.register_service(service_name, ip_addr, sa[1])
|
|
1014
|
+
|
|
1015
|
+
status['IPAddress'] = ip_addr
|
|
1016
|
+
status['BindAddress'] = server_address
|
|
1017
|
+
status['Port'] = sa[1]
|
|
1018
|
+
status['Protocol'] = options.protocol
|
|
1019
|
+
status['TestMode'] = options.test
|
|
1020
|
+
status['ComputerName'] = GetComputerName()
|
|
1021
|
+
|
|
1022
|
+
if GPU_STATS:
|
|
1023
|
+
try:
|
|
1024
|
+
pynvml.nvmlInit()
|
|
1025
|
+
except:
|
|
1026
|
+
GPU_STATS = False
|
|
1027
|
+
|
|
1028
|
+
sp = statusPoller()
|
|
1029
|
+
sp.start()
|
|
1030
|
+
|
|
1031
|
+
|
|
1032
|
+
logger.info("Serving HTTP on %s port %d ..." % (ip_addr, sa[1]))
|
|
1033
|
+
try:
|
|
1034
|
+
httpd.serve_forever()
|
|
1035
|
+
finally:
|
|
1036
|
+
logger.info('Shutting down ...')
|
|
1037
|
+
httpd.shutdown()
|
|
1038
|
+
httpd.server_close()
|
|
1039
|
+
|
|
1040
|
+
ns.unregister(service_name)
|
|
1041
|
+
|
|
1042
|
+
if options.profile:
|
|
1043
|
+
mProfile.report(display=False, profiledir=profileOutDir)
|
|
1044
|
+
|
|
1045
|
+
if options.thread_profile:
|
|
1046
|
+
tp.profile_off()
|
|
1047
|
+
|
|
1048
|
+
sp.stop()
|
|
1049
|
+
|
|
1050
|
+
if GPU_STATS:
|
|
1051
|
+
pynvml.nvmlShutdown()
|
|
1052
|
+
|
|
1053
|
+
try:
|
|
1054
|
+
from pytest_cov.embed import cleanup
|
|
1055
|
+
cleanup()
|
|
1056
|
+
except:
|
|
1057
|
+
pass
|
|
1058
|
+
|
|
1059
|
+
sys.exit()
|
|
1060
|
+
|
|
1061
|
+
|
|
1062
|
+
if __name__ == '__main__':
|
|
1063
|
+
main()
|