modified key
[sgn.git] / lib / CXGN / Trial / TrialDesignStore.pm
blobd69cdd36799c8a5a34790a30a9b711c01013b68e
1 package CXGN::Trial::TrialDesignStore;
3 =head1 NAME
5 CXGN::Trial::TrialDesignStore - Module to validate and store a trial's design (for genotyping, phenotyping and analysis trials)
7 =head1 USAGE
9 my $design_store = CXGN::Trial::TrialDesignStore->new({
10 bcs_schema => $c->dbic_schema("Bio::Chado::Schema"),
11 trial_id => $trial_id,
12 trial_name => $trial_name,
13 design_type => 'CRD',
14 design => $design_hash,
15 is_genotyping => 0,
16 is_analysis => 0,
17 operator = "janedoe"
18 });
20 my $validate_error = $design_store->validate_design();
21 my $store_error;
23 if ($validate_error) {
24 print STDERR "VALIDATE ERROR: $validate_error\n";
26 else {
27 try {
28 $store error = $design_store->store();
29 } catch {
30 $store_error = $_;
34 if ($store_error) {
35 print STDERR "ERROR SAVING TRIAL!: $store_error\n";
38 If a genotyping experiment is stored, is_genotyping has to be set to true (1). If an analysis is stored, is_analysis has to be set to true. For a phenotyping experiment, both are set to false (0).
40 =head1 DESCRIPTION
42 This class is used for storing a completely new design (plots and possibly plants and possibly subplots).
44 =over 4
46 =item -
48 Used from CXGN::Trial::TrialCreate for saving newly designed field trials in SGN::Controller::AJAX::Trial->save_experimental_design_POST
50 =item -
52 Used from CXGN::Trial::TrialCreate for saving uploaded field trials in SGN::Controller::AJAX::Trial->upload_trial_file_POST
54 =item -
56 Used from CXGN::Trial::TrialCreate for saving newly designed genotyping plate OR saving uploaded genotyping plate in SGN::Controller::AJAX::GenotypingTrial->store_genotype_trial
58 =back
60 This is used for storing new treatment (field management factor) trials.
62 =over 4
64 =item -
66 Used from CXGN::Trial::TrialCreate for saving or uploading field trials with treatments in SGN::Controller::AJAX::Trial->save_experimental_design_POST and SGN::Controller::AJAX::Trial->upload_trial_file_POST
68 =item -
70 Used from CXGN::Trial::TrialMetadata->trial_add_treatment for adding a new treatment to a trial
72 =item -
74 To add new treatments, There should be a key in the design called "treatments" specifying which stocks to include in the treatment like:
77 "treatments" =>
79 "fertilizer_10ml" => ["plot1", "plot2", "plot1_plant1", "plot2_plant1"],
80 "water" => ["plot1", "plot2"]
84 =back
86 This is NOT used for adding plants or tissue_samples to existing trials.
88 =over 5
90 =item -
92 Note: For adding plants to a design already saved, use CXGN::Trial->create_plant_entities to auto-generate plant names or CXGN::Trial->save_plant_entries to save user defined plant names.
94 =item -
96 For adding tissue samples to a design already saved, use CXGN::Trial->create_tissue_samples to auto-generate sample names.
98 =back
100 For field_layout trials, the design should be a HasfRef of HashRefs like:
103 '1001' => {
104 "plot_name" => "plot1",
105 "plot_number" => 1001,
106 "accession_name" => "accession1",
107 "block_number" => 1,
108 "row_number" => 2,
109 "col_number" => 3,
110 "rep_number" => 1,
111 "is_a_control" => 1,
112 "seedlot_name" => "seedlot1",
113 "num_seed_per_plot" => 12,
114 "plot_geo_json" => {},
115 "plant_names" => ["plant1", "plant2"],
119 For genotyping_layout trials, the design should be a HashRef of HashRefs like:
121 'A01' => {
122 "plot_name" => "mytissuesample_A01",
123 "stock_name" => "accession1",
124 "plot_number" => "A01",
125 "row_number" => "A",
126 "col_number" => "1",
127 "is_blank" => 0,
128 "concentration" => "5",
129 "volume" => "2",
130 "tissue_type" => "leaf",
131 "dna_person" => "nmorales",
132 "extraction" => "ctab",
133 "acquisition_date" => "2018/02/16",
134 "notes" => "test notes",
139 store() will do the following for FIELD LAYOUT trials:
141 =over 5
143 =item 1)
145 Search for a trial's associated nd_experiment. There should only be one nd_experiment of type = field_layout.
147 =item 2)
149 Foreach plot in the design hash, searches for the accession's stock_name.
150 # TO BE IMPLEMENTED: A boolean option to allow stock_names to be added to the database on the fly. Normally this would be set to 0, but for certain loading scripts this could be set to 1.
152 =item 3)
154 Finds or creates a stock entry for each plot_name in the design hash.
155 #TO BE IMPLEMENTED: Associate an owner to the plot
157 =item 4)
159 Creates stockprops (block, rep, plot_number, etc) for plots.
161 =item 5)
163 For each plot, creates a stock relationship between the plot and accession if not already present.
165 =item 6)
167 If seedlot given: for each plot, creates a seed transaction stock relationship between the plot and seedlot
169 =item 7)
171 For each plot, creates an nd_experiment_stock entry if not already present. They are all linked to the same nd_experiment entry found in step 1.
173 =item 8)
175 Finds or creates a stock entry for each plant_names in the design hash.
176 #TO BE IMPLEMENTED: Associate an owner to the plant
178 =item 9)
180 Creates stockprops (block, rep, plot_number, plant_index_number, etc) for plants.
181 =item 10)
183 For each plant, creates a stock_relationship between the plant and accession if not already present.
185 =item 11)
187 For each plant, creates a stock_relationship between the plant and plot if not already present.
189 =item 12)
191 For each plant creates an nd_experiment_stock entry if not already present. They are all linked to the same nd_experiment entry found in step 1.
193 If there are subplot entries (currently for splitplot design)
195 =item 13)
197 Finds or creates a stock entry for each subplot_names in the design hash.
198 #TO BE IMPLEMENTED: Associate an owner to the subplot
200 =item 14)
202 Creates stockprops (block, rep, plot_number, plant_index_number, etc) for subplots.
204 =item 15)
206 For each subplot, creates a stock_relationship between the subplot and accession if not already present.
208 =item 16)
210 For each subplot, creates a stock_relationship between the subplot and plot if not already present.
212 =item 17)
214 For each subplot, creates a stock_relationship between the subplot and plant if not already present.
216 =item 18)
218 For each subplot creates an nd_experiment_stock entry if not already present. They are all linked to the same nd_experiment entry found in step 1.
220 store() will do the following for GENOTYPING LAYOUT trials:
222 =back
224 =over 5
227 =item 1)
229 Search for a trial's associated nd_experiment. There should only be one nd_experiment of type = genotyping_layout.
230 =item 2)
233 Foreach tissue_sample in the design hash, searches for the source_observation_unit's stock_name. The source_observation_unit can be in order of descending desireability: tissue_sample, plant, plot, or accession
235 =item 3)
237 Finds or creates a stock entry for each tissue in the design hash.
239 =item 4)
241 Creates stockprops (col_number, row_number, plot_number, notes, dna_person, etc) for tissue_sample.
243 =item 5)
245 For each tissue_sample, creates a stock relationship between the tissue_sample and source_observation_unit if not already present.
247 =item 6)
249 If the source_observation_unit is a tissue_sample, it will create stock relationships to the tissue_sample's parent plant, plot, and accession if they exist.
251 =item 7)
253 If the source_observation_unit is a plant, it will create stock relationships to the plant's parent plot and accession if they exist.
255 =item 8)
257 If the source_observation_unit is a plot, it will create stock relationships to the plot's parent accession if it exists.
259 =item 9)
261 For each tissue_sample, creates an nd_experiment_stock entry if not already present. They are all linked to the same nd_experiment entry found in step 1.
263 =back
266 =head1 AUTHORS
268 Nicolas Morales (nm529@cornell.edu)
269 refactoring by Lukas Mueller (lam87@cornell.edu), Nov 2019
271 =cut
273 use Data::Dumper;
274 use CXGN::Trial::TrialDesignStore::PhenotypingTrial;
275 use CXGN::Trial::TrialDesignStore::GenotypingTrial;
276 use CXGN::Trial::TrialDesignStore::Analysis;
277 use CXGN::Trial::TrialDesignStore::CrossingTrial;
278 use CXGN::Trial::TrialDesignStore::SamplingTrial;
280 sub new {
281 my $class = shift;
282 my $args = shift;
284 my $type;
286 if (($args->{is_genotyping} == 1) && ($args->{is_analysis} == 1)) {
287 die "Trial design can't have is_genotyping and is_analysis set at the same time.\n";
290 if ($args->{is_genotyping} == 1) {
291 $type = "genotyping_trial";
294 if ($args->{is_analysis} == 1) {
295 $type = "analysis";
298 if ($args->{is_sampling_trial} == 1) {
299 $type = "sampling_trial";
302 if( (! $args->{is_genotyping}) && (! $args->{is_analysis}) && (! $args->{is_sampling_trial}) ) {
303 $type = "phenotyping_trial";
306 my $object;
307 if ($type eq "genotyping_trial") {
308 print STDERR "Generating GENOTYPING TRIAL\n";
309 $object = CXGN::Trial::TrialDesignStore::GenotypingTrial->new($args);
311 if ($type eq "phenotyping_trial") {
312 print STDERR "Generating PHENOTYPING TRIAL OBJECT...\n";
313 $object = CXGN::Trial::TrialDesignStore::PhenotypingTrial->new($args);
315 if ($type eq "analysis") {
316 print STDERR "Generating ANALYSIS TRIAL...\n";
317 $object = CXGN::Trial::TrialDesignStore::Analysis->new($args);
319 if ($type eq "cross") {
320 print STDERR "Generating CROSSING TRIAL...\n";
321 $object = CXGN::Trial::TrialDesignStore::CrossingTrial->new($args);
323 if ($type eq "sampling_trial") {
324 print STDERR "Generating SAMPLING TRIAL...\n";
325 $object = CXGN::Trial::TrialDesignStore::SamplingTrial->new($args);
328 return $object;