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

lucuma.core.math.units.scala Maven / Gradle / Ivy

There is a newer version: 0.108.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.math

import coulomb.*
import coulomb.conversion.TruncatingUnitConversion
import coulomb.conversion.ValueConversion
import coulomb.define.*
import coulomb.syntax.*
import coulomb.units.accepted.*
import coulomb.units.mks.*
import coulomb.units.si.*
import coulomb.units.si.prefixes.*
import coulomb.units.time.*
import eu.timepit.refined.*
import eu.timepit.refined.api.Refined
import eu.timepit.refined.api.Validate
import eu.timepit.refined.auto.*
import eu.timepit.refined.numeric.*
import eu.timepit.refined.types.numeric.NonNegInt
import eu.timepit.refined.types.numeric.PosInt
import lucuma.core.util.TypeString
import lucuma.refined.*
import spire.math.*

trait units {

  type Electron
  given BaseUnit[Electron, "electron", "e-"] = BaseUnit()

  type Pixels
  given BaseUnit[Pixels, "pixels", "px"] = BaseUnit()

  // Wavelength units
  type Picometer  = Pico * Meter
  type Nanometer  = Nano * Meter
  type Micrometer = Micro * Meter
  type Angstrom
  given DerivedUnit[Angstrom, Hecto * Picometer, "angstrom", "Å"] = DerivedUnit()

  type NanometersPerPixel = Nanometer / Pixels
  type PicometersPerPixel = Picometer / Pixels

  type MetersPerSecond      = Meter / Second
  type CentimetersPerSecond = (Centi * Meter) / Second
  type KilometersPerSecond  = (Kilo * Meter) / Second

  type Year
  given DerivedUnit[Year, 365 * Day, "year", "y"] = DerivedUnit()

  type ArcSecond
  given DerivedUnit[ArcSecond, Degree / 3600, "arc second", "arcsec"] = DerivedUnit()

  type DeciArcSecond  = Deci * ArcSecond
  type MilliArcSecond = Milli * ArcSecond
  type MicroArcSecond = Micro * ArcSecond

  type MilliArcSecondPerYear = MilliArcSecond / Year
  type MicroArcSecondPerYear = MicroArcSecond / Year

  // Integrated Brightness units
  type VegaMagnitude
  given BaseUnit[VegaMagnitude, "Vega magnitude", "Vega mag"] = BaseUnit()
  given TypeString[VegaMagnitude] = TypeString("VEGA_MAGNITUDE")

  type ABMagnitude
  given BaseUnit[ABMagnitude, "AB magnitude", "AB mag"] = BaseUnit()
  given TypeString[ABMagnitude] = TypeString("AB_MAGNITUDE")

  type Jansky
  given DerivedUnit[Jansky, (10 ^ -26) * Watt / ((Meter ^ 2) * (Hertz ^ -1)), "Jansky", "Jy"] = DerivedUnit()
  given TypeString[Jansky] = TypeString("JANSKY")

  type WattsPerMeter2Micrometer
  given DerivedUnit[WattsPerMeter2Micrometer, Watt / ((Meter ^ 2) * Micrometer), "W/m²/µm", "W/m²/µm"] = DerivedUnit()
  given TypeString[WattsPerMeter2Micrometer] = TypeString("W_PER_M_SQUARED_PER_UM")

  type Erg
  given DerivedUnit[Erg, (10 ^ -7) * Joule, "erg", "erg"] = DerivedUnit()

  type ErgsPerSecondCentimeter2Angstrom
  given DerivedUnit[ErgsPerSecondCentimeter2Angstrom, Erg / (Second * (Centimeter ^ 2) * Hertz), "erg/s/cm²/Å", "erg/s/cm²/Å"] = DerivedUnit()
  given TypeString[ErgsPerSecondCentimeter2Angstrom] = TypeString("ERG_PER_S_PER_CM_SQUARED_PER_A")

  type ErgsPerSecondCentimeter2Hertz
  given DerivedUnit[ErgsPerSecondCentimeter2Hertz, Erg / (Second * (Centimeter ^ 2) * Hertz), "erg/s/cm²/Hz", "erg/s/cm²/Hz"] = DerivedUnit()
  given TypeString[ErgsPerSecondCentimeter2Hertz] = TypeString("ERG_PER_S_PER_CM_SQUARED_PER_HZ")

  // Surface Brightness units
  type VegaMagnitudePerArcsec2
  given DerivedUnit[VegaMagnitudePerArcsec2, VegaMagnitude / (ArcSecond ^ 2), "Vega mag/arcsec²", "Vega mag/arcsec²"] = DerivedUnit()
  given TypeString[VegaMagnitudePerArcsec2] = TypeString("VEGA_MAG_PER_ARCSEC_SQUARED")

  type ABMagnitudePerArcsec2
  given DerivedUnit[ABMagnitudePerArcsec2, ABMagnitude / (ArcSecond ^ 2), "AB mag/arcsec²", "AB mag/arcsec²"] = DerivedUnit()
  given TypeString[ABMagnitudePerArcsec2] = TypeString("AB_MAG_PER_ARCSEC_SQUARED")

