File size: 10,362 Bytes
fa532ba
 
 
 
 
b803baf
5fe18d9
 
 
fa532ba
 
b803baf
 
5fe18d9
 
 
b803baf
5fe18d9
fa532ba
 
b803baf
 
5fe18d9
fa532ba
3eaa798
b803baf
 
3eaa798
fa532ba
 
 
 
 
 
 
 
1617d68
 
 
 
 
 
 
 
 
fa532ba
 
b803baf
 
fa532ba
 
5fe18d9
6fcc4a7
86d64eb
5fe18d9
b803baf
fa532ba
3eaa798
dcb6733
b803baf
 
 
3eaa798
fa532ba
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b803baf
dcb6733
b803baf
fa532ba
 
b803baf
 
 
fa532ba
 
b803baf
 
fa532ba
 
 
b803baf
 
 
 
5fe18d9
 
b803baf
fa532ba
 
b803baf
 
5fe18d9
fa532ba
3eaa798
fa532ba
b803baf
 
fa532ba
 
b803baf
 
5fe18d9
 
fa532ba
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
from pydantic import BaseModel, Field, validator, ValidationError
from typing import List, Dict, Any, Optional, Literal, Union
from enum import Enum

# These are the necessary components that make up the Trials 
class Variables(BaseModel):
    controlled: Union[List[str], None] = Field(..., title="Controlled Variables", description="An array of controlled variables, which will be constant (controlled) across all trials")
    independent: Union[List[str], None] = Field(..., title="Independent Variables", description="An array of independent variables (ie treatments), which will be intentionally varied across one or more trials")
    outcome: Union[List[str], None] = Field(..., title="Outcome Variables", description="An array of outcome variables (ie dependent or response variables) which is hypothesized to change across the trials")

class Treatment(BaseModel):
    name: Union[str, None] = Field(..., title="Name", description="The treatment name")
    description: Union[str, None] = Field(..., title="Description", description="The treatment description, including the conditions within this treatment")
    crops: Union[List[str], None] = Field(..., title="Crops", description="An array of crops being tested in this treatment")
    fields: Union[List[str], None] = Field(..., title="Fields", description="An array of fields in which this treatment has occurred or will occur")
    learnings: Union[List[str], None] = Field(..., title="Learnings", description="An array of lessons learned from this experiment")
    variables: Union[Variables, None] = Field(..., title="Variables", description="Variables (ie factors) in this experiment. Some variables are constant (controlled) and some will vary in order to learn something (independent)")
    confoundingFactors: Union[List[str], None] = Field(..., title="Confounding Factors", description="An array of factors which may impact the outcomes of the experiment that were not planned for.")

class Trial(BaseModel):
    name: Union[str, None] = Field(..., title="Name", description="The name of this trial") 
    description: Union[str, None] = Field(..., title="Description", description="A description of this trial") 
    treatments: Union[List[Treatment], None] = Field(..., title="Treatments", description="An array of different treatments (strips or blocks with the same conditions applied) performed by the partner") 

class TrialLite(BaseModel):
    name: Union[str, None] = Field(..., title="Name", description="The name of this trial") 
    description: Union[str, None] = Field(..., title="Description", description="A description of this trial") 
    
#################################################################################

# These are the necessary components that make up the Interactions
class Role(str, Enum):
    PARTNER = 'partner'
    STAFF = 'staff'
    AGRONOMIST = 'agronomist'
    OTHER = 'other'

    def description(self):
        descriptions = {
            'partner': "A partner in the trial or interaction.",
            'staff': "Staff members working on the project.",
            'agronomist': "Agronomist providing expertise in the trial.",
            'other': "Other roles involved in the trial or interaction."
        }
        return descriptions.get(self.value, "No description available.")
    
class Person(BaseModel):
    name: Union[str, None] = Field(..., title="Name", description="Name of this person") 
    role: Union[Role, None] = Field(..., title="Role", description="Role of this person")
    
class Interactions(BaseModel):
    people: Union[List[Person], None] = Field(..., title="People", description="An array of people involved in or mentioned in this interaction")
    date: Union[str, None] = Field(..., title="Date", description="Date of the interaction in ISO 8601 format (YYYY-MM-DD)", example="2024-10-05")
    nextMeeting: Union[str, None] = Field(..., title="Date of next meeting in ISO 8601 format (YYYY-MM-DD)", description="Proposed date of the next future interaction in ISO 8601 format (YYYY-MM-DD)", example="2024-10-05")
    nextSteps: Union[List[str], None] = Field(..., title="Next Steps", description="Array containing a list of next steps from the interaction")
    summary: Union[str, None] = Field(..., title="Summary", description="Summary of the interaction")

class InteractionsLite(BaseModel):
    date: Union[str, None] = Field(..., title="Date", description="Date of the interaction in ISO 8601 format (YYYY-MM-DD)", example="2024-10-05")
    nextMeeting: Union[str, None] = Field(..., title="Date of next meeting", description="Proposed date of the next future interaction")
    nextSteps: Union[List[str], None] = Field(..., title="Next Steps", description="List of individual next steps derived from the interaction")
    summary: Union[str, None] = Field(..., title="Summary", description="Summary of the interaction")
    
