@@ -648,6 +648,110 @@ def to_phase(self, to_phase, from_phase, Phi=None):
648648
649649 return self * Phi (to_phase ) / Phi (from_phase )
650650
651+ @sbd .dataclass_input (eph = sbd .Ephem )
652+ @sbd .quantity_to_dataclass (eph = (sbd .Ephem , "delta" ))
653+ def to_cross_section (self , Ap , aper , eph ):
654+ """Convert from Afρ to dust geometric cross-sectional area.
655+
656+
657+ Parameters
658+ ----------
659+ Ap : float
660+ Grain geometric albedo. Note that A in the Afρ quantity is ``4 *
661+ Ap`` (A'Hearn et al. 1984).
662+
663+ aper : `~astropy.units.Quantity` or `~sbpy.activity.Aperture`
664+ Aperture of the observation as a circular radius (length
665+ or angular units), or as an `~sbpy.activity.Aperture`.
666+
667+ eph: `~astropy.units.Quantity`, dictionary-like, `~sbpy.data.Ephem`
668+ Observer-comet distance, or ephemeris data object with "delta"
669+ defined.
670+
671+
672+ Returns
673+ -------
674+ G : `~astropy.units.Quantity`
675+
676+
677+ Examples
678+ --------
679+ >>> afrho = Afrho(1000 * u.cm)
680+ >>> eph = {"rh": 1 * u.au, "delta": 1 * u.au, "phase": 60 * u.deg}
681+ >>> aper = 1 * u.arcsec
682+ >>> afrho.to_cross_section(0.05, aper, eph)
683+
684+ To account for phase angle, first use ``to_phase``:
685+ >>> afrho.to_phase(0 * u.deg, eph["phase"]).to_cross_section(0.1, aper, eph)
686+
687+ """
688+
689+ # G = pi (rh delta)**2 F_comet / (Ap F_sun)
690+ # Ap = A / 4
691+ # G = pi 4 * (rh delta)**2 F_comet / (A F_sun)
692+ # G A / pi = 4 * (rh delta)**2 F_comet / F_sun
693+ #
694+ # Afrho = 4 (rh delta)**2 F_comet / (rho F_sun)
695+ # Afrho rho = 4 * (rh delta)**2 F_comet / F_sun = G A / pi
696+ #
697+ # G = Afrho rho pi / A
698+ # G = Afrho rho pi / (4 Ap)
699+
700+ # rho = effective circular aperture radius at the distance of
701+ # the comet. Keep track of array dimensionality as Ephem
702+ # objects can needlessly increase the number of dimensions.
703+ if isinstance (aper , Aperture ):
704+ rho = aper .coma_equivalent_radius ()
705+ ndim = np .ndim (rho )
706+ else :
707+ rho = aper
708+ ndim = np .ndim (rho )
709+ rho = rho .to ("km" , sbu .projected_size (eph ))
710+
711+ G = (self * rho * np .pi / (4 * Ap )).to ("km2" )
712+ return G
713+
714+ @classmethod
715+ @sbd .dataclass_input (eph = sbd .Ephem )
716+ @sbd .quantity_to_dataclass (eph = (sbd .Ephem , "delta" ))
717+ def from_cross_section (cls , G , Ap , aper , eph ):
718+ """Initialize from dust geometric cross-sectional area.
719+
720+
721+ Parameters
722+ ----------
723+ G : `~astropy.units.Quantity`
724+ Dust geometric cross-sectional area.
725+
726+ Ap : float
727+ Grain geometric albedo. Note that A in the Afρ quantity is ``4 *
728+ Ap`` (A'Hearn et al. 1984).
729+
730+ aper : `~astropy.units.Quantity` or `~sbpy.activity.Aperture`
731+ Aperture of the observation as a circular radius (length or angular
732+ units), or as an `~sbpy.activity.Aperture`.
733+
734+ eph: `~astropy.units.Quantity`, dictionary-like, `~sbpy.data.Ephem`
735+ Observer-comet distance, or ephemeris data object with "delta"
736+ defined.
737+
738+
739+ Returns
740+ -------
741+ G : `~astropy.units.Quantity`
742+
743+
744+ Examples
745+ --------
746+ >>> eph = {"rh": 1 * u.au, "delta": 1 * u.au}
747+ >>> aper = 1 * u.arcsec
748+ >>> Afrho.from_cross_section(1 * u.km**2, 0.05, aper, eph)
749+
750+ """
751+
752+ G1 = cls (1 * u .cm ).to_cross_section (Ap , aper , eph )
753+ return cls ((G / G1 ).to ("" ) * u .cm )
754+
651755
652756class Efrho (DustComaQuantity ):
653757 """Coma dust quantity for thermal emission.
@@ -662,7 +766,7 @@ class Efrho(DustComaQuantity):
662766 The value(s).
663767
664768 unit : str, `~astropy.units.Unit`, optional
665- The unit of the input value. Strings must be parseable by
769+ The unit of the input value. Strings must be parsable by
666770 :mod:`~astropy.units` package.
667771
668772 dtype : `~numpy.dtype`, optional
@@ -780,3 +884,102 @@ def _source_fluxd(self, wfb, eph, unit=None, Tscale=1.1, T=None, B=None):
780884 )
781885
782886 return B
887+
888+ @sbd .dataclass_input (eph = sbd .Ephem )
889+ @sbd .quantity_to_dataclass (eph = (sbd .Ephem , "delta" ))
890+ def to_cross_section (self , epsilon , aper , eph ):
891+ """Convert from εfρ to dust geometric cross-sectional area.
892+
893+
894+ Parameters
895+ ----------
896+ epsilon : float
897+ Grain emissivity.
898+
899+ aper : `~astropy.units.Quantity` or `~sbpy.activity.Aperture`
900+ Aperture of the observation as a circular radius (length
901+ or angular units), or as an `~sbpy.activity.Aperture`.
902+
903+ eph: `~astropy.units.Quantity`, dictionary-like, `~sbpy.data.Ephem`
904+ Observer-comet distance, or ephemeris data object with "delta"
905+ defined.
906+
907+
908+ Returns
909+ -------
910+ G : `~astropy.units.Quantity`
911+
912+
913+ Examples
914+ --------
915+ >>> efrho = Efrho(1000 * u.cm)
916+ >>> eph = {"rh": 1 * u.au, "delta": 1 * u.au}
917+ >>> aper = 1 * u.arcsec
918+ >>> efrho.to_cross_section(0.95, aper, eph)
919+
920+ """
921+
922+ # F_comet = G epsilon pi B(T) / delta**2
923+ # G = F_comet delta**2 / (epsilon pi B(T))
924+ # G epsilon = F_comet delta**2 / (pi B(T))
925+ #
926+ # efrho = F_comet rho / (pi rho_angular**2 B(T))
927+ # = F_comet rho / (pi (rho**2 / delta**2) B(T))
928+ # = F_comet delta**2 / (pi rho B(T))
929+ # efrho rho = F_comet delta**2 / (pi B(T)) = G epsilon
930+ #
931+ # G = efrho rho / epsilon
932+
933+ # rho = effective circular aperture radius at the distance of
934+ # the comet. Keep track of array dimensionality as Ephem
935+ # objects can needlessly increase the number of dimensions.
936+ if isinstance (aper , Aperture ):
937+ rho = aper .coma_equivalent_radius ()
938+ ndim = np .ndim (rho )
939+ else :
940+ rho = aper
941+ ndim = np .ndim (rho )
942+ rho = rho .to ("km" , sbu .projected_size (eph ))
943+
944+ G = (self * rho / epsilon ).to ("km2" )
945+ return G
946+
947+ @classmethod
948+ @sbd .dataclass_input (eph = sbd .Ephem )
949+ @sbd .quantity_to_dataclass (eph = (sbd .Ephem , "delta" ))
950+ def from_cross_section (cls , G , epsilon , aper , eph ):
951+ """Initialize from dust geometric cross-sectional area.
952+
953+
954+ Parameters
955+ ----------
956+ G : `~astropy.units.Quantity`
957+ Dust geometric cross-sectional area.
958+
959+ epsilon : float
960+ Grain emissivity.
961+
962+ aper : `~astropy.units.Quantity` or `~sbpy.activity.Aperture`
963+ Aperture of the observation as a circular radius (length
964+ or angular units), or as an `~sbpy.activity.Aperture`.
965+
966+ eph: `~astropy.units.Quantity`, dictionary-like, `~sbpy.data.Ephem`
967+ Observer-comet distance, or ephemeris data object with "delta"
968+ defined.
969+
970+
971+ Returns
972+ -------
973+ G : `~astropy.units.Quantity`
974+
975+
976+ Examples
977+ --------
978+ >>> eph = {"rh": 1 * u.au, "delta": 1 * u.au}
979+ >>> aper = 1 * u.arcsec
980+ >>> Efrho.from_cross_section(1 * u.km**2, 0.95, aper, eph)
981+
982+ """
983+
984+ G1 = Efrho (1 * u .cm ).to_cross_section (epsilon , aper , eph )
985+ return Efrho ((G / G1 ).to ("" ) * u .cm )
0 commit comments