  type JanskyPerArcsec2
  given DerivedUnit[JanskyPerArcsec2, Jansky / (ArcSecond ^ 2), "Jy/arcsec²", "Jy/arcsec²"] = DerivedUnit()
  given TypeString[JanskyPerArcsec2] = TypeString("JY_PER_ARCSEC_SQUARED")

  type WattsPerMeter2MicrometerArcsec2
  given DerivedUnit[WattsPerMeter2MicrometerArcsec2, WattsPerMeter2Micrometer / (ArcSecond ^ 2), "W/m²/µm/arcsec²", "W/m²/µm/arcsec²"] = DerivedUnit()
  given TypeString[WattsPerMeter2MicrometerArcsec2] = TypeString("W_PER_M_SQUARED_PER_UM_PER_ARCSEC_SQUARED")

  type ErgsPerSecondCentimeter2AngstromArcsec2
  given DerivedUnit[ErgsPerSecondCentimeter2AngstromArcsec2, ErgsPerSecondCentimeter2Angstrom / (ArcSecond ^ 2), "erg/s/cm²/Å/arcsec²", "erg/s/cm²/Å/arcsec²"] = DerivedUnit()
  given TypeString[ErgsPerSecondCentimeter2AngstromArcsec2] =
    TypeString("ERG_PER_S_PER_CM_SQUARED_PER_A_PER_ARCSEC_SQUARED")

  type ErgsPerSecondCentimeter2HertzArcsec2
  given DerivedUnit[ErgsPerSecondCentimeter2HertzArcsec2, ErgsPerSecondCentimeter2Hertz / (ArcSecond ^ 2), "erg/s/cm²/Hz/arcsec²", "erg/s/cm²/Hz/arcsec²"] = DerivedUnit()
  given TypeString[ErgsPerSecondCentimeter2HertzArcsec2] =
    TypeString("ERG_PER_S_PER_CM_SQUARED_PER_HZ_PER_ARCSEC_SQUARED")

  // Integrated Line Flux units
  type WattsPerMeter2
  given DerivedUnit[WattsPerMeter2, Watt / (Meter ^ 2), "W/m²", "W/m²"] = DerivedUnit()
  given TypeString[WattsPerMeter2] = TypeString("W_PER_M_SQUARED")

  type ErgsPerSecondCentimeter2
  given DerivedUnit[ErgsPerSecondCentimeter2, Erg / (Second * (Centimeter ^ 2)), "erg/s/cm²", "erg/s/cm²"] = DerivedUnit()
  given TypeString[ErgsPerSecondCentimeter2] = TypeString("ERG_PER_S_PER_CM_SQUARED")

  // Surface Line Flux units
  type WattsPerMeter2Arcsec2
  given DerivedUnit[WattsPerMeter2Arcsec2, WattsPerMeter2 / (ArcSecond ^ 2), "W/m²/arcsec²", "W/m²/arcsec²"] = DerivedUnit()
  given TypeString[WattsPerMeter2Arcsec2] = TypeString("W_PER_M_SQUARED_PER_ARCSEC_SQUARED")

  type ErgsPerSecondCentimeter2Arcsec2
  given DerivedUnit[ErgsPerSecondCentimeter2Arcsec2, ErgsPerSecondCentimeter2 / (ArcSecond ^ 2), "erg/s/cm²/arcsec²", "erg/s/cm²/arcsec²"] = DerivedUnit()
  given TypeString[ErgsPerSecondCentimeter2Arcsec2] =
    TypeString("ERG_PER_S_PER_CM_SQUARED_PER_ARCSEC_SQUARED")

  // PosInt can be converted to Rational exactly
  given rationalPosIntConverter: ValueConversion[PosInt, Rational] = Rational(_)

  given ValueConversion[NonNegInt, Double] = _.value.toDouble

  given ValueConversion[Parallax.LongParallaxμas, Rational] = Rational(_)

  given refinedValueConversion[V, P]: ValueConversion[V Refined P, V] = _.value

  given [UF, UT]: TruncatingUnitConversion[PosInt, UF, UT] = v =>
    refineV[Positive](coulomb.conversion.standard.unit.ctx_TUC_Int(v))
      .getOrElse(1.refined[Positive])

  extension [A](inline a: A)
    inline def withRefinedUnit[P, U](using inline p: Predicate[A, P]): Quantity[Refined[A, P], U] = refineMV(a).withUnit[U]

  inline def refineQV[R]: RefineQV[R] = RefineQV()

  final class RefineQV[P] {
    inline def apply[V, U](q: Quantity[V, U])(using Validate[V, P]): Either[String, Quantity[V Refined P, U]] = {
      refineV(q.value).map(_.withUnit[U])
    }
  }

}

object units extends units




© 2015 - 2024 Weber Informatics LLC | Privacy Policy