# Model files are now saved in LPS coordinate system

**URL:** <https://discourse.slicer.org/t/model-files-are-now-saved-in-lps-coordinate-system/10446>\
**Category:** Development\
**Created:** [February 26, 2020, 5:23pm UTC](https://discourse.slicer.org/t/model-files-are-now-saved-in-lps-coordinate-system/10446 "2020-02-26T17:23:22Z")\
**Posts on this page:** 19\
**Page:** 1

<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:** [February 26, 2020, 5:23pm UTC](https://discourse.slicer.org/t/model-files-are-now-saved-in-lps-coordinate-system/10446/1 "2020-02-26T17:23:22Z")

</div>

While Slicer uses RAS coordinate system internally, images, transforms, and markups files are stored in LPS coordinate system, because DICOM and all medical image computing software (maybe except a few very old ones) uses LPS coordinate system in files.

However, Slicer has been still using its internal RAS coordinate system in mesh files (STL, VTK, VTP, OBJ, PLY), which [caused issues when interfacing with third-party software](https://issues.slicer.org/view.php?id=4445).

Starting from tomorrow (Slicer-4.11.0-2020-02-26, revision 28794), Slicer Preview Release will **save models in LPS coordinate system, and assume mesh files to be in LPS coordinate system by default.**

Slicer started embedding coordinate system name in mesh files a few years ago (see `SPACE=RAS` in the file header), so all the files that Slicer saved in recent years will load correctly and any scene files created with any version of Slicer will also load the models with correct orientation, too.

Manual setting of coordinate system (in Add data dialog / Options column) is only needed when loading a mesh file without a scene that were created by Slicer-4.6 (2017-09-27) and earlier; and obj files created by Slicer-4.6 and Slicer-4.8 (between 2016-10-11 and 2018-03-26), or files are created by third-party software in RAS coordinate system.

See more details and list of modified files in [this commit](http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=28794).

solid 3D Slicer output. SPACE=LPS  
facet normal 0.670457 -0.150029 0.726621  
outer loop  
vertex 86.7619 22.6655 32.2962  
vertex 85.9753 22.2651 32.9394

If you encounter orientation issues when loading a model file, you have the following options:

- Option A: Specify the coordinate system when you open the model file. In “Add data” dialog, click “Show Options” and then choose “RAS” as coordinate system.

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

- Option B: Update the third-party software that generate the mesh to save coordinates in LPS coordinate system instead of RAS coordinate system. Conversion is simple inverting the sign of the first two coordinates.

- Option C: Write “SPACE=RAS” in the comment/description field in the mesh file (for STL, OBJ, PLY, VTK file; for VTP files, add in the first value of a vtkStringArray field array named “SPACE”) to indicate that the values are stored in RAS coordinate system. This option is useful if coordinates have to be stored in RAS coordinate system (for example, for compatibility with other software).

> **Examples of file headers that specify what coordinate system is used (click on the arrow on the left to expand)**
>
> Example of an STL file header that stores coordinates in RAS coordinate system:
> 
> ```plaintext
> solid 3D Slicer output. SPACE=RAS
> facet normal 0.670457 -0.150029 0.726621
> outer loop
> vertex 86.7619 22.6655 32.2962
> vertex 85.9753 22.2651 32.9394
> ...
> 
> ```
> 
> Example of an OBJ file header that stores coordinates in RAS coordinate system:
> 
> ```plaintext
> # 3D Slicer output. SPACE=RAS
> 
> mtllib Segment_1.mtl
> 
> v 83.3949 8.0714 -7.2143
> v 83.3949 9.0714 -7.2143
> v 83.3949 10.0714 -7.2143
> ...
> 
> ```
> 
> Example of a VTK file header that stores coordinates in RAS coordinate system:
> 
> ```plaintext
> # vtk DataFile Version 4.2
> 3D Slicer output. SPACE=RAS
> BINARY
> DATASET POLYDATA
> POINTS 7192 float 
> ...
> 
> ```
> 
> Example of a PLY file header that stores coordinates in RAS coordinate system:
> 
> ```plaintext
> ply
> format binary_little_endian 1.0
> comment VTK generated PLY File
> comment SPACE=RAS
> obj_info vtkPolyData points and polygons: vtk4.0
> element vertex 13327
> property float x
> property float y
> ...
> 
> ```
> 
> Example of a VTP file header that stores coordinates in RAS coordinate system:
> 
> ```plaintext
> <?xml version="1.0"?>
> <VTKFile type="PolyData" version="0.1" byte_order="LittleEndian" header_type="UInt32">
> <PolyData>
> <FieldData>
> <Array type="String" Name="SPACE" NumberOfTuples="1" format="ascii">
> 82 65 83 0
> </Array>
> </FieldData>
> <Piece NumberOfPoints="13327" NumberOfVerts="0" NumberOfLines="0" NumberOfStrips="0" NumberOfPolys="26650">
> <PointData>
> ...
> 
> ```

See C++ code examples of writing coordinate system information when saving a mesh file [here](https://github.com/Slicer/SlicerGitSVNArchive/blob/c0829f596f0ea661e0c5484056bd1374a3d22958/Libs/MRML/Core/vtkMRMLModelStorageNode.cxx#L421-L647).

---

<div class="post-metadata">

**Author:** ![Juicy](https://avatars.discourse-cdn.com/v4/letter/j/74df32/32.png) [@Juicy](https://discourse.slicer.org/u/Juicy)\
**Post date:** [February 26, 2020, 7:29pm UTC](https://discourse.slicer.org/t/model-files-are-now-saved-in-lps-coordinate-system/10446/2 "2020-02-26T19:29:35Z")

</div>

Will Slicer convert to using LPS internally at some point? It seems as though it would make sense given how many other applications use LPS.

---

<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:** [February 26, 2020, 7:36pm UTC](https://discourse.slicer.org/t/model-files-are-now-saved-in-lps-coordinate-system/10446/3 "2020-02-26T19:36:21Z")

</div>

Compatibility with other applications is taken care of by using LPS in files. It would make things simpler to switch to LPS internally, too. It is just a matter of development priorities. There are other things that would make bigger impact for Slicer developers (such as switching to VTK oriented image data) and users (better widgets, measurements, 4D support, etc.).

---

<div class="post-metadata">

**Author:** ![siaeleni](https://avatars.discourse-cdn.com/v4/letter/s/b4bc9f/32.png) [@siaeleni](https://discourse.slicer.org/u/siaeleni)\
**Post date:** [April 10, 2020, 6:16pm UTC](https://discourse.slicer.org/t/model-files-are-now-saved-in-lps-coordinate-system/10446/4 "2020-04-10T18:16:34Z")

</div>

@lassoan Hi Andras, the link at the end seems that it is unavailable. Could you please provide that since I am trying to find a way to read/write files in different spaces using python? Thanks a lot.

---

<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:** [April 10, 2020, 6:34pm UTC](https://discourse.slicer.org/t/model-files-are-now-saved-in-lps-coordinate-system/10446/5 "2020-04-10T18:34:50Z")

</div>

I’ve udpated the link. If you want to load an STL/OBJ/PLY/VTK/VTU file that does not have embedded cordinate system information in it and is stored in RAS coordinate system then you can load it like this:

```python
modelNode = slicer.modules.models.logic().AddModel(
  "something.stl", slicer.vtkMRMLStorageNode.CoordinateSystemRAS)

```

---

<div class="post-metadata">

**Author:** ![brhoom](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/brhoom/32/1228_2.png) [@brhoom](https://discourse.slicer.org/u/brhoom)\
**Post date:** [October 27, 2020, 9:06pm UTC](https://discourse.slicer.org/t/model-files-are-now-saved-in-lps-coordinate-system/10446/6 "2020-10-27T21:06:10Z")

</div>

Good to know, I was having some problems recently related to this. It would be nice if this option is also available for markups.

---

<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:** [October 27, 2020, 9:26pm UTC](https://discourse.slicer.org/t/model-files-are-now-saved-in-lps-coordinate-system/10446/7 "2020-10-27T21:26:09Z")

</div>

Yes, the same automatic LPS/RAS coordinate system switch is available for markups, too.

---

<div class="post-metadata">

**Author:** ![Saima](https://avatars.discourse-cdn.com/v4/letter/s/9d8465/32.png) [@Saima](https://discourse.slicer.org/u/Saima)\
**Post date:** [April 20, 2021, 5:44am UTC](https://discourse.slicer.org/t/model-files-are-now-saved-in-lps-coordinate-system/10446/8 "2021-04-20T05:44:19Z")

</div>

> [@lassoan](#):
>
> `slicer.vtkMRMLStorageNode.CoordinateSystemRAS`

if you add fiducials like  
markupsNode3 = slicer.mrmlScene.AddNewNodeByClass(“vtkMRMLMarkupsFiducialNode”)  
markupsNode3.CreateDefaultDisplayNodes()

how to get the RAS coordinates for fiducials.

Thanks

---

<div class="post-metadata">

**Author:** ![Saima](https://avatars.discourse-cdn.com/v4/letter/s/9d8465/32.png) [@Saima](https://discourse.slicer.org/u/Saima)\
**Post date:** [April 22, 2021, 4:46am UTC](https://discourse.slicer.org/t/model-files-are-now-saved-in-lps-coordinate-system/10446/9 "2021-04-22T04:46:55Z")

</div>

> [@lassoan](#):
>
> `slicer.vtkMRMLStorageNode.CoordinateSystemRAS`

how to save node in RAS coordinate system.

Regards,  
Saima Safdar

---

<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:** [April 22, 2021, 4:49am UTC](https://discourse.slicer.org/t/model-files-are-now-saved-in-lps-coordinate-system/10446/10 "2021-04-22T04:49:40Z")

</div>

You can specified the desired coordinate system in [`SetCoordinateSystem` method of the storage node](https://apidocs.slicer.org/master/classvtkMRMLMarkupsStorageNode.html#aaf267d2551286c7b1bb0740bc19aa6a1).

I would not recommend saving in RAS though, as in medical image computing, data files generally use LPS.

---

<div class="post-metadata">

**Author:** ![pya942976269](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pya942976269/32/14267_2.png) [@pya942976269](https://discourse.slicer.org/u/pya942976269)\
**Post date:** [May 10, 2022, 10:13am UTC](https://discourse.slicer.org/t/model-files-are-now-saved-in-lps-coordinate-system/10446/11 "2022-05-10T10:13:30Z")

</div>

Is there a specific procedure or read/write method to make “SPACE=RAS” in the operation of option C?  
Thank you.

---

<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:** [May 10, 2022, 11:23pm UTC](https://discourse.slicer.org/t/model-files-are-now-saved-in-lps-coordinate-system/10446/12 "2022-05-10T23:23:09Z")

</div>

> [@pya942976269](#):
>
> Is there a specific procedure or read/write method to make “SPACE=RAS” in the operation of option C?

If you run your Python script in Slicer then you can use the [vtkMRMLModelStorageNode](http://apidocs.slicer.org/master/classvtkMRMLStorageNode.html). It can save models in LPS or RAS and always saves the coordinate system name in the header.

If you run code in a different environment then you can write the coordinate system specification in the file header yourself. If you use VTK then you can copy [Slicer’s implementation](https://github.com/Slicer/Slicer/blob/1efef1b35da0f95835c4f56def90629782cd492e/Libs/MRML/Core/vtkMRMLModelStorageNode.cxx#L479-L732).

---

<div class="post-metadata">

**Author:** ![pya942976269](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pya942976269/32/14267_2.png) [@pya942976269](https://discourse.slicer.org/u/pya942976269)\
**Post date:** [May 13, 2022, 8:24am UTC](https://discourse.slicer.org/t/model-files-are-now-saved-in-lps-coordinate-system/10446/13 "2022-05-13T08:24:44Z")

</div>

Since I don’t understand this operation well, can you please provide me with a sample program?

---

<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:** [May 13, 2022, 5:04pm UTC](https://discourse.slicer.org/t/model-files-are-now-saved-in-lps-coordinate-system/10446/14 "2022-05-13T17:04:35Z")

</div>

The source code that I linked to shows what Slicer does and you can do exactly the same in your software. If you need more help then you can create a standalone example by copy-pasting the relevant code parts from Slicer’s implementation into a similar VTK example and post the link here so that we can have a look and comment on it.

---

<div class="post-metadata">

**Author:** ![joanne40226](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/joanne40226/32/14681_2.png) [@joanne40226](https://discourse.slicer.org/u/joanne40226)\
**Post date:** [August 20, 2022, 2:29am UTC](https://discourse.slicer.org/t/model-files-are-now-saved-in-lps-coordinate-system/10446/15 "2022-08-20T02:29:46Z")

</div>

@lassoan Hi, i try OptionA with markups however it does not surve the coordinate system choice.  
What can i do if i want to read my markups(saved by LPS) into RAS?  
Thank you for your time!

---

<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:** [August 20, 2022, 7:27am UTC](https://discourse.slicer.org/t/model-files-are-now-saved-in-lps-coordinate-system/10446/16 "2022-08-20T07:27:03Z")

</div>

Could you upload your markup file to somewhere (Dropbox, OneDrive, Google drive) and post the link here?

---

<div class="post-metadata">

**Author:** ![joanne40226](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/joanne40226/32/14681_2.png) [@joanne40226](https://discourse.slicer.org/u/joanne40226)\
**Post date:** [August 20, 2022, 12:07pm UTC](https://discourse.slicer.org/t/model-files-are-now-saved-in-lps-coordinate-system/10446/17 "2022-08-20T12:07:50Z")

</div>

@lassoan

> **[000\_transed.mrk.json](https://drive.google.com/file/d/1UHKW3cdwGwKGncme7Dk8VJJQDk1L-3nS/view?usp=sharing)**
>
> Google Drive file.

thank you!

---

<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:** [August 20, 2022, 8:51pm UTC](https://discourse.slicer.org/t/model-files-are-now-saved-in-lps-coordinate-system/10446/18 "2022-08-20T20:51:56Z")

</div>

I’ve checked the file and everything looks good. The control point coordinates in the .mrk.json file are defined in LPS coordinate system (first control point: `[195.993, 6.125, -90.188]`). When Slicer loads the file, it converts the coordinates into RAS coordinate system (first control point: `[-195.993, -6.125, -90.188]`).

```json
{
...
    "markups": [ {
            "type": "Fiducial",
            "coordinateSystem": "LPS", ...
            "controlPoints": [
                { ... "position": [195.99323699260385, 6.125348335657372, -90.18842609112076], ... },
                { ... "position": [150.0713619926038, 71.15759015694647, -79.89948566143325], ... }, ...]
...
}

```

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/0/9/09e2a8d188afa51a00bbfd3c98f804159624fd28.png)

If you specify the control points in RAS coordinate system then in the file set `"coordinateSystem": "RAS"`.

---

<div class="post-metadata">

**Author:** ![joanne40226](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/joanne40226/32/14681_2.png) [@joanne40226](https://discourse.slicer.org/u/joanne40226)\
**Post date:** [August 21, 2022, 2:59am UTC](https://discourse.slicer.org/t/model-files-are-now-saved-in-lps-coordinate-system/10446/19 "2022-08-21T02:59:34Z")

</div>

@lassoan  
I see whats going now! Thank you so much for the information.
