Skip to content

API Reference

注意(プライベート要素)

このモジュールには先頭にアンダースコアを含む「プライベート」なクラス/関数が存在します。既定ではそれらの詳細はドキュメントから除外されます。

パッケージ全体

ISD Readerパッケージ

ISDフォルダ内のDescription.xmlファイルを解析/対応するバイナリ画像データを 適切なdtype(uint8/16/32)でNumPy2次元配列としてアクセス可能とする

このパッケージには以下が含まれる
  • 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がNumPy2次元配列である

BinaryFileNotFound

Bases: Exception

ISDフォルダ内に指定されたバイナリファイルが見つからない場合に発生する例外

Source code in .build\ja\isdreader\isd_helper.py
55
56
57
58
59
class BinaryFileNotFound(Exception):
    """
    ISDフォルダ内に指定されたバイナリファイルが見つからない場合に発生する例外
    """
    pass

DescriptionNotFound

Bases: Exception

ISDフォルダ内にDescription.xmlが見つからない場合に発生する例外

Source code in .build\ja\isdreader\isd_helper.py
41
42
43
44
45
class DescriptionNotFound(Exception):
    """
    ISDフォルダ内にDescription.xmlが見つからない場合に発生する例外
    """
    pass

InvalidChannel

Bases: Exception

指定されたチャンネルインデックスが無効な場合に発生する例外

Source code in .build\ja\isdreader\isd_helper.py
13
14
15
16
17
class InvalidChannel(Exception):
    """
    指定されたチャンネルインデックスが無効な場合に発生する例外
    """
    pass

InvalidDataGate

Bases: Exception

指定されたデータゲートインデックスが無効な場合に発生する例外

Source code in .build\ja\isdreader\isd_helper.py
20
21
22
23
24
class InvalidDataGate(Exception):
    """
    指定されたデータゲートインデックスが無効な場合に発生する例外
    """
    pass

IsdNotFound

Bases: Exception

指定されたISDフォルダが存在しない場合に発生する例外

Source code in .build\ja\isdreader\isd_helper.py
34
35
36
37
38
class IsdNotFound(Exception):
    """
    指定されたISDフォルダが存在しない場合に発生する例外
    """
    pass

IsdReader

ISDフォルダ全体を現すルートクラス このクラスはISD取得データセット内の全チャンネル、DataGate、および画像アクセス のメインエントリポイントである すなわち、ISDデータ全体を包括するオブジェクトクラスとなる Attributes: path: 包括すべきISDフォルダへのパス description_path: Description.xmlファイルへのパス(ISD直下に固定) logger: このオブジェクト用のロガーインスタンス

Source code in .build\ja\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
133
class IsdReader:
    """
    ISDフォルダ全体を現すルートクラス
    このクラスはISD取得データセット内の全チャンネル、DataGate、および画像アクセス
    のメインエントリポイントである
    すなわち、ISDデータ全体を包括するオブジェクトクラスとなる
    Attributes:
      path: 包括すべきISDフォルダへのパス
      description_path: Description.xmlファイルへのパス(ISD直下に固定)
      logger: このオブジェクト用のロガーインスタンス
    """
# --------------------------------------------------------------------------------------------------------
    def __init__(self, *, isd_path: Union[str, Path], logger: Optional[logging.Logger] = None) -> None:
        """
        引数ISDフォルダからIsdReaderオブジェクトを初期化する
        Args:
          isd_path: ISDフォルダへのパス(文字列またはpathlib.Path)。
          logger: オプションのロガーインスタンス。Noneの場合はデフォルトロガー
        Raises:
          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の文字列による概要を返す
        Returns:
          サイズと利用可能なチャンネルを含む文字列
        """
        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インスタンスを取得、または全チャンネルをリストアップする
        Args:
          ch: None、或いは指定のChChunk番号
        Returns:
          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を直接取得するメソッド
        Args:
          ch: チャンネル番号(1オリジン)
          gate: DataGate番号(1オリジン)
          image_type: 画像タイプ(省略形、フルネーム)
          slice_no: スライス番号(1オリジン、デフォルト: 1)
        Returns:
          指定された条件で見つかった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インスタンスを取得、または全チャンネルをリストアップする Args: ch: None、或いは指定のChChunk番号 Returns: chがNoneの場合は利用可能なチャンネル番号のリストアップ、それ以外の場合は指定のChChunkまたはNone

