# Unable to load a segmentation encoded as .tag file

**URL:** <https://discourse.slicer.org/t/unable-to-load-a-segmentation-encoded-as-tag-file/15271>\
**Category:** Support\
**Tags:** segmentation, dicom\
**Created:** [December 29, 2020, 3:03pm UTC](https://discourse.slicer.org/t/unable-to-load-a-segmentation-encoded-as-tag-file/15271 "2020-12-29T15:03:40Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Maxnach](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/maxnach/32/9366_2.png) [@Maxnach](https://discourse.slicer.org/u/Maxnach)\
**Post date:** [December 29, 2020, 3:03pm UTC](https://discourse.slicer.org/t/unable-to-load-a-segmentation-encoded-as-tag-file/15271/1 "2020-12-29T15:03:40Z")

</div>

Operating system: Windows 10  
Slicer version: 4.13.0  
Expected behavior: Load pre-existing segmentation .tag file  
Actual behavior: Unable to load

Hello 3Dslicer community,

I’m just starting with this amazing software. I would like to load pre-existing segmentation mask generated from a dicom CT-image using another software and saved as .tag files. I can succesfully load the dicom file, but when I load the .tag file (segmentation mask) nothing happens. That would save me a lot of time as I have hundreds of segmented mask file already saved and would like to manipulate them in 3Dslicer with the corresponding dicom image.

Best,

Max

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [December 29, 2020, 3:36pm UTC](https://discourse.slicer.org/t/unable-to-load-a-segmentation-encoded-as-tag-file/15271/2 "2020-12-29T15:36:41Z")

</div>

I’m not aware of that format or of any existing tools in Slicer that will load those files. Usually it’s possible to reverse engineer a format like that. Your best bet is to look for any documentation about the software that generated these files and see if you can maybe find (or write) a converter to a more common format.

---

<div class="post-metadata">

**Author:** ![Maxnach](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/maxnach/32/9366_2.png) [@Maxnach](https://discourse.slicer.org/u/Maxnach)\
**Post date:** [December 29, 2020, 4:29pm UTC](https://discourse.slicer.org/t/unable-to-load-a-segmentation-encoded-as-tag-file/15271/3 "2020-12-29T16:29:12Z")

</div>

Thank you so much for your quick reply. I’m a newbie in dev (medical background) but I know the architecture of these .tag files:

The TAG file format is loosely based on the university of Waterloo IM format.

The image file is composed of two sections:

•The header

•the image binary data.

The Header

The header is entirely composed of lines of ASCII text. Each line is terminated by the characters and (0x0D and 0x0A). The header is terminated by a character (0x0C).

Everything on a line following a “\*” will be considered as comments and can be disregarded by the program.

The header is composed of a series of keywords value pairs. The keyword and values are separated by “:”. Each pair of keyword and values are separated by one or more separation characters. The recognized separators are: " " (space), “,” (comma), “\t” (tab) or “\n” (new-line). You can use lowercase or uppercase indifferently in the keywords, the program converts all the keywords characters to uppercase before parsing the header.

The recognized keywords and their permitted values are:

x:

“X” resolution (in pixels).

y:

“Y” resolution (in pixels).

z:

Number of images in the file.

type:

Gives the size of each pixel, the values supported by the program are BYTE or SHORT (only BYTE is used for the “.tag” files).

org\_x:

Position in “x”, “y” and “z” of the center of the top left pixel of the image.

org\_y:

org\_z:

dim\_x:

Total dimension in “x” and “y” of the image (in millimeters).

dim\_y:

inc\_x:

Distance between 2 consecutive pixels in “x” and “y” of the image (in millimeters).

inc\_y:

epais:

Slice thickness.

dir\_h\_x:

X, y and z components of the horizontal direction vector (in patient system).

dir\_h\_y:

dir\_h\_z:

dir\_v\_x:

X, y and z components of the vertical direction vector (in patient system).

dir\_v\_y:

dir\_v\_z:

uid:

Unique number used to make sure this tag is associated with the correct GLI image.

chksum:

Checksum of the original GLI image.

x:256 y:256 z:9 type:BYTE

org\_x:-204.2221 org\_y:-181.8909 org\_z:-250.0000

inc\_x:0.7105 inc\_y:0.7105 epais:5.0000

dir\_h\_x:1.0000 dir\_h\_y:0.0000 dir\_h\_z:0.0000

dir\_v\_x:0.0000 dir\_v\_y:1.0000 dir\_v\_z:0.0000

uid:AFCCCAC6 chksum:09F1588D bin:256

- number of echos: 0

^L

Sample TAG header

The Image Data

The image data is written in binary form. There are X x Y x Z pixels in the image data. The values for X, Y and Z come from the header. Each pixel takes 1 or 2 bytes according to the value associated with the “type” keyword (tag files use “Byte”, so one byte per pixel). The pixels are written using the algorithm:

```
      for each image k

                for each line j (starting at the top)

                          for each pixel i (starting at the left)

                                    write pixel [k][j][i] ;

```

Could that help ?

Best regards,

Max

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [December 29, 2020, 7:34pm UTC](https://discourse.slicer.org/t/unable-to-load-a-segmentation-encoded-as-tag-file/15271/4 "2020-12-29T19:34:50Z")

</div>

You can read such images using [RawImageGuess extension](https://github.com/acetylsalicyl/SlicerRawImageGuess). You can get image dimensions, spacing, etc. from the information in the image header. RawImageGuess can generate a nhdr header file that you can use to load the .tag file.

You can easily create such nhdr file automatically, using a Python script, by parsing the .tag file header. Mapping from .tag to .nrrd:

- x, y, z -\> sizes
- type -\> type
- org\_\* -\> space origin
- inc\_\* and dir\_\* -\> space\_directions (it is a 3x3 matrix, column norms equal inc\* values, first column direction is dir\_h, second column direction is dir\_v, third column direction is _cross(dir\_h, dir\_v)_)

To make eveyone’s life easier, I would recommend you to ask the developers of the software that generates these .tag files to generate standard .nrrd files instead.

---

<div class="post-metadata">

**Author:** ![Maxnach](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/maxnach/32/9366_2.png) [@Maxnach](https://discourse.slicer.org/u/Maxnach)\
**Post date:** [December 30, 2020, 9:18am UTC](https://discourse.slicer.org/t/unable-to-load-a-segmentation-encoded-as-tag-file/15271/5 "2020-12-30T09:18:08Z")

</div>

Thank you so much, I’m indeed able to load the .tag file using the .nhdr header. I do not know how to code in Python to perform this process in batch , I will probably do it manually or a ask around.

I’m now trying to match the original dicom and the mask, but it seems 3D slicer considers them as separated volume. I tried loading the mask from the segmentation module using import labelmask/model nothing happens when I click on import (hence I’m not able to indicate the path of the .nhdr file)… any ideas…?

Best regards,

Max

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [December 30, 2020, 6:36pm UTC](https://discourse.slicer.org/t/unable-to-load-a-segmentation-encoded-as-tag-file/15271/6 "2020-12-30T18:36:44Z")

</div>

RawImageGuess always sets a default image orientation, while axes of your input DICOM volume may be oriented differently. To make the segmentation line up with the original DICOM images, you probably need to compute the space\_directions matrix as I described above.

---

<div class="post-metadata">

**Author:** ![Maxnach](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/maxnach/32/9366_2.png) [@Maxnach](https://discourse.slicer.org/u/Maxnach)\
**Post date:** [January 5, 2021, 4:35pm UTC](https://discourse.slicer.org/t/unable-to-load-a-segmentation-encoded-as-tag-file/15271/7 "2021-01-05T16:35:55Z")

</div>

Hello,

Thank you very much for your answers. I almost succeeded in alignement, I computed the space direction matrix only using the inc\* value and the mask is almost aligned. However, it seems my problem is to correctly indicate the number of size of header (in bytes) : how could I know it? I tried with [http://bytesizematters.com/](http://bytesizematters.com/) (lol), it indicates 223 without space but it’s still not correct.

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/0/8/08015ed2392291aeadce295933d0e749afc33871.png)

So If I get it right, I have to be sure all my parameters are ok by manually checking on 3D slicer, and when everything is ok I can creare a python loop.

May I ask you an advice for the next step : how can I make 3D slicer understand that this file (openned with the .nhdr header) is actually a segmention and not a volume ? In the segmentation tools, nothing happens when I click on “import” (whether I select labelmaps or model).

Best regards,

Maxime

Edit : Here is the .tag file : [[2.tag - Google Drive](https://drive.google.com/file/d/1ooXY464Iw3Z3FKblze0j9xLwoWnZk89e/view?usp=sharing)]

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [January 5, 2021, 5:09pm UTC](https://discourse.slicer.org/t/unable-to-load-a-segmentation-encoded-as-tag-file/15271/8 "2021-01-05T17:09:38Z")

</div>

> [@Maxnach](#):
>
> how can I make 3D slicer understand that this file (openned with the .nhdr header) is actually a segmention and not a volume ?

You can use the Volumes → Volume Information interface to turn it into a Labelmap volume, then you can import it to a Segmentation

---

<div class="post-metadata">

**Author:** ![Maxnach](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/maxnach/32/9366_2.png) [@Maxnach](https://discourse.slicer.org/u/Maxnach)\
**Post date:** [January 5, 2021, 5:31pm UTC](https://discourse.slicer.org/t/unable-to-load-a-segmentation-encoded-as-tag-file/15271/9 "2021-01-05T17:31:06Z")

</div>

Oh gosh thanks, that indeed works !! I feel I’m almost there :

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/d/3/d377b4493992c801b7139395d1d2c7ed7d04f20e.png)

I will try to solve the byte size issue (pretty sure the header size I put is not correct) and then test whether the radiomics extension works correctly on the mask…

If that works, you have just saved me weeks of labour.

Best regards,

Maxime

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [January 5, 2021, 5:35pm UTC](https://discourse.slicer.org/t/unable-to-load-a-segmentation-encoded-as-tag-file/15271/10 "2021-01-05T17:35:46Z")

</div>

See some more options of how to conveniently load an image file directly as labelmap volume or segmentation: [https://slicer.readthedocs.io/en/latest/user\_guide/modules/volumes.html#load-image-file-as-labelmap-volume](https://slicer.readthedocs.io/en/latest/user_guide/modules/volumes.html#load-image-file-as-labelmap-volume)

---

<div class="post-metadata">

**Author:** ![Maxnach](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/maxnach/32/9366_2.png) [@Maxnach](https://discourse.slicer.org/u/Maxnach)\
**Post date:** [January 5, 2021, 5:53pm UTC](https://discourse.slicer.org/t/unable-to-load-a-segmentation-encoded-as-tag-file/15271/11 "2021-01-05T17:53:44Z")

</div>

Thank you for these tips, it seems I can load it as a labelmap volume directly, but not as a segmentation (since I load an .nhdr file and not a .nrrd)

I tried the radiomics analysis (even though mask is not perfectly aligned), but I have a blank sheet as a results… any ideas?

Maxime

Edit: it’s not a problem of mask/volume as I’m able to calculte segmentation statistics

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [January 5, 2021, 8:30pm UTC](https://discourse.slicer.org/t/unable-to-load-a-segmentation-encoded-as-tag-file/15271/12 "2021-01-05T20:30:08Z")

</div>

I’ve added .nhdr as an acceptable extension for segmentation files (in addition to nrrd). It will be available in Slicer Preview Release from tomorrow.
