Source code for pleiades.sammy.alphanumerics.angular_distribution

from typing import List

from pydantic import BaseModel, ConfigDict, Field, model_validator

"""
    These notes are taken from the SAMMY manual.
    -   * denotes a default options
    -   Mutually exclusive options are grouped together starting with ------ and ending with ------
    -   options can be written out multiple ways indicated with ["Default","Alternate 1","Alternate 2"]

    Angular distribution options = [
    ----------------------------
        "USE LABORATORY CROSS sections",
        "USE CENTER-OF-MASS Cross sections", *
    ----------------------------
        "PREPARE LEGENDRE COEfficients in endf format",
        "OMIT FINITE SIZE CORrections",
        "INCIDENT NEUTRON ATTenuation is included",
        "APPROXIMATE SCATTEREd neutron attenuation",
        "ANGLE-AVERAGE FOR DIfferential cross section",
    ----------------------------
    ]
"""


[docs] class AngularDistributionOptions(BaseModel): model_config = ConfigDict(validate_default=True) # Reference frame options (mutually exclusive) use_laboratory_cross_sections: bool = Field( default=False, description="For angle-differential data, output cross sections in laboratory frame", ) use_center_of_mass_cross_sections: bool = Field( default=True, description="For angle-differential data, output cross sections in center-of-mass frame (Default)", ) # Additional angular distribution options prepare_legendre_coefficients_in_endf_format: bool = Field( default=False, description="Generate SAMMY.N04 with ENDF File-4 Legendre coefficients for elastic angular distributions", ) omit_finite_size_corrections: bool = Field( default=False, description="Do not include finite size corrections for angular distributions", ) incident_neutron_attenuation_is_included: bool = Field( default=False, description="Include incident neutron attenuation for angular distributions", ) approximate_scattered_neutron_attenuation: bool = Field( default=False, description="Include approximate scattered neutron attenuation for angular distributions", ) angle_average_for_differential_cross_section: bool = Field( default=False, description="Perform angle averaging for differential cross sections using quadratic interpolation", ) # Define mutually exclusive groups as a class attribute mutually_exclusive_groups: List[List[str]] = [ [ "use_laboratory_cross_sections", "use_center_of_mass_cross_sections", ], ]
[docs] @model_validator(mode="after") def enforce_exclusivity(self) -> "AngularDistributionOptions": """Validate mutually exclusive fields and ensure exactly one frame option is selected.""" # Check reference frame options (mutually exclusive and exactly one must be True) if self.use_laboratory_cross_sections == self.use_center_of_mass_cross_sections: raise ValueError( "Exactly one of USE LABORATORY CROSS SECTIONS or USE CENTER-OF-MASS CROSS SECTIONS must be enabled" ) return self
[docs] def get_alphanumeric_commands(self) -> List[str]: """Return the list of alphanumeric commands based on the selected options.""" commands = [] if self.use_laboratory_cross_sections: commands.append("USE LABORATORY CROSS SECTIONS") if self.use_center_of_mass_cross_sections: commands.append("USE CENTER-OF-MASS CROSS SECTIONS") if self.prepare_legendre_coefficients_in_endf_format: commands.append("PREPARE LEGENDRE COEFFICIENTS IN ENDF FORMAT") if self.omit_finite_size_corrections: commands.append("OMIT FINITE SIZE CORRECTIONS") if self.incident_neutron_attenuation_is_included: commands.append("INCIDENT NEUTRON ATTENUATION IS INCLUDED") if self.approximate_scattered_neutron_attenuation: commands.append("APPROXIMATE SCATTERED NEUTRON ATTENUATION") if self.angle_average_for_differential_cross_section: commands.append("ANGLE-AVERAGE FOR DIFFERENTIAL CROSS SECTION") return commands
# Example usage if __name__ == "__main__": try: # Example valid configuration - default options = AngularDistributionOptions() print("Default configuration:") print(options.get_alphanumeric_commands()) # Example valid configuration - custom options = AngularDistributionOptions( use_laboratory_cross_sections=True, use_center_of_mass_cross_sections=False, prepare_legendre_coefficients_in_endf_format=True, omit_finite_size_corrections=True, ) print("Custom configuration:") print(options.get_alphanumeric_commands()) # Example with mutually exclusive error options = AngularDistributionOptions( use_laboratory_cross_sections=True, use_center_of_mass_cross_sections=True, # This should fail ) except ValueError as e: print(f"Validation error: {e}")