pyobs-core 2.0.0.dev67__tar.gz → 2.0.0.dev70__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 (449) hide show
  1. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/.gitignore +6 -0
  2. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/PKG-INFO +1 -1
  3. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/calibration/_ccddata_calibrator.py +5 -0
  4. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/photometry/aperture_photometry.py +4 -1
  5. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/mixins/pipeline.py +27 -3
  6. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/utils/archive/local_archive.py +7 -1
  7. pyobs_core-2.0.0.dev70/pyobs/utils/pipeline/__init__.py +14 -0
  8. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/pipeline/pipeline.py +10 -2
  9. pyobs_core-2.0.0.dev70/pyobs/utils/pipeline/progress.py +40 -0
  10. pyobs_core-2.0.0.dev67/pyobs/utils/pipeline/night.py → pyobs_core-2.0.0.dev70/pyobs/utils/pipeline/reduction.py +101 -74
  11. pyobs_core-2.0.0.dev70/pyobs/utils/pipeline/reduction_base.py +104 -0
  12. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyproject.toml +1 -1
  13. pyobs_core-2.0.0.dev67/pyobs/utils/pipeline/__init__.py +0 -4
  14. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/LICENSE +0 -0
  15. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/__init__.py +0 -0
  16. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/application.py +0 -0
  17. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/background_task.py +0 -0
  18. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/cli/__init__.py +0 -0
  19. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/cli/_cli.py +0 -0
  20. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/cli/pyobs.py +0 -0
  21. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/cli/pyobsd.py +0 -0
  22. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/cli/pyobsw.py +0 -0
  23. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/comm/__init__.py +0 -0
  24. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/comm/comm.py +0 -0
  25. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/comm/commlogging.py +0 -0
  26. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/comm/dummy/__init__.py +0 -0
  27. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/comm/dummy/dummycomm.py +0 -0
  28. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/comm/local/__init__.py +0 -0
  29. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/comm/local/localcomm.py +0 -0
  30. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/comm/local/localnetwork.py +0 -0
  31. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/comm/proxy.py +0 -0
  32. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/comm/xmpp/__init__.py +0 -0
  33. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/comm/xmpp/rpc.py +0 -0
  34. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/comm/xmpp/serializer.py +0 -0
  35. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/comm/xmpp/xep_0009/__init__.py +0 -0
  36. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/comm/xmpp/xep_0009/binding.py +0 -0
  37. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/comm/xmpp/xep_0009/rpc.py +0 -0
  38. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/comm/xmpp/xep_0009_timeout/__init__.py +0 -0
  39. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/comm/xmpp/xep_0009_timeout/rpc.py +0 -0
  40. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/comm/xmpp/xep_0009_timeout/stanza/RPC.py +0 -0
  41. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/comm/xmpp/xep_0009_timeout/stanza/__init__.py +0 -0
  42. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/comm/xmpp/xmppclient.py +0 -0
  43. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/comm/xmpp/xmppcomm.py +0 -0
  44. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/events/__init__.py +0 -0
  45. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/events/badweather.py +0 -0
  46. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/events/event.py +0 -0
  47. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/events/exposurestatuschanged.py +0 -0
  48. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/events/filterchanged.py +0 -0
  49. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/events/focusfound.py +0 -0
  50. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/events/goodweather.py +0 -0
  51. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/events/log.py +0 -0
  52. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/events/modechanged.py +0 -0
  53. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/events/moduleclosed.py +0 -0
  54. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/events/moduleopened.py +0 -0
  55. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/events/motionstatuschanged.py +0 -0
  56. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/events/move.py +0 -0
  57. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/events/newimage.py +0 -0
  58. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/events/newspectrum.py +0 -0
  59. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/events/offsets.py +0 -0
  60. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/events/roofclosing.py +0 -0
  61. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/events/roofopened.py +0 -0
  62. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/events/taskfailed.py +0 -0
  63. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/events/taskfinished.py +0 -0
  64. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/events/taskstarted.py +0 -0
  65. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/events/testevent.py +0 -0
  66. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/__init__.py +0 -0
  67. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/image.py +0 -0
  68. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/meta/__init__.py +0 -0
  69. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/meta/altazoffsets.py +0 -0
  70. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/meta/exptime.py +0 -0
  71. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/meta/genericoffset.py +0 -0
  72. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/meta/onskydistance.py +0 -0
  73. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/meta/pixeloffsets.py +0 -0
  74. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/meta/radecoffsets.py +0 -0
  75. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/meta/skyoffsets.py +0 -0
  76. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processor.py +0 -0
  77. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/__init__.py +0 -0
  78. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/_daobackgroundremover.py +0 -0
  79. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/annotation/__init__.py +0 -0
  80. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/annotation/_pillow.py +0 -0
  81. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/annotation/circle.py +0 -0
  82. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/annotation/crosshair.py +0 -0
  83. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/annotation/text.py +0 -0
  84. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/astrometry/__init__.py +0 -0
  85. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/astrometry/_dotnet_request.py +0 -0
  86. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/astrometry/_dotnet_request_builder.py +0 -0
  87. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/astrometry/_dotnet_request_logger.py +0 -0
  88. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/astrometry/_dotnet_response_saver.py +0 -0
  89. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/astrometry/astrometry.py +0 -0
  90. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/astrometry/dotnet.py +0 -0
  91. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/calibration/__init__.py +0 -0
  92. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/calibration/_calibration_cache.py +0 -0
  93. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/calibration/calibration.py +0 -0
  94. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/detection/__init__.py +0 -0
  95. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/detection/_pysep_stats_calculator.py +0 -0
  96. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/detection/_source_catalog.py +0 -0
  97. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/detection/daophot.py +0 -0
  98. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/detection/pysep.py +0 -0
  99. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/detection/simpledisk.py +0 -0
  100. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/detection/sourcedetection.py +0 -0
  101. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/exptime/__init__.py +0 -0
  102. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/exptime/exptime.py +0 -0
  103. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/exptime/star.py +0 -0
  104. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/image/__init__.py +0 -0
  105. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/image/addfitsheaders.py +0 -0
  106. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/image/download.py +0 -0
  107. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/image/flip.py +0 -0
  108. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/image/grayscale.py +0 -0
  109. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/image/httpserver.py +0 -0
  110. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/image/normalize.py +0 -0
  111. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/image/save.py +0 -0
  112. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/image/saveimage.py +0 -0
  113. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/image/smooth.py +0 -0
  114. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/image/softbin.py +0 -0
  115. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/misc/__init__.py +0 -0
  116. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/misc/addmask.py +0 -0
  117. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/misc/catalogcircularmask.py +0 -0
  118. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/misc/circularmask.py +0 -0
  119. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/misc/createfilename.py +0 -0
  120. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/misc/imagesourcefilter.py +0 -0
  121. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/misc/removebackground.py +0 -0
  122. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/modules/__init__.py +0 -0
  123. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/modules/getfitsheaders.py +0 -0
  124. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/offsets/__init__.py +0 -0
  125. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/offsets/astrometry.py +0 -0
  126. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/offsets/brighteststar.py +0 -0
  127. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/offsets/brighteststar_guiding.py +0 -0
  128. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/offsets/dummyoffsets.py +0 -0
  129. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/offsets/dummyskyoffsets.py +0 -0
  130. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/offsets/fitsheader.py +0 -0
  131. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/offsets/offsets.py +0 -0
  132. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/offsets/pixeloffsets.py +0 -0
  133. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/offsets/projected.py +0 -0
  134. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/offsets/spilled_light.py +0 -0
  135. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/photometry/__init__.py +0 -0
  136. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/photometry/_photometry_calculator.py +0 -0
  137. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/photometry/_photutil_aperture_photometry.py +0 -0
  138. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/photometry/_sep_aperture_photometry.py +0 -0
  139. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/photometry/photometry.py +0 -0
  140. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/photometry/photutil.py +0 -0
  141. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/photometry/pysep.py +0 -0
  142. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/wcs/__init__.py +0 -0
  143. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/images/processors/wcs/solarhelioprojective.py +0 -0
  144. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IAbortable.py +0 -0
  145. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IAcquisition.py +0 -0
  146. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IAutoFocus.py +0 -0
  147. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IAutoGuiding.py +0 -0
  148. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IAutonomous.py +0 -0
  149. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IBinning.py +0 -0
  150. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/ICalibrate.py +0 -0
  151. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/ICamera.py +0 -0
  152. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IConfig.py +0 -0
  153. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/ICooling.py +0 -0
  154. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IData.py +0 -0
  155. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IDataSequence.py +0 -0
  156. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IDome.py +0 -0
  157. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IExposure.py +0 -0
  158. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IExposureTime.py +0 -0
  159. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IFilters.py +0 -0
  160. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IFitsHeaderAfter.py +0 -0
  161. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IFitsHeaderBefore.py +0 -0
  162. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IFlatField.py +0 -0
  163. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IFocusModel.py +0 -0
  164. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IFocuser.py +0 -0
  165. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IGain.py +0 -0
  166. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IImageFormat.py +0 -0
  167. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IImageType.py +0 -0
  168. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IMode.py +0 -0
  169. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IModule.py +0 -0
  170. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IMotion.py +0 -0
  171. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IMultiFiber.py +0 -0
  172. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IOffsetsAltAz.py +0 -0
  173. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IOffsetsRaDec.py +0 -0
  174. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IPointingAltAz.py +0 -0
  175. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IPointingBody.py +0 -0
  176. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IPointingHeliocentricPolar.py +0 -0
  177. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IPointingHeliographicStonyhurst.py +0 -0
  178. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IPointingHelioprojective.py +0 -0
  179. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IPointingOrbitalElements.py +0 -0
  180. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IPointingRaDec.py +0 -0
  181. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IPointingSeries.py +0 -0
  182. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IReady.py +0 -0
  183. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IRoof.py +0 -0
  184. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IRotation.py +0 -0
  185. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IRunnable.py +0 -0
  186. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IRunning.py +0 -0
  187. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IScriptRunner.py +0 -0
  188. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/ISpectrograph.py +0 -0
  189. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IStartStop.py +0 -0
  190. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IStructuredConfig.py +0 -0
  191. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/ISyncTarget.py +0 -0
  192. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/ITelescope.py +0 -0
  193. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/ITemperatures.py +0 -0
  194. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/ITrackingMode.py +0 -0
  195. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/ITrackingRate.py +0 -0
  196. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IVideo.py +0 -0
  197. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IWeather.py +0 -0
  198. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/IWindow.py +0 -0
  199. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/__init__.py +0 -0
  200. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/interfaces/interface.py +0 -0
  201. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/mixins/__init__.py +0 -0
  202. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/mixins/camerasettings.py +0 -0
  203. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/mixins/fitsheader.py +0 -0
  204. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/mixins/fitsnamespace.py +0 -0
  205. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/mixins/follow.py +0 -0
  206. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/mixins/motionstatus.py +0 -0
  207. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/mixins/waitformotion.py +0 -0
  208. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/mixins/weatheraware.py +0 -0
  209. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/__init__.py +0 -0
  210. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/camera/__init__.py +0 -0
  211. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/camera/adaptive.py +0 -0
  212. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/camera/basecamera.py +0 -0
  213. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/camera/basespectrograph.py +0 -0
  214. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/camera/basevideo.py +0 -0
  215. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/camera/dummycamera.py +0 -0
  216. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/camera/dummyspectrograph.py +0 -0
  217. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/camera/dummyvideo.py +0 -0
  218. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/camera/pipelinecamera.py +0 -0
  219. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/flatfield/__init__.py +0 -0
  220. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/flatfield/flatfield.py +0 -0
  221. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/flatfield/pointing.py +0 -0
  222. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/flatfield/scheduler.py +0 -0
  223. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/focus/__init__.py +0 -0
  224. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/focus/dummyautofocus.py +0 -0
  225. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/focus/focusmodel.py +0 -0
  226. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/focus/focusseries.py +0 -0
  227. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/image/__init__.py +0 -0
  228. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/image/imagewatcher.py +0 -0
  229. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/image/imagewriter.py +0 -0
  230. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/image/pipeline.py +0 -0
  231. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/image/seeing.py +0 -0
  232. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/module.py +0 -0
  233. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/pointing/__init__.py +0 -0
  234. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/pointing/_base.py +0 -0
  235. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/pointing/_baseguiding.py +0 -0
  236. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/pointing/acquisition.py +0 -0
  237. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/pointing/autoguiding.py +0 -0
  238. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/pointing/dummyacquisition.py +0 -0
  239. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/pointing/dummyguiding.py +0 -0
  240. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/pointing/guidingstatistics/__init__.py +0 -0
  241. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/pointing/guidingstatistics/guidingstatistics.py +0 -0
  242. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/pointing/guidingstatistics/pixeloffset.py +0 -0
  243. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/pointing/guidingstatistics/skyoffsets.py +0 -0
  244. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/pointing/guidingstatistics/uptime.py +0 -0
  245. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/pointing/scienceframeguiding.py +0 -0
  246. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/robotic/__init__.py +0 -0
  247. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/robotic/mastermind.py +0 -0
  248. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/robotic/pointing.py +0 -0
  249. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/robotic/scheduler.py +0 -0
  250. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/robotic/scriptrunner.py +0 -0
  251. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/roof/__init__.py +0 -0
  252. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/roof/basedome.py +0 -0
  253. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/roof/baseroof.py +0 -0
  254. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/roof/dummyroof.py +0 -0
  255. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/telescope/__init__.py +0 -0
  256. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/telescope/_dummytelescopebase.py +0 -0
  257. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/telescope/basetelescope.py +0 -0
  258. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/telescope/dummyaltaztelescope.py +0 -0
  259. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/telescope/dummyradectelescope.py +0 -0
  260. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/telescope/dummysolartelescope.py +0 -0
  261. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/test/__init__.py +0 -0
  262. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/test/standalone.py +0 -0
  263. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/utils/__init__.py +0 -0
  264. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/utils/dummymode.py +0 -0
  265. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/utils/fluentlogger.py +0 -0
  266. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/utils/httpfilecache.py +0 -0
  267. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/utils/kiosk.py +0 -0
  268. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/utils/matrix.py +0 -0
  269. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/utils/stellarium.py +0 -0
  270. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/utils/telegram.py +0 -0
  271. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/utils/trigger.py +0 -0
  272. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/weather/__init__.py +0 -0
  273. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/weather/mockweather.py +0 -0
  274. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/weather/weather.py +0 -0
  275. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/weather/weather_api.py +0 -0
  276. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/modules/weather/weather_state.py +0 -0
  277. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/object.py +0 -0
  278. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/py.typed +0 -0
  279. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/__init__.py +0 -0
  280. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/observation.py +0 -0
  281. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/__init__.py +0 -0
  282. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/_executor.py +0 -0
  283. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/astroplanscheduler.py +0 -0
  284. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/constraints/__init__.py +0 -0
  285. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/constraints/airmassconstraint.py +0 -0
  286. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/constraints/constraint.py +0 -0
  287. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/constraints/moonilluminationconstraint.py +0 -0
  288. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/constraints/moonseparationconstraint.py +0 -0
  289. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/constraints/solarelevationconstraint.py +0 -0
  290. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/constraints/timeconstraint.py +0 -0
  291. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/dataprovider.py +0 -0
  292. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/merits/__init__.py +0 -0
  293. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/merits/aftertime.py +0 -0
  294. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/merits/beforetime.py +0 -0
  295. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/merits/constant.py +0 -0
  296. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/merits/follow.py +0 -0
  297. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/merits/interval.py +0 -0
  298. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/merits/merit.py +0 -0
  299. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/merits/pernight.py +0 -0
  300. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/merits/random.py +0 -0
  301. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/merits/timewindow.py +0 -0
  302. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/merits/transit.py +0 -0
  303. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/observationarchiveevolution.py +0 -0
  304. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/ondemandscheduler.py +0 -0
  305. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/targets/__init__.py +0 -0
  306. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/targets/dynamictarget.py +0 -0
  307. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/targets/heliocentricpolartarget.py +0 -0
  308. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/targets/helioprojectivetarget.py +0 -0
  309. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/targets/picker/__init__.py +0 -0
  310. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/targets/picker/csvpicker.py +0 -0
  311. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/targets/picker/picker.py +0 -0
  312. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/targets/siderealtarget.py +0 -0
  313. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/targets/target.py +0 -0
  314. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scheduler/taskscheduler.py +0 -0
  315. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scripts/__init__.py +0 -0
  316. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scripts/calibration/__init__.py +0 -0
  317. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scripts/calibration/darkbias.py +0 -0
  318. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scripts/calibration/pointing.py +0 -0
  319. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scripts/calibration/skyflats.py +0 -0
  320. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scripts/control/__init__.py +0 -0
  321. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scripts/control/cases.py +0 -0
  322. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scripts/control/conditional.py +0 -0
  323. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scripts/control/parallel.py +0 -0
  324. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scripts/control/selector.py +0 -0
  325. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scripts/control/sequential.py +0 -0
  326. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scripts/exceptions.py +0 -0
  327. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scripts/imaging/__init__.py +0 -0
  328. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scripts/imaging/autofocus.py +0 -0
  329. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scripts/imaging/imaging.py +0 -0
  330. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scripts/imaging/transitimaging.py +0 -0
  331. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scripts/script.py +0 -0
  332. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scripts/utils/__init__.py +0 -0
  333. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scripts/utils/callmodule.py +0 -0
  334. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scripts/utils/debugtrigger.py +0 -0
  335. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/scripts/utils/log.py +0 -0
  336. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/storage/__init__.py +0 -0
  337. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/storage/backend/__init__.py +0 -0
  338. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/storage/backend/observationarchive.py +0 -0
  339. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/storage/backend/taskarchive.py +0 -0
  340. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/storage/filesystem/__init__.py +0 -0
  341. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/storage/filesystem/observationarchive.py +0 -0
  342. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/storage/filesystem/taskarchive.py +0 -0
  343. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/storage/lco/__init__.py +0 -0
  344. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/storage/lco/_portal.py +0 -0
  345. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/storage/lco/_schedulereader.py +0 -0
  346. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/storage/lco/_schedulewriter.py +0 -0
  347. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/storage/lco/configdb.py +0 -0
  348. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/storage/lco/mockobservationarchive.py +0 -0
  349. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/storage/lco/observationarchive.py +0 -0
  350. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/storage/lco/scripts/__init__.py +0 -0
  351. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/storage/lco/scripts/autofocus.py +0 -0
  352. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/storage/lco/scripts/default.py +0 -0
  353. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/storage/lco/scripts/script.py +0 -0
  354. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/storage/lco/task.py +0 -0
  355. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/storage/lco/taskarchive.py +0 -0
  356. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/storage/lco/taskrunner.py +0 -0
  357. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/storage/memory/__init__.py +0 -0
  358. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/storage/memory/observationarchive.py +0 -0
  359. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/storage/memory/taskarchive.py +0 -0
  360. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/storage/observationarchive.py +0 -0
  361. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/storage/taskarchive.py +0 -0
  362. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/task.py +0 -0
  363. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/taskrunner.py +0 -0
  364. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/utils/__init__.py +0 -0
  365. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/utils/archive/__init__.py +0 -0
  366. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/utils/archive/archive.py +0 -0
  367. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/utils/archive/pyobs_archive.py +0 -0
  368. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/utils/exptime/__init__.py +0 -0
  369. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/utils/exptime/exptime.py +0 -0
  370. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/utils/exptime/stellarexptime.py +0 -0
  371. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/utils/skyflats/__init__.py +0 -0
  372. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/utils/skyflats/exptimeeval.py +0 -0
  373. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/utils/skyflats/flatfielder.py +0 -0
  374. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/utils/skyflats/pointing/__init__.py +0 -0
  375. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/utils/skyflats/pointing/base.py +0 -0
  376. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/utils/skyflats/pointing/static.py +0 -0
  377. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/utils/skyflats/priorities/__init__.py +0 -0
  378. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/utils/skyflats/priorities/archive.py +0 -0
  379. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/utils/skyflats/priorities/base.py +0 -0
  380. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/utils/skyflats/priorities/const.py +0 -0
  381. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/robotic/utils/skyflats/scheduler.py +0 -0
  382. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/__init__.py +0 -0
  383. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/average.py +0 -0
  384. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/cache.py +0 -0
  385. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/config.py +0 -0
  386. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/config_schema.py +0 -0
  387. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/coordinates.py +0 -0
  388. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/curvefit.py +0 -0
  389. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/enums.py +0 -0
  390. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/exceptions.py +0 -0
  391. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/fits.py +0 -0
  392. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/focusseries/__init__.py +0 -0
  393. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/focusseries/base.py +0 -0
  394. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/focusseries/photometry.py +0 -0
  395. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/focusseries/projection.py +0 -0
  396. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/grids/__init__.py +0 -0
  397. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/grids/filters.py +0 -0
  398. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/grids/grid.py +0 -0
  399. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/grids/gridnode.py +0 -0
  400. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/grids/pipeline.py +0 -0
  401. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/gui/__init__.py +0 -0
  402. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/gui/camera/__init__.py +0 -0
  403. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/gui/camera/binningwidget.py +0 -0
  404. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/gui/camera/datadisplaywidget.py +0 -0
  405. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/gui/camera/exposewidget.py +0 -0
  406. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/gui/camera/exposuretimewidget.py +0 -0
  407. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/gui/camera/imageformatwidget.py +0 -0
  408. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/gui/camera/listpickerdialog.py +0 -0
  409. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/gui/camera/windowingwidget.py +0 -0
  410. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/http.py +0 -0
  411. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/influxdb.py +0 -0
  412. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/logger.py +0 -0
  413. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/logging/__init__.py +0 -0
  414. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/logging/context.py +0 -0
  415. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/logging/resolvableerror.py +0 -0
  416. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/modulegui.py +0 -0
  417. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/offsets/__init__.py +0 -0
  418. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/offsets/applyaltazoffsets.py +0 -0
  419. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/offsets/applyoffsets.py +0 -0
  420. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/offsets/applyradecoffsets.py +0 -0
  421. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/parallel.py +0 -0
  422. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/publisher/__init__.py +0 -0
  423. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/publisher/csv.py +0 -0
  424. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/publisher/http.py +0 -0
  425. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/publisher/log.py +0 -0
  426. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/publisher/multi.py +0 -0
  427. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/publisher/publisher.py +0 -0
  428. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/serialization.py +0 -0
  429. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/shellcommand.py +0 -0
  430. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/threads/__init__.py +0 -0
  431. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/threads/lockwithabort.py +0 -0
  432. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/time.py +0 -0
  433. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/utils/units.py +0 -0
  434. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/version.py +0 -0
  435. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/vfs/__init__.py +0 -0
  436. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/vfs/archivefile.py +0 -0
  437. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/vfs/bufferedfile.py +0 -0
  438. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/vfs/file.py +0 -0
  439. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/vfs/filelists/__init__.py +0 -0
  440. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/vfs/filelists/filelist.py +0 -0
  441. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/vfs/filelists/testing.py +0 -0
  442. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/vfs/httpfile.py +0 -0
  443. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/vfs/localfile.py +0 -0
  444. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/vfs/memfile.py +0 -0
  445. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/vfs/sftpfile.py +0 -0
  446. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/vfs/smbfile.py +0 -0
  447. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/vfs/sshfile.py +0 -0
  448. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/vfs/tempfile.py +0 -0
  449. {pyobs_core-2.0.0.dev67 → pyobs_core-2.0.0.dev70}/pyobs/vfs/vfs.py +0 -0
