chime-experiment / ch_util

CHIME utilities
https://chime-experiment.github.io/ch_util
MIT License
2 stars 3 forks source link

Update tools.py so that get_feed_positions(...) works for Outriggers #31

Open aaronpearlman opened 2 years ago

aaronpearlman commented 2 years ago

For Mattias Lazda (@lazdam):

Code changes are needed in order for ch_util.tools.get_feed_positions(...) to work for pco and the other Outriggers. Here is a proposed plan for the software dev. required to get this to work (other suggested changes/ideas are welcome):

# Determine position
try:
    pos = [0.0] * 3

    for node in [rfl, foc, cas, slt]:
        prop = lay.node_property(node)

        for ind, dim in enumerate(["x_offset", "y_offset", "z_offset"]):

            if dim in prop:
                pos[ind] += float(prop[dim].value)  # in metres

    if "y_offset" not in lay.node_property(slt):
        pos[1] += (float(slt.sn[-1]) - 1.5) * 0.3048

Here, rfl refers to reflector components, foc refers to the focal line slot (place that a cassette is located on the focal line, i.e. FSA_NN), cas is a cassette component, and slt is a cassette slot (place that a feed is located in a cassette). These are all components entered and tracked in layoutdb.

The cassette slots are numbered n = [0, 1, 2, 3]. CHIME has 4 slots, but there are 2 (n = [0, 1]) in the cassettes at pco. At CHIME, the positions of slt relative to the center of the cassette is (n - 1.5) * 0.3048 m. This needs to be defined for pco.

Task list:

Currently, cyl == 6 is defined for pco in _get_input_props(...) (lines 740-745) [private function]. pos = None is set for all the pco feeds currently.

Optional:

kiyo-masui commented 2 years ago

Critical detail: we do not need cassette position measurements at this time. The ‘y_offset’ property of the focal line slots is meant to capture their nominal position, which can be trivially calculated from their number. (Something like (x - 31.5) 2 0.3048.)

Offsets from nominal (which could come from measurements, or just inferred based on the presence of the “2cm gap”) can be captured as a ‘y_offset’ property of the cassetts.

kiyo-masui commented 2 years ago

Also, don’t forget the cylinder rotation. This is non-zero at pco, by design.

lazdam commented 2 years ago

@kiyo-masui Should the y_offset property of the focal line slot be (x - 15.5) * 2 * 0.3048, x \in [0,31] instead of (x - 31.5) * 2 * 0.3048, x \in [0,63] to compensate for the fact that pco has only 32 focal line slots instead of 64 like with CHIME?

kiyo-masui commented 2 years ago

Right. My bad.

lazdam commented 2 years ago

y-offset properties of focal line slots have been added to layoutdb and should now be visible, with values ranging from -9.4488 m to 9.4488 m. Have not yet added the 2 cm offset property to the cassettes that are affected.

mondana commented 2 years ago

How were they measured or estimated?

lazdam commented 2 years ago

@mondana Estimated using the equation I mentioned above, y_offset = (x - 15.5) * 2 * 0.3048 m, for x \in [0,31]. If my understanding of Kiyo's message is correct, we are assuming that the centre-to-centre separation between pco feeds is the same as the CHIME feeds (0.3048 m). However, since there are only two cassette slots per focal line slot at Allenby, we multiply by 2 instead of 4 (as was done for CHIME, which had 4 cassette slots per focal line slot).

lazdam commented 2 years ago

I have just finished bug testing and believe I have something that works as intended. I calculated the positions of the feeds using an almost identical method to that of CHIME:

elif cyl == 6:

      # Dealing with an PCO feed

      # Determine position
      try:
          pos = [0.0] * 3

          for node in [rfl, foc, cas, slt]:
              prop = lay.node_property(node)

              for ind, dim in enumerate(["x_offset", "y_offset", "z_offset"]):

                  if dim in prop:
                      pos[ind] += float(prop[dim].value)  # in metres

          if "y_offset" not in lay.node_property(slt):
              pos[1] += (float(slt.sn[-1]) - 0.5) * 0.3048

      except:

          pos = None

Note that the only difference is in the calculation of the position in the following line:

  if "y_offset" not in lay.node_property(slt):
      pos[1] += (float(slt.sn[-1]) - 0.5) * 0.3048

where we subtract by 0.5 instead of 1.5 since there are only n = [0, 1] cassette slots per focal line slot instead of n = [0,1,2,3] for CHIME.

When I first ran the code, it was failing to fetch the y_offset property that I added to the focal line slots 2 days ago. @kiyo-masui pointed out that I should have set the y_offset property to start at the same time that the cassettes were installed, so this is something that I need to go back and fix. Consequently, when I tested this the other day, I was fetching the properties at a time earlier than when I had set the y_offset property, hence why it was failing to find it.

However, I tried again today and set the datetime to some later time on July 6, 2022 and the code worked as intended. For the 6 antennas that are connected as of the time of writing this (July 06, 2022), here are the results (note the pos property of the PCOAntennas):

