1 package CXGN
::Trial
::TrialCreate
;
5 CXGN::Trial::TrialCreate - Module to create an entirely new trial based on a specified design. For field_layout experiments and genotyping_layout experiments.
8 1) Create a new project entry in Project table based on trial and description supplied to object. If there is a project with the name already saved, it will return an error and do nothing.
9 2) Create a single new experiment entry in nd_experiment. If is_genotyping is supplied, this will be type = genotyping_layout. Otherwise, this will be type = field_layout.
10 3) Will associate the location to the project through the nd_experiment as well as through a projectprop. Location lookup happens based on location name that is provided. Assumes locations already stored in database.
11 4) Will associate the trial to its breeding program. Lookup is by breeding program name that is provided and assumes bp already exists in database. Will return an error if breeding program name not found.
12 5) Creates a single nd_experiment_project entry, linking project to nd_experiment.
13 6) Creates a year and design projectprop. Also a project_type projectprop if provided. For genotyping plates also creates others like, genotyping_facility and plate_format projectprops
14 7) Calls the CXGN::Trial::TrialDesignStore object to handle storing stocks (tissue_samples, or plots and plants and subplots) and stockprops (rep, block, well, etc)
18 FOR FIELD PHENOTYPING TRIALS:
19 my $trial_create = CXGN::Trial::TrialCreate->new({
20 chado_schema => $c->dbic_schema("Bio::Chado::Schema"),
21 dbh => $c->dbc->dbh(),
22 owner_id => $c->user()->get_object()->get_sp_person_id(),
23 operator => $c->user()->get_object()->get_username(),
25 design => $design_hash,
26 program => $breeding_program->name(),
28 planting_date => $planting_date,
29 trial_description => $project_description,
30 trial_location => $location->name(),
31 trial_name => $trial_name,
32 trial_type => $trialtype,
33 field_size => $field_size, #(ha)
34 plot_width => $plot_width, #(m)
35 plot_length => $plot_length, #(m)
36 field_trial_is_planned_to_cross => 'yes', #yes or no
37 field_trial_is_planned_to_be_genotyped => 'no', #yes or no
38 field_trial_from_field_trial => ['source_trial_id1', 'source_trial_id2'],
39 genotyping_trial_from_field_trial => ['genotyping_trial_id1'],
40 crossing_trial_from_field_trial => ['crossing_trial_id1']
43 $trial_create->save_trial();
45 print STDERR "ERROR SAVING TRIAL!\n";
48 FOR GENOTYPING PLATES:
49 my $ct = CXGN::Trial::TrialCreate->new( {
50 chado_schema => $c->dbic_schema("Bio::Chado::Schema"),
51 dbh => $c->dbc->dbh(),
52 owner_id => $c->user()->get_object()->get_sp_person_id(),
53 operator => $c->user()->get_object()->get_username(),
55 planting_date => $planting_date,
56 trial_location => $location->name(),
57 program => $breeding_program->name(),
58 trial_description => $description,
59 design_type => 'genotyping_plate',
60 design => $design_hash,
61 trial_name => $trial_name,
63 genotyping_user_id => $user_id,
64 genotyping_project_name => $project_name,
65 genotyping_facility_submit => $plate_info->{genotyping_facility_submit},
66 genotyping_facility => $plate_info->{genotyping_facility},
67 genotyping_plate_format => $plate_info->{plate_format},
68 genotyping_plate_sample_type => $plate_info->{sample_type},
69 genotyping_trial_from_field_trial => ['field_trial_id1'],
74 print STDERR "ERROR SAVING TRIAL!\n";
77 ---------------------------------------------------------------------------------
79 For field_layout trials, the design should be a HasfRef of HashRefs like:
83 "plot_name" => "plot1",
84 "plot_number" => 1001,
85 "accession_name" => "accession1",
91 "seedlot_name" => "seedlot1",
92 "num_seed_per_plot" => 12,
93 "plot_geo_json" => {},
94 "plant_names" => ["plant1", "plant2"],
98 For genotyping_layout trials, the design should be a HashRef of HashRefs like:
102 "plot_name" => "mytissuesample_A01",
103 "stock_name" => "accession1",
104 "plot_number" => "A01",
108 "concentration" => "5",
110 "tissue_type" => "leaf",
111 "dna_person" => "nmorales",
112 "extraction" => "ctab",
113 "acquisition_date" => "2018/02/16",
114 "notes" => "test notes",
123 Jeremy D. Edwards (jde22@cornell.edu)
129 use MooseX
::FollowPBP
;
130 use Moose
::Util
::TypeConstraints
;
132 use CXGN
::Stock
::StockLookup
;
133 use CXGN
::Location
::LocationLookup
;
134 use CXGN
::People
::Person
;
136 use SGN
::Model
::Cvterm
;
137 use CXGN
::Trial
::TrialDesignStore
;
140 has
'chado_schema' => (
142 isa
=> 'DBIx::Class::Schema',
143 predicate
=> 'has_chado_schema',
147 has
'dbh' => (is
=> 'rw',predicate
=> 'has_dbh', required
=> 1,);
148 #has 'user_name' => (isa => 'Str', is => 'rw', predicate => 'has_user_name', required => 1,);
149 has
'trial_id' => (isa
=> 'Maybe[Int]', is
=> 'rw', predicate
=> 'has_trial_id');
150 has
'program' => (isa
=>'Str', is
=> 'rw', predicate
=> 'has_program', required
=> 1,);
151 has
'trial_year' => (isa
=> 'Maybe[Str]', is
=> 'rw', predicate
=> 'has_trial_year', required
=> 0,);
152 has
'trial_description' => (isa
=> 'Maybe[Str]', is
=> 'rw', predicate
=> 'has_trial_description', required
=> 0,);
153 has
'trial_location' => (isa
=> 'Maybe[Str]', is
=> 'rw', predicate
=> 'has_trial_location', required
=> 0,);
154 has
'design_type' => (isa
=> 'Maybe[Str]', is
=> 'rw', predicate
=> 'has_design_type', required
=> 0);
155 has
'design' => (isa
=> 'HashRef[HashRef]|Undef', is
=> 'rw', predicate
=> 'has_design', required
=> 0);
156 has
'trial_name' => (isa
=> 'Str', is
=> 'rw', predicate
=> 'has_trial_name', required
=> 1);
157 has
'trial_type' => (isa
=> 'Str', is
=> 'rw', predicate
=> 'has_trial_type', required
=> 0);
158 has
'trial_type_value' => (isa
=> 'Str', is
=> 'rw', predicate
=> 'has_trial_type_value', required
=> 0);
159 has
'trial_has_plant_entries' => (isa
=> 'Int', is
=> 'rw', predicate
=> 'has_trial_has_plant_entries', required
=> 0);
160 has
'trial_has_subplot_entries' => (isa
=> 'Int', is
=> 'rw', predicate
=> 'has_trial_has_subplot_entries', required
=> 0);
161 has
'field_size' => (isa
=> 'Num', is
=> 'rw', predicate
=> 'has_field_size', required
=> 0);
162 has
'plot_width' => (isa
=> 'Num', is
=> 'rw', predicate
=> 'has_plot_width', required
=> 0);
163 has
'plot_length' => (isa
=> 'Num', is
=> 'rw', predicate
=> 'has_plot_length', required
=> 0);
164 has
'planting_date' => (isa
=> 'Str', is
=> 'rw', predicate
=> 'has_planting_date', required
=> 0);
165 has
'transplanting_date' => (isa
=> 'Str', is
=> 'rw', predicate
=> 'has_transplanting_date', required
=> 0);
166 has
'harvest_date' => (isa
=> 'Str', is
=> 'rw', predicate
=> 'has_harvest_date', required
=> 0);
167 has
'operator' => (isa
=> 'Str', is
=> 'rw', predicate
=> 'has_operator', required
=> 1);
168 has
'trial_stock_type' => (isa
=> 'Str', is
=> 'rw', predicate
=> 'has_trial_stock_type', required
=> 0, default => 'accession');
169 has
'additional_info' => (isa
=> 'Maybe[HashRef]', is
=> 'rw', required
=> 0);
171 # Trial linkage when saving a field trial
173 has
'field_trial_is_planned_to_cross' => (isa
=> 'Str', is
=> 'rw', predicate
=> 'has_field_trial_is_planned_to_cross', required
=> 0);
174 has
'field_trial_is_planned_to_be_genotyped' => (isa
=> 'Str', is
=> 'rw', predicate
=> 'has_field_trial_is_planned_to_be_genotyped', required
=> 0);
175 has
'field_trial_from_field_trial' => (isa
=> 'ArrayRef', is
=> 'rw', predicate
=> 'has_field_trial_from_field_trial', required
=> 0);
176 has
'crossing_trial_from_field_trial' => (isa
=> 'ArrayRef', is
=> 'rw', predicate
=> 'has_crossing_trial_from_field_trial', required
=> 0);
178 # Trial linkage when saving either a field trial or genotyping plate
180 has
'genotyping_trial_from_field_trial' => (isa
=> 'ArrayRef', is
=> 'rw', predicate
=> 'has_genotyping_trial_from_field_trial', required
=> 0);
182 # Properties for genotyping plates
184 has
'is_genotyping' => (isa
=> 'Bool', is
=> 'rw', required
=> 0, default => 0, );
185 has
'genotyping_user_id' => (isa
=> 'Str', is
=> 'rw');
186 has
'genotyping_project_id' => (isa
=> 'Int', is
=> 'rw');
187 has
'genotyping_facility_submitted' => (isa
=> 'Str', is
=> 'rw');
188 has
'genotyping_facility' => (isa
=> 'Str', is
=> 'rw');
189 has
'genotyping_plate_format' => (isa
=> 'Str', is
=> 'rw');
190 has
'genotyping_plate_sample_type' => (isa
=> 'Str', is
=> 'rw');
192 # properties for analyses
194 has
'is_analysis' => (isa
=> 'Bool', is
=> 'rw', required
=> 0, default => 0, );
195 has
'analysis_model_protocol_id' => (isa
=> 'Int|Undef', is
=> 'rw', required
=> 0 );
197 # Trial linkage when saving either a sampling trial
199 has
'sampling_trial_from_field_trial' => (isa
=> 'ArrayRef', is
=> 'rw', predicate
=> 'has_sampling_trial_from_field_trial', required
=> 0);
201 # Properties for sampling trials
203 has
'is_sampling_trial' => (isa
=> 'Bool', is
=> 'rw', required
=> 0, default => 0, );
204 has
'sampling_trial_facility' => (isa
=> 'Str', is
=> 'rw');
205 has
'sampling_trial_sample_type' => (isa
=> 'Str', is
=> 'rw');
207 has
'owner_id' => (isa
=> 'Int' , is
=> 'rw');
209 sub trial_name_already_exists
{
212 if ($self->get_is_analysis()) { return; }
213 my $trial_name = $self->get_trial_name();
214 my $schema = $self->get_chado_schema();
215 if($schema->resultset('Project::Project')->find({name
=> $trial_name})){
223 sub get_breeding_program_id
{
225 my $breeding_program_ref = $self->get_chado_schema->resultset('Project::Project')->find({name
=>$self->get_program});
226 if (!$breeding_program_ref ) {
227 print STDERR
"UNDEF breeding program " . $self->get_program . "\n\n";
230 my $breeding_program_id = $breeding_program_ref->project_id();
231 #print STDERR "get_breeding_program _id returning $breeding_program_id";
232 return $breeding_program_id;
237 print STDERR
"Check 4.1: ".localtime();
239 my $chado_schema = $self->get_chado_schema();
240 my %design = %{$self->get_design()};
241 my $trial_name = $self->get_trial_name();
242 $trial_name =~ s/^\s+|\s+$//g; #trim whitespace from both ends
244 # if a trial id is provided, the project row has already been
245 # created by other means, so use that trial_id
247 if (! $self->has_trial_id()) {
250 print STDERR
"Trial not saved: Can't create trial without a trial name\n";
251 return { error
=> "Trial not saved: Can't create trial without a trial name" };
254 if ($self->trial_name_already_exists()) {
255 print STDERR
"Can't create trial: Trial name already exists\n";
256 return { error
=> "Trial not saved: Trial name already exists" };
259 if (!$self->get_breeding_program_id()) {
260 print STDERR
"Can't create trial: Breeding program does not exist\n";
261 return { error
=> "Trial not saved: breeding program does not exist" };
265 #my $user_name = $self->get_user_name();
266 #my $dbh = $self->get_dbh();
267 #my $owner_sp_person_id;
268 #$owner_sp_person_id = CXGN::People::Person->get_person_by_username($dbh, $user_name); #add person id as an option.
269 #if (!$owner_sp_person_id) {
270 # print STDERR "Can't create trial: User/owner not found\n";
271 # die "no owner $user_name" ;
275 my $geolocation_lookup = CXGN
::Location
::LocationLookup
->new(schema
=> $chado_schema);
276 $geolocation_lookup->set_location_name($self->get_trial_location());
277 $geolocation = $geolocation_lookup->get_geolocation();
279 print STDERR
"Can't create trial: Location not found: ".$self->get_trial_location()."\n";
280 return { error
=> "Trial not saved: location not found" };
283 my $project_year_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'project year', 'project_property');
284 my $project_planting_date_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'project_planting_date', 'project_property');
285 my $project_design_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'design', 'project_property');
286 my $field_size_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'field_size', 'project_property');
287 my $plot_width_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'plot_width', 'project_property');
288 my $plot_length_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'plot_length', 'project_property');
289 my $field_trial_is_planned_to_be_genotyped_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'field_trial_is_planned_to_be_genotyped', 'project_property');
290 my $field_trial_is_planned_to_cross_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'field_trial_is_planned_to_cross', 'project_property');
291 my $has_plant_entries_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'project_has_plant_entries', 'project_property');
292 my $has_subplot_entries_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'project_has_subplot_entries', 'project_property');
293 my $genotyping_facility_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'genotyping_facility', 'project_property');
294 my $genotyping_facility_submitted_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'genotyping_facility_submitted', 'project_property');
295 my $genotyping_plate_format_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'genotyping_plate_format', 'project_property');
296 my $genotyping_plate_sample_type_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'genotyping_plate_sample_type', 'project_property');
297 my $genotyping_user_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'genotyping_user_id', 'nd_experiment_property');
298 my $genotyping_project_name_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'genotyping_project_name', 'nd_experiment_property');
299 my $trial_stock_type_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'trial_stock_type', 'project_property');
300 my $sampling_facility_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'sampling_facility', 'project_property');
301 my $sampling_trial_sample_type_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'sampling_trial_sample_type', 'project_property');
304 if ($self->has_trial_id()) {
305 $project = $chado_schema->resultset('Project::Project')->find( { project_id
=> $self->get_trial_id() });
306 if (! $project) { die "The specified project id ".$self->get_trial_id()." does not exit in the database\n"; }
309 $project = $chado_schema->resultset('Project::Project')
312 description
=> $self->get_trial_description(),
316 my $t = CXGN
::Trial
->new({
317 bcs_schema
=> $chado_schema,
318 trial_id
=> $project->project_id()
321 $t->set_trial_owner($self->get_owner_id);
322 #print STDERR "TRIAL TYPE = ".ref($t)."!!!!\n";
323 my $nd_experiment_type_id;
324 if ($self->get_is_genotyping()) {
325 print STDERR
"Generating a genotyping trial...\n";
326 $nd_experiment_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'genotyping_layout', 'experiment_type')->cvterm_id();
328 elsif ($self->get_is_analysis()) {
329 print STDERR
"Generating an analysis trial...\n";
330 $nd_experiment_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, , 'analysis_experiment', 'experiment_type')->cvterm_id();
332 elsif ($self->get_is_sampling_trial()) {
333 print STDERR
"Generating a sampling trial...\n";
334 $nd_experiment_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, , 'sampling_layout', 'experiment_type')->cvterm_id();
337 print STDERR
"Generating a phenotyping trial...\n";
338 $nd_experiment_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, , 'field_layout', 'experiment_type')->cvterm_id();
340 my $nd_experiment = $chado_schema->resultset('NaturalDiversity::NdExperiment')
342 nd_geolocation_id
=> $geolocation->nd_geolocation_id(),
343 type_id
=> $nd_experiment_type_id,
347 if ($self->get_is_genotyping()) {
348 #print STDERR "Storing user_id and project_name provided by the IGD spreadksheet for later recovery in the spreadsheet download... ".(join ",", ($self->get_genotyping_user_id(), $self->get_genotyping_project_name()))."\n";
349 $nd_experiment->create_nd_experimentprops({
350 $genotyping_user_cvterm->name() => $self->get_genotyping_user_id(),
351 # $genotyping_project_name_cvterm->name() => $self->get_genotyping_project_name(),
354 $project->create_projectprops({
355 $genotyping_facility_cvterm->name() => $self->get_genotyping_facility(),
356 $genotyping_facility_submitted_cvterm->name() => $self->get_genotyping_facility_submitted(),
357 $genotyping_plate_format_cvterm->name() => $self->get_genotyping_plate_format(),
358 $genotyping_plate_sample_type_cvterm->name() => $self->get_genotyping_plate_sample_type()
361 my $genotyping_project_relationship_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'genotyping_project_and_plate_relationship', 'project_relationship');
362 my $relationship_row = $chado_schema->resultset("Project::ProjectRelationship")->create ({
363 object_project_id
=> $self->get_genotyping_project_id(),
364 subject_project_id
=> $project->project_id(),
365 type_id
=> $genotyping_project_relationship_cvterm->cvterm_id()
367 $relationship_row->insert();
369 my $source_field_trial_ids = $t->set_source_field_trials_for_genotyping_trial($self->get_genotyping_trial_from_field_trial);
371 elsif ($self->get_is_analysis()) {
372 if ($self->get_analysis_model_protocol_id) {
373 #link to the saved analysis model
374 $nd_experiment->find_or_create_related('nd_experiment_protocols', {nd_protocol_id
=> $self->get_analysis_model_protocol_id() });
377 elsif ($self->get_is_sampling_trial()) {
378 $project->create_projectprops({
379 $sampling_facility_cvterm->name() => $self->get_sampling_trial_facility(),
380 $sampling_trial_sample_type_cvterm->name() => $self->get_sampling_trial_sample_type()
383 my $source_field_trial_ids = $t->set_source_field_trials_for_sampling_trial($self->get_sampling_trial_from_field_trial);
386 my $source_field_trial_ids = $t->set_field_trials_source_field_trials($self->get_field_trial_from_field_trial);
387 my $genotyping_trial_ids = $t->set_genotyping_trials_from_field_trial($self->get_genotyping_trial_from_field_trial);
388 my $crossing_trial_ids = $t->set_crossing_trials_from_field_trial($self->get_crossing_trial_from_field_trial);
391 $t->set_location($geolocation->nd_geolocation_id()); # set location also as a project prop
392 $t->set_breeding_program($self->get_breeding_program_id);
393 if ($self->get_trial_type){
394 $t->set_project_type($self->get_trial_type);
396 if ($self->get_planting_date()){ # here is local getter
397 $t->set_planting_date($self->get_planting_date); # here is Project.pm unusual setter with writing to db instead of object
399 if ($self->get_harvest_date()){ # here is local getter
400 $t->set_harvest_date($self->get_harvest_date); # here is Project.pm unusual setter with writing to db instead of object
402 if ($self->get_transplanting_date()){ # here is local getter
403 $t->set_transplanting_date($self->get_transplanting_date); # here is Project.pm unusual setter with writing to db instead of object
407 $nd_experiment->find_or_create_related('nd_experiment_projects',{project_id
=> $project->project_id()});
409 $project->create_projectprops({
410 $project_year_cvterm->name() => $self->get_trial_year(),
411 $project_design_cvterm->name() => $self->get_design_type()
413 if ($self->has_field_size && $self->get_field_size){
414 $project->create_projectprops({
415 $field_size_cvterm->name() => $self->get_field_size
418 if ($self->has_plot_width && $self->get_plot_width){
419 $project->create_projectprops({
420 $plot_width_cvterm->name() => $self->get_plot_width
423 if ($self->has_plot_length && $self->get_plot_length){
424 $project->create_projectprops({
425 $plot_length_cvterm->name() => $self->get_plot_length
428 if ($self->has_trial_has_plant_entries && $self->get_trial_has_plant_entries){
429 $project->create_projectprops({
430 $has_plant_entries_cvterm->name() => $self->get_trial_has_plant_entries
433 if ($self->has_trial_has_subplot_entries && $self->get_trial_has_subplot_entries){
434 $project->create_projectprops({
435 $has_subplot_entries_cvterm->name() => $self->get_trial_has_subplot_entries
438 if ($self->has_field_trial_is_planned_to_cross && $self->get_field_trial_is_planned_to_cross){
439 $project->create_projectprops({
440 $field_trial_is_planned_to_cross_cvterm->name() => $self->get_field_trial_is_planned_to_cross
443 if ($self->has_field_trial_is_planned_to_be_genotyped && $self->get_field_trial_is_planned_to_be_genotyped){
444 $project->create_projectprops({
445 $field_trial_is_planned_to_be_genotyped_cvterm->name() => $self->get_field_trial_is_planned_to_be_genotyped
449 if (!$self->get_is_genotyping) {
450 if ($self->has_trial_stock_type && $self->get_trial_stock_type){
451 $project->create_projectprops({
452 $trial_stock_type_cvterm->name() => $self->get_trial_stock_type()
457 my $design_type = $self->get_design_type();
458 if ($design_type eq 'greenhouse') {
459 my $has_plants_cvterm = SGN
::Model
::Cvterm
->get_cvterm_row($chado_schema, 'project_has_plant_entries', 'project_property');
460 $project->create_projectprops({ $has_plants_cvterm->name() => 'varies' });
463 print STDERR
"NOW CALLING TRIAl DESIGN STORE...\n";
464 my $trial_design_store = CXGN
::Trial
::TrialDesignStore
->new({
465 bcs_schema
=> $chado_schema,
466 trial_id
=> $project->project_id(),
467 trial_name
=> $trial_name,
468 nd_geolocation_id
=> $geolocation->nd_geolocation_id(),
469 nd_experiment_id
=> $nd_experiment->nd_experiment_id(),
470 design_type
=> $design_type,
472 is_genotyping
=> $self->get_is_genotyping(),
473 is_analysis
=> $self->get_is_analysis(),
474 is_sampling_trial
=> $self->get_is_sampling_trial(),
475 new_treatment_has_plant_entries
=> $self->get_trial_has_plant_entries,
476 new_treatment_has_subplot_entries
=> $self->get_trial_has_subplot_entries,
477 operator
=> $self->get_operator,
478 trial_stock_type
=> $self->get_trial_stock_type(),
481 my $validate_design_error = $trial_design_store->validate_design();
482 if ($validate_design_error) {
483 print STDERR
"ERROR: $validate_design_error\n";
484 return { error
=> "Error validating trial design: $validate_design_error." };
487 $error = $trial_design_store->store();
489 print STDERR
"ERROR store: $_\n";
494 return { error
=> $error };
496 return { trial_id
=> $project->project_id };