@@ -160,3 +160,9 @@ cython_debug/
160
160
  # and can be added to the global gitignore or merged into this file. For a more nuclear
161
161
  # option (not recommended) you can uncomment the following to ignore the entire idea folder.
162
162
  .idea/
163
+
164
+ # graphify local build cache and machine-specific state (outputs are tracked)
165
+ graphify-out/cache/
166
+ graphify-out/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/
167
+ graphify-out/.graphify_python
168
+ graphify-out/.graphify_root
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyobs-core
3
- Version: 2.0.0.dev67
3
+ Version: 2.0.0.dev70
4
4
  Summary: robotic telescope software
5
5
  Author-email: Tim-Oliver Husser <thusser@uni-goettingen.de>
6
6
  License-Expression: MIT
@@ -8,6 +8,11 @@ from pyobs.images import Image
8
8
 
9
9
  class _CCDDataCalibrator:
10
10
  def __init__(self, image: Image, bias: Image | None = None, dark: Image | None = None, flat: Image | None = None):
11
+ # to_ccddata() below never carries a catalog through anyway, so drop it before trim() to
12
+ # avoid its stale-catalog guard rejecting an image whose catalog wouldn't survive regardless.
13
+ if image.safe_catalog is not None:
14
+ image = image.copy()
15
+ image.catalog = None
11
16
  self._image = image.trim()
12
17
  self._bias = self._optional_to_ccddata(bias)
13
18
  self._dark = self._optional_to_ccddata(dark)
@@ -1,5 +1,6 @@
1
1
  import asyncio
2
2
  import logging
3
+ from abc import abstractmethod
3
4
  from typing import Any
4
5
 
5
6
  from pyobs.images import Image
@@ -12,10 +13,12 @@ log = logging.getLogger(__name__)
12
13
 
13
14
 
14
15
  class AperturePhotometry(Photometry):
15
- __module__ = "pyobs.images.processors.photometry"
16
+ """Base class for aperture photometry processors -- not meant to be used directly,
17
+ see PhotUtilsPhotometry/SepPhotometry for concrete calculators."""
16
18
 
17
19
  APERTURE_RADII = range(1, 9)
18
20
 
21
+ @abstractmethod
19
22
  def __init__(self, calculator: _PhotometryCalculator, **kwargs: Any) -> None:
20
23
  self._calculator = calculator
21
24
  super().__init__(**kwargs)
@@ -1,12 +1,15 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import logging
4
- from typing import Any
4
+ from typing import TYPE_CHECKING, Any
5
5
 
6
6
  from pyobs.images import Image, ImageProcessor
7
7
  from pyobs.object import Object
8
8
  from pyobs.utils.exceptions import ImageError
