Events
Events are the most basic type of asynchronous notification in TMT when an activity occurs somewhere in the TMT system and other components need to be notified. Each type of event has a unique purpose and unique information, but they all share same structural features. All events have EventInfo and a ParameterSet.
The csw-params
library offers out of the box support to serialize Events using Cbor, so that events can be produced and consumed by JVM (Java virtual machine) as well as Non-JVM applications.
For more on Cbor, refer to the technical doc.
EventTime
Each event includes its time of creation in UTC format. You can access that eventTime as follows:
- Scala
-
source
val source = Prefix("iris.filter.wheel") val eventName = EventName("temperatures") val event = SystemEvent(source, eventName) // accessing eventTime val eventTime = event.eventTime
- Java
-
source
//apply returns current time in UTC UTCTime now = UTCTime.now(); //using constructor UTCTime anHourAgo = new UTCTime(Instant.now().minusSeconds(3600)); //return current time in UTC UTCTime currentTime = UTCTime.now(); //some past time using utility function UTCTime aDayAgo = new UTCTime(Instant.now().minusSeconds(86400));
System Event
SystemEvent
is the type used to describe the majority of events in the system. An example is a demand that is the output of an algorithm in one component that is used as an input to another. SystemEvent
is also used to publish internal state or status values of a component that may be of interest to other components in the system.
- Scala
-
source
// keys val k1: Key[Int] = KeyType.IntKey.make("encoder") val k2: Key[Int] = KeyType.IntKey.make("speed") val k3: Key[String] = KeyType.StringKey.make("filter") val k4: Key[Int] = KeyType.IntKey.make("notUsed") // prefixes val ck1 = Prefix("wfos.red.filter") val name1 = EventName("filterWheel") val ck3 = Prefix("iris.imager.filter") val name3 = EventName("status") // parameters val p1: Parameter[Int] = k1.set(22) val p2: Parameter[Int] = k2.set(44) val p3: Parameter[String] = k3.set("A", "B", "C", "D") // Create SystemEvent using madd val se1: SystemEvent = SystemEvent(ck1, name1).madd(p1, p2) // Create SystemEvent using apply val se2: SystemEvent = SystemEvent(ck3, name3, Set(p1, p2)) // Create SystemEvent and use add val se3: SystemEvent = SystemEvent(ck3, name3).add(p1).add(p2).add(p3) // access keys val k1Exists: Boolean = se1.exists(k1) // true // access Parameters val p4: Option[Parameter[Int]] = se1.get(k1) // access values val v1: Array[Int] = se1(k1).values val v2: Array[Int] = se2.parameter(k2).values // k4 is missing val missingKeys: Set[String] = se3.missingKeys(k1, k2, k3, k4) // remove keys val se4: SystemEvent = se3.remove(k3) // add more than one parameters, using madd val se5: SystemEvent = se4.madd(k3.set("X", "Y", "Z").withUnits(Units.day), k4.set(99, 100)) val paramSize: Int = se5.size // update existing key with set val se6: SystemEvent = se5.add(k2.set(5, 6, 7, 8))
- Java
-
source
//keys Key<Integer> k1 = JKeyType.IntKey().make("encoder", JUnits.encoder); Key<Integer> k2 = JKeyType.IntKey().make("speed"); Key<String> k3 = JKeyType.StringKey().make("filter"); Key<Integer> k4 = JKeyType.IntKey().make("notUsed"); //prefixes Prefix prefix1 = Prefix.apply(JSubsystem.WFOS, "red.filter"); EventName name1 = new EventName("filterWheel"); Prefix prefix2 = Prefix.apply(JSubsystem.IRIS, "imager.filter"); EventName name2 = new EventName("status"); //parameters Parameter<Integer> p1 = k1.set(22); Parameter<Integer> p2 = k2.set(44); Parameter<String> p3 = k3.set("A", "B", "C", "D"); //Create SystemEvent using madd SystemEvent se1 = new SystemEvent(prefix1, name1).madd(p1, p2); //Create SystemEvent using add SystemEvent se2 = new SystemEvent(prefix2, name2).add(p1).add(p2); //Create SystemEvent and use add SystemEvent se3 = new SystemEvent(prefix2, name2).add(p1).add(p2).add(p3); //access keys boolean k1Exists = se1.exists(k1); //true //access Parameters Optional<Parameter<Integer>> p4 = se1.jGet(k1); //access values List<Integer> v1 = se1.jGet(k1).orElseThrow().jValues(); List<Integer> v2 = se2.parameter(k2).jValues(); //k4 is missing Set<String> missingKeys = se3.jMissingKeys(k1, k2, k3, k4); //remove keys SystemEvent se4 = se3.remove(k3);
Observe Event
ObserveEvent are standardized events used to describe an activities within the data acquisition process. These events are typically published by Science Detector Assemblies, which emit ObserveEvents during their exposures to signal the occurrence of specific activities/actions during the acquisition of data. Observe Events serve the following purposes in OSW:
- Provide a TMT-standardized API for notification of activities in detector systems
- Provide TMT-standardized events that can be used to synchronize and trigger actions in other parts of the distributed software system
- Provide a standardized API to science and engineering detector systems to ease interfacing Sequencers
- Provide TMT-standardized APIs that can be more easily used by user interface programs that must deal with many detector systems
- Provide notification of actions that can be used to generate observatory efficiency metrics and time accounting
IR Science Detector Systems Observe Events
The Observe Events for IR science detector systems are based on the events proposed for the IRIS instrument at their PDR2. These events include Observe Events for actions.
A state and data event are defined to allow user interfaces and Sequencers to monitor and control with similar behavior across the observatory.
Observe Event | Description | Probable Publisher |
---|---|---|
observeStart | Indicates the start of execution of actions related to an Observe command | Instrument Sequencer or possibly OCS Sequencer |
exposureStart | Indicates the start of data acquisition that results in a file produced for DMS. This is a potential metadata event for DMS | Detector Assembly or possibly Instrument Sequencer |
exposureEnd | Indicates the end of data acquisition that results in a file produced for DMS. This is a potential metadata event for DMS | Detector Assembly or possibly Instrument Sequencer |
readoutEnd | Indicates that a readout that is part of a ramp has completed | Detector HCD or possibly Detector Assembly |
readoutFailed | Indicates that a readout that is part of a ramp has failed indicating transfer failure or some other issue | Detector HCD or possibly Detector Assembly |
dataWriteStart | Indicates that the instrument has started writing the exposure data file or transfer of exposure data to DMS. | Detector Assembly or possibly Detector HCD |
dataWriteEnd | Indicates that the instrument has finished writing the exposure data file or transfer of exposure data to DMS. | Detector Assembly or possibly Detector HCD |
exposureAbort | Indicates that a request was made to abort the exposure and it has completed. Normal data events should occur if data is recoverable. Abort should not fail | Detector Assembly or possibly Detector HCD |
observeEnd | Indicates the end of execution of actions related to an Observe command | Instrument Sequencer or possibly OCS Sequencer |
Two additional standardized events are defined to enable uniform detector information for Sequencers and user interfaces. These events are also based on the IRIS design.
IR Detector Exposure State Event
An exposure state Observe Event called irDetectorExposureState is provided as a state variable to indicate the current state of the detector system. The Exposure State Event groups parameters that change relatively slowly, and this event should be published whenever any of the parameters changes. The Exposure State Event includes the following mandatory parameters, but a detector system may add additional parameters as well. (The parameters in this event are based on the IRIS PDR2 model files.)
Parameters | Description |
---|---|
exposureId | ExposureId is an identifier in ESW/DMS for a single exposure. The ExposureId follows the structure: 2020A-001-123-WFOS-IMG1-SCI0-0001 with an included ObsId or when no ObsId is present, in the standalone format: 20200706-190204-WFOS-IMG1-SCI0-0001 with a UTC time when the ExposureId is created. |
exposureInProgress | A Boolean indicating if detector system is acquiring an exposure • Delimited by exposureStart and exposureEnd. exposureInProgress should be false if abortInProgress is true (TBD) |
abortInProgress | Indicates that an abort has been requested and is underway |
isAborted | Indicates that an abort has occurred and is completed. abortInProgress should be false when isAborted is true. isAborted should be set to false with the next exposure |
operationalState | Enumeration indicating if the detector system is available and operational. READY, NOT_READY, BUSY, ERROR. READY indicates system can execute exposures. NOT_READY indicates system cannot execute exposures. BUSY indicates system is BUSY most likely acquiring data. ERROR indicates the detector system is in an error state. This could happen as a result of a command or a spontaneous failure. Corrective action is required. |
errorMessage | An optional parameter that can be included when the detector system is in the ERROR operationalState. This value should be cleared and removed from the state when the operationalState returns to READY |
This event should be published whenever any of the state parameters change. Parameters such as errorMessage and isAborted should be cleared when a new exposure is started.
IR Detector Exposure Data Event
A second mandatory Observe Event named irDetectorExposureData contains fast-changing data about the internals of the current exposure. This data is useful for user interfaces and Sequencers. This event should be published at the read rate or 1 Hz (whichever is less) during an ongoing exposure.
Parameters | Description |
---|---|
exposureId | ExposureId is an identifier in ESW/DMS for a single exposure. The ExposureId follows the structure: 2020A-001-123-WFOS-IMG1-SCI0-0001 with an included ObsId or when no ObsId is present, in the standalone format: 20200706-190204-WFOS-IMG1-SCI0-0001 with a UTC time when the ExposureId is created. |
readsInRamp | The integer total number of reads in the ramp. Value should be constant during an exposure. (Note: for multi-array detectors, it is assumed that all arrays work with the same configuration). |
readsComplete | Integer number of current completed read from 1 to readsInRamp. Should be reset to 0 at the start of every ramp |
rampsInExposure | The integer total number of ramps in the current exposure. Value should be constant during an exposure |
rampsComplete | Integer number of completed ramp from 1 to rampsInExposure. Should be reset to 0 at the start of every exposure |
exposureTime | Length in seconds of the current exposure |
remainingExposureTime | Number of seconds remaining in current exposure • Should count down in seconds – no faster than 1 Hz |
Optical Science Detector Systems
The first light CCD-based instrument WFOS is not as advanced as IRIS and information in this section is based on author experience. The specific events may change in detail, but it is expected that what is presented here is adequate.
Optical detectors are often larger and somewhat simpler to control at the electronics level than IR detectors. Optical detector systems for astronomy often include several CCDs forming a mosaic that together cover the focal plane and are viewed as a single image. All the detectors operate in unison as a single detector system.
Optical detectors need to have shutters to control when light is collected on the detector. CCD based detectors accumulate photons/charge while the shutter is open and are read out after the shutter closes. Some modes such as nod and shuffle require more detailed control of the detector and system. (This is not covered here because TMT has not mentioned any modes such as this. The design may need to be extended to handle other ways of using the CCD.)
The optical science detector system Observe Events are largely identical to the IR science detector Observe Events
Observe Event | Description | Probable Publisher |
---|---|---|
observeStart | Indicates the start of execution of actions related to an Observe command | Instrument Sequencer or possibly OCS Sequencer |
prepareStart | Indicates that the detector system is preparing to start an exposure | Detector Assembly or possibly Instrument Sequencer |
exposureStart | Indicates the start of data acquisition that results in a file produced for DMS. This is a potential metadata event for DMS | Detector Assembly or possibly Instrument Sequencer |
exposureEnd | Indicates the end of data acquisition that results in a file produced for DMS. This is a potential metadata event for DMS | Detector Assembly or possibly Instrument Sequencer |
readoutEnd | Indicates that a readout that is part of a ramp has completed | Detector HCD or possibly Detector Assembly |
readoutFailed | Indicates that a readout that is part of a ramp has failed indicating transfer failure or some other issue | Detector HCD or possibly Detector Assembly |
dataWriteStart | Indicates that the instrument has started writing the exposure data file or transfer of exposure data to DMS. | Detector Assembly or possibly Detector HCD |
dataWriteEnd | Indicates that the instrument has finished writing the exposure data file or transfer of exposure data to DMS. | Detector Assembly or possibly Detector HCD |
exposureAbort | Indicates that a request was made to abort the exposure and it has completed. Normal data events should occur if data is recoverable. Abort should not fail | Detector Assembly or possibly Detector HCD |
observeEnd | Indicates the end of execution of actions related to an Observe command | Instrument Sequencer or possibly OCS Sequencer |
there is a question about whether observeStart and observeEnd are generated by the Instrument Sequencer or OCS Sequencer. Each observeStart and observeEnd is associated with an Observe command. If an instrument sequencer never receives more than one Observe, then the Observe Events can be published by the OCS Sequencer. Note that these events have required parameters, which are given in RD06
Two additional standardized events are defined to enable uniform detector information for Sequencers and user interfaces. These events are also based on the preceding sections.
Optical Detector Exposure State Event
An exposure state Observe Event called opticalDetectorExposureState is provided as a state variable to indicate the current state of the detector system. The Exposure State Event groups parameters that change relatively slowly, and this event should be published whenever any of its parameters changes. The Exposure State Event includes the following mandatory parameters (Table 3-4), but a detector system may add their own parameters as well. The optical and IR detector exposure state events are identical.
Parameters | Description |
---|---|
exposureId | ExposureId is an identifier in ESW/DMS for a single exposure. The ExposureId follows the structure: 2020A-001-123-WFOS-IMG1-SCI0-0001 with an included ObsId or when no ObsId is present, in the standalone format: 20200706-190204-WFOS-IMG1-SCI0-0001 with a UTC time when the ExposureId is created. |
exposureInProgress | A Boolean indicating if detector system is acquiring an exposure. Delimited by exposureStart and exposureEnd. exposureInProgress should be false if abortInProgress is true (TBD) |
abortInProgress | Indicates that an abort has been requested and is underway |
isAborted | Indicates that an abort has occurred and is completed. abortInProgress should be false when isAborted is true. isAborted should be set to false with the next exposure |
operationalState | Enumeration indicating if the detector system is available and operational. READY, NOT_READY, BUSY, ERROR. READY indicates system can execute exposures. NOT_READY indicates system cannot execute exposures. BUSY indicates system is BUSY most likely acquiring data. ERROR indicates the detector system is in an error state. This could happen as a result of a command or a spontaneous failure. Corrective action is required. |
errorMessage | An optional parameter that can be included when the detector system is in the ERROR operationalState. This value should be cleared and removed from the state when the operationalState returns to READY |
This event is standardized to allow ESW user interfaces to have minimal, uniform information about the state of any Science Detector System.
Optical Detector Exposure Data Event
A second mandatory Observe Event named opticalDetectorExposureData event contains faster changing data about the internals of the current exposure. This data is useful for user interfaces and Sequencers. This event should be published at 1 Hz during an ongoing exposure. This event does not have much information compared to the IR use case and is primarily for tracking the remaining current exposure time in user interfaces or sequencers.
Parameters | Description |
---|---|
exposureId | ExposureId is an identifier in ESW/DMS for a single exposure. The ExposureId follows the structure: 2020A-001-123-WFOS-IMG1-SCI0-0001 with an included ObsId or when no ObsId is present, in the standalone format: 20200706-190204-WFOS-IMG1-SCI0-0001 with a UTC time when the ExposureId is created. |
exposureTime | Length in seconds of the current exposure |
coaddsInExposure | The integer total number of coadds in the current exposure. Value should be constant during an exposure |
coaddsDone | Integer number of completed coadds from 1 to coaddsInExposure. Should be reset to 0 at the start of every exposure. |
remainingExposureTime | Number of seconds remaining in current exposure • Should count down in seconds – no faster than 1 Hz |
Wavefront Detector Systems
There are many detector systems in the TMT Software System that are not part of the science data chain. This section considers standardized events for wave front sensors and guider detectors that will need to be visualized by ESW user interfaces. The events described are made as simple as needed to enable this functionality.
Subsystem teams or TMT Systems Engineering will need to
determine if the subsystem wavefront detector images or guide
camera detector images need to be visualized or manipulated by
ESW user interfaces.
This Observe Event design is integrated with the ESW.VIZ subsystem (RD02), which allows systems to publish images on named streams in order to minimize impact on WFS and Guider Detector Systems. Within VIZ subsystems providing images can POST their images to a Transfer Service on a named stream. Other notes subscribe to the stream and receive the images when they are published.
The following are assumptions regarding WFS and Guider images in the TMT Software System.
- WFS and Guider images do not rely on header/metadata collection by DMS. WFS and Guider images will have headers, but the images from WFS and guiders are transient and are not persisted by DMS. A detector system creating a WFS or Guider image will create the header metadata itself or read values from the CSW Event Service.
- World Coordinate System for WFS and Guider images is determined independent of ESW or OSW. This is assumed because ESW has no way of determining the WCS parameters for WFS or Guider images. It is necessary that these systems create the WCS data themselves.
- WFS and Guider images are transient and are not written to or transferred to the DMS as with science and calibration images. There are no requirements to automatically save images of this type unless specifically requested.
- Some WFS/Guider images may occasionally be saved for diagnostic purposes. The DMS will allow blob data to be stored and associated with specific key-words. But these images would be in the Engineering Database and will not be in the science archive. These images would be captured and stored through the action of a user.
- WFS and Guider images are not associated with observer observations or proposals. Science images are associated with science programs and observations. This is not needed for WFS and Guider images and isn’t supported.
A subsystem publishing an image to a VIZ stream indicates success or failure.
Observe Event | Description | Probable Publisher |
---|---|---|
publishSuccess | Indicates the WFS or guider detector system has successfully published an image to VBDS | VBDS Transfer Service or possibly Detector Assembly |
publishFailed | Indicates that a WFS or guider detector system has failed while publishing an image to VBDS | Detector Assembly or possibly VBDS Transfer |
WFS and Guider Detector Exposure State Event
An exposure state Observe Event called wfsDetectorExposureState is provided as a state variable to indicate the current state of the wavefront sensor or guider detector system. The Exposure State Event groups parameters that change relatively slowly, and this event should be published whenever any of its parameters changes.
The Exposure State Event includes the following mandatory parameters, but a detector system may add their own as well.
Parameters | Description |
---|---|
exposureId | ExposureId is an identifier in ESW/DMS for a single exposure. The ExposureId follows the structure: 2020A-001-123-WFOS-IMG1-SCI0-0001 with an included ObsId or when no ObsId is present, in the standalone format: 20200706-190204-WFOS-IMG1-SCI0-0001 with a UTC time when the ExposureId is created. |
exposureInProgress | A Boolean indicating if detector system is acquiring an exposure • Delimited by exposureStart and exposureEnd. exposureInProgress should be false if abortInProgress is true (TBD) |
abortInProgress | Indicates that an abort has been requested and is underway |
isAborted | Indicates that an abort has occurred and is completed. abortInProgress should be false when isAborted is true. isAborted should be set to false with the next exposure |
operationalState | Enumeration indicating if the detector system is available and operational. READY, NOT_READY, BUSY, ERROR. READY indicates system can execute exposures. NOT_READY indicates system cannot execute exposures. BUSY indicates system is BUSY most likely acquiring data. ERROR indicates the detector system is in an error state. This could happen as a result of a command or a spontaneous failure. Corrective action is required. |
errorMessage | An optional parameter that can be included when the detector system is in the ERROR operationalState. This value should be cleared and removed from the state when the operationalState returns to READY |
This event is standardized to allow ESW user interfaces to have minimal, uniform information about the state of any WFS or Guider Detector system.
WFS and Guider Detector Exposure Data Event
At this time there is no WFS and Guider Detector Exposure Event. Any specific telemetry for these detector systems is available in their API model files and will not at this time be standardized.
Sequencers
Moving up from the acquisition of science detector data, it is necessary to have events that indicate activities for each observation and the acquisition process. The overall execution of an observation’s science Sequence is under the control of the master sequencer of ESW.OCS. During the acquisition process there may be additional OCS Sequencers that control the overall acquisition process. Regardless, the OCS Sequencer publishes Observe Events.
There are quite a few Observe Events related to the acquisition process as defined in the workflows (RD07) by the three phases:
- Preset – moving the telescope and subsystems to point to the sky coordinates of the observation and configurating all the other subsystems needed for the observation.
- Guide Star Acquisition – locking the telescope to the sky, closing loops, and delivering the telescope to the predefined hotspot needed for the science observation.
- Science Target Acquisition – any additional adjustments specific to a science observation needed after the previous phase.
The following table shows the events related to the overall observation and its acquisition
Observe Event | Description | Probable Publisher |
---|---|---|
observationStart | Indicates the start of execution of actions related to an observation including acquisition and science data acquisition | OCS Sequencer |
presetStart | Indicates the start of the preset phase of acquisition | OCS Sequencer |
presetEnd | Indicates the end of the preset phase of acquisition | OCS Sequencer |
guidestarAcqStart | Indicates the start of locking the telescope to the sky with guide and WFS targets | OCS Sequencer |
guidestarAcqEnd | Indicates the end of locking the telescope to the sky with guide and WFS targets | OCS Sequencer |
scitargetAcqStart | Indicates the start of acquisition phase where science target is peaked up as needed after guidestar locking | OCS Sequencer |
offsetStart | Indicates indicates the start of a telescope offset or dither | OCS Sequencer |
offsetEnd | Indicates indicates the end of a telescope offset or dither | OCS Sequencer |
scitargetAcqEnd | Indicates the end of acquisition phase where science target is centered as needed after guidestar locking | OCS Sequencer |
observeStart | Indicates the start of execution of actions related to an Observe command | OCS Sequencer |
EXPOSURE OBSERVE EVENTS DISCUSSED IN IR Science Detector Systems Observe Events/Wavefront Detector Systems OCCUR HERE | ||
observeEnd | Indicates the end of execution of actions related to an Observe command | OCS Sequencer |
observationEnd | Indicates the end of execution of actions related to an observation including acquisition and science data acquisition. | OCS Sequencer |
observePaused | Indicates that a user has paused the current observation Sequence which will happen after the current step concludes | OCS Sequencer |
observeResumed | Indicates that a user has resumed a paused observation Sequence | OCS Sequencer |
downtimeStart | Indicates that something has occurred that interrupts the normal observing workflow and time accounting. This event will have a hint (TBD) that indicates the cause of the downtime for statistics. Examples are: weather, equipment or other technical failure, etc. Downtime is ended by the start of an observation or exposure | OCS Sequencer |
inputRequestStart | Indicates the start of a request to the user for input | OCS Sequencer |
inputRequestEnd | Indicates the end of a request for user input | OCS Sequencer |
Downtime Considerations
The downtimeStart Observe Event is provided to allow the operator to indicate that there is a problem that is hindering the normal observing workflow. The event includes a category that the downtime will be associated with. Common examples are weather or equipment failure. The categories and usage will be worked out at a later time. Sometimes metrics and statistics subtract the time associated with weather loss or technical failures. It is challenging to assign downtime algorithmically. We anticipate that the telescope observing assistant will assign a category through a user interface program provided by ESW.HCMS. The downtime will be started by the downtimeStart event and ended by the next observationStart or exposureStart event.
How to create any observe event
The following snippet shows how to create a observe event
- Scala
-
source
val obsId = ObsId("1234A-001-0123") val prefix = Prefix("tcs.pk") val wfsObserveEvent: ObserveEvent = WFSDetectorEvent.publishSuccess(prefix) val irObserveEvent: ObserveEvent = IRDetectorEvent.observeStart(prefix, obsId) val opdObserveEvent: ObserveEvent = OpticalDetectorEvent.observeStart(prefix, obsId)
- Java
-
source
//prefixes Prefix prefix1 = Prefix.apply(JSubsystem.TCS, "pk"); EventName name1 = new EventName("targetCoords"); Prefix prefix2 = Prefix.apply(JSubsystem.TCS, "cm"); EventName name2 = new EventName("guiderCoords"); //Key Key<Coords.SolarSystemCoord> planets = JKeyType.SolarSystemCoordKey().make("planets", JUnits.NoUnits); //values Coords.SolarSystemCoord planet1 = new Coords.SolarSystemCoord(new Coords.Tag("solar1"), JCoords.Jupiter()); Coords.SolarSystemCoord planet2 = new Coords.SolarSystemCoord(new Coords.Tag("solar2"), JCoords.Venus()); //parameters Parameter<Coords.SolarSystemCoord> param = planets.set(planet1, planet2); //events ObserveEvent observeEvent = IRDetectorEvent.observeStart(prefix1, ObsId.apply("1234A-123-124"));
JSON Serialization
Events can be serialized to JSON. The library has provided JsonSupport helper class and methods to serialize Status, Observe and System events.
- Scala
-
source
import play.api.libs.json.{JsValue, Json} // key val k1: Key[MatrixData[Double]] = DoubleMatrixKey.make("myMatrix") val name1 = EventName("correctionInfo") val prefix = Prefix("aoesw.rpg") // values val m1: MatrixData[Double] = MatrixData.fromArrays( Array(1.0, 2.0, 3.0), Array(4.1, 5.1, 6.1), Array(7.2, 8.2, 9.2) ) // parameter val i1: Parameter[MatrixData[Double]] = k1.set(m1) // events val observeEvent: ObserveEvent = IRDetectorEvent.observeStart(prefix, ObsId("1232A-123-123")).madd(i1) val systemEvent: SystemEvent = SystemEvent(prefix, name1).add(i1) // json support - write val observeJson: JsValue = JsonSupport.writeEvent(observeEvent) val systemJson: JsValue = JsonSupport.writeEvent(systemEvent) // optionally prettify val str: String = Json.prettyPrint(systemJson) // construct command from string val systemEventFromPrettyStr: SystemEvent = JsonSupport.readEvent[SystemEvent](Json.parse(str)) // json support - read val observeEvent1: ObserveEvent = JsonSupport.readEvent[ObserveEvent](observeJson) val systemEvent1: SystemEvent = JsonSupport.readEvent[SystemEvent](systemJson)
- Java
-
source
//key Key<MatrixData<Double>> k1 = JKeyType.DoubleMatrixKey().make("myMatrix"); //prefixes Prefix prefix1 = Prefix.apply(JSubsystem.AOESW, "rpg"); EventName name1 = new EventName("correctionInfo"); //values Double[][] doubles = {{1.0, 2.0, 3.0}, {4.1, 5.1, 6.1}, {7.2, 8.2, 9.2}}; MatrixData<Double> m1 = MatrixData.fromArrays(doubles); //parameter Parameter<MatrixData<Double>> i1 = k1.set(m1); //events ObserveEvent observeEvent = IRDetectorEvent.observeStart(prefix1, ObsId.apply("1234A-123-124")); SystemEvent systemEvent = new SystemEvent(prefix1, name1).add(i1); //json support - write JsValue observeJson = JavaJsonSupport.writeEvent(observeEvent); JsValue systemJson = JavaJsonSupport.writeEvent(systemEvent); //optionally prettify String str = Json.prettyPrint(systemJson); //construct DemandState from string SystemEvent statusFromPrettyStr = JavaJsonSupport.readEvent(Json.parse(str)); //json support - read ObserveEvent observeEvent1 = JavaJsonSupport.readEvent(observeJson); SystemEvent systemEvent1 = JavaJsonSupport.readEvent(systemJson);
Unique Key Constraint
By choice, a ParameterSet in either ObserveEvent or SystemEvent event will be optimized to store only unique keys. When using add
or madd
methods on events to add new parameters, if the parameter being added has a key which is already present in the paramSet
, the already stored parameter will be replaced by the given parameter.
If the Set
is created by component developers and given directly while creating an event, then it will be the responsibility of component developers to maintain uniqueness with parameters based on key.
Here are some examples that illustrate this point:
- Scala
-
source
// keys val encoderKey: Key[Int] = KeyType.IntKey.make("encoder") val filterKey: Key[Int] = KeyType.IntKey.make("filter") val miscKey: Key[Int] = KeyType.IntKey.make("misc") // prefix val prefix = Prefix("wfos.blue.filter") val name1 = EventName("filterWheel") // params val encParam1 = encoderKey.set(1) val encParam2 = encoderKey.set(2) val encParam3 = encoderKey.set(3) val filterParam1 = filterKey.set(1) val filterParam2 = filterKey.set(2) val filterParam3 = filterKey.set(3) val miscParam1 = miscKey.set(100) // StatusEvent with duplicate key via constructor val systemEvent = SystemEvent(prefix, name1, Set(encParam1, encParam2, encParam3, filterParam1, filterParam2, filterParam3)) // four duplicate keys are removed; now contains one Encoder and one Filter key val uniqueKeys1 = systemEvent.paramSet.toList.map(_.keyName) // try adding duplicate keys via add + madd val changedStatusEvent = systemEvent .add(encParam3) .madd( filterParam1, filterParam2, filterParam3 ) // duplicate keys will not be added. Should contain one Encoder and one Filter key val uniqueKeys2 = changedStatusEvent.paramSet.toList.map(_.keyName) // miscKey(unique) will be added; encoderKey(duplicate) will not be added val finalStatusEvent = systemEvent.madd(Set(miscParam1, encParam1)) // now contains encoderKey, filterKey, miscKey val uniqueKeys3 = finalStatusEvent.paramSet.toList.map(_.keyName)
- Java
-
source
//keys Key<Integer> encoderKey = JKeyType.IntKey().make("encoder", JUnits.encoder); Key<Integer> filterKey = JKeyType.IntKey().make("filter"); Key<Integer> miscKey = JKeyType.IntKey().make("misc"); //prefix Prefix prefix1 = Prefix.apply(JSubsystem.WFOS, "blue.filter"); EventName name1 = new EventName("filterWheel"); //params Parameter<Integer> encParam1 = encoderKey.set(1); Parameter<Integer> encParam2 = encoderKey.set(2); Parameter<Integer> encParam3 = encoderKey.set(3); Parameter<Integer> filterParam1 = filterKey.set(1); Parameter<Integer> filterParam2 = filterKey.set(2); Parameter<Integer> filterParam3 = filterKey.set(3); Parameter<Integer> miscParam1 = miscKey.set(100); //StatusEvent with duplicate key via madd SystemEvent event = new SystemEvent(prefix1, name1).madd( encParam1, encParam2, encParam3, filterParam1, filterParam2, filterParam3); //four duplicate keys are removed; now contains one Encoder and one Filter key Set<String> uniqueKeys1 = event.jParamSet().stream().map(Parameter::keyName).collect(Collectors.toUnmodifiableSet()); //try adding duplicate keys via add + madd SystemEvent changedEvent = event.add(encParam3).madd(filterParam1, filterParam2, filterParam3); //duplicate keys will not be added. Should contain one Encoder and one Filter key Set<String> uniqueKeys2 = changedEvent.jParamSet().stream().map(Parameter::keyName).collect(Collectors.toUnmodifiableSet()); //miscKey(unique) will be added; encoderKey(duplicate) will not be added SystemEvent finalEvent = changedEvent.madd(miscParam1, encParam1); //now contains encoderKey, filterKey, miscKey Set<String> uniqueKeys3 = finalEvent.jParamSet().stream().map(Parameter::keyName).collect(Collectors.toUnmodifiableSet());