pyobs-core 2.0.0.dev52__tar.gz → 2.0.0.dev53__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 (448) hide show
  1. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/PKG-INFO +1 -1
  2. pyobs_core-2.0.0.dev53/pyobs/images/processor.py +63 -0
  3. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/astrometry/dotnet.py +34 -26
  4. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/mixins/pipeline.py +16 -2
  5. pyobs_core-2.0.0.dev53/pyobs/robotic/scheduler/_executor.py +28 -0
  6. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scheduler/constraints/moonilluminationconstraint.py +1 -1
  7. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scheduler/constraints/moonseparationconstraint.py +3 -4
  8. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scheduler/constraints/solarelevationconstraint.py +2 -3
  9. pyobs_core-2.0.0.dev53/pyobs/robotic/scheduler/dataprovider.py +78 -0
  10. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scheduler/ondemandscheduler.py +6 -3
  11. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/vfs/vfs.py +15 -6
  12. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyproject.toml +1 -1
  13. pyobs_core-2.0.0.dev52/pyobs/images/processor.py +0 -28
  14. pyobs_core-2.0.0.dev52/pyobs/robotic/scheduler/dataprovider.py +0 -49
  15. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/.gitignore +0 -0
  16. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/LICENSE +0 -0
  17. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/__init__.py +0 -0
  18. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/application.py +0 -0
  19. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/background_task.py +0 -0
  20. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/cli/__init__.py +0 -0
  21. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/cli/_cli.py +0 -0
  22. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/cli/pyobs.py +0 -0
  23. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/cli/pyobsd.py +0 -0
  24. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/cli/pyobsw.py +0 -0
  25. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/comm/__init__.py +0 -0
  26. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/comm/comm.py +0 -0
  27. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/comm/commlogging.py +0 -0
  28. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/comm/dummy/__init__.py +0 -0
  29. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/comm/dummy/dummycomm.py +0 -0
  30. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/comm/local/__init__.py +0 -0
  31. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/comm/local/localcomm.py +0 -0
  32. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/comm/local/localnetwork.py +0 -0
  33. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/comm/proxy.py +0 -0
  34. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/comm/xmpp/__init__.py +0 -0
  35. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/comm/xmpp/rpc.py +0 -0
  36. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/comm/xmpp/serializer.py +0 -0
  37. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/comm/xmpp/xep_0009/__init__.py +0 -0
  38. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/comm/xmpp/xep_0009/binding.py +0 -0
  39. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/comm/xmpp/xep_0009/rpc.py +0 -0
  40. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/comm/xmpp/xep_0009_timeout/__init__.py +0 -0
  41. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/comm/xmpp/xep_0009_timeout/rpc.py +0 -0
  42. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/comm/xmpp/xep_0009_timeout/stanza/RPC.py +0 -0
  43. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/comm/xmpp/xep_0009_timeout/stanza/__init__.py +0 -0
  44. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/comm/xmpp/xmppclient.py +0 -0
  45. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/comm/xmpp/xmppcomm.py +0 -0
  46. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/events/__init__.py +0 -0
  47. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/events/badweather.py +0 -0
  48. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/events/event.py +0 -0
  49. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/events/exposurestatuschanged.py +0 -0
  50. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/events/filterchanged.py +0 -0
  51. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/events/focusfound.py +0 -0
  52. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/events/goodweather.py +0 -0
  53. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/events/log.py +0 -0
  54. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/events/modechanged.py +0 -0
  55. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/events/moduleclosed.py +0 -0
  56. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/events/moduleopened.py +0 -0
  57. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/events/motionstatuschanged.py +0 -0
  58. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/events/move.py +0 -0
  59. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/events/newimage.py +0 -0
  60. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/events/newspectrum.py +0 -0
  61. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/events/offsets.py +0 -0
  62. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/events/roofclosing.py +0 -0
  63. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/events/roofopened.py +0 -0
  64. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/events/taskfailed.py +0 -0
  65. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/events/taskfinished.py +0 -0
  66. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/events/taskstarted.py +0 -0
  67. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/events/testevent.py +0 -0
  68. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/__init__.py +0 -0
  69. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/image.py +0 -0
  70. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/meta/__init__.py +0 -0
  71. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/meta/altazoffsets.py +0 -0
  72. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/meta/exptime.py +0 -0
  73. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/meta/genericoffset.py +0 -0
  74. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/meta/onskydistance.py +0 -0
  75. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/meta/pixeloffsets.py +0 -0
  76. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/meta/radecoffsets.py +0 -0
  77. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/meta/skyoffsets.py +0 -0
  78. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/__init__.py +0 -0
  79. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/_daobackgroundremover.py +0 -0
  80. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/annotation/__init__.py +0 -0
  81. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/annotation/_pillow.py +0 -0
  82. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/annotation/circle.py +0 -0
  83. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/annotation/crosshair.py +0 -0
  84. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/annotation/text.py +0 -0
  85. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/astrometry/__init__.py +0 -0
  86. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/astrometry/_dotnet_request.py +0 -0
  87. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/astrometry/_dotnet_request_builder.py +0 -0
  88. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/astrometry/_dotnet_request_logger.py +0 -0
  89. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/astrometry/_dotnet_response_saver.py +0 -0
  90. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/astrometry/astrometry.py +0 -0
  91. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/calibration/__init__.py +0 -0
  92. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/calibration/_calibration_cache.py +0 -0
  93. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/calibration/_ccddata_calibrator.py +0 -0
  94. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/calibration/calibration.py +0 -0
  95. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/detection/__init__.py +0 -0
  96. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/detection/_pysep_stats_calculator.py +0 -0
  97. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/detection/_source_catalog.py +0 -0
  98. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/detection/daophot.py +0 -0
  99. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/detection/pysep.py +0 -0
  100. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/detection/simpledisk.py +0 -0
  101. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/detection/sourcedetection.py +0 -0
  102. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/exptime/__init__.py +0 -0
  103. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/exptime/exptime.py +0 -0
  104. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/exptime/star.py +0 -0
  105. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/image/__init__.py +0 -0
  106. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/image/addfitsheaders.py +0 -0
  107. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/image/download.py +0 -0
  108. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/image/flip.py +0 -0
  109. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/image/grayscale.py +0 -0
  110. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/image/httpserver.py +0 -0
  111. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/image/normalize.py +0 -0
  112. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/image/save.py +0 -0
  113. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/image/saveimage.py +0 -0
  114. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/image/smooth.py +0 -0
  115. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/image/softbin.py +0 -0
  116. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/misc/__init__.py +0 -0
  117. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/misc/addmask.py +0 -0
  118. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/misc/catalogcircularmask.py +0 -0
  119. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/misc/circularmask.py +0 -0
  120. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/misc/createfilename.py +0 -0
  121. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/misc/imagesourcefilter.py +0 -0
  122. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/misc/removebackground.py +0 -0
  123. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/modules/__init__.py +0 -0
  124. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/modules/getfitsheaders.py +0 -0
  125. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/offsets/__init__.py +0 -0
  126. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/offsets/astrometry.py +0 -0
  127. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/offsets/brighteststar.py +0 -0
  128. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/offsets/brighteststar_guiding.py +0 -0
  129. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/offsets/dummyoffsets.py +0 -0
  130. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/offsets/dummyskyoffsets.py +0 -0
  131. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/offsets/fitsheader.py +0 -0
  132. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/offsets/offsets.py +0 -0
  133. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/offsets/pixeloffsets.py +0 -0
  134. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/offsets/projected.py +0 -0
  135. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/offsets/spilled_light.py +0 -0
  136. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/photometry/__init__.py +0 -0
  137. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/photometry/_photometry_calculator.py +0 -0
  138. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/photometry/_photutil_aperture_photometry.py +0 -0
  139. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/photometry/_sep_aperture_photometry.py +0 -0
  140. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/photometry/aperture_photometry.py +0 -0
  141. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/photometry/photometry.py +0 -0
  142. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/photometry/photutil.py +0 -0
  143. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/photometry/pysep.py +0 -0
  144. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/wcs/__init__.py +0 -0
  145. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/images/processors/wcs/solarhelioprojective.py +0 -0
  146. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IAbortable.py +0 -0
  147. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IAcquisition.py +0 -0
  148. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IAutoFocus.py +0 -0
  149. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IAutoGuiding.py +0 -0
  150. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IAutonomous.py +0 -0
  151. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IBinning.py +0 -0
  152. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/ICalibrate.py +0 -0
  153. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/ICamera.py +0 -0
  154. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IConfig.py +0 -0
  155. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/ICooling.py +0 -0
  156. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IData.py +0 -0
  157. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IDataSequence.py +0 -0
  158. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IDome.py +0 -0
  159. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IExposure.py +0 -0
  160. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IExposureTime.py +0 -0
  161. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IFilters.py +0 -0
  162. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IFitsHeaderAfter.py +0 -0
  163. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IFitsHeaderBefore.py +0 -0
  164. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IFlatField.py +0 -0
  165. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IFocusModel.py +0 -0
  166. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IFocuser.py +0 -0
  167. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IGain.py +0 -0
  168. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IImageFormat.py +0 -0
  169. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IImageType.py +0 -0
  170. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IMode.py +0 -0
  171. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IModule.py +0 -0
  172. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IMotion.py +0 -0
  173. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IMultiFiber.py +0 -0
  174. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IOffsetsAltAz.py +0 -0
  175. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IOffsetsRaDec.py +0 -0
  176. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IPointingAltAz.py +0 -0
  177. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IPointingBody.py +0 -0
  178. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IPointingHeliocentricPolar.py +0 -0
  179. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IPointingHeliographicStonyhurst.py +0 -0
  180. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IPointingHelioprojective.py +0 -0
  181. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IPointingOrbitalElements.py +0 -0
  182. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IPointingRaDec.py +0 -0
  183. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IPointingSeries.py +0 -0
  184. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IReady.py +0 -0
  185. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IRoof.py +0 -0
  186. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IRotation.py +0 -0
  187. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IRunnable.py +0 -0
  188. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IRunning.py +0 -0
  189. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IScriptRunner.py +0 -0
  190. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/ISpectrograph.py +0 -0
  191. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IStartStop.py +0 -0
  192. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IStructuredConfig.py +0 -0
  193. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/ISyncTarget.py +0 -0
  194. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/ITelescope.py +0 -0
  195. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/ITemperatures.py +0 -0
  196. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/ITrackingMode.py +0 -0
  197. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/ITrackingRate.py +0 -0
  198. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IVideo.py +0 -0
  199. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IWeather.py +0 -0
  200. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/IWindow.py +0 -0
  201. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/__init__.py +0 -0
  202. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/interfaces/interface.py +0 -0
  203. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/mixins/__init__.py +0 -0
  204. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/mixins/camerasettings.py +0 -0
  205. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/mixins/fitsheader.py +0 -0
  206. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/mixins/fitsnamespace.py +0 -0
  207. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/mixins/follow.py +0 -0
  208. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/mixins/motionstatus.py +0 -0
  209. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/mixins/waitformotion.py +0 -0
  210. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/mixins/weatheraware.py +0 -0
  211. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/__init__.py +0 -0
  212. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/camera/__init__.py +0 -0
  213. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/camera/adaptive.py +0 -0
  214. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/camera/basecamera.py +0 -0
  215. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/camera/basespectrograph.py +0 -0
  216. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/camera/basevideo.py +0 -0
  217. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/camera/dummycamera.py +0 -0
  218. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/camera/dummyspectrograph.py +0 -0
  219. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/camera/dummyvideo.py +0 -0
  220. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/camera/pipelinecamera.py +0 -0
  221. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/flatfield/__init__.py +0 -0
  222. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/flatfield/flatfield.py +0 -0
  223. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/flatfield/pointing.py +0 -0
  224. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/flatfield/scheduler.py +0 -0
  225. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/focus/__init__.py +0 -0
  226. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/focus/dummyautofocus.py +0 -0
  227. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/focus/focusmodel.py +0 -0
  228. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/focus/focusseries.py +0 -0
  229. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/image/__init__.py +0 -0
  230. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/image/imagewatcher.py +0 -0
  231. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/image/imagewriter.py +0 -0
  232. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/image/pipeline.py +0 -0
  233. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/image/seeing.py +0 -0
  234. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/module.py +0 -0
  235. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/pointing/__init__.py +0 -0
  236. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/pointing/_base.py +0 -0
  237. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/pointing/_baseguiding.py +0 -0
  238. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/pointing/acquisition.py +0 -0
  239. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/pointing/autoguiding.py +0 -0
  240. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/pointing/dummyacquisition.py +0 -0
  241. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/pointing/dummyguiding.py +0 -0
  242. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/pointing/guidingstatistics/__init__.py +0 -0
  243. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/pointing/guidingstatistics/guidingstatistics.py +0 -0
  244. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/pointing/guidingstatistics/pixeloffset.py +0 -0
  245. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/pointing/guidingstatistics/skyoffsets.py +0 -0
  246. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/pointing/guidingstatistics/uptime.py +0 -0
  247. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/pointing/scienceframeguiding.py +0 -0
  248. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/robotic/__init__.py +0 -0
  249. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/robotic/mastermind.py +0 -0
  250. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/robotic/pointing.py +0 -0
  251. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/robotic/scheduler.py +0 -0
  252. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/robotic/scriptrunner.py +0 -0
  253. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/roof/__init__.py +0 -0
  254. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/roof/basedome.py +0 -0
  255. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/roof/baseroof.py +0 -0
  256. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/roof/dummyroof.py +0 -0
  257. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/telescope/__init__.py +0 -0
  258. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/telescope/_dummytelescopebase.py +0 -0
  259. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/telescope/basetelescope.py +0 -0
  260. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/telescope/dummyaltaztelescope.py +0 -0
  261. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/telescope/dummyradectelescope.py +0 -0
  262. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/telescope/dummysolartelescope.py +0 -0
  263. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/test/__init__.py +0 -0
  264. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/test/standalone.py +0 -0
  265. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/utils/__init__.py +0 -0
  266. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/utils/dummymode.py +0 -0
  267. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/utils/fluentlogger.py +0 -0
  268. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/utils/httpfilecache.py +0 -0
  269. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/utils/kiosk.py +0 -0
  270. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/utils/matrix.py +0 -0
  271. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/utils/stellarium.py +0 -0
  272. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/utils/telegram.py +0 -0
  273. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/utils/trigger.py +0 -0
  274. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/weather/__init__.py +0 -0
  275. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/weather/mockweather.py +0 -0
  276. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/weather/weather.py +0 -0
  277. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/weather/weather_api.py +0 -0
  278. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/modules/weather/weather_state.py +0 -0
  279. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/object.py +0 -0
  280. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/py.typed +0 -0
  281. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/__init__.py +0 -0
  282. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/observation.py +0 -0
  283. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scheduler/__init__.py +0 -0
  284. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scheduler/astroplanscheduler.py +0 -0
  285. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scheduler/constraints/__init__.py +0 -0
  286. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scheduler/constraints/airmassconstraint.py +0 -0
  287. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scheduler/constraints/constraint.py +0 -0
  288. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scheduler/constraints/timeconstraint.py +0 -0
  289. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scheduler/merits/__init__.py +0 -0
  290. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scheduler/merits/aftertime.py +0 -0
  291. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scheduler/merits/beforetime.py +0 -0
  292. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scheduler/merits/constant.py +0 -0
  293. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scheduler/merits/follow.py +0 -0
  294. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scheduler/merits/interval.py +0 -0
  295. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scheduler/merits/merit.py +0 -0
  296. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scheduler/merits/pernight.py +0 -0
  297. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scheduler/merits/random.py +0 -0
  298. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scheduler/merits/timewindow.py +0 -0
  299. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scheduler/merits/transit.py +0 -0
  300. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scheduler/observationarchiveevolution.py +0 -0
  301. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scheduler/targets/__init__.py +0 -0
  302. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scheduler/targets/dynamictarget.py +0 -0
  303. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scheduler/targets/heliocentricpolartarget.py +0 -0
  304. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scheduler/targets/helioprojectivetarget.py +0 -0
  305. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scheduler/targets/picker/__init__.py +0 -0
  306. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scheduler/targets/picker/csvpicker.py +0 -0
  307. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scheduler/targets/picker/picker.py +0 -0
  308. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scheduler/targets/siderealtarget.py +0 -0
  309. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scheduler/targets/target.py +0 -0
  310. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scheduler/taskscheduler.py +0 -0
  311. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scripts/__init__.py +0 -0
  312. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scripts/calibration/__init__.py +0 -0
  313. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scripts/calibration/darkbias.py +0 -0
  314. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scripts/calibration/pointing.py +0 -0
  315. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scripts/calibration/skyflats.py +0 -0
  316. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scripts/control/__init__.py +0 -0
  317. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scripts/control/cases.py +0 -0
  318. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scripts/control/conditional.py +0 -0
  319. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scripts/control/parallel.py +0 -0
  320. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scripts/control/selector.py +0 -0
  321. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scripts/control/sequential.py +0 -0
  322. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scripts/exceptions.py +0 -0
  323. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scripts/imaging/__init__.py +0 -0
  324. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scripts/imaging/autofocus.py +0 -0
  325. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scripts/imaging/imaging.py +0 -0
  326. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scripts/imaging/transitimaging.py +0 -0
  327. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scripts/script.py +0 -0
  328. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scripts/utils/__init__.py +0 -0
  329. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scripts/utils/callmodule.py +0 -0
  330. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scripts/utils/debugtrigger.py +0 -0
  331. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/scripts/utils/log.py +0 -0
  332. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/storage/__init__.py +0 -0
  333. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/storage/backend/__init__.py +0 -0
  334. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/storage/backend/observationarchive.py +0 -0
  335. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/storage/backend/taskarchive.py +0 -0
  336. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/storage/filesystem/__init__.py +0 -0
  337. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/storage/filesystem/observationarchive.py +0 -0
  338. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/storage/filesystem/taskarchive.py +0 -0
  339. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/storage/lco/__init__.py +0 -0
  340. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/storage/lco/_portal.py +0 -0
  341. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/storage/lco/_schedulereader.py +0 -0
  342. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/storage/lco/_schedulewriter.py +0 -0
  343. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/storage/lco/configdb.py +0 -0
  344. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/storage/lco/mockobservationarchive.py +0 -0
  345. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/storage/lco/observationarchive.py +0 -0
  346. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/storage/lco/scripts/__init__.py +0 -0
  347. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/storage/lco/scripts/autofocus.py +0 -0
  348. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/storage/lco/scripts/default.py +0 -0
  349. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/storage/lco/scripts/script.py +0 -0
  350. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/storage/lco/task.py +0 -0
  351. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/storage/lco/taskarchive.py +0 -0
  352. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/storage/lco/taskrunner.py +0 -0
  353. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/storage/memory/__init__.py +0 -0
  354. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/storage/memory/observationarchive.py +0 -0
  355. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/storage/memory/taskarchive.py +0 -0
  356. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/storage/observationarchive.py +0 -0
  357. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/storage/taskarchive.py +0 -0
  358. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/task.py +0 -0
  359. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/taskrunner.py +0 -0
  360. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/utils/__init__.py +0 -0
  361. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/utils/archive/__init__.py +0 -0
  362. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/utils/archive/archive.py +0 -0
  363. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/utils/archive/local_archive.py +0 -0
  364. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/utils/archive/pyobs_archive.py +0 -0
  365. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/utils/exptime/__init__.py +0 -0
  366. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/utils/exptime/exptime.py +0 -0
  367. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/utils/exptime/stellarexptime.py +0 -0
  368. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/utils/skyflats/__init__.py +0 -0
  369. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/utils/skyflats/exptimeeval.py +0 -0
  370. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/utils/skyflats/flatfielder.py +0 -0
  371. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/utils/skyflats/pointing/__init__.py +0 -0
  372. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/utils/skyflats/pointing/base.py +0 -0
  373. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/utils/skyflats/pointing/static.py +0 -0
  374. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/utils/skyflats/priorities/__init__.py +0 -0
  375. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/utils/skyflats/priorities/archive.py +0 -0
  376. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/utils/skyflats/priorities/base.py +0 -0
  377. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/utils/skyflats/priorities/const.py +0 -0
  378. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/robotic/utils/skyflats/scheduler.py +0 -0
  379. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/__init__.py +0 -0
  380. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/average.py +0 -0
  381. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/cache.py +0 -0
  382. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/config.py +0 -0
  383. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/config_schema.py +0 -0
  384. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/coordinates.py +0 -0
  385. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/curvefit.py +0 -0
  386. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/enums.py +0 -0
  387. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/exceptions.py +0 -0
  388. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/fits.py +0 -0
  389. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/focusseries/__init__.py +0 -0
  390. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/focusseries/base.py +0 -0
  391. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/focusseries/photometry.py +0 -0
  392. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/focusseries/projection.py +0 -0
  393. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/grids/__init__.py +0 -0
  394. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/grids/filters.py +0 -0
  395. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/grids/grid.py +0 -0
  396. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/grids/gridnode.py +0 -0
  397. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/grids/pipeline.py +0 -0
  398. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/gui/__init__.py +0 -0
  399. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/gui/camera/__init__.py +0 -0
  400. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/gui/camera/binningwidget.py +0 -0
  401. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/gui/camera/datadisplaywidget.py +0 -0
  402. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/gui/camera/exposewidget.py +0 -0
  403. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/gui/camera/exposuretimewidget.py +0 -0
  404. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/gui/camera/imageformatwidget.py +0 -0
  405. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/gui/camera/listpickerdialog.py +0 -0
  406. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/gui/camera/windowingwidget.py +0 -0
  407. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/http.py +0 -0
  408. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/influxdb.py +0 -0
  409. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/logger.py +0 -0
  410. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/logging/__init__.py +0 -0
  411. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/logging/context.py +0 -0
  412. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/logging/resolvableerror.py +0 -0
  413. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/modulegui.py +0 -0
  414. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/offsets/__init__.py +0 -0
  415. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/offsets/applyaltazoffsets.py +0 -0
  416. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/offsets/applyoffsets.py +0 -0
  417. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/offsets/applyradecoffsets.py +0 -0
  418. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/parallel.py +0 -0
  419. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/pipeline/__init__.py +0 -0
  420. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/pipeline/night.py +0 -0
  421. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/pipeline/pipeline.py +0 -0
  422. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/publisher/__init__.py +0 -0
  423. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/publisher/csv.py +0 -0
  424. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/publisher/http.py +0 -0
  425. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/publisher/log.py +0 -0
  426. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/publisher/multi.py +0 -0
  427. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/publisher/publisher.py +0 -0
  428. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/serialization.py +0 -0
  429. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/shellcommand.py +0 -0
  430. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/threads/__init__.py +0 -0
  431. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/threads/lockwithabort.py +0 -0
  432. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/time.py +0 -0
  433. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/utils/units.py +0 -0
  434. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/version.py +0 -0
  435. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/vfs/__init__.py +0 -0
  436. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/vfs/archivefile.py +0 -0
  437. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/vfs/bufferedfile.py +0 -0
  438. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/vfs/file.py +0 -0
  439. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/vfs/filelists/__init__.py +0 -0
  440. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/vfs/filelists/filelist.py +0 -0
  441. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/vfs/filelists/testing.py +0 -0
  442. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/vfs/httpfile.py +0 -0
  443. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/vfs/localfile.py +0 -0
  444. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/vfs/memfile.py +0 -0
  445. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/vfs/sftpfile.py +0 -0
  446. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/vfs/smbfile.py +0 -0
  447. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/vfs/sshfile.py +0 -0
  448. {pyobs_core-2.0.0.dev52 → pyobs_core-2.0.0.dev53}/pyobs/vfs/tempfile.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyobs-core
