Skip to content

API 参考

注意(私有元素)

此模块包含以下划线开头的“私有”类/函数。默认情况下,它们的详细信息不会包含在文档中。

完整包

ISD 读取器包

此包解析 ISD 文件夹中的 Description.xml 文件,并将相应的二进制图像数据转换为具有相应数据类型(uint8/16/32)的 NumPy 二维数组。

此包包含: - IsdReader:读取 ISD 数据集的主要入口点,即包含 ISD 数据本身的对象类。 - 用于处理各种错误的异常类

使用示例:

from isdreader import IsdReader isd = IsdReader(isd_path="/path/to/folder.isd") ch = isd.GetCh(1) dg = ch.GetDataGate(2) img = dg.GetImage("AP") arr = img.load_image() 其中,arr 是一个 NumPy 二维数组。

BinaryFileNotFound

Bases: Exception

如果在 ISD 文件夹中找不到指定的二进制文件,则会发生异常。

Source code in .build\zh\isdreader\isd_helper.py
55
56
57
58
59
class BinaryFileNotFound(Exception):
    """
    如果在 ISD 文件夹中找不到指定的二进制文件,则会发生异常。
    """
    pass

DescriptionNotFound

Bases: Exception

如果在 ISD 文件夹中找不到 Description.xml 文件,则会发生异常。

Source code in .build\zh\isdreader\isd_helper.py
41
42
43
44
45
class DescriptionNotFound(Exception):
    """
    如果在 ISD 文件夹中找不到 Description.xml 文件,则会发生异常。
    """
    pass

InvalidChannel

Bases: Exception

当指定的通道索引无效时,会发生异常。

Source code in .build\zh\isdreader\isd_helper.py
13
14
15
16
17
class InvalidChannel(Exception):
    """
    当指定的通道索引无效时,会发生异常。
    """
    pass

InvalidDataGate

Bases: Exception

当指定的数据门索引无效时,会发生异常。

Source code in .build\zh\isdreader\isd_helper.py
20
21
22
23
24
class InvalidDataGate(Exception):
    """
    当指定的数据门索引无效时,会发生异常。
    """
    pass

IsdNotFound

Bases: Exception

当指定的 ISD 文件夹不存在时,会发生异常。

Source code in .build\zh\isdreader\isd_helper.py
34
35
36
37
38
class IsdNotFound(Exception):
    """
    当指定的 ISD 文件夹不存在时,会发生异常。
    """
    pass

IsdReader

代表整个 ISD 文件夹的根类 此类是访问 ISD 采集数据集中所有通道、数据门和图像的主要入口点。 换句话说,它是一个包含整个 ISD 数据的对象类。 属性: path:要包含的 ISD 文件夹的路径 description_path:Description.xml 文件的路径(位于 ISD 文件夹下) logger:此对象的日志记录器实例

Source code in .build\zh\isdreader\isd_root.py
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 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
 69
 70
 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
 99
100
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
class IsdReader:
    """
    代表整个 ISD 文件夹的根类
    此类是访问 ISD 采集数据集中所有通道、数据门和图像的主要入口点。
    换句话说,它是一个包含整个 ISD 数据的对象类。
    属性:
      path:要包含的 ISD 文件夹的路径
      description_path:Description.xml 文件的路径(位于 ISD 文件夹下)
      logger:此对象的日志记录器实例
    """
# --------------------------------------------------------------------------------------------------------
    def __init__(self, *, isd_path: Union[str, Path], logger: Optional[logging.Logger] = None) -> None:
        """
        根据 ISD 文件夹参数初始化 IsdReader 对象。
        参数:
          isd_path:ISD 文件夹的路径(字符串或 pathlib.Path)。
          logger:可选的日志记录器实例。如果为 None,则使用默认日志记录器。
        异常:
          TypeError:如果 isd_path 不是字符串或 Path 类型。
          IsdNotFound:如果 ISD 文件夹不存在。
          DescriptionNotFound:如果在 ISD 文件夹中找不到 Description.xml 文件。
        """
        if not isinstance(isd_path, (str, Path)):
            raise TypeError("isd_path must be str or pathlib.Path")

        self.path = Path(isd_path)
        if not self.path.exists() or not self.path.is_dir():
            raise IsdNotFound(f"ISD folder not found: {isd_path}")

        self.description_path = self.path / "Description.xml"
        if not self.description_path.exists():
            raise DescriptionNotFound(f"Description.xml not found in: {self.path}")

        tree = etree.parse(self.description_path)
        root = tree.getroot()
        isd_root = Path(self.description_path).parent

        self._scan_type = root.findtext("Info/ScanType")
        self._width_pixel = int(root.findtext("Info/WidthPixel") or 0)
        self._height_pixel = int(root.findtext("Info/HeightPixel") or 0)

        wp = root.find("Info/WidthPhysical")
        if wp is not None:
            try:
                self._width_physical = float(wp.text.strip())
            except Exception:
                self._width_physical = None
            self._width_physical_unit = wp.get("Unit")
        else:
            self._width_physical = None
            self._width_physical_unit = None

        hp = root.find("Info/HeightPhysical")
        if hp is not None:
            try:
                self._height_physical = float(hp.text.strip())
            except Exception:
                self._height_physical = None
            self._height_physical_unit = hp.get("Unit")
        else:
            self._height_physical = None
            self._height_physical_unit = None

        self._channels: List[ChChunk] = []
        for ch_elem in root.findall("Channel"):
            self._channels.append(ChChunk(root, ch_elem, isd_root, self._width_pixel or 0, self._height_pixel or 0))

        self._root_elem = root

        self.logger = logger or logging.getLogger(__name__)
# --------------------------------------------------------------------------------------------------------
    def __repr__(self) -> str:
        """
        此函数返回 IsdReader 的字符串摘要。
        返回值:
          包含大小和可用通道数的字符串。
        """
        parts: List[str] = []
        if self._width_pixel is not None and self._height_pixel is not None:
            parts.append(f"size={self._width_pixel}x{self._height_pixel}")
        chs = self.GetCh()
        if chs:
            parts.append(f"channels={','.join(str(int(c)) for c in chs)}")
        return f"IsdReader[{', '.join(parts)}]"
# --------------------------------------------------------------------------------------------------------
    def GetCh(self, ch: Optional[int] = None):
        """
        获取 ChChunk 实例或列出所有频道。
        参数:
          ch:None 或指定的 ChChunk 编号
        返回值:
          如果 ch 为 None,则返回可用频道编号列表;否则,返回指定的 ChChunk 或 None。
        """
        if ch is None:
            return [c._ch for c in self._channels if c._ch is not None]
        for c in self._channels:
            if c._ch == int(ch):
                return c
        return None
# --------------------------------------------------------------------------------------------------------
    def GetImage(self, *, ch: int, gate: int, image_type: str, slice_no: Optional[int] = 1) -> Optional[ImageChunk]:
        """
        直接检索 ImageChunk 的方法
        参数:
          ch:通道号(1 为起始值)
          gate:数据门编号(1 为起始值)
          image_type:图像类型(缩写或全称)
          slice_no:切片编号(1 为起始值,默认值:1)
        返回值:
          找到符合指定条件的 ImageChunk 实例;否则,返回 None
        """
        chObj = self.GetCh(ch)
        if chObj is None:
            return None
        gateObj = chObj.GetDataGate(gate)
        if gateObj is None:
            return None
        imgObj = gateObj.GetImage(image_type, slice_no)
        return imgObj

GetCh(ch=None)

获取 ChChunk 实例或列出所有频道。 参数: ch:None 或指定的 ChChunk 编号 返回值: 如果 ch 为 None,则返回可用频道编号列表;否则,返回指定的 ChChunk 或 None。

Source code in .build\zh\isdreader\isd_root.py
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
def GetCh(self, ch: Optional[int] = None):
    """
    获取 ChChunk 实例或列出所有频道。
    参数:
      ch:None 或指定的 ChChunk 编号
    返回值:
      如果 ch 为 None,则返回可用频道编号列表;否则,返回指定的 ChChunk 或 None。
    """
    if ch is None:
        return [c._ch for c in self._channels if c._ch is not None]
    for c in self._channels:
        if c._ch == int(ch):
            return c
    return None

GetImage(*, ch, gate, image_type, slice_no=1)

直接检索 ImageChunk 的方法 参数: ch:通道号(1 为起始值) gate:数据门编号(1 为起始值) image_type:图像类型(缩写或全称) slice_no:切片编号(1 为起始值,默认值:1) 返回值: 找到符合指定条件的 ImageChunk 实例;否则,返回 None

Source code in .build\zh\isdreader\isd_root.py
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
def GetImage(self, *, ch: int, gate: int, image_type: str, slice_no: Optional[int] = 1) -> Optional[ImageChunk]:
    """
    直接检索 ImageChunk 的方法
    参数:
      ch:通道号(1 为起始值)
      gate:数据门编号(1 为起始值)
      image_type:图像类型(缩写或全称)
      slice_no:切片编号(1 为起始值,默认值:1)
    返回值:
      找到符合指定条件的 ImageChunk 实例;否则,返回 None
    """
    chObj = self.GetCh(ch)
    if chObj is None:
        return None
    gateObj = chObj.GetDataGate(gate)
    if gateObj is None:
        return None
    imgObj = gateObj.GetImage(image_type, slice_no)
    return imgObj

__init__(*, isd_path, logger=None)

根据 ISD 文件夹参数初始化 IsdReader 对象。 参数: isd_path:ISD 文件夹的路径(字符串或 pathlib.Path)。 logger:可选的日志记录器实例。如果为 None,则使用默认日志记录器。 异常: TypeError:如果 isd_path 不是字符串或 Path 类型。 IsdNotFound:如果 ISD 文件夹不存在。 DescriptionNotFound:如果在 ISD 文件夹中找不到 Description.xml 文件。

Source code in .build\zh\isdreader\isd_root.py
25
26
27
28
29
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
def __init__(self, *, isd_path: Union[str, Path], logger: Optional[logging.Logger] = None) -> None:
    """
    根据 ISD 文件夹参数初始化 IsdReader 对象。
    参数:
      isd_path:ISD 文件夹的路径(字符串或 pathlib.Path)。
      logger:可选的日志记录器实例。如果为 None,则使用默认日志记录器。
    异常:
      TypeError:如果 isd_path 不是字符串或 Path 类型。
      IsdNotFound:如果 ISD 文件夹不存在。
      DescriptionNotFound:如果在 ISD 文件夹中找不到 Description.xml 文件。
    """
    if not isinstance(isd_path, (str, Path)):
        raise TypeError("isd_path must be str or pathlib.Path")

    self.path = Path(isd_path)
    if not self.path.exists() or not self.path.is_dir():
        raise IsdNotFound(f"ISD folder not found: {isd_path}")

    self.description_path = self.path / "Description.xml"
    if not self.description_path.exists():
        raise DescriptionNotFound(f"Description.xml not found in: {self.path}")

    tree = etree.parse(self.description_path)
    root = tree.getroot()
    isd_root = Path(self.description_path).parent

    self._scan_type = root.findtext("Info/ScanType")
    self._width_pixel = int(root.findtext("Info/WidthPixel") or 0)
    self._height_pixel = int(root.findtext("Info/HeightPixel") or 0)

    wp = root.find("Info/WidthPhysical")
    if wp is not None:
        try:
            self._width_physical = float(wp.text.strip())
        except Exception:
            self._width_physical = None
        self._width_physical_unit = wp.get("Unit")
    else:
        self._width_physical = None
        self._width_physical_unit = None

    hp = root.find("Info/HeightPhysical")
    if hp is not None:
        try:
            self._height_physical = float(hp.text.strip())
        except Exception:
            self._height_physical = None
        self._height_physical_unit = hp.get("Unit")
    else:
        self._height_physical = None
        self._height_physical_unit = None

    self._channels: List[ChChunk] = []
    for ch_elem in root.findall("Channel"):
        self._channels.append(ChChunk(root, ch_elem, isd_root, self._width_pixel or 0, self._height_pixel or 0))

    self._root_elem = root

    self.logger = logger or logging.getLogger(__name__)

__repr__()

此函数返回 IsdReader 的字符串摘要。 返回值: 包含大小和可用通道数的字符串。

Source code in .build\zh\isdreader\isd_root.py
85
86
87
88
89
90
91
92
93
94
95
96
97
def __repr__(self) -> str:
    """
    此函数返回 IsdReader 的字符串摘要。
    返回值:
      包含大小和可用通道数的字符串。
    """
    parts: List[str] = []
    if self._width_pixel is not None and self._height_pixel is not None:
        parts.append(f"size={self._width_pixel}x{self._height_pixel}")
    chs = self.GetCh()
    if chs:
        parts.append(f"channels={','.join(str(int(c)) for c in chs)}")
    return f"IsdReader[{', '.join(parts)}]"

主要模块

ChChunk

表示一个通道的类,该通道可能包含多个数据门。 此类对应于采集系统中的物理超声通道。

Source code in .build\zh\isdreader\chunks.py
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
class ChChunk:
    """
    表示一个通道的类,该通道可能包含多个数据门。
    此类对应于采集系统中的物理超声通道。
    """
    def __init__(self, root_elem: etree.Element, ch_elem: etree.Element, isd_root: Path, width: int, height: int):
        """
        初始化 ChChunk 实例。
        参数:
          root_elem:Description.xml 的根 XML 元素
          ch_elem:通道 XML 元素
          isd_root:ISD 文件夹根路径
          width:图像宽度(像素)
          height:图像高度(像素)
        """
        self._elem = ch_elem
        self._ch_id_xml: int = int(ch_elem.get("id", "-1"))
        self._ch: Optional[int] = (self._ch_id_xml + 1) if self._ch_id_xml != -1 else None
        self._channel_name: Optional[str] = ch_elem.get("Name")
        self._sampling_freq_mhz: Optional[float] = float(ch_elem.get("SamplingFreqMHz") or 0)
        self._datagates: List[DataGateChunk] = []
        for dg in ch_elem.findall(".//DataGate"):
            self._datagates.append(
                DataGateChunk(
                    root_elem,
                    ch_elem,
                    dg,
                    isd_root,
                    self._ch,
                    self._channel_name,
                    width,
                    height,
                    self._sampling_freq_mhz or 0.0,
                )
            )
        self._assigned: Dict[str, Any] = {}
# --------------------------------------------------------------------------------------------------------
    def list_datagates(self) -> List[int]:
        """
        列出所有可用的 DataGate 编号。
        返回值:
          DataGate 编号列表(1 个来源)
        """
        return [dg._dg_public for dg in self._datagates if dg._dg_public is not None]
# --------------------------------------------------------------------------------------------------------
    def GetDataGate(self, data_gate: Optional[int] = None):
        """
        检索 DataGateChunk 实例或列出所有 DataGate。
        参数:
          data_gate:如果为 None,则列出 DataGate 编号;否则,返回相应的 DataGateChunk。
        返回值:
          如果 data_gate 为 None,则返回 DataGate 编号列表;否则,返回 DataGateChunk 实例或 None。
        """
        if data_gate is None:
            return self.list_datagates()
        dg_num = int(data_gate)
        for dg in self._datagates:
            if dg._dg_public == dg_num:
                return dg
        return None
# --------------------------------------------------------------------------------------------------------
    def __repr__(self) -> str:
        """
        返回此 ChChunk 的字符串摘要。
        返回值:
          包含通道号、名称和数据门的字符串表示形式。
        """
        return f"ChChunk[ch={self._ch}, name={self._channel_name}, data_gates={self.list_datagates()}]"

GetDataGate(data_gate=None)

检索 DataGateChunk 实例或列出所有 DataGate。 参数: data_gate:如果为 None,则列出 DataGate 编号;否则,返回相应的 DataGateChunk。 返回值: 如果 data_gate 为 None,则返回 DataGate 编号列表;否则,返回 DataGateChunk 实例或 None。

Source code in .build\zh\isdreader\chunks.py
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
def GetDataGate(self, data_gate: Optional[int] = None):
    """
    检索 DataGateChunk 实例或列出所有 DataGate。
    参数:
      data_gate:如果为 None,则列出 DataGate 编号;否则,返回相应的 DataGateChunk。
    返回值:
      如果 data_gate 为 None,则返回 DataGate 编号列表;否则,返回 DataGateChunk 实例或 None。
    """
    if data_gate is None:
        return self.list_datagates()
    dg_num = int(data_gate)
    for dg in self._datagates:
        if dg._dg_public == dg_num:
            return dg
    return None

__init__(root_elem, ch_elem, isd_root, width, height)

初始化 ChChunk 实例。 参数: root_elem:Description.xml 的根 XML 元素 ch_elem:通道 XML 元素 isd_root:ISD 文件夹根路径 width:图像宽度(像素) height:图像高度(像素)

Source code in .build\zh\isdreader\chunks.py
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
def __init__(self, root_elem: etree.Element, ch_elem: etree.Element, isd_root: Path, width: int, height: int):
    """
    初始化 ChChunk 实例。
    参数:
      root_elem:Description.xml 的根 XML 元素
      ch_elem:通道 XML 元素
      isd_root:ISD 文件夹根路径
      width:图像宽度(像素)
      height:图像高度(像素)
    """
    self._elem = ch_elem
    self._ch_id_xml: int = int(ch_elem.get("id", "-1"))
    self._ch: Optional[int] = (self._ch_id_xml + 1) if self._ch_id_xml != -1 else None
    self._channel_name: Optional[str] = ch_elem.get("Name")
    self._sampling_freq_mhz: Optional[float] = float(ch_elem.get("SamplingFreqMHz") or 0)
    self._datagates: List[DataGateChunk] = []
    for dg in ch_elem.findall(".//DataGate"):
        self._datagates.append(
            DataGateChunk(
                root_elem,
                ch_elem,
                dg,
                isd_root,
                self._ch,
                self._channel_name,
                width,
                height,
                self._sampling_freq_mhz or 0.0,
            )
        )
    self._assigned: Dict[str, Any] = {}

__repr__()

返回此 ChChunk 的字符串摘要。 返回值: 包含通道号、名称和数据门的字符串表示形式。

Source code in .build\zh\isdreader\chunks.py
401
402
403
404
405
406
407
def __repr__(self) -> str:
    """
    返回此 ChChunk 的字符串摘要。
    返回值:
      包含通道号、名称和数据门的字符串表示形式。
    """
    return f"ChChunk[ch={self._ch}, name={self._channel_name}, data_gates={self.list_datagates()}]"

list_datagates()

列出所有可用的 DataGate 编号。 返回值: DataGate 编号列表(1 个来源)

Source code in .build\zh\isdreader\chunks.py
377
378
379
380
381
382
383
def list_datagates(self) -> List[int]:
    """
    列出所有可用的 DataGate 编号。
    返回值:
      DataGate 编号列表(1 个来源)
    """
    return [dg._dg_public for dg in self._datagates if dg._dg_public is not None]

DataGateChunk

表示通道内数据门的类。 请注意,一个数据门可以包含多个切片图像。

Source code in .build\zh\isdreader\chunks.py
196
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
235
236
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
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
class DataGateChunk:
    """
    表示通道内数据门的类。
    请注意,一个数据门可以包含多个切片图像。
    """
# --------------------------------------------------------------------------------------------------------
    def __init__(
        self,
        root_elem: etree.Element,
        ch_elem: etree.Element,
        dg_elem: etree.Element,
        isd_root: Path,
        ch_public: Optional[int],
        ch_name: Optional[str],
        width: int,
        height: int,
        sampling_freq_mhz: float,
    ):
        """
        初始化 DataGateChunk 实例
        参数:
          root_elem:Description.xml 的根 XML 元素
          ch_elem:通道 XML 元素
          dg_elem:数据门 XML 元素
          isd_root:ISD 文件夹根路径
          ch_public:公共通道号(1 为起始值)
          ch_name:通道名称
          width:图像宽度(像素)
          height:图像高度(像素)
          sampling_freq_mhz:采样频率(MHz)
        """
        self._elem = dg_elem
        self._dg_id_xml: int = int(dg_elem.get("id", "-1"))
        self._dg_public: Optional[int] = (self._dg_id_xml - 1) if self._dg_id_xml != -1 else None
        self._data_gate_name = dg_elem.get("Name")
        self._image_elems: List[etree.Element] = dg_elem.findall(".//Image")
        self._images: Dict[Tuple[int, str], ImageChunk] = {}
        self._root_elem = root_elem
        self._ch_elem = ch_elem
        self._isd_root = isd_root
        self._ch_public = ch_public
        self._ch_name = ch_name
        self._width = width
        self._height = height
        self._sampling_freq_mhz = sampling_freq_mhz
        self._assigned: Dict[str, Any] = {}
# --------------------------------------------------------------------------------------------------------
    def _ensure_image(self, img_elem: etree.Element, type_abbr: str, type_elem: etree.Element) -> ImageChunk:
        """
        检查是否存在指定图像元素和类型的 ImageChunk。
        参数:
          img_elem:图像 XML 元素
          type_abbr:图像类型缩写
          type_elem:特定图像类型的 XML 元素
        返回值:
          ImageChunk 实例
        """
        try:
            img_id = int(img_elem.get("id", "0"))
        except Exception:
            img_id = 0
        key = (img_id, type_abbr)
        if key in self._images:
            return self._images[key]
        img = ImageChunk(
            root_elem=self._root_elem,
            ch_elem=self._ch_elem,
            dg_elem=self._elem,
            img_elem=img_elem,
            isd_root=self._isd_root,
            ch_public=self._ch_public,
            dg_xml_id=self._dg_id_xml,
            type_abbr=type_abbr,
            type_elem=type_elem,
        )
        self._images[key] = img
        return img
# --------------------------------------------------------------------------------------------------------
    def list_images(self) -> List[int]:
        """
        列出所有可用的切片编号(从 1 个原点开始)。
        返回值:
          切片编号列表。
        """
        res: List[int] = []
        for el in self._image_elems:
            try:
                res.append(int(el.get("id", "0")) + 1)
            except Exception:
                continue
        return res
# --------------------------------------------------------------------------------------------------------
    def GetSlice(self, slice_no: Optional[int] = None):
        """
        列出所有切片。
        参数:
          slice_no:如果为 None,则列出所有切片编号;否则,将发生 TypeError。
        返回值:
          如果 slice_no 为 None,则列出切片编号。
        异常:
          TypeError:如果指定了 slice_no。
        """
        if slice_no is None:
            return self.list_images()
        raise TypeError("GetSlice with slice_no does not return ImageChunk; use GetImage(image_type, slice_no)")
# --------------------------------------------------------------------------------------------------------
    def ImageTypes(self) -> str:
        """
        返回一个描述可用图像类型的字符串。
        返回值:
          以逗号分隔的图像类型缩写和全称字符串。
        """
        return ", ".join(f"{k}: {_IMAGE_TYPE_MAP[k]}" for k in _IMAGE_TYPE_MAP)
# --------------------------------------------------------------------------------------------------------
    def GetImage(self, image_type: str, slice_no: Optional[int] = 1) -> Optional[ImageChunk]:
        """
        返回指定类型和切片的 ImageChunk 实例。
        参数:
          image_type:图像类型(缩写或全称)
          slice_no:切片编号(1 为默认值,默认值为 1)
        返回值:
          如果找到 ImageChunk 实例,则返回该实例;否则返回 None。
        """
        idx = int(slice_no) - 1
        for el in self._image_elems:
            try:
                if int(el.get("id", "-1")) == idx:
                    abbr, t = _select_type_elem_for_image(el, image_type)
                    return self._ensure_image(el, abbr, t)
            except Exception:
                continue
        return None
# --------------------------------------------------------------------------------------------------------
    def __repr__(self) -> str:
        """
        此函数返回此 DataGateChunk 的字符串摘要。
        返回值:
          包含 ID、名称和可用图像的字符串表示形式。
        """
        imgs = self.list_images()
        name = self._data_gate_name or ""
        return f"DataGateChunk[id={self._dg_public}, name={name}, images={imgs}]"

GetImage(image_type, slice_no=1)

返回指定类型和切片的 ImageChunk 实例。 参数: image_type:图像类型(缩写或全称) slice_no:切片编号(1 为默认值,默认值为 1) 返回值: 如果找到 ImageChunk 实例,则返回该实例;否则返回 None。

Source code in .build\zh\isdreader\chunks.py
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
def GetImage(self, image_type: str, slice_no: Optional[int] = 1) -> Optional[ImageChunk]:
    """
    返回指定类型和切片的 ImageChunk 实例。
    参数:
      image_type:图像类型(缩写或全称)
      slice_no:切片编号(1 为默认值,默认值为 1)
    返回值:
      如果找到 ImageChunk 实例,则返回该实例;否则返回 None。
    """
    idx = int(slice_no) - 1
    for el in self._image_elems:
        try:
            if int(el.get("id", "-1")) == idx:
                abbr, t = _select_type_elem_for_image(el, image_type)
                return self._ensure_image(el, abbr, t)
        except Exception:
            continue
    return None

GetSlice(slice_no=None)

列出所有切片。 参数: slice_no:如果为 None,则列出所有切片编号;否则,将发生 TypeError。 返回值: 如果 slice_no 为 None,则列出切片编号。 异常: TypeError:如果指定了 slice_no。

Source code in .build\zh\isdreader\chunks.py
288
289
290
291
292
293
294
295
296
297
298
299
300
def GetSlice(self, slice_no: Optional[int] = None):
    """
    列出所有切片。
    参数:
      slice_no:如果为 None,则列出所有切片编号;否则,将发生 TypeError。
    返回值:
      如果 slice_no 为 None,则列出切片编号。
    异常:
      TypeError:如果指定了 slice_no。
    """
    if slice_no is None:
        return self.list_images()
    raise TypeError("GetSlice with slice_no does not return ImageChunk; use GetImage(image_type, slice_no)")

ImageTypes()

返回一个描述可用图像类型的字符串。 返回值: 以逗号分隔的图像类型缩写和全称字符串。

Source code in .build\zh\isdreader\chunks.py
302
303
304
305
306
307
308
def ImageTypes(self) -> str:
    """
    返回一个描述可用图像类型的字符串。
    返回值:
      以逗号分隔的图像类型缩写和全称字符串。
    """
    return ", ".join(f"{k}: {_IMAGE_TYPE_MAP[k]}" for k in _IMAGE_TYPE_MAP)

__init__(root_elem, ch_elem, dg_elem, isd_root, ch_public, ch_name, width, height, sampling_freq_mhz)

初始化 DataGateChunk 实例 参数: root_elem:Description.xml 的根 XML 元素 ch_elem:通道 XML 元素 dg_elem:数据门 XML 元素 isd_root:ISD 文件夹根路径 ch_public:公共通道号(1 为起始值) ch_name:通道名称 width:图像宽度(像素) height:图像高度(像素) sampling_freq_mhz:采样频率(MHz)

Source code in .build\zh\isdreader\chunks.py
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
235
236
237
238
239
240
241
def __init__(
    self,
    root_elem: etree.Element,
    ch_elem: etree.Element,
    dg_elem: etree.Element,
    isd_root: Path,
    ch_public: Optional[int],
    ch_name: Optional[str],
    width: int,
    height: int,
    sampling_freq_mhz: float,
):
    """
    初始化 DataGateChunk 实例
    参数:
      root_elem:Description.xml 的根 XML 元素
      ch_elem:通道 XML 元素
      dg_elem:数据门 XML 元素
      isd_root:ISD 文件夹根路径
      ch_public:公共通道号(1 为起始值)
      ch_name:通道名称
      width:图像宽度(像素)
      height:图像高度(像素)
      sampling_freq_mhz:采样频率(MHz)
    """
    self._elem = dg_elem
    self._dg_id_xml: int = int(dg_elem.get("id", "-1"))
    self._dg_public: Optional[int] = (self._dg_id_xml - 1) if self._dg_id_xml != -1 else None
    self._data_gate_name = dg_elem.get("Name")
    self._image_elems: List[etree.Element] = dg_elem.findall(".//Image")
    self._images: Dict[Tuple[int, str], ImageChunk] = {}
    self._root_elem = root_elem
    self._ch_elem = ch_elem
    self._isd_root = isd_root
    self._ch_public = ch_public
    self._ch_name = ch_name
    self._width = width
    self._height = height
    self._sampling_freq_mhz = sampling_freq_mhz
    self._assigned: Dict[str, Any] = {}

__repr__()

此函数返回此 DataGateChunk 的字符串摘要。 返回值: 包含 ID、名称和可用图像的字符串表示形式。

Source code in .build\zh\isdreader\chunks.py
329
330
331
332
333
334
335
336
337
def __repr__(self) -> str:
    """
    此函数返回此 DataGateChunk 的字符串摘要。
    返回值:
      包含 ID、名称和可用图像的字符串表示形式。
    """
    imgs = self.list_images()
    name = self._data_gate_name or ""
    return f"DataGateChunk[id={self._dg_public}, name={name}, images={imgs}]"

list_images()

列出所有可用的切片编号(从 1 个原点开始)。 返回值: 切片编号列表。

Source code in .build\zh\isdreader\chunks.py
274
275
276
277
278
279
280
281
282
283
284
285
286
def list_images(self) -> List[int]:
    """
    列出所有可用的切片编号(从 1 个原点开始)。
    返回值:
      切片编号列表。
    """
    res: List[int] = []
    for el in self._image_elems:
        try:
            res.append(int(el.get("id", "0")) + 1)
        except Exception:
            continue
    return res

ImageChunk

一个包含 DataGate 中单个图像数据(包括元数据)的类。 此类保存所有元数据,并提供对二进制图像数据的访问。

Source code in .build\zh\isdreader\chunks.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
 69
 70
 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
 99
100
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
class ImageChunk:
    """
    一个包含 DataGate 中单个图像数据(包括元数据)的类。
    此类保存所有元数据,并提供对二进制图像数据的访问。
    """
# --------------------------------------------------------------------------------------------------------
    def __init__(
        self,
        root_elem: etree.Element,
        ch_elem: etree.Element,
        dg_elem: etree.Element,
        img_elem: etree.Element,
        isd_root: Path,
        ch_public: int,
        dg_xml_id: int,
        type_abbr: str,
        type_elem: etree.Element,
    ):
        """
        初始化此 ImageChunk 实例。
        参数:
          root_elem:Description.xml 的根 XML 元素
          ch_elem:通道 XML 元素
          dg_elem:数据门 XML 元素
          img_elem:图像 XML 元素
          isd_root:ISD 文件夹根目录的路径
          ch_public:公共通道号(1 源)
          dg_xml_id:数据门 XML ID 属性
          type_abbr:图像类型缩写(例如“PP”、“AP”等)
          type_elem:特定图像类型的 XML 元素
        """
        self._root_elem = root_elem
        self._ch_elem = ch_elem
        self._dg_elem = dg_elem
        self._img_elem = img_elem

        self.image_name: str = img_elem.get("Name", "01")

        self._type_elem = type_elem
        self._type_abbr = type_abbr

        self._isd_root = Path(isd_root)
        self._ch_public = ch_public
        self._dg_xml_id = dg_xml_id
        self._width = int(root_elem.findtext("Info/WidthPixel") or 0)
        self._height = int(root_elem.findtext("Info/HeightPixel") or 0)

        self._inject_properties_from_definitions()

        self._img_array: Optional[np.ndarray] = None
# --------------------------------------------------------------------------------------------------------
    def _inject_properties_from_definitions(self) -> None:
        """PROPERTY_DEFINITIONSからメタデータプロパティをこのインスタンスに与える"""
        root = self._root_elem
        ch_letter = CH_NUM_TO_LETTER.get(int(self._ch_public), "")
        dg = self._dg_elem
        type_elem = self._type_elem

        for prop_key in PROPERTY_DEFINITIONS.keys():
            final_key = prop_key.replace("$", ch_letter) if "$" in prop_key else prop_key
            if not hasattr(self, final_key):
                setattr(self, final_key, None)

        for prop_name, spec in PROPERTY_DEFINITIONS.items():
            kind = spec.get("kind")
            if kind == "info":
                node = root.find(f".//Info/{spec['path']}")
                if node is not None and node.text:
                    setattr(self, prop_name, node.text.strip())
            elif kind == "parameter":
                v = _find_category_item(root, spec["category"], spec["item"])
                if v is not None:
                    setattr(self, prop_name, v)
            elif kind == "channel_param":
                v = _find_channel_category_item(root, ch_letter, spec["category_base"], spec["item"])
                if v is not None:
                    setattr(self, prop_name, v)
            elif kind == "parameter_in_ch":
                v = _find_parameter_in_ch(root, spec["category"], spec["item_template"], ch_letter)
                if v is not None:
                    prop_final = prop_name.replace("$", ch_letter)
                    setattr(self, prop_final, v)
            elif kind == "gate_param":
                category_base = spec.get("category_base", "Gate - Ch.$")
                dg_name = dg.get("Name") if dg is not None else None
                v = _find_category_item_for_gate(root, category_base, ch_letter, dg_name, spec["item"])
                if v is not None:
                    setattr(self, prop_name, v)
            elif kind == "image_type":
                v = _find_image_type_value(type_elem, spec["key"])
                if v is not None:
                    setattr(self, prop_name, v)
# --------------------------------------------------------------------------------------------------------
    def build_metadata_args(self) -> Tuple[int, int, int]:
        """
        从 ImageChunk 属性构造要传递给 binary_loader 的参数。
        返回值:
          用于二进制加载的 (width, height, data_size) 元组。
        """
        width = int(getattr(self, "WidthPixel", self._width) or self._width)
        height = int(getattr(self, "HeightPixel", self._height) or self._height)
        data_size = int(getattr(self, "ImgDataSize", 8) or 8)
        return width, height, data_size
# --------------------------------------------------------------------------------------------------------
    def load_image(self, y_flipped: bool = True) -> np.ndarray:
        """
        读取二进制图像数据并将其作为二维 NumPy 数组返回。
        参数:
          y_flipped:如果为 True,则读取的图像将垂直翻转(默认值:True)
        返回值:
          二维 NumPy 图像数组
        异常:
          MiscellaneousError:如果找不到图像文件名
          BinaryFileNotFound:如果二进制文件不存在
        """
        fn = _find_image_type_value(self._type_elem, "FileName")
        if fn is None:
            raise MiscellaneousError("Image file name not found")
        if not fn.casefold().endswith(".bin"):
            fn = fn + ".bin"
        resolver = _PathResolver(self._isd_root)
        bin_path = resolver.resolve_binary_path(
            ch=self._ch_public,
            data_gate=(self._dg_xml_id - 1),
            img_name=self.image_name,
            image_type=fn,
        )
        if not bin_path.exists():
            raise BinaryFileNotFound(f"Binary file not found: {bin_path}")

        width, height, data_size = self.build_metadata_args()

        loader = _BinaryLoader(logger=_logger)
        arr = loader.load_as_2d_array(bin_path, width, height, data_size)

        self._img_array = np.flipud(arr) if y_flipped else arr
        return self._img_array
# --------------------------------------------------------------------------------------------------------
    @property
    def img_array(self) -> np.ndarray:
        """
        访问已加载的图像数组。
        返回值:
          已加载的二维 NumPy 数组
        异常:
          MiscellaneousError:如果图像尚未加载。
        """
        if self._img_array is None:
            raise MiscellaneousError("Image not loaded. Call load_image() first")
        return self._img_array
# --------------------------------------------------------------------------------------------------------
    def __repr__(self) -> str:
        """
        此操作返回此 ImageChunk 的字符串摘要。
        返回值:
          包含所有注入属性的字符串表示形式。
        """
        parts: List[str] = []
        ch_letter = CH_NUM_TO_LETTER.get(int(self._ch_public), "")
        for key in PROPERTY_DEFINITIONS.keys():
            final_key = key.replace("$", ch_letter) if "$" in key else key
            val = getattr(self, final_key, None)
            parts.append(f"{final_key}={val!r}")
        return f"ImageChunk[name={self.image_name}, type={self._type_abbr}, {', '.join(parts)}]"

img_array property

访问已加载的图像数组。 返回值: 已加载的二维 NumPy 数组 异常: MiscellaneousError:如果图像尚未加载。

__init__(root_elem, ch_elem, dg_elem, img_elem, isd_root, ch_public, dg_xml_id, type_abbr, type_elem)

初始化此 ImageChunk 实例。 参数: root_elem:Description.xml 的根 XML 元素 ch_elem:通道 XML 元素 dg_elem:数据门 XML 元素 img_elem:图像 XML 元素 isd_root:ISD 文件夹根目录的路径 ch_public:公共通道号(1 源) dg_xml_id:数据门 XML ID 属性 type_abbr:图像类型缩写(例如“PP”、“AP”等) type_elem:特定图像类型的 XML 元素

Source code in .build\zh\isdreader\chunks.py
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
69
70
71
72
73
74
75
76
77
78
79
def __init__(
    self,
    root_elem: etree.Element,
    ch_elem: etree.Element,
    dg_elem: etree.Element,
    img_elem: etree.Element,
    isd_root: Path,
    ch_public: int,
    dg_xml_id: int,
    type_abbr: str,
    type_elem: etree.Element,
):
    """
    初始化此 ImageChunk 实例。
    参数:
      root_elem:Description.xml 的根 XML 元素
      ch_elem:通道 XML 元素
      dg_elem:数据门 XML 元素
      img_elem:图像 XML 元素
      isd_root:ISD 文件夹根目录的路径
      ch_public:公共通道号(1 源)
      dg_xml_id:数据门 XML ID 属性
      type_abbr:图像类型缩写(例如“PP”、“AP”等)
      type_elem:特定图像类型的 XML 元素
    """
    self._root_elem = root_elem
    self._ch_elem = ch_elem
    self._dg_elem = dg_elem
    self._img_elem = img_elem

    self.image_name: str = img_elem.get("Name", "01")

    self._type_elem = type_elem
    self._type_abbr = type_abbr

    self._isd_root = Path(isd_root)
    self._ch_public = ch_public
    self._dg_xml_id = dg_xml_id
    self._width = int(root_elem.findtext("Info/WidthPixel") or 0)
    self._height = int(root_elem.findtext("Info/HeightPixel") or 0)

    self._inject_properties_from_definitions()

    self._img_array: Optional[np.ndarray] = None

__repr__()

此操作返回此 ImageChunk 的字符串摘要。 返回值: 包含所有注入属性的字符串表示形式。

Source code in .build\zh\isdreader\chunks.py
181
182
183
184
185
186
187
188
189
190
191
192
193
def __repr__(self) -> str:
    """
    此操作返回此 ImageChunk 的字符串摘要。
    返回值:
      包含所有注入属性的字符串表示形式。
    """
    parts: List[str] = []
    ch_letter = CH_NUM_TO_LETTER.get(int(self._ch_public), "")
    for key in PROPERTY_DEFINITIONS.keys():
        final_key = key.replace("$", ch_letter) if "$" in key else key
        val = getattr(self, final_key, None)
        parts.append(f"{final_key}={val!r}")
    return f"ImageChunk[name={self.image_name}, type={self._type_abbr}, {', '.join(parts)}]"

build_metadata_args()

从 ImageChunk 属性构造要传递给 binary_loader 的参数。 返回值: 用于二进制加载的 (width, height, data_size) 元组。

Source code in .build\zh\isdreader\chunks.py
123
124
125
126
127
128
129
130
131
132
def build_metadata_args(self) -> Tuple[int, int, int]:
    """
    从 ImageChunk 属性构造要传递给 binary_loader 的参数。
    返回值:
      用于二进制加载的 (width, height, data_size) 元组。
    """
    width = int(getattr(self, "WidthPixel", self._width) or self._width)
    height = int(getattr(self, "HeightPixel", self._height) or self._height)
    data_size = int(getattr(self, "ImgDataSize", 8) or 8)
    return width, height, data_size

load_image(y_flipped=True)

读取二进制图像数据并将其作为二维 NumPy 数组返回。 参数: y_flipped:如果为 True,则读取的图像将垂直翻转(默认值:True) 返回值: 二维 NumPy 图像数组 异常: MiscellaneousError:如果找不到图像文件名 BinaryFileNotFound:如果二进制文件不存在

Source code in .build\zh\isdreader\chunks.py
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
def load_image(self, y_flipped: bool = True) -> np.ndarray:
    """
    读取二进制图像数据并将其作为二维 NumPy 数组返回。
    参数:
      y_flipped:如果为 True,则读取的图像将垂直翻转(默认值:True)
    返回值:
      二维 NumPy 图像数组
    异常:
      MiscellaneousError:如果找不到图像文件名
      BinaryFileNotFound:如果二进制文件不存在
    """
    fn = _find_image_type_value(self._type_elem, "FileName")
    if fn is None:
        raise MiscellaneousError("Image file name not found")
    if not fn.casefold().endswith(".bin"):
        fn = fn + ".bin"
    resolver = _PathResolver(self._isd_root)
    bin_path = resolver.resolve_binary_path(
        ch=self._ch_public,
        data_gate=(self._dg_xml_id - 1),
        img_name=self.image_name,
        image_type=fn,
    )
    if not bin_path.exists():
        raise BinaryFileNotFound(f"Binary file not found: {bin_path}")

    width, height, data_size = self.build_metadata_args()

    loader = _BinaryLoader(logger=_logger)
    arr = loader.load_as_2d_array(bin_path, width, height, data_size)

    self._img_array = np.flipud(arr) if y_flipped else arr
    return self._img_array

CH_NUM_TO_LETTER = {1: 'A', 2: 'B', 3: 'C', 4: 'D'} module-attribute

将缩写图像类型映射到全称

BinaryFileNotFound

Bases: Exception

如果在 ISD 文件夹中找不到指定的二进制文件,则会发生异常。

Source code in .build\zh\isdreader\isd_helper.py
55
56
57
58
59
class BinaryFileNotFound(Exception):
    """
    如果在 ISD 文件夹中找不到指定的二进制文件,则会发生异常。
    """
    pass

DescriptionNotFound

Bases: Exception

如果在 ISD 文件夹中找不到 Description.xml 文件,则会发生异常。

Source code in .build\zh\isdreader\isd_helper.py
41
42
43
44
45
class DescriptionNotFound(Exception):
    """
    如果在 ISD 文件夹中找不到 Description.xml 文件,则会发生异常。
    """
    pass

InsufficientMetaData

Bases: Exception

当元数据不足以继续处理时,会发生异常。

Source code in .build\zh\isdreader\isd_helper.py
48
49
50
51
52
class InsufficientMetaData(Exception):
    """
    当元数据不足以继续处理时,会发生异常。
    """
    pass

InvalidChannel

Bases: Exception

当指定的通道索引无效时,会发生异常。

Source code in .build\zh\isdreader\isd_helper.py
13
14
15
16
17
class InvalidChannel(Exception):
    """
    当指定的通道索引无效时,会发生异常。
    """
    pass

InvalidDataGate

Bases: Exception

当指定的数据门索引无效时,会发生异常。

Source code in .build\zh\isdreader\isd_helper.py
20
21
22
23
24
class InvalidDataGate(Exception):
    """
    当指定的数据门索引无效时,会发生异常。
    """
    pass

InvalidSliceNo

Bases: Exception

当指定的切片编号无效时,会发生异常。

Source code in .build\zh\isdreader\isd_helper.py
27
28
29
30
31
class InvalidSliceNo(Exception):
    """
    当指定的切片编号无效时,会发生异常。
    """
    pass

IsdNotFound

Bases: Exception

当指定的 ISD 文件夹不存在时,会发生异常。

Source code in .build\zh\isdreader\isd_helper.py
34
35
36
37
38
class IsdNotFound(Exception):
    """
    当指定的 ISD 文件夹不存在时,会发生异常。
    """
    pass

MiscellaneousError

Bases: Exception

因其他未知原因导致的例外情况

Source code in .build\zh\isdreader\isd_helper.py
62
63
64
65
66
class MiscellaneousError(Exception):
    """
    因其他未知原因导致的例外情况
    """
    pass

IsdReader

代表整个 ISD 文件夹的根类 此类是访问 ISD 采集数据集中所有通道、数据门和图像的主要入口点。 换句话说,它是一个包含整个 ISD 数据的对象类。 属性: path:要包含的 ISD 文件夹的路径 description_path:Description.xml 文件的路径(位于 ISD 文件夹下) logger:此对象的日志记录器实例

Source code in .build\zh\isdreader\isd_root.py
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 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
 69
 70
 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
 99
100
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
class IsdReader:
    """
    代表整个 ISD 文件夹的根类
    此类是访问 ISD 采集数据集中所有通道、数据门和图像的主要入口点。
    换句话说,它是一个包含整个 ISD 数据的对象类。
    属性:
      path:要包含的 ISD 文件夹的路径
      description_path:Description.xml 文件的路径(位于 ISD 文件夹下)
      logger:此对象的日志记录器实例
    """
# --------------------------------------------------------------------------------------------------------
    def __init__(self, *, isd_path: Union[str, Path], logger: Optional[logging.Logger] = None) -> None:
        """
        根据 ISD 文件夹参数初始化 IsdReader 对象。
        参数:
          isd_path:ISD 文件夹的路径(字符串或 pathlib.Path)。
          logger:可选的日志记录器实例。如果为 None,则使用默认日志记录器。
        异常:
          TypeError:如果 isd_path 不是字符串或 Path 类型。
          IsdNotFound:如果 ISD 文件夹不存在。
          DescriptionNotFound:如果在 ISD 文件夹中找不到 Description.xml 文件。
        """
        if not isinstance(isd_path, (str, Path)):
            raise TypeError("isd_path must be str or pathlib.Path")

        self.path = Path(isd_path)
        if not self.path.exists() or not self.path.is_dir():
            raise IsdNotFound(f"ISD folder not found: {isd_path}")

        self.description_path = self.path / "Description.xml"
        if not self.description_path.exists():
            raise DescriptionNotFound(f"Description.xml not found in: {self.path}")

        tree = etree.parse(self.description_path)
        root = tree.getroot()
        isd_root = Path(self.description_path).parent

        self._scan_type = root.findtext("Info/ScanType")
        self._width_pixel = int(root.findtext("Info/WidthPixel") or 0)
        self._height_pixel = int(root.findtext("Info/HeightPixel") or 0)

        wp = root.find("Info/WidthPhysical")
        if wp is not None:
            try:
                self._width_physical = float(wp.text.strip())
            except Exception:
                self._width_physical = None
            self._width_physical_unit = wp.get("Unit")
        else:
            self._width_physical = None
            self._width_physical_unit = None

        hp = root.find("Info/HeightPhysical")
        if hp is not None:
            try:
                self._height_physical = float(hp.text.strip())
            except Exception:
                self._height_physical = None
            self._height_physical_unit = hp.get("Unit")
        else:
            self._height_physical = None
            self._height_physical_unit = None

        self._channels: List[ChChunk] = []
        for ch_elem in root.findall("Channel"):
            self._channels.append(ChChunk(root, ch_elem, isd_root, self._width_pixel or 0, self._height_pixel or 0))

        self._root_elem = root

        self.logger = logger or logging.getLogger(__name__)
# --------------------------------------------------------------------------------------------------------
    def __repr__(self) -> str:
        """
        此函数返回 IsdReader 的字符串摘要。
        返回值:
          包含大小和可用通道数的字符串。
        """
        parts: List[str] = []
        if self._width_pixel is not None and self._height_pixel is not None:
            parts.append(f"size={self._width_pixel}x{self._height_pixel}")
        chs = self.GetCh()
        if chs:
            parts.append(f"channels={','.join(str(int(c)) for c in chs)}")
        return f"IsdReader[{', '.join(parts)}]"
# --------------------------------------------------------------------------------------------------------
    def GetCh(self, ch: Optional[int] = None):
        """
        获取 ChChunk 实例或列出所有频道。
        参数:
          ch:None 或指定的 ChChunk 编号
        返回值:
          如果 ch 为 None,则返回可用频道编号列表;否则,返回指定的 ChChunk 或 None。
        """
        if ch is None:
            return [c._ch for c in self._channels if c._ch is not None]
        for c in self._channels:
            if c._ch == int(ch):
                return c
        return None
# --------------------------------------------------------------------------------------------------------
    def GetImage(self, *, ch: int, gate: int, image_type: str, slice_no: Optional[int] = 1) -> Optional[ImageChunk]:
        """
        直接检索 ImageChunk 的方法
        参数:
          ch:通道号(1 为起始值)
          gate:数据门编号(1 为起始值)
          image_type:图像类型(缩写或全称)
          slice_no:切片编号(1 为起始值,默认值:1)
        返回值:
          找到符合指定条件的 ImageChunk 实例;否则,返回 None
        """
        chObj = self.GetCh(ch)
        if chObj is None:
            return None
        gateObj = chObj.GetDataGate(gate)
        if gateObj is None:
            return None
        imgObj = gateObj.GetImage(image_type, slice_no)
        return imgObj

GetCh(ch=None)

获取 ChChunk 实例或列出所有频道。 参数: ch:None 或指定的 ChChunk 编号 返回值: 如果 ch 为 None,则返回可用频道编号列表;否则,返回指定的 ChChunk 或 None。

Source code in .build\zh\isdreader\isd_root.py
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
def GetCh(self, ch: Optional[int] = None):
    """
    获取 ChChunk 实例或列出所有频道。
    参数:
      ch:None 或指定的 ChChunk 编号
    返回值:
      如果 ch 为 None,则返回可用频道编号列表;否则,返回指定的 ChChunk 或 None。
    """
    if ch is None:
        return [c._ch for c in self._channels if c._ch is not None]
    for c in self._channels:
        if c._ch == int(ch):
            return c
    return None

GetImage(*, ch, gate, image_type, slice_no=1)

直接检索 ImageChunk 的方法 参数: ch:通道号(1 为起始值) gate:数据门编号(1 为起始值) image_type:图像类型(缩写或全称) slice_no:切片编号(1 为起始值,默认值:1) 返回值: 找到符合指定条件的 ImageChunk 实例;否则,返回 None

Source code in .build\zh\isdreader\isd_root.py
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
def GetImage(self, *, ch: int, gate: int, image_type: str, slice_no: Optional[int] = 1) -> Optional[ImageChunk]:
    """
    直接检索 ImageChunk 的方法
    参数:
      ch:通道号(1 为起始值)
      gate:数据门编号(1 为起始值)
      image_type:图像类型(缩写或全称)
      slice_no:切片编号(1 为起始值,默认值:1)
    返回值:
      找到符合指定条件的 ImageChunk 实例;否则,返回 None
    """
    chObj = self.GetCh(ch)
    if chObj is None:
        return None
    gateObj = chObj.GetDataGate(gate)
    if gateObj is None:
        return None
    imgObj = gateObj.GetImage(image_type, slice_no)
    return imgObj

__init__(*, isd_path, logger=None)

根据 ISD 文件夹参数初始化 IsdReader 对象。 参数: isd_path:ISD 文件夹的路径(字符串或 pathlib.Path)。 logger:可选的日志记录器实例。如果为 None,则使用默认日志记录器。 异常: TypeError:如果 isd_path 不是字符串或 Path 类型。 IsdNotFound:如果 ISD 文件夹不存在。 DescriptionNotFound:如果在 ISD 文件夹中找不到 Description.xml 文件。

Source code in .build\zh\isdreader\isd_root.py
25
26
27
28
29
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
def __init__(self, *, isd_path: Union[str, Path], logger: Optional[logging.Logger] = None) -> None:
    """
    根据 ISD 文件夹参数初始化 IsdReader 对象。
    参数:
      isd_path:ISD 文件夹的路径(字符串或 pathlib.Path)。
      logger:可选的日志记录器实例。如果为 None,则使用默认日志记录器。
    异常:
      TypeError:如果 isd_path 不是字符串或 Path 类型。
      IsdNotFound:如果 ISD 文件夹不存在。
      DescriptionNotFound:如果在 ISD 文件夹中找不到 Description.xml 文件。
    """
    if not isinstance(isd_path, (str, Path)):
        raise TypeError("isd_path must be str or pathlib.Path")

    self.path = Path(isd_path)
    if not self.path.exists() or not self.path.is_dir():
        raise IsdNotFound(f"ISD folder not found: {isd_path}")

    self.description_path = self.path / "Description.xml"
    if not self.description_path.exists():
        raise DescriptionNotFound(f"Description.xml not found in: {self.path}")

    tree = etree.parse(self.description_path)
    root = tree.getroot()
    isd_root = Path(self.description_path).parent

    self._scan_type = root.findtext("Info/ScanType")
    self._width_pixel = int(root.findtext("Info/WidthPixel") or 0)
    self._height_pixel = int(root.findtext("Info/HeightPixel") or 0)

    wp = root.find("Info/WidthPhysical")
    if wp is not None:
        try:
            self._width_physical = float(wp.text.strip())
        except Exception:
            self._width_physical = None
        self._width_physical_unit = wp.get("Unit")
    else:
        self._width_physical = None
        self._width_physical_unit = None

    hp = root.find("Info/HeightPhysical")
    if hp is not None:
        try:
            self._height_physical = float(hp.text.strip())
        except Exception:
            self._height_physical = None
        self._height_physical_unit = hp.get("Unit")
    else:
        self._height_physical = None
        self._height_physical_unit = None

    self._channels: List[ChChunk] = []
    for ch_elem in root.findall("Channel"):
        self._channels.append(ChChunk(root, ch_elem, isd_root, self._width_pixel or 0, self._height_pixel or 0))

    self._root_elem = root

    self.logger = logger or logging.getLogger(__name__)

__repr__()

此函数返回 IsdReader 的字符串摘要。 返回值: 包含大小和可用通道数的字符串。

Source code in .build\zh\isdreader\isd_root.py
85
86
87
88
89
90
91
92
93
94
95
96
97
def __repr__(self) -> str:
    """
    此函数返回 IsdReader 的字符串摘要。
    返回值:
      包含大小和可用通道数的字符串。
    """
    parts: List[str] = []
    if self._width_pixel is not None and self._height_pixel is not None:
        parts.append(f"size={self._width_pixel}x{self._height_pixel}")
    chs = self.GetCh()
    if chs:
        parts.append(f"channels={','.join(str(int(c)) for c in chs)}")
    return f"IsdReader[{', '.join(parts)}]"