diff --git a/exact/exact/base/static/images/logo.svg b/exact/exact/base/static/images/logo.svg index ef474674..70e65b74 100644 --- a/exact/exact/base/static/images/logo.svg +++ b/exact/exact/base/static/images/logo.svg @@ -1,136 +1,22 @@ - - - - - EXACT annotation software logo - EXACT annotation software logo with stylized D mark and crosshair accent. - - - - - - - - - - - - - - - - EXACT - + + + + + + + + + + + + - - - - EXACT annotation software logo - - - - + \ No newline at end of file diff --git a/exact/requirements.txt b/exact/requirements.txt index 1b709adc..97d85514 100644 --- a/exact/requirements.txt +++ b/exact/requirements.txt @@ -7,7 +7,7 @@ confusable-homoglyphs==3.3.1 drf-flex-fields==1.0.2 -Django==4.2.18 +Django==4.2.30 django-appconf==1.0.5 django-extensions==3.2.3 django-filter==23.5 @@ -18,7 +18,7 @@ django-registration==3.4 django-templated-mail==1.1.1 django-widget-tweaks==1.5.0 djangorestframework==3.15.2 -djangorestframework-simplejwt==5.3.1 +djangorestframework-simplejwt==5.5.1 djoser==2.3.0 zarr==2.18.7 xmltodict==0.13.0 @@ -37,13 +37,13 @@ pyvips>=2.2.1 pydicom>=2.4.4 ptvsd>=4.3.2 czifile==2019.7.2 -GitPython==3.1.41 -gdown==5.1.0 +GitPython==3.1.50 +gdown==6.1.0 pandas==2.2.1 qt-wsi-registration==0.0.14 EXACT-Sync>=0.0.39 pyyaml>=6.0.1 -Werkzeug==3.0.6 +Werkzeug==3.1.8 h5py==3.10.0 slideio==2.7.1 django-passkeys==1.3.0.1 diff --git a/exact/util/slideio.py b/exact/util/slideio.py index fd7d09f8..38cdaf41 100644 --- a/exact/util/slideio.py +++ b/exact/util/slideio.py @@ -134,6 +134,60 @@ def frame_type(self): return FrameType.ZSTACK return FrameType.TIMESERIES + @property + def meta_data(self) -> dict: + result = {} + _dcm = self._read_dcm_meta() + if _dcm is None: + return result + def _get(tag, default=''): + v = getattr(_dcm, tag, None) + return str(v).strip() if v is not None else default + # Timing + ft = getattr(_dcm, 'FrameTime', None) + if ft is not None: + result['fps'] = round(1000.0 / float(ft), 3) + series_date = _get('SeriesDate') + series_time = _get('SeriesTime') + if series_date: + ts = series_date + if series_time: + t = series_time.split('.')[0] + ts += ' ' + t[:2] + ':' + t[2:4] + ':' + t[4:6] + result['acquisition_datetime'] = ts + # Device / study + for tag, key in [ + ('Modality', 'modality'), + ('Manufacturer', 'manufacturer'), + ('ManufacturerModelName','device_model'), + ('DeviceSerialNumber', 'device_serial'), + ('SeriesDescription', 'series_description'), + ('StudyDescription', 'study_description'), + ('PatientID', 'patient_id'), + ('InstitutionName', 'institution'), + ]: + v = _get(tag) + if v: + result[key] = v + return result + + @property + def meta_data_dict(self) -> dict: + labels = { + 'fps': 'Frame rate (fps)', + 'acquisition_datetime': 'Acquisition date/time', + 'modality': 'Modality', + 'manufacturer': 'Manufacturer', + 'device_model': 'Device model', + 'device_serial': 'Device serial', + 'series_description': 'Series description', + 'study_description': 'Study description', + 'patient_id': 'Patient ID', + 'institution': 'Institution', + } + present = self.meta_data + return {k: v for k, v in labels.items() if k in present} + def get_thumbnail(self, size): return Image.fromarray(self.scene.read_block(rect=[0, 0, *self.scene.rect[2:]], size=size))