plantbreeding / BrAPI

Repository for version control of the BrAPI specifications
https://brapi.org
MIT License
57 stars 32 forks source link

Support crosses in BrAPI #265

Closed bauchetg closed 2 years ago

bauchetg commented 6 years ago

for first developments see: https://github.com/trife/Hackathon/issues/38

bauchetg commented 6 years ago

Summary of existing brapi germplasm/pedigree and why we need a cross specific call, two use cases are detailed, a minimal (cross info) and extended (cross + metadata) version. brapi_cross_call_elements.xlsx

bauchetg commented 6 years ago

Three components:

1- Cross experiment project, project id, location, description 2- Cross project id, cross name (family name=(stockprop same as crossname)), cross type, parent1, parent2, parent1type, parent2 type, observationUnite(plot/plant, accession (need year and description)) 3- Cross info Cross name, cross ID, cross info (nested id for different cvterms for wishlist), progeny (cross id to fetch parents)

BrapiCoordinatorSelby commented 6 years ago

Crossing Plan Obj


{
    CrossingPlanDbId: "abc123",
    CrossingPlanName: "New Plan",
    CrossType: "(Diallel, Polycross, etc)"
    active: true,
    females: [
        {
            FemaleObservationUnitDbId: 23546
            FemaleObservationUnitName: 12-1201K-1_R12C10_Plot142
            FemaleGermplasmDbId: ak2jd3s4flkskj
            FemaleGermplasmName: Female_1
            MaleCount: 3
            Males:[
                {
                    MaleObservationUnitDbId: null
                    MaleObservationUnitName: null
                    MaleGermplasmName: Male1
                    MaleGermplasmDbId: foobar1
                    priorety: 1
                },
                {
                    MaleObservationUnitDbId: 23546
                    MaleObservationUnitName: 12-1201K-1_R12C10_Plot142
                    MaleGermplasmName: Male2
                    MaleGermplasmDbId: barbaz2
                    priorety: 3
                },
                {
                    MaleObservationUnitDbId: 23546
                    MaleObservationUnitName: 12-1201K-1_R12C10_Plot143
                    MaleGermplasmName: Male3
                    MaleGermplasmDbId: foobaz3
                    priorety: 2
                }
            ]
        }
    ]
}
BrapiCoordinatorSelby commented 6 years ago

Submit New Cross data

[
    {
        studyDbId, (or CrossingProjectDbId): "abc123",
        crossName (family name=(stockprop same as crossname)): "01012018FEMALE1X01012018MALE1", 
        crossType: "Bi-parental, self, OP, etc", 
        parent1GermplasmDbId: "12345",
        parent1ObservationUnitDbId: "23456",
        parent1Type: "FEMALE", 
        parent2GermplasmDbId: "98765",
        parent2ObservationUnitDbId: "87654",
        parent2Type: "MALE", 
        pollinationTimeStamp: "20180101T11:11:11.12Z"
    },
]
nickmorales commented 6 years ago

The crossing plan object you posted above is useful as an input for cross collection applications like the ODK BTract and Android apps, but i don't think it describes actual crosses well.

Like Guillaume posted above, the three parts could be formatted in an object like:

{
  'crossingProjectDbId' : '1001',
  'crossingProjectName': 'myIbadanCrosses2018',
  'crossingProjectDescription': 'Crosses between germplasm X and germplasm Y in male nursery study X2018 and female nursery study Y2018',
  'programDbId': '10',
  'programName': 'IITA',
  'crosses': [
    {
      'crossDbId': '20020',
      'crossName': 'myIbadanCrosses2018_01',
      'crossType': 'biparental',
      'parent1GermplasmDbId': "12345",
      'parent1GermplasmName': "TME419",
      'parent1ObservationUnitDbId': "23456",
      'parent1ObservationUnitName': "myIbadanPlot9001",
      'parent1Type': "FEMALE", 
      'parent2GermplasmDbId': "98765",
      'parent2GermplasmName': "myGermplasmName01",
      'parent2ObservationUnitDbId': "87654",
      'parent2ObservationUnitName': "myIbadanPlot9002",
      'parent2Type': "MALE", 
      'pollinationTimeStamp': "20180101T11:11:11.12Z",
      'crossInfo': [
        {
          'type': 'NumberOfSeeds',
          'value': '9'
        },
        {
          'type': 'myCrossAtrribute',
          'value': 'great'
        }
      ]
    }
  ]
}
BrapiCoordinatorSelby commented 5 years ago

From Wageningen Hackathon GET /corssingprojects

GET /corssingprojects/DbId

GET /corssingprojects/DbId/plan

GET /corssingprojects/DbId/crosses

POST /corssingprojects/DbId/crosses

imilne commented 5 years ago

The dangers of cut and paste...

bauchetg commented 5 years ago

