pyobs-core 2.0.0.dev66__tar.gz → 2.0.0.dev68__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.dev66 → pyobs_core-2.0.0.dev68}/PKG-INFO +1 -1
  2. pyobs_core-2.0.0.dev68/pyobs/robotic/scheduler/_executor.py +28 -0
  3. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scheduler/constraints/moonilluminationconstraint.py +1 -1
  4. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scheduler/constraints/moonseparationconstraint.py +3 -4
  5. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scheduler/constraints/solarelevationconstraint.py +2 -3
  6. pyobs_core-2.0.0.dev68/pyobs/robotic/scheduler/dataprovider.py +78 -0
  7. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scheduler/observationarchiveevolution.py +32 -1
  8. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scheduler/ondemandscheduler.py +12 -3
  9. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/utils/archive/local_archive.py +7 -1
  10. pyobs_core-2.0.0.dev68/pyobs/utils/pipeline/__init__.py +4 -0
  11. pyobs_core-2.0.0.dev66/pyobs/utils/pipeline/night.py → pyobs_core-2.0.0.dev68/pyobs/utils/pipeline/reduction.py +37 -16
  12. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyproject.toml +1 -1
  13. pyobs_core-2.0.0.dev66/pyobs/robotic/scheduler/dataprovider.py +0 -49
  14. pyobs_core-2.0.0.dev66/pyobs/utils/pipeline/__init__.py +0 -4
  15. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/.gitignore +0 -0
  16. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/LICENSE +0 -0
  17. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/__init__.py +0 -0
  18. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/application.py +0 -0
  19. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/background_task.py +0 -0
  20. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/cli/__init__.py +0 -0
  21. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/cli/_cli.py +0 -0
  22. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/cli/pyobs.py +0 -0
  23. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/cli/pyobsd.py +0 -0
  24. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/cli/pyobsw.py +0 -0
  25. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/comm/__init__.py +0 -0
  26. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/comm/comm.py +0 -0
  27. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/comm/commlogging.py +0 -0
  28. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/comm/dummy/__init__.py +0 -0
  29. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/comm/dummy/dummycomm.py +0 -0
  30. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/comm/local/__init__.py +0 -0
  31. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/comm/local/localcomm.py +0 -0
  32. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/comm/local/localnetwork.py +0 -0
  33. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/comm/proxy.py +0 -0
  34. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/comm/xmpp/__init__.py +0 -0
  35. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/comm/xmpp/rpc.py +0 -0
  36. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/comm/xmpp/serializer.py +0 -0
  37. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/comm/xmpp/xep_0009/__init__.py +0 -0
  38. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/comm/xmpp/xep_0009/binding.py +0 -0
  39. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/comm/xmpp/xep_0009/rpc.py +0 -0
  40. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/comm/xmpp/xep_0009_timeout/__init__.py +0 -0
  41. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/comm/xmpp/xep_0009_timeout/rpc.py +0 -0
  42. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/comm/xmpp/xep_0009_timeout/stanza/RPC.py +0 -0
  43. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/comm/xmpp/xep_0009_timeout/stanza/__init__.py +0 -0
  44. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/comm/xmpp/xmppclient.py +0 -0
  45. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/comm/xmpp/xmppcomm.py +0 -0
  46. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/events/__init__.py +0 -0
  47. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/events/badweather.py +0 -0
  48. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/events/event.py +0 -0
  49. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/events/exposurestatuschanged.py +0 -0
  50. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/events/filterchanged.py +0 -0
  51. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/events/focusfound.py +0 -0
  52. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/events/goodweather.py +0 -0
  53. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/events/log.py +0 -0
  54. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/events/modechanged.py +0 -0
  55. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/events/moduleclosed.py +0 -0
  56. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/events/moduleopened.py +0 -0
  57. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/events/motionstatuschanged.py +0 -0
  58. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/events/move.py +0 -0
  59. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/events/newimage.py +0 -0
  60. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/events/newspectrum.py +0 -0
  61. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/events/offsets.py +0 -0
  62. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/events/roofclosing.py +0 -0
  63. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/events/roofopened.py +0 -0
  64. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/events/taskfailed.py +0 -0
  65. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/events/taskfinished.py +0 -0
  66. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/events/taskstarted.py +0 -0
  67. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/events/testevent.py +0 -0
  68. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/__init__.py +0 -0
  69. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/image.py +0 -0
  70. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/meta/__init__.py +0 -0
  71. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/meta/altazoffsets.py +0 -0
  72. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/meta/exptime.py +0 -0
  73. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/meta/genericoffset.py +0 -0
  74. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/meta/onskydistance.py +0 -0
  75. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/meta/pixeloffsets.py +0 -0
  76. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/meta/radecoffsets.py +0 -0
  77. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/meta/skyoffsets.py +0 -0
  78. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processor.py +0 -0
  79. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/__init__.py +0 -0
  80. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/_daobackgroundremover.py +0 -0
  81. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/annotation/__init__.py +0 -0
  82. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/annotation/_pillow.py +0 -0
  83. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/annotation/circle.py +0 -0
  84. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/annotation/crosshair.py +0 -0
  85. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/annotation/text.py +0 -0
  86. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/astrometry/__init__.py +0 -0
  87. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/astrometry/_dotnet_request.py +0 -0
  88. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/astrometry/_dotnet_request_builder.py +0 -0
  89. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/astrometry/_dotnet_request_logger.py +0 -0
  90. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/astrometry/_dotnet_response_saver.py +0 -0
  91. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/astrometry/astrometry.py +0 -0
  92. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/astrometry/dotnet.py +0 -0
  93. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/calibration/__init__.py +0 -0
  94. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/calibration/_calibration_cache.py +0 -0
  95. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/calibration/_ccddata_calibrator.py +0 -0
  96. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/calibration/calibration.py +0 -0
  97. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/detection/__init__.py +0 -0
  98. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/detection/_pysep_stats_calculator.py +0 -0
  99. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/detection/_source_catalog.py +0 -0
  100. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/detection/daophot.py +0 -0
  101. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/detection/pysep.py +0 -0
  102. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/detection/simpledisk.py +0 -0
  103. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/detection/sourcedetection.py +0 -0
  104. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/exptime/__init__.py +0 -0
  105. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/exptime/exptime.py +0 -0
  106. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/exptime/star.py +0 -0
  107. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/image/__init__.py +0 -0
  108. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/image/addfitsheaders.py +0 -0
  109. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/image/download.py +0 -0
  110. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/image/flip.py +0 -0
  111. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/image/grayscale.py +0 -0
  112. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/image/httpserver.py +0 -0
  113. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/image/normalize.py +0 -0
  114. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/image/save.py +0 -0
  115. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/image/saveimage.py +0 -0
  116. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/image/smooth.py +0 -0
  117. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/image/softbin.py +0 -0
  118. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/misc/__init__.py +0 -0
  119. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/misc/addmask.py +0 -0
  120. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/misc/catalogcircularmask.py +0 -0
  121. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/misc/circularmask.py +0 -0
  122. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/misc/createfilename.py +0 -0
  123. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/misc/imagesourcefilter.py +0 -0
  124. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/misc/removebackground.py +0 -0
  125. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/modules/__init__.py +0 -0
  126. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/modules/getfitsheaders.py +0 -0
  127. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/offsets/__init__.py +0 -0
  128. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/offsets/astrometry.py +0 -0
  129. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/offsets/brighteststar.py +0 -0
  130. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/offsets/brighteststar_guiding.py +0 -0
  131. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/offsets/dummyoffsets.py +0 -0
  132. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/offsets/dummyskyoffsets.py +0 -0
  133. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/offsets/fitsheader.py +0 -0
  134. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/offsets/offsets.py +0 -0
  135. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/offsets/pixeloffsets.py +0 -0
  136. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/offsets/projected.py +0 -0
  137. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/offsets/spilled_light.py +0 -0
  138. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/photometry/__init__.py +0 -0
  139. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/photometry/_photometry_calculator.py +0 -0
  140. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/photometry/_photutil_aperture_photometry.py +0 -0
  141. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/photometry/_sep_aperture_photometry.py +0 -0
  142. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/photometry/aperture_photometry.py +0 -0
  143. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/photometry/photometry.py +0 -0
  144. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/photometry/photutil.py +0 -0
  145. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/photometry/pysep.py +0 -0
  146. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/wcs/__init__.py +0 -0
  147. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/images/processors/wcs/solarhelioprojective.py +0 -0
  148. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IAbortable.py +0 -0
  149. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IAcquisition.py +0 -0
  150. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IAutoFocus.py +0 -0
  151. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IAutoGuiding.py +0 -0
  152. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IAutonomous.py +0 -0
  153. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IBinning.py +0 -0
  154. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/ICalibrate.py +0 -0
  155. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/ICamera.py +0 -0
  156. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IConfig.py +0 -0
  157. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/ICooling.py +0 -0
  158. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IData.py +0 -0
  159. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IDataSequence.py +0 -0
  160. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IDome.py +0 -0
  161. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IExposure.py +0 -0
  162. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IExposureTime.py +0 -0
  163. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IFilters.py +0 -0
  164. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IFitsHeaderAfter.py +0 -0
  165. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IFitsHeaderBefore.py +0 -0
  166. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IFlatField.py +0 -0
  167. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IFocusModel.py +0 -0
  168. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IFocuser.py +0 -0
  169. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IGain.py +0 -0
  170. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IImageFormat.py +0 -0
  171. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IImageType.py +0 -0
  172. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IMode.py +0 -0
  173. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IModule.py +0 -0
  174. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IMotion.py +0 -0
  175. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IMultiFiber.py +0 -0
  176. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IOffsetsAltAz.py +0 -0
  177. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IOffsetsRaDec.py +0 -0
  178. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IPointingAltAz.py +0 -0
  179. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IPointingBody.py +0 -0
  180. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IPointingHeliocentricPolar.py +0 -0
  181. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IPointingHeliographicStonyhurst.py +0 -0
  182. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IPointingHelioprojective.py +0 -0
  183. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IPointingOrbitalElements.py +0 -0
  184. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IPointingRaDec.py +0 -0
  185. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IPointingSeries.py +0 -0
  186. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IReady.py +0 -0
  187. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IRoof.py +0 -0
  188. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IRotation.py +0 -0
  189. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IRunnable.py +0 -0
  190. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IRunning.py +0 -0
  191. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IScriptRunner.py +0 -0
  192. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/ISpectrograph.py +0 -0
  193. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IStartStop.py +0 -0
  194. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IStructuredConfig.py +0 -0
  195. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/ISyncTarget.py +0 -0
  196. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/ITelescope.py +0 -0
  197. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/ITemperatures.py +0 -0
  198. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/ITrackingMode.py +0 -0
  199. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/ITrackingRate.py +0 -0
  200. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IVideo.py +0 -0
  201. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IWeather.py +0 -0
  202. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/IWindow.py +0 -0
  203. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/__init__.py +0 -0
  204. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/interfaces/interface.py +0 -0
  205. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/mixins/__init__.py +0 -0
  206. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/mixins/camerasettings.py +0 -0
  207. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/mixins/fitsheader.py +0 -0
  208. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/mixins/fitsnamespace.py +0 -0
  209. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/mixins/follow.py +0 -0
  210. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/mixins/motionstatus.py +0 -0
  211. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/mixins/pipeline.py +0 -0
  212. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/mixins/waitformotion.py +0 -0
  213. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/mixins/weatheraware.py +0 -0
  214. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/__init__.py +0 -0
  215. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/camera/__init__.py +0 -0
  216. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/camera/adaptive.py +0 -0
  217. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/camera/basecamera.py +0 -0
  218. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/camera/basespectrograph.py +0 -0
  219. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/camera/basevideo.py +0 -0
  220. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/camera/dummycamera.py +0 -0
  221. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/camera/dummyspectrograph.py +0 -0
  222. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/camera/dummyvideo.py +0 -0
  223. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/camera/pipelinecamera.py +0 -0
  224. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/flatfield/__init__.py +0 -0
  225. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/flatfield/flatfield.py +0 -0
  226. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/flatfield/pointing.py +0 -0
  227. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/flatfield/scheduler.py +0 -0
  228. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/focus/__init__.py +0 -0
  229. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/focus/dummyautofocus.py +0 -0
  230. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/focus/focusmodel.py +0 -0
  231. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/focus/focusseries.py +0 -0
  232. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/image/__init__.py +0 -0
  233. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/image/imagewatcher.py +0 -0
  234. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/image/imagewriter.py +0 -0
  235. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/image/pipeline.py +0 -0
  236. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/image/seeing.py +0 -0
  237. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/module.py +0 -0
  238. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/pointing/__init__.py +0 -0
  239. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/pointing/_base.py +0 -0
  240. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/pointing/_baseguiding.py +0 -0
  241. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/pointing/acquisition.py +0 -0
  242. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/pointing/autoguiding.py +0 -0
  243. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/pointing/dummyacquisition.py +0 -0
  244. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/pointing/dummyguiding.py +0 -0
  245. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/pointing/guidingstatistics/__init__.py +0 -0
  246. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/pointing/guidingstatistics/guidingstatistics.py +0 -0
  247. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/pointing/guidingstatistics/pixeloffset.py +0 -0
  248. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/pointing/guidingstatistics/skyoffsets.py +0 -0
  249. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/pointing/guidingstatistics/uptime.py +0 -0
  250. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/pointing/scienceframeguiding.py +0 -0
  251. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/robotic/__init__.py +0 -0
  252. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/robotic/mastermind.py +0 -0
  253. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/robotic/pointing.py +0 -0
  254. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/robotic/scheduler.py +0 -0
  255. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/robotic/scriptrunner.py +0 -0
  256. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/roof/__init__.py +0 -0
  257. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/roof/basedome.py +0 -0
  258. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/roof/baseroof.py +0 -0
  259. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/roof/dummyroof.py +0 -0
  260. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/telescope/__init__.py +0 -0
  261. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/telescope/_dummytelescopebase.py +0 -0
  262. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/telescope/basetelescope.py +0 -0
  263. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/telescope/dummyaltaztelescope.py +0 -0
  264. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/telescope/dummyradectelescope.py +0 -0
  265. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/telescope/dummysolartelescope.py +0 -0
  266. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/test/__init__.py +0 -0
  267. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/test/standalone.py +0 -0
  268. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/utils/__init__.py +0 -0
  269. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/utils/dummymode.py +0 -0
  270. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/utils/fluentlogger.py +0 -0
  271. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/utils/httpfilecache.py +0 -0
  272. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/utils/kiosk.py +0 -0
  273. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/utils/matrix.py +0 -0
  274. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/utils/stellarium.py +0 -0
  275. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/utils/telegram.py +0 -0
  276. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/utils/trigger.py +0 -0
  277. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/weather/__init__.py +0 -0
  278. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/weather/mockweather.py +0 -0
  279. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/weather/weather.py +0 -0
  280. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/weather/weather_api.py +0 -0
  281. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/modules/weather/weather_state.py +0 -0
  282. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/object.py +0 -0
  283. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/py.typed +0 -0
  284. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/__init__.py +0 -0
  285. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/observation.py +0 -0
  286. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scheduler/__init__.py +0 -0
  287. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scheduler/astroplanscheduler.py +0 -0
  288. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scheduler/constraints/__init__.py +0 -0
  289. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scheduler/constraints/airmassconstraint.py +0 -0
  290. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scheduler/constraints/constraint.py +0 -0
  291. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scheduler/constraints/timeconstraint.py +0 -0
  292. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scheduler/merits/__init__.py +0 -0
  293. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scheduler/merits/aftertime.py +0 -0
  294. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scheduler/merits/beforetime.py +0 -0
  295. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scheduler/merits/constant.py +0 -0
  296. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scheduler/merits/follow.py +0 -0
  297. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scheduler/merits/interval.py +0 -0
  298. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scheduler/merits/merit.py +0 -0
  299. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scheduler/merits/pernight.py +0 -0
  300. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scheduler/merits/random.py +0 -0
  301. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scheduler/merits/timewindow.py +0 -0
  302. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scheduler/merits/transit.py +0 -0
  303. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scheduler/targets/__init__.py +0 -0
  304. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scheduler/targets/dynamictarget.py +0 -0
  305. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scheduler/targets/heliocentricpolartarget.py +0 -0
  306. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scheduler/targets/helioprojectivetarget.py +0 -0
  307. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scheduler/targets/picker/__init__.py +0 -0
  308. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scheduler/targets/picker/csvpicker.py +0 -0
  309. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scheduler/targets/picker/picker.py +0 -0
  310. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scheduler/targets/siderealtarget.py +0 -0
  311. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scheduler/targets/target.py +0 -0
  312. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scheduler/taskscheduler.py +0 -0
  313. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scripts/__init__.py +0 -0
  314. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scripts/calibration/__init__.py +0 -0
  315. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scripts/calibration/darkbias.py +0 -0
  316. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scripts/calibration/pointing.py +0 -0
  317. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scripts/calibration/skyflats.py +0 -0
  318. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scripts/control/__init__.py +0 -0
  319. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scripts/control/cases.py +0 -0
  320. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scripts/control/conditional.py +0 -0
  321. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scripts/control/parallel.py +0 -0
  322. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scripts/control/selector.py +0 -0
  323. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scripts/control/sequential.py +0 -0
  324. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scripts/exceptions.py +0 -0
  325. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scripts/imaging/__init__.py +0 -0
  326. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scripts/imaging/autofocus.py +0 -0
  327. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scripts/imaging/imaging.py +0 -0
  328. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scripts/imaging/transitimaging.py +0 -0
  329. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scripts/script.py +0 -0
  330. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scripts/utils/__init__.py +0 -0
  331. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scripts/utils/callmodule.py +0 -0
  332. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scripts/utils/debugtrigger.py +0 -0
  333. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/scripts/utils/log.py +0 -0
  334. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/storage/__init__.py +0 -0
  335. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/storage/backend/__init__.py +0 -0
  336. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/storage/backend/observationarchive.py +0 -0
  337. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/storage/backend/taskarchive.py +0 -0
  338. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/storage/filesystem/__init__.py +0 -0
  339. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/storage/filesystem/observationarchive.py +0 -0
  340. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/storage/filesystem/taskarchive.py +0 -0
  341. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/storage/lco/__init__.py +0 -0
  342. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/storage/lco/_portal.py +0 -0
  343. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/storage/lco/_schedulereader.py +0 -0
  344. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/storage/lco/_schedulewriter.py +0 -0
  345. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/storage/lco/configdb.py +0 -0
  346. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/storage/lco/mockobservationarchive.py +0 -0
  347. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/storage/lco/observationarchive.py +0 -0
  348. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/storage/lco/scripts/__init__.py +0 -0
  349. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/storage/lco/scripts/autofocus.py +0 -0
  350. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/storage/lco/scripts/default.py +0 -0
  351. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/storage/lco/scripts/script.py +0 -0
  352. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/storage/lco/task.py +0 -0
  353. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/storage/lco/taskarchive.py +0 -0
  354. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/storage/lco/taskrunner.py +0 -0
  355. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/storage/memory/__init__.py +0 -0
  356. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/storage/memory/observationarchive.py +0 -0
  357. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/storage/memory/taskarchive.py +0 -0
  358. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/storage/observationarchive.py +0 -0
  359. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/storage/taskarchive.py +0 -0
  360. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/task.py +0 -0
  361. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/taskrunner.py +0 -0
  362. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/utils/__init__.py +0 -0
  363. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/utils/archive/__init__.py +0 -0
  364. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/utils/archive/archive.py +0 -0
  365. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/utils/archive/pyobs_archive.py +0 -0
  366. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/utils/exptime/__init__.py +0 -0
  367. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/utils/exptime/exptime.py +0 -0
  368. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/utils/exptime/stellarexptime.py +0 -0
  369. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/utils/skyflats/__init__.py +0 -0
  370. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/utils/skyflats/exptimeeval.py +0 -0
  371. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/utils/skyflats/flatfielder.py +0 -0
  372. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/utils/skyflats/pointing/__init__.py +0 -0
  373. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/utils/skyflats/pointing/base.py +0 -0
  374. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/utils/skyflats/pointing/static.py +0 -0
  375. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/utils/skyflats/priorities/__init__.py +0 -0
  376. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/utils/skyflats/priorities/archive.py +0 -0
  377. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/utils/skyflats/priorities/base.py +0 -0
  378. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/utils/skyflats/priorities/const.py +0 -0
  379. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/robotic/utils/skyflats/scheduler.py +0 -0
  380. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/__init__.py +0 -0
  381. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/average.py +0 -0
  382. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/cache.py +0 -0
  383. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/config.py +0 -0
  384. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/config_schema.py +0 -0
  385. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/coordinates.py +0 -0
  386. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/curvefit.py +0 -0
  387. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/enums.py +0 -0
  388. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/exceptions.py +0 -0
  389. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/fits.py +0 -0
  390. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/focusseries/__init__.py +0 -0
  391. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/focusseries/base.py +0 -0
  392. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/focusseries/photometry.py +0 -0
  393. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/focusseries/projection.py +0 -0
  394. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/grids/__init__.py +0 -0
  395. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/grids/filters.py +0 -0
  396. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/grids/grid.py +0 -0
  397. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/grids/gridnode.py +0 -0
  398. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/grids/pipeline.py +0 -0
  399. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/gui/__init__.py +0 -0
  400. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/gui/camera/__init__.py +0 -0
  401. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/gui/camera/binningwidget.py +0 -0
  402. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/gui/camera/datadisplaywidget.py +0 -0
  403. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/gui/camera/exposewidget.py +0 -0
  404. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/gui/camera/exposuretimewidget.py +0 -0
  405. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/gui/camera/imageformatwidget.py +0 -0
  406. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/gui/camera/listpickerdialog.py +0 -0
  407. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/gui/camera/windowingwidget.py +0 -0
  408. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/http.py +0 -0
  409. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/influxdb.py +0 -0
  410. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/logger.py +0 -0
  411. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/logging/__init__.py +0 -0
  412. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/logging/context.py +0 -0
  413. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/logging/resolvableerror.py +0 -0
  414. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/modulegui.py +0 -0
  415. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/offsets/__init__.py +0 -0
  416. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/offsets/applyaltazoffsets.py +0 -0
  417. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/offsets/applyoffsets.py +0 -0
  418. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/offsets/applyradecoffsets.py +0 -0
  419. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/parallel.py +0 -0
  420. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/pipeline/pipeline.py +0 -0
  421. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/publisher/__init__.py +0 -0
  422. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/publisher/csv.py +0 -0
  423. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/publisher/http.py +0 -0
  424. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/publisher/log.py +0 -0
  425. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/publisher/multi.py +0 -0
  426. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/publisher/publisher.py +0 -0
  427. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/serialization.py +0 -0
  428. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/shellcommand.py +0 -0
  429. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/threads/__init__.py +0 -0
  430. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/threads/lockwithabort.py +0 -0
  431. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/time.py +0 -0
  432. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/utils/units.py +0 -0
  433. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/version.py +0 -0
  434. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/vfs/__init__.py +0 -0
  435. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/vfs/archivefile.py +0 -0
  436. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/vfs/bufferedfile.py +0 -0
  437. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/vfs/file.py +0 -0
  438. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/vfs/filelists/__init__.py +0 -0
  439. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/vfs/filelists/filelist.py +0 -0
  440. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/vfs/filelists/testing.py +0 -0
  441. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/vfs/httpfile.py +0 -0
  442. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/vfs/localfile.py +0 -0
  443. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/vfs/memfile.py +0 -0
  444. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/vfs/sftpfile.py +0 -0
  445. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/vfs/smbfile.py +0 -0
  446. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/vfs/sshfile.py +0 -0
  447. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/vfs/tempfile.py +0 -0
  448. {pyobs_core-2.0.0.dev66 → pyobs_core-2.0.0.dev68}/pyobs/vfs/vfs.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyobs-core