3
- Version: 2.0.0.dev52
3
+ Version: 2.0.0.dev53
4
4
  Summary: robotic telescope software
5
5
  Author-email: Tim-Oliver Husser <thusser@uni-goettingen.de>
6
6
  License-Expression: MIT
@@ -0,0 +1,63 @@
1
+ from abc import ABCMeta, abstractmethod
2
+ from typing import Any
3
+
4
+ from pyobs.images import Image
5
+ from pyobs.object import Object
6
+ from pyobs.utils.exceptions import ImageError
7
+
8
+
9
+ class ImageProcessor(Object, metaclass=ABCMeta):
10
+ VALID_ERROR_MODES = frozenset(("raise", "error", "info", "ignore"))
11
+
12
+ def __init__(self, on_error: str = "raise", **kwargs: Any):
13
+ """Init new image processor.
14
+
15
+ Args:
16
+ on_error: How the pipeline should handle an ImageError raised by this step. One of:
17
+ - "raise" (default): re-raise the exception, aborting the pipeline.
18
+ - "error": call handle_error(), pass its return value downstream.
19
+ - "info": log at INFO level, pass the pre-step image downstream unmodified.
20
+ - "ignore": silently pass the pre-step image downstream unmodified.
21
+ """
22
+ Object.__init__(self, **kwargs)
23
+
24
+ self._on_error = on_error
25
+ if self._on_error not in self.VALID_ERROR_MODES:
26
+ raise ValueError(f"on_error must be one of {sorted(self.VALID_ERROR_MODES)}, got {self._on_error!r}.")
27
+
28
+ @property
29
+ def on_error(self) -> str:
30
+ """The error handling mode for this step."""
31
+ return self._on_error
32
+
33
+ @abstractmethod
34
+ async def __call__(self, image: Image) -> Image:
35
+ """Processes an image.
36
+
37
+ Args:
38
+ image: Image to process.
39
+
40
+ Returns:
41
+ Processed image.
42
+ """
43
+
44
+ def handle_error(self, image: Image, error: ImageError) -> Image:
45
+ """Handle an ImageError raised by this step, when on_error == "error".
46
+
47
+ Override this to customize error handling (e.g. tag the image with a FITS header).
48
+ The default implementation re-raises the error.
49
+
50
+ Args:
51
+ image: The image that caused the error.
52
+ error: The ImageError that was raised.
53
+
54
+ Returns:
55
+ The image to pass to the next pipeline step.
56
+ """
57
+ raise error
58
+
59
+ async def reset(self) -> None:
60
+ """Resets state of image processor"""
61
+
62
+
63
+ __all__ = ["ImageProcessor"]
@@ -31,11 +31,15 @@ class AstrometryDotNet(Astrometry):
31
31
  (commonly degrees for astrometry.net). Default: ``3.0``.