Defining better the set of 'crossType' to be covered, namely: -> biparental: An individual plant pollinated by another individual plant. -> self: A self pollinated individual plant. -> open pollinated: An individual plant pollinated by a group of plants or open pollinated (pollen may be from a group with known or unknown members). -> bulk: A group of plants (usually a related family) pollinated by an individual plant. -> bulk selfed: A group of plants (usually a related family) that are self pollinated (each individual selfed, not combined pollen). -> bulk and open pollinated: A group of plants (usually a related family) that are pollinated by another group of plants or open pollinated (pollen may be from a group with known or unknown members). -> doubled haploid: Plants derived from doubling the chromosome number of haploid tissue.

bellerbrock commented 5 years ago

Thanks for linking to this @bauchetg. A POST call for crossing data will be very helpful

Two things that aren't clear to me from the plan: What's the distinction between family and cross, and what's the distinction between cross and pollination? In a way they are 3 separate concepts and would need to be tracked differently.

Say you have a crossing project, lets call it 19Nursery, and in it you plan to do a biparental cross using Accession1 as female and Accession2 as male.

Within the project you give that cross the name 19Nursery_Accession1xAccession2. But the family Accession1xAccession2 is not unique to the project - you may use the same combination of parents in next year's nursery and the years after that. Some data you'd want to track within the project at the cross level, other data you might want to aggregate across projects at the family level.

Then for a cross within the project, what does the 'pollinationTimeStamp' indicate? In all cases I'm aware of there will be multiple pollinations for the cross 19Nursery_Accession1xAccession2. You might pollinate 5 Accession1 flowers a day using Accession2 pollen, and continue the process over many weeks. Should BrAPI track a unique pollination name 19Nursery_Accession1xAccession2.001, 19Nursery_Accession1xAccession2.002, etc. for each one? If it does, then each would have a timestamp, and later on a measurement of whether the pollination was a success or not.

bauchetg commented 5 years ago

Draft cross calls from hackathon:

required calls

###############

GET /crossingprojects

returns array of Crossing Project objects

GET /crossingprojects/DbId

{ 'crossingPlanDbId' : '1001', 'crossingPlan': 'myCrosses2018plan', 'crossingPlanDescription': 'list of crosses planned in nursery study 2018', 'crossingProjectDbId' : '1001', 'crossingProjectName': 'myIbadanCrosses2018', 'crossingProjectDescription': 'Crosses between germplasm X and germplasm Y in male nursery study X2018 and female nursery study Y2018', 'programDbId': '10', 'programName': 'IITA', 'crossplan': [ { 'crossPlanDbId': '20020', 'crossPlanName': 'myIbadanCrosses2018_01', 'crossPlanType': 'biparental', 'parent1GermplasmDbId': "12345", 'parent1GermplasmName': "TME419", 'parent1ObservationUnitDbId': "23456", 'parent1ObservationUnitName': "myIbadanPlot9001", 'parent1Type': "FEMALE", 'parent2GermplasmDbId': "98765", 'parent2GermplasmName': "myGermplasmName01", 'parent2ObservationUnitDbId': "87654", 'parent2ObservationUnitName': "myIbadanPlot9002", 'parent2Type': "MALE", } ] 'crosses': [ { 'crossDbId': '20020', 'crossName': 'myIbadanCrosses2018_01', 'crossType': 'biparental', 'parent1GermplasmDbId': "12345", 'parent1GermplasmName': "TME419", 'parent1ObservationUnitDbId': "23456", 'parent1ObservationUnitName': "myIbadanPlot9001", 'parent1Type': "FEMALE", 'parent2GermplasmDbId': "98765", 'parent2GermplasmName': "myGermplasmName01", 'parent2ObservationUnitDbId': "87654", 'parent2ObservationUnitName': "myIbadanPlot9002", 'parent2Type': "MALE", 'pollinationTimeStamp': "20180101T11:11:11.12Z", 'crossInfo': [ { 'type': 'NumberOfSeeds', 'value': '9' }, { 'type': 'myCrossAtrribute', 'value': 'great' } ] } ] }

GET /crossingprojects/DbId/plan

