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

gem.Observation.scala Maven / Gradle / Ivy

The newest version!
// Copyright (c) 2016-2020 Association of Universities for Research in Astronomy, Inc. (AURA)
// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause

package gem

import cats.{ Eq, Order, Show }
import cats.implicits._
import gem.config.StaticConfig
import gsp.math.Index

/** ADT for an observation, with constructors for each instrument. */
sealed trait Observation {
  def title: String
  def targetEnvironment: TargetEnvironment
  def staticConfig: StaticConfig
  def sequence: List[Step]
}

object Observation {

  /** A Phoenix observation.
    * @group Constructors
    */
  final case class Phoenix(
    title: String,
    targetEnvironment: TargetEnvironment.Phoenix,
    staticConfig: StaticConfig.Phoenix,
    sequence: List[Step.Phoenix]
  ) extends Observation

  /** A Michelle observation.
    * @group Constructors
    */
  final case class Michelle(
    title: String,
    targetEnvironment: TargetEnvironment.Michelle,
    staticConfig: StaticConfig.Michelle,
    sequence: List[Step.Michelle]
  ) extends Observation

  /** A Gnirs observation.
    * @group Constructors
    */
  final case class Gnirs(
    title: String,
    targetEnvironment: TargetEnvironment.Gnirs,
    staticConfig: StaticConfig.Gnirs,
    sequence: List[Step.Gnirs]
  ) extends Observation

  /** A Niri observation.
    * @group Constructors
    */
  final case class Niri(
    title: String,
    targetEnvironment: TargetEnvironment.Niri,
    staticConfig: StaticConfig.Niri,
    sequence: List[Step.Niri]
  ) extends Observation

  /** A Trecs observation.
    * @group Constructors
    */
  final case class Trecs(
    title: String,
    targetEnvironment: TargetEnvironment.Trecs,
    staticConfig: StaticConfig.Trecs,
    sequence: List[Step.Trecs]
  ) extends Observation

  /** A Nici observation.
    * @group Constructors
    */
  final case class Nici(
    title: String,
    targetEnvironment: TargetEnvironment.Nici,
    staticConfig: StaticConfig.Nici,
    sequence: List[Step.Nici]
  ) extends Observation

  /** A Nifs observation.
    * @group Constructors
    */
  final case class Nifs(
    title: String,
    targetEnvironment: TargetEnvironment.Nifs,
    staticConfig: StaticConfig.Nifs,
    sequence: List[Step.Nifs]
  ) extends Observation

  /** A Gpi observation.
    * @group Constructors
    */
  final case class Gpi(
    title: String,
    targetEnvironment: TargetEnvironment.Gpi,
    staticConfig: StaticConfig.Gpi,
    sequence: List[Step.Gpi]
  ) extends Observation

  /** A Gsaoi observation.
    * @group Constructors
    */
  final case class Gsaoi(
    title: String,
    targetEnvironment: TargetEnvironment.Gsaoi,
    staticConfig: StaticConfig.Gsaoi,
    sequence: List[Step.Gsaoi]
  ) extends Observation

  /** A GmosS observation.
    * @group Constructors
    */
  final case class GmosS(
    title: String,
    targetEnvironment: TargetEnvironment.GmosS,
    staticConfig: StaticConfig.GmosS,
    sequence: List[Step.GmosS]
  ) extends Observation

  /** A AcqCam observation.
    * @group Constructors
    */
  final case class AcqCam(
    title: String,
    targetEnvironment: TargetEnvironment.AcqCam,
    staticConfig: StaticConfig.AcqCam,
    sequence: List[Step.AcqCam]
  ) extends Observation

  /** A GmosN observation.
    * @group Constructors
    */
  final case class GmosN(
    title: String,
    targetEnvironment: TargetEnvironment.GmosN,
    staticConfig: StaticConfig.GmosN,
    sequence: List[Step.GmosN]
  ) extends Observation

  /** A Bhros observation.
    * @group Constructors
    */
  final case class Bhros(
    title: String,
    targetEnvironment: TargetEnvironment.Bhros,
    staticConfig: StaticConfig.Bhros,
    sequence: List[Step.Bhros]
  ) extends Observation

  /** A Visitor observation.
    * @group Constructors
    */
  final case class Visitor(
    title: String,
    targetEnvironment: TargetEnvironment.Visitor,
    staticConfig: StaticConfig.Visitor,
    sequence: List[Step.Visitor]
  ) extends Observation

  /** A Flamingos2 observation.
    * @group Constructors
    */
  final case class Flamingos2(
    title: String,
    targetEnvironment: TargetEnvironment.Flamingos2,
    staticConfig: StaticConfig.Flamingos2,
    sequence: List[Step.Flamingos2]
  ) extends Observation

  /** A Ghost observation.
    * @group Constructors
    */
  final case class Ghost(
    title: String,
    targetEnvironment: TargetEnvironment.Ghost,
    staticConfig: StaticConfig.Ghost,
    sequence: List[Step.Ghost]
  ) extends Observation

