Skip to content

Commit

Permalink
Merge pull request #413 from DigitalSlideArchive/name-template
Browse files Browse the repository at this point in the history
Name template option
  • Loading branch information
manthey authored Nov 26, 2024
2 parents 2a680f6 + efc17cd commit 0014f92
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 13 deletions.
1 change: 1 addition & 0 deletions devops/wsi_deid/girder.local.conf
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ cache_memcached_password = None
enabled = True

[wsi_deid]
name_template = "{tokenId}"
redact_macro_square = False
always_redact_label = False
edit_metadata = False
Expand Down
14 changes: 12 additions & 2 deletions docs/CUSTOMIZING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,6 @@ If ``InputFileName`` is added to the list of export fields in the ``upload_metad
import_text_association_columns = ["SurgPathNum", "First_Name", "Last_Name", "Date_of_Birth"]
...
Choosing Custom Metadata To Add to Exported Images
++++++++++++++++++++++++++++++++++++++++++++++++++

Expand All @@ -354,7 +353,6 @@ If the setting is absent or set to ``None``, then all metadata from the upload f
upload_metadata_add_to_images = None
...
Creating New TokenIDs for Refiling Images
+++++++++++++++++++++++++++++++++++++++++

Expand All @@ -371,6 +369,18 @@ For example, if the specified pattern is ``0123#@@1###``, a randomly generated T
new_token_pattern = "####@@#####"
...
Naming Images Based on Database Values
++++++++++++++++++++++++++++++++++++++

By default, images filed based on database lookup are named based on their ``tokenId`` and a unique image number. This can be changed to include data from the database lookup, if it is exists. The ``name_template`` specifies how this is done; the default is ``{tokenId}``. You can include, for instance, a tumor record number by changing it to ``{tokenId}_{tumor_record_number}``. Note that if all fields are not present, it will default to the tokenId.

.. code-block:: python
[wsi_deid]
...
name_templaye = "{tokenId}"
...
An Example to Allow All Import Files
++++++++++++++++++++++++++++++++++++

Expand Down
21 changes: 21 additions & 0 deletions wsi_deid/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import json
import os
import re
import string

import girder
import PIL.Image
Expand Down Expand Up @@ -143,6 +144,26 @@ def validateNewTokenPattern(doc):
doc['value'] = None


@setting_utilities.validator({
PluginSettings.WSI_DEID_BASE + 'name_template',
})
def validateStringTemplate(doc):
if doc.get('value', None) is not None:
doc['value'] = re.sub(
r'\{tokenid\}', '{tokenId}', str(doc['value']).strip(),
flags=re.IGNORECASE)
try:
names = [fn for _, fn, _, _ in string.Formatter().parse(doc['value']) if fn is not None]
except Exception:
names = []
if not len(names):
msg = 'The template string must contain at least one reference in brases'
raise ValidationException(msg)

if not doc['value']:
doc['value'] = None


@setting_utilities.validator({
PluginSettings.WSI_DEID_BASE + 'hide_metadata_keys',
PluginSettings.WSI_DEID_BASE + 'hide_metadata_keys_format_aperio',
Expand Down
1 change: 1 addition & 0 deletions wsi_deid/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
'show_next_item': True,
'show_metadata_in_lists': True,
'show_next_folder': True,
'name_template': '{tokenid}',
'no_redact_control_keys': {
r'^internal;aperio_version$': '',
r'^internal;openslide;openslide\.(?!comment$)': '',
Expand Down
7 changes: 4 additions & 3 deletions wsi_deid/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from . import config, matching_api
from .constants import TokenOnlyPrefix
from .process import get_image_barcode, get_image_text, refile_image
from .process import get_image_barcode, get_image_name, get_image_text, refile_image


def start_ocr_item_job(job):
Expand Down Expand Up @@ -163,8 +163,9 @@ def match_images_via_api(imageIds, userId, job, reportInfo):
tokenId = result[0]['token_id']
info = {'fields': result[0].get('tumors')[0]}
oldName = item['name']
item = refile_image(item, user, tokenId, TokenOnlyPrefix + tokenId,
{TokenOnlyPrefix + tokenId: info})
newNameRoot = get_image_name(tokenId, info)
item = refile_image(item, user, tokenId, TokenOnlyPrefix + newNameRoot,
{TokenOnlyPrefix + newNameRoot: info})
Job().updateJob(
job,
log=f'Moved item {oldName} to folder {tokenId} as {item["name"]} based on api lookup\n',
Expand Down
12 changes: 12 additions & 0 deletions wsi_deid/process.py
Original file line number Diff line number Diff line change
Expand Up @@ -1724,6 +1724,18 @@ def get_image_barcode(item):
return results


def get_image_name(prefix, info):
template = config.getConfig('name_template') or '{tokenId}'
try:
name = template.format(tokenId=prefix, **info['fields'])
if name != template and name:
return name
except Exception:
logger.exception(
'Could not fill name template (%r) with tokenId=%s, %r', template, prefix, info)
return prefix


def refile_image(item, user, tokenId, imageId, uploadInfo=None):
"""
Refile an item to a new name and folder.
Expand Down
8 changes: 8 additions & 0 deletions wsi_deid/web_client/templates/ConfigView.pug
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,14 @@ form#g-wsi_deid-form(role="form")
p.g-hui-description
| All of the settings in this section can be specified through the Girder configuration file. If changed via these settings, these values override the values in the configuration file.

.form-group
label(for="g-wsi-deid-base_name_template") Image Name Template
p.g-hui-description
| By default, items imported and matched to a database are given a name of the returned tokenId and a unique image number. Additional data from the database record can be added as part of the name. The template is in the python format string style.
input#g-wsi-deid-base_name_template.form-control.input-sm(
type="text", value=settings['wsi_deid.base_name_template'] || '',
title='A python template string style, such as "{tokenId}"',
spellcheck="false")
.form-group
input#g-wsi-deid-base_add_title_to_label.input-sm(type="checkbox", checked=(settings['wsi_deid.base_add_title_to_label'] ? "checked" : undefined))
label(for="g-wsi-deid-base_add_title_to_label") Add File Name To Label
Expand Down
16 changes: 8 additions & 8 deletions wsi_deid/web_client/views/HierarchyWidget.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,19 +196,19 @@ function addControls(key, settings) {
{
key: 'redactlist',
text: 'Redact Checked',
class: 'btn-info disabled',
class: 'btn-primary disabled',
action: 'list/process',
check: () => settings.show_metadata_in_lists
}, {
key: 'import',
text: 'Import',
class: 'btn-info',
class: 'btn-primary',
action: 'ingest',
check: () => settings.show_import_button !== false
}, {
key: 'ocr',
text: 'Find label text',
class: 'btn-info',
class: 'btn-primary',
action: 'ocrall',
check: _.constant(true)
}
Expand All @@ -217,13 +217,13 @@ function addControls(key, settings) {
{
key: 'export',
text: 'Export Recent',
class: 'btn-info',
class: 'btn-primary',
action: 'export',
check: () => settings.show_export_button !== false
}, {
key: 'exportall',
text: 'Export All',
class: 'btn-info',
class: 'btn-primary',
action: 'exportall',
check: () => settings.show_export_button !== false
}
Expand All @@ -232,7 +232,7 @@ function addControls(key, settings) {
{
key: 'finishlist',
text: 'Approve Checked',
class: 'btn-info disabled',
class: 'btn-primary disabled',
action: 'list/finish',
check: () => settings.show_metadata_in_lists
}
Expand All @@ -241,7 +241,7 @@ function addControls(key, settings) {
{
key: 'redactlist',
text: 'Redact Checked',
class: 'btn-info disabled',
class: 'btn-primary disabled',
action: 'list/process',
check: () => settings.show_metadata_in_lists
}
Expand All @@ -250,7 +250,7 @@ function addControls(key, settings) {
{
key: 'import',
text: 'Import',
class: 'btn-info',
class: 'btn-primary',
action: 'ingest',
check: () => settings.show_import_button !== false
}
Expand Down

0 comments on commit 0014f92

Please sign in to comment.