Source code in .build\ja\isdreader\isd_root.py
100
101
102
103
104
105
106
107
108
109
110
111
112
113
def GetCh(self, ch: Optional[int] = None):
    """
    ChChunkインスタンスを取得、または全チャンネルをリストアップする
    Args:
      ch: None、或いは指定のChChunk番号
    Returns:
      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を直接取得するメソッド Args: ch: チャンネル番号(1オリジン) gate: DataGate番号(1オリジン) image_type: 画像タイプ(省略形、フルネーム) slice_no: スライス番号(1オリジン、デフォルト: 1) Returns: 指定された条件で見つかったImageChunkインスタンス、それ以外の場合はNone

Source code in .build\ja\isdreader\isd_root.py
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
def GetImage(self, *, ch: int, gate: int, image_type: str, slice_no: Optional[int] = 1) -> Optional[ImageChunk]:
    """
    ImageChunkを直接取得するメソッド
    Args:
      ch: チャンネル番号(1オリジン)
      gate: DataGate番号(1オリジン)
      image_type: 画像タイプ(省略形、フルネーム)
      slice_no: スライス番号(1オリジン、デフォルト: 1)
    Returns:
      指定された条件で見つかった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オブジェクトを初期化する Args: isd_path: ISDフォルダへのパス(文字列またはpathlib.Path)。 logger: オプションのロガーインスタンス。Noneの場合はデフォルトロガー Raises: TypeError: isd_pathが文字列またはPathでない場合 IsdNotFound: ISDフォルダが存在しない場合 DescriptionNotFound: ISDフォルダ内にDescription.xmlが見つからない場合

