From 84c6a08f5a1e7bdbd67886364b176fddc62c0c08 Mon Sep 17 00:00:00 2001 From: Sebastian Aranda Sanchez Date: Fri, 9 Aug 2024 10:58:20 -0400 Subject: [PATCH 1/4] Component cleaning: Remove and reorder imports Add PropTypes Use object destructuring for props and state --- .../components/AuxTel/Dome/Dome.container.jsx | 12 +- love/src/components/AuxTel/Dome/Dome.jsx | 115 ++++++++++++++---- 2 files changed, 99 insertions(+), 28 deletions(-) diff --git a/love/src/components/AuxTel/Dome/Dome.container.jsx b/love/src/components/AuxTel/Dome/Dome.container.jsx index b9ddfc1a0..c6fec2fc4 100644 --- a/love/src/components/AuxTel/Dome/Dome.container.jsx +++ b/love/src/components/AuxTel/Dome/Dome.container.jsx @@ -19,11 +19,11 @@ this program. If not, see . import React from 'react'; import { connect } from 'react-redux'; -import Dome from './Dome'; -import { getDomeState, getATMCSState } from '../../../redux/selectors'; -import { addGroup, removeGroup } from '../../../redux/actions/ws'; -import SubscriptionTableContainer from '../../GeneralPurpose/SubscriptionTable/SubscriptionTable.container'; +import SubscriptionTableContainer from 'components/GeneralPurpose/SubscriptionTable/SubscriptionTable.container'; +import { getDomeState, getATMCSState } from 'redux/selectors'; +import { addGroup, removeGroup } from 'redux/actions/ws'; import { EUIs } from 'Config'; +import Dome from './Dome'; export const schema = { description: 'Summary view of the ATDome. Contains general information about the dome and mount state', @@ -143,13 +143,13 @@ const mapStateToProps = (state) => { const mapDispatchToProps = (dispatch) => { const subscriptions = [ 'telemetry-ATDome-0-position', + 'telemetry-ATMCS-0-mount_AzEl_Encoders', + 'telemetry-ATMCS-0-mount_Nasmyth_Encoders', 'event-ATDome-0-azimuthState', 'event-ATDome-0-azimuthCommandedState', 'event-ATDome-0-dropoutDoorState', 'event-ATDome-0-mainDoorState', 'event-ATDome-0-allAxesInPosition', - 'telemetry-ATMCS-0-mount_AzEl_Encoders', - 'telemetry-ATMCS-0-mount_Nasmyth_Encoders', 'event-ATMCS-0-atMountState', 'event-ATMCS-0-target', 'event-ATMCS-0-allAxesInPosition', diff --git a/love/src/components/AuxTel/Dome/Dome.jsx b/love/src/components/AuxTel/Dome/Dome.jsx index 82883da63..50a8c0c32 100644 --- a/love/src/components/AuxTel/Dome/Dome.jsx +++ b/love/src/components/AuxTel/Dome/Dome.jsx @@ -18,30 +18,101 @@ this program. If not, see . */ import React, { Component } from 'react'; -// import PropTypes from 'prop-types'; +import PropTypes from 'prop-types'; import ManagerInterface, { fixedFloat, parseCommanderData } from 'Utils'; -// import SkymapGrid from '../Skymap/SkymapGrid'; import PlotContainer from 'components/GeneralPurpose/Plot/Plot.container'; import TimeSeriesControls from 'components/GeneralPurpose/Plot/TimeSeriesControls/TimeSeriesControls'; -import DomeTopView from './DomeTopView'; +import Elevation from 'components/GeneralPurpose/Elevation/Elevation'; +import Azimuth from 'components/GeneralPurpose/Azimuth/Azimuth'; +import WindRose from 'components/icons/WindRose/WindRose'; import DomePointing from './DomePointing'; import DomeShutter from './DomeShutter'; import MountTopView from './MountTopView'; -import Elevation from 'components/GeneralPurpose/Elevation/Elevation'; -import Azimuth from 'components/GeneralPurpose/Azimuth/Azimuth'; - -import WindRose from '../../icons/WindRose/WindRose'; import DomeSummaryTable from './DomeSummaryTable/DomeSummaryTable'; - import styles from './Dome.module.css'; export default class Dome extends Component { static propTypes = { - // raftsDetailedState: PropTypes.string, - // imageReadinessDetailedState: PropTypes.string, - // calibrationDetailedState: PropTypes.string, - // shutterDetailedState: PropTypes.string, - // imageSequence: PropTypes.object, + /** Width for the diferent SVG components */ + width: PropTypes.number, + /** Height for the diferent SVG components */ + height: PropTypes.number, + /** Dropout door opening percentage */ + dropoutDoorOpeningPercentage: PropTypes.number, + /** Main door opening percentage */ + mainDoorOpeningPercentage: PropTypes.number, + /** Azimuth position */ + azimuthPosition: PropTypes.number, + /** Azimuth state */ + azimuthState: PropTypes.string, + /** Azimuth commanded */ + azimuthCommanded: PropTypes.number, + /** Dome in position */ + domeInPosition: PropTypes.bool, + /** Dropout door state */ + dropoutDoorState: PropTypes.string, + /** Main door state */ + mainDoorState: PropTypes.string, + /** AT mount state */ + atMountState: PropTypes.string, + /** Mount in position */ + mountInPosition: PropTypes.bool, + /** Track ID */ + trackID: PropTypes.number, + /** Target azimuth */ + targetAzimuth: PropTypes.number, + /** Target elevation */ + targetElevation: PropTypes.number, + /** Target nasmyth1 */ + targetNasmyth1: PropTypes.number, + /** Target nasmyth2 */ + targetNasmyth2: PropTypes.number, + /** M3 state */ + m3State: PropTypes.string, + /** Min elevation */ + minEl: PropTypes.number, + /** Min azimuth */ + minAz: PropTypes.number, + /** Min nasmyth1 */ + minNas1: PropTypes.number, + /** Min nasmyth2 */ + minNas2: PropTypes.number, + /** Min M3 */ + minM3: PropTypes.number, + /** Max elevation */ + maxEl: PropTypes.number, + /** Max azimuth */ + maxAz: PropTypes.number, + /** Max nasmyth1 */ + maxNas1: PropTypes.number, + /** Max nasmyth2 */ + maxNas2: PropTypes.number, + /** Max M3 */ + maxM3: PropTypes.number, + /** Time azimuth limit */ + timeAzLim: PropTypes.number, + /** Time rotation limit */ + timeRotLim: PropTypes.number, + /** Time unobservable */ + timeUnobservable: PropTypes.number, + /** Time elevation high limit */ + timeElHighLimit: PropTypes.number, + /** Current pointing azimuth */ + currentPointingAz: PropTypes.number, + /** Current pointing elevation */ + currentPointingEl: PropTypes.number, + /** Current pointing nasmyth1 */ + currentPointingNasmyth1: PropTypes.number, + /** Current pointing nasmyth2 */ + currentPointingNasmyth2: PropTypes.number, + /** AT dome summary state */ + atDomeSummaryState: PropTypes.string, + /** ATMCS summary state */ + ATMCSSummaryState: PropTypes.string, + /** AT dome tracking */ + atDomeTracking: PropTypes.bool, + /** Target name */ + targetName: PropTypes.string, }; static defaultProps = { @@ -196,10 +267,9 @@ export default class Dome extends Component { }; render() { - const width = this.props.width; - const height = this.props.height; - const { + width, + height, dropoutDoorOpeningPercentage, mainDoorOpeningPercentage, azimuthPosition, @@ -216,12 +286,12 @@ export default class Dome extends Component { targetNasmyth1, targetNasmyth2, m3State, - minEl, + // minEl, minAz, minNas1, minNas2, minM3, - maxEl, + // maxEl, maxAz, maxNas1, maxNas2, @@ -240,6 +310,8 @@ export default class Dome extends Component { targetName, } = this.props; + const { timeWindow, isLive, historicalData } = this.state; + const isProjected = true; let azDiff = Math.abs(azimuthPosition - currentPointingAz); if (azDiff > 180) azDiff = azDiff - 360; @@ -257,16 +329,15 @@ export default class Dome extends Component { }; const timeSeriesControlsProps = { - timeWindow: this.state.timeWindow, - isLive: this.state.isLive, - historicalData: this.state.historicalData, + timeWindow: timeWindow, + isLive: isLive, + historicalData: historicalData, }; return (
- {/* */}
From 33f4c18fd8374a4a257a82bf8d4198dd41410020 Mon Sep 17 00:00:00 2001 From: Sebastian Aranda Sanchez Date: Fri, 9 Aug 2024 12:50:26 -0400 Subject: [PATCH 2/4] Add RA, Dec and Rotator position to `AuxTel/Dome` component --- .../components/AuxTel/Dome/Dome.container.jsx | 12 +++++++-- love/src/components/AuxTel/Dome/Dome.jsx | 26 +++++++++++++++++-- .../components/AuxTel/Dome/Dome.module.css | 24 ++++++++++++++--- love/src/redux/selectors/selectors.js | 10 +++++++ 4 files changed, 65 insertions(+), 7 deletions(-) diff --git a/love/src/components/AuxTel/Dome/Dome.container.jsx b/love/src/components/AuxTel/Dome/Dome.container.jsx index c6fec2fc4..ff4c565cb 100644 --- a/love/src/components/AuxTel/Dome/Dome.container.jsx +++ b/love/src/components/AuxTel/Dome/Dome.container.jsx @@ -20,7 +20,7 @@ this program. If not, see . import React from 'react'; import { connect } from 'react-redux'; import SubscriptionTableContainer from 'components/GeneralPurpose/SubscriptionTable/SubscriptionTable.container'; -import { getDomeState, getATMCSState } from 'redux/selectors'; +import { getDomeState, getATMCSState, getAuxiliaryTelescopeState } from 'redux/selectors'; import { addGroup, removeGroup } from 'redux/actions/ws'; import { EUIs } from 'Config'; import Dome from './Dome'; @@ -87,6 +87,9 @@ const DomeContainer = ({ controls, atDomeTracking, targetName, + telescopeRA, + telescopeDec, + telescopeRotator, ...props }) => { if (props.isRaw) { @@ -130,6 +133,9 @@ const DomeContainer = ({ ATMCSSummaryState={ATMCSSummaryState} atDomeTracking={atDomeTracking} targetName={targetName} + telescopeRA={telescopeRA} + telescopeDec={telescopeDec} + telescopeRotator={telescopeRotator} /> ); }; @@ -137,7 +143,8 @@ const DomeContainer = ({ const mapStateToProps = (state) => { const domeState = getDomeState(state); const mountState = getATMCSState(state); - return { ...domeState, ...mountState }; + const telescopeState = getAuxiliaryTelescopeState(state); + return { ...domeState, ...mountState, ...telescopeState }; }; const mapDispatchToProps = (dispatch) => { @@ -145,6 +152,7 @@ const mapDispatchToProps = (dispatch) => { 'telemetry-ATDome-0-position', 'telemetry-ATMCS-0-mount_AzEl_Encoders', 'telemetry-ATMCS-0-mount_Nasmyth_Encoders', + 'telemetry-Scheduler-2-observatoryState', 'event-ATDome-0-azimuthState', 'event-ATDome-0-azimuthCommandedState', 'event-ATDome-0-dropoutDoorState', diff --git a/love/src/components/AuxTel/Dome/Dome.jsx b/love/src/components/AuxTel/Dome/Dome.jsx index 50a8c0c32..1d46097b4 100644 --- a/love/src/components/AuxTel/Dome/Dome.jsx +++ b/love/src/components/AuxTel/Dome/Dome.jsx @@ -113,6 +113,12 @@ export default class Dome extends Component { atDomeTracking: PropTypes.bool, /** Target name */ targetName: PropTypes.string, + /** Telescope RA */ + telescopeRA: PropTypes.number, + /** Telescope Dec */ + telescopeDec: PropTypes.number, + /** Rotator position */ + telescopeRotator: PropTypes.number, }; static defaultProps = { @@ -308,6 +314,9 @@ export default class Dome extends Component { ATMCSSummaryState, atDomeTracking, targetName, + telescopeRA, + telescopeDec, + telescopeRotator, } = this.props; const { timeWindow, isLive, historicalData } = this.state; @@ -356,7 +365,6 @@ export default class Dome extends Component { targetValue={targetElevation} />
- Vignetting distance: - {vignettingDistance}º + {vignettingDistance}° +
+
+ Telescope RA: {telescopeRA}° +
+
+ Telescope Dec: {telescopeDec}° +
+
+ Rotator position: {telescopeRotator}° +
+
. align-self: center; flex-wrap: wrap; position: relative; - width: 70%; + width: 100%; max-width: 700px; + container-type: inline-size; } .skymapGridContainer svg { @@ -47,7 +48,7 @@ this program. If not, see . .topRow { display: grid; justify-items: center; - row-gap: 2em; + column-gap: 5em; padding: 1em 0; grid-template-columns: minmax(0, 1fr) minmax(22em, 24em); } @@ -134,7 +135,7 @@ this program. If not, see . .vignettingDistanceContainer { position: absolute; left: 50%; - bottom: 0%; + bottom: calc(var(--content-padding) * -1); transform: translate(-50%, 0); } @@ -142,6 +143,13 @@ this program. If not, see . color: var(--base-font-color); } +.telescopeParametersContainer { + display: flex; + gap: var(--content-padding); + white-space: nowrap; + font-size: var(--font-size-larger); +} + .innerDome { fill: var(--second-tertiary-background-color); fill-opacity: 0.6; @@ -168,3 +176,13 @@ this program. If not, see . .elevationPlot { height: 18em; } + +@container (width < 600px) { + .vignettingDistanceContainer { + bottom: -90px; + } + .telescopeParametersContainer { + flex-direction: column; + gap: 0; + } +} diff --git a/love/src/redux/selectors/selectors.js b/love/src/redux/selectors/selectors.js index 3c9435660..84d8c9dfd 100644 --- a/love/src/redux/selectors/selectors.js +++ b/love/src/redux/selectors/selectors.js @@ -613,6 +613,16 @@ export const getATMCSState = (state) => { }; }; +export const getAuxiliaryTelescopeState = (state) => { + const subscriptions = ['telemetry-Scheduler-2-observatoryState']; + const data = getStreamsData(state, subscriptions); + return { + telescopeRA: data['telemetry-Scheduler-2-observatoryState']?.ra?.value ?? 0, + telescopeDec: data['telemetry-Scheduler-2-observatoryState']?.declination?.value ?? 0, + telescopeRotator: data['telemetry-Scheduler-2-observatoryState']?.telescopeRotator?.value ?? 0, + }; +}; + export const getMountSubscriptions = (index) => { return [ // ATHexapod From cdb4fcb008b9c15d3bacf4dabd086d2e158a8d19 Mon Sep 17 00:00:00 2001 From: Sebastian Aranda Sanchez Date: Fri, 9 Aug 2024 15:33:51 -0400 Subject: [PATCH 3/4] Add component configuration to allow showing different formats for the RA and Dec values --- love/src/Utils.js | 31 +++++++++++++++++++ .../components/AuxTel/Dome/Dome.container.jsx | 8 +++++ love/src/components/AuxTel/Dome/Dome.jsx | 10 ++++-- 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/love/src/Utils.js b/love/src/Utils.js index 8c3af25bb..87552bbfb 100644 --- a/love/src/Utils.js +++ b/love/src/Utils.js @@ -1551,6 +1551,37 @@ export function degrees(radians) { return (radians * 180) / Math.PI; } +/** + * Function to transform degress to Right Ascension hour format + * e.g. 180.55 -> 12:02:12 + * @param {number} degrees degrees to be transformed + * @returns {string} Right Ascension hour format + */ +export function degreesToHMS(degrees) { + const h = Math.floor(degrees / 15); + const m = Math.floor((degrees % 15) * 4); + const s = Math.floor(((degrees % 15) * 4 - m) * 60); + return `${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`; +} + +/** + * Function to transform degress to Declination hour format + * e.g. 180.55 -> +180:02:12 + * @param {number} degrees degrees to be transformed + * @returns {string} Declination hour format + */ +export function degreesToDMS(degrees) { + const d = Math.floor(degrees); + const m = Math.floor((degrees % 1) * 4); + const s = Math.floor(((degrees % 1) * 4 - m) * 60); + const hourFormat = + `${Math.sign(degrees) >= 0 ? '+' : '-'}` + + `${d.toString().padStart(2, '0')}` + + `:${m.toString().padStart(2, '0')}` + + `:${s.toString().padStart(2, '0')}`; + return hourFormat; +} + /** * Function to pase a number or string to float with fixed decimal points * as specified by the points param diff --git a/love/src/components/AuxTel/Dome/Dome.container.jsx b/love/src/components/AuxTel/Dome/Dome.container.jsx index ff4c565cb..4203bdd67 100644 --- a/love/src/components/AuxTel/Dome/Dome.container.jsx +++ b/love/src/components/AuxTel/Dome/Dome.container.jsx @@ -47,6 +47,12 @@ export const schema = { isPrivate: false, default: EUIs.ATDOME, }, + raDecHourFormat: { + type: 'boolean', + description: 'Whether to display the RA and DEC in hour format', + isPrivate: false, + default: false, + }, }, }; @@ -90,6 +96,7 @@ const DomeContainer = ({ telescopeRA, telescopeDec, telescopeRotator, + raDecHourFormat, ...props }) => { if (props.isRaw) { @@ -136,6 +143,7 @@ const DomeContainer = ({ telescopeRA={telescopeRA} telescopeDec={telescopeDec} telescopeRotator={telescopeRotator} + raDecHourFormat={raDecHourFormat} /> ); }; diff --git a/love/src/components/AuxTel/Dome/Dome.jsx b/love/src/components/AuxTel/Dome/Dome.jsx index 1d46097b4..9dd8005c9 100644 --- a/love/src/components/AuxTel/Dome/Dome.jsx +++ b/love/src/components/AuxTel/Dome/Dome.jsx @@ -19,7 +19,7 @@ this program. If not, see . import React, { Component } from 'react'; import PropTypes from 'prop-types'; -import ManagerInterface, { fixedFloat, parseCommanderData } from 'Utils'; +import ManagerInterface, { fixedFloat, parseCommanderData, degreesToHMS, degreesToDMS } from 'Utils'; import PlotContainer from 'components/GeneralPurpose/Plot/Plot.container'; import TimeSeriesControls from 'components/GeneralPurpose/Plot/TimeSeriesControls/TimeSeriesControls'; import Elevation from 'components/GeneralPurpose/Elevation/Elevation'; @@ -317,6 +317,7 @@ export default class Dome extends Component { telescopeRA, telescopeDec, telescopeRotator, + raDecHourFormat, } = this.props; const { timeWindow, isLive, historicalData } = this.state; @@ -343,6 +344,9 @@ export default class Dome extends Component { historicalData: historicalData, }; + const parsedTelescopeRA = raDecHourFormat ? degreesToHMS(telescopeRA) : `${telescopeRA}°`; + const parsedTelescopeDec = raDecHourFormat ? degreesToDMS(telescopeDec) : `${telescopeDec}°`; + return (
@@ -416,10 +420,10 @@ export default class Dome extends Component { className={styles.telescopeParametersContainer} >
- Telescope RA: {telescopeRA}° + Telescope RA: {parsedTelescopeRA}
- Telescope Dec: {telescopeDec}° + Telescope Dec: {parsedTelescopeDec}
Rotator position: {telescopeRotator}° From b2b587ff2efadb885cbc562274370e879ce9f81b Mon Sep 17 00:00:00 2001 From: Sebastian Aranda Sanchez Date: Fri, 9 Aug 2024 15:39:35 -0400 Subject: [PATCH 4/4] Update CHANGELOG --- CHANGELOG.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 632eeae8a..6af033f66 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,11 @@ Version History =============== +v6.3.0 +------ + +* Add RA, Dec and Rotator parameters to the ATDome component ``_ + v6.2.0 ------