3
- Version: 2.0.0.dev66
3
+ Version: 2.0.0.dev68
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,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"]
@@ -9,6 +9,8 @@ from astroplan import Observer
9
9
  from ...utils.time import Time
10
10
 
11
11
  if TYPE_CHECKING:
12
+ from collections.abc import Iterable
13
+
12
14
  from pyobs.robotic import Observation, Task
13
15
  from pyobs.robotic.observation import ObservationList
14
16
  from pyobs.robotic.storage.observationarchive import ObservationArchive
@@ -20,6 +22,23 @@ class ObservationArchiveEvolution:
20
22
  self._obs_for_task: dict[Any, ObservationList] = {}
21
23
  self._obs_for_night: dict[datetime.date, ObservationList] = {}
22
24
  self._observer = observer
25
+ self._current_night: datetime.date | None = None
26
+ self._frozen = False
27
+
28
+ async def prefetch(self, tasks: Iterable[Task], start: Time, night: datetime.date) -> None:
29
+ """Populates the task cache and the one real night (anchored to `start`) up front. Call
30
+ once per schedule() run before any evaluation, then freeze(). Runs on the caller's
31
+ event loop (real I/O)."""
32
+ self._current_night = night
33
+ for task in tasks:
34
+ await self.observations_for_task(task)
35
+ await self.observations_for_night(night)
36
+
37
+ def freeze(self) -> None:
38
+ """Freezes observation cache. After this: a task-id miss raises RuntimeError; a night
39
+ miss seeds an empty list (future nights are provably empty of COMPLETED observations,
40
+ since `start` is pinned at least `_safety_time` ahead of real wall-clock time)."""
41
+ self._frozen = True
23
42
 
