All Downloads are FREE. Search and download functionalities are using the official Maven repository.

lucuma.core.model.ExposureTimeMode.scala Maven / Gradle / Ivy

There is a newer version: 0.105.0
Show newest version
// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA)
// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause

package lucuma.core.model

import cats.Eq
import cats.syntax.all.*
import eu.timepit.refined.cats.*
import eu.timepit.refined.types.numeric.PosInt
import lucuma.core.math.SignalToNoise
import lucuma.core.util.TimeSpan
import monocle.Focus
import monocle.Lens
import monocle.Optional
import monocle.Prism
import monocle.macros.GenPrism

sealed trait ExposureTimeMode extends Product with Serializable

object ExposureTimeMode {

  final case class SignalToNoiseMode(value: SignalToNoise)             extends ExposureTimeMode
  final case class FixedExposureMode(count: PosInt, time: TimeSpan) extends ExposureTimeMode

  given Eq[ExposureTimeMode] =
    Eq.instance {
      case (SignalToNoiseMode(a), SignalToNoiseMode(b))           => a === b
      case (FixedExposureMode(ac, ad), FixedExposureMode(bc, bd)) => ac === bc && ad === bd
      case _                                              => false
    }

  val signalToNoise: Prism[ExposureTimeMode, SignalToNoiseMode] =
    GenPrism[ExposureTimeMode, SignalToNoiseMode]

  val fixedExposure: Prism[ExposureTimeMode, FixedExposureMode] =
    GenPrism[ExposureTimeMode, FixedExposureMode]

  val signalToNoiseValue: Optional[ExposureTimeMode, SignalToNoise] =
    Optional[ExposureTimeMode, SignalToNoise] {
      case SignalToNoiseMode(value) => value.some
      case FixedExposureMode(_, _)  => none
    } { nnd =>
      {
        case s @ SignalToNoiseMode(_)    => SignalToNoiseMode.value.replace(nnd)(s)
        case f @ FixedExposureMode(_, _) => f
      }
    }

  val exposureCount: Optional[ExposureTimeMode, PosInt] =
    Optional[ExposureTimeMode, PosInt] {
      case FixedExposureMode(count, _) => count.some
      case SignalToNoiseMode(_)        => none
    } { nni =>
      {
        case f @ FixedExposureMode(_, _) => FixedExposureMode.count.replace(nni)(f)
        case s @ SignalToNoiseMode(_)    => s
      }
    }

  val exposureTime: Optional[ExposureTimeMode, TimeSpan] =
    Optional[ExposureTimeMode, TimeSpan] {
      case FixedExposureMode(_, time) => time.some
      case SignalToNoiseMode(_)       => none
    } { pbd =>
      {
        case f @ FixedExposureMode(_, _) => FixedExposureMode.time.replace(pbd)(f)
        case s @ SignalToNoiseMode(_)    => s
      }
    }

  object SignalToNoiseMode {
    val value: Lens[SignalToNoiseMode, SignalToNoise] = Focus[SignalToNoiseMode](_.value)

    given Eq[SignalToNoiseMode] = Eq.by(_.value)
  }

  object FixedExposureMode {
    val count: Lens[FixedExposureMode, PosInt] = Focus[FixedExposureMode](_.count)
    val time: Lens[FixedExposureMode, TimeSpan]   = Focus[FixedExposureMode](_.time)

    given Eq[FixedExposureMode] = Eq.by(f => (f.count, f.time))
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy