Skip to content

Commit

Permalink
NEOS chip gap calculation uneven (#152)
Browse files Browse the repository at this point in the history
Gaps between individual chips was inconsistent, this places the
gaps in the correct places.

Additionally removed the NEOS Band enum
  • Loading branch information
dahlend authored Nov 12, 2024
1 parent ff7ab41 commit 44d3a46
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 52 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Horizons orbit table query now includes, M1/2, K1/2, PC, and rotation period.

### Fixed

- NEOS Chip size calculation was slightly incorrect with regard to the placement of the
gaps between the chips.
- NEOS FOV rotation was being calculated in the ecliptic frame, whereas images will be
in the equatorial frame. Rotation is now defaulting to the equatorial frame.


## [v1.0.3]

Expand Down
12 changes: 10 additions & 2 deletions src/kete/neos.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
import numpy as np
from .fov import NeosCmos, NeosVisit


__all__ = ["sunshield_rotation", "NeosCmos", "NeosVisit", "FOV_WIDTH", "FOV_HEIGHT"]


BANDS: list[float] = [4700.0, 8000.0]
"""Effective wavelength of the NC1 and NC2 bands in nm."""

FOV_WIDTH: float = 7.10
"""Expected effective field of view width in degrees"""
"""Expected effective field of view width in degrees. Approximate Value."""

FOV_HEIGHT: float = 1.68
"""Expected effective field of view height in degrees"""
"""Expected effective field of view height in degrees. Approximate Value."""

FOV_CHIP_GAP: float = 0.11
"""Expected effective gap between individual chips in degrees. Approximate Value."""

ZERO_MAGS: list[float] = [170.662, 64.13]
"""Zero point magnitude for nc1 and nc2"""
Expand Down
17 changes: 7 additions & 10 deletions src/kete/rust/fovs/definitions.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use kete_core::fov::{self, NeosBand};
use kete_core::fov::{self};
use kete_core::fov::{FovLike, SkyPatch};
use nalgebra::Vector3;
use pyo3::{exceptions, prelude::*};
Expand Down Expand Up @@ -607,7 +607,7 @@ impl PyNeosCmos {
subloop_id,
exposure_id,
cmos_id,
band.into(),
band,
))
}

Expand Down Expand Up @@ -677,11 +677,7 @@ impl PyNeosCmos {
/// Band Number
#[getter]
pub fn band(&self) -> u8 {
match self.0.band {
NeosBand::NC1 => 1,
NeosBand::NC2 => 2,
NeosBand::Undefined => 0,
}
self.0.band
}

/// Rotation angle of the FOV in degrees.
Expand Down Expand Up @@ -738,22 +734,23 @@ impl PyNeosVisit {
exposure_id: u8,
band: u8,
) -> Self {
let pointing = pointing.into_vector(crate::frame::PyFrames::Ecliptic);
let pointing = pointing.into_vector(crate::frame::PyFrames::Equatorial);
let pointing = pointing.raw.into();
let observer = observer.as_equatorial().unwrap().0;
PyNeosVisit(fov::NeosVisit::from_pointing(
x_width.to_radians(),
y_width.to_radians(),
gap_angle.to_radians(),
pointing,
rotation.to_radians(),
observer.0,
observer,
side_id,
stack_id,
quad_id,
loop_id,
subloop_id,
exposure_id,
band.into(),
band,
))
}

Expand Down
60 changes: 20 additions & 40 deletions src/kete_core/src/fov/neos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,6 @@ use crate::prelude::*;
use nalgebra::Vector3;
use serde::{Deserialize, Serialize};

/// NEOS bands
#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq)]
pub enum NeosBand {
/// No Band defined.
Undefined,

/// NEOS NC1 Band.
NC1,

/// NEOS NC2 Band.
NC2,
}

/// Convert a NEOS band from u8
/// 1 is NC1 2 is NC2, everything else is Undefined.
impl From<u8> for NeosBand {
fn from(value: u8) -> Self {
match value {
1 => NeosBand::NC1,
2 => NeosBand::NC2,
_ => NeosBand::Undefined,
}
}
}

/// NEOS frame data, a single detector on a single band
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct NeosCmos {
Expand Down Expand Up @@ -62,7 +37,7 @@ pub struct NeosCmos {
pub exposure_id: u8,

/// Wavelength band
pub band: NeosBand,
pub band: u8,

/// CMOS ID
/// ID number of the CMOS chip, 0, 1, 2, or 3
Expand All @@ -83,7 +58,7 @@ impl NeosCmos {
subloop_id: u8,
exposure_id: u8,
cmos_id: u8,
band: NeosBand,
band: u8,
) -> Self {
let patch =
OnSkyRectangle::new(pointing, rotation, NEOS_WIDTH, NEOS_HEIGHT, observer.frame);
Expand Down Expand Up @@ -164,7 +139,7 @@ pub struct NeosVisit {
pub exposure_id: u8,

/// Wavelength band
pub band: NeosBand,
pub band: u8,
}

impl NeosVisit {
Expand Down Expand Up @@ -235,7 +210,7 @@ impl NeosVisit {
loop_id: u8,
subloop_id: u8,
exposure_id: u8,
band: NeosBand,
band: u8,
) -> Self {
// Rotate the Z axis to match the defined rotation angle, this vector is not
// orthogonal to the pointing vector, but is in the correct plane of the final
Expand All @@ -250,29 +225,34 @@ impl NeosVisit {
// orthogonal to the two existing vectors.
let up_vec = pointing.cross(&left_vec);

// +------+-+------+-+------+-+------+ ^
// | 1 |g| 2 |g| 3 |g| 4 | |
// | |a| |a| |a| | y
// | |p| |p| |p| | |
// +------+-+------+-+------+-+------+ _
// <-cf-> x ->
// +-------+-+-------+-+-------+-+-------+ ^
// | |g| |g| |g| | |
// | 1 |a| 2 |a| 3 |a| 4 | y
// | |p| |p| |p| | |
// +-------+-+-------+-+-------+-+-------+ -
// | <---- x -----> |
//
// pointing vector is in the middle of the 'a' in the central gap.
// Pointing vector is in the middle of the 'a' in the central gap.

// the Y direction is bounded by 2 planes, calculate them one time
let y_top: Vector3<f64> = rotate_around(&up_vec, left_vec, y_width / 2.0);
let y_bottom: Vector3<f64> = rotate_around(&(-up_vec), left_vec, -y_width / 2.0);

let half_gap = gap_angle / 2.0;

// chip width in the x direction:
// 4 * chip_width + 3 * gap_angle = x_width
// chip_width = (x_width - 3 * gap_angle) / 4
let chip_width = (x_width - 3.0 * gap_angle) / 4.0;

// for each chip calculate the x bounds
let chip_1_a: Vector3<f64> = rotate_around(&left_vec, up_vec, -x_width / 2.0);
let chip_1_b: Vector3<f64> = -rotate_around(&left_vec, up_vec, -x_width / 4.0 - half_gap);
let chip_2_a: Vector3<f64> = rotate_around(&left_vec, up_vec, -x_width / 4.0 + half_gap);
let chip_1_b: Vector3<f64> = -rotate_around(&left_vec, up_vec, -x_width / 2.0 + chip_width);
let chip_2_a: Vector3<f64> = rotate_around(&left_vec, up_vec, -chip_width - half_gap);
let chip_2_b: Vector3<f64> = -rotate_around(&left_vec, up_vec, -half_gap);
let chip_3_a: Vector3<f64> = rotate_around(&left_vec, up_vec, half_gap);
let chip_3_b: Vector3<f64> = -rotate_around(&left_vec, up_vec, x_width / 4.0 - half_gap);
let chip_4_a: Vector3<f64> = rotate_around(&left_vec, up_vec, x_width / 4.0 + half_gap);
let chip_3_b: Vector3<f64> = -rotate_around(&left_vec, up_vec, chip_width + half_gap);
let chip_4_a: Vector3<f64> = rotate_around(&left_vec, up_vec, x_width / 2.0 - chip_width);
let chip_4_b: Vector3<f64> = -rotate_around(&left_vec, up_vec, x_width / 2.0);

// make the patches for each chip
Expand Down

0 comments on commit 44d3a46

Please sign in to comment.