Skip to content

Commit

Permalink
[RFR] change some underlying code on Series/Objects pages, and clean up
Browse files Browse the repository at this point in the history
  • Loading branch information
Dan Levitas committed Aug 17, 2023
1 parent da018ad commit 3f4bad9
Show file tree
Hide file tree
Showing 8 changed files with 174 additions and 207 deletions.
53 changes: 0 additions & 53 deletions handler/ezBIDS_core/createThumbnailsMovies.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,59 +27,6 @@
# Functions


# def create_movie_thumbnails(nifti_file, output_dir, object_img_array, v):
# """
# Generates a PNG for each volume of a 4D acquisition.

# Parameters
# ----------

# nifti_file : string
# path of 4D nifti file.

# output_dir: string
# path of folder where movie PNG files will be stored

# object_img_array: numpy.darray
# result of nib.load(nifti_file).dataobj

# v: int
# volume index
# """

# max_len = len(str(object_img_array.shape[3]))

# if not os.path.isfile("{}/{}.png".format(output_dir, v)):

# slice_x = object_img_array[floor(object_img_array.shape[0] / 2), :, :, v]
# slice_y = object_img_array[:, floor(object_img_array.shape[1] / 2), :, v]
# slice_z = object_img_array[:, :, floor(object_img_array.shape[2] / 2), v]

# fig, axes = plt.subplots(1, 3, figsize=(9, 3))
# for index, slices in enumerate([slice_x, slice_y, slice_z]):
# axes[index].imshow(slices.T, cmap="gray", origin="lower", aspect="auto")
# axes[index].axis("off")
# plt.tight_layout(pad=0, w_pad=0, h_pad=0)
# plt.close()

# fig.canvas.draw()

# w, h = fig.canvas.get_width_height()
# buf = np.frombuffer(fig.canvas.tostring_argb(), dtype=np.uint8)
# buf.shape = (w, h, 4)

# buf = np.roll(buf, 3, axis=2)

# w, h, d = buf.shape
# png = Image.frombytes("RGBA", (w, h), buf.tobytes())

# # Sort files in UNIX-friendly way (i.e. zero pad)
# v_len = len(str(v))
# new_v = "0" * (max_len - v_len) + str(v)

# png.save("{}/{}.png".format(output_dir, new_v))


def create_thumbnail(nifti_file, image):
"""
Generates a PNG for the 2nd volume of a 4D acquisition.
Expand Down
18 changes: 10 additions & 8 deletions handler/ezBIDS_core/ezBIDS_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -1987,13 +1987,15 @@ def entity_labels_identification(dataset_list_unique_series, lookup_dic):

# echo
if (unique_dic["EchoNumber"]
and not any(x in unique_dic["type"] for x in ["fmap/epi",
"fmap/magnitude1",
"fmap/magnitude2",
"fmap/phasediff",
"fmap/phase1",
"fmap/phase2",
"fmap/fieldmap"])):
and not any(x in unique_dic["type"]for x in
[
"fmap/epi",
"fmap/magnitude1",
"fmap/magnitude2",
"fmap/phasediff",
"fmap/phase1",
"fmap/phase2",
"fmap/fieldmap"])):
series_entities["echo"] = str(unique_dic["EchoNumber"])

# flip
Expand Down Expand Up @@ -2232,7 +2234,6 @@ def modify_objects_info(dataset_list):
items.append({"path": item,
"name": "nii.gz",
"pngPaths": [],
"moviePath": None,
"headers": protocol["headers"]})

# Objects-level info for ezBIDS_core.json
Expand Down Expand Up @@ -2297,6 +2298,7 @@ def extract_series_info(dataset_list_unique_series):
"nifti_path": unique_dic["nifti_path"],
"series_idx": unique_dic["series_idx"],
"AcquisitionDateTime": unique_dic["AcquisitionDateTime"],
"PED": unique_dic["direction"],
"entities": unique_dic["entities"],
"type": unique_dic["type"],
"error": unique_dic["error"],
Expand Down
4 changes: 2 additions & 2 deletions handler/ezBIDS_core/update_ezBIDS_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"""
Created on Tue Jan 25 13:55:10 2022
update ezBIDS_core.json with pngPaths and moviePath
update ezBIDS_core.json with pngPaths
@author: dlevitas
"""
Expand All @@ -20,7 +20,7 @@

json_list = pd.read_csv("list", header=None, lineterminator="\n").to_numpy().flatten().tolist()

# place paths to thumbnails and movies in ezBIDS_core.json
# place paths to image thumbnails in ezBIDS_core.json
with open("ezBIDS_core.json", "r") as ezBIDS_json:
ezBIDS = json.load(ezBIDS_json)

Expand Down
26 changes: 13 additions & 13 deletions ui/src/Events.vue
Original file line number Diff line number Diff line change
Expand Up @@ -341,19 +341,19 @@ export default defineComponent({
//create new event objects
const eventObjects = createEventObjects(this.ezbids, files);
//adjust eventObjects error message based on exclusion of corresponding func/bold
this.ezbids.objects.forEach((o:IObject)=>{
let correspondingFuncBoldEvents = eventObjects.filter(object=>object.ModifiedSeriesNumber == o.ModifiedSeriesNumber && o._type == "func/bold")
if(correspondingFuncBoldEvents.length > 0) {
correspondingFuncBoldEvents.forEach(object=>{
object.analysisResults.errors = []
if(o._exclude == true) {
object.analysisResults.errors = [`The corresponding func/bold (#${o.series_idx}) to this acquisition has been set (or was set) to exclude from BIDS conversion. Recommendation is to also exclude this acquisition from BIDS conversion (assuming the func/bold is still set for exclusion), unless you have good reason for keeping it.`]
}
})
}
})
// //adjust eventObjects error message based on exclusion of corresponding func/bold
// this.ezbids.objects.forEach((o:IObject)=>{
// let correspondingFuncBoldEvents = eventObjects.filter(object=>object.ModifiedSeriesNumber == o.ModifiedSeriesNumber && o._type == "func/bold")
// if(correspondingFuncBoldEvents.length) {
// correspondingFuncBoldEvents.forEach(object=>{
// object.analysisResults.errors = []
// if(o._exclude == true) {
// object.analysisResults.errors = [`The corresponding func/bold (#${o.series_idx}) to this acquisition has been set (or was set) to exclude from BIDS conversion. Recommendation is to also exclude this acquisition from BIDS conversion (assuming the func/bold is still set for exclusion), unless you have good reason for keeping it.`]
// }
// })
// }
// })
eventObjects.forEach(object=>{
this.$store.commit("addObject", object);
Expand Down
128 changes: 62 additions & 66 deletions ui/src/Objects.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
@click="select(o, o_ses)">

<el-tag type="info" size="mini" v-if="o.series_idx !== undefined" :title="'Series#'+o.series_idx+' '+o._SeriesDescription">#{{o.series_idx}}</el-tag>&nbsp;
<datatype :type="o._type" :series_idx="o.series_idx" :entities="o.entities"/>
<datatype :type="o._type" :series_idx="o.series_idx" :entities="o._entities"/>
<small v-if="o._type == 'exclude'">&nbsp;({{o._SeriesDescription}})</small>

<span v-if="!isExcluded(o)">
Expand Down Expand Up @@ -473,86 +473,82 @@
break;
}
}
//for func/sbref object(s), update validationWarnings if corresponding func/bold has been excluded
/* Ensure direction (dir) entity labels are capitalized (e.g. AP, not ap).
Can occur when user adds this themselves.
*/
if(o._entities.direction && o._entities.direction !== "") {
if(o._entities.direction !== o._entities.direction.toUpperCase()) {
o.validationErrors.push("Please ensure that the phase-encoding direction entity label is fully capitalized")
}
}
//func/sbref are implicitly linked to a func/bold; make sure these have same entities and exclusion criteria
if(o._type == "func/sbref") {
let funcBoldObjects = this.$store.state.ezbids.objects.filter(o=>o._type == "func/bold" && (o._entities.part == "" || o._entities.part == "mag" || o._entities.part == "phase"))
funcBoldObjects.forEach(func=>{
//TODO - rewrite this.
let funcEntities = Object.fromEntries(Object.entries(func._entities).filter(([_, v]) => v != "")); //remove empty entity labels
let objEntities = Object.fromEntries(Object.entries(o._entities).filter(([_, v]) => v != "")); //remove empty entity labels
if(deepEqual(funcEntities, objEntities)) {
o.ModifiedSeriesNumber = func.ModifiedSeriesNumber
o.analysisResults.section_id = func.analysisResults.section_id
o.validationWarnings = [];
if(func._exclude === true || func._type == "exclude") {
o.exclude = true
o._exclude = true
o.validationWarnings = [`The corresponding func/bold #"+func.series_idx+" is currently set to exclude from BIDS conversion. \
Since this func/sbref is linked, it will also be excluded from conversion. Please modify if incorrect.`]
let correspondingFuncBold = this.ezbids.objects.filter((object:IObject)=>parseInt(object.ModifiedSeriesNumber) == parseInt(o.ModifiedSeriesNumber) + 1 && object._type == "func/bold") //func/sbref [should] always come right before their func/bold
if(correspondingFuncBold) { // should be no more than one
correspondingFuncBold.forEach((boldObj:IObject)=>{
o.analysisResults.section_id = boldObj.analysisResults.section_id
for(let k in boldObj._entities) {
if(boldObj._entities[k] !== "" && k !== "echo") {
if(k === "part" && boldObj._entities[k] === "phase") {
//pass
} else {
o._entities[k] = boldObj._entities[k]
}
}
}
if(func._exclude === false) {
if(boldObj._exclude === true || correspondingFuncBold._type === "exclude") {
o.exclude = true
o._exclude = true
o.validationWarnings = [`The corresponding func/bold #${boldObj.series_idx} is currently set to exclude from BIDS conversion. \
Since this func/sbref is linked, it will also be excluded from conversion unless the corresponding
func/bold is unexcluded. Please modify if incorrect.`]
}
if(boldObj._exclude === false) {
o.exclude = false
o._exclude = false
o.validationWarnings = []
}
}
})
})
}
}
//for func/events object(s), update series_idx and ModifiedSeriesNumber to match corresponding func/bold object.
//Also update validationWarnings if corresponding func/bold has been excluded
//func/events are implicitly linked to a func/bold; make sure these have same entities and exclusion criteria
if(o._type == "func/events") {
let funcBoldObjects = this.$store.state.ezbids.objects.filter(o=>o._type == "func/bold" && (o._entities.part == "" || o._entities.part == "mag" || o._entities.part == "phase"))
funcBoldObjects.forEach(func=>{
//TODO - rewrite this.
let funcEntities = Object.fromEntries(Object.entries(func._entities).filter(([_, v]) => v != "")); //remove empty entity labels
let objEntities = Object.fromEntries(Object.entries(o._entities).filter(([_, v]) => v != "")); //remove empty entity labels
if(deepEqual(funcEntities, objEntities)) {
o.ModifiedSeriesNumber = func.ModifiedSeriesNumber
o.analysisResults.section_id = func.analysisResults.section_id
o.validationWarnings = [];
if(func._exclude === true || func._type == "exclude") {
o.exclude = true
o._exclude = true
o.validationWarnings = ["The corresponding func/bold #"+func.series_idx+" is currently set to exclude from BIDS conversion. \
Since this func/sbref is linked, it will also be excluded from conversion. Please modify if incorrect."]
let correspondingFuncBold = this.ezbids.objects.filter((object:IObject)=>object._type == "func/bold" &&
object._entities.subject == o._entities.subject &&
object._entities.session == o._entities.session &&
object._entities.task == o._entities.task &&
object._entities.run == o._entities.run)
if(correspondingFuncBold) { // should be no more than one
correspondingFuncBold.forEach((boldObj:IObject)=>{
o.ModifiedSeriesNumber = boldObj.ModifiedSeriesNumber
o.analysisResults.section_id = boldObj.analysisResults.section_id
for(let k in boldObj._entities) {
if(boldObj._entities[k] !== "" && k !== "echo") {
if(k === "part" && boldObj._entities[k] === "phase") {
//pass
} else {
o._entities[k] = boldObj._entities[k]
}
}
}
if(func._exclude === false) {
if(boldObj._exclude === true || correspondingFuncBold._type === "exclude") {
o.exclude = true
o._exclude = true
o.validationWarnings = [`The corresponding func/bold #${boldObj.series_idx} is currently set to exclude from BIDS conversion. \
Since this func/events is linked, it will also be excluded from conversion unless the corresponding
func/bold is unexcluded. Please modify if incorrect.`]
}
if(boldObj._exclude === false) {
o.exclude = false
o._exclude = false
o.validationWarnings = []
}
}
})
//find bold object with the same set of entities
const matchingBold = this.$store.state.ezbids.objects
.filter((o:IObject)=>o._type == "func/bold")
////common func/bold acquisitions are magnitude ("mag"); the part entity label can have this value or be left blank. Both convey the same information
.filter((o:IObject)=>(o._entities.part == "" || o._entities.part == "mag"))
.find((func:IObject)=>{
for(let k in o._entities) {
if(o._entities[k] != func._entities[k]) return false;
}
return true
});
if(matchingBold) {
o.ModifiedSeriesNumber = matchingBold.ModifiedSeriesNumber;
o.analysisResults.section_id = matchingBold.analysisResults.section_id;
if(matchingBold._exclude) {
o.validationWarnings = ["The corresponding func/bold #${matchingBold.series_idx} is currently set to exclude from BIDS conversion. \
Since this func/sbref is linked, it will also be excluded from conversion. Please modify if incorrect."]
}
})
}
console.log(o)
}
},
Expand Down
Loading

0 comments on commit 3f4bad9

Please sign in to comment.