Source code in .build\ja\isdreader\isd_root.py
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
def __init__(self, *, isd_path: Union[str, Path], logger: Optional[logging.Logger] = None) -> None:
    """
    引数ISDフォルダからIsdReaderオブジェクトを初期化する
    Args:
      isd_path: ISDフォルダへのパス(文字列またはpathlib.Path)。
      logger: オプションのロガーインスタンス。Noneの場合はデフォルトロガー
    Raises:
      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の文字列による概要を返す Returns: サイズと利用可能なチャンネルを含む文字列

Source code in .build\ja\isdreader\isd_root.py
86
87
88
89
90
91
92
93
94
95
96
97
98
def __repr__(self) -> str:
    """
    このIsdReaderの文字列による概要を返す
    Returns:
      サイズと利用可能なチャンネルを含む文字列
    """
    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

複数のDataGateを含有しうるチャンネルを表すクラス 本クラスは取得システム内の物理的な超音波チャンネルに対応する

Source code in .build\ja\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:
    """
    複数のDataGateを含有しうるチャンネルを表すクラス
    本クラスは取得システム内の物理的な超音波チャンネルに対応する
    """
    def __init__(self, root_elem: etree.Element, ch_elem: etree.Element, isd_root: Path, width: int, height: int):
        """
        ChChunkインスタンスを初期化する
        Args:
          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番号をリストアップする
        Returns:
          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をリストアップする
        Args:
          data_gate: Noneの場合はDataGate番号をリストアップする、それ以外の場合は対応するDataGateChunkを返す
        Returns:
          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の文字列による概要を返す
        Returns:
          チャンネル番号、名前、およびDataGateを含む文字列表現
        """
        return f"ChChunk[ch={self._ch}, name={self._channel_name}, data_gates={self.list_datagates()}]"

GetDataGate(data_gate=None)

DataGateChunkインスタンスを取得、または全DataGateをリストアップする Args: data_gate: Noneの場合はDataGate番号をリストアップする、それ以外の場合は対応するDataGateChunkを返す Returns: data_gateがNoneの場合はDataGate番号のリスト、それ以外の場合はDataGateChunkインスタンスまたはNone

Source code in .build\ja\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をリストアップする
    Args:
      data_gate: Noneの場合はDataGate番号をリストアップする、それ以外の場合は対応するDataGateChunkを返す
    Returns:
      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インスタンスを初期化する Args: root_elem: Description.xmlのルートXML要素 ch_elem: チャンネルXML要素 isd_root: ISDフォルダルートへのパス width: 画像の幅(ピクセル数) height: 画像の高さ(ピクセル数)

Source code in .build\ja\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インスタンスを初期化する
    Args:
      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の文字列による概要を返す Returns: チャンネル番号、名前、およびDataGateを含む文字列表現

Source code in .build\ja\isdreader\chunks.py
401
402
403
404
405
406
407
def __repr__(self) -> str:
    """
    このChChunkの文字列による概要を返す
    Returns:
      チャンネル番号、名前、およびDataGateを含む文字列表現
    """
    return f"ChChunk[ch={self._ch}, name={self._channel_name}, data_gates={self.list_datagates()}]"

list_datagates()

利用可能な全DataGate番号をリストアップする Returns: DataGate番号のリスト(1オリジン)

Source code in .build\ja\isdreader\chunks.py
377
378
379
380
381
382
383
def list_datagates(self) -> List[int]:
    """
    利用可能な全DataGate番号をリストアップする
    Returns:
      DataGate番号のリスト(1オリジン)
    """
    return [dg._dg_public for dg in self._datagates if dg._dg_public is not None]

DataGateChunk

チャンネル内のDataGateを表すクラス なおDataGateは複数のスライス画像を含有しうる

Source code in .build\ja\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:
    """
    チャンネル内のDataGateを表すクラス
    なおDataGateは複数のスライス画像を含有しうる
    """
# --------------------------------------------------------------------------------------------------------
    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インスタンスを初期化する
        Args:
          root_elem: Description.xmlのルートXML要素
          ch_elem: チャンネルXML要素
          dg_elem: DataGate 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の存在を確認する
        Args:
          img_elem: 画像XML要素
          type_abbr: 画像タイプの省略形
          type_elem: 特定の画像タイプのXML要素
        Returns:
          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オリジン)をリストアップする
        Returns:
          スライス番号のリスト
        """
        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):
        """
        全スライスをリストアップする
        Args:
          slice_no: Noneの場合は全スライス番号のリストアップを行う、それ以外の場合はTypeErrorが発生
        Returns:
          slice_noがNoneの場合はスライス番号のリスト
        Raises:
          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:
        """
        利用可能な画像タイプを説明する文字列を返却する
        Returns:
          画像タイプの省略形とフルネームのカンマ区切り文字列
        """
        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インスタンスを返却する
        Args:
          image_type: 画像タイプ(省略形、もしくはフルネーム)
          slice_no: スライス番号(1オリジン、デフォルト: 1)
        Returns:
          見つかった場合は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の文字列による概要を返す
        Returns:
          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インスタンスを返却する Args: image_type: 画像タイプ(省略形、もしくはフルネーム) slice_no: スライス番号(1オリジン、デフォルト: 1) Returns: 見つかった場合はImageChunkインスタンス、それ以外の場合はNone

Source code in .build\ja\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インスタンスを返却する
    Args:
      image_type: 画像タイプ(省略形、もしくはフルネーム)
      slice_no: スライス番号(1オリジン、デフォルト: 1)
    Returns:
      見つかった場合は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)

全スライスをリストアップする Args: slice_no: Noneの場合は全スライス番号のリストアップを行う、それ以外の場合はTypeErrorが発生 Returns: slice_noがNoneの場合はスライス番号のリスト Raises: TypeError: slice_noが指定された場合

Source code in .build\ja\isdreader\chunks.py
288
289
290
291
292
293
294
295
296
297
298
299
300
def GetSlice(self, slice_no: Optional[int] = None):
    """
    全スライスをリストアップする
    Args:
      slice_no: Noneの場合は全スライス番号のリストアップを行う、それ以外の場合はTypeErrorが発生
    Returns:
      slice_noがNoneの場合はスライス番号のリスト
    Raises:
      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()