PCOAntenna(id=3, delay=0, input_sn='FCA000003', corr='FCA', reflector='pco_cylinder', antenna='ANT0612H', rf_thru='BKR0_A03', cyl=6, pol='S', flag=True, pos=[0.00, -8.69, 0.00])

PCOAntenna(id=21, delay=0, input_sn='FCA000205', corr='FCA', reflector='pco_cylinder', antenna='ANT0600H', rf_thru='BKR0_C05', cyl=6, pol='S', flag=True, pos=[0.00, -3.20, 0.00])

PCOAntenna(id=41, delay=0, input_sn='FCA000409', corr='FCA', reflector='pco_cylinder', antenna='ANT1324H', rf_thru='BKR0_E09', cyl=6, pol='S', flag=True, pos=[0.00, 2.90, 0.00])

PCOAntenna(id=57, delay=0, input_sn='FCA000609', corr='FCA', reflector='pco_cylinder', antenna='ANT1316H', rf_thru='BKR0_G09', cyl=6, pol='S', flag=True, pos=[0.00, 7.77, 0.00])

-----------------

PCOAntenna(id=62, delay=0, input_sn='FCA000614', corr='FCA', reflector='pco_cylinder', antenna='ANT0359H', rf_thru='BKR0_G14', cyl=6, pol='S', flag=True, pos=[0.00, 9.30, 0.00])

PCOAntenna(id=126, delay=0, input_sn='FCA000714', corr='FCA', reflector='pco_cylinder', antenna='ANT0359H', rf_thru='BKR0_H14', cyl=6, pol='E', flag=True, pos=[0.00, 9.30, 0.00])

I've separated the 4 antennas which are later connected to notch filters from the 2 with only attenuators. Note that the y - position of the of the last two antennas are the same which agrees with what we'd expect since they both come from the same feed, just different polarizations.

@mondana To double check that everything agreed with the connections we made the other day, I worked through each of the trees on layoutdb and did not notice any inconsistencies.

Once we add the y-offset property to the cassettes to address the 2cm gap, the code the way it is written now will be able to add it to the y-offset without any additional steps.

If there's anything I missed, let me know and I'll address it before I issue a pull request from my forked repo.

kiyo-masui commented 2 years ago

One more thing - did you include the (intensional) cylinder rotation (Allenby is not NS aligned since it is rotated to match the DRAO FOV)?

Sorry, can’t check the code myself - on a plane and just queuing up emails to send when I land.

On Jul 6, 2022, at 6:19 PM, Mattias Lazda @.***> wrote:



I have just finished bug testing and believe I have something that works as intended. I calculated the positions of the feeds using an almost identical method to that of CHIME:

elif cyl == 6:

  # Dealing with an PCO feed

  # Determine position
  try:
      pos = [0.0] * 3

      for node in [rfl, foc, cas, slt]:
          prop = lay.node_property(node)

          for ind, dim in enumerate(["x_offset", "y_offset", "z_offset"]):

              if dim in prop:
                  pos[ind] += float(prop[dim].value)  # in metres

      if "y_offset" not in lay.node_property(slt):
          pos[1] += (float(slt.sn[-1]) - 0.5) * 0.3048

  except:

      pos = None

Note that the only difference is in the calculation of the position in the following line:

if "y_offset" not in lay.node_property(slt): pos[1] += (float(slt.sn[-1]) - 0.5) * 0.3048

where we subtract by 0.5 instead of 1.5 since there are only n = [0, 1] cassette slots per focal line slot instead of n = [0,1,2,3] for CHIME.

When I first ran the code, it was failing to fetch the y_offset property that I added to the focal line slots 2 days ago. @kiyo-masuihttps://github.com/kiyo-masui pointed out that I should have set the y_offset property to start at the same time that the cassettes were installed, so this is something that I need to go back and fix. Consequently, when I tested this the other day, I was fetching the properties at a time earlier than when I had set the y_offset property, hence why it was failing to find it.

However, I tried again today and set the datetime to some later time on July 6, 2022 and the code worked as intended. For the 6 antennas that are connected as of the time of writing this (July 06, 2022), here are the results (note the pos property of the PCOAntennas):

PCOAntenna(id=3, delay=0, input_sn='FCA000003', corr='FCA', reflector='pco_cylinder', antenna='ANT0612H', rf_thru='BKR0_A03', cyl=6, pol='S', flag=True, pos=[0.00, -8.69, 0.00])

PCOAntenna(id=21, delay=0, input_sn='FCA000205', corr='FCA', reflector='pco_cylinder', antenna='ANT0600H', rf_thru='BKR0_C05', cyl=6, pol='S', flag=True, pos=[0.00, -3.20, 0.00])

