Title: Update Acquisition container timestamp (shown in UI) from Dicom Tag SeriesTime in Dicom file
Date: 04-03-2020
Description:
This notebook can be used to update the Acquisition container timestamp (shown in UI) is not correct.
# Install specific packages required for this notebook
!pip install flywheel-sdk pandas
# Import packages
from getpass import getpass
import logging
import os
import datetime
import pandas as pd
import flywheel
from permission import check_user_permission
# Instantiate a logger
logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s %(message)s')
log = logging.getLogger('root')
API_KEY = getpass('Enter API_KEY here: ')
Instantiate the Flywheel API client
fw = flywheel.Client(API_KEY if 'API_KEY' in locals() else os.environ.get('FW_KEY'))
Show Flywheel logging information
log.info('You are now logged in as %s to %s', fw.get_current_user()['email'], fw.get_config()['site']['api_url'])
PROJECT_LABEL = input('Enter your project label here: ')
project = fw.projects.find_first(f'label={PROJECT_LABEL}')
Before starting off, we want to check your permission on the Flywheel Instance in order to proceed in this notebook.
min_reqs = {
"site": "user",
"group": "ro",
"project": ['containers_modify_metadata','files_view_metadata','files_view_contents','files_modify_metadata']
}
GROUP_ID = input('Please enter the Group ID that you will be working with: ')
check_user_permission
will return True if both the group and project meet the minimum requirement, else a compatible list will be printed.
check_user_permission(fw, min_reqs, group=GROUP_ID, project=PROJECT_LABEL)
def update_acquisition_timestamp(item):
"""Get and modify the updated timestamp., if there is any discrepancy between the two timestamps.
Args:
item (dict): Dictionary with the following required keys: 'timestamp', 'series_time', 'acq_id'
Return:
(datetime): Updated Timestamp
"""
correctTmstmp = modify_time(item['timestamp'], item['series_time'])
#only update the container if there is any changes
if correctTmstmp != item['timestamp']:
update_container_timestamp(item['acq_id'], correctTmstmp)
return correctTmstmp
def modify_time(timestamp, series_time):
"""Modify the timestamp.
Args:
timestamp (datetime): Timestamp
series_time (datetime): Reference Timestamp
Return:
(datetime): Updated Timestamp
"""
if (timestamp.hour != series_time.hour) or (timestamp.minute != series_time.minute) or (timestamp.second != series_time.second):
timestamp = timestamp.replace(hour=series_time.hour, minute=series_time.minute, second=series_time.second)
return timestamp
def update_container_timestamp(acq_id, ts):
"""Update the acquisition container timestamp with `ts`.
Args:
acq_id (str) : Acquisition ID
ts (datetime) : Timestamp
"""
acq = fw.get_acquisition(acq_id)
acq.update({'timestamp': ts})
Here, we will get the acquistion container timestamp (timestamp
) and the series timestamp (series_time
) generated from the DICOM file. The get_updated_timestamp
function will be call and return with the updated_timestamp.
df = pd.DataFrame()
for session in project.sessions.iter():
for acquisition in session.acquisitions.iter():
#reload is necessary to load the entire acquisition
acquisition = acquisition.reload()
for file in acquisition.files :
if file['type'] == 'dicom':
item = {
'series_number': file.info.get('SeriesNumber'),
'acq_label': acquisition.label,
'acq_id': acquisition.id,
'timestamp': acquisition.timestamp,
'series_time': datetime.datetime.strptime(file.info.get('SeriesTime'), '%H%M%S.%f'),
}
item['updated_timestamp'] = update_acquisition_timestamp(item)
# append to the table
df = df.append(item, ignore_index=True)
df.iloc[:, [3,4,5]].head(10)
series_time | timestamp | updated_timestamp | |
---|---|---|---|
0 | 1900-01-01 13:28:08.418 | 2019-10-27 13:30:08+00:00 | 2019-10-27 13:28:08+00:00 |
1 | 1900-01-01 13:12:28.470 | 2019-10-27 13:14:14+00:00 | 2019-10-27 13:12:28+00:00 |
2 | 1900-01-01 13:40:49.388 | 2019-10-27 13:30:45+00:00 | 2019-10-27 13:40:49+00:00 |
3 | 1900-01-01 13:40:18.805 | 2019-10-27 08:24:33+00:00 | 2019-10-27 13:40:18+00:00 |
4 | 1900-01-01 12:28:54.360 | 2019-10-27 12:28:35+00:00 | 2019-10-27 12:28:54+00:00 |
5 | 1900-01-01 12:59:48.381 | 2019-10-27 13:03:34+00:00 | 2019-10-27 12:59:48+00:00 |
6 | 1900-01-01 12:59:48.265 | 2019-10-27 13:03:32+00:00 | 2019-10-27 12:59:48+00:00 |
7 | 1900-01-01 12:28:54.324 | 2019-10-27 12:28:35+00:00 | 2019-10-27 12:28:54+00:00 |
8 | 1900-01-01 13:26:22.327 | 2019-10-27 13:15:31+00:00 | 2019-10-27 13:26:22+00:00 |
9 | 1900-01-01 13:05:28.439 | 2019-10-27 13:08:44+00:00 | 2019-10-27 13:05:28+00:00 |