利用可能な画像タイプを説明する文字列を返却する Returns: 画像タイプの省略形とフルネームのカンマ区切り文字列

Source code in .build\ja\isdreader\chunks.py
302
303
304
305
306
307
308
def ImageTypes(self) -> str:
    """
    利用可能な画像タイプを説明する文字列を返却する
    Returns:
      画像タイプの省略形とフルネームのカンマ区切り文字列
    """
    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インスタンスを初期化する Args: root_elem: Description.xmlのルートXML要素 ch_elem: チャンネルXML要素 dg_elem: DataGate XML要素 isd_root: ISDフォルダルートへのパス ch_public: パブリックチャンネル番号(1オリジン) ch_name: チャンネルの名前 width: 画像の幅(ピクセル数) height: 画像の高さ(ピクセル数) sampling_freq_mhz: サンプリング周波数(MHz)

Source code in .build\ja\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インスタンスを初期化する
    Args:
      root_elem: Description.xmlのルートXML要素
      ch_elem: チャンネルXML要素
      dg_elem: DataGate 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の文字列による概要を返す Returns: id、名前、および利用可能な画像を含む文字列表現

Source code in .build\ja\isdreader\chunks.py
329
330
331
332
333
334
335
336
337
def __repr__(self) -> str:
    """
    このDataGateChunkの文字列による概要を返す
    Returns:
      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オリジン)をリストアップする Returns: スライス番号のリスト

Source code in .build\ja\isdreader\chunks.py
274
275
276
277
278
279
280
281
282
283
284
285
286
def list_images(self) -> List[int]:
    """
    利用可能な全スライス番号(1オリジン)をリストアップする
    Returns:
      スライス番号のリスト
    """
    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\ja\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インスタンスを初期化する
        Args:
          root_elem: Description.xmlのルートXML要素
          ch_elem: チャンネルXML要素
          dg_elem: DataGate XML要素
          img_elem: 画像XML要素
          isd_root: ISDフォルダルートへのパス
          ch_public: パブリックチャンネル番号(1オリジン)
          dg_xml_id: DataGateの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に渡すパラメータを構築する
        Returns:
          バイナリ読み込み用の(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:
        """
        バイナリ画像データを読み込み2次元NumPy配列として返却する
        Args:
          y_flipped: Trueの場合、読み込んだ画像を垂直方向に反転(デフォルト: True)
        Returns:
          画像の2次元NumPy配列
        Raises:
          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:
        """
        読み込まれた画像配列にアクセスする
        Returns:
          読み込まれた2次元NumPy配列
        Raises:
          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の文字列による概要を返す
        Returns:
          注入された全プロパティを含む文字列表現
        """
        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

読み込まれた画像配列にアクセスする Returns: 読み込まれた2次元NumPy配列 Raises: MiscellaneousError: 画像がまだ読み込まれていない場合

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

本ImageChunkインスタンスを初期化する Args: root_elem: Description.xmlのルートXML要素 ch_elem: チャンネルXML要素 dg_elem: DataGate XML要素 img_elem: 画像XML要素 isd_root: ISDフォルダルートへのパス ch_public: パブリックチャンネル番号(1オリジン) dg_xml_id: DataGateのXML id属性 type_abbr: 画像タイプの省略形("PP"、"AP"等) type_elem: 特定の画像タイプのXML要素

Source code in .build\ja\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インスタンスを初期化する
    Args:
      root_elem: Description.xmlのルートXML要素
      ch_elem: チャンネルXML要素
      dg_elem: DataGate XML要素
      img_elem: 画像XML要素
      isd_root: ISDフォルダルートへのパス
      ch_public: パブリックチャンネル番号(1オリジン)
      dg_xml_id: DataGateの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の文字列による概要を返す Returns: 注入された全プロパティを含む文字列表現

