Keys and Parameters

The library offers a flexible and typesafe means to create Parameters to store values like primitive types, collection types or domain specific types.

A Parameter is a Key and Value where the Value must be from a set of defined primitive types including binary data. The Value of a Parameter is always considered to be an Array of the type (i.e. if a single value is stored it is at array location 0). A Parameter is immutable; a modification to an existing Parameter will return a new instance.

A Value can also have Units, which must be of the defined types. See Units for more information. At this time Units are informational only–no calculation or conversion support is provided. Some systems may provide a key value with different units, and receiver can inspect the Units to make a decision on how to handle the value.

A ParameterSet is a Set of Parameter. Various other message types include a ParameterSet (e.g. Setup, Event). A key is unique in a ParameterSet since it is a Set.

How to Create a Parameter

  • choose an appropriate KeyType from the tables below for your language(Scala/Java).
  • calling the make method on KeyType and supplying a String keyName will return a suitably typed Key instance.
  • exploit the overloaded set and -> methods, which will allow you to store values of the based on chosen KeyType. e.g. JKeyType.BooleanKey will allow storing only java.lang.Boolean values.

Primitive Datatypes

Primitive Scala KeyType Java KeyType
Boolean KeyType.BooleanKey JKeyType.BooleanKey
Character KeyType.CharKey JKeyType.JCharKey
Byte KeyType.ByteKey JKeyType.ByteKey
Short KeyType.ShortKey JKeyType.ShortKey
Long KeyType.LongKey JKeyType.LongKey
Int KeyType.IntKey JKeyType.IntKey
Float KeyType.FloatKey JKeyType.FloatKey
Double KeyType.DoubleKey JKeyType.DoubleKey
String KeyType.StringKey JKeyType.StringKey
UtcTime KeyType.UTCTimeKey JKeyType.UTCTimeKey
TaiTime KeyType.TAITimeKey JKeyType.TAITimeKey
Scala
source// declare keyName
val s1: String = "encoder"

// making 3 keys
val k1: Key[Boolean] = KeyType.BooleanKey.make(s1)
val k2: Key[Short]   = KeyType.ShortKey.make("RandomKeyName")
val k3: Key[String]  = KeyType.StringKey.make(s1)

// storing a single value
val booleanParam: Parameter[Boolean] = k1.set(true)

// storing multiple values
val paramWithShorts1: Parameter[Short] = k2.set(1, 2, 3, 4)
val paramWithShorts3: Parameter[Short] = k2.setAll(Array[Short](1, 2, 3, 4))

// associating units
val weekDays: Array[String]            = Array("Sunday", "Monday", "Tuesday")
val paramWithUnits1: Parameter[String] = k3.setAll(weekDays)
val paramWithUnits2: Parameter[String] = k3.setAll(weekDays) withUnits Units.day

// default unit is NoUnits
assert(booleanParam.units === Units.NoUnits)

// set units explicitly on an existing Parameter
val paramWithUnits3: Parameter[Short] = paramWithShorts1.withUnits(Units.meter)

// retrieve values from Parameter
val allValues: Array[Short] = paramWithShorts1.values

// retrieve just top value
val head: Short = paramWithShorts1.head
Java
source//making 3 keys
String keyName = "encoder";
Key<Boolean> k1 = JKeyType.BooleanKey().make(keyName);
Key<Short> k2 = JKeyType.ShortKey().make(keyName, JUnits.NoUnits);
Key<String> k3 = JKeyType.StringKey().make(keyName, JUnits.day);

//storing a single value
Parameter<Boolean> booleanParam = k1.set(true);

//storing multiple values
Short[] shortArray = {1, 2, 3, 4};
Parameter<Short> paramWithManyShorts1 = k2.setAll(shortArray);
Parameter<Short> paramWithManyShorts2 = k2.set((short) 1, (short) 2, (short) 3, (short) 4);

//associating units
String[] weekDays = {"Sunday", "Monday", "Tuesday"};
Parameter<String> paramWithUnits1 = k3.setAll(weekDays);
Parameter<String> paramWithUnits2 = k3.setAll(weekDays).withUnits(JUnits.day);

//deault unit is NoUnits()
boolean hasDefaultUnit = booleanParam.units() == JUnits.NoUnits; //true

//set units explicitly on an existing Parameter
Parameter<Short> paramWithUnits3 = paramWithManyShorts1.withUnits(JUnits.meter);

//retrieve values from Parameter
Short[] allValues = (Short[]) paramWithManyShorts1.values();

//retrieve just top value
Short head = paramWithManyShorts1.head();

Arrays

Primitive Scala KeyType Java KeyType
ByteArray KeyType.ByteArrayKey JKeyType.ByteArrayKey
ShortArray KeyType.ShortArrayKey JKeyType.ShortArrayKey
LongArray KeyType.LongArrayKey JKeyType.LongArrayKey
IntArray KeyType.IntArrayKey JKeyType.IntArrayKey
FloatArray KeyType.FloatArrayKey JKeyType.FloatArrayKey
DoubleArray KeyType.DoubleArrayKey JKeyType.DoubleArrayKey
Scala
source// make some arrays
val arr1: Array[Double] = Array(1.0, 2.0, 3.0, 4.0, 5.0)
val arr2: Array[Double] = Array(10.0, 20.0, 30.0, 40.0, 50.0)

// keys
val filterKey: Key[ArrayData[Double]] = KeyType.DoubleArrayKey.make("filter")

// Store some values using helper class ArrayData
val p1: Parameter[ArrayData[Double]] = filterKey.set(ArrayData(arr1), ArrayData(arr2))
val p2: Parameter[ArrayData[Double]] = filterKey -> ArrayData(arr1 ++ arr2) withUnits Units.liter

// add units to existing parameters
val p1AsCount = p1.withUnits(Units.count)

// default unit is NoUnits
assert(p1.units === Units.NoUnits)

// retrieving values
val head: Array[Double]                 = p1.head.data.toArray
val allValues: Array[ArrayData[Double]] = p1.values
Java
source//make some arrays
Double[] arr1 = {1.0, 2.0, 3.0, 4.0, 5.0};
Double[] arr2 = {10.0, 20.0, 30.0, 40.0, 50.0};

//keys
Key<ArrayData<Double>> filterKey = JKeyType.DoubleArrayKey().make("filter", JUnits.NoUnits);

//Store some values using helper method in ArrayData
Parameter<ArrayData<Double>> p1 = filterKey.set(ArrayData.fromArray(arr1), ArrayData.fromArray(arr2));
Parameter<ArrayData<Double>> p2 = filterKey.set(ArrayData.fromArray(arr2)).withUnits(JUnits.liter);

//add units to existing parameters
Parameter<ArrayData<Double>> p1AsCount = p1.withUnits(JUnits.count);

//default unit is NoUnits()
boolean bDefaultUnit = JUnits.NoUnits == p1.units();

//retrieving values
List<Double> head = p1.head().jValues();
List<ArrayData<Double>> listOfArrayData = p1.jValues();
Double[] arrayOfDoubles = (Double[]) p2.jValues().get(0).values();

Matrices

Primitive Scala KeyType Java KeyType
ByteMatrix KeyType.ByteMatrixKey JKeyType.ByteMatrixKey
ShortMatrix KeyType.ShortMatrixKey JKeyType.ShortMatrixKey
LongMatrix KeyType.LongMatrixKey JKeyType.LongMatrixKey
IntMatrix KeyType.IntMatrixKey JKeyType.IntMatrixKey
FloatMatrix KeyType.FloatMatrixKey JKeyType.FloatMatrixKey
DoubleMatrix KeyType.DoubleMatrixKey JKeyType.DoubleMatrixKey
Scala
source// make some arrays
val m1: Array[Array[Byte]] = Array(Array[Byte](1, 2, 3), Array[Byte](4, 5, 6), Array[Byte](7, 8, 9))
val m2: Array[Array[Byte]] = Array(Array[Byte](1, 2, 3, 4, 5), Array[Byte](10, 20, 30, 40, 50))

// keys
val encoderKey: Key[MatrixData[Byte]] = KeyType.ByteMatrixKey.make("encoder")

// Store some values using helper class MatrixData
val p1: Parameter[MatrixData[Byte]] = encoderKey.set(MatrixData.fromArrays(m1))
val p2: Parameter[MatrixData[Byte]] = encoderKey.set(m1, m2) withUnits Units.liter

// add units to existing parameters
val p1AsLiter = p1.withUnits(Units.liter)

// default unit is NoUnits
assert(p1.units === Units.NoUnits)

// retrieving values
val head: Array[Array[Byte]]           = p1.head.data.map(_.toArray).toArray
val allValues: Array[MatrixData[Byte]] = p1.values
Java
source//make some arrays
Byte[][] m1 = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
Byte[][] m2 = {{1, 2, 3, 4, 5}, {10, 20, 30, 40, 50}};

//keys
Key<MatrixData<Byte>> encoderKey = JKeyType.ByteMatrixKey().make("encoder", JUnits.NoUnits);

//Store some values using helper method in ArrayData
Parameter<MatrixData<Byte>> p1 = encoderKey.set(
        MatrixData.fromArrays(m1),
        MatrixData.fromArrays(m2));
Parameter<MatrixData<Byte>> p2 = encoderKey.set(
        MatrixData.fromArrays(m2)
).withUnits(JUnits.liter);

//add units to existing parameters
Parameter<MatrixData<Byte>> p1AsLiter = p1.withUnits(JUnits.liter);

//default unit is NoUnits()
boolean bDefaultUnit = JUnits.NoUnits == p1.units();

//retrieving values
MatrixData<Byte> head = p1.head();
List<MatrixData<Byte>> matrixData1 = p1.jValues();
List<MatrixData<Byte>> matrixData2 = p2.jValues();

Domain Specific Types

Primitive Scala KeyType Java KeyType
Choice KeyType.ChoiceKey JKeyType.ChoiceKey

Coordinate Types

Primitive Scala KeyType Java KeyType
EqCoord KeyType.EqCoordKey JKeyType.EqCoordKey
SolarSystemCoord KeyType.SolarSystemCoordKey JKeyType.SolarSystemCoordKey
MinorPlanetCoord KeyType.MinorPlanetCoordKey JKeyType.MinorPlanetCoordKey
CometCoord KeyType.CometCoordKey JKeyType.CometCoordKey
AltAzCoord KeyType.AltAzCoordKey JKeyType.AltAzCoordKey
Coord (*) KeyType.CoordKey JKeyType.CoordKey
Note

Note that since Coord is the base trait of the other coordinate types, you can use it as the key for any of the coordinate types.

Coordinate Types Example

The following example demonstrates the basic usage of the coordinate parameter types:

Scala
sourceimport Angle._
import Coords._

// Coordinate types
val pm               = ProperMotion(0.5, 2.33)
val eqCoord          = EqCoord(ra = "12:13:14.15", dec = "-30:31:32.3", frame = FK5, pmx = pm.pmx, pmy = pm.pmy)
val solarSystemCoord = SolarSystemCoord(Tag("BASE"), Venus)
val minorPlanetCoord = MinorPlanetCoord(Tag("GUIDER1"), 2000, 90.degree, 2.degree, 100.degree, 1.4, 0.234, 220.degree)
val cometCoord       = CometCoord(Tag("BASE"), 2000.0, 90.degree, 2.degree, 100.degree, 1.4, 0.234)
val altAzCoord       = AltAzCoord(Tag("BASE"), 301.degree, 42.5.degree)

// Can use base trait CoordKey to store values for all types
val basePosKey = CoordKey.make("BasePosition")
val posParam   = basePosKey.set(eqCoord, solarSystemCoord, minorPlanetCoord, cometCoord, altAzCoord)

