Advertisement
Python253

metal_albedo_analysis_tool_plus

Jun 7th, 2024 (edited)
519
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 14.40 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # Filename: metal_albedo_analysis_tool_plus.py
  4. # Version: 1.0.1
  5. # Author: Jeoi Reqi
  6.  
  7. """
  8. Description:
  9.    - This script provides a comprehensive suite of tools for analyzing the optical properties of metals and common materials, focusing on albedo and index of refraction (IOR).
  10.    - Albedo refers to the proportion of incident light that is reflected by a surface, making it a crucial factor in determining the visual appearance of metals and materials.
  11.    - Index of refraction (IOR) quantifies how light bends as it passes through a material, influencing its optical properties such as reflection and refraction.
  12.    - By leveraging the provided functionalities, users can explore and understand the albedo characteristics of various metals and common materials.
  13.    - Users can also compare the metal IOR values to gain insights into their optical behaviors.
  14.    - This script also outputs the difference in value of the compared metal IOR to the terminal.
  15.  
  16. Requirements:
  17.    - Python 3.x
  18.    - Numpy module for numerical computations & array manipulation
  19.    - Matplotlib library for data visualization
  20.  
  21. Functions:
  22.    - visualize_metal_colors():
  23.        Visualizes metal colors by plotting their albedo.
  24.    - display_metal_data():
  25.        Displays the available metal data as a numbered list.
  26.    - calculate_albedo():
  27.        Calculates the albedo of a specific metal selected by the user.
  28.    - compare_ior(metal1, metal2):
  29.        Compares the index of refraction between two metals selected by the user.
  30.    - visualize_common_materials_albedo():
  31.        Visualizes the albedo of common materials.
  32.    - visualize_metal_ior():
  33.        Visualizes the index of refraction (IOR) of metals by plotting their values.
  34.    - search_metal_by_ior():
  35.        Allows the user to search for metals based on a specified range of index of refraction (IOR) values.
  36.    - visualize_common_materials_ior():
  37.        Visualizes the index of refraction (IOR) of common materials.
  38.  
  39. Usage:
  40.    - Run the script in a Python environment.
  41.    - Follow the on-screen menu options to choose between different functionalities.
  42.    - Enter the appropriate input as prompted to perform desired actions.
  43.  
  44. Example Output:
  45.  
  46.                :: MENU OPTIONS ::
  47.  
  48.                1. Visualize Metal Colors
  49.                2. Calculate Albedo
  50.                3. Compare Index of Refraction
  51.                4. Visualize Albedo of Common Materials
  52.                0. Exit
  53.  
  54.                Enter your choice (0-4): 3
  55.  
  56.                Metal data:
  57.                 1. Aluminum
  58.                 2. Brass
  59.                 3. Chrome
  60.                 4. Cobalt
  61.                 5. Copper
  62.                 6. Gold
  63.                 7. Iron
  64.                 8. Lead
  65.                 9. Mercury
  66.                10. Nickel
  67.                11. Palladium
  68.                12. Platinum
  69.                13. Silver
  70.                14. Titanium
  71.                15. Zinc
  72.  
  73.                Enter the number of the first metal: 7
  74.  
  75.                Enter the number of the second metal: 11
  76.  
  77.                Palladium has a higher Index of Refraction (1.0250) than Iron (1.0060).
  78.                The difference is 0.0190.
  79.  
  80. Additional Notes:
  81.    - Metal data includes information such as RGB values and index of refraction.
  82.    - The script utilizes Matplotlib for data visualization.
  83.    - Users can interactively explore metal properties and compare them using this tool.
  84. """
  85.  
  86. import numpy as np
  87. import matplotlib.pyplot as plt
  88.  
  89. # Common Metal Data
  90. """
  91.    - This dictionary contains data about common metals including their RGB color values and Index of Refraction (IOR).
  92.  
  93.    * metal_data : dict
  94.        A dictionary where each key represents a metal name and each value is another dictionary containing the following:
  95.            - Color_RGB: Tuple representing the color of the metal in RGB format.
  96.            - IOR: Index of Refraction value for the metal.
  97. """
  98. metal_data = {
  99.     "Aluminum": {"Color_RGB": (245, 246, 246), "IOR": 1.002},
  100.     "Brass": {"Color_RGB": (214, 185, 123), "IOR": 1.005},
  101.     "Chrome": {"Color_RGB": (196, 197, 197), "IOR": 1.03},
  102.     "Cobalt": {"Color_RGB": (211, 210, 207), "IOR": 1.031},
  103.     "Copper": {"Color_RGB": (250, 208, 192), "IOR": 1.219},
  104.     "Gold": {"Color_RGB": (255, 226, 155), "IOR": 1.350},
  105.     "Iron": {"Color_RGB": (198, 198, 200), "IOR": 1.006},
  106.     "Lead": {"Color_RGB": (67, 69, 71), "IOR": 1.016},
  107.     "Mercury": {"Color_RGB": (229, 228, 228), "IOR": 1.013},
  108.     "Nickel": {"Color_RGB": (211, 203, 190), "IOR": 1.016},
  109.     "Palladium": {"Color_RGB": (222, 217, 211), "IOR": 1.025},
  110.     "Platinum": {"Color_RGB": (213, 208, 200), "IOR": 1.024},
  111.     "Silver": {"Color_RGB": (252, 250, 245), "IOR": 1.082},
  112.     "Titanium": {"Color_RGB": (195, 186, 177), "IOR": 1.086},
  113.     "Zinc": {"Color_RGB": (213, 234, 237), "IOR": 1.011},
  114. }
  115.  
  116. # Common Materials & Their Albedo Range (Min, Max)
  117. """
  118.    - This dictionary contains data about common materials along with their albedo range, represented by a tuple containing the min and max values.
  119.  
  120.    * common_materials : dict
  121.        - A dictionary where each key represents a material name, and each value is a tuple containing the albedo range (minimum, maximum).
  122.          If the maximum value is not available, it is represented as `None`.
  123. """
  124. common_materials = {
  125.     "Acrylic glass": (1.490, 1.492),
  126.     "Air": (1.000, None),
  127.     "Alabaster": (0.92, 0.92),
  128.     "Alcohol, Ethyl (grain)": (1.360, None),
  129.     "Aluminum": (1.390, 1.440),
  130.     "Asphalt": (1.635, None),
  131.     "Beer": (1.345, None),
  132.     "Black Acrylic Paint": (0.05, 0.05),
  133.     "Bronze": (1.180, None),
  134.     "Colored Paint": (0.15, 0.35),
  135.     "Crystal": (2.000, None),
  136.     "Diamond": (2.418, None),
  137.     "Emerald": (1.560, 1.605),
  138.     "Eye, Lens": (1.410, None),
  139.     "Forged Iron": (0.04, 0.04),
  140.     "Glass": (1.500, None),
  141.     "Glass, Pyrex": (1.474, None),
  142.     "Gold": (0.470, None),
  143.     "Granite Gray": (0.35, 0.4),
  144.     "Ice": (1.309, None),
  145.     "Iron": (2.950, None),
  146.     "Ivory": (1.540, None),
  147.     "Lead": (2.010, None),
  148.     "Lucite": (1.495, None),
  149.     "Magnesium Oxide": (0.96, 0.96),
  150.     "Mercury (liquid)": (1.620, None),
  151.     "Milk": (1.350, None),
  152.     "Natural Silk Fabric": (0.35, 0.55),
  153.     "Nickel": (1.080, None),
  154.     "Nylon": (1.530, None),
  155.     "Pearl": (1.530, 1.690),
  156.     "Plaster": (0.4, 0.45),
  157.     "Plastic": (1.460, None),
  158.     "Skin": (0.25, 0.35),
  159.     "Teflon": (1.350, 1.380),
  160.     "Titanium": (2.160, None),
  161.     "Vodka": (1.363, None),
  162.     "Water (35 deg C)": (1.325, None),
  163.     "White Acrylic Paint": (0.8, 0.8),
  164.     "White Gypsum": (0.85, 0.85),
  165.     "White Paper Sheet": (0.6, 0.7),
  166. }
  167.  
  168. # Function To Visualize Metal Colors
  169. def visualize_metal_colors():
  170.     """
  171.        Visualize the albedo of common metals.
  172.            - This function generates a horizontal bar plot visualizing the albedo (mean color) of common metals.
  173.            - Each bar represents a metal, and its length corresponds to the albedo value.
  174.    """
  175.     color_values = []
  176.     metal_names = []
  177.  
  178.     # Sort metal data alphabetically by metal names
  179.     sorted_metal_data = sorted(metal_data.items(), key=lambda x: x[0])
  180.  
  181.     for metal_name, metal_data_single in sorted_metal_data:
  182.         metal_names.append(metal_name)
  183.         color_values.append(np.mean(metal_data_single["Color_RGB"]) / 255)
  184.  
  185.     plt.figure(figsize=(10, 6))
  186.     plt.title('Metal Albedo')
  187.  
  188.     # Reverse the order of metal names
  189.     metal_names = metal_names[::-1]
  190.     color_values = color_values[::-1]
  191.  
  192.     bars = plt.barh(metal_names, color_values, color='green')
  193.     plt.xlabel('Albedo')
  194.     plt.ylabel('Metal')
  195.     plt.grid(axis='x')
  196.     plt.xlim(0.65, 1.0)  # Set the x-axis limits to start at 0.65
  197.  
  198.     # Add annotations to each bar
  199.     for bar in bars:
  200.         width = bar.get_width()
  201.         plt.text(width, bar.get_y() + bar.get_height() / 2,
  202.                  f'{width:.3f}',
  203.                  va='center', ha='left',
  204.                  color='black', fontweight='bold')
  205.     plt.show()
  206.  
  207. # Function To Display Metal Data As A Numbered List
  208. def display_metal_data():
  209.     """
  210.        Display metal data as a numbered list.
  211.            - This function prints the list of common metals along with their index numbers.
  212.    """
  213.     print("\nMetal data:")
  214.     for index, (metal_name, _) in enumerate(metal_data.items(), start=1):
  215.         print(f"{index:2}. {metal_name}")
  216.  
  217. # Function To Calculate The Albedo Of A Specific Metal
  218. def calculate_albedo():
  219.     """
  220.        Calculate the albedo of a specific metal.
  221.            - This function prompts the user to select a metal from the list and calculates its albedo.
  222.    """
  223.     # Step 1: Display the list of available metals.
  224.     display_metal_data()
  225.    
  226.     # Step 2: Prompt the user to select a metal from the list.
  227.     metal_index_str = input("\nEnter the number of the metal: ")
  228.    
  229.     try:
  230.         metal_index = int(metal_index_str)
  231.         if 1 <= metal_index <= len(metal_data):
  232.             metal_name = list(metal_data.keys())[metal_index - 1]
  233.             metal_single = metal_data[metal_name]
  234.            
  235.             # Step 3: Calculate the albedo of the selected metal.
  236.             albedo = np.mean(metal_single["Color_RGB"]) / 255
  237.             print(f"\nThe albedo of {metal_name} is: {albedo:.4f}")
  238.         else:
  239.             print("\nInvalid metal number!")
  240.     except ValueError:
  241.         print("\nInvalid input! Please enter a valid number.")
  242.  
  243. # Function To Compare The Index Of Refraction Between Two Metals
  244. def compare_ior(metal1_str, metal2_str):
  245.     """
  246.        Compare the Index of Refraction (IOR) between two metals.
  247.            - This function takes two metal indices as input and compares their IOR values.
  248.    """
  249.     try:
  250.         # Step 1: Convert input strings to integers.
  251.         metal1_index = int(metal1_str)
  252.         metal2_index = int(metal2_str)
  253.        
  254.         # Step 2: Check if the input indices are within the valid range.
  255.         if 1 <= metal1_index <= len(metal_data) and 1 <= metal2_index <= len(metal_data):
  256.             # Step 3: Retrieve metal names based on the input indices.
  257.             metal1_name = list(metal_data.keys())[metal1_index - 1]
  258.             metal2_name = list(metal_data.keys())[metal2_index - 1]
  259.             metal1_data = metal_data[metal1_name]
  260.             metal2_data = metal_data[metal2_name]
  261.            
  262.             # Step 4: Compare the IOR values of the two metals.
  263.             if metal1_data["IOR"] > metal2_data["IOR"]:
  264.                 print(f"\n{metal1_name} has a higher Index of Refraction ({metal1_data['IOR']:.4f}) than {metal2_name} ({metal2_data['IOR']:.4f}).")
  265.                 print(f"The difference is {metal1_data['IOR'] - metal2_data['IOR']:.4f}.")
  266.             elif metal1_data["IOR"] < metal2_data["IOR"]:
  267.                 print(f"\n{metal2_name} has a higher Index of Refraction ({metal2_data['IOR']:.4f}) than {metal1_name} ({metal1_data['IOR']:.4f}).")
  268.                 print(f"The difference is {metal2_data['IOR'] - metal1_data['IOR']:.4f}.")
  269.             else:
  270.                 print(f"\nThe Index of Refraction of {metal1_name} ({metal1_data['IOR']:.4f}) and {metal2_name} ({metal2_data['IOR']:.4f}) are equal.")
  271.         else:
  272.             print("\nInvalid metal numbers!")
  273.     except ValueError:
  274.         print("\nInvalid input! Please enter valid numbers.")
  275.     print()
  276.  
  277. # Function To Visualize Albedo Of Common Materials
  278. def visualize_common_materials_albedo():
  279.     """
  280.    Visualize the albedo of common materials.
  281.        - This function generates a horizontal bar plot visualizing the albedo range of common materials.
  282.        - Each bar represents a material, and the range of albedo is shown using two colors for minimum and maximum values.
  283.    """
  284.     material_names = list(common_materials.keys())
  285.     min_values = [common_materials[material][0] if common_materials[material][0] is not None else 0 for material in material_names]
  286.     max_values = [common_materials[material][1] if common_materials[material][1] is not None else 0 for material in material_names]
  287.  
  288.     y_pos = np.arange(len(material_names))
  289.  
  290.     # Reverse the y_pos array
  291.     y_pos = y_pos[::-1]
  292.  
  293.     plt.figure(figsize=(14, 18))
  294.     plt.title('Albedo of Common Materials')
  295.  
  296.     # Step 1: Create horizontal bar plot
  297.     bars_max = plt.barh(y_pos, max_values, color='yellow', label='Max')
  298.     bars_min = plt.barh(y_pos, min_values, color='green', alpha=0.5, label='Min')
  299.  
  300.     plt.yticks(y_pos, material_names)
  301.     plt.xlabel('Albedo Range')
  302.     plt.ylabel('Material')
  303.     plt.legend(loc='upper right')
  304.     plt.grid(axis='x')
  305.     plt.xlim(0, 3.6)
  306.  
  307.     # Step 2: Add annotations to each bar for max values with the range
  308.     for bar_max, bar_min, max_val, min_val in zip(bars_max, bars_min, max_values, min_values):
  309.         if max_val != 0:
  310.             annotation = f"[MIN: {min_val:.3f} - MAX: {max_val:.3f}]"
  311.             plt.text(bar_max.get_width(), bar_max.get_y() + bar_max.get_height() / 2,
  312.                      annotation,
  313.                      va='center', ha='left',
  314.                      color='black', fontweight='bold')
  315.         elif min_val != 0:
  316.             annotation = f"[MIN: {min_val:.3f} - MAX: N/A]"
  317.             plt.text(bar_min.get_width(), bar_min.get_y() + bar_min.get_height() / 2,
  318.                      annotation,
  319.                      va='center', ha='left',
  320.                      color='black', fontweight='bold')
  321.     plt.show()
  322.  
  323. # Menu-Driven Interface
  324. while True:
  325.     print("\n:: MENU OPTIONS ::\n")
  326.     print("1. Visualize Metal Colors")
  327.     print("2. Calculate Albedo")
  328.     print("3. Compare Index of Refraction")
  329.     print("4. Visualize Albedo of Common Materials")
  330.     print("0. Exit")
  331.  
  332.     choice = input("\nEnter your choice (0-4): ")
  333.  
  334.     if choice == '1':
  335.         print("\nMetal Data:")
  336.         for metal, data in metal_data.items():
  337.             print(f"{metal}: RGB={data['Color_RGB']} IOR: {data['IOR']:.4f}")
  338.         visualize_metal_colors()
  339.     elif choice == '2':
  340.         calculate_albedo()
  341.     elif choice == '3':
  342.         display_metal_data()
  343.         metal1 = input("\nEnter the number of the first metal: ")
  344.         metal2 = input("\nEnter the number of the second metal: ")
  345.         compare_ior(metal1, metal2)
  346.     elif choice == '4':
  347.         visualize_common_materials_albedo()
  348.     elif choice == '0':
  349.         print("\nExiting program...   Goodbye!\n")
  350.         break
  351.     else:
  352.         print("\nInvalid choice! Please enter a valid option.\n")
  353.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement