pyobs-core 2.13.2__tar.gz → 2.13.4__tar.gz

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.
Files changed (475) hide show
  1. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/PKG-INFO +1 -1
  2. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/camera/basevideo.py +4 -0
  3. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/astroplanscheduler.py +56 -33
  4. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scripts/calibration/darkbias.py +1 -1
  5. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/stretch.py +13 -6
  6. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyproject.toml +1 -1
  7. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/.gitignore +0 -0
  8. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/LICENSE +0 -0
  9. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/__init__.py +0 -0
  10. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/application.py +0 -0
  11. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/background_task.py +0 -0
  12. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/cli/__init__.py +0 -0
  13. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/cli/_cli.py +0 -0
  14. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/cli/pyobs.py +0 -0
  15. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/cli/pyobsd.py +0 -0
  16. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/cli/pyobsw.py +0 -0
  17. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/comm/__init__.py +0 -0
  18. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/comm/comm.py +0 -0
  19. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/comm/commlogging.py +0 -0
  20. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/comm/dummy/__init__.py +0 -0
  21. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/comm/dummy/dummycomm.py +0 -0
  22. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/comm/local/__init__.py +0 -0
  23. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/comm/local/localcomm.py +0 -0
  24. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/comm/local/localnetwork.py +0 -0
  25. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/comm/proxy.py +0 -0
  26. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/comm/xmpp/__init__.py +0 -0
  27. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/comm/xmpp/rpc.py +0 -0
  28. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/comm/xmpp/serializer.py +0 -0
  29. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/comm/xmpp/xep_0009/__init__.py +0 -0
  30. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/comm/xmpp/xep_0009/binding.py +0 -0
  31. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/comm/xmpp/xep_0009/rpc.py +0 -0
  32. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/comm/xmpp/xep_0009_timeout/__init__.py +0 -0
  33. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/comm/xmpp/xep_0009_timeout/rpc.py +0 -0
  34. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/comm/xmpp/xep_0009_timeout/stanza/RPC.py +0 -0
  35. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/comm/xmpp/xep_0009_timeout/stanza/__init__.py +0 -0
  36. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/comm/xmpp/xmppclient.py +0 -0
  37. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/comm/xmpp/xmppcomm.py +0 -0
  38. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/events/__init__.py +0 -0
  39. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/events/badweather.py +0 -0
  40. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/events/event.py +0 -0
  41. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/events/exposurestatuschanged.py +0 -0
  42. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/events/filterchanged.py +0 -0
  43. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/events/focusfound.py +0 -0
  44. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/events/goodweather.py +0 -0
  45. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/events/log.py +0 -0
  46. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/events/modechanged.py +0 -0
  47. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/events/moduleclosed.py +0 -0
  48. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/events/moduleopened.py +0 -0
  49. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/events/motionstatuschanged.py +0 -0
  50. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/events/move.py +0 -0
  51. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/events/newimage.py +0 -0
  52. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/events/newspectrum.py +0 -0
  53. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/events/offsets.py +0 -0
  54. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/events/roofclosing.py +0 -0
  55. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/events/roofopened.py +0 -0
  56. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/events/taskfailed.py +0 -0
  57. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/events/taskfinished.py +0 -0
  58. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/events/taskskipped.py +0 -0
  59. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/events/taskstarted.py +0 -0
  60. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/events/testevent.py +0 -0
  61. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/__init__.py +0 -0
  62. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/image.py +0 -0
  63. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/meta/__init__.py +0 -0
  64. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/meta/altazoffsets.py +0 -0
  65. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/meta/datapipeline.py +0 -0
  66. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/meta/exptime.py +0 -0
  67. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/meta/genericoffset.py +0 -0
  68. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/meta/onskydistance.py +0 -0
  69. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/meta/pixeloffsets.py +0 -0
  70. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/meta/radecoffsets.py +0 -0
  71. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/meta/skyoffsets.py +0 -0
  72. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processor.py +0 -0
  73. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/__init__.py +0 -0
  74. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/_daobackgroundremover.py +0 -0
  75. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/annotation/__init__.py +0 -0
  76. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/annotation/_pillow.py +0 -0
  77. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/annotation/circle.py +0 -0
  78. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/annotation/crosshair.py +0 -0
  79. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/annotation/text.py +0 -0
  80. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/astrometry/__init__.py +0 -0
  81. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/astrometry/_dotnet_request.py +0 -0
  82. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/astrometry/_dotnet_request_builder.py +0 -0
  83. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/astrometry/_dotnet_request_logger.py +0 -0
  84. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/astrometry/_dotnet_response_saver.py +0 -0
  85. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/astrometry/astrometry.py +0 -0
  86. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/astrometry/dotnet.py +0 -0
  87. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/calibration/__init__.py +0 -0
  88. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/calibration/_calibration_cache.py +0 -0
  89. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/calibration/_ccddata_calibrator.py +0 -0
  90. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/calibration/calibration.py +0 -0
  91. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/detection/__init__.py +0 -0
  92. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/detection/_pysep_stats_calculator.py +0 -0
  93. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/detection/_source_catalog.py +0 -0
  94. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/detection/daophot.py +0 -0
  95. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/detection/pysep.py +0 -0
  96. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/detection/simpledisk.py +0 -0
  97. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/detection/sourcedetection.py +0 -0
  98. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/exptime/__init__.py +0 -0
  99. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/exptime/exptime.py +0 -0
  100. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/exptime/star.py +0 -0
  101. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/image/__init__.py +0 -0
  102. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/image/addfitsheaders.py +0 -0
  103. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/image/download.py +0 -0
  104. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/image/flip.py +0 -0
  105. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/image/grayscale.py +0 -0
  106. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/image/httpserver.py +0 -0
  107. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/image/normalize.py +0 -0
  108. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/image/save.py +0 -0
  109. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/image/saveimage.py +0 -0
  110. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/image/smooth.py +0 -0
  111. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/image/softbin.py +0 -0
  112. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/misc/__init__.py +0 -0
  113. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/misc/addmask.py +0 -0
  114. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/misc/catalogcircularmask.py +0 -0
  115. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/misc/circularmask.py +0 -0
  116. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/misc/createfilename.py +0 -0
  117. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/misc/imagesourcefilter.py +0 -0
  118. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/misc/removebackground.py +0 -0
  119. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/modules/__init__.py +0 -0
  120. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/modules/getfitsheaders.py +0 -0
  121. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/offsets/__init__.py +0 -0
  122. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/offsets/astrometry.py +0 -0
  123. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/offsets/brighteststar.py +0 -0
  124. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/offsets/brighteststar_guiding.py +0 -0
  125. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/offsets/dummyoffsets.py +0 -0
  126. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/offsets/dummyskyoffsets.py +0 -0
  127. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/offsets/fitsheader.py +0 -0
  128. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/offsets/offsets.py +0 -0
  129. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/offsets/pixeloffsets.py +0 -0
  130. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/offsets/projected.py +0 -0
  131. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/offsets/spilled_light.py +0 -0
  132. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/photometry/__init__.py +0 -0
  133. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/photometry/_photometry_calculator.py +0 -0
  134. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/photometry/_photutil_aperture_photometry.py +0 -0
  135. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/photometry/_sep_aperture_photometry.py +0 -0
  136. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/photometry/aperture_photometry.py +0 -0
  137. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/photometry/photometry.py +0 -0
  138. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/photometry/photutil.py +0 -0
  139. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/photometry/pysep.py +0 -0
  140. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/stack/__init__.py +0 -0
  141. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/stack/combinestack.py +0 -0
  142. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/stack/mean.py +0 -0
  143. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/stack/median.py +0 -0
  144. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/stack/sigmaclip.py +0 -0
  145. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/stack/sum.py +0 -0
  146. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/wcs/__init__.py +0 -0
  147. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/images/processors/wcs/solarhelioprojective.py +0 -0
  148. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IAbortable.py +0 -0
  149. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IAcquisition.py +0 -0
  150. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IAutoFocus.py +0 -0
  151. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IAutoGuiding.py +0 -0
  152. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IAutonomous.py +0 -0
  153. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IBinning.py +0 -0
  154. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/ICalibrate.py +0 -0
  155. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/ICamera.py +0 -0
  156. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IConfig.py +0 -0
  157. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/ICooling.py +0 -0
  158. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IData.py +0 -0
  159. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IDataPipeline.py +0 -0
  160. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IDataSequence.py +0 -0
  161. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IDataStack.py +0 -0
  162. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IDome.py +0 -0
  163. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IExposure.py +0 -0
  164. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IExposureTime.py +0 -0
  165. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IFilters.py +0 -0
  166. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IFitsHeaderAfter.py +0 -0
  167. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IFitsHeaderBefore.py +0 -0
  168. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IFlatField.py +0 -0
  169. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IFocusModel.py +0 -0
  170. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IFocuser.py +0 -0
  171. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IGain.py +0 -0
  172. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IImageFormat.py +0 -0
  173. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IImageType.py +0 -0
  174. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IMode.py +0 -0
  175. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IModule.py +0 -0
  176. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IMotion.py +0 -0
  177. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IMultiFiber.py +0 -0
  178. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IOffsetsAltAz.py +0 -0
  179. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IOffsetsRaDec.py +0 -0
  180. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IPointingAltAz.py +0 -0
  181. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IPointingBody.py +0 -0
  182. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IPointingHeliocentricPolar.py +0 -0
  183. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IPointingHeliographicStonyhurst.py +0 -0
  184. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IPointingHelioprojective.py +0 -0
  185. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IPointingOrbitalElements.py +0 -0
  186. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IPointingRaDec.py +0 -0
  187. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IPointingSeries.py +0 -0
  188. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IPushNotifications.py +0 -0
  189. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IReady.py +0 -0
  190. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IResettable.py +0 -0
  191. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IRobotic.py +0 -0
  192. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IRoboticScheduler.py +0 -0
  193. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IRoof.py +0 -0
  194. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IRotation.py +0 -0
  195. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IRunnable.py +0 -0
  196. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IRunning.py +0 -0
  197. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IScriptRunner.py +0 -0
  198. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/ISpectrograph.py +0 -0
  199. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IStartStop.py +0 -0
  200. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IStructuredConfig.py +0 -0
  201. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/ISyncTarget.py +0 -0
  202. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/ITelescope.py +0 -0
  203. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/ITemperatures.py +0 -0
  204. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/ITrackingMode.py +0 -0
  205. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/ITrackingRate.py +0 -0
  206. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IVideo.py +0 -0
  207. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IWeather.py +0 -0
  208. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/IWindow.py +0 -0
  209. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/__init__.py +0 -0
  210. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/interfaces/interface.py +0 -0
  211. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/mixins/__init__.py +0 -0
  212. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/mixins/camerasettings.py +0 -0
  213. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/mixins/datapipeline.py +0 -0
  214. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/mixins/datasequence.py +0 -0
  215. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/mixins/fitsheader.py +0 -0
  216. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/mixins/fitsnamespace.py +0 -0
  217. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/mixins/follow.py +0 -0
  218. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/mixins/motionstatus.py +0 -0
  219. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/mixins/pipeline.py +0 -0
  220. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/mixins/waitformotion.py +0 -0
  221. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/mixins/weatheraware.py +0 -0
  222. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/__init__.py +0 -0
  223. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/camera/__init__.py +0 -0
  224. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/camera/adaptive.py +0 -0
  225. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/camera/basecamera.py +0 -0
  226. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/camera/basespectrograph.py +0 -0
  227. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/camera/dummycamera.py +0 -0
  228. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/camera/dummyspectrograph.py +0 -0
  229. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/camera/dummyvideo.py +0 -0
  230. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/camera/pipelinecamera.py +0 -0
  231. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/camera/videoframes.py +0 -0
  232. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/flatfield/__init__.py +0 -0
  233. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/flatfield/flatfield.py +0 -0
  234. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/flatfield/pointing.py +0 -0
  235. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/flatfield/scheduler.py +0 -0
  236. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/focus/__init__.py +0 -0
  237. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/focus/dummyautofocus.py +0 -0
  238. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/focus/focusmodel.py +0 -0
  239. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/focus/focusseries.py +0 -0
  240. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/image/__init__.py +0 -0
  241. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/image/imagewatcher.py +0 -0
  242. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/image/imagewriter.py +0 -0
  243. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/image/pipeline.py +0 -0
  244. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/image/seeing.py +0 -0
  245. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/module.py +0 -0
  246. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/pointing/__init__.py +0 -0
  247. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/pointing/_base.py +0 -0
  248. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/pointing/_baseguiding.py +0 -0
  249. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/pointing/acquisition.py +0 -0
  250. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/pointing/autoguiding.py +0 -0
  251. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/pointing/dummyacquisition.py +0 -0
  252. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/pointing/dummyguiding.py +0 -0
  253. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/pointing/guidingsource.py +0 -0
  254. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/pointing/guidingstatistics/__init__.py +0 -0
  255. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/pointing/guidingstatistics/guidingstatistics.py +0 -0
  256. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/pointing/guidingstatistics/pixeloffset.py +0 -0
  257. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/pointing/guidingstatistics/skyoffsets.py +0 -0
  258. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/pointing/guidingstatistics/uptime.py +0 -0
  259. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/pointing/scienceframeguiding.py +0 -0
  260. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/robotic/__init__.py +0 -0
  261. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/robotic/dummymastermind.py +0 -0
  262. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/robotic/dummyscheduler.py +0 -0
  263. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/robotic/mastermind.py +0 -0
  264. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/robotic/pointing.py +0 -0
  265. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/robotic/scheduler.py +0 -0
  266. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/robotic/scriptrunner.py +0 -0
  267. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/roof/__init__.py +0 -0
  268. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/roof/basedome.py +0 -0
  269. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/roof/baseroof.py +0 -0
  270. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/roof/dummyroof.py +0 -0
  271. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/telescope/__init__.py +0 -0
  272. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/telescope/_dummytelescopebase.py +0 -0
  273. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/telescope/basetelescope.py +0 -0
  274. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/telescope/dummyaltaztelescope.py +0 -0
  275. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/telescope/dummyradectelescope.py +0 -0
  276. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/telescope/dummysolartelescope.py +0 -0
  277. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/test/__init__.py +0 -0
  278. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/test/standalone.py +0 -0
  279. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/utils/__init__.py +0 -0
  280. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/utils/dummymode.py +0 -0
  281. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/utils/dummystructuredconfig.py +0 -0
  282. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/utils/fluentlogger.py +0 -0
  283. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/utils/httpfilecache.py +0 -0
  284. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/utils/kiosk.py +0 -0
  285. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/utils/matrix.py +0 -0
  286. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/utils/pushnotifier.py +0 -0
  287. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/utils/stellarium.py +0 -0
  288. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/utils/telegram.py +0 -0
  289. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/utils/trigger.py +0 -0
  290. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/weather/__init__.py +0 -0
  291. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/weather/mockweather.py +0 -0
  292. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/weather/weather.py +0 -0
  293. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/weather/weather_api.py +0 -0
  294. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/modules/weather/weather_state.py +0 -0
  295. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/object.py +0 -0
  296. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/py.typed +0 -0
  297. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/__init__.py +0 -0
  298. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/instruments.py +0 -0
  299. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/observation.py +0 -0
  300. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/__init__.py +0 -0
  301. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/_executor.py +0 -0
  302. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/constraints/__init__.py +0 -0
  303. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/constraints/airmassconstraint.py +0 -0
  304. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/constraints/constraint.py +0 -0
  305. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/constraints/moonilluminationconstraint.py +0 -0
  306. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/constraints/moonseparationconstraint.py +0 -0
  307. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/constraints/solarelevationconstraint.py +0 -0
  308. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/constraints/timeconstraint.py +0 -0
  309. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/dataprovider.py +0 -0
  310. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/merits/__init__.py +0 -0
  311. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/merits/aftertime.py +0 -0
  312. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/merits/beforetime.py +0 -0
  313. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/merits/constant.py +0 -0
  314. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/merits/follow.py +0 -0
  315. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/merits/interval.py +0 -0
  316. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/merits/merit.py +0 -0
  317. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/merits/pernight.py +0 -0
  318. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/merits/random.py +0 -0
  319. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/merits/timewindow.py +0 -0
  320. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/merits/transit.py +0 -0
  321. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/observationarchiveevolution.py +0 -0
  322. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/ondemandscheduler.py +0 -0
  323. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/targets/__init__.py +0 -0
  324. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/targets/dynamictarget.py +0 -0
  325. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/targets/heliocentricpolartarget.py +0 -0
  326. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/targets/helioprojectivetarget.py +0 -0
  327. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/targets/picker/__init__.py +0 -0
  328. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/targets/picker/csvpicker.py +0 -0
  329. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/targets/picker/picker.py +0 -0
  330. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/targets/siderealtarget.py +0 -0
  331. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/targets/target.py +0 -0
  332. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scheduler/taskscheduler.py +0 -0
  333. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scripts/__init__.py +0 -0
  334. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scripts/calibration/__init__.py +0 -0
  335. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scripts/calibration/pointing.py +0 -0
  336. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scripts/calibration/skyflats.py +0 -0
  337. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scripts/control/__init__.py +0 -0
  338. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scripts/control/cases.py +0 -0
  339. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scripts/control/conditional.py +0 -0
  340. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scripts/control/parallel.py +0 -0
  341. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scripts/control/selector.py +0 -0
  342. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scripts/control/sequential.py +0 -0
  343. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scripts/exceptions.py +0 -0
  344. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scripts/imaging/__init__.py +0 -0
  345. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scripts/imaging/autofocus.py +0 -0
  346. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scripts/imaging/imaging.py +0 -0
  347. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scripts/imaging/transitimaging.py +0 -0
  348. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scripts/script.py +0 -0
  349. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scripts/utils/__init__.py +0 -0
  350. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scripts/utils/callmodule.py +0 -0
  351. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scripts/utils/debugtrigger.py +0 -0
  352. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/scripts/utils/log.py +0 -0
  353. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/storage/__init__.py +0 -0
  354. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/storage/filesystem/__init__.py +0 -0
  355. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/storage/filesystem/observationarchive.py +0 -0
  356. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/storage/filesystem/taskarchive.py +0 -0
  357. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/storage/lco/__init__.py +0 -0
  358. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/storage/lco/_portal.py +0 -0
  359. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/storage/lco/_schedulereader.py +0 -0
  360. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/storage/lco/_schedulewriter.py +0 -0
  361. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/storage/lco/configdb.py +0 -0
  362. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/storage/lco/mockobservationarchive.py +0 -0
  363. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/storage/lco/observationarchive.py +0 -0
  364. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/storage/lco/scripts/__init__.py +0 -0
  365. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/storage/lco/scripts/autofocus.py +0 -0
  366. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/storage/lco/scripts/default.py +0 -0
  367. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/storage/lco/scripts/script.py +0 -0
  368. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/storage/lco/task.py +0 -0
  369. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/storage/lco/taskarchive.py +0 -0
  370. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/storage/lco/taskrunner.py +0 -0
  371. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/storage/memory/__init__.py +0 -0
  372. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/storage/memory/observationarchive.py +0 -0
  373. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/storage/memory/taskarchive.py +0 -0
  374. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/storage/observationarchive.py +0 -0
  375. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/storage/portal/__init__.py +0 -0
  376. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/storage/portal/observationarchive.py +0 -0
  377. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/storage/portal/taskarchive.py +0 -0
  378. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/storage/taskarchive.py +0 -0
  379. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/task.py +0 -0
  380. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/taskrunner.py +0 -0
  381. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/utils/__init__.py +0 -0
  382. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/utils/archive/__init__.py +0 -0
  383. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/utils/archive/archive.py +0 -0
  384. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/utils/archive/local_archive.py +0 -0
  385. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/utils/archive/pyobs_archive.py +0 -0
  386. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/utils/calibration.py +0 -0
  387. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/utils/exptime/__init__.py +0 -0
  388. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/utils/exptime/exptime.py +0 -0
  389. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/utils/exptime/stellarexptime.py +0 -0
  390. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/utils/skyflats/__init__.py +0 -0
  391. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/utils/skyflats/exptimeeval.py +0 -0
  392. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/utils/skyflats/flatfielder.py +0 -0
  393. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/utils/skyflats/pointing/__init__.py +0 -0
  394. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/utils/skyflats/pointing/base.py +0 -0
  395. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/utils/skyflats/pointing/static.py +0 -0
  396. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/utils/skyflats/priorities/__init__.py +0 -0
  397. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/utils/skyflats/priorities/archive.py +0 -0
  398. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/utils/skyflats/priorities/base.py +0 -0
  399. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/utils/skyflats/priorities/const.py +0 -0
  400. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/robotic/utils/skyflats/scheduler.py +0 -0
  401. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/__init__.py +0 -0
  402. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/average.py +0 -0
  403. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/cache.py +0 -0
  404. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/config.py +0 -0
  405. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/config_schema.py +0 -0
  406. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/coordinates.py +0 -0
  407. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/curvefit.py +0 -0
  408. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/enums.py +0 -0
  409. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/exceptions.py +0 -0
  410. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/exptime_grouping.py +0 -0
  411. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/fits.py +0 -0
  412. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/focusseries/__init__.py +0 -0
  413. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/focusseries/base.py +0 -0
  414. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/focusseries/photometry.py +0 -0
  415. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/focusseries/projection.py +0 -0
  416. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/grids/__init__.py +0 -0
  417. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/grids/filters.py +0 -0
  418. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/grids/grid.py +0 -0
  419. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/grids/gridnode.py +0 -0
  420. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/grids/pipeline.py +0 -0
  421. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/gui/__init__.py +0 -0
  422. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/gui/camera/__init__.py +0 -0
  423. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/gui/camera/binningwidget.py +0 -0
  424. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/gui/camera/datadisplaywidget.py +0 -0
  425. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/gui/camera/exposewidget.py +0 -0
  426. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/gui/camera/exposuretimewidget.py +0 -0
  427. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/gui/camera/imageformatwidget.py +0 -0
  428. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/gui/camera/listpickerdialog.py +0 -0
  429. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/gui/camera/windowingwidget.py +0 -0
  430. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/http.py +0 -0
  431. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/influxdb.py +0 -0
  432. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/logger.py +0 -0
  433. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/logging/__init__.py +0 -0
  434. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/logging/context.py +0 -0
  435. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/logging/resolvableerror.py +0 -0
  436. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/modulegui.py +0 -0
  437. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/offsets/__init__.py +0 -0
  438. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/offsets/applyaltazoffsets.py +0 -0
  439. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/offsets/applyoffsets.py +0 -0
  440. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/offsets/applyradecoffsets.py +0 -0
  441. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/parallel.py +0 -0
  442. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/pipeline/__init__.py +0 -0
  443. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/pipeline/pipeline.py +0 -0
  444. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/pipeline/progress.py +0 -0
  445. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/pipeline/reduction.py +0 -0
  446. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/pipeline/reduction_base.py +0 -0
  447. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/publisher/__init__.py +0 -0
  448. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/publisher/csv.py +0 -0
  449. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/publisher/http.py +0 -0
  450. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/publisher/log.py +0 -0
  451. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/publisher/multi.py +0 -0
  452. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/publisher/publisher.py +0 -0
  453. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/serialization.py +0 -0
  454. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/shellcommand.py +0 -0
  455. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/threads/__init__.py +0 -0
  456. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/threads/lockwithabort.py +0 -0
  457. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/time.py +0 -0
  458. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/units.py +0 -0
  459. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/utils/versions.py +0 -0
  460. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/version.py +0 -0
  461. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/vfs/__init__.py +0 -0
  462. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/vfs/archivefile.py +0 -0
  463. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/vfs/bufferedfile.py +0 -0
  464. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/vfs/file.py +0 -0
  465. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/vfs/filelists/__init__.py +0 -0
  466. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/vfs/filelists/filelist.py +0 -0
  467. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/vfs/filelists/testing.py +0 -0
  468. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/vfs/httpfile.py +0 -0
  469. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/vfs/localfile.py +0 -0
  470. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/vfs/memfile.py +0 -0
  471. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/vfs/sftpfile.py +0 -0
  472. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/vfs/smbfile.py +0 -0
  473. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/vfs/sshfile.py +0 -0
  474. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/vfs/tempfile.py +0 -0
  475. {pyobs_core-2.13.2 → pyobs_core-2.13.4}/pyobs/vfs/vfs.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: pyobs-core