#################################################################################

# These are the components for Farm Activities, Fields, and Plantings
class Status(str, Enum):
    ACTIVE = 'active'
    ARCHIVED = 'archived'

# Depending on how well this works, come back and hard-code this based on some parameter(s)
class Convention(str, Enum):
    ACTIVITY = 'log--activity'
    OBSERVATION = 'log--observation'
    FLAMING = 'log--activity--flaming'
    GRAZING = 'log--activity--grazing'
    MOWING = 'log--activity--mowing'
    SOLARIZATION = 'log--activity--solarization'
    TERMINATION = 'log--activity--termination'
    TILLAGE = 'log--activity--tillage'
    HARVEST = 'log--activity--harvest'
    HERBICIDE = 'log--input--herbicide_or_pesticide'
    IRRIGATION = 'log--input--irrigation'
    LIME = 'log--input--lime'
    ORGANIC = 'log--input--organic_matter'
    SEEDTREAT = 'log--input--seed_treatment'
    SEEDLINGTREAT = 'log--input--seedling_treatment'
    MODUS = 'log--lab_test--modus_lab_test'
    SEEDING = 'log--seeding--seeding'
    TRANSPLANT = 'log--transplanting--transplant'

class Structure(str, Enum):
    CLAY = 'clay'
    SANDYCLAY = 'sandy clay'
    SILTYCLAY = 'silty clay'
    SANDYCLAYLOAM = 'sandy clay loam'
    SILYCLAMLOAM = 'silty clay loam'
    CLAYLOAM = 'clay loam'
    SANDYLOAM = 'sandy loam'
    SILTLOAM = 'silt loam'
    LOAM = 'loam'
    LOAMYSAND = 'loamy sand'
    SAND = 'sand'
    SILT = 'silt'
  
class Log(BaseModel): 
    convention: Union[Convention, None] = Field(..., title="Logs", description="This log's convention (i.e. this log's category or type)")
    date: Union[str, None] = Field(..., title="Date", description="Date the log (i.e. action of the activity or input) was performed in ISO 8601 format (YYYY-MM-DD)", example="2024-10-05")
    description: Union[str, None] = Field(..., title="Description", description="A description of the details of the log (i.e. details about farm activity performed")

class Soil(BaseModel): 
    description: Union[str, None] = Field(..., title="Description", description="A general description of the soil")
    structure: Union[List[Structure], None] = Field(..., title="Structure", description="The structure of the soil using options from the major soil texture classes (sand, clay, silt)")
    biology: Union[str, None] = Field(..., title="Biology", description="Biological activity levels of the soil, including fluffiness, worms and bugs, and other evidence of soil biological activity")

class Yield(BaseModel):
    quantity: Union[str, None] = Field(..., title="Quantity", description="A description of the total yield (harvested amount) from this planting, including units when available")
    quality: Union[str, None] = Field(..., title="Quality", description="The product quality of the harvest.  For example, small or large fruits, sweet or tart flavor, easily molding or containing mold, high number of product seconds, etc.)")

# It breaks if soil and yield aren't lists for some reason
class Planting(BaseModel):
    name: Union[str, None] = Field(..., title="Name", description="The name of the planting")
    status: Union[Status, None] = Field(..., title="Status", description="The status of the planting. \"active\" is a planting which is currently still in the field.  \"archived\" is a planting which is no longer in the field (has been terminated or harvested)")
    crop: Union[List[str], None] = Field(..., title="Crop", description="A list of the crops in this planting")
    variety: Union[List[str], None] = Field(..., title="Variety", description="A list of the crop varieties in this planting")
    logs: Union[List[Log], None] = Field(..., title="Logs", description="An array of all logs that are associated with this individual planting")
    soil: Union[List[Soil], None] = Field(..., title="Soil", description="Information about the soil associated with or observed during the time of this planting")
    yield_: Union[List[Yield], None] = Field(..., title="Yield", description="One set of quantitative and qualitative yield observations for this planting") 

class FarmActivities(BaseModel):
    name: Union[str, None] = Field(..., title="Name", description="The name of the agricultural field.")
    description: Union[str, None] = Field(..., title="Description", description="The description of the agricultural field.")
    plantings: Union[List[Planting], None] = Field(..., title="Plantings", description="An array of all the plantings which have occurred on this field")

# These are extra for the modular approach (step-wise)
class FarmActivitiesLite(BaseModel):
    name: Union[str, None] = Field(..., title="Name", description="The name of the agricultural field.")
    description: Union[str, None] = Field(..., title="Description", description="The description of the agricultural field.")
    
class PlantingLite(BaseModel):
    name: Union[str, None] = Field(..., title="Name", description="The name of the planting")
    status: Union[Status, None] = Field(..., title="Status", description="The status of the planting. \"active\" is a planting which is currently still in the field.  \"archived\" is a planting which is no longer in the field (has been terminated or harvested)")
    crop: Union[List[str], None] = Field(..., title="Crop", description="An array of the crops in this planting")
    variety: Union[List[str], None] = Field(..., title="Variety", description="An array of the varieties in this planting")