9
9
 
10
+ if TYPE_CHECKING:
11
+ from pyobs.robotic.utils.archive import Archive
12
+
10
13
  log = logging.getLogger(__name__)
11
14
 
12
15
 
@@ -15,21 +18,42 @@ class PipelineMixin:
15
18
 
16
19
  __module__ = "pyobs.mixins"
17
20
 
18
- def __init__(self, steps: list[dict[str, Any] | ImageProcessor] | None = None, **kwargs: Any):
21
+ def __init__(
22
+ self,
23
+ steps: list[dict[str, Any] | ImageProcessor] | None = None,
24
+ archive: dict[str, Any] | Archive | None = None,
25
+ **kwargs: Any,
26
+ ):
19
27
  """Initializes the mixin.
20
28
 
21
29
  Args:
22
30
  steps: Pipeline steps to run on images.
31
+ archive: Default archive config/object for steps that accept one (e.g.
32
+ Calibration) and don't already specify their own -- lets a pipeline's
33
+ steps share the archive it was itself given, instead of repeating the
34
+ same archive config in every step that needs one. Steps that don't
35
+ declare an archive parameter just absorb and drop it via their own
36
+ **kwargs, the same as any other unrecognized Object kwarg.
23
37
  """
24
38
 
25
39
  # store
26
40
  if isinstance(self, Object):
