Skip to content

Commit 1af77b6

Browse files
authored
Merge pull request #1500 from ImagingDataCommons/release-49-sp
cart and filter downloads
2 parents ddd1b06 + 45aced5 commit 1af77b6

6 files changed

Lines changed: 108 additions & 51 deletions

File tree

idc/views.py

Lines changed: 45 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@
3939
from cohorts.models import Cohort, Cohort_Perms
4040

4141
from idc_collections.models import Program, DataSource, Collection, ImagingDataCommonsVersion, Attribute, Attribute_Tooltips, DataSetType, Citation
42-
from idc_collections.collex_metadata_utils import build_explorer_context, get_collex_metadata, create_file_manifest, get_cart_data_serieslvl, get_cart_data_studylvl, get_table_data_with_cart_data
42+
from idc_collections.collex_metadata_utils import (build_explorer_context, get_collex_metadata, create_file_manifest,
43+
get_cart_data_serieslvl, get_cart_data_studylvl,
44+
get_table_data_with_cart_data, cart_manifest)
4345
from allauth.socialaccount.models import SocialAccount
4446
from django.core.exceptions import ObjectDoesNotExist
4547
from django.http import HttpResponse, JsonResponse
@@ -48,7 +50,7 @@
4850
from idc.models import User_Data
4951
from solr_helpers import build_solr_query, query_solr_and_format_result
5052

51-
53+
from idc.settings import MAX_FILE_LIST_REQUEST
5254

5355
debug = settings.DEBUG
5456
logger = logging.getLogger(__name__)
@@ -678,35 +680,48 @@ def cart_data(request):
678680
return JsonResponse(response, status=status)
679681

680682

