Trait observation API
This describes the updates to the API handling crop trait observations and observation data.
-
Method
is the primary mechanism that groups trait data and provides the context about the experiment. -
CropTrait
defines a trait and may optionally have a limited set ofCropTraitCodes
that are allowed
It is best to imagine that Method
represents a spreadsheet where columns are CropTraits
and rows are Inventories
(trait x
inventory).
Each cell in this table contains one or more CropTraitObservations
.
-
CropTraitObservation
contains one result of the observation. There can be multiple CTO for one traitx
inventory. -
CropTraitObservationData
contains the raw data traitx
inventoryx
individual.
Link between CTO and CTOD
CropTraitObservationData
records the detailed trait observations of different individuals of one inventory and there are usually many CTOD records for one inventory
and cropTrait
in one method
.
The CTOD#cropTraitObservation
is required, so a CTOD record cannot exist without a corresponding CTO.
The CTOD#cropTraitObservation
is not required and a CTOD record can exist without a corresponding CTO.
CTOD observations may be captured under a different CropTrait
(e.g. numerical/quantitative values) while the corresponding CTO could be a coded trait.
There is no direct link between ctod
and cto
records. The following is incorrect:
Regardless, must ensure that:
ctod.method == cto.method
ctod.inventory == cto.inventory
ctod.cropTrait == cto.cropTrait
ctod.cropTraitCode == cto.cropTraitCode
(can be null if theCropTrait
is not using codes)ctod.cropTraitCode.cropTrait == cto.cropTraitCode.cropTrait
(I think we handle that in@PrePersist/@PreUpdate
already)
update(CropTraitObservation)
CTO: The implementation of create
and delete
methods for CTO remains the same. The update(CTO)
method is updated and behaves as following:
The following is incorrect:
- If there exist 0 CTOD for this
cto
, just update thecto
If there exists at least 1 CTOD for thiscto
then updatecto
only ifmethod
,inventory
,cropTrait
andcropTraitCode
match the firstctod
- Refuse to update CTO if there are any CTOD records linked to it -- CTO value must be generated from CTODs.
create(CropTraitObservationData)
and update(CropTraitObservationData)
CTOD: The following is incorrect:
To ensure thatCTO
andCTOD
records are properly linked together, the API must ignore the incomingctod.cropTraitObservation
. The actualCTO
is calculated by loading existing CTO records byctod.method
,inventory
andcropTrait
because multiple records are possible according to unique constraint on the table for differentcrop_trait_code_id
,numeric_value
andstring_value
.
Every time a CTOD is created/updated/removed the server will recalculate CTO records based on all existing CTODs. This means thatCTOD#cropTraitObservation
may change as a result of CTOD modifications.
create(ctod)
must assert thatctod.cropTraitObservation == null
. Similarly,update(ctod)
must assert thatctod.cropTraitObservation == null
.
Generating CTOs from CTODs
GGCE API is able to generate and propose CTO records calculated from CTODs. The user still needs to review and add them manually.