24
43
  async def evolve(self, scheduled_task: Observation, night: datetime.date) -> None:
25
44
  from pyobs.robotic.observation import Observation, ObservationState
@@ -50,6 +69,11 @@ class ObservationArchiveEvolution:
50
69
  from pyobs.robotic.observation import ObservationList, ObservationState
51
70
 
52
71
  if task.id not in self._obs_for_task:
72
+ if self._frozen:
73
+ raise RuntimeError(
74
+ f"Task {task.id} not in observation cache after freeze(). "
75
+ f"This is a bug -- all task IDs must be prefetched before freeze().",
76
+ )
53
77
  if self._obs_archive is not None:
54
78
  self._obs_for_task[task.id] = await self._obs_archive.get_observations(
55
79
  task=task, state=ObservationState.COMPLETED
@@ -70,7 +94,14 @@ class ObservationArchiveEvolution:
70
94
  from pyobs.robotic.observation import ObservationList, ObservationState
71
95
 
72
96
  if date not in self._obs_for_night:
73
- if self._obs_archive is not None:
97
+ if self._frozen:
98
+ # `start` is pinned at least `_safety_time` ahead of real wall-clock time, so any
99
+ # night after the prefetched one cannot possibly have COMPLETED observations yet.
100
+ assert (
101
+ self._current_night is not None and date > self._current_night
102
+ ), f"Night {date} not prefetched and not strictly after current night {self._current_night}."
103
+ self._obs_for_night[date] = ObservationList()
104
+ elif self._obs_archive is not None:
74
105
  start = Time(datetime.datetime.combine(date, datetime.time(0, 0, 0)))
75
106
  end = Time(datetime.datetime.combine(date, datetime.time(23, 59, 59)))
76
107
  self._obs_for_night[date] = await self._obs_archive.get_observations(
@@ -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
@@ -67,6 +68,12 @@ class OnDemandScheduler(TaskScheduler):
67
68
  data = DataProvider(self._observer, archive)
68
69
  projects_dict = {project.code: project for project in projects}
69
70
 
71
+ # prefetch historical observations on the main loop (the only place aiohttp session works),
72
+ # then freeze to prevent any lazy archive fetches from the worker thread
73
+ night = data.night(start)
74
+ await data.archive.prefetch(tasks, start, night)
75
+ data.archive.freeze()
76
+
70
77
  # schedule from start to end
71
78
  async for task in self.schedule_in_interval(tasks, projects_dict, start, end, data):
72
79
  # evolve archive -- night is keyed by the task's own scheduled time, not "now", since
@@ -252,7 +259,7 @@ class OnDemandScheduler(TaskScheduler):
252
259
  ) -> tuple[Task | None, float]:
253
260
 
254
261
  # evaluate all merit functions at given time
255
- merits = await self.evaluate_constraints_and_merits(tasks, projects, start, end, data)
262
+ merits = await run_cpu_bound(self.evaluate_constraints_and_merits, tasks, projects, start, end, data)
256
263
 
257
264
  # find max one
258
265
  idx = np.argmax(merits)
@@ -276,7 +283,7 @@ class OnDemandScheduler(TaskScheduler):
276
283
  other_tasks = [t for t in tasks if t is not task]
277
284
  t = start + TimeDelta(step * u.second)
278
285
  while t < start + TimeDelta(task.estimate_duration(time=start) * u.second):
279
- merits = await self.evaluate_constraints_and_merits(other_tasks, projects, t, end, data)
286
+ merits = await run_cpu_bound(self.evaluate_constraints_and_merits, other_tasks, projects, t, end, data)
280
287
  for i, m in enumerate(merits):
281
288
  if m > merit:
282
289
  return other_tasks[i], t, m
@@ -297,7 +304,9 @@ class OnDemandScheduler(TaskScheduler):
297
304
  better_start: Time = start + TimeDelta(task.estimate_duration(time=start) * u.second)
298
305
 
299
306
  # evaluate merit of better_task at new start time
300
- merit = (await self.evaluate_constraints_and_merits([better_task], projects, better_start, end, data))[0]
307
+ merit = (
308
+ await run_cpu_bound(self.evaluate_constraints_and_merits, [better_task], projects, better_start, end, data)
309
+ )[0]
301
310
 
302
311
  # if it got better, return it, otherwise return Nones
303
312
  if merit >= better_merit:
@@ -166,7 +166,13 @@ class LocalArchive(Archive):
166
166
  return headers
167
167
 
168
168
  async def upload_frames(self, images: list[Image]) -> None:
169
- pass
169
+ self._root_path.mkdir(parents=True, exist_ok=True)
170
+ for image in images:
171
+ filename = image.header.get("FNAME")
172
+ if not filename:
173
+ raise ValueError("Image has no FNAME header set, cannot determine output filename.")
174
+ image.writeto(str(self._root_path / filename), overwrite=True)
175
+ self._update_root() # refresh the in-memory index so newly-written frames are queryable
170
176
 
171
177
 
172
178
  __all__ = ["LocalArchive"]
@@ -0,0 +1,4 @@
1
+ from .pipeline import Pipeline
2
+ from .reduction import Reduction
3
+
4
+ __all__ = ["Reduction", "Pipeline"]
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import logging
4
+ import os
4
5
  import os.path
5
6
  from typing import Any
6
7
 
@@ -19,28 +20,27 @@ log = logging.getLogger(__name__)
19
20
  FILENAME = "{SITEID}{TELID}-{INSTRUME}-{DAY-OBS|date:}-{IMAGETYP}-{XBINNING}x{YBINNING}{FILTER|filter}.fits"
20
21
 
21
22
 
22
- class Night:
23
+ class Reduction:
23
24
  def __init__(
24
25
  self,
25
26
  archive: dict[str, Any] | Archive,
26
27
  pipeline: dict[str, Any] | Pipeline,
27
- worker_procs: int = 4,
28
28
  filenames_calib: str = FILENAME,
29
29
  min_flats: int = 10,
30
- store_local: str | None = None,
30
+ output: str | dict[str, Any] | Archive | None = None,
31
31
  create_calibs: bool = True,
32
32
  calib_science: bool = True,
33
- **kwargs: Any,
34
33
  ):
35
- """Creates a Night object for reducing a given night.
34
+ """Creates a Reduction object for reducing a given observation period.
36
35
 
37
36
  Args:
38
- archive: Archive to fetch images from and write results to.
37
+ archive: Archive to fetch raw and calibration frames from. Also the output
38
+ destination, unless output is set.
39
39
  pipeline: Science pipeline.
40
- worker_procs: Number of worker processes.
41
40
  filenames_calib: Filename pattern for master calibration files.
42
41
  min_flats: Minimum number of raw frames to create flat field.
43
- store_local: If True, files are stored in given local directory instead of uploaded to archive.
42
+ output: Where to write results. A string is a local directory path; a dict or
43
+ Archive is an output archive. If not set, results are written back to archive.
44
44
  create_calibs: If False, no calibration files are created for night.
45
45
  calib_science: If False, no science frames are calibrated.
46
46
  """
@@ -50,12 +50,18 @@ class Night:
50
50
  self._pipeline = get_object(pipeline, Pipeline, archive=archive)
51
51
 
52
52
  # stuff
53
- self._worker_processes = worker_procs
54
53
  self._min_flats = min_flats
55
- self._store_local = store_local
54
+ self._store_local: str | None = output if isinstance(output, str) else None
55
+ self._output_archive = (
56
+ self._archive if output is None or isinstance(output, str) else get_object(output, Archive)
57
+ )
56
58
  self._create_calibs = create_calibs
57
59
  self._calib_science = calib_science
58
60
 
61
+ # make sure the local output directory exists
62
+ if self._store_local:
63
+ os.makedirs(self._store_local, exist_ok=True)
64
+
59
65
  # cache for master calibration frames
60
66
  self._master_frames: dict[tuple[ImageType, str, str, str | None], Image] = {}
61
67
 
@@ -128,6 +134,7 @@ class Night:
128
134
  images = await self._archive.download_frames(infos)
129
135
  if len(images) < 3:
130
136
  log.warning("Too few (%d) frames found, skipping...", len(infos))
137
+ return None
131
138
 
132
139
  # create master
133
140
  calib: Image | None = None
@@ -191,7 +198,7 @@ class Night:
191
198
  calib.writeto(path, overwrite=True)
192
199
  else:
193
200
  log.info("Uploading master calibration frame as %s...", calib.header["FNAME"])
194
- await self._archive.upload_frames([calib])
201
+ await self._output_archive.upload_frames([calib])
195
202
 
196
203
  # finished
197
204
  return calib
@@ -230,7 +237,7 @@ class Night:
230
237
  calibrated.writeto(path, overwrite=True)
231
238
  else:
232
239
  log.info("(%d/%d) Uploading calibrated images as %s...", i, total, calibrated.header["FNAME"])
233
- await self._archive.upload_frames([calibrated])
240
+ await self._output_archive.upload_frames([calibrated])
234
241
 
235
242
  except Exception:
236
243
  log.exception("(%d/%d) Error processing image %s.", i, total, info.filename)
@@ -256,18 +263,32 @@ class Night:
256
263
  for binning in options["binnings"]:
257
264
  # create bias and dark
258
265
  if self._create_calibs:
259
- await self._create_master_calib(night, instrument, ImageType.BIAS, binning)
260
- await self._create_master_calib(night, instrument, ImageType.DARK, binning)
266
+ try:
267
+ await self._create_master_calib(night, instrument, ImageType.BIAS, binning)
268
+ except Exception:
269
+ log.exception("Error creating master bias for instrument %s, binning %s.", instrument, binning)
270
+ try:
271
+ await self._create_master_calib(night, instrument, ImageType.DARK, binning)
272
+ except Exception:
273
+ log.exception("Error creating master dark for instrument %s, binning %s.", instrument, binning)
261
274
 
262
275
  # loop filters
263
276
  for filter_name in options["filters"]:
264
277
  # create flat
265
278
  if self._create_calibs:
266
- await self._create_master_calib(night, instrument, ImageType.SKYFLAT, binning, filter_name)
279
+ try:
280
+ await self._create_master_calib(night, instrument, ImageType.SKYFLAT, binning, filter_name)
281
+ except Exception:
282
+ log.exception(
283
+ "Error creating master flat for instrument %s, binning %s, filter %s.",
284
+ instrument,
285
+ binning,
286
+ filter_name,
287
+ )
267
288
 
268
289
  # calibrate science data
269
290
  if self._calib_science:
270
291
  await self._calib_data(night, instrument, binning, filter_name)
271
292
 
272
293
 
273
- __all__ = ["Night"]
294
+ __all__ = ["Reduction"]
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pyobs-core"
3
- version = "2.0.0.dev66"
3
+ version = "2.0.0.dev68"
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,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"]
@@ -1,4 +0,0 @@
1
- from .night import Night
2
- from .pipeline import Pipeline
3
-
4
- __all__ = ["Night", "Pipeline"]