32
32
  :param int timeout: Timeout in seconds for the network call to the astrometry
33
33
  web service. Default: ``10``.
34
- :param bool exceptions: Whether to raise exceptions on failure. If ``True``,
35
- processing errors are raised (typically as
36
- :class:`pyobs.images.exceptions.ImageError`). If ``False``,
37
- errors are handled by marking the image header and returning
38
- the original image. Default: ``True``.
34
+ :param bool exceptions: Deprecated, use ``on_error`` instead. ``exceptions=False`` is
35
+ equivalent to ``on_error="error"``; ``exceptions=True`` (the
36
+ default) is equivalent to ``on_error="raise"``.
37
+ :param str on_error: How the pipeline should handle a failed solve: ``"raise"`` (default,
38
+ abort the pipeline), ``"error"`` (mark ``WCSERR=1`` in the header, log
39
+ a warning, and pass the image through -- see ``handle_error``),
40
+ ``"info"``, or ``"ignore"``. Only takes effect when this processor
41
+ runs as a step in a ``PipelineMixin`` pipeline; a direct call always
42
+ raises on failure.
39
43
  :param kwargs: Additional keyword arguments forwarded to
40
44
  :class:`pyobs.images.processors.astrometry.Astrometry`.
41
45
 
@@ -48,11 +52,9 @@ class AstrometryDotNet(Astrometry):
48
52
  - On success, receives solver output and writes the resulting WCS into a copy of
49
53
  the input image using :class:`pyobs.images.processors.astrometry._ResponseImageWriter`.
50
54
  - Logs the outcome, including WCS information, and returns the result image.
51
- - On failure:
52
-
53
- - If ``exceptions=True``, raises the underlying :class:`pyobs.images.exceptions.ImageError`.
54
- - If ``exceptions=False``, sets ``WCSERR=1`` in the FITS header, logs a warning, and returns the original
55
- image unchanged.
55
+ - On failure, raises the underlying :class:`pyobs.images.exceptions.ImageError`. When run as
56
+ a pipeline step with ``on_error="error"``, the pipeline calls ``handle_error``, which sets
57
+ ``WCSERR=1`` in the FITS header, logs a warning, and returns the original image unchanged.
56
58
 
57
59
  Input/Output
58
60
  ------------
@@ -69,20 +71,20 @@ class AstrometryDotNet(Astrometry):
69
71
  class: pyobs.images.processors.astrometry.AstrometryDotNet
70
72
  url: "http://localhost:8080/api"
71
73
 
72
- Handle failures without raising exceptions:
74
+ Handle failures without aborting the pipeline:
73
75
 
74
76
  .. code-block:: yaml
75
77
 
76
78
  class: pyobs.images.processors.astrometry.AstrometryDotNet