  /** An observation is identified by its program and a serial index. */
  final case class Id(pid: Program.Id, index: Index) {
    def format: String =
      s"${ProgramId.fromString.reverseGet(pid)}-${Index.fromString.reverseGet(index)}"
  }
  object Id {

    def fromString(s: String): Option[Observation.Id] =
      s.lastIndexOf('-') match {
        case -1 => None
        case  n =>
          val (a, b) = s.splitAt(n)
          Index.fromString.getOption(b.drop(1)).flatMap { i =>
            Program.Id.fromString.getOption(a).map(Observation.Id(_, i))
          }
      }

    def unsafeFromString(s: String): Observation.Id =
      fromString(s).getOrElse(sys.error("Malformed Observation.Id: " + s))

    /** Observations are ordered by program id and index. */
    implicit val OrderId: Order[Id] =
      Order.by(a => (a.pid, a.index))

    implicit val OrderingId: scala.math.Ordering[Id] =
      OrderId.toOrdering

    implicit val showId: Show[Id] =
      Show.fromToString

  }

  /** Assemble an Observation from its parts, assuming they're consistent. */
  def unsafeAssemble(
    title: String,
    targetEnvironment: TargetEnvironment,
    staticConfig: StaticConfig,
    sequence: List[Step]
  ): Observation = {

    implicit class SequenceOps(ss: List[Step]) {
      def narrow[A](pf: PartialFunction[Step, A]): List[A] =
        ss.collect(pf orElse {
          case _ => sys.error("inconsistent sequence contains multiple instruments")
        })
    }

    (targetEnvironment, staticConfig) match {
        case (te: TargetEnvironment.Phoenix,    sc: StaticConfig.Phoenix)    => Observation.Phoenix(   title, te, sc, sequence.narrow { case s: Step.Phoenix    => s })
        case (te: TargetEnvironment.Michelle,   sc: StaticConfig.Michelle)   => Observation.Michelle(  title, te, sc, sequence.narrow { case s: Step.Michelle   => s })
        case (te: TargetEnvironment.Gnirs,      sc: StaticConfig.Gnirs)      => Observation.Gnirs(     title, te, sc, sequence.narrow { case s: Step.Gnirs      => s })
        case (te: TargetEnvironment.Niri,       sc: StaticConfig.Niri)       => Observation.Niri(      title, te, sc, sequence.narrow { case s: Step.Niri       => s })
        case (te: TargetEnvironment.Trecs,      sc: StaticConfig.Trecs)      => Observation.Trecs(     title, te, sc, sequence.narrow { case s: Step.Trecs      => s })
        case (te: TargetEnvironment.Nici,       sc: StaticConfig.Nici)       => Observation.Nici(      title, te, sc, sequence.narrow { case s: Step.Nici       => s })
        case (te: TargetEnvironment.Nifs,       sc: StaticConfig.Nifs)       => Observation.Nifs(      title, te, sc, sequence.narrow { case s: Step.Nifs       => s })
        case (te: TargetEnvironment.Gpi,        sc: StaticConfig.Gpi)        => Observation.Gpi(       title, te, sc, sequence.narrow { case s: Step.Gpi        => s })
        case (te: TargetEnvironment.Gsaoi,      sc: StaticConfig.Gsaoi)      => Observation.Gsaoi(     title, te, sc, sequence.narrow { case s: Step.Gsaoi      => s })
        case (te: TargetEnvironment.GmosS,      sc: StaticConfig.GmosS)      => Observation.GmosS(     title, te, sc, sequence.narrow { case s: Step.GmosS      => s })
        case (te: TargetEnvironment.AcqCam,     sc: StaticConfig.AcqCam)     => Observation.AcqCam(    title, te, sc, sequence.narrow { case s: Step.AcqCam     => s })
        case (te: TargetEnvironment.GmosN,      sc: StaticConfig.GmosN)      => Observation.GmosN(     title, te, sc, sequence.narrow { case s: Step.GmosN      => s })
        case (te: TargetEnvironment.Bhros,      sc: StaticConfig.Bhros)      => Observation.Bhros(     title, te, sc, sequence.narrow { case s: Step.Bhros      => s })
        case (te: TargetEnvironment.Visitor,    sc: StaticConfig.Visitor)    => Observation.Visitor(   title, te, sc, sequence.narrow { case s: Step.Visitor    => s })
        case (te: TargetEnvironment.Flamingos2, sc: StaticConfig.Flamingos2) => Observation.Flamingos2(title, te, sc, sequence.narrow { case s: Step.Flamingos2 => s })
        case (te: TargetEnvironment.Ghost,      sc: StaticConfig.Ghost)      => Observation.Ghost(     title, te, sc, sequence.narrow { case s: Step.Ghost      => s })
        case _ => sys.error("inconsistent observation")
      }

  }

  implicit val EqObservation: Eq[Observation] =
    Eq.fromUniversalEquals

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy