Skip to content

utils

compute_fileset_matches Link

compute_fileset_matches(scan)

Return a dictionary mapping the scan tasks to fileset names.

Parameters:

Name Type Description Default

scan Link

Scan

The scan instance to list the filesets from.

required

Returns:

Type Description
dict

A dictionary mapping the scan tasks to fileset names.

Examples:

>>> from plantdb.server.core.utils import compute_fileset_matches
>>> from plantdb.commons.test_database import dummy_db
>>> db = dummy_db(with_fileset=True)
>>> scan = db.get_scan("myscan_001")
>>> compute_fileset_matches(scan)
{'fileset': 'fileset_001'}
>>> db.disconnect()  # clean up (delete) the temporary dummy database
Source code in plantdb/server/core/utils.py
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
def compute_fileset_matches(scan):
    """Return a dictionary mapping the scan tasks to fileset names.

    Parameters
    ----------
    scan : plantdb.commons.fsdb.core.Scan
        The scan instance to list the filesets from.

    Returns
    -------
    dict
        A dictionary mapping the scan tasks to fileset names.

    Examples
    --------
    >>> from plantdb.server.core.utils import compute_fileset_matches
    >>> from plantdb.commons.test_database import dummy_db
    >>> db = dummy_db(with_fileset=True)
    >>> scan = db.get_scan("myscan_001")
    >>> compute_fileset_matches(scan)
    {'fileset': 'fileset_001'}
    >>> db.disconnect()  # clean up (delete) the temporary dummy database
    """
    filesets_matches = {}
    for fs in scan.get_filesets():
        x = fs.id.split('_')[0]  # get the task name
        filesets_matches[x] = fs.id
    return filesets_matches

get_file_uri Link

get_file_uri(scan, fileset, file)

Return the URI for the corresponding scan/fileset/file tree.

Parameters:

Name Type Description Default

scan Link

Scan or str

A Scan instance or the name of the scan dataset.

required

fileset Link

Fileset or str

A Fileset instance or the name of the fileset.

required

file Link

File or str

A File instance or the name of the file.

required

Returns:

Type Description
str

The URI for the corresponding scan/fileset/file tree.

Examples:

>>> from plantdb.server.core.utils import compute_fileset_matches
>>> from plantdb.server.core.utils import get_file_uri
>>> from plantdb.commons.test_database import test_database
>>> db = test_database('real_plant_analyzed')
>>> db.connect()
>>> scan = db.get_scan('real_plant_analyzed')
>>> fs_match = compute_fileset_matches(scan)
>>> fs = scan.get_fileset(fs_match['PointCloud'])
>>> f = fs.get_file("PointCloud")
>>> get_file_uri(scan, fs, f)
'/files/real_plant_analyzed/PointCloud_1_0_1_0_10_0_7ee836e5a9/PointCloud.ply'
Source code in plantdb/server/core/utils.py
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
def get_file_uri(scan, fileset, file):
    """Return the URI for the corresponding `scan/fileset/file` tree.

    Parameters
    ----------
    scan : plantdb.commons.fsdb.core.Scan or str
        A ``Scan`` instance or the name of the scan dataset.
    fileset : plantdb.commons.fsdb.core.Fileset or str
        A ``Fileset`` instance or the name of the fileset.
    file : plantdb.commons.fsdb.core.File or str
        A ``File`` instance or the name of the file.

    Returns
    -------
    str
        The URI for the corresponding `scan/fileset/file` tree.

    Examples
    --------
    >>> from plantdb.server.core.utils import compute_fileset_matches
    >>> from plantdb.server.core.utils import get_file_uri
    >>> from plantdb.commons.test_database import test_database
    >>> db = test_database('real_plant_analyzed')
    >>> db.connect()
    >>> scan = db.get_scan('real_plant_analyzed')
    >>> fs_match = compute_fileset_matches(scan)
    >>> fs = scan.get_fileset(fs_match['PointCloud'])
    >>> f = fs.get_file("PointCloud")
    >>> get_file_uri(scan, fs, f)
    '/files/real_plant_analyzed/PointCloud_1_0_1_0_10_0_7ee836e5a9/PointCloud.ply'
    """
    from plantdb.commons.fsdb.core import Scan
    from plantdb.commons.fsdb.core import Fileset
    from plantdb.commons.fsdb.core import File
    scan_id = scan.id if isinstance(scan, Scan) else scan
    fileset_id = fileset.id if isinstance(fileset, Fileset) else fileset
    file_id = file.path().name if isinstance(file, File) else file
    return f"/files/{scan_id}/{fileset_id}/{file_id}"

get_image_uri Link

get_image_uri(scan, fileset, file, size='orig', as_base64=False)

Return the URI for the corresponding scan/fileset/file tree.

Parameters:

Name Type Description Default

scan Link

Scan or str

A Scan instance or the name of the scan dataset.

required

fileset Link

Fileset or str

A Fileset instance or the name of the fileset.

required

file Link

File or str

A File instance or the name of the file.

required

size Link

(orig, large, thumb)

If an integer, use it as the size of the cached image to create and return. Otherwise, should be one of the following strings, default to 'orig':

  • 'thumb': image max width and height to 150.
  • 'large': image max width and height to 1500;
  • 'orig': original image, no chache;
'orig'

as_base64 Link

bool

A boolean flag indicating whether to return an image as a base64 string.

False

Returns:

Type Description
str

The URI for the corresponding scan/fileset/file tree.

Examples:

>>> from plantdb.server.core.utils import get_image_uri
>>> from plantdb.commons.test_database import test_database
>>> from plantdb.server.core.utils import compute_fileset_matches
>>> db = test_database('real_plant_analyzed')
>>> db.connect()
>>> scan = db.get_scan('real_plant_analyzed')
>>> get_image_uri(scan, 'images', '00000_rgb.jpg', size='orig')
'/image/real_plant_analyzed/images/00000_rgb.jpg?size=orig'
>>> get_image_uri(scan, 'images', '00011_rgb.jpg', size='thumb', as_base64=True)
'/image/real_plant_analyzed/images/00011_rgb.jpg?size=thumb&as_base64=true'
Source code in plantdb/server/core/utils.py
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
def get_image_uri(scan, fileset, file, size="orig", as_base64=False):
    """Return the URI for the corresponding `scan/fileset/file` tree.

    Parameters
    ----------
    scan : plantdb.commons.fsdb.core.Scan or str
        A ``Scan`` instance or the name of the scan dataset.
    fileset : plantdb.commons.fsdb.core.Fileset or str
        A ``Fileset`` instance or the name of the fileset.
    file : plantdb.commons.fsdb.core.File or str
        A ``File`` instance or the name of the file.
    size : {'orig', 'large', 'thumb'} or int, optional
        If an integer, use it as the size of the cached image to create and return.
        Otherwise, should be one of the following strings, default to `'orig'`:

          - `'thumb'`: image max width and height to `150`.
          - `'large'`: image max width and height to `1500`;
          - `'orig'`: original image, no chache;
    as_base64 : bool, optional
        A boolean flag indicating whether to return an image as a base64 string.

    Returns
    -------
    str
        The URI for the corresponding `scan/fileset/file` tree.

    Examples
    --------
    >>> from plantdb.server.core.utils import get_image_uri
    >>> from plantdb.commons.test_database import test_database
    >>> from plantdb.server.core.utils import compute_fileset_matches
    >>> db = test_database('real_plant_analyzed')
    >>> db.connect()
    >>> scan = db.get_scan('real_plant_analyzed')
    >>> get_image_uri(scan, 'images', '00000_rgb.jpg', size='orig')
    '/image/real_plant_analyzed/images/00000_rgb.jpg?size=orig'
    >>> get_image_uri(scan, 'images', '00011_rgb.jpg', size='thumb', as_base64=True)
    '/image/real_plant_analyzed/images/00011_rgb.jpg?size=thumb&as_base64=true'
    """
    from plantdb.commons.fsdb.core import Scan
    from plantdb.commons.fsdb.core import Fileset
    from plantdb.commons.fsdb.core import File
    scan_id = scan.id if isinstance(scan, Scan) else scan
    fileset_id = fileset.id if isinstance(fileset, Fileset) else fileset
    file_id = file.path().name if isinstance(file, File) else file

    # Assemble optional query parameters
    query: dict[str, str] = {}
    if size is not None:
        query["size"] = str(size)
    if as_base64:
        # Use lower‑case JSON‑style booleans for consistency
        query["as_base64"] = str(as_base64).lower()

    query_str = f"?{parse.urlencode(query)}" if query else ""
    return f"/image/{scan_id}/{fileset_id}/{file_id}{query_str}"