3
- Version: 2.13.2
3
+ Version: 2.13.4
4
4
  Summary: robotic telescope software
5
5
  Author-email: Tim-Oliver Husser <thusser@uni-goettingen.de>
6
6
  License-Expression: MIT
@@ -725,6 +725,7 @@ class BaseVideo(
725
725
  ValueError: If the crop lies completely outside the frame, or binning is larger than it.
726
726
  """
727
727
  data = record.data
728
+ source_dtype = data.dtype
728
729
  x0, y0 = 0, 0
729
730
  if crop is not None:
730
731
  x, y, w, h = crop
@@ -761,6 +762,9 @@ class BaseVideo(
761
762
  for key in image.header:
762
763
  meta[key] = self._json_safe(image.header[key])
763
764
  meta["DTYPE"] = data.dtype.newbyteorder("<").str
765
+ # binning turns integer data into float32, so a client needs the original dtype to resolve
766
+ # "full" cuts and the default cuts mode
767
+ meta["SRCDTYPE"] = source_dtype.newbyteorder("<").str
764
768
  # NAXISn alone doesn't tell a client how many axes to read (e.g. colour frames are 3D)
765
769
  meta["NAXIS"] = data.ndim
766
770
  meta["VIDFRAME"] = record.number
@@ -3,12 +3,15 @@ from __future__ import annotations
3
3
  import asyncio
4
4
  import logging
5
5
  import multiprocessing as mp
6
+ import queue
7
+ import traceback
6
8
  from collections.abc import AsyncIterator
7
9
  from typing import TYPE_CHECKING, Any
8
10
 
9
11
  import astroplan
10
12
  import astropy.units as u
11
13
  from astroplan import FixedTarget, ObservingBlock
14
+ from astropy.time import Time as AstropyTime
12
15
 
13
16
  from pyobs.object import Object
14
17
  from pyobs.robotic.instruments import InstrumentCapabilities
@@ -22,6 +25,9 @@ if TYPE_CHECKING:
22
25
 
23
26
  log = logging.getLogger(__name__)
24
27
 
28
+ # (task id, start, end) of a scheduled block, as sent back from the scheduler process
29
+ ScheduledBlock = tuple[Any, AstropyTime, AstropyTime]
30
+
25
31
 
26
32
  class AstroplanScheduler(TaskScheduler):
27
33
  """Scheduler based on astroplan."""
@@ -124,7 +130,8 @@ class AstroplanScheduler(TaskScheduler):
124
130
  task.duration * u.second,
125
131
  priority,
126
132
  constraints=[c.to_astroplan() for c in task.constraints] if task.constraints else None,
127
- configuration={"request": task},
133
+ # no task in configuration: scheduled blocks are pickled back from the worker process,
134
+ # and tasks reference unpicklable comm proxies; _convert_blocks matches by name instead
128
135
  name=task.id,
129
136
  )
130
137
  )
@@ -134,27 +141,39 @@ class AstroplanScheduler(TaskScheduler):
134
141
 
135
142
  async def _schedule_blocks(
136
143
  self, blocks: list[ObservingBlock], start: Time, end: Time, constraints: list[Any], abort: asyncio.Event
137
- ) -> list[ObservingBlock]:
144
+ ) -> list[ScheduledBlock]:
138
145
 
139
146
  # run actual scheduler in separate process and wait for it
140
- queue_out: mp.Queue[list[ObservingBlock]] = mp.Queue()
147
+ queue_out: mp.Queue[tuple[str, Any]] = mp.Queue()
141
148
  p = mp.Process(target=self._schedule_process, args=(blocks, start, end, constraints, self.observer, queue_out))
142
149
  p.start()
143
150
 
144
- # wait for process to finish
145
- # note that the process only finishes, when the queue is empty! so we have to poll the queue first
146
- # and then the process.
147
- loop = asyncio.get_running_loop()
148
- future = loop.run_in_executor(None, queue_out.get, True) # type: ignore[arg-type]
149
- while not future.done():
151
+ # wait for result, polling the queue: the process only finishes when the queue is drained, and a
152
+ # blocking get() would hang forever if the process dies without sending anything
153
+ while True:
150
154
  if abort.is_set():
151
155
  p.kill()
152
156
  return []
153
- else:
154
- await asyncio.sleep(0.1)
155
- scheduled_blocks: list[ObservingBlock] = await future
157
+ try:
158
+ status, result = queue_out.get_nowait()
159
+ break
160
+ except queue.Empty:
161
+ pass
162
+ if not p.is_alive():
163
+ # anything put before exit has been flushed to the pipe by now
164
+ try:
165
+ status, result = queue_out.get_nowait()
166
+ break
167
+ except queue.Empty:
168
+ raise RuntimeError(f"Scheduler process exited with code {p.exitcode} without sending a result.")
169
+ await asyncio.sleep(0.1)
170
+
171
+ loop = asyncio.get_running_loop()
156
172
  await loop.run_in_executor(None, p.join)
157
173
 
174
+ if status == "error":
175
+ raise RuntimeError(f"Scheduler process failed:\n{result}")
176
+ scheduled_blocks: list[ScheduledBlock] = result
158
177
  return scheduled_blocks
159
178
 
160
179
  @staticmethod
@@ -164,38 +183,44 @@ class AstroplanScheduler(TaskScheduler):
164
183
  end: Time,
165
184
  constraints: list[Any],
166
185
  observer: Any,
167
- scheduled_blocks: mp.Queue[list[ObservingBlock]],
186
+ queue_out: mp.Queue[tuple[str, Any]],
168
187
  ) -> None:
169
- """Actually do the scheduling, usually run in a separate process."""
188
+ """Actually do the scheduling, usually run in a separate process.
189
+
190
+ Only plain (name, start, end) tuples are sent back, since the result is pickled and blocks may
191
+ reference objects that can't be pickled.
192
+ """
170
193
 
171
194
  # log it
172
195
  log.info("Calculating schedule for %d schedulable block(s) starting at %s...", len(blocks), start)
173
196
 
174
- # we don't need any transitions
175
- transitioner = astroplan.Transitioner()
197
+ try:
198
+ # we don't need any transitions
199
+ transitioner = astroplan.Transitioner()
176
200
 
177
- # create scheduler
178
- scheduler = astroplan.PriorityScheduler(constraints, observer, transitioner=transitioner)
201
+ # create scheduler
202
+ scheduler = astroplan.PriorityScheduler(constraints, observer, transitioner=transitioner)
179
203
 
180
- # run scheduler
181
- logging.disable(logging.WARNING)
182
- time_range = astroplan.Schedule(start, end)
183
- schedule = scheduler(blocks, time_range)
184
- logging.disable(logging.NOTSET)
204
+ # run scheduler
205
+ logging.disable(logging.WARNING)
206
+ try:
207
+ time_range = astroplan.Schedule(start, end)
208
+ schedule = scheduler(blocks, time_range)
209
+ finally:
210
+ logging.disable(logging.NOTSET)
185
211
 
186
- # put scheduled blocks in queue
187
- scheduled_blocks.put(schedule.scheduled_blocks)
212
+ # put scheduled blocks in queue
213
+ queue_out.put(("ok", [(b.name, b.start_time, b.end_time) for b in schedule.scheduled_blocks]))
188
214
 
189
- # clean up
190
- del transitioner, scheduler, schedule
215
+ except Exception:
216
+ queue_out.put(("error", traceback.format_exc()))
191
217
 
192
- async def _convert_blocks(self, blocks: list[ObservingBlock], tasks: list[Task]) -> ObservationList:
218
+ async def _convert_blocks(self, blocks: list[ScheduledBlock], tasks: list[Task]) -> ObservationList:
193
219
  from pyobs.robotic import Observation, ObservationList
194
220
 
195
221
  scheduled_tasks = ObservationList()
196
- for block in blocks:
222
+ for task_id, block_start, block_end in blocks:
197
223
  # find task
198
- task_id = block.name
199
224
  for task in tasks:
200
225
  if task.id == task_id:
201
226
  break
@@ -203,9 +228,7 @@ class AstroplanScheduler(TaskScheduler):
203
228
  raise ValueError(f"Could not find task with id '{task_id}'")
204
229
 
205
230
  # create scheduled task
206
- scheduled_tasks.append(
207
- Observation(task=task, start=block.start_time, end=block.end_time, target=task.target)
208
- )
231
+ scheduled_tasks.append(Observation(task=task, start=block_start, end=block_end, target=task.target))
209
232
 
210
233
  return scheduled_tasks
211
234
 
@@ -250,7 +250,7 @@ class DarkBiasScript(Script):
250
250
  by_combo = await science_exptimes_for_night(self.archive, self.site, night)
251
251
  exptimes = self._flatten_matching_exptimes(by_combo)
252
252
  if not exptimes:
253
- log.warning(
253
+ log.info(
254
254
  "No science exptimes found for night %s at binning %s; nothing to expose.",
255
255
  night,
256
256
  self._binning_str(),
@@ -75,26 +75,29 @@ def downsample(data: NDArray[Any], factor: int) -> NDArray[Any]:
75
75
  return cropped.reshape(shape).mean(axis=(1, 3))
76
76
 
77
77
 
78
- def compute_cuts(data: NDArray[Any], params: StretchParams) -> tuple[float, float]:
78
+ def compute_cuts(data: NDArray[Any], params: StretchParams, dtype: Any = None) -> tuple[float, float]:
79
79
  """Computes the low and high cut for the given data.
80
80
 
81
81
  Args:
82
82
  data: Image data.
83
83
  params: Stretch parameters.
84
+ dtype: dtype that decides the ``full`` range and the default cuts mode, if different from the
85
+ data's, e.g. when it was downsampled to float32 from integer data. Defaults to the data's dtype.
84
86
 
85
87
  Returns:
86
88
  Tuple of (low, high) data values.
87
89
  """
90
+ dtype = np.dtype(dtype) if dtype is not None else data.dtype
88
91
  cuts = params.cuts
89
92
  if cuts is None:
90
- cuts = "full" if data.dtype == np.uint8 else "minmax"
93
+ cuts = "full" if dtype == np.uint8 else "minmax"
91
94
 
92
95
  if cuts == "manual":
93
96
  return float(params.lo), float(params.hi) # type: ignore[arg-type]
94
97
  if cuts == "full":
95
- if not np.issubdtype(data.dtype, np.integer):
98
+ if not np.issubdtype(dtype, np.integer):
96
99
  raise ValueError("Cuts mode 'full' needs integer data.")
97
- info = np.iinfo(data.dtype)
100
+ info = np.iinfo(dtype)
98
101
  return float(info.min), float(info.max)
99
102
 
100
103
  sample = data[::_CUTS_SUBSAMPLE, ::_CUTS_SUBSAMPLE] if data.shape[0] > 256 else data
@@ -109,7 +112,7 @@ def compute_cuts(data: NDArray[Any], params: StretchParams) -> tuple[float, floa
109
112
  return float(low), float(high)
110
113
 
111
114
 
112
- def stretch_to_uint8(data: NDArray[Any], params: StretchParams | None = None) -> NDArray[np.uint8]:
115
+ def stretch_to_uint8(data: NDArray[Any], params: StretchParams | None = None, dtype: Any = None) -> NDArray[np.uint8]:
113
116
  """Maps image data to 8 bit for display.
114
117
 
115
118
  Colour images (3D, colour as last axis) use the same cuts for all channels.
@@ -117,18 +120,22 @@ def stretch_to_uint8(data: NDArray[Any], params: StretchParams | None = None) ->
117
120
  Args:
118
121
  data: Image data.
119
122
  params: Stretch parameters, defaults if None.
123
+ dtype: dtype the cuts follow, if the data was already downsampled from a different one (e.g. a
124
+ binned raw frame that was integer data before). Defaults to the data's dtype.
120
125
 
121
126
  Returns:
122
127
  8-bit image.
123
128
  """
124
129
  params = params if params is not None else StretchParams()
130
+ # downsampling turns integer data into float32, the cuts follow the input
131
+ dtype = np.dtype(dtype) if dtype is not None else data.dtype
125
132
  data = downsample(data, params.scale)
126
133
 
127
134
  # fast path: 8-bit data with its full range and a linear stretch is already what we want
128
135
  if data.dtype == np.uint8 and params.stretch == "linear" and params.cuts in (None, "full"):
129
136
  return data
130
137
 
131
- low, high = compute_cuts(data, params)
138
+ low, high = compute_cuts(data, params, dtype)
132
139
  span = high - low if high > low else 1.0
133
140
  x = np.clip((data.astype(np.float32) - low) / span, 0.0, 1.0)
134
141
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pyobs-core"
3
- version = "2.13.2"
3
+ version = "2.13.4"
4
4
  description = "robotic telescope software"
5
5
  authors = [{ name = "Tim-Oliver Husser", email = "thusser@uni-goettingen.de" }]
6
6
  requires-python = ">=3.11"
File without changes
File without changes