Source code in .build\ja\isdreader\chunks.py
181
182
183
184
185
186
187
188
189
190
191
192
193
def __repr__(self) -> str:
    """
    このImageChunkの文字列による概要を返す
    Returns:
      注入された全プロパティを含む文字列表現
    """
    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に渡すパラメータを構築する Returns: バイナリ読み込み用の(width, height, data_size)のタプル

Source code in .build\ja\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に渡すパラメータを構築する
    Returns:
      バイナリ読み込み用の(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)

バイナリ画像データを読み込み2次元NumPy配列として返却する Args: y_flipped: Trueの場合、読み込んだ画像を垂直方向に反転(デフォルト: True) Returns: 画像の2次元NumPy配列 Raises: MiscellaneousError: 画像ファイル名が見つからない場合 BinaryFileNotFound: バイナリファイルが存在しない場合

Source code in .build\ja\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:
    """
    バイナリ画像データを読み込み2次元NumPy配列として返却する
    Args:
      y_flipped: Trueの場合、読み込んだ画像を垂直方向に反転(デフォルト: True)
    Returns:
      画像の2次元NumPy配列
    Raises:
      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\ja\isdreader\isd_helper.py
55
56
57
58
59
class BinaryFileNotFound(Exception):
    """
    ISDフォルダ内に指定されたバイナリファイルが見つからない場合に発生する例外
    """
    pass

DescriptionNotFound

Bases: Exception

ISDフォルダ内にDescription.xmlが見つからない場合に発生する例外

Source code in .build\ja\isdreader\isd_helper.py
41
42
43
44
45
class DescriptionNotFound(Exception):
    """
    ISDフォルダ内にDescription.xmlが見つからない場合に発生する例外
    """
    pass

InsufficientMetaData

Bases: Exception

処理を続行するのに十分なメタデータが得られない場合に発生する例外

Source code in .build\ja\isdreader\isd_helper.py
48
49
50
51
52
class InsufficientMetaData(Exception):
    """
    処理を続行するのに十分なメタデータが得られない場合に発生する例外
    """
    pass

InvalidChannel

Bases: Exception

指定されたチャンネルインデックスが無効な場合に発生する例外

Source code in .build\ja\isdreader\isd_helper.py
13
14
15
16
17
class InvalidChannel(Exception):
    """
    指定されたチャンネルインデックスが無効な場合に発生する例外
    """
    pass

InvalidDataGate

Bases: Exception

指定されたデータゲートインデックスが無効な場合に発生する例外

Source code in .build\ja\isdreader\isd_helper.py
20
21
22
23
24
class InvalidDataGate(Exception):
    """
    指定されたデータゲートインデックスが無効な場合に発生する例外
    """
    pass

InvalidSliceNo

Bases: Exception

指定されたスライス番号が無効な場合に発生する例外

Source code in .build\ja\isdreader\isd_helper.py
27
28
29
30
31
class InvalidSliceNo(Exception):
    """
    指定されたスライス番号が無効な場合に発生する例外
    """
    pass

IsdNotFound

Bases: Exception

指定されたISDフォルダが存在しない場合に発生する例外

Source code in .build\ja\isdreader\isd_helper.py
34
35
36
37
38
class IsdNotFound(Exception):
    """
    指定されたISDフォルダが存在しない場合に発生する例外
    """
    pass

MiscellaneousError

Bases: Exception

その他の未知の理由で発生する例外

Source code in .build\ja\isdreader\isd_helper.py
62
63
64
65
66
class MiscellaneousError(Exception):
    """
    その他の未知の理由で発生する例外
    """
    pass

IsdReader

ISDフォルダ全体を現すルートクラス このクラスはISD取得データセット内の全チャンネル、DataGate、および画像アクセス のメインエントリポイントである すなわち、ISDデータ全体を包括するオブジェクトクラスとなる Attributes: path: 包括すべきISDフォルダへのパス description_path: Description.xmlファイルへのパス(ISD直下に固定) logger: このオブジェクト用のロガーインスタンス

Source code in .build\ja\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
133
class IsdReader:
    """
    ISDフォルダ全体を現すルートクラス
    このクラスはISD取得データセット内の全チャンネル、DataGate、および画像アクセス
    のメインエントリポイントである
    すなわち、ISDデータ全体を包括するオブジェクトクラスとなる
    Attributes:
      path: 包括すべきISDフォルダへのパス
      description_path: Description.xmlファイルへのパス(ISD直下に固定)
      logger: このオブジェクト用のロガーインスタンス
    """
# --------------------------------------------------------------------------------------------------------
    def __init__(self, *, isd_path: Union[str, Path], logger: Optional[logging.Logger] = None) -> None:
        """
        引数ISDフォルダからIsdReaderオブジェクトを初期化する
        Args:
          isd_path: ISDフォルダへのパス(文字列またはpathlib.Path)。
          logger: オプションのロガーインスタンス。Noneの場合はデフォルトロガー
        Raises:
          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の文字列による概要を返す
        Returns:
          サイズと利用可能なチャンネルを含む文字列
        """
        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インスタンスを取得、または全チャンネルをリストアップする
        Args:
          ch: None、或いは指定のChChunk番号
        Returns:
          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を直接取得するメソッド
        Args:
          ch: チャンネル番号(1オリジン)
          gate: DataGate番号(1オリジン)
          image_type: 画像タイプ(省略形、フルネーム)
          slice_no: スライス番号(1オリジン、デフォルト: 1)
        Returns:
          指定された条件で見つかった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インスタンスを取得、または全チャンネルをリストアップする Args: ch: None、或いは指定のChChunk番号 Returns: chがNoneの場合は利用可能なチャンネル番号のリストアップ、それ以外の場合は指定のChChunkまたはNone

Source code in .build\ja\isdreader\isd_root.py
100
101
102
103
104
105
106
107
108
109
110
111
112
113
def GetCh(self, ch: Optional[int] = None):
    """
    ChChunkインスタンスを取得、または全チャンネルをリストアップする
    Args:
      ch: None、或いは指定のChChunk番号
    Returns:
      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を直接取得するメソッド Args: ch: チャンネル番号(1オリジン) gate: DataGate番号(1オリジン) image_type: 画像タイプ(省略形、フルネーム) slice_no: スライス番号(1オリジン、デフォルト: 1) Returns: 指定された条件で見つかったImageChunkインスタンス、それ以外の場合はNone