PCOAntenna(id=41, delay=0, input_sn='FCA000409', corr='FCA', reflector='pco_cylinder', antenna='ANT1324H', rf_thru='BKR0_E09', cyl=6, pol='S', flag=True, pos=[0.00, 2.90, 0.00])

PCOAntenna(id=57, delay=0, input_sn='FCA000609', corr='FCA', reflector='pco_cylinder', antenna='ANT1316H', rf_thru='BKR0_G09', cyl=6, pol='S', flag=True, pos=[0.00, 7.77, 0.00])


PCOAntenna(id=62, delay=0, input_sn='FCA000614', corr='FCA', reflector='pco_cylinder', antenna='ANT0359H', rf_thru='BKR0_G14', cyl=6, pol='S', flag=True, pos=[0.00, 9.30, 0.00])

PCOAntenna(id=126, delay=0, input_sn='FCA000714', corr='FCA', reflector='pco_cylinder', antenna='ANT0359H', rf_thru='BKR0_H14', cyl=6, pol='E', flag=True, pos=[0.00, 9.30, 0.00])

I've separated the 4 antennas which are later connected to notch filters from the 2 with only attenuators. Note that the y - position of the of the last two antennas are the same which agrees with what we'd expect since they both come from the same feed, just different polarizations.

@mondanahttps://github.com/mondana To double check that everything agreed with the connections we made the other day, I worked through each of the trees on layoutdb and did not notice any inconsistencies.

Once we add the y-offset property to the cassettes to address the 2cm gap, the code the way it is written now will be able to add it to the y-offset without any additional steps.

If there's anything I missed, let me know and I'll address it before I issue a pull request from my forked repo.

— Reply to this email directly, view it on GitHubhttps://github.com/chime-experiment/ch_util/issues/31#issuecomment-1176806451, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AADBPH5LJPJJN2P46CZZ3FDVSYA4XANCNFSM52DSNR6Q. You are receiving this because you were mentioned.Message ID: @.***>

lazdam commented 2 years ago

@kiyo-masui I may be misunderstanding the code, but I think this is already implemented for all the telescopes under the ArrayAntenna class / position property that all subsequent classes inherit from (e.g. CHIMEAntenna, PathfinderAntenna, PCOAntenna etc.):

https://github.com/chime-experiment/ch_util/blob/master/ch_util/tools.py#:~:text=%40property-,def%20pos(self)%3A,-if%20hasattr(

@property
    def pos(self):
        if hasattr(self, "_pos"):

            pos = self._pos

            if self._rotation:

                t = np.radians(self._rotation)
                c, s = np.cos(t), np.sin(t)

                pos = [c * pos[0] - s * pos[1], s * pos[0] + c * pos[1], pos[2]]

            if any(self._offset):

                pos = [pos[dim] + off for dim, off in enumerate(self._offset)]

            return pos

        else:
            return None

To be more specific, PCOAntenna is defined as:

class PCOAntenna(ArrayAntenna):
    """PCO outrigger antenna for the CHIME/FRB project."""

    _rotation = 0.00 # <--- This needs to be updated
    _offset = [0.00, 0.00, 0.00]
    _delay = 0 

which inherits from ArrayAntenna which has the position property defined at the top. When we calculate the feed positions and return a PCOAntenna object at the end of the calculation, I think it also updates the positions to take into account the rotation. I'm not 100% sure though, because we never define _pos for PCOAntenna, only pos, so I don't know if the if hasattr(self, "_pos") statement will pass.

lazdam commented 2 years ago

Unless your question was just did I change _rotation from 0.00 to its actual rotation, then my answer would be "not yet".

lazdam commented 2 years ago

Update: I ran the code and set an arbitrary rotation angle for the test. It does indeed automatically update the positions of the antennas using the calculation above. All I think that is left is to determine the actual rotation of the telescope and define _PCO_ROT.

kiyo-masui commented 2 years ago

Tom knows the number.

Kiyoshi Masui Assistant Professor - MIT Physics/MIT Kavli Institute office: (617) 452-4647 - mobile: (857) 207-6121 MIT McNair building 37, room 664d @.**@.> pronouns: he/him

On Jul 14, 2022, at 1:27 PM, Mattias Lazda @.**@.>> wrote:

Update: I ran the code and set an arbitrary rotation angle for the test. It does indeed automatically update the positions of the antennas using the calculation above. All I think that is left is to determine the actual rotation of the telescope and define _PCO_ROT.

— Reply to this email directly, view it on GitHubhttps://github.com/chime-experiment/ch_util/issues/31#issuecomment-1184646556, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AADBPH2YUZ7BE5OAGWHYMFDVUA5XNANCNFSM52DSNR6Q. You are receiving this because you were mentioned.Message ID: @.***>

jkaczmarek commented 2 years ago

cylinder & focal line is rotated -0.67 deg from astronomical north (which is to say it is rotated slightly west). This is given in doclib #1530 also, the entire cylinder is rolled (~0.5deg. don't quote me. i will find the exact number) but this shouldn't change your measurements of the focal line