2 package SGN
::Controller
::AJAX
::BrAPI
;
9 use CXGN
::BreedersToolbox
::Projects
;
11 use CXGN
::Trial
::TrialLayout
;
12 use CXGN
::Chado
::Stock
;
14 use CXGN
::BreederSearch
;
15 use CXGN
::Trial
::TrialCreate
;
16 use JSON
qw( decode_json );
20 BEGIN { extends
'Catalyst::Controller::REST' };
23 default => 'application/json',
25 map => { 'application/json' => 'JSON', 'text/html' => 'JSON' },
28 has
'bcs_schema' => ( isa
=> 'Bio::Chado::Schema',
32 my $DEFAULT_PAGE_SIZE=20;
35 sub brapi
: Chained
('/') PathPart
('brapi') CaptureArgs
(1) {
41 $self->bcs_schema( $c->dbic_schema("Bio::Chado::Schema") );
42 $c->stash->{api_version
} = $version;
43 $c->response->headers->header( "Access-Control-Allow-Origin" => '*' );
44 $c->stash->{status
} = \
@status;
45 $c->stash->{session_token
} = $c->req->param("session_token");
46 $c->stash->{current_page
} = $c->req->param("currentPage") || 1;
47 $c->stash->{page_size
} = $c->req->param("pageSize") || $DEFAULT_PAGE_SIZE;
51 sub _authenticate_user
{
53 my $status = $c->stash->{status
};
54 my @status = @
$status;
56 my ($person_id, $user_type, $user_pref, $expired) = CXGN
::Login
->new($c->dbc->dbh)->query_from_cookie($c->stash->{session_token
});
57 #print STDERR $person_id." : ".$user_type." : ".$expired;
59 if (!$person_id || $expired || $user_type ne 'curator') {
60 push(@status, 'You must login and have permission to access BrAPI calls.');
61 my %metadata = (status
=>\
@status);
62 $c->stash->{rest
} = \
%metadata;
69 =head2 /brapi/v1/token
71 Usage: For logging a user in and loggin a user out through the API
77 "grant_type" : "password", //(optional, text, `password`) ... The grant type, only allowed value is password, but can be ignored
78 "username" : "user38", // (required, text, `thepoweruser`) ... The username
79 "password" : "secretpw", // (optional, text, `mylittlesecret`) ... The password
80 "client_id" : "blabla" // (optional, text, `blabla`) ... The client id, currently ignored.
90 "userDisplayName": "John Smith",
91 "access_token": "R6gKDBRxM4HLj6eGi4u5HkQjYoIBTPfvtZzUD8TUzg4",
92 "expires_in": "The lifetime in seconds of the access token"
99 "access_token" : "R6gKDBRxM4HLj6eGi4u5HkQjYoIBTPfvtZzUD8TUzg4" // (optional, text, `R6gKDBRxM4HLj6eGi4u5HkQjYoIBTPfvtZzUD8TUzg4`) ... The user access token. Default: current user token.
106 "status" : { "message" : "User has been logged out successfully."},
114 sub authenticate_token
: Chained
('brapi') PathPart
('token') Args
(0) : ActionClass
('REST') { }
116 sub authenticate_token_DELETE
{
120 my $login_controller = CXGN
::Login
->new($c->dbc->dbh);
122 my $status = $c->stash->{status
};
123 my @status = @
$status;
125 $login_controller->logout_user();
130 my %metadata = (pagination
=>\
%pagination, status
=>\
@status, datafiles
=>\
@data_files);
131 my %response = (metadata
=>\
%metadata, result
=>\
%result);
132 $c->stash->{rest
} = \
%response;
135 sub authenticate_token_POST
{
139 my $login_controller = CXGN
::Login
->new($c->dbc->dbh);
140 my $params = $c->req->params();
142 my $status = $c->stash->{status
};
143 my @status = @
$status;
148 if ( $login_controller->login_allowed() ) {
149 if ($params->{grant_type
} eq 'password' || !$params->{grant_type
}) {
150 my $login_info = $login_controller->login_user( $params->{username
}, $params->{password
} );
151 if ($login_info->{account_disabled
}) {
152 push(@status, 'Account Disabled');
154 if ($login_info->{incorrect_password
}) {
155 push(@status, 'Incorrect Password');
157 if ($login_info->{duplicate_cookie_string
}) {
158 push(@status, 'Duplicate Cookie String');
160 if ($login_info->{logins_disabled
}) {
161 push(@status, 'Logins Disabled');
163 if ($login_info->{person_id
}) {
164 push(@status, 'Login Successfull');
165 $cookie = $login_info->{cookie_string
};
166 $first_name = $login_info->{first_name
};
167 $last_name = $login_info->{last_name
};
170 push(@status, 'Grant Type Not Supported. Valid grant type: password');
173 push(@status, 'Login Not Allowed');
177 my %metadata = (pagination
=>\
%pagination, status
=>\
@status, datafiles
=>\
@data_files);
178 my %response = (metadata
=>\
%metadata, access_token
=>$cookie, userDisplayName
=>"$first_name $last_name", expires_in
=>$CXGN::Login
::LOGIN_TIMEOUT
);
179 $c->stash->{rest
} = \
%response;
183 =head2 /brapi/v1/calls
185 Usage: For determining which calls have been implemented and with which datafile types and methods
205 "call": "allelematrix",
216 "call": "germplasm/id/mcpd",
225 "call": "doesntexistyet",
240 sub calls
: Chained
('brapi') PathPart
('calls') Args
(0) : ActionClass
('REST') { }
246 my $status = $c->stash->{status
};
247 my @status = @
$status;
249 push @data, {call
=>'token', datatypes
=>['json'], methods
=>['POST','DELETE']};
250 push @data, {call
=>'calls', datatypes
=>['json'], methods
=>['GET']};
253 my %result = (data
=>\
@data);
255 my %metadata = (pagination
=>\
%pagination, status
=>\
@status, datafiles
=>\
@data_files);
256 my %response = (metadata
=>\
%metadata, result
=>\
%result);
257 $c->stash->{rest
} = \
%response;
262 sub pagination_response
{
263 my $data_count = shift;
264 my $page_size = shift;
266 my $total_pages_decimal = $data_count/$page_size;
267 my $total_pages = ($total_pages_decimal == int $total_pages_decimal) ?
$total_pages_decimal : int($total_pages_decimal + 1);
268 my %pagination = (pageSize
=>$page_size, currentPage
=>$page, totalCount
=>$data_count, totalPages
=>$total_pages);
273 =head2 /brapi/v1/germplasm-search?germplasmName=&germplasmGenus=&germplasmSubTaxa=&germplasmDbId&germplasmPUI=http://data.inra.fr/accession/234Col342&germplasmSpecies=Triticum&panel=diversitypanel1&collection=none&pageSize=pageSize&page=page
275 Usage: For searching a germplasm by name. Allows for exact and wildcard match methods. http://docs.brapi.apiary.io/#germplasm
281 "germplasmPUI" : "http://...", // (optional, text, `http://data.inra.fr/accession/234Col342`) ... The name or synonym of external genebank accession identifier
282 "germplasmDbId" : 986, // (optional, text, `986`) ... The name or synonym of external genebank accession identifier
283 "germplasmSpecies" : "tomato", // (optional, text, `aestivum`) ... The name or synonym of genus or species ( merge with below ?)
284 "germplasmGenus" : "Solanum lycopersicum", //(optional, text, `Triticum, Hordeum`) ... The name or synonym of genus or species
285 "germplasmName" : "XYZ1", // (optional, text, `Triticum, Hordeum`) ... The name or synonym of the accession
286 "accessionNumber" : "ITC1234" // optional
287 "pageSize" : 100, // (optional, integer, `1000`) ... The size of the pages to be returned. Default is `1000`.
288 "page": 1 (optional, integer, `10`) ... Which result page is requested
307 "germplasmDbId": "01BEL084609",
308 "defaultDisplayName": "Pahang",
309 "accessionNumber": "ITC0609",
310 "germplasmName": "Pahang",
311 "germplasmPUI": "http://www.crop-diversity.org/mgis/accession/01BEL084609",
312 "pedigree": "TOBA97/SW90.1057",
313 "germplasmSeedSource": "Female GID:4/Male GID:4",
315 "commonCropName": "banana",
316 "instituteCode": "01BEL084",
317 "instituteName": "ITC",
318 "biologicalStatusOfAccessionCode": 412,
319 "countryOfOriginCode": "UNK",
320 "typeOfGermplasmStorageCode": 10,
322 "species": "acuminata",
323 "speciesAuthority": "",
324 "subtaxa": "sp malaccensis var pahang",
325 "subtaxaAuthority": "",
329 "donorAccessionNumber": "",
330 "donorInstituteCode": "",
334 "acquisitionDate": "19470131"
342 sub germplasm_synonyms
{
344 my $stock_id = shift;
345 my $synonym_id = shift;
347 my $rsp = $schema->resultset("Stock::Stockprop")->search({type_id
=> $synonym_id, stock_id
=>$stock_id });
348 while (my $stockprop = $rsp->next()) {
349 push( @synonyms, $stockprop->value() );
354 sub germplasm_pedigree_string
{
356 my $stock_id = shift;
357 my $s = CXGN
::Chado
::Stock
->new($schema, $stock_id);
358 my $pedigree_root = $s->get_parents('1');
359 my $pedigree_string = $pedigree_root->get_pedigree_string('1');
360 return $pedigree_string;
363 sub germplasm_list
: Chained
('brapi') PathPart
('germplasm-search') Args
(0) : ActionClass
('REST') { }
365 #sub germplasm_list_POST {
368 # my $auth = _authenticate_user($c);
370 # my $status = $c->stash->{status};
371 # my @status = @$status;
373 # $c->stash->{rest} = {status => \@status};
376 sub germplasm_list_POST
{
379 #my $auth = _authenticate_user($c);
380 my $params = $c->req->params();
382 my $status = $c->stash->{status
};
383 my @status = @
$status;
385 my $germplasm_name = $params->{germplasmName
};
386 my $accession_number = $params->{accessionNumber
};
387 my $genus = $params->{germplasmGenus
};
388 my $subtaxa = $params->{germplasmSubTaxa
};
389 my $species = $params->{germplasmSpecies
};
390 my $germplasm_id = $params->{germplasmDbId
};
391 my $permplasm_pui = $params->{germplasmPUI
};
392 my $match_method = $params->{matchMethod
};
393 if ($match_method && ($match_method ne 'exact' || $match_method ne 'wildcard')) {
394 push(@status, "matchMethod '$match_method' not recognized. Allowed matchMethods: wildcard, exact. Wildcard allows % or * for multiple characters and ? for single characters.");
400 my $accession_type_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'accession', 'stock_type')->cvterm_id();
403 my @select_list = ['me.stock_id', 'me.name', 'me.uniquename'];
404 my @sselect_as_list = ['stock_id', 'name', 'uniquename'];
406 $search_params{'me.type_id'} = $accession_type_cvterm_id;
407 $order_params{'-asc'} = 'me.stock_id';
409 if ($germplasm_name && (!$match_method || $match_method eq 'exact')) {
410 $search_params{'me.uniquename'} = $germplasm_name;
412 if ($germplasm_name && $match_method eq 'wildcard') {
413 $germplasm_name =~ tr/*?/%_/;
414 $search_params{'me.uniquename'} = { 'ilike' => $germplasm_name };
416 if ($germplasm_id && (!$match_method || $match_method eq 'exact')) {
417 $search_params{'me.stock_id'} = $germplasm_id;
419 if ($germplasm_id && $match_method eq 'wildcard') {
420 $germplasm_id =~ tr/*?/%_/;
421 $search_params{'me.stock_id'} = { 'ilike' => $germplasm_id };
423 #print STDERR Dumper \%search_params;
424 my $rs = $self->bcs_schema()->resultset("Stock::Stock")->search( \
%search_params, { '+select'=> \
@select_list, '+as'=> \
@sselect_as_list, order_by
=> \
%order_params } );
425 my $synonym_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema(), 'stock_synonym', 'stock_property')->cvterm_id();
426 if ($accession_number) {
427 $search_params{'stockprops.type_id'} = $synonym_id;
428 $search_params{'stockprops.value'} = $accession_number;
429 $rs = $self->bcs_schema()->resultset("Stock::Stock")->search( \
%search_params, { join=>{'stockprops'}, '+select'=> \
@select_list, '+as'=> \
@sselect_as_list, order_by
=> \
%order_params } );
434 $total_count = $rs->count();
435 my $rs_slice = $rs->slice($c->stash->{page_size
}*($c->stash->{current_page
}-1), $c->stash->{page_size
}*$c->stash->{current_page
}-1);
436 while (my $stock = $rs_slice->next()) {
438 germplasmDbId
=>$stock->get_column('stock_id'),
439 defaultDisplayName
=>$stock->get_column('name'),
440 germplasmName
=>$stock->get_column('uniquename'),
441 accessionNumber
=>$accession_number,
442 germplasmPUI
=>$stock->get_column('uniquename'),
443 pedigree
=>germplasm_pedigree_string
($self->bcs_schema(), $stock->get_column('stock_id')),
444 germplasmSeedSource
=>'',
445 synonyms
=>germplasm_synonyms
($self->bcs_schema(), $stock->get_column('stock_id'), $synonym_id),
449 biologicalStatusOfAccessionCode
=>'',
450 countryOfOriginCode
=>'',
451 typeOfGermplasmStorageCode
=>'',
454 speciesAuthority
=>'',
456 subtaxaAuthority
=>'',
463 %result = (data
=> \
@data);
464 my %metadata = (pagination
=> pagination_response
($total_count, $c->stash->{page_size
}, $c->stash->{current_page
}), status
=>\
@status);
465 my %response = (metadata
=>\
%metadata, result
=>\
%result);
466 $c->stash->{rest
} = \
%response;
469 =head2 brapi/v1/germplasm/{id}
471 Usage: To retrieve details for a single germplasm
480 "germplasmDbId": "01BEL084609",
481 "defaultDisplayName": "Pahang",
482 "germplasmName": "Pahang",
483 "accessionNumber": "ITC0609",
484 "germplasmPUI": "http://www.crop-diversity.org/mgis/accession/01BEL084609",
485 "pedigree": "TOBA97/SW90.1057",
486 "seedSource": "Female GID:4/Male GID:4",
487 "synonyms": ["Pahanga","Pahange"],
495 sub germplasm_single
: Chained
('brapi') PathPart
('germplasm') CaptureArgs
(1) {
498 my $stock_id = shift;
500 $c->stash->{stock_id
} = $stock_id;
501 $c->stash->{stock
} = CXGN
::Chado
::Stock
->new($self->bcs_schema(), $stock_id);
505 sub germplasm_detail
: Chained
('germplasm_single') PathPart
('') Args
(0) : ActionClass
('REST') { }
507 sub germplasm_detail_POST
{
510 my $auth = _authenticate_user
($c);
511 my $status = $c->stash->{status
};
512 my @status = @
$status;
514 $c->stash->{rest
} = {status
=>\
@status};
517 sub germplasm_detail_GET
{
520 #my $auth = _authenticate_user($c);
521 my $rs = $c->stash->{stock
};
522 my $schema = $self->bcs_schema();
523 my $status = $c->stash->{status
};
524 my @status = @
$status;
527 if ($c->stash->{stock
}) {
532 my $synonym_id = $schema->resultset("Cv::Cvterm")->find( { name
=> "synonym" })->cvterm_id();
534 %result = (germplasmDbId
=>$c->stash->{stock_id
}, defaultDisplayName
=>$c->stash->{stock
}->get_name(), germplasmName
=>$c->stash->{stock
}->get_uniquename(), accessionNumber
=>$c->stash->{stock
}->get_uniquename(), germplasmPUI
=>$c->stash->{stock
}->get_uniquename(), pedigree
=>germplasm_pedigree_string
($self->bcs_schema(), $c->stash->{stock_id
}), seedSource
=>'', synonyms
=>germplasm_synonyms
($schema, $c->stash->{stock_id
}, $synonym_id));
536 my %metadata = (pagination
=>pagination_response
($total_count, $c->stash->{page_size
}, $c->stash->{current_page
}), status
=>\
@status);
537 my %response = (metadata
=>\
%metadata, result
=>\
%result);
538 $c->stash->{rest
} = \
%response;
541 =head2 brapi/v1/germplasm/{id}/MCPD
543 Usage: To retrieve multi crop passport descriptor for a single germplasm
552 "germplasmDbId": "01BEL084609",
553 "defaultDisplayName": "Pahang",
554 "accessionNumber": "ITC0609",
555 "germplasmName": "Pahang",
556 "germplasmPUI": "http://www.crop-diversity.org/mgis/accession/01BEL084609",
557 "pedigree": "TOBA97/SW90.1057",
558 "germplasmSeedSource": "Female GID:4/Male GID:4",
560 "commonCropName": "banana",
561 "instituteCode": "01BEL084",
562 "instituteName": "ITC",
563 "biologicalStatusOfAccessionCode": 412,
564 "countryOfOriginCode": "UNK",
565 "typeOfGermplasmStorageCode": 10,
567 "species": "acuminata",
568 "speciesAuthority": "",
569 "subtaxa": "sp malaccensis var pahang",
570 "subtaxaAuthority": "",
574 "donorAccessionNumber": "",
575 "donorInstituteCode": "",
579 "acquisitionDate": "19470131"
586 sub germplasm_mcpd
: Chained
('germplasm_single') PathPart
('MCPD') Args
(0) : ActionClass
('REST') { }
588 sub germplasm_mcpd_POST
{
591 my $auth = _authenticate_user
($c);
592 my $status = $c->stash->{status
};
593 my @status = @
$status;
595 $c->stash->{rest
} = {status
=>\
@status};
598 sub germplasm_mcpd_GET
{
601 #my $auth = _authenticate_user($c);
602 my $schema = $self->bcs_schema();
604 my $status = $c->stash->{status
};
605 my @status = @
$status;
607 my $synonym_id = $schema->resultset("Cv::Cvterm")->find( { name
=> "synonym" })->cvterm_id();
608 my $organism = CXGN
::Chado
::Organism
->new( $schema, $c->stash->{stock
}->get_organism_id() );
610 %result = (germplasmDbId
=>$c->stash->{stock_id
}, defaultDisplayName
=>$c->stash->{stock
}->get_uniquename(), accessionNumber
=>$c->stash->{stock
}->get_uniquename(), germplasmName
=>$c->stash->{stock
}->get_name(), germplasmPUI
=>$c->stash->{stock
}->get_uniquename(), pedigree
=>germplasm_pedigree_string
($schema, $c->stash->{stock_id
}), germplasmSeedSource
=>'', synonyms
=>germplasm_synonyms
($schema, $c->stash->{stock_id
}, $synonym_id), commonCropName
=>$organism->get_common_name(), instituteCode
=>'', instituteName
=>'', biologicalStatusOfAccessionCode
=>'', countryOfOriginCode
=>'', typeOfGermplasmStorageCode
=>'', genus
=>$organism->get_genus(), species
=>$organism->get_species(), speciesAuthority
=>'', subtaxa
=>$organism->get_taxon(), subtaxaAuthority
=>'', donors
=>'', acquisitionDate
=>'');
613 my %metadata = (pagination
=>\
%pagination, status
=>\
@status);
614 my %response = (metadata
=>\
%metadata, result
=>\
%result);
615 $c->stash->{rest
} = \
%response;
619 =head2 brapi/v1/studies?programId=programId
621 Usage: To retrieve studies
638 "name": "Earlygenerationtesting",
639 "studyType": "Trial",
640 "years": ["2005", "2008"],
644 "studyPUI" : "PUI string",
645 "studyType": "Trial",
646 "startDate": "2015-06-01",
647 "endDate" : "2015-12-31",
653 "name": "Earlygenerationtesting",
654 "seasons": ["2005", "2008"],
658 "studyPUI" : "PUI string",
659 "studyType": "Trial",
660 "startDate": "2015-06-01",
661 "endDate" : "2015-12-31",
672 sub studies_list
: Chained
('brapi') PathPart
('studies') Args
(0) : ActionClass
('REST') { }
674 sub studies_list_POST
{
677 my $auth = _authenticate_user
($c);
678 my $status = $c->stash->{status
};
679 my @status = @
$status;
681 my $study_name = $c->req->param('studyName');
682 my $location_id = $c->req->param('locationDbId');
683 my $years = $c->req->param('studyYears');
684 my $program_id = $c->req->param('programDbId');
685 my $optional_info = $c->req->param('optionalInfo');
689 if ($optional_info) {
690 my $opt_info_hash = decode_json
($optional_info);
691 $description = $opt_info_hash->{"studyObjective"};
692 $study_type = $opt_info_hash->{"studyType"};
695 my $program_obj = CXGN
::BreedersToolbox
::Projects
->new({schema
=> $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado') });
696 my $programs = $program_obj->get_breeding_programs();
699 foreach (@
$programs) {
700 if ($_->[0] == $program_id) {
702 $program_name = $_->[1];
705 if (!$program_check) {
706 push @status, "Program not found with programDbId = ".$program_id;
707 $c->stash->{rest
} = {status
=> \
@status };
711 my $locations = $program_obj->get_all_locations();
714 foreach (@
$locations) {
715 if ($_->[0] == $location_id) {
717 $location_name = $_->[1];
720 if (!$location_check) {
721 push @status, "Location not found with locationDbId = ".$location_id;
722 $c->stash->{rest
} = {status
=> \
@status };
727 my $trial_create = CXGN
::Trial
::TrialCreate
->new({
729 chado_schema
=> $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado'),
730 metadata_schema
=> $c->dbic_schema("CXGN::Metadata::Schema"),
731 phenome_schema
=> $c->dbic_schema("CXGN::Phenome::Schema"),
732 user_name
=> $c->user()->get_object()->get_username(),
733 program
=> $program_name,
734 trial_year
=> $years,
735 trial_description
=> $description,
736 design_type
=> $study_type,
737 trial_location
=> $location_name,
738 trial_name
=> $study_name,
739 design
=> $trial_design,
742 if ($trial_create->trial_name_already_exists()) {
743 push @status, "Trial name \"".$trial_create->get_trial_name()."\" already exists.";
744 $c->stash->{rest
} = {status
=> \
@status };
751 $trial_create->save_trial();
753 push @status, "Error saving trial in the database $_";
754 $c->stash->{rest
} = {status
=> \
@status};
761 push @status, "Study saved successfully.";
762 $c->stash->{rest
} = {status
=> \
@status};
765 sub studies_list_GET
{
768 #my $auth = _authenticate_user($c);
769 my $program_id = $c->req->param("programId");
770 my $status = $c->stash->{status
};
771 my @status = @
$status;
777 $rs = $self->bcs_schema->resultset('Project::Project')->search(
778 {'type.name' => 'breeding_program_trial_relationship' },
779 {join=> {'project_relationship_subject_projects' => 'type'},
780 '+select'=> ['me.project_id'],
781 '+as'=> ['study_id' ],
782 order_by
=>{ -asc
=>'me.project_id' }
785 }elsif ($program_id) {
786 $rs = $self->bcs_schema->resultset('Project::Project')->search(
787 {'type.name' => 'breeding_program_trial_relationship', 'project_relationship_subject_projects.object_project_id' => $program_id },
788 {join=> {'project_relationship_subject_projects' => 'type'},
789 '+select'=> ['me.project_id'],
790 '+as'=> ['study_id' ],
791 order_by
=>{ -asc
=>'me.project_id' }
798 $total_count = $rs->count();
799 my $rs_slice = $rs->slice($c->stash->{page_size
}*($c->stash->{current_page
}-1), $c->stash->{page_size
}*$c->stash->{current_page
}-1);
800 while (my $s = $rs_slice->next()) {
801 my $t = CXGN
::Trial
->new( { trial_id
=> $s->get_column('study_id'), bcs_schema
=> $self->bcs_schema } );
803 my @years = ($t->get_year());
804 my %optional_info = (studyPUI
=>'', startDate
=> $t->get_planting_date(), endDate
=> $t->get_harvest_date());
805 my $project_type = '';
806 if ($t->get_project_type()) {
807 $project_type = $t->get_project_type()->[1];
810 if ($t->get_location()) {
811 $location = $t->get_location()->[0];
813 push @data, {studyDbId
=>$t->get_trial_id(), name
=>$t->get_name(), studyType
=>$project_type, years
=>\
@years, locationDbId
=>$location, optionalInfo
=>\
%optional_info};
817 %result = (data
=>\
@data);
818 my %metadata = (pagination
=>pagination_response
($total_count, $c->stash->{page_size
}, $c->stash->{current_page
}), status
=>\
@status);
819 my %response = (metadata
=>\
%metadata, result
=>\
%result);
820 $c->stash->{rest
} = \
%response;
823 =head2 brapi/v1/studies/{studyId}/germplasm?pageSize=20&page=1
825 Usage: To retrieve all germplasm used in a study
840 "studyName": "myBestTrial",
843 "germplasmDbId": "382",
844 "trialEntryNumberId": "1",
845 "defaultDisplayName": "Pahang",
846 "germplasmName": "Pahang",
847 "accessionNumber": "ITC0609",
848 "germplasmPUI": "http://www.crop-diversity.org/mgis/accession/01BEL084609",
849 "pedigree": "TOBA97/SW90.1057",
851 "synonyms": ["01BEL084609"],
854 "germplasmDbId": "394",
855 "trialEntryNumberId": "2",
856 "defaultDisplayName": "Pahang",
857 "germplasmName": "Pahang",
858 "accessionNumber": "ITC0727",
859 "germplasmPUI": "http://www.crop-diversity.org/mgis/accession/01BEL084727",
860 "pedigree": "TOBA97/SW90.1057",
862 "synonyms": [ "01BEL084727"],
872 sub studies_single
: Chained
('brapi') PathPart
('studies') CaptureArgs
(1) {
875 my $study_id = shift;
877 $c->stash->{study_id
} = $study_id;
878 my $t = CXGN
::Trial
->new( { trial_id
=> $study_id, bcs_schema
=> $self->bcs_schema } );
879 $c->stash->{study} = $t;
880 $c->stash->{studyName
} = $t->get_name();
884 sub studies_germplasm
: Chained
('studies_single') PathPart
('germplasm') Args
(0) : ActionClass
('REST') { }
886 sub studies_germplasm_POST
{
889 my $auth = _authenticate_user
($c);
890 my $status = $c->stash->{status
};
891 my @status = @
$status;
893 my $metadata = $c->req->params("metadata");
894 my $result = $c->req->params("result");
895 my %metadata_hash = %$metadata;
896 my %result_hash = %$result;
898 print STDERR Dumper
($metadata);
899 print STDERR Dumper
($result);
901 my $pagintation = $metadata_hash{"pagination"};
902 push(@status, $metadata_hash{"status"});
904 $c->stash->{rest
} = {status
=>\
@status};
907 sub studies_germplasm_GET
{
910 #my $auth = _authenticate_user($c);
912 my $status = $c->stash->{status
};
913 my @status = @
$status;
916 my $synonym_id = $self->bcs_schema->resultset("Cv::Cvterm")->find( { name
=> "synonym" })->cvterm_id();
917 my $tl = CXGN
::Trial
::TrialLayout
->new( { schema
=> $self->bcs_schema, trial_id
=> $c->stash->{study_id
} });
918 my ($accessions, $controls) = $tl->_get_trial_accession_names_and_control_names();
922 push (@
$accessions, @
$controls);
923 $total_count = scalar(@
$accessions);
924 my $start = $c->stash->{page_size
}*($c->stash->{current_page
}-1);
925 my $end = $c->stash->{page_size
}*$c->stash->{current_page
}-1;
926 for( my $i = $start; $i <= $end; $i++ ) {
927 if (@
$accessions[$i]) {
928 push @germplasm_data, { germplasmDbId
=>@
$accessions[$i]->{stock_id
}, germplasmName
=>@
$accessions[$i]->{accession_name
}, studyEntryNumberId
=>'', defaultDisplayName
=>@
$accessions[$i]->{accession_name
}, accessionNumber
=>@
$accessions[$i]->{accession_name
}, germplasmPUI
=>@
$accessions[$i]->{accession_name
}, pedigree
=>germplasm_pedigree_string
($self->bcs_schema, @
$accessions[$i]->{stock_id
}), seedSource
=>'', synonyms
=>germplasm_synonyms
($self->bcs_schema, @
$accessions[$i]->{stock_id
}, $synonym_id)};
933 %result = (studyDbId
=>$c->stash->{study_id
}, studyName
=>$c->stash->{studyName
}, data
=>\
@germplasm_data);
935 my %metadata = (pagination
=>pagination_response
($total_count, $c->stash->{page_size
}, $c->stash->{current_page
}), status
=>\
@status);
936 my %response = (metadata
=>\
%metadata, result
=>\
%result);
937 $c->stash->{rest
} = \
%response;
941 =head2 brapi/v1/germplasm/{id}/pedigree?notation=purdy
943 Usage: To retrieve pedigree information for a single germplasm
952 "germplasmDbId": "382",
953 "pedigree": "TOBA97/SW90.1057",
963 sub germplasm_pedigree
: Chained
('germplasm_single') PathPart
('pedigree') Args
(0) : ActionClass
('REST') { }
965 sub germplasm_pedigree_POST
{
968 my $auth = _authenticate_user
($c);
969 my $status = $c->stash->{status
};
970 my @status = @
$status;
972 $c->stash->{rest
} = {status
=>\
@status};
975 sub germplasm_pedigree_GET
{
978 #my $auth = _authenticate_user($c);
979 my $schema = $self->bcs_schema();
981 my $status = $c->stash->{status
};
982 my @status = @
$status;
985 if ($c->req->param('notation')) {
986 push @status, 'notation not implemented';
987 if ($c->req->param('notation') ne 'purdy') {
988 push @status, {code
=>'ERR-1', message
=>'Unsupported notation code.'};
992 my $s = $c->stash->{stock
};
997 my @direct_parents = $s->get_direct_parents();
999 %result = (germplasmDbId
=>$c->stash->{stock_id
}, pedigree
=>germplasm_pedigree_string
($schema, $c->stash->{stock_id
}), parent1Id
=>$direct_parents[0][0], parent2Id
=>$direct_parents[1][0]);
1002 my %metadata = (pagination
=>pagination_response
($total_count, $c->stash->{page_size
}, $c->stash->{current_page
}), status
=>\
@status);
1003 my %response = (metadata
=>\
%metadata, result
=>\
%result);
1004 $c->stash->{rest
} = \
%response;
1007 =head2 brapi/v1/germplasm/{id}/markerprofiles
1009 Usage: To retrieve markerprofile ids for a single germplasm
1011 Return JSON example:
1018 "germplasmDbId": "382",
1030 sub germplasm_markerprofile
: Chained
('germplasm_single') PathPart
('markerprofiles') Args
(0) : ActionClass
('REST') { }
1032 sub germplasm_markerprofile_POST
{
1035 my $auth = _authenticate_user
($c);
1036 my $status = $c->stash->{status
};
1037 my @status = @
$status;
1039 $c->stash->{rest
} = {status
=>\
@status};
1042 sub germplasm_markerprofile_GET
{
1045 #my $auth = _authenticate_user($c);
1046 my $schema = $self->bcs_schema();
1048 my $status = $c->stash->{status
};
1049 my @status = @
$status;
1050 my @marker_profiles;
1052 my $snp_genotyping_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'snp genotyping', 'genotype_property')->cvterm_id();
1054 my $rs = $self->bcs_schema->resultset('NaturalDiversity::NdExperiment')->search(
1055 {'genotypeprops.type_id' => $snp_genotyping_cvterm_id, 'stock.stock_id'=>$c->stash->{stock_id
}},
1056 {join=> [{'nd_experiment_genotypes' => {'genotype' => 'genotypeprops'} }, {'nd_experiment_protocols' => 'nd_protocol' }, {'nd_experiment_stocks' => 'stock'} ],
1057 select=> ['genotypeprops.genotypeprop_id'],
1058 as
=> ['genotypeprop_id'],
1059 order_by
=>{ -asc
=>'genotypeprops.genotypeprop_id' }
1063 my $rs_slice = $rs->slice($c->stash->{page_size
}*($c->stash->{current_page
}-1), $c->stash->{page_size
}*$c->stash->{current_page
}-1);
1064 while (my $gt = $rs_slice->next()) {
1065 push @marker_profiles, $gt->get_column('genotypeprop_id');
1067 %result = (germplasmDbId
=>$c->stash->{stock_id
}, markerProfiles
=>\
@marker_profiles);
1068 my $total_count = scalar(@marker_profiles);
1069 my %metadata = (pagination
=>pagination_response
($total_count, $c->stash->{page_size
}, $c->stash->{current_page
}), status
=>\
@status);
1070 my %response = (metadata
=>\
%metadata, result
=>\
%result);
1071 $c->stash->{rest
} = \
%response;
1076 # Need to implement Germplasm Attributes
1080 =head2 brapi/v1/markerprofiles?germplasm=germplasmDbId&extract=extractDbId&method=methodDbId
1082 Usage: To retrieve markerprofile ids for a single germplasm
1084 Return JSON example:
1098 "markerProfileDbId": "993",
1099 "germplasmDbId" : 2374,
1100 "extractDbId" : 3939,
1101 "analysisMethod": "GoldenGate",
1105 "markerProfileDbId": "994",
1106 "germplasmDbId" : 2374,
1107 "extractDbId" : 3939,
1108 "analysisMethod": "GBS",
1119 sub markerprofiles_list
: Chained
('brapi') PathPart
('markerprofiles') Args
(0) : ActionClass
('REST') { }
1121 sub markerprofiles_list_POST
{
1124 my $auth = _authenticate_user
($c);
1125 my $status = $c->stash->{status
};
1126 my @status = @
$status;
1128 $c->stash->{rest
} = {status
=>\
@status};
1131 sub markerprofiles_list_GET
{
1134 #my $auth = _authenticate_user($c);
1135 my $germplasm = $c->req->param("germplasm");
1136 my $extract = $c->req->param("extract");
1137 my $method = $c->req->param("method");
1138 my $status = $c->stash->{status
};
1139 my @status = @
$status;
1143 my $snp_genotyping_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'snp genotyping', 'genotype_property')->cvterm_id();
1146 if ($germplasm && $method) {
1147 $rs = $self->bcs_schema->resultset('NaturalDiversity::NdExperiment')->search(
1148 {'genotypeprops.type_id' => $snp_genotyping_cvterm_id, 'stock.stock_id'=>$germplasm, 'nd_protocol.nd_protocol_id'=>$method},
1149 {join=> [{'nd_experiment_genotypes' => {'genotype' => 'genotypeprops'} }, {'nd_experiment_protocols' => 'nd_protocol' }, {'nd_experiment_stocks' => 'stock'} ],
1150 select=> ['genotypeprops.genotypeprop_id', 'genotypeprops.value', 'nd_protocol.name', 'stock.stock_id'],
1151 as
=> ['genotypeprop_id', 'value', 'protocol_name', 'stock_id'],
1152 order_by
=>{ -asc
=>'genotypeprops.genotypeprop_id' }
1156 if ($germplasm && !$method) {
1157 $rs = $self->bcs_schema->resultset('NaturalDiversity::NdExperiment')->search(
1158 {'genotypeprops.type_id' => $snp_genotyping_cvterm_id, 'stock.stock_id'=>$germplasm},
1159 {join=> [{'nd_experiment_genotypes' => {'genotype' => 'genotypeprops'} }, {'nd_experiment_protocols' => 'nd_protocol' }, {'nd_experiment_stocks' => 'stock'} ],
1160 select=> ['genotypeprops.genotypeprop_id', 'genotypeprops.value', 'nd_protocol.name', 'stock.stock_id'],
1161 as
=> ['genotypeprop_id', 'value', 'protocol_name', 'stock_id'],
1162 order_by
=>{ -asc
=>'genotypeprops.genotypeprop_id' }
1166 if (!$germplasm && $method) {
1167 $rs = $self->bcs_schema->resultset('NaturalDiversity::NdExperiment')->search(
1168 {'genotypeprops.type_id' => $snp_genotyping_cvterm_id, 'nd_protocol.nd_protocol_id'=>$method},
1169 {join=> [{'nd_experiment_genotypes' => {'genotype' => 'genotypeprops'} }, {'nd_experiment_protocols' => 'nd_protocol' }, {'nd_experiment_stocks' => 'stock'} ],
1170 select=> ['genotypeprops.genotypeprop_id', 'genotypeprops.value', 'nd_protocol.name', 'stock.stock_id'],
1171 as
=> ['genotypeprop_id', 'value', 'protocol_name', 'stock_id'],
1172 order_by
=>{ -asc
=>'genotypeprops.genotypeprop_id' }
1176 if (!$germplasm && !$method) {
1177 $rs = $self->bcs_schema->resultset('NaturalDiversity::NdExperiment')->search(
1178 { 'genotypeprops.type_id' => $snp_genotyping_cvterm_id },
1179 {join=> [{'nd_experiment_genotypes' => {'genotype' => 'genotypeprops'} }, {'nd_experiment_protocols' => 'nd_protocol' }, {'nd_experiment_stocks' => 'stock'} ],
1180 select=> ['genotypeprops.genotypeprop_id', 'genotypeprops.value', 'nd_protocol.name', 'stock.stock_id'],
1181 as
=> ['genotypeprop_id', 'value', 'protocol_name', 'stock_id'],
1182 order_by
=>{ -asc
=>'genotypeprops.genotypeprop_id' }
1188 push @status, 'Extract not supported';
1192 my $rs_slice = $rs->slice($c->stash->{page_size
}*($c->stash->{current_page
}-1), $c->stash->{page_size
}*$c->stash->{current_page
}-1);
1193 while (my $row = $rs_slice->next()) {
1194 my $genotype_json = $row->get_column('value');
1195 my $genotype = JSON
::Any
->decode($genotype_json);
1197 push @data, {markerProfileDbId
=> $row->get_column('genotypeprop_id'), germplasmDbId
=> $row->get_column('stock_id'), extractDbId
=> "", analysisMethod
=> $row->get_column('protocol_name'), resultCount
=> scalar(keys(%$genotype)) };
1201 my $total_count = $rs->count();
1203 %result = (data
=> \
@data);
1204 my %metadata = (pagination
=>pagination_response
($total_count, $c->stash->{page_size
}, $c->stash->{current_page
}), status
=>\
@status);
1205 my %response = (metadata
=>\
%metadata, result
=>\
%result);
1206 $c->stash->{rest
} = \
%response;
1210 =head2 brapi/v1/markerprofiles/markerprofilesDbId
1212 Usage: To retrieve data for a single markerprofile
1214 Return JSON example:
1227 "germplasmDbId": 993,
1228 "extractDbId" : 38383,
1229 "markerprofileDbId": 37484,
1230 "analysisMethod": "GBS-Pst1",
1231 "encoding": "AA,BB,AB",
1232 "data" : [ { "marker1": "AA" }, { "marker2":"AB" }, ... ]
1240 sub markerprofiles_single
: Chained
('brapi') PathPart
('markerprofiles') CaptureArgs
(1) {
1244 $c->stash->{markerprofile_id
} = $id; # this is genotypeprop_id
1247 sub genotype_fetch
: Chained
('markerprofiles_single') PathPart
('') Args
(0) : ActionClass
('REST') { }
1249 sub genotype_fetch_POST
{
1252 my $auth = _authenticate_user
($c);
1253 my $status = $c->stash->{status
};
1254 my @status = @
$status;
1256 $c->stash->{rest
} = {status
=>\
@status};
1259 sub genotype_fetch_GET
{
1262 #my $auth = _authenticate_user($c);
1263 my $status = $c->stash->{status
};
1264 my @status = @
$status;
1268 my $total_count = 0;
1269 my $rs = $self->bcs_schema->resultset('NaturalDiversity::NdExperiment')->find(
1270 {'genotypeprops.genotypeprop_id' => $c->stash->{markerprofile_id
} },
1271 {join=> [{'nd_experiment_genotypes' => {'genotype' => 'genotypeprops'} }, {'nd_experiment_protocols' => 'nd_protocol' }, {'nd_experiment_stocks' => 'stock'} ],
1272 select=> ['genotypeprops.value', 'nd_protocol.name', 'stock.stock_id'],
1273 as
=> ['value', 'protocol_name', 'stock_id'],
1278 my $genotype_json = $rs->get_column('value');
1279 my $genotype = JSON
::Any
->decode($genotype_json);
1280 $total_count = scalar keys %$genotype;
1282 foreach my $m (sort genosort
keys %$genotype) {
1283 push @data, { $m=>$self->convert_dosage_to_genotype($genotype->{$m}) };
1286 my $start = $c->stash->{page_size
}*($c->stash->{current_page
}-1);
1287 my $end = $c->stash->{page_size
}*$c->stash->{current_page
};
1288 my @data_window = splice @data, $start, $end;
1290 %result = (germplasmDbId
=>$rs->get_column('stock_id'), extractDbId
=>'', markerprofileDbId
=>$c->stash->{markerprofile_id
}, analysisMethod
=>$rs->get_column('protocol_name'), encoding
=>"AA,BB,AB", data
=> \
@data_window);
1293 my %metadata = (pagination
=>pagination_response
($total_count, $c->stash->{page_size
}, $c->stash->{current_page
}), status
=>\
@status);
1294 my %response = (metadata
=>\
%metadata, result
=>\
%result);
1295 $c->stash->{rest
} = \
%response;
1299 sub markerprofiles_methods
: Chained
('brapi') PathPart
('markerprofiles/methods') Args
(0) {
1302 #my $auth = _authenticate_user($c);
1303 my $status = $c->stash->{status
};
1304 my @status = @
$status;
1306 my $rs = $self->bcs_schema()->resultset("NaturalDiversity::NdProtocol")->search( { } );
1308 while (my $row = $rs->next()) {
1309 push @response, [ $row->nd_protocol_id(), $row->name() ];
1311 $c->stash->{rest
} = \
@response;
1317 my ($a_chr, $a_pos, $b_chr, $b_pos);
1318 if ($a =~ m/S(\d+)\_(.*)/) {
1322 if ($b =~ m/S(\d+)\_(.*)/) {
1327 if ($a_chr && $b_chr) {
1328 if ($a_chr == $b_chr) {
1329 return $a_pos <=> $b_pos;
1331 return $a_chr <=> $b_chr;
1338 sub convert_dosage_to_genotype
{
1343 if ($dosage eq "NA") {
1349 elsif ($dosage == 0) {
1352 elsif ($dosage == 2) {
1361 =head2 brapi/v1/allelematrix?markerprofileDbId=100&markerprofileDbId=101
1363 Usage: Gives a matrix data structure for a given list of markerprofileDbIds
1365 Return JSON example:
1377 "makerprofileDbIds": ["markerprofileId1","markerprofileId2","markerprofileId3"],
1379 { "markerId1":["AB","AA","AA"] },
1380 { "markerId2":["AA","AB","AA"] },
1381 { "markerId3":["AB","AB","BB"] }
1390 sub allelematrix
: Chained
('brapi') PathPart
('allelematrix') Args
(0) {
1393 #my $auth = _authenticate_user($c);
1394 my $status = $c->stash->{status
};
1395 my @status = @
$status;
1397 my @profile_ids = $c->req->param('markerprofileDbId');
1398 my $data_format = $c->req->param('format');
1399 #print STDERR Dumper \@profile_ids;
1400 #my @profile_ids = split ",", $markerprofile_ids;
1402 my $rs = $self->bcs_schema()->resultset("Genetic::Genotypeprop")->search( { genotypeprop_id
=> { -in => \
@profile_ids }});
1407 my @marker_score_lines;
1408 my @ordered_refmarkers;
1410 if ($rs->count() > 0) {
1411 while (my $profile = $rs->next()) {
1412 my $profile_json = $profile->value();
1413 my $refmarkers = JSON
::Any
->decode($profile_json);
1414 #print STDERR Dumper($refmarkers);
1415 push @ordered_refmarkers, sort genosort
keys(%$refmarkers);
1418 #print Dumper(\@ordered_refmarkers);
1420 my $json = JSON
->new();
1421 $rs = $self->bcs_schema()->resultset("Genetic::Genotypeprop")->search( { genotypeprop_id
=> { -in => \
@profile_ids }});
1422 while (my $profile = $rs->next()) {
1423 foreach my $m (@ordered_refmarkers) {
1424 my $markers_json = $profile->value();
1425 $markers = $json->decode($markers_json);
1427 $scores{$profile->genotypeprop_id()}->{$m} = $self->convert_dosage_to_genotype($markers->{$m});
1432 #print STDERR Dumper \%scores;
1435 foreach my $line (keys %scores) {
1444 my @marker_score_json_lines;
1445 if (!$data_format || $data_format eq 'json' ){
1446 @json_lines = @lines;
1447 print STDERR
scalar(@ordered_refmarkers)."\n";
1449 for (my $n = $c->stash->{page_size
} * ($c->stash->{current_page
}-1); $n< ($c->stash->{page_size
} * ($c->stash->{current_page
})); $n++) {
1451 my %markers_by_line;
1452 my $m = $ordered_refmarkers[$n];
1453 #print STDERR Dumper $m;
1454 foreach my $line (keys %scores) {
1455 push @
{$markers_by_line{$m}}, $scores{$line}->{$m};
1456 if (!exists $markers_seen{$m} ) {
1457 #print STDERR Dumper \@{$markers_by_line{$m}};
1458 $markers_seen{$m} = \@
{$markers_by_line{$m}};
1459 #push @marker_score_lines, { $m => \@{$markers_by_line{$m}} };
1464 foreach my $marker_name (sort keys %markers_seen) {
1465 my $marker_scores = $markers_seen{$marker_name};
1466 #print STDERR Dumper $marker_scores;
1467 push @marker_score_json_lines, { $marker_name => $marker_scores };
1471 } elsif ($data_format eq 'tsv') {
1472 my $dir = $c->tempfiles_subdir('download');
1473 my ($fh, $tempfile) = $c->tempfile( TEMPLATE
=> 'download/allelematrix_'.$data_format.'_'.'XXXXX');
1474 $file_path = $c->config->{basepath
}."/".$tempfile.".tsv";
1475 open(my $fh, ">", $file_path);
1476 print STDERR
$file_path."\n";
1477 print $fh "markerprofileDbIds\t", join("\t", @lines), "\n";
1479 my %markers_by_line;
1480 print STDERR
scalar(@ordered_refmarkers)."\n";
1481 foreach my $m (@ordered_refmarkers) {
1482 #print STDERR Dumper $m;
1483 foreach my $line (keys %scores) {
1484 push @
{$markers_by_line{$m}}, $scores{$line}->{$m};
1485 if (!exists $markers_seen{$m} ) {
1486 #print STDERR Dumper \@{$markers_by_line{$m}};
1487 $markers_seen{$m} = \@
{$markers_by_line{$m}};
1488 #push @marker_score_lines, { $m => \@{$markers_by_line{$m}} };
1493 foreach my $marker_name (sort keys %markers_seen) {
1494 my $marker_scores = $markers_seen{$marker_name};
1495 #print STDERR Dumper $marker_scores;
1496 print $fh "$marker_name\t", join("\t", @
{$marker_scores}),"\n";
1501 $data_file_path = $file_path;
1506 $total_count = scalar(keys %$markers);
1508 $c->stash->{rest
} = {
1509 metadata
=> { pagination
=>pagination_response
($total_count, $c->stash->{page_size
}, $c->stash->{current_page
}), status
=> \
@status, datafiles
=>$data_file_path },
1510 result
=> {markerprofileDbIds
=> \
@json_lines, data
=> \
@marker_score_json_lines},
1516 =head2 brapi/v1/programs
1518 Usage: To retrieve a list of programs being worked on
1520 Return JSON example:
1534 "programDbid": "123",
1535 "name": "Wheat Resistance Program",
1536 "objective" : "Disease resistance",
1537 "leadPerson" : "Dr. Henry Beachell"
1540 "programDbId": "456",
1541 "name": "Wheat Improvement Program",
1542 "objective" : "Yield improvement",
1543 "leadPerson" : "Dr. Norman Borlaug"
1553 sub programs_list
: Chained
('brapi') PathPart
('programs') Args
(0) : ActionClass
('REST') { }
1555 sub programs_list_POST
{
1558 my $auth = _authenticate_user
($c);
1559 my $status = $c->stash->{status
};
1560 my @status = @
$status;
1562 $c->stash->{rest
} = {status
=>\
@status};
1565 sub programs_list_GET
{
1568 #my $auth = _authenticate_user($c);
1569 my $status = $c->stash->{status
};
1570 my @status = @
$status;
1574 my $ps = CXGN
::BreedersToolbox
::Projects
->new( { schema
=> $c->dbic_schema("Bio::Chado::Schema") });
1576 my $programs = $ps -> get_breeding_programs
();
1577 my $total_count = scalar(@
$programs);
1579 my $start = $c->stash->{page_size
}*($c->stash->{current_page
}-1);
1580 my $end = $c->stash->{page_size
}*$c->stash->{current_page
}-1;
1581 for( my $i = $start; $i <= $end; $i++ ) {
1582 if (@
$programs[$i]) {
1583 push @data, {programDbId
=>@
$programs[$i]->[0], name
=>@
$programs[$i]->[1], objective
=>@
$programs[$i]->[2], leadPerson
=>''};
1587 %result = (data
=>\
@data);
1588 my %metadata = (pagination
=>pagination_response
($total_count, $c->stash->{page_size
}, $c->stash->{current_page
}), status
=>\
@status);
1589 my %response = (metadata
=>\
%metadata, result
=>\
%result);
1590 $c->stash->{rest
} = \
%response;
1594 =head2 brapi/v1/studyTypes
1596 Usage: To retrieve a list of programs being worked onthe various study types
1598 Return JSON example:
1613 "description": "Description for Nursery study type"
1617 "description": "Description for Nursery study type"
1627 sub studies_types_list
: Chained
('brapi') PathPart
('studyTypes') Args
(0) : ActionClass
('REST') { }
1629 sub studies_types_list_POST
{
1632 my $auth = _authenticate_user
($c);
1633 my $status = $c->stash->{status
};
1634 my @status = @
$status;
1636 $c->stash->{rest
} = {status
=>\
@status};
1639 sub studies_types_list_GET
{
1642 #my $auth = _authenticate_user($c);
1645 my $status = $c->stash->{status
};
1646 my @status = @
$status;
1648 my @cvterm_ids = CXGN
::Trial
::get_all_project_types
($self->bcs_schema);
1650 foreach (@cvterm_ids) {
1651 $cvterm = CXGN
::Chado
::Cvterm
->new($c->dbc->dbh, $_->[0]);
1652 push @data, {name
=>$_->[1], description
=>$cvterm->get_definition },
1655 my $total_count = scalar(@cvterm_ids);
1656 %result = (data
=> \
@data);
1657 my %metadata = (pagination
=>pagination_response
($total_count, $c->stash->{page_size
}, $c->stash->{current_page
}), status
=>\
@status);
1658 my %response = (metadata
=>\
%metadata, result
=>\
%result);
1659 $c->stash->{rest
} = \
%response;
1663 sub studies_instances
: Chained
('studies_single') PathPart
('instances') Args
(0) : ActionClass
('REST') { }
1665 sub studies_instances_POST
{
1668 my $auth = _authenticate_user
($c);
1669 my $status = $c->stash->{status
};
1670 my @status = @
$status;
1672 $c->stash->{rest
} = {status
=>\
@status};
1675 sub studies_instances_GET
{
1678 #my $auth = _authenticate_user($c);
1680 my $status = $c->stash->{status
};
1681 my @status = @
$status;
1682 my $total_count = 0;
1684 my %metadata = (pagination
=>pagination_response
($total_count, $c->stash->{page_size
}, $c->stash->{current_page
}), status
=>\
@status);
1685 my %response = (metadata
=>\
%metadata, result
=>\
%result);
1686 $c->stash->{rest
} = \
%response;
1690 sub studies_info
: Chained
('studies_single') PathPart
('') Args
(0) : ActionClass
('REST') { }
1692 sub studies_info_POST
{
1695 my $auth = _authenticate_user
($c);
1696 my $status = $c->stash->{status
};
1697 my @status = @
$status;
1699 $c->stash->{rest
} = {status
=> \
@status};
1702 sub studies_info_GET
{
1705 #my $auth = _authenticate_user($c);
1707 my $status = $c->stash->{status
};
1708 my @status = @
$status;
1709 my $total_count = 0;
1711 my $t = $c->stash->{study};
1714 my @years = ($t->get_year());
1715 my %optional_info = (studyPUI
=>'', startDate
=>'', endDate
=>'');
1716 my $project_type = '';
1717 if ($t->get_project_type()) {
1718 $project_type = $t->get_project_type()->[1];
1721 if ($t->get_location()) {
1722 $location = $t->get_location()->[0];
1724 my $ps = CXGN
::BreedersToolbox
::Projects
->new( { schema
=> $self->bcs_schema });
1725 my $programs = $ps->get_breeding_program_with_trial($c->stash->{study_id
});
1727 %result = (studyDbId
=>$t->get_trial_id(), studyName
=>$t->get_name(), studyType
=>$project_type, years
=>\
@years, locationDbId
=>$location, programDbId
=>@
$programs[0]->[0], programName
=>@
$programs[0]->[1], optionalInfo
=>\
%optional_info);
1729 push @status, "Study ID not found.";
1732 my %metadata = (pagination
=>pagination_response
($total_count, $c->stash->{page_size
}, $c->stash->{current_page
}), status
=>\
@status);
1733 my %response = (metadata
=>\
%metadata, result
=>\
%result);
1734 $c->stash->{rest
} = \
%response;
1738 sub studies_details
: Chained
('studies_single') PathPart
('details') Args
(0) : ActionClass
('REST') { }
1740 sub studies_details_POST
{
1743 my $auth = _authenticate_user
($c);
1744 my $status = $c->stash->{status
};
1745 my @status = @
$status;
1747 $c->stash->{rest
} = {status
=> \
@status};
1750 sub studies_details_GET
{
1753 #my $auth = _authenticate_user($c);
1754 my $status = $c->stash->{status
};
1755 my @status = @
$status;
1757 my $total_count = 0;
1759 my $schema = $self->bcs_schema();
1760 my $t = $c->stash->{study};
1761 my $tl = CXGN
::Trial
::TrialLayout
->new( { schema
=> $schema, trial_id
=> $c->stash->{study_id
} });
1765 my ($accessions, $controls) = $tl->_get_trial_accession_names_and_control_names();
1767 foreach (@
$accessions) {
1768 push @germplasm_data, { germplasmDbId
=>$_->{stock_id
}, germplasmName
=>$_->{accession_name
}, germplasmPUI
=>$_->{accession_name
} };
1770 foreach (@
$controls) {
1771 push @germplasm_data, { germplasmDbId
=>$_->{stock_id
}, germplasmName
=>$_->{accession_name
}, germplasmPUI
=>$_->{accession_name
} };
1774 my $ps = CXGN
::BreedersToolbox
::Projects
->new( { schema
=> $self->bcs_schema });
1775 my $programs = $ps->get_breeding_program_with_trial($c->stash->{study_id
});
1778 studyDbId
=> $c->stash->{study_id
},
1779 studyId
=> $t->get_name(),
1781 studyName
=> $t->get_name(),
1782 studyObjective
=> $t->get_description(),
1783 studyType
=> $t->get_project_type() ?
$t->get_project_type()->[1] : "trial",
1784 studyLocation
=> $t->get_location() ?
$t->get_location()->[1] : undef,
1785 studyProject
=> $t->get_breeding_program(),
1787 studyPlatform
=> "",
1788 startDate
=> $t->get_planting_date(),
1789 endDate
=> $t->get_harvest_date(),
1790 programDbId
=>@
$programs[0]->[0],
1791 programName
=>@
$programs[0]->[1],
1792 designType
=> $tl->get_design_type(),
1795 meteoStationCode
=> "",
1796 meteoStationNetwork
=> "",
1798 studyComments
=> "",
1801 observationVariables
=> "",
1802 germplasm
=> \
@germplasm_data,
1806 my %metadata = (pagination
=>pagination_response
($total_count, $c->stash->{page_size
}, $c->stash->{current_page
}), status
=>\
@status);
1807 my %response = (metadata
=>\
%metadata, result
=>\
%result);
1808 $c->stash->{rest
} = \
%response;
1812 sub studies_layout
: Chained
('studies_single') PathPart
('layout') Args
(0) : ActionClass
('REST') { }
1814 sub studies_layout_POST
{
1817 my $auth = _authenticate_user
($c);
1818 my $status = $c->stash->{status
};
1819 my @status = @
$status;
1821 $c->stash->{rest
} = {status
=> \
@status};
1824 sub studies_layout_GET
{
1827 #my $auth = _authenticate_user($c);
1828 my $status = $c->stash->{status
};
1829 my @status = @
$status;
1831 my $total_count = 0;
1833 my $tl = CXGN
::Trial
::TrialLayout
->new( { schema
=> $self->bcs_schema, trial_id
=> $c->stash->{study_id
} });
1834 my $design = $tl->get_design();
1837 my $formatted_plot = {};
1842 foreach my $plot_number (keys %$design) {
1843 $check_id = $design->{$plot_number}->{is_a_control
} ?
1 : 0;
1844 if ($check_id == 1) {
1849 %optional_info = (germplasmName
=> $design->{$plot_number}->{accession_name
}, blockNumber
=> $design->{$plot_number}->{block_number
} ?
$design->{$plot_number}->{block_number
} : undef, rowNumber
=> $design->{$plot_number}->{row_number
} ?
$design->{$plot_number}->{row_number
} : undef, columnNumber
=> $design->{$plot_number}->{col_number
} ?
$design->{$plot_number}->{col_number
} : undef, type
=> $type);
1851 studyDbId
=> $c->stash->{study_id
},
1852 plotDbId
=> $design->{$plot_number}->{plot_id
},
1853 plotName
=> $design->{$plot_number}->{plot_name
},
1854 replicate
=> $design->{$plot_number}->{replicate
} ?
1 : 0,
1855 germplasmDbId
=> $design->{$plot_number}->{accession_id
},
1856 optionalInfo
=> \
%optional_info
1858 push @
$plot_data, $formatted_plot;
1861 %result = (data
=>$plot_data);
1862 my %metadata = (pagination
=>pagination_response
($total_count, $c->stash->{page_size
}, $c->stash->{current_page
}), status
=>\
@status);
1863 my %response = (metadata
=>\
%metadata, result
=>\
%result);
1864 $c->stash->{rest
} = \
%response;
1868 =head2 brapi/v1/studies/<studyDbId>/observationVariable/<observationVariableDbId>
1870 Usage: To retrieve phenotypic values on a the plot level for an entire trial
1872 Return JSON example:
1874 "metadata" : "status": [],
1886 "observationVariableDbId" : 393939,
1887 "observationVariableName" : "Yield",
1888 "plotName": "ZIPA_68_Ibadan_2014",
1889 "timestamp" : "2015-11-05 15:12",
1890 "uploadedBy" : {dbUserId},
1891 "operator" : "Jane Doe",
1892 "germplasmName": 143,
1903 sub studies_plot_phenotypes
: Chained
('studies_single') PathPart
('observationVariable') Args
(1) : ActionClass
('REST') { }
1905 sub studies_plot_phenotypes_POST
{
1908 my $trait_id = shift;
1909 my $auth = _authenticate_user
($c);
1910 my $status = $c->stash->{status
};
1911 my @status = @
$status;
1913 $c->stash->{rest
} = {status
=> \
@status};
1916 sub studies_plot_phenotypes_GET
{
1919 my $trait_id = shift;
1920 #my $auth = _authenticate_user($c);
1921 my $status = $c->stash->{status
};
1922 my @status = @
$status;
1925 my $t = $c->stash->{study};
1926 my $phenotype_data = $t->get_stock_phenotypes_for_trait($trait_id, 'plot');
1928 my $trait =$self->bcs_schema->resultset('Cv::Cvterm')->find({ cvterm_id
=> $trait_id });
1930 #print STDERR Dumper $phenotype_data;
1933 my $total_count = scalar(@
$phenotype_data);
1934 my $start = $c->stash->{page_size
}*($c->stash->{current_page
}-1);
1935 my $end = $c->stash->{page_size
}*$c->stash->{current_page
}-1;
1936 for( my $i = $start; $i <= $end; $i++ ) {
1937 if (@
$phenotype_data[$i]) {
1938 my $pheno_uniquename = @
$phenotype_data[$i]->[2];
1939 my ($part1 , $part2) = split( /date: /, $pheno_uniquename);
1940 my ($timestamp , $operator) = split( /\ \ operator = /, $part2);
1942 my $plot_id = @
$phenotype_data[$i]->[0];
1943 my $stock_plot_relationship_type_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema(), 'plot_of', 'stock_relationship')->cvterm_id();
1944 my $germplasm =$self->bcs_schema->resultset('Stock::StockRelationship')->find({ 'me.subject_id' => $plot_id, 'me.type_id' =>$stock_plot_relationship_type_id }, {join => 'object', '+select'=> ['object.stock_id', 'object.uniquename'], '+as'=> ['germplasm_id', 'germplasm_name'] } );
1946 my %data_hash = (studyDbId
=> $c->stash->{study_id
}, plotDbId
=> $plot_id, observationVariableDbId
=> $trait_id, observationVariableName
=> $trait->name(), plotName
=> @
$phenotype_data[$i]->[1], timestamp
=> $timestamp, uploadedBy
=> @
$phenotype_data[$i]->[3], operator
=> $operator, germplasmDbId
=> $germplasm->get_column('germplasm_id'), germplasmName
=> $germplasm->get_column('germplasm_name'), value
=> @
$phenotype_data[$i]->[4] );
1947 push @data, \
%data_hash;
1951 %result = (data
=>\
@data);
1952 my %metadata = (pagination
=>pagination_response
($total_count, $c->stash->{page_size
}, $c->stash->{current_page
}), status
=>\
@status);
1953 my %response = (metadata
=>\
%metadata, result
=>\
%result);
1954 $c->stash->{rest
} = \
%response;
1958 =head2 brapi/v1/studies/<studyDbId>/table
1960 Usage: To retrieve phenotypic values for a study, in a manner representative of a table, with headers and data separated
1962 Return JSON example:
1975 "observationVariableDbId": [ '', '', '', '', '', '', '', '', 44444, 55555, 66666...],
1976 "observationVariableName": [ "plotDbId", "plotName", "block", "rep", "germplasmID", "germplasmName", "operator", "timestamp", "Yield", "Color", "Dry Matter"...],
1980 [1, "plot1", 1, 1, "CIP1", 41, "user1", "2015-11-05 15:12", 10, "yellow", 9, ...],
1981 [2, "plot2", 1, 1, "CIP2", 42, "user1", "2015-11-05 20:12", 3, "red", 4, ...]
1990 sub studies_table
: Chained
('studies_single') PathPart
('table') Args
(0) : ActionClass
('REST') { }
1992 sub studies_table_POST
{
1995 my $trait_id = shift;
1996 my $auth = _authenticate_user
($c);
1997 my $status = $c->stash->{status
};
1998 my @status = @
$status;
2000 $c->stash->{rest
} = {status
=> \
@status};
2003 sub studies_table_GET
{
2006 #my $auth = _authenticate_user($c);
2007 my $status = $c->stash->{status
};
2008 my @status = @
$status;
2011 my $timestamp = $c->req->param("timestamp") || 0;
2012 my $bs = CXGN
::BreederSearch
->new( { dbh
=> $self->bcs_schema->storage->dbh() });
2013 my $trial_id = $c->stash->{study_id
};
2014 my $trial_sql = "\'$trial_id\'";
2015 my @data = $bs->get_extended_phenotype_info_matrix(undef,$trial_sql, undef, $timestamp);
2017 #print STDERR Dumper \@data;
2019 my $total_count = scalar(@data)-1;
2020 my @header_names = split /\t/, $data[0];
2021 #print STDERR Dumper \@header_names;
2022 my @trait_names = @header_names[11 .. $#header_names];
2023 #print STDERR Dumper \@trait_names;
2025 foreach my $t (@trait_names) {
2026 push @header_ids, SGN
::Model
::Cvterm
->get_cvterm_row_from_trait_name($self->bcs_schema, $t)->cvterm_id();
2029 my $start = $c->stash->{page_size
}*($c->stash->{current_page
}-1)+1;
2030 my $end = $c->stash->{page_size
}*$c->stash->{current_page
}+1;
2032 for (my $line = $start; $line < $end; $line++) {
2034 my @columns = split /\t/, $data[$line], -1;
2036 push @data_window, \
@columns;
2040 #print STDERR Dumper \@data_window;
2042 %result = (studyDbId
=> $c->stash->{study_id
}, observationVariableDbId
=> \
@header_ids, observationVariableName
=> \
@header_names, data
=>\
@data_window);
2043 my %metadata = (pagination
=>pagination_response
($total_count, $c->stash->{page_size
}, $c->stash->{current_page
}), status
=>\
@status);
2044 my %response = (metadata
=>\
%metadata, result
=>\
%result);
2045 $c->stash->{rest
} = \
%response;
2049 =head2 brapi/v1/phenotypes?observationUnitLevel=plot&studyDbId=876&studyPUI=&studyLocation=&studySet=&studyProject=&treatmentFactor=lowInput&germplasmGenus=&germplasmSubTaxa=&germplasmDbId&germplasmPUI=http://data.inra.fr/accession/234Col342&germplasmSpecies=Triticum&panel=diversitypanel1&collection=none&observationVariables=CO_321:000034,CO_321:000025&location=bergheim&season=2005,2006&pageSize={pageSize}&page={page}
2051 Usage: To retrieve a phenotype dataset
2053 Return JSON example:
2066 "observationUnitDbId": 20,
2067 "observationUnitPUI": "http://phenome-fppn.fr/maugio/bloc/12/2345",
2070 "studyLocation": "Bergheim",
2071 "studyPUI": "http://phenome-fppn.fr/phenoarch/2014/1",
2072 "studyProject": "Inovine",
2073 "studySet": ["National Network", "Frost suceptibility network"],
2074 "studyPlatform": "Phenome",
2075 "observationUnitLevelTypes" : [ "plant","plot", "bloc"],
2076 "observationUnitLevelLabels": [ "1","26123", "1"],
2077 "germplasmPUI": "http://inra.fr/vassal/41207Col0001E",
2078 "germplasmDbId": 3425,
2079 "germplasmName": "charger",
2083 "factor" : "water regimen" ,
2084 "modality":"water deficit"
2098 "instanceNumber" : 1,
2099 "observationVariableId": "CO_321:0000045",
2100 //"observationVariableDbId": 35,
2102 "observationValue" : "red",
2103 "observationTimeStamp": null,
2104 "quality": "reliability of the observation",
2105 "collectionFacilityLabel": "phenodyne",
2106 "collector" : "John Doe and team"
2109 "instanceNumber" : 1,
2110 "observationVariableId": "http://www.cropontology.org/rdf/CO_321:0000025",
2111 //"observationVariableDbId": 35,
2113 "observationValue" : 32,
2114 "observationTimeStamp": "2006-07-03::10:00",
2116 "collectionFacilityLabel": null,
2117 "collector" : "userURIOrName"
2128 sub phenotypes_dataset
: Chained
('brapi') PathPart
('phenotypes') Args
(0) : ActionClass
('REST') { }
2130 sub phenotypes_dataset_POST
{
2133 my $auth = _authenticate_user
($c);
2134 my $status = $c->stash->{status
};
2135 my @status = @
$status;
2137 $c->stash->{rest
} = {status
=> \
@status};
2140 sub phenotypes_dataset_GET
{
2143 #my $auth = _authenticate_user($c);
2144 my $status = $c->stash->{status
};
2145 my $params = $c->req->params();
2146 my @status = @
$status;
2148 my $study_id = $params->{studyDbId
};
2149 my $t = CXGN
::Trial
->new( { trial_id
=> $study_id, bcs_schema
=> $self->bcs_schema } );
2150 my $traits_assayed = $t->get_traits_assayed();
2151 print STDERR Dumper
$traits_assayed;
2153 my $count_limit = $c->stash->{page_size
};
2154 foreach (@
$traits_assayed) {
2155 if ($_->[2] < $count_limit) {
2159 $count_limit = $count_limit - $_->[2];
2165 my $total_count = '0';
2167 observationUnitDbId
=>
2169 my %metadata = (pagination
=>pagination_response
($total_count, $c->stash->{page_size
}, $c->stash->{current_page
}), status
=>\
@status);
2170 my %response = (metadata
=>\
%metadata, result
=>\
%result);
2171 $c->stash->{rest
} = \
%response;
2176 sub traits_list
: Chained
('brapi') PathPart
('traits') Args
(0) : ActionClass
('REST') { }
2178 sub traits_list_POST
{
2181 my $auth = _authenticate_user
($c);
2182 my $status = $c->stash->{status
};
2183 my @status = @
$status;
2185 $c->stash->{rest
} = {status
=> \
@status};
2188 sub traits_list_GET
{
2191 #my $auth = _authenticate_user($c);
2192 my $status = $c->stash->{status
};
2193 my @status = @
$status;
2195 #my $db_rs = $self->bcs_schema()->resultset("General::Db")->search( { name => $c->config->{trait_ontology_db_name} } );
2196 #if ($db_rs->count ==0) { return undef; }
2197 #my $db_id = $db_rs->first()->db_id();
2199 #my $q = "SELECT cvterm.cvterm_id, cvterm.name, cvterm.definition, cvtermprop.value, dbxref.accession FROM cvterm LEFT JOIN cvtermprop using(cvterm_id) JOIN dbxref USING(dbxref_id) WHERE dbxref.db_id=?";
2200 #my $h = $self->bcs_schema()->storage->dbh()->prepare($q);
2201 #$h->execute($db_id);
2203 my $q = "SELECT cvterm_id, name FROM materialized_traits;";
2204 my $p = $self->bcs_schema()->storage->dbh()->prepare($q);
2208 while (my ($cvterm_id, $name) = $p->fetchrow_array()) {
2209 my $q2 = "SELECT cvterm.definition, cvtermprop.value, dbxref.accession FROM cvterm LEFT JOIN cvtermprop using(cvterm_id) JOIN dbxref USING(dbxref_id) WHERE cvterm.cvterm_id=?";
2210 my $h = $self->bcs_schema()->storage->dbh()->prepare($q2);
2211 $h->execute($cvterm_id);
2213 while (my ($description, $scale, $accession) = $h->fetchrow_array()) {
2214 my @observation_vars = ();
2215 push (@observation_vars, ($name, $accession));
2216 push @data, { traitDbId
=> $cvterm_id, traitId
=> $name, name
=> $name, description
=> $description, observationVariables
=> \
@observation_vars, defaultValue
=> '', scale
=>$scale };
2220 my $total_count = $p->rows;
2221 my %result = (data
=> \
@data);
2222 my %metadata = (pagination
=>pagination_response
($total_count, $c->stash->{page_size
}, $c->stash->{current_page
}), status
=>\
@status);
2223 my %response = (metadata
=>\
%metadata, result
=>\
%result);
2224 $c->stash->{rest
} = \
%response;
2228 sub traits_single
: Chained
('brapi') PathPart
('traits') CaptureArgs
(1) {
2231 #my $auth = _authenticate_user($c);
2232 my $cvterm_id = shift;
2233 my $status = $c->stash->{status
};
2234 my @status = @
$status;
2237 my $q = "SELECT cvterm_id, name FROM materialized_traits where cvterm_id=?;";
2238 my $p = $self->bcs_schema()->storage->dbh()->prepare($q);
2239 $p->execute($cvterm_id);
2241 while (my ($cvterm_id, $name) = $p->fetchrow_array()) {
2242 my $q2 = "SELECT cvterm.definition, cvtermprop.value, dbxref.accession FROM cvterm LEFT JOIN cvtermprop using(cvterm_id) JOIN dbxref USING(dbxref_id) WHERE cvterm.cvterm_id=?";
2243 my $h = $self->bcs_schema()->storage->dbh()->prepare($q2);
2244 $h->execute($cvterm_id);
2246 while (my ($description, $scale, $accession) = $h->fetchrow_array()) {
2247 my @observation_vars = ();
2248 push (@observation_vars, ($name, $accession));
2249 %result = ( traitDbId
=> $cvterm_id, traitId
=> $name, name
=> $name, description
=> $description, observationVariables
=> \
@observation_vars, defaultValue
=> '', scale
=>$scale );
2253 my $total_count = $p->rows;
2254 my %metadata = (pagination
=>pagination_response
($total_count, $c->stash->{page_size
}, $c->stash->{current_page
}), status
=>\
@status);
2255 my %response = (metadata
=>\
%metadata, result
=>\
%result);
2256 $c->stash->{rest
} = \
%response;
2260 =head2 brapi/v1/maps?species=speciesId
2262 Usage: To retrieve a list of all maps available in the database.
2264 Return JSON example:
2280 "species": "Some species",
2283 "publishedDate": "2008-04-16",
2284 "markerCount": 1000,
2285 "linkageGroupCount": 7,
2286 "comments": "This map contains ..."
2290 "name": "Some Other map",
2291 "species": "Some Species",
2294 "publishedDate": "2009-01-12",
2295 "markerCount": 1501,
2296 "linkageGroupCount": 7,
2297 "comments": "this is blah blah"
2307 sub maps_list
: Chained
('brapi') PathPart
('maps') Args
(0) : ActionClass
('REST') { }
2309 sub maps_list_POST
{
2312 my $auth = _authenticate_user
($c);
2313 my $status = $c->stash->{status
};
2314 my @status = @
$status;
2316 $c->stash->{rest
} = {status
=> \
@status};
2322 #my $auth = _authenticate_user($c);
2323 my $status = $c->stash->{status
};
2324 my @status = @
$status;
2326 my $snp_genotyping_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'snp genotyping', 'genotype_property')->cvterm_id();
2327 my $rs = $self->bcs_schema()->resultset("NaturalDiversity::NdProtocol")->search( { } );
2330 while (my $row = $rs->next()) {
2332 print STDERR
"Retrieving map info for ".$row->name()." ID:".$row->nd_protocol_id()."\n";
2333 #$self->bcs_schema->storage->debug(1);
2334 my $lg_rs = $self->bcs_schema()->resultset("NaturalDiversity::NdProtocol")->search( { 'genotypeprops.type_id' => $snp_genotyping_cvterm_id, 'me.nd_protocol_id' => $row->nd_protocol_id() } )->search_related('nd_experiment_protocols')->search_related('nd_experiment')->search_related('nd_experiment_genotypes')->search_related('genotype')->search_related('genotypeprops', {}, {select=>['genotype.description', 'genotypeprops.value'], as
=>['description', 'value'], rows
=>1, order_by
=>{ -asc
=> 'genotypeprops.genotypeprop_id' }} );
2336 my $lg_row = $lg_rs->first();
2339 die "This was never supposed to happen :-(";
2342 my $scores = JSON
::Any
->decode($lg_row->get_column('value'));
2345 my $marker_count =0;
2346 foreach my $m (sort genosort
(keys %$scores)) {
2347 my ($chr, $pos) = split "_", $m;
2348 #print STDERR "CHR: $chr. POS: $pos\n";
2352 my $lg_count = scalar(keys(%chrs));
2355 mapId
=> $row->nd_protocol_id(),
2356 name
=> $row->name(),
2357 species
=> $lg_row->get_column('description'),
2360 markerCount
=> $marker_count,
2361 publishedDate
=> undef,
2363 linkageGroupCount
=> $lg_count,
2366 push @data, \
%map_info;
2369 my $total_count = scalar(@data);
2370 my $start = $c->stash->{page_size
}*($c->stash->{current_page
}-1);
2371 my $end = $c->stash->{page_size
}*$c->stash->{current_page
};
2372 my @data_window = splice @data, $start, $end;
2374 my %result = (data
=> \
@data_window);
2375 my %metadata = (pagination
=>pagination_response
($total_count, $c->stash->{page_size
}, $c->stash->{current_page
}), status
=>\
@status);
2376 my %response = (metadata
=>\
%metadata, result
=>\
%result);
2377 $c->stash->{rest
} = \
%response;
2382 =head2 brapi/v1/maps/<map_id>
2384 Usage: To retrieve details for a specific map_id
2386 Return JSON example:
2404 "linkageGroupId": 1,
2405 "numberMarkers": 100000,
2406 "maxPosition": 10000000
2409 "linkageGroupId": 2,
2410 "numberMarkers": 1247,
2411 "maxPostion": 12347889
2421 sub maps_single
: Chained
('brapi') PathPart
('maps') CaptureArgs
(1) {
2426 $c->stash->{map_id
} = $map_id;
2430 sub maps_details
: Chained
('maps_single') PathPart
('') Args
(0) : ActionClass
('REST') { }
2432 sub maps_details_POST
{
2435 my $auth = _authenticate_user
($c);
2436 my $status = $c->stash->{status
};
2437 my @status = @
$status;
2439 $c->stash->{rest
} = {status
=> \
@status};
2442 sub maps_details_GET
{
2445 #my $auth = _authenticate_user($c);
2446 my $status = $c->stash->{status
};
2447 my @status = @
$status;
2448 my $params = $c->req->params();
2449 my $total_count = 0;
2451 my $snp_genotyping_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'snp genotyping', 'genotype_property')->cvterm_id();
2453 # maps are just marker lists associated with specific protocols
2454 my $rs = $self->bcs_schema()->resultset("NaturalDiversity::NdProtocol")->find( { nd_protocol_id
=> $c->stash->{map_id
} } );
2458 print STDERR
"Retrieving map info for ".$rs->name()."\n";
2459 #$self->bcs_schema->storage->debug(1);
2460 my $lg_rs = $self->bcs_schema()->resultset("NaturalDiversity::NdExperimentProtocol")->search( { 'genotypeprops.type_id' => $snp_genotyping_cvterm_id, 'me.nd_protocol_id' => $rs->nd_protocol_id() })->search_related('nd_experiment')->search_related('nd_experiment_genotypes')->search_related('genotype')->search_related('genotypeprops', {}, {rows
=>1, order_by
=>{ -asc
=> 'genotypeprops.genotypeprop_id' }} );
2463 die "This was never supposed to happen :-(";
2468 my @ordered_refmarkers;
2469 while (my $profile = $lg_rs->next()) {
2470 my $profile_json = $profile->value();
2471 my $refmarkers = JSON
::Any
->decode($profile_json);
2472 #print STDERR Dumper($refmarkers);
2473 push @ordered_refmarkers, sort genosort
keys(%$refmarkers);
2477 foreach my $m (@ordered_refmarkers) {
2479 my ($chr, $pos) = split "_", $m;
2480 #print STDERR "CHR: $chr. POS: $pos\n";
2482 $markers{$chr}->{$m} = 1;
2485 if ($pos > $chrs{$chr}) {
2495 foreach my $ci (sort (keys %chrs)) {
2496 my $num_markers = scalar keys %{ $markers{$ci} };
2497 my %linkage_groups_data = (linkageGroupId
=> $ci, numberMarkers
=> $num_markers, maxPosition
=> $chrs{$ci} );
2498 push @data, \
%linkage_groups_data;
2501 $total_count = scalar(@data);
2502 my $start = $c->stash->{page_size
}*($c->stash->{current_page
}-1);
2503 my $end = $c->stash->{page_size
}*$c->stash->{current_page
};
2504 my @data_window = splice @data, $start, $end;
2507 mapId
=> $rs->nd_protocol_id(),
2508 name
=> $rs->name(),
2511 linkageGroups
=> \
@data_window,
2514 my %metadata = (pagination
=>pagination_response
($total_count, $c->stash->{page_size
}, $c->stash->{current_page
}), status
=>\
@status);
2515 my %response = (metadata
=>\
%metadata, result
=>\
%map_info);
2516 $c->stash->{rest
} = \
%response;
2520 =head2 brapi/v1/maps/<map_id>/position?linkageGroupIdList=1,2,3
2522 Usage: To retrieve marker position data for a species map_id. Can provide a list of linkage groups (e.g. chromosomes) to narrow result set.
2524 Return JSON example:
2527 "pagination" : { "pageSize": 30, "currentPage": 2, "totalCount": 40, "totalPages":2 },
2534 "markerName": "marker1",
2536 "linkageGroup": "1A"
2539 "markerName": "marker2",
2541 "linkageGroup": "1A"
2551 sub maps_marker_detail
: Chained
('maps_single') PathPart
('positions') Args
(0) : ActionClass
('REST') { }
2553 sub maps_marker_detail_POST
{
2556 my $auth = _authenticate_user
($c);
2557 my $status = $c->stash->{status
};
2558 my @status = @
$status;
2560 $c->stash->{rest
} = {status
=> \
@status};
2563 sub maps_marker_detail_GET
{
2566 #my $auth = _authenticate_user($c);
2567 my $status = $c->stash->{status
};
2568 my @status = @
$status;
2569 my $params = $c->req->params();
2572 if ($params->{linkageGroupIdList
}) {
2573 my $linkage_groups_list = $params->{linkageGroupIdList
};
2574 my @linkage_groups_array = split /,/, $linkage_groups_list;
2575 %linkage_groups = map { $_ => 1 } @linkage_groups_array;
2578 my $snp_genotyping_cvterm_id = SGN
::Model
::Cvterm
->get_cvterm_row($self->bcs_schema, 'snp genotyping', 'genotype_property')->cvterm_id();
2579 my $rs = $self->bcs_schema()->resultset("NaturalDiversity::NdProtocol")->find( { nd_protocol_id
=> $c->stash->{map_id
} } );
2582 print STDERR
"Retrieving map info for ".$rs->name()."\n";
2583 #$self->bcs_schema->storage->debug(1);
2584 my $lg_rs = $self->bcs_schema()->resultset("NaturalDiversity::NdProtocol")->search( { 'genotypeprops.type_id' => $snp_genotyping_cvterm_id, 'me.nd_protocol_id' => $rs->nd_protocol_id()})->search_related('nd_experiment_protocols')->search_related('nd_experiment')->search_related('nd_experiment_genotypes')->search_related('genotype')->search_related('genotypeprops', {}, {rows
=>1, order_by
=>{ -asc
=> 'genotypeprops.genotypeprop_id' }} );
2587 die "This was never supposed to happen :-(";
2590 my @ordered_refmarkers;
2591 while (my $profile = $lg_rs->next()) {
2592 my $profile_json = $profile->value();
2593 my $refmarkers = JSON
::Any
->decode($profile_json);
2594 #print STDERR Dumper($refmarkers);
2595 push @ordered_refmarkers, sort genosort
keys(%$refmarkers);
2600 foreach my $m (@ordered_refmarkers) {
2601 my ($chr, $pos) = split "_", $m;
2602 #print STDERR "CHR: $chr. POS: $pos\n";
2605 # "markerName": "marker1",
2606 # "location": "1000",
2607 # "linkageGroup": "1A"
2609 if (%linkage_groups) {
2610 if (exists $linkage_groups{$chr} ) {
2611 if ($params->{min
} && $params->{max
}) {
2612 if ($pos >= $params->{min
} && $pos <= $params->{max
}) {
2613 push @markers, { markerId
=> $m, markerName
=> $m, location
=> $pos, linkageGroup
=> $chr };
2615 } elsif ($params->{min
}) {
2616 if ($pos >= $params->{min
}) {
2617 push @markers, { markerId
=> $m, markerName
=> $m, location
=> $pos, linkageGroup
=> $chr };
2619 } elsif ($params->{max
}) {
2620 if ($pos <= $params->{max
}) {
2621 push @markers, { markerId
=> $m, markerName
=> $m, location
=> $pos, linkageGroup
=> $chr };
2624 push @markers, { markerId
=> $m, markerName
=> $m, location
=> $pos, linkageGroup
=> $chr };
2628 push @markers, { markerId
=> $m, markerName
=> $m, location
=> $pos, linkageGroup
=> $chr };
2633 my $total_count = scalar(@markers);
2634 my $start = $c->stash->{page_size
}*($c->stash->{current_page
}-1);
2635 my $end = $c->stash->{page_size
}*$c->stash->{current_page
};
2636 my @data_window = splice @markers, $start, $end;
2638 my %result = (data
=> \
@data_window);
2639 my %metadata = (pagination
=>pagination_response
($total_count, $c->stash->{page_size
}, $c->stash->{current_page
}), status
=>\
@status);
2640 my %response = (metadata
=>\
%metadata, result
=>\
%result);
2641 $c->stash->{rest
} = \
%response;
2645 sub locations_list
: Chained
('brapi') PathPart
('locations') Args
(0) : ActionClass
('REST') { }
2647 sub locations_list_POST
{
2650 my $auth = _authenticate_user
($c);
2651 my $status = $c->stash->{status
};
2652 my @status = @
$status;
2654 $c->stash->{rest
} = {status
=> \
@status};
2657 sub locations_list_GET
{
2660 #my $auth = _authenticate_user($c);
2661 my $status = $c->stash->{status
};
2662 my @status = @
$status;
2666 my $locations = CXGN
::Trial
::get_all_locations
($self->bcs_schema);
2668 my $total_count = scalar(@
$locations);
2669 my $start = $c->stash->{page_size
}*($c->stash->{current_page
}-1);
2670 my $end = $c->stash->{page_size
}*$c->stash->{current_page
}-1;
2671 for( my $i = $start; $i <= $end; $i++ ) {
2672 if (@
$locations[$i]) {
2673 push @data, {locationDbId
=> @
$locations[$i]->[0], name
=> @
$locations[$i]->[1], countryCode
=> @
$locations[$i]->[6], countryName
=> @
$locations[$i]->[5], latitude
=>@
$locations[$i]->[2], longitude
=>@
$locations[$i]->[3], altitude
=>@
$locations[$i]->[4], attributes
=> @
$locations[$i]->[7]};
2677 my %result = (data
=>\
@data);
2678 my %metadata = (pagination
=>pagination_response
($total_count, $c->stash->{page_size
}, $c->stash->{current_page
}), status
=>\
@status);
2679 my %response = (metadata
=>\
%metadata, result
=>\
%result);
2680 $c->stash->{rest
} = \
%response;
2685 sub authenticate
: Chained
('brapi') PathPart
('authenticate/oauth') Args
(0) {
2689 $c->res->redirect("https://accounts.google.com/o/oauth2/auth?scope=profile&response_type=code&client_id=1068256137120-62dvk8sncnbglglrmiroms0f5d7lg111.apps.googleusercontent.com&redirect_uri=https://cassavabase.org/oauth2callback");
2691 $c->stash->{rest
} = { success
=> 1 };