Source code in .build\ja\isdreader\isd_root.py
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
def GetImage(self, *, ch: int, gate: int, image_type: str, slice_no: Optional[int] = 1) -> Optional[ImageChunk]:
    """
    ImageChunkを直接取得するメソッド
    Args:
      ch: チャンネル番号(1オリジン)
      gate: DataGate番号(1オリジン)
      image_type: 画像タイプ(省略形、フルネーム)
      slice_no: スライス番号(1オリジン、デフォルト: 1)
    Returns:
      指定された条件で見つかった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オブジェクトを初期化する Args: isd_path: ISDフォルダへのパス(文字列またはpathlib.Path)。 logger: オプションのロガーインスタンス。Noneの場合はデフォルトロガー Raises: TypeError: isd_pathが文字列またはPathでない場合 IsdNotFound: ISDフォルダが存在しない場合 DescriptionNotFound: ISDフォルダ内にDescription.xmlが見つからない場合

Source code in .build\ja\isdreader\isd_root.py
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
def __init__(self, *, isd_path: Union[str, Path], logger: Optional[logging.Logger] = None) -> None:
    """
    引数ISDフォルダからIsdReaderオブジェクトを初期化する
    Args:
      isd_path: ISDフォルダへのパス(文字列またはpathlib.Path)。
      logger: オプションのロガーインスタンス。Noneの場合はデフォルトロガー
    Raises:
      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の文字列による概要を返す Returns: サイズと利用可能なチャンネルを含む文字列

Source code in .build\ja\isdreader\isd_root.py
86
87
88
89
90
91
92
93
94
95
96
97
98
def __repr__(self) -> str:
    """
    このIsdReaderの文字列による概要を返す
    Returns:
      サイズと利用可能なチャンネルを含む文字列
    """
    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)}]"