.center() vs .get_2d_center_offsets()

Hi everyone,

Is there a small bug in regards to resource position calculations?

plt_carrier_1[0] = plate_0 = Cos_96_Rd(name = 'test_plate_1')

# Checking automated calculations
plate_0.get_2d_center_offsets()
# >>> [Coordinate(x=63.5, y=43.0, z=0)]

plate_0.center()
# >>> Coordinate(x=63.5, y=43.0, z=0)

.get_2d_center_offsets() returns a list containing a Coordinate and .center() only returns the Coordinate - that is as I’d expect it.

But .center() should calculate the center of the resource/plate in all dimensions, including z, but it doesn’t.
This means these two method return the same Coordinate even though one explicitly states it is only concerned about the “2d_center” (.get_2d_center_offsets()), leading to the assumption that the other is concerned about the “3d_center” (.center())?

Is this by design or a bug?

i agree that this is named in a confusing way, but this is working as intended. How should we improve naming? Perhaps center(x=True, y=False, z=True) with all True by default?

I am not sure what you mean by this?

My question is, why does .center() return the same as .get_2D_center_offsets(), just not in a list, i.e. what is the added value?

If center is not actually returning the complete center of a resource then I think we’d need a true .get_3D_center().

A method center(x: bool, y: bool, z: bool) could return a Coordinate with centers along the dimensions that are marked True. The current behavior of getting a 2d center on the xy plane would then be center(x=True, y=True, z=False).

get_2D_center_offsets takes a parameter n to get items spaced along the y axis.

We could even make it center(x: int, y: int, z: int) to take integers, and equally space n points along those dimensions. (all >0). This single method would be very powerful.

Ohhh I see:

.center() → currently gets the 2D_center of the resource but
.get_2D_center_offsets() → actually gets n number of offsets from the 2D_center, hence it returns a list - and I assume by default n=1 which is why it “only” returns the same as the current .center(), in a list, while actually there is a lot more going on below the surface!

I really like both of your suggestions of how to amend center!

What about combining both of your suggestions into one OP Resource method?:

central_location_list = Resource.center(
    dims=(x: bool = True, y: bool = True, z: bool = True),
    n_points=(x: int = 1, y: int = 1, z: int = 1),
)
# ==> creates a list of Coordinates, in this case a list of a single coordinate, the single center point.

If a dims/dimension is False then its corresponding n_points will be ignored and that dimension will be represented as 0 in the returning [Coordinate]?

1 Like

this could be simplified by just taking an int right? 0 is equivalent to False

haha

Yes, you are of course absolutely right! That is much simpler and does the same.

done update resource.center(s) · PyLabRobot/pylabrobot@9321bcc · GitHub

1 Like

Awesome, thank you very much, Rick!

To summarise, from your commit Docstring:

Examples:
      Get the center of a resource:
      >>> r = Resource("resource", size_x=12, size_y=12, size_z=12)
      >>> r.center()
      Coordinate(x=6.0, y=6.0, z=6.0)
      
     # Get the center of a resource with 2 points in the x direction:
      >>> r = Resource("resource", size_x=12, size_y=12, size_z=12)
      >>> r.center(xn=2)
      [Coordinate(x=4.0, y=6.0, z=6.0), Coordinate(x=9.0, y=6.0, z=6.0)]

      # Get the center of a resource with 2 points in the x and y directions:
      >>> r = Resource("resource", size_x=12, size_y=12, size_z=12)
      >>> r.center(xn=2, yn=2)
      [Coordinate(x=4.0, y=4.0, z=6.0), Coordinate(x=8.0, y=4.0, z=6.0),
       Coordinate(x=4.0, y=8.0, z=6.0), Coordinate(x=8.0, y=8.0, z=6.0)]

You created two Resource class methods:

  1. .center() → calculates the mid-center point of a resource across all dimensions?
  2. .centers() → calculates a list of central points, evenly spaced based on the number of points asked for in each dimension?

I am seeing some slightly different behaviour in my script that I cannot explain:

plt_carrier_1[0] = test_plate_0 = Cos_96_Rd(name = 'test_plate_0')

test_plate_0
# returns: Plate(name=test_plate_0, size_x=127.0, size_y=86.0, size_z=14.5, location=(000.000, 000.000, 000.000))

test_plate_0.center()
# returns: Coordinate(x=63.5, y=43.0, z=0)

test_plate_0.centers()
# returns: [Coordinate(x=63.5, y=43.0, z=7.25)]

.center() does not calculate the central location of the resource in the z-dimension.
This is reflected in its default arguments.

Should the Docstring be changed?

fixed with add docstring for center · PyLabRobot/pylabrobot@eaa748f · GitHub

centers docstring still said center, which was wrong. resource.centers() will include the z. For center() singular, perhaps it’s should but I also like current behavior. This is not super consistent, so perhaps good to set zn=0 by default?

Also added a docstring for center singular that’s hopefully correct.

1 Like