{ 'crossingPlanDbId' : '1001', 'crossingPlan': 'myCrosses2018plan', 'crossingPlanDescription': 'list of crosses planned in nursery study 2018', 'programDbId': '10', 'programName': 'IITA', 'crosses': [ { 'crossPlanDbId': '20020', 'crossPlanName': 'myIbadanCrosses2018_01', 'crossPlanType': 'biparental', 'crossPriority': '1', 'parent1GermplasmDbId': "12345", 'parent1GermplasmName': "TME419", // 'parent1ObservationUnitDbId': "23456", // 'parent1ObservationUnitName': "myIbadanPlot9001", 'parent1Type': "FEMALE", 'parent2GermplasmDbId': "98765", 'parent2GermplasmName': "myGermplasmName01", // 'parent2ObservationUnitDbId': "87654", // 'parent2ObservationUnitName': "myIbadanPlot9002", 'parent2Type': "MALE", } ] }

GET /crossingprojects/DbId/crosses

{ 'crossingProjectDbId' : '1001', 'crossingProjectName': 'myIbadanCrosses2018', 'crossingProjectDescription': 'Crosses between germplasm X and germplasm Y in male nursery study X2018 and female nursery study Y2018', 'programDbId': '10', 'programName': 'IITA', 'crosses': [ { 'crossDbId': '20020', 'crossName': 'myIbadanCrosses2018_01', 'crossType': 'biparental', 'parent1GermplasmDbId': "12345", 'parent1GermplasmName': "TME419", 'parent1ObservationUnitDbId': "23456", 'parent1ObservationUnitName': "myIbadanPlot9001", 'parent1Type': "FEMALE", 'parent2GermplasmDbId': "98765", 'parent2GermplasmName': "myGermplasmName01", 'parent2ObservationUnitDbId': "87654", 'parent2ObservationUnitName': "myIbadanPlot9002", 'parent2Type': "MALE", 'pollinationTimeStamp': "20180101T11:11:11.12Z", 'crossInfo': [ { 'type': 'NumberOfSeeds', 'value': '9' }, { 'type': 'myCrossAtrribute', 'value': 'great' } ] } ] }

POST /crossingprojects/DbId/crosses

Send new crosses from handheld
return confirmation of acceptance
Follow simplified post design above
bellerbrock commented 5 years ago

hey @bauchetg, any insight into the 'pollinationTimeStamp' field? Rather than a 1:1 relationship, wouldn't a cross usually include many pollinations and pollinationTimeStamps?

bauchetg commented 5 years ago

@bellerbrock yes and that s an important point. One cross can be one/multiple pollination or just one according to crop biology and practices. Term definition is here important.

trife commented 5 years ago

One of the things that's come up at CIP is that there is a difference between a crossing experiment and a specific wishlist. Crosses may be included in a wishlist but the list may not comprehensively reflect all of the genotypes in crossing block, which have been designated as males or females. It looks like this is partially reflected above (actual crosses vs. planned), but I would propose an additional call for total crossing block that includes a male/female field and sends a total list of individuals within the crossing experiment.

bellerbrock commented 5 years ago

good point @trife. Crossing experiment plan GET call may become complex, but there are many levels of necessary information:

Also, here's another suggestion for the /crossingprojects/DbId/crosses call, with the use case of submitting from Intercross to BreeDBase with minimal data in mind. Possibly without the crossingProjectDbId in the url, more like the observations PUT call (https://github.com/plantbreeding/API/issues/255) that just relies on ObservationUnitDbId.


  {
    "femaleObservationUnitDbId": "87654", //required
    "maleObservationUnitDbId": "98765", //required
    "crossInfo": [
      {
        "eventVariableName": "Flower number", //required
        "value": "11", //required
        "collector": "Bryan", //optional
        "eventTimeStamp": "2018-06-19T18:59:45.751Z", //optional
        "eventNumber": "19_00001" // optional, equivalent to the Intercross Cross ID field
      },
      {
        "eventVariableName": "Fruit number", //required
        "value": "7", //required
        "collector": "Trevor", //optional
        "eventTimeStamp": "2018-07-19T18:59:45.751Z", //optional
        "eventNumber": "19_00001" // optional
      },
      {
        "eventVariableName": "Flower number", //required
        "value": "6", //required
        "collector": "Guillaume", //optional
        "eventTimeStamp": "2018-06-29T18:59:45.751Z", //optional
        "eventNumber": "19_00002" // optional
      },
    ]
  },
  {
    "femaleObservationUnitDbId": "54321", //required
    "maleObservationUnitDbId": "98765", //required
    "crossInfo": [
      {
       " eventVariableName": "Flower number", //required
        "value": "6", //required
        "collector": "Bryan", //optional
        "eventTimeStamp": "2018-06-25T18:59:45.751Z", //optional
        "eventNumber": "19_00003" // optional
      }
    ]
  }
]
chaneylc commented 3 years ago

Bumping this thread based on our discussion today,

It would be useful to add /crosses/{crossingProjectDbId} (same for /plannedcrosses) Although, with the current api you can do this for now: CrossingProjectQueryParams request = new CrossingProjectQueryParams(); request.page(paginationManager.getPage()).pageSize(paginationManager.getPageSize()); request.crossingProjectDbId("test"); crossingProjectsApi.crossingprojectsGetAsync(request, callback);

Also adding /crossingprojects/{programDbId} and searches for crossing projects, and crosses calls would be useful.

BrapiCoordinatorSelby commented 2 years ago

After 3 and a half years, I think everything in this issue is taken care of in BrAPI V2.1. I am closing this issue, please open new issues for any other cross related comments.