get_scan_date Link

get_scan_date(scan)

Get the acquisition datetime of a scan.

Try to get the data from the scan metadata 'acquisition_date', else from the directory creation time.

Parameters:

Name Type Description Default

scan Link

Scan

The scan instance to get the date & time from.

required

Returns:

Type Description
str

The formatted datetime string.

Examples:

>>> from plantdb.server.core.utils import get_scan_date
>>> from plantdb.commons.test_database import test_database
>>> db = test_database(['real_plant_analyzed', 'virtual_plant_analyzed'])
>>> db.connect()
>>> scan = db.get_scan('real_plant_analyzed')
>>> print(get_scan_date(scan))
>>> scan = db.get_scan('virtual_plant_analyzed')
>>> print(get_scan_date(scan))
>>> db.disconnect()
Source code in plantdb/server/core/utils.py
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
def get_scan_date(scan):
    """Get the acquisition datetime of a scan.

    Try to get the data from the scan metadata 'acquisition_date', else from the directory creation time.

    Parameters
    ----------
    scan : plantdb.commons.fsdb.core.Scan
        The scan instance to get the date & time from.

    Returns
    -------
    str
        The formatted datetime string.

    Examples
    --------
    >>> from plantdb.server.core.utils import get_scan_date
    >>> from plantdb.commons.test_database import test_database
    >>> db = test_database(['real_plant_analyzed', 'virtual_plant_analyzed'])
    >>> db.connect()
    >>> scan = db.get_scan('real_plant_analyzed')
    >>> print(get_scan_date(scan))
    >>> scan = db.get_scan('virtual_plant_analyzed')
    >>> print(get_scan_date(scan))
    >>> db.disconnect()
    """
    dt = scan.get_metadata('acquisition_date')
    try:
        assert isinstance(dt, str)
    except:
        # Get directory creation date as acquisition date
        c_time = scan.path().lstat().st_ctime
        dt = datetime.datetime.fromtimestamp(c_time)
        date = dt.strftime("%Y-%m-%d")
        time = dt.strftime("%H:%M:%S")
    else:
        date, time = dt.split(' ')
    return f"{date} {time}"

get_scan_template Link

get_scan_template(scan_id, error=False)

Template dictionary for a scan.

Source code in plantdb/server/core/utils.py
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
def get_scan_template(scan_id: str, error=False) -> dict:
    """Template dictionary for a scan."""
    return {
        "id": scan_id,
        "metadata": {
            "date": "01-01-00 00:00:00",
            "species": "N/A",
            "plant": "N/A",
            "environment": "N/A",
            "nbPhotos": 0,
            "files": {
                "metadata": None,
                "archive": None
            }
        },
        "thumbnailUri": "",
        "images": None,  # list of original image filenames
        "tasks_fileset": None,  # dict mapping task names to fileset names
        "filesUri": {},  # dict mapping task names to task file URI
        "isVirtual": False,
        "hasColmap": False,
        "hasPointCloud": False,
        "hasTriangleMesh": False,
        "hasCurveSkeleton": False,
        "hasTreeGraph": False,
        "hasAnglesAndInternodes": False,
        "hasAutomatedMeasures": False,
        "hasManualMeasures": False,
        "hasSegmentation2D": False,
        "hasPcdGroundTruth": False,
        "hasPointCloudEvaluation": False,
        "hasSegmentedPointCloud": False,
        "hasSegmentedPcdEvaluation": False,
        "error": error,
    }