77
79
  url: "http://localhost:8080/api"
78
- exceptions: false
80
+ on_error: error
79
81
 
80
82
  Notes
81
83
  -----
82
84
  - The ``_DotNetRequestBuilder`` determines how sources are extracted and how the
83
85
  request is formed (including any unit conventions for ``radius``). Consult its
84
86
  documentation for details.
85
- - ``WCSERR`` is used as a failure marker in the FITS header when ``exceptions=False``.
87
+ - ``WCSERR`` is used as a failure marker in the FITS header when ``handle_error`` runs.
86
88
  """
87
89
 
88
90
  __module__ = "pyobs.images.processors.astrometry"
@@ -93,7 +95,8 @@ class AstrometryDotNet(Astrometry):
93
95
  source_count: int = 50,
94
96
  radius: float = 3.0,
95
97
  timeout: int = 10,
96
- exceptions: bool = True,
98
+ exceptions: bool | None = None,
99
+ on_error: str = "raise",
97
100
  **kwargs: Any,
98
101
  ):
99
102
  """Init new astronomy.net processor.
@@ -103,17 +106,28 @@ class AstrometryDotNet(Astrometry):
103
106
  source_count: Number of sources to send.
104
107
  radius: Radius to search in.
105
108
  timeout: Timeout in seconds for call to astrometry web service.
106
- exceptions: Whether to raise Exceptions.
109
+ exceptions: Deprecated, use on_error instead. Whether to raise Exceptions.
110
+ on_error: How to handle a failed solve. One of "raise", "error", "info", "ignore".
111
+ On "error", handle_error() marks the image with WCSERR=1 and logs a warning.
107
112
  """
108
- Astrometry.__init__(self, **kwargs)
113
+ Astrometry.__init__(self, on_error=on_error, **kwargs)
109
114
 
110
115
  self.url = url
111
116
 
112
117
  self.timeout = timeout
113
- self.exceptions = exceptions
118
+
119
+ # backwards compat: if 'exceptions' is set but 'on_error' is left at its default,
120
+ # derive on_error from it.
121
+ if exceptions is not None and on_error == "raise":
122
+ self._on_error = "raise" if exceptions else "error"
114
123
 
115
124
  self._request_builder = _DotNetRequestBuilder(source_count, radius)
116
125
 
126
+ @property
127
+ def exceptions(self) -> bool:
128
+ """Deprecated, use on_error instead."""
129
+ return self.on_error != "error"
130
+
117
131
  async def _process(self, image: Image) -> Image:
118
132
  # build the request
119
133
  request = self._request_builder(image)
@@ -132,10 +146,7 @@ class AstrometryDotNet(Astrometry):
132
146
 
133
147
  return result_image
134
148
 
135
- def _handle_error(self, image: Image, error: exc.ImageError) -> Image:
136
- if self.exceptions:
137
- raise error
138
-
149
+ def handle_error(self, image: Image, error: exc.ImageError) -> Image:
139
150
  image.header["WCSERR"] = 1
140
151
 
141
152
  log.warning(error.message)
@@ -145,16 +156,13 @@ class AstrometryDotNet(Astrometry):
145
156
  async def __call__(self, image: Image) -> Image:
146
157
  """Find astrometric solution on given image.
147
158
 
148
- Writes WCSERR=1 into FITS header on failure.
159
+ Writes WCSERR=1 into FITS header on failure (see handle_error).
149
160
 
150
161
  Args:
151
162
  image: Image to analyse.
152
163
  """
153
164
 
154
- try:
155
- return await self._process(image)
156
- except exc.ImageError as e:
157
- return self._handle_error(image, e)
165
+ return await self._process(image)
158
166
 
159
167
 
160
168
  __all__ = ["AstrometryDotNet"]
@@ -5,6 +5,7 @@ from typing import Any
5
5
 
6
6
  from pyobs.images import Image, ImageProcessor
7
7
  from pyobs.object import Object
8
+ from pyobs.utils.exceptions import ImageError
8
9
 
9
10
  log = logging.getLogger(__name__)
10
11
 
@@ -37,6 +38,10 @@ class PipelineMixin:
37
38
  async def run_pipeline(self, image: Image) -> Image:
38
39
  """Run the pipeline on the given image.
39
40
 
41
+ Each step is run, and an ImageError it raises is handled according to the step's
42
+ on_error setting (default "raise"): re-raised, dispatched to the step's handle_error(),
43
+ logged, or ignored. Non-ImageError exceptions always propagate.
44
+
40
45
  Args:
41
46
  image: Image to run pipeline on.
42
47
 
@@ -44,9 +49,18 @@ class PipelineMixin:
44
49
  Image after pipeline run.