27
41
  steps = [] if steps is None else steps
28
- self.__pipeline_steps = [self.add_child_object(step, ImageProcessor) for step in steps]
42
+ self.__pipeline_steps = [
43
+ self.add_child_object(self._with_default_archive(step, archive), ImageProcessor) for step in steps
44
+ ]
29
45
 
30
46
  else:
31
47
  raise ValueError("This class is no Object.")
32
48
 
49
+ @staticmethod
50
+ def _with_default_archive(
51
+ step: dict[str, Any] | ImageProcessor, archive: dict[str, Any] | Archive | None
52
+ ) -> dict[str, Any] | ImageProcessor:
53
+ if archive is not None and isinstance(step, dict) and "archive" not in step:
54
+ return {**step, "archive": archive}
55
+ return step
56
+
33
57
  async def reset_pipeline(self) -> None:
34
58
  """Resets all previous state of the involved image processors."""
35
59
  for step in self.__pipeline_steps:
@@ -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,14 @@
1
+ from .pipeline import Pipeline
2
+ from .progress import MasterCalibCreated, ProgressCallback, ProgressEvent, ScienceFrameProcessed
3
+ from .reduction import Reduction
4
+ from .reduction_base import ReductionBase
5
+
6
+ __all__ = [
7
+ "Reduction",
8
+ "ReductionBase",
9
+ "Pipeline",
10
+ "MasterCalibCreated",
11
+ "ScienceFrameProcessed",
12
+ "ProgressEvent",
13
+ "ProgressCallback",
14
+ ]
@@ -22,14 +22,22 @@ log = logging.getLogger(__name__)
22
22
  class Pipeline(Object, PipelineMixin):
