@@ -391,11 +391,11 @@ def _get_empty_data_array(
391391 self ,
392392 grid_shape : tuple [int , int ],
393393 beam_type : Literal [
394- "efield" , "power" , "feed_iresponse " , "feed_projection "
394+ "efield" , "power" , "feed_aligned_response " , "feed_aligned_projection "
395395 ] = "efield" ,
396396 ) -> FloatArray :
397397 """Get the empty data to fill in the eval methods."""
398- if beam_type in ["efield" , "feed_projection " ]:
398+ if beam_type in ["efield" , "feed_aligned_projection " ]:
399399 return np .zeros (
400400 (self .Naxes_vec , self .Nfeeds , * grid_shape ), dtype = np .complex128
401401 )
@@ -404,7 +404,7 @@ def _get_empty_data_array(
404404 (1 , self .Npols , * grid_shape ),
405405 dtype = np .complex128 if self .Npols > self .Nfeeds else np .float64 ,
406406 )
407- elif beam_type == "feed_iresponse " :
407+ elif beam_type == "feed_aligned_response " :
408408 return np .zeros ((1 , self .Nfeeds , * grid_shape ), dtype = np .complex128 )
409409
410410 def efield_eval (
@@ -516,11 +516,23 @@ def power_eval(
516516
517517 return data_array
518518
519- def feed_iresponse_eval (
519+ def feed_aligned_response_eval (
520520 self , * , az_array : FloatArray , za_array : FloatArray , freq_array : FloatArray
521521 ) -> FloatArray :
522522 """
523- Evaluate the feed I response at the given coordinates.
523+ Evaluate the feed aligned response at the given coordinates.
524+
525+ The feed aligned response is the complex response of each instrumental
526+ feed to electric fields aligned with it -- i.e. after projecting electric
527+ fields to directions aligned with the feeds (these directions are
528+ non-orthogonal in many directions on the sky even though the feeds are
529+ generally physically orthogonal). Since the projection has already happened,
530+ the feed aligned response only has a feed index, no vector component axis.
531+ Non-zero phase is caused by time delays which can vary spatially but do
532+ not depend on incident polarization.
533+
534+ Unpolarized light is equally spread among all polarization orientations,
535+ so the feed aligned response can be used as the response to unpolarized light.
524536
525537 Parameters
526538 ----------
@@ -544,11 +556,11 @@ def feed_iresponse_eval(
544556 az_array = az_array , za_array = za_array , freq_array = freq_array
545557 )
546558
547- if hasattr (self , "_feed_iresponse_eval " ):
559+ if hasattr (self , "_feed_aligned_response_eval " ):
548560 za_grid , _ = np .meshgrid (za_array , freq_array )
549561 az_grid , f_grid = np .meshgrid (az_array , freq_array )
550562
551- return self ._feed_iresponse_eval (
563+ return self ._feed_aligned_response_eval (
552564 az_grid = az_grid , za_grid = za_grid , f_grid = f_grid
553565 ).astype (complex )
554566 else :
@@ -574,11 +586,18 @@ def feed_iresponse_eval(
574586
575587 return data_array .astype (complex )
576588
577- def feed_projection_eval (
589+ def feed_aligned_projection_eval (
578590 self , * , az_array : FloatArray , za_array : FloatArray , freq_array : FloatArray
579591 ) -> FloatArray :
580592 """
581- Evaluate the feed projection at the given coordinates.
593+ Evaluate the feed aligned projection at the given coordinates.
594+
595+ The feed aligned projection is the projection from celestial polarization
596+ vector components (orthogonal on the sky) to instrumental feed vector
597+ components (often non-orthogonal on the sky). This is similar to a
598+ rotation matrix in that it just converts between coordinate systems
599+ (the magnitude of the response is removed), but is not unitary because
600+ the projection of the feeds are not orthogonal in all directions on the sky.
582601
583602 Parameters
584603 ----------
@@ -605,8 +624,8 @@ def feed_projection_eval(
605624 za_grid , _ = np .meshgrid (za_array , freq_array )
606625 az_grid , f_grid = np .meshgrid (az_array , freq_array )
607626
608- if hasattr (self , "_feed_projection_eval " ):
609- return self ._feed_projection_eval (
627+ if hasattr (self , "_feed_aligned_projection_eval " ):
628+ return self ._feed_aligned_projection_eval (
610629 az_grid = az_grid , za_grid = za_grid , f_grid = f_grid
611630 ).astype (complex )
612631 else :
@@ -615,7 +634,7 @@ def feed_projection_eval(
615634 )
616635
617636 # set f to the magnitude of the I response, assume no time delays
618- f_vals = self .feed_iresponse_eval (
637+ f_vals = self .feed_aligned_response_eval (
619638 az_array = az_array , za_array = za_array , freq_array = freq_array
620639 )
621640 data_array = self ._get_empty_data_array (az_grid .shape )
@@ -631,7 +650,7 @@ def to_uvbeam(
631650 self ,
632651 freq_array : FloatArray ,
633652 beam_type : Literal [
634- "efield" , "power" , "feed_iresponse " , "feed_projection "
653+ "efield" , "power" , "feed_aligned_response " , "feed_aligned_projection "
635654 ] = "efield" ,
636655 pixel_coordinate_system : (
637656 Literal ["az_za" , "orthoslant_zenith" , "healpix" ] | None
@@ -653,7 +672,8 @@ def to_uvbeam(
653672 freq_array : ndarray of float
654673 Array of frequencies in Hz to evaluate the beam at.
655674 beam_type : str
656- Beam type, one of "efield", "power", "feed_iresponse" or "feed_projection".
675+ Beam type, one of "efield", "power", "feed_aligned_response" or
676+ "feed_aligned_projection".
657677 pixel_coordinate_system : str
658678 Pixel coordinate system, options are "az_za", "orthoslant_zenith" and
659679 "healpix". Forced to be "healpix" if ``nside`` is given and by
@@ -676,7 +696,12 @@ def to_uvbeam(
676696 Healpix ordering parameter, defaults to "ring" if nside is provided.
677697
678698 """
679- allowed_beam_types = ["efield" , "power" , "feed_iresponse" , "feed_projection" ]
699+ allowed_beam_types = [
700+ "efield" ,
701+ "power" ,
702+ "feed_aligned_response" ,
703+ "feed_aligned_projection" ,
704+ ]
680705 if beam_type not in allowed_beam_types :
681706 raise ValueError (f"Beam type must be one of { allowed_beam_types } " )
682707
@@ -761,7 +786,7 @@ def plot(
761786 self ,
762787 * ,
763788 beam_type : Literal [
764- "efield" , "power" , "feed_iresponse " , "feed_projection "
789+ "efield" , "power" , "feed_aligned_response " , "feed_aligned_projection "
765790 ] = "efield" ,
766791 freq : float ,
767792 complex_type : str = "real" ,
@@ -782,7 +807,8 @@ def plot(
782807 Parameters
783808 ----------
784809 beam_type : str
785- Beam type, one of "efield", "power", "feed_iresponse" or "feed_projection".
810+ Beam type, one of "efield", "power", "feed_aligned_response" or
811+ "feed_aligned_projection".
786812 freq : int
787813 The frequency index to plot.
788814 complex_type : str
0 commit comments