45
50
  """
46
51
 
47
- # loop steps, just let any exception pass
48
52
  for step in self.__pipeline_steps:
49
- image = await step(image)
53
+ try:
54
+ image = await step(image)
55
+ except ImageError as e:
56
+ if step.on_error == "raise":
57
+ raise
58
+ elif step.on_error == "error":
59
+ image = step.handle_error(image, e)
60
+ elif step.on_error == "info":
61
+ log.info("Step %s: %s", type(step).__name__, e)
62
+ elif step.on_error == "ignore":
63
+ pass
50
64
 
51
65
  # finished
52
66
  return image
@@ -0,0 +1,28 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+ from collections.abc import Callable, Coroutine
5
+ from concurrent.futures import ThreadPoolExecutor
6
+ from typing import Any, TypeVar
7
+
8
+ _T = TypeVar("_T")
9
+
10
+ # single worker: evaluate_constraints_and_merits calls are always awaited sequentially by the
11
+ # caller (never fired concurrently), and DataProvider's functools.cache is not safe under real
12
+ # concurrent access -- one worker keeps that access serialized while still freeing the main loop.
13
+ _executor = ThreadPoolExecutor(max_workers=1, thread_name_prefix="pyobs-scheduler")
14
+
15
+
16
+ async def run_cpu_bound(coro_fn: Callable[..., Coroutine[Any, Any, _T]], *args: object) -> _T:
17
+ """Runs an async callable to completion on a dedicated worker thread, off the caller's loop.
18
+
19
+ Args:
20
+ coro_fn: An async callable whose body does not itself need to run on the caller's
21
+ event loop (no dependency on the caller's other tasks, timers, or comm state).
22
+ args: Positional args for coro_fn.
23
+ """
24
+ loop = asyncio.get_running_loop()
25
+ return await loop.run_in_executor(_executor, lambda: asyncio.run(coro_fn(*args)))
26
+
27
+
28
+ __all__ = ["run_cpu_bound"]
@@ -24,7 +24,7 @@ class MoonIlluminationConstraint(Constraint):
24
24
  return astroplan.MoonIlluminationConstraint(max=self.max_phase)
25
25
 
26
26
  async def __call__(self, time: Time, task: Task, data: DataProvider) -> bool:
27
- moon_illumination = float(data.observer.moon_illumination(time))
27
+ moon_illumination = data.moon_illumination(time)
28
28
  return moon_illumination <= self.max_phase
29
29
 
30
30
 
@@ -3,7 +3,6 @@ from __future__ import annotations
3
3
  from typing import TYPE_CHECKING
4
4
 
5
5
  import astroplan
6
- import astropy.coordinates
7
6
  import astropy.units as u
8
7
  import numpy as np
9
8
  from astropy.coordinates import SkyCoord
@@ -32,12 +31,12 @@ class MoonSeparationConstraint(Constraint):
32
31
  if task.target is None:
33
32
  return True
34
33
  coord = task.target.coordinates(time)
35
- moon_separation = astropy.coordinates.get_body("moon", time).separation(coord, origin_mismatch="ignore")
34
+ moon_separation = data.moon(time).separation(coord, origin_mismatch="ignore") # type: ignore[unexpected-keyword]
36
35
  return float(moon_separation.degree) >= self.min_distance
37
36
 
38
37
  async def filter_skycoord(self, time: Time, coords: SkyCoord, data: DataProvider) -> np.ndarray:
39
- moon = astropy.coordinates.get_body("moon", time)
40
- separations = moon.separation(coords, origin_mismatch="ignore").deg
38
+ moon = data.moon(time)
39
+ separations = moon.separation(coords, origin_mismatch="ignore").deg # type: ignore[unexpected-keyword]
41
40
  return np.asarray(separations >= self.min_distance, dtype=np.bool_)
42
41
 
43
42
 
@@ -5,7 +5,6 @@ from typing import TYPE_CHECKING, Literal
5
5
 
6
6
  import astroplan
7
7
  import astropy.units as u
8
- from astropy.coordinates import get_sun
9
8
  from pydantic import Field
10
9
 
11
10
  from pyobs.utils.time import Time
@@ -34,12 +33,12 @@ class SolarElevationConstraint(Constraint):
34
33
  return astroplan.AtNightConstraint(max_solar_altitude=self.max_elevation * u.deg)
35
34
 
36
35
  async def __call__(self, time: Time, task: Task, data: DataProvider) -> bool:
37
- sun = data.observer.sun_altaz(time)
36
+ sun = data.sun_altaz(time)
38
37
  in_range = self.min_elevation <= float(sun.alt.degree) <= self.max_elevation
39
38
  if self.direction == "both":
40
39
  return in_range
41
40
  else:
42
- sun_coord = get_sun(time)
41
+ sun_coord = data.sun(time)
43
42
  transit = data.observer.target_meridian_transit_time(time, sun_coord, which="nearest")
44
43
  midnight = data.observer.midnight(time, which="nearest")
45
44
 
@@ -0,0 +1,78 @@
1
+ from __future__ import annotations
2
+
3
+ import datetime
4
+ from dataclasses import dataclass
5
+ from functools import cache
6
+
7
+ import astropy.coordinates
8
+ from astroplan import Observer
9
+ from astropy.coordinates import SkyCoord
10
+
11
+ from pyobs.robotic.scheduler.observationarchiveevolution import (
12
+ ObservationArchiveEvolution,
13
+ )
14
+ from pyobs.utils.time import Time
15
+
16
+
17
+ @dataclass
18
+ class TaskSuccess:
19
+ date: Time
20
+ night: Time
21
+
22
+
23
+ class DataProvider:
24
+ """Data provider for Merit classes.
25
+
26
+ The ``@cache``d methods below are only safe to call from a single thread at a time -- they're
27
+ used exclusively from within the scheduler's dedicated single-worker executor
28
+ (`pyobs.robotic.scheduler._executor.run_cpu_bound`), never concurrently from the caller's main
29
+ event loop. A new `DataProvider` is created per `schedule()` call, so cache lifetime is bounded
30
+ to one schedule computation and never leaks stale values across runs.
31
+ """
32
+
33
+ def __init__(self, observer: Observer, archive: ObservationArchiveEvolution | None = None):
34
+ self.observer = observer
35
+ self.archive = archive if archive else ObservationArchiveEvolution(observer)
36
+
37
+ @cache
38
+ def last_sunset(self, time: Time) -> Time:
39
+ """Returns the time of the last sunset."""
40
+
41
+ # get last sunset
42
+ return Time(self.observer.sun_set_time(time, which="previous"))
43
+
44
+ @cache
45
+ def last_sunrise(self, time: Time) -> Time:
46
+ """Returns the time of the last sunrise."""
47
+
48
+ # get last sunset
49
+ return Time(self.observer.sun_rise_time(time, which="previous"))
50
+
51
+ @cache
52
+ def night(self, time: Time) -> datetime.date:
53
+ """Returns the time of the last sunset."""
54
+ sunset = self.last_sunset(time)
55
+ return sunset.to_datetime().date()
56
+
57
+ @cache
58
+ def sun(self, time: Time) -> SkyCoord:
59
+ """Returns the Sun's coordinates at the given time."""
60
+ return astropy.coordinates.get_sun(time)
61
+
62
+ @cache
63
+ def sun_altaz(self, time: Time) -> SkyCoord:
64
+ """Returns the Sun's AltAz coordinates at the given time, as seen by the observer."""
65
+ return self.observer.sun_altaz(time)
66
+
67
+ @cache
68
+ def moon(self, time: Time) -> SkyCoord:
69
+ """Returns the Moon's coordinates at the given time."""
70
+ return astropy.coordinates.get_body("moon", time)
71
+
72
+ @cache
73
+ def moon_illumination(self, time: Time) -> float:
74
+ """Returns the Moon's illumination fraction at the given time."""
75
+ return float(self.observer.moon_illumination(time))
76
+
77
+
78
+ __all__ = ["DataProvider"]
@@ -14,6 +14,7 @@ from pyobs.robotic.storage.observationarchive import ObservationArchive
14
14
  from pyobs.utils.time import Time
15
15
 
16
16
  from . import DataProvider
17
+ from ._executor import run_cpu_bound
17
18
  from .constraints import Constraint
18
19
  from .observationarchiveevolution import ObservationArchiveEvolution
19
20
  from .taskscheduler import TaskScheduler
@@ -250,7 +251,7 @@ class OnDemandScheduler(TaskScheduler):
250
251
  ) -> tuple[Task | None, float]:
251
252
 
252
253
  # evaluate all merit functions at given time
253
- merits = await self.evaluate_constraints_and_merits(tasks, projects, start, end, data)
254
+ merits = await run_cpu_bound(self.evaluate_constraints_and_merits, tasks, projects, start, end, data)
254
255
 
255
256
  # find max one
256
257
  idx = np.argmax(merits)
@@ -274,7 +275,7 @@ class OnDemandScheduler(TaskScheduler):
274
275
  other_tasks = [t for t in tasks if t is not task]
275
276
  t = start + TimeDelta(step * u.second)
276
277
  while t < start + TimeDelta(task.estimate_duration(time=start) * u.second):
277
- merits = await self.evaluate_constraints_and_merits(other_tasks, projects, t, end, data)
278
+ merits = await run_cpu_bound(self.evaluate_constraints_and_merits, other_tasks, projects, t, end, data)
278
279
  for i, m in enumerate(merits):
279
280
  if m > merit:
280
281
  return other_tasks[i], t, m
@@ -295,7 +296,9 @@ class OnDemandScheduler(TaskScheduler):
295
296
  better_start: Time = start + TimeDelta(task.estimate_duration(time=start) * u.second)
296
297
 
297
298
  # evaluate merit of better_task at new start time
298
- merit = (await self.evaluate_constraints_and_merits([better_task], projects, better_start, end, data))[0]
299
+ merit = (
300
+ await run_cpu_bound(self.evaluate_constraints_and_merits, [better_task], projects, better_start, end, data)
301
+ )[0]
299
302
 
300
303
  # if it got better, return it, otherwise return Nones
301
304
  if merit >= better_merit:
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import asyncio
3
4
  import io
4
5
  import logging
5
6
  from collections.abc import Awaitable, Callable
@@ -114,11 +115,15 @@ class VirtualFileSystem:
114
115
  hdulist: hdu list to write.
115
116
  """
116
117
 
117
- # open file
118
- async with self.open_file(filename, "wb") as f:
118
+ def _serialize() -> bytes:
119
119
  with io.BytesIO() as bio:
120
120
  hdulist.writeto(bio, *args, **kwargs)
121
- await f.write(bio.getvalue())
121
+ return bio.getvalue()
122
+
123
+ # open file
124
+ async with self.open_file(filename, "wb") as f:
125
+ data = await asyncio.to_thread(_serialize)
126
+ await f.write(data)
122
127
 
123
128
  async def read_image(self, filename: str) -> Image:
124
129
  """Convenience function that wraps around open_file() to read an Image.
@@ -145,11 +150,15 @@ class VirtualFileSystem:
145
150
  image: Image to write.
146
151
  """
147
152
 
148
- # open file
149
- async with self.open_file(filename, "wb") as f:
153
+ def _serialize() -> bytes:
150
154
  with io.BytesIO() as bio:
151
155
  image.writeto(bio, *args, **kwargs)
152
- await f.write(bio.getvalue())
156
+ return bio.getvalue()
157
+
158
+ # open file
159
+ async with self.open_file(filename, "wb") as f:
160
+ data = await asyncio.to_thread(_serialize)
161
+ await f.write(data)
153
162
 
154
163
  async def write_bytes(self, filename: str, data: bytes, *args: Any, **kwargs: Any) -> None:
155
164
  """Convenience function for writing bytes to a file.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pyobs-core"
3
- version = "2.0.0.dev52"
3
+ version = "2.0.0.dev53"
4
4
  description = "robotic telescope software"
5
5
  authors = [{ name = "Tim-Oliver Husser", email = "thusser@uni-goettingen.de" }]
6
6
  requires-python = ">=3.11"
@@ -1,28 +0,0 @@
1
- from abc import ABCMeta, abstractmethod
2
- from typing import Any
3
-
4
- from pyobs.images import Image
5
- from pyobs.object import Object
6
-
7
-
8
- class ImageProcessor(Object, metaclass=ABCMeta):
9
- def __init__(self, **kwargs: Any):
10
- """Init new image processor."""
11
- Object.__init__(self, **kwargs)
12
-
13
- @abstractmethod
14
- async def __call__(self, image: Image) -> Image:
15
- """Processes an image.
16
-
17
- Args:
18
- image: Image to process.
19
-
20
- Returns:
21
- Processed image.
22
- """
23
-
24
- async def reset(self) -> None:
25
- """Resets state of image processor"""
26
-
27
-
28
- __all__ = ["ImageProcessor"]
@@ -1,49 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import datetime
4
- from dataclasses import dataclass
5
- from functools import cache
6
-
7
- from astroplan import Observer
8
-
9
- from pyobs.robotic.scheduler.observationarchiveevolution import (
10
- ObservationArchiveEvolution,
11
- )
12
- from pyobs.utils.time import Time
13
-
14
-
15
- @dataclass
16
- class TaskSuccess:
17
- date: Time
18
- night: Time
19
-
20
-
21
- class DataProvider:
22
- """Data provider for Merit classes."""
23
-
24
- def __init__(self, observer: Observer, archive: ObservationArchiveEvolution | None = None):
25
- self.observer = observer
26
- self.archive = archive if archive else ObservationArchiveEvolution(observer)
27
-
28
- @cache
29
- def last_sunset(self, time: Time) -> Time:
30
- """Returns the time of the last sunset."""
31
-
32
- # get last sunset
33
- return Time(self.observer.sun_set_time(time, which="previous"))
34
-
35
- @cache
36
- def last_sunrise(self, time: Time) -> Time:
37
- """Returns the time of the last sunrise."""
38
-
39
- # get last sunset
40
- return Time(self.observer.sun_rise_time(time, which="previous"))
41
-
42
- @cache
43
- def night(self, time: Time) -> datetime.date:
44
- """Returns the time of the last sunset."""
45
- sunset = self.last_sunset(time)
46
- return sunset.to_datetime().date()
47
-
48
-
49
- __all__ = ["DataProvider"]