23
23
  """Pipeline based on the astropy package ccdproc."""
24
24
 
25
- def __init__(self, steps: list[dict[str, Any] | ImageProcessor], **kwargs: Any):
25
+ def __init__(
26
+ self,
27
+ steps: list[dict[str, Any] | ImageProcessor],
28
+ archive: dict[str, Any] | Archive | None = None,
29
+ **kwargs: Any,
30
+ ):
26
31
  """Pipeline for science images.
27
32
 
28
33
  Args:
29
34
  steps: List of pipeline steps to perform.
35
+ archive: Default archive config/object for steps that accept one (e.g.
36
+ Calibration) and don't already specify their own. See
37
+ PipelineMixin.__init__.
30
38
  """
31
39
  Object.__init__(self, **kwargs)
32
- PipelineMixin.__init__(self, steps)
40
+ PipelineMixin.__init__(self, steps, archive=archive)
33
41
 
34
42
  @staticmethod
35
43
  def _combine_calib_images(
@@ -0,0 +1,40 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Callable
4
+ from dataclasses import dataclass
5
+ from typing import Literal
6
+
7
+ from pyobs.utils.enums import ImageType
8
+
9
+
10
+ @dataclass
11
+ class MasterCalibCreated:
12
+ """A master calibration frame (BIAS/DARK/SKYFLAT) was created and stored/uploaded."""
13
+
14
+ image_type: ImageType
15
+ instrument: str
16
+ binning: str
17
+ filter_name: str | None
18
+ filename: str
19
+
20
+
21
+ @dataclass
22
+ class ScienceFrameProcessed:
23
+ """One science frame finished processing (successfully or not).
24
+
25
+ index/total are cumulative across the whole reduction run, not just the current
26
+ instrument/binning/filter batch.
27
+ """
28
+
29
+ index: int
30
+ total: int
31
+ filename: str | None
32
+ status: Literal["ok", "error"]
33
+ error: str | None = None
34
+
35
+
36
+ ProgressEvent = MasterCalibCreated | ScienceFrameProcessed
37
+ ProgressCallback = Callable[[ProgressEvent], None]
38
+
39
+
40
+ __all__ = ["MasterCalibCreated", "ScienceFrameProcessed", "ProgressEvent", "ProgressCallback"]
@@ -1,17 +1,19 @@
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
 
7
8
  from pyobs.images import Image
8
9
  from pyobs.object import get_object
9
- from pyobs.robotic.utils.archive import Archive
10
+ from pyobs.robotic.utils.archive import Archive, FrameInfo
10
11
  from pyobs.utils.enums import ImageType
11
12
  from pyobs.utils.fits import FilenameFormatter
12
- from pyobs.utils.time import Time
13
13
 
14
14
  from .pipeline import Pipeline
15
+ from .progress import MasterCalibCreated, ProgressCallback, ScienceFrameProcessed
16
+ from .reduction_base import ReductionBase
15
17
 
16
18
  log = logging.getLogger(__name__)
17
19
 
@@ -19,87 +21,53 @@ log = logging.getLogger(__name__)
19
21
  FILENAME = "{SITEID}{TELID}-{INSTRUME}-{DAY-OBS|date:}-{IMAGETYP}-{XBINNING}x{YBINNING}{FILTER|filter}.fits"
20
22
 
21
23
 
22
- class Night:
24
+ class Reduction(ReductionBase):
23
25
  def __init__(
24
26
  self,
25
27
  archive: dict[str, Any] | Archive,
26
28
  pipeline: dict[str, Any] | Pipeline,
27
- worker_procs: int = 4,
28
29
  filenames_calib: str = FILENAME,
29
30
  min_flats: int = 10,
30
- store_local: str | None = None,
31
+ output: str | dict[str, Any] | Archive | None = None,
31
32
  create_calibs: bool = True,
32
33
  calib_science: bool = True,
33
- **kwargs: Any,
34
+ progress_callback: ProgressCallback | None = None,
34
35
  ):
35
- """Creates a Night object for reducing a given night.
36
+ """Creates a Reduction object for reducing a given observation period.
36
37
 
37
38
  Args:
38
- archive: Archive to fetch images from and write results to.
39
+ archive: Archive to fetch raw and calibration frames from. Also the output
40
+ destination, unless output is set.
39
41
  pipeline: Science pipeline.
40
- worker_procs: Number of worker processes.
41
42
  filenames_calib: Filename pattern for master calibration files.
42
43
  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.
44
+ output: Where to write results. A string is a local directory path; a dict or
45
+ Archive is an output archive. If not set, results are written back to archive.
44
46
  create_calibs: If False, no calibration files are created for night.
45
47
  calib_science: If False, no science frames are calibrated.
48
+ progress_callback: See ReductionBase.
46
49
  """
50
+ super().__init__(archive=archive, pipeline=pipeline, min_flats=min_flats, progress_callback=progress_callback)
47
51
 
48
- # get archive and science pipeline
49
- self._archive = get_object(archive, Archive)
50
- self._pipeline = get_object(pipeline, Pipeline, archive=archive)
51
-
52
- # stuff
53
- self._worker_processes = worker_procs
54
- self._min_flats = min_flats
55
- self._store_local = store_local
52
+ self._store_local: str | None = output if isinstance(output, str) else None
53
+ self._output_archive = (
54
+ self._archive if output is None or isinstance(output, str) else get_object(output, Archive)
55
+ )
56
56
  self._create_calibs = create_calibs
57
57
  self._calib_science = calib_science
58
58
 
59
- # cache for master calibration frames
60
- self._master_frames: dict[tuple[ImageType, str, str, str | None], Image] = {}
59
+ # make sure the local output directory exists
60
+ if self._store_local:
61
+ os.makedirs(self._store_local, exist_ok=True)
61
62
 
62
63
  # default filename patterns
63
64
  self._fmt_calib = FilenameFormatter(filenames_calib)
64
65
 
65
- async def _find_master(
66
- self,
67
- night: str,
68
- image_type: ImageType,
69
- instrument: str,
70
- binning: str,
71
- filter_name: str | None = None,
72
- max_days: float = 30.0,
73
- ) -> Image | None:
74
- """Find master calibration frame for given parameters using a cache.
75
-
76
- Args:
77
- image_type: image type.
78
- instrument: Instrument name.
79
- binning: Binning.
80
- filter_name: Name of filter.
81
- max_days: Maximum number of days from DATE-OBS to find frames.
82
-
83
- Returns:
84
- Image or None
85
- """
86
-
87
- # is in cache?
88
- if (image_type, instrument, binning, filter_name) in self._master_frames:
89
- return self._master_frames[image_type, instrument, binning, filter_name]
90
-
91
- # try to download one
92
- midnight = Time(night + " 23:59:59")
93
- image = await self._pipeline.find_master(
94
- self._archive, image_type, midnight, instrument, binning, filter_name, max_days=max_days
95
- )
96
- if image is not None:
97
- # store and return it
98
- self._master_frames[image_type, instrument, binning, filter_name] = image
99
- return image
100
- else:
101
- # still nothing
102
- return None
66
+ # populated by _count_science_frames() at the start of __call__, consumed by _calib_data()
67
+ # so science frames are only listed from the archive once per combination, not twice
68
+ self._science_frame_cache: dict[tuple[str, str, str], list[FrameInfo]] = {}
69
+ self._frames_done = 0
70
+ self._frames_total = 0
103
71
 
104
72
  async def _create_master_calib(
105
73
  self, night: str, instrument: str, image_type: ImageType, binning: str, filter_name: str | None = None
@@ -128,6 +96,7 @@ class Night:
128
96
  images = await self._archive.download_frames(infos)
129
97
  if len(images) < 3:
130
98
  log.warning("Too few (%d) frames found, skipping...", len(infos))
99
+ return None
131
100
 
132
101
  # create master
133
102
  calib: Image | None = None
@@ -191,21 +160,43 @@ class Night:
191
160
  calib.writeto(path, overwrite=True)
192
161
  else:
193
162
  log.info("Uploading master calibration frame as %s...", calib.header["FNAME"])
194
- await self._archive.upload_frames([calib])
163
+ await self._output_archive.upload_frames([calib])
164
+
165
+ self._report_progress(
166
+ MasterCalibCreated(
167
+ image_type=image_type,
168
+ instrument=instrument,
169
+ binning=binning,
170
+ filter_name=filter_name,
171
+ filename=calib.header["FNAME"],
172
+ )
173
+ )
195
174
 
196
175
  # finished
197
176
  return calib
198
177
 
178
+ async def _count_science_frames(self, night: str, options: dict[str, list[Any]]) -> int:
179
+ """Pre-pass: list (not download) OBJECT frames for every instrument/binning/filter
180
+ combination once, caching the results so _calib_data() doesn't have to list them
181
+ again, and return the total count across the whole night for progress reporting."""
182
+ total = 0
183
+ for instrument in options["instruments"]:
184
+ for binning in options["binnings"]:
185
+ for filter_name in options["filters"]:
186
+ infos = await self._archive.list_frames(
187
+ night=night,
188
+ instrument=instrument,
189
+ image_type=ImageType.OBJECT,
190
+ binning=binning,
191
+ filter_name=filter_name,
192
+ rlevel=0,
193
+ )
194
+ self._science_frame_cache[instrument, binning, filter_name] = infos
195
+ total += len(infos)
196
+ return total
197
+
199
198
  async def _calib_data(self, night: str, instrument: str, binning: str, filter_name: str) -> None:
200
- # get all frames
201
- infos = await self._archive.list_frames(
202
- night=night,
203
- instrument=instrument,
204
- image_type=ImageType.OBJECT,
205
- binning=binning,
206
- filter_name=filter_name,
207
- rlevel=0,
208
- )
199
+ infos = self._science_frame_cache.get((instrument, binning, filter_name), [])
209
200
  total = len(infos)
210
201
  if total == 0:
211
202
  return
@@ -230,10 +221,27 @@ class Night:
230
221
  calibrated.writeto(path, overwrite=True)
231
222
  else:
232
223
  log.info("(%d/%d) Uploading calibrated images as %s...", i, total, calibrated.header["FNAME"])
233
- await self._archive.upload_frames([calibrated])
224
+ await self._output_archive.upload_frames([calibrated])
225
+
226
+ self._frames_done += 1
227
+ self._report_progress(
228
+ ScienceFrameProcessed(
229
+ index=self._frames_done, total=self._frames_total, filename=info.filename, status="ok"
230
+ )
231
+ )
234
232
 
235
- except Exception:
233
+ except Exception as e:
236
234
  log.exception("(%d/%d) Error processing image %s.", i, total, info.filename)
235
+ self._frames_done += 1
236
+ self._report_progress(
237
+ ScienceFrameProcessed(
238
+ index=self._frames_done,
239
+ total=self._frames_total,
240
+ filename=info.filename,
241
+ status="error",
242
+ error=str(e),
243
+ )
244
+ )
237
245
 
238
246
  async def __call__(self, site: str, night: str) -> None:
239
247
  """Reduces all data im this night."""
@@ -248,6 +256,11 @@ class Night:
248
256
  len(options["filters"]),
249
257
  )
250
258
 
259
+ # pre-pass: know the total science-frame count up front for progress reporting, and
260
+ # cache the per-combination frame lists so _calib_data() doesn't list them again
261
+ if self._calib_science:
262
+ self._frames_total = await self._count_science_frames(night, options)
263
+
251
264
  # loop instruments
252
265
  for instrument in options["instruments"]:
253
266
  log.info("Reducing data for instrument %s...", instrument)
@@ -256,18 +269,32 @@ class Night:
256
269
  for binning in options["binnings"]:
257
270
  # create bias and dark
258
271
  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)
272
+ try:
273
+ await self._create_master_calib(night, instrument, ImageType.BIAS, binning)
274
+ except Exception:
275
+ log.exception("Error creating master bias for instrument %s, binning %s.", instrument, binning)
276
+ try:
277
+ await self._create_master_calib(night, instrument, ImageType.DARK, binning)
278
+ except Exception:
279
+ log.exception("Error creating master dark for instrument %s, binning %s.", instrument, binning)
261
280
 
262
281
  # loop filters
263
282
  for filter_name in options["filters"]:
264
283
  # create flat
265
284
  if self._create_calibs:
266
- await self._create_master_calib(night, instrument, ImageType.SKYFLAT, binning, filter_name)
285
+ try:
286
+ await self._create_master_calib(night, instrument, ImageType.SKYFLAT, binning, filter_name)
287
+ except Exception:
288
+ log.exception(
289
+ "Error creating master flat for instrument %s, binning %s, filter %s.",
290
+ instrument,
291
+ binning,
292
+ filter_name,
293
+ )
267
294
 
268
295
  # calibrate science data
269
296
  if self._calib_science:
270
297
  await self._calib_data(night, instrument, binning, filter_name)
271
298
 
272
299
 
273
- __all__ = ["Night"]
300
+ __all__ = ["Reduction"]
@@ -0,0 +1,104 @@
1
+ from __future__ import annotations
2
+
3
+ import logging
4
+ from abc import ABC, abstractmethod
5
+ from typing import Any
6
+
7
+ from pyobs.images import Image
8
+ from pyobs.object import get_object
9
+ from pyobs.robotic.utils.archive import Archive
10
+ from pyobs.utils.enums import ImageType
11
+ from pyobs.utils.time import Time
12
+
13
+ from .pipeline import Pipeline
14
+ from .progress import ProgressCallback, ProgressEvent
15
+
16
+ log = logging.getLogger(__name__)
17
+
18
+
19
+ class ReductionBase(ABC):
20
+ """Common base for classes that reduce one observation period's worth of data.
21
+
22
+ Holds the archive/pipeline plumbing, the master-calibration-frame cache and lookup
23
+ (shared by any reduction strategy that needs BIAS/DARK/SKYFLAT masters), and the
24
+ progress-callback mechanism. Concrete subclasses implement __call__.
25
+ """
26
+
27
+ def __init__(
28
+ self,
29
+ archive: dict[str, Any] | Archive,
30
+ pipeline: dict[str, Any] | Pipeline,
31
+ min_flats: int = 10,
32
+ progress_callback: ProgressCallback | None = None,
33
+ ):
34
+ """
35
+ Args:
36
+ archive: Archive to fetch raw and calibration frames from.
37
+ pipeline: Science pipeline.
38
+ min_flats: Minimum number of raw frames to create flat field.
39
+ progress_callback: Optional callable invoked with a ProgressEvent whenever a
40
+ master calibration frame is created or a science frame finishes processing.
41
+ Exceptions raised by the callback are logged and otherwise ignored.
42
+ """
43
+ self._archive = get_object(archive, Archive)
44
+ self._pipeline = get_object(pipeline, Pipeline, archive=archive)
45
+ self._min_flats = min_flats
46
+ self._progress_callback = progress_callback
47
+
48
+ # cache for master calibration frames
49
+ self._master_frames: dict[tuple[ImageType, str, str, str | None], Image] = {}
50
+
51
+ def _report_progress(self, event: ProgressEvent) -> None:
52
+ if self._progress_callback is None:
53
+ return
54
+ try:
55
+ self._progress_callback(event)
56
+ except Exception:
57
+ log.exception("Error in progress callback.")
58
+
59
+ async def _find_master(
60
+ self,
61
+ night: str,
62
+ image_type: ImageType,
63
+ instrument: str,
64
+ binning: str,
65
+ filter_name: str | None = None,
66
+ max_days: float = 30.0,
67
+ ) -> Image | None:
68
+ """Find master calibration frame for given parameters using a cache.
69
+
70
+ Args:
71
+ image_type: image type.
72
+ instrument: Instrument name.
73
+ binning: Binning.
74
+ filter_name: Name of filter.
75
+ max_days: Maximum number of days from DATE-OBS to find frames.
76
+
77
+ Returns:
78
+ Image or None
79
+ """
80
+
81
+ # is in cache?
82
+ if (image_type, instrument, binning, filter_name) in self._master_frames:
83
+ return self._master_frames[image_type, instrument, binning, filter_name]
84
+
85
+ # try to download one
86
+ midnight = Time(night + " 23:59:59")
87
+ image = await self._pipeline.find_master(
88
+ self._archive, image_type, midnight, instrument, binning, filter_name, max_days=max_days
89
+ )
90
+ if image is not None:
91
+ # store and return it
92
+ self._master_frames[image_type, instrument, binning, filter_name] = image
93
+ return image
94
+ else:
95
+ # still nothing
96
+ return None
97
+
98
+ @abstractmethod
99
+ async def __call__(self, site: str, night: str) -> None:
100
+ """Reduces all data for the given site and observation period."""
101
+ ...
102
+
103
+
104
+ __all__ = ["ReductionBase"]
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pyobs-core"
3
- version = "2.0.0.dev67"
3
+ version = "2.0.0.dev70"
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,4 +0,0 @@
1
- from .night import Night
2
- from .pipeline import Pipeline
3
-
4
- __all__ = ["Night", "Pipeline"]