// retrieving values
assert(posParam.values.length == 5)
assert(posParam.values(0) == eqCoord)
assert(posParam.values(1) == solarSystemCoord)
assert(posParam.values(2) == minorPlanetCoord)
assert(posParam.values(3) == cometCoord)
assert(posParam.values(4) == altAzCoord)
Java
source
//import csw.params.core.models.Coords.*; //import static csw.params.core.models.JCoords.*; //import static csw.params.core.models.Coords.*; // Coordinate types ProperMotion pm = new ProperMotion(0.5, 2.33); EqCoord eqCoord = new EqCoord("12:13:14.15", "-30:31:32.3", FK5(), BASE(), DEFAULT_CATNAME(), pm.pmx(), pm.pmy()); SolarSystemCoord solarSystemCoord = new SolarSystemCoord(BASE(), Venus()); MinorPlanetCoord minorPlanetCoord = new MinorPlanetCoord(GUIDER1(), 2000, JAngle.degree(90), JAngle.degree(2), JAngle.degree(100), 1.4, 0.234, JAngle.degree(220)); CometCoord cometCoord = new CometCoord(BASE(), 2000.0, JAngle.degree(90), JAngle.degree(2), JAngle.degree(100), 1.4, 0.234); AltAzCoord altAzCoord = new AltAzCoord(BASE(), JAngle.degree(301), JAngle.degree(42.5)); // Can use base trait CoordKey to store values for all types Key<Coord> basePosKey = JKeyType.CoordKey().make("BasePosition", JUnits.NoUnits); Parameter<Coord> posParam = basePosKey.set(eqCoord, solarSystemCoord, minorPlanetCoord, cometCoord, altAzCoord); //retrieving values assert (posParam.jValues().size() == 5); assert (posParam.jValues().get(0).equals(eqCoord)); assert (posParam.jValues().get(1).equals(solarSystemCoord)); assert (posParam.jValues().get(2).equals(minorPlanetCoord)); assert (posParam.jValues().get(3).equals(cometCoord)); assert (posParam.jValues().get(4).equals(altAzCoord));

Struct

Struct got removed in 4.0.0 version.

Choice

A key for a choice item similar to an enumeration.

Scala
source// Choice
val choices = Choices.from("A", "B", "C")

// keys
val choice1Key: GChoiceKey = ChoiceKey.make("mode", NoUnits, choices)
val choice2Key: GChoiceKey = ChoiceKey.make(
  "mode-reset",
  NoUnits,
  Choices.fromChoices(Choice("c"), Choice("b"), Choice("a"))
)

// store values
val p1: Parameter[Choice] = choice1Key
  .setAll(Array(Choice("A")))
  .withUnits(Units.foot)
val p2: Parameter[Choice] = choice2Key.setAll(Array(Choice("c")))

// add units
val paramWithFoot = p1.withUnits(Units.foot)

// default unit is NoUnits
assert(p2.units === Units.NoUnits)

// retrieving values
val head: Choice          = p1.head
val values: Array[Choice] = p2.values
Java
source//Choice
final Choices choices = Choices.from("A", "B", "C");

//keys
GChoiceKey choice1Key = JKeyType.ChoiceKey().make("mode", JUnits.NoUnits, choices);
GChoiceKey choice2Key = JKeyType.ChoiceKey().make(
        "mode-reset", JUnits.NoUnits,
        Choices.fromChoices(
                new Choice("c"),
                new Choice("b"),
                new Choice("a")));

//store values
Parameter<Choice> p1 = choice1Key.set(new Choice("A")).withUnits(JUnits.foot);
Parameter<Choice> p2 = choice2Key.set(new Choice("c"));

//add units
Parameter<Choice> paramWithFoot = p1.withUnits(JUnits.foot);

//default unit is NoUnits()
boolean bDefaultUnit = JUnits.NoUnits == p2.units();

//retrieving values
Choice head = p1.head();
List<Choice> values = p2.jValues();

Source Code for Examples