681-
def get_series(request, collection_id, patient_id=None, study_uid=None):
683+
def get_series(request, collection_id=None, patient_id=None, study_uid=None):
684+
status = 200
685+
response = {"result": []}
682686
try:
683-
status = 200
684-
response = { "result": [] }
685-
source = ImagingDataCommonsVersion.objects.get(active=True).get_data_sources(
686-
active=True, source_type=DataSource.SOLR,
687-
aggregate_level="SeriesInstanceUID"
688-
).first()
689-
filters = {
690-
"collection_id": [collection_id]
691-
}
692-
if patient_id:
693-
filters['PatientID'] = [patient_id]
694-
if study_uid:
695-
filters["StudyInstanceUID"] = [study_uid]
696-
filter_query = build_solr_query(
697-
filters,
698-
with_tags_for_ex=False,
699-
search_child_records_by=None, solr_default_op='AND'
700-
)
701-
result = query_solr_and_format_result(
702-
{
703-
"collection": source.name,
704-
"fields": ["collection_id", "PatientID", "StudyInstanceUID", "Modality", "crdc_series_uuid", "SeriesInstanceUID", "aws_bucket", "instance_size"],
705-
"query_string": None,
706-
"fqs": [filter_query['full_query_str']],
707-
"facets": None, "sort": None, "counts_only": False, "limit": 2000
687+
fields = ["collection_id", "PatientID", "StudyInstanceUID", "Modality", "crdc_series_uuid", "SeriesInstanceUID", "aws_bucket", "instance_size"]
688+
result = {}
689+
if not collection_id:
690+
# This is a request for filters and/or a cart
691+
body_unicode = request.body.decode('utf-8')
692+
body = json.loads(body_unicode)
693+
partitions = body.get("partitions", {})
694+
filtergrp_list = body.get("filtergrp_list", {})
695+
if not(len(partitions) or len(filtergrp_list)):
696+
raise Exception("You can only request series IDs based on a filter, collection ID, Patient ID, or study ID!")
697+
result = cart_manifest(filtergrp_list, partitions, 0, fields, MAX_FILE_LIST_REQUEST)
698+
else:
699+
source = ImagingDataCommonsVersion.objects.get(active=True).get_data_sources(
700+
active=True, source_type=DataSource.SOLR,
701+
aggregate_level="SeriesInstanceUID"
702+
).first()
703+
filters = {
704+
"collection_id": [collection_id]
708705
}
709-
)
706+
if patient_id:
707+
filters['PatientID'] = [patient_id]
708+
if study_uid:
709+
filters["StudyInstanceUID"] = [study_uid]
710+
filter_query = build_solr_query(
711+
filters,
712+
with_tags_for_ex=False,
713+
search_child_records_by=None, solr_default_op='AND'
714+
)
715+
result = query_solr_and_format_result(
716+
{
717+
"collection": source.name,
718+
"fields": fields,
719+
"query_string": None,
720+
"fqs": [filter_query['full_query_str']],
721+
"facets": None, "sort": None, "counts_only": False, "limit": 2000
722+
}
723+
)
724+
710725
for doc in result['docs']:
711726
response['result'].append({
712727
"series_id": doc['SeriesInstanceUID'],
@@ -716,7 +731,7 @@ def get_series(request, collection_id, patient_id=None, study_uid=None):
716731
"modality": doc['Modality'][0],
717732
"study_id": doc['StudyInstanceUID'],
718733
"patient_id": doc["PatientID"],
719-
"collection_id": doc['collection_id']
734+
"collection_id": doc['collection_id'][0]
720735
})
721736

722737
except Exception as e:

static/js/cohorts/export-manifest.js

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,29 +75,28 @@ require([
7575
if (button.hasClass('series-export') || button.hasClass('study-export')){
7676
update_export_modal_for_mini(button);
7777
} else if (button.hasClass('cart-export')){
78-
updatePartitionsFromScratch();
7978
window.updatePartitionsFromScratch();
80-
var ret =cartutils.formcartdata();
79+
let ret = cartutils.formcartdata();
8180
window.partitions = ret[0];
8281
window.filtergrp_lst = ret[1];
8382

84-
var projS = new Set();
83+
let projS = new Set();
8584
for (var i=0;i<partitions.length;i++){
8685
projS.add(partitions[i].id[0]);
8786
}
88-
var mxstudies=0;
89-
var mxseries=0;
90-
var projl = [...projS]
91-
for (var i=0;i<projl.length;i++){
92-
var proj = projl[i]
87+
let mxstudies=0;
88+
let mxseries=0;
89+
let projl = [...projS]
90+
for (let i=0;i<projl.length;i++){
91+
let proj = projl[i]
9392
mxseries+= window.selProjects[proj].mxseries;
9493
mxstudies+= window.selProjects[proj].mxstudies;
9594
}
96-
var filterSets = new Array();
95+
let filterSets = [];
9796
for(let i=0; i< window.cartHist.length;i++) {
9897
filterSets.push(window.cartHist[i]['filter'])
9998
}
100-
update_export_modal_for_cart(partitions, filterSets);
99+
update_export_modal_for_cart(window.partitions, filterSets);
101100
} else if (button.hasClass('cart-export-from-cp')){
102101
update_export_modal_for_cart(window.partitions, window.filtergrp_list);
103102
} else if(button.hasClass('export-cohort-manifest')) {

static/js/downloader.js

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,19 @@ require.config({
2121
baseUrl: STATIC_FILES_URL + 'js/',
2222
paths: {
2323
jquery: 'libs/jquery-3.7.1.min',
24-
base: 'base'
24+
base: 'base',
25+
cartutils: 'cartutils',
26+
filterutils: 'filterutils'
27+
},
28+
shim: {
29+
'cartutils': ['jquery'],
30+
'filterutils': ['jquery']
2531
}
2632
});
2733

2834
require([
29-
'base', 'jquery'
30-
], function (base, $) {
35+
'base', 'jquery', 'cartutils', 'filterutils',
36+
], function (base, $, cartutils, filterutils) {
3137

3238
const byte_level = Object.freeze({
3339
1: "KB",
@@ -423,7 +429,6 @@ require([
423429
response = await fetch(s3_url, {
424430
signal: abort_controller.signal
425431
});
426-
console.error("Checking response.");
427432
if (!response.ok) {
428433
console.error("[Worker] Saw !ok response of ",response.status);
429434
if(pending_abort) {
@@ -749,8 +754,34 @@ require([
749754

750755
} else {
751756
let response = null;
752-
if(download_type in ["filter", "cart"]) {
753-
response = await fetch(`${BASE_URL}${SERIES_IDS_FILTER_URL}`);
757+
if(["cohort", "cart"].includes(download_type)) {
758+
let filter_and_cart = {};
759+
if (download_type === "cohort") {
760+
let filtergrp_list = [];
761+
for(const [attr, vals] of Object.entries(filterutils.parseFilterObj())) {
762+
filtergrp_list.push({[attr]: vals});
763+
}
764+
filter_and_cart["filtergrp_list"] = filtergrp_list;
765+
} else {
766+
window.updatePartitionsFromScratch();
767+
let ret = cartutils.formcartdata();
768+
window.partitions = ret[0];
769+
window.filtergrp_lst = ret[1];
770+
let filterSets = [];
771+
for(let i=0; i< window.cartHist.length;i++) {
772+
filterSets.push(window.cartHist[i]['filter']);
773+
}
774+
filter_and_cart['partitions'] = window.partitions;
775+
filter_and_cart['filtergrp_list'] = filterSets;
776+
}
777+
response = await fetch(`${BASE_URL}${SERIES_IDS_FILTER_URL}`, {
778+
method: "POST",
779+
body: JSON.stringify(filter_and_cart),
780+
headers: {
781+
"X-CSRFToken": csrftoken,
782+
"content-type": "application/json"
783+
}
784+
});
754785
} else {
755786
let study_uri = (study_id !== undefined && study_id !== null) ? `${study_id}/` : "";
756787
let patient_uri = (patient_id !== undefined && patient_id !== null) ? `${patient_id}/` : "";

static/js/explore.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -483,8 +483,8 @@ require([
483483

484484
const download_tooltip = {
485485
dynamicTip: function(ref){
486-
let table_type = $(ref).parents('table').attr('data-table-type');
487-
return `Download all of the image instances in this ${table_type}.`;
486+
let download_type = $(ref).attr('data-download-type');
487+
return `Download all of the image instances in this ${download_type}.`;
488488
},
489489
content: 'Download all images.', // placeholder text
490490
theme: 'dark',

static/js/image_search.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ require([
141141
success: function (data) {
142142
try {
143143
let curInd = window.cartHist.length-1;
144-
let tmp=filterutils.parseFilterObj()
144+
let tmp=filterutils.parseFilterObj();
145145
let filtObj=JSON.parse(JSON.stringify(tmp));
146146
if (cartHist[curInd].selections.length>0){
147147
let cartSel = new Object();

templates/idc/explore_data_core.html

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -630,7 +630,13 @@ <h4>Cohort Filters</h4>
630630
data-default-title="Export this cohort's series as a manifest for download."
631631
data-target="#export-manifest-modal"
632632
title="Select a filter to enable this feature."
633-
> Manifest <i class="fa fa-solid fa-download"></i>
633+
> Manifest <i class="fa fa-solid fa-list"></i>
634+
</button>
635+
<button id="download-cohort-images" class="btn btn-primary btn-small filter-activated-controls download-all-instances" disabled
636+
data-default-title="Download the instance image files for this cohort."
637+
title="Select a filter to enable this feature."
638+
data-download-type="cohort"
639+
> Download <i class="fa fa-solid fa-download"></i>
634640
</button>
635641
<button class="btn btn-small btn-special citations-button filter-activated-controls" disabled data-toggle="modal" data-target="#citations-modal" role="button"
636642
data-default-title="Display this cohort's citation list in Vancouver format."
@@ -675,7 +681,13 @@ <h4>Cart</h4>
675681
<button id="export-manifest-cart" class="btn btn-primary cart-export btn-small cart-activated-controls" disabled data-toggle="modal"
676682
data-target="#export-manifest-modal"
677683
title="Add items to the cart to enable this feature."
678-
> Manifest <i class="fa fa-solid fa-download"></i>
684+
> Manifest <i class="fa fa-solid fa-list"></i>
685+
</button>
686+
<button id="download-cart-images" class="btn btn-primary btn-small cart-activated-controls download-all-instances" disabled
687+
data-default-title="Download the instance image files for this cart."
688+
title="Select a filter to enable this feature."
689+
data-download-type="cart"
690+
> Download <i class="fa fa-solid fa-download"></i>
679691
</button>
680692
<button class="btn btn-small btn-special citations-button cart-activated-controls for-cart" disabled data-toggle="modal" data-target="#citations-modal" role="button"
681693
data-default-title="Display this cart's citation list in Vancouver format."

0 commit comments

Comments
 (0)