# Screws spacial organize

**URL:** <https://discourse.slicer.org/t/screws-spacial-organize/24573>\
**Category:** Support\
**Created:** [July 30, 2022, 8:39am UTC](https://discourse.slicer.org/t/screws-spacial-organize/24573 "2022-07-30T08:39:37Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![apparrilla](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/apparrilla/32/9230_2.png) [@apparrilla](https://discourse.slicer.org/u/apparrilla)\
**Post date:** [July 30, 2022, 8:39am UTC](https://discourse.slicer.org/t/screws-spacial-organize/24573/1 "2022-07-30T08:39:37Z")

</div>

Hi everyone,  
I´ve segmented the screws of an intraoperative CBCT of one of my spinal surgeries.  
This is the result:

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

I´ve used Segment Statistics to get each segment center and I want to iterate all of them.

My problem is that they are messed up in space. Is there any way to organize them in colums and rows to iterate them in logical order from upper left to botton right?

Thanks in advance!

---

<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:** [July 30, 2022, 2:23pm UTC](https://discourse.slicer.org/t/screws-spacial-organize/24573/2 "2022-07-30T14:23:14Z")

</div>

Maybe you can give them names related to the level in the spine and then sort them in the resulting statistics table.

---

<div class="post-metadata">

**Author:** ![apparrilla](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/apparrilla/32/9230_2.png) [@apparrilla](https://discourse.slicer.org/u/apparrilla)\
**Post date:** [July 30, 2022, 3:16pm UTC](https://discourse.slicer.org/t/screws-spacial-organize/24573/3 "2022-07-30T15:16:05Z")

</div>

Hi Steve,  
This is the main problem. I get all screws in a single segment and then I split it with Islands tool. They have no order at all and I want to rename them in an automated way by position in the space.  
Thanks for your help!

---

<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:** [July 30, 2022, 3:39pm UTC](https://discourse.slicer.org/t/screws-spacial-organize/24573/4 "2022-07-30T15:39:12Z")

</div>

Glad to help, but unfortunately I don’t think there’s any existing/reliable way to do this automatically. It would be possible to come up with a heuristic that would usually give you a reasonable answer but may not be correct if there is a lot of variability in the input. In the Segment Statistics advanced options you can enable calculation of centroids (in patient RAS space). You could break those into R, A, and S and probably sorting by R and S would be what you want.

---

<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:** [July 31, 2022, 8:37am UTC](https://discourse.slicer.org/t/screws-spacial-organize/24573/5 "2022-07-31T08:37:46Z")

</div>

@apparrilla what is your end goal? Would you like to simulate insertion (choose a screw and position/orient in a CT image)?

---

<div class="post-metadata">

**Author:** ![apparrilla](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/apparrilla/32/9230_2.png) [@apparrilla](https://discourse.slicer.org/u/apparrilla)\
**Post date:** [July 31, 2022, 11:33pm UTC](https://discourse.slicer.org/t/screws-spacial-organize/24573/6 "2022-07-31T23:33:25Z")

</div>

@lassoan , This is just what I want to do.

I have some peace of code that is working for me. Maybe usefull for anyone else:

```auto
def orderScrews (self, segmentationNode):
    import SegmentStatistics
    segStatLogic = SegmentStatistics.SegmentStatisticsLogic()
    segStatLogic.getParameterNode().SetParameter("Segmentation", segmentationNode.GetID())
    segStatLogic.getParameterNode().SetParameter("LabelmapSegmentStatisticsPlugin.centroid_ras.enabled", str(True))
    segStatLogic.computeStatistics()
    stats = segStatLogic.getStatistics()

    pointListNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLMarkupsFiducialNode","ScrewPoints")
    pointListNode.CreateDefaultDisplayNodes()
    for segmentId in stats["SegmentIDs"]:
      centroid_ras = stats[segmentId,"LabelmapSegmentStatisticsPlugin.centroid_ras"]
      segmentName = segmentationNode.GetSegmentation().GetSegment(segmentId).GetName()
      pointListNode.AddFiducialFromArray(centroid_ras, segmentName)

    nOfControlPoints = pointListNode.GetNumberOfControlPoints()
    points = np.zeros([nOfControlPoints,2])
    for i in range(0, nOfControlPoints):
      point = np.zeros(3)
      pointListNode.GetNthControlPointPosition(i, point)
      points[i,:] = (point[0],point[2])
    print("points: %s"%points)

    numberScrew = 1
    pointsMini = points
    while pointsMini.size > 2:
      s = pointsMini.sum(axis=1)
      diff = np.diff(pointsMini, axis=1)
      first = pointsMini[np.argmax(diff)]
      print("first: %s" % first)
      first_index = np.where(points == first)
      first_mini_index = np.where(pointsMini == first)
      segmentationNode.GetSegmentation().GetNthSegment(int(first_index[0][0])).SetName("Screw_%s"% numberScrew)
      numberScrew += 1
      second = pointsMini[np.argmax(s)]
      print("second: %s" % second)
      second_index = np.where(points == second)
      second_mini_index = np.where(pointsMini == second)
      segmentationNode.GetSegmentation().GetNthSegment(int(second_index[0][0])).SetName("Screw_%s"% numberScrew)
      numberScrew += 1
      pointsMini = np.delete(pointsMini, [first_mini_index[0][0],second_mini_index[0][0]], axis=0)
      print ("pointsMini: %s" % pointsMini)    
    print("pointsMini.size: %s" % pointsMini.size)
    if pointsMini.size ==2:
      print("pointsMini[0]: %s" %pointsMini[0])
      last_index = np.where(points == pointsMini[0])
      print("last_index: %s"%last_index[0][0])
      segmentationNode.GetSegmentation().GetNthSegment(int(last_index[0][0])).SetName("Screw_%s"% numberScrew)

```

---

<div class="post-metadata">

**Author:** ![apparrilla](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/apparrilla/32/9230_2.png) [@apparrilla](https://discourse.slicer.org/u/apparrilla)\
**Post date:** [August 1, 2022, 5:46am UTC](https://discourse.slicer.org/t/screws-spacial-organize/24573/7 "2022-08-01T05:46:01Z")

</div>

My end goal is to speed up the intraoperative screw reviewing after control CBCT.

---

<div class="post-metadata">

**Author:** ![apparrilla](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/apparrilla/32/9230_2.png) [@apparrilla](https://discourse.slicer.org/u/apparrilla)\
**Post date:** [August 1, 2022, 8:09am UTC](https://discourse.slicer.org/t/screws-spacial-organize/24573/8 "2022-08-01T08:09:51Z")

</div>

@lassoan .  
I´ve found a problem with my code if “second” i the same point as “first” because I loose a screw.  
I´ve tryied to fix it with:

```auto
second = pointsMini[np.argmax(s)]
if np.array_equal(first, second): continue

```

Slicer crash with this with no error in Python Interactor. I just have to close Slicer because it´s continuosly processing something (while loop… of couse).  
I´ve also tried: (first==second).all() and np…array\_equiv(first, second) but all of them block Slicer app.

Do you know what i´m doing worng?  
Thanks in advance.
