Spaces:
Sleeping
Sleeping
File size: 7,072 Bytes
dbbc9f9 0b7abd6 d7b7032 dbbc9f9 30b0367 d7b7032 3aeec2f ce80c98 d7b7032 ce80c98 d7b7032 3aeec2f dbbc9f9 d7b7032 dbbc9f9 d7b7032 dbbc9f9 d7b7032 9a08316 d7b7032 9a08316 d7b7032 6b77134 d7b7032 9a08316 dbbc9f9 d7b7032 0b7abd6 d7b7032 0b7abd6 d7b7032 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
import os
import requests
import gradio as gr
import json # For handling JSON responses
from pymatgen.core import Structure, Lattice
from pymatgen.io.cif import CifWriter
from pymatgen.io.xyz import XYZ
# Retrieve the API key from the environment variable
groq_api_key = os.getenv("GROQ_API_KEY")
if not groq_api_key:
raise ValueError("GROQ_API_KEY is missing! Set it in the Hugging Face Spaces 'Secrets'.")
# Define the API endpoint and headers
url = "https://api.groq.com/openai/v1/chat/completions"
headers = {"Authorization": f"Bearer {groq_api_key}"}
# Function to interact with Groq API
def get_material_info(user_input):
json_format = """
```json
{
"materials": [
{
"Material Name": "...",
"Key Properties": {
"Property 1": "value unit",
"Property 2": "value unit",
"...": "..."
},
"Suitability Explanation": "...",
"Atomic Structure": "..."
},
{
"Material Name": "...",
"Key Properties": {
"Property 1": "value unit",
"Property 2": "value unit",
"...": "..."
},
"Suitability Explanation": "...",
"Atomic Structure": "..."
},
{
"Material Name": "...",
"Key Properties": {
"Property 1": "value unit",
"Property 2": "value unit",
"...": "..."
},
"Suitability Explanation": "...",
"Atomic Structure": "..."
}
]
}
```
"""
prompt = f"""You are a materials science expert. A user is asking for applications of materials.
Based on the user's request: "{user_input}", identify the 3 best materials for this application.
For each material, provide:
- Material Name:
- Key Properties relevant to the application: (e.g., strength, conductivity, melting point) with values if possible.
- A brief explanation of why this material is suitable for the application.
- A simplified representation of its atomic structure (if readily available and can be described textually, e.g., "FCC lattice", "HCP lattice", or a simple chemical formula with a basic structural description).
Format your response as a JSON object with the following structure:
{json_format}
"""
body = {
"model": "llama-3.1-8b-instant",
"messages": [{"role": "user", "content": prompt}]
}
response = requests.post(url, headers=headers, json=body)
if response.status_code == 200:
try:
return json.loads(response.json()['choices'][0]['message']['content'])
except json.JSONDecodeError:
return f"Error decoding JSON: {response.text}"
else:
return f"Error: {response.json()}"
def create_structure_file(material_info, file_format="xyz"):
if not isinstance(material_info, dict) or "materials" not in material_info or not material_info["materials"]:
return "No material information found to create structure file.", None
# Choose the first material for structure generation (can be modified to let user choose)
first_material = material_info["materials"][0]
structure_description = first_material.get("Atomic Structure", "")
material_name = first_material.get("Material Name", "unknown")
if not structure_description:
return f"No atomic structure information available for {material_name}.", None
# Attempt to create a basic structure based on the description
try:
if "FCC lattice" in structure_description.lower():
lattice = Lattice.cubic(4.0) # Example lattice parameter
structure = Structure(lattice, ["A", "A", "A", "A"], [[0, 0, 0], [0.5, 0.5, 0], [0.5, 0, 0.5], [0, 0.5, 0.5]])
elif "HCP lattice" in structure_description.lower():
lattice = Lattice.hexagonal(3.0, 5.0) # Example lattice parameters
structure = Structure(lattice, ["A", "A"], [[0, 0, 0], [1/3, 2/3, 1/2]])
elif structure_description and len(structure_description.split()) == 2: # Attempt simple diatomic
formula, struct = structure_description.split()
if len(formula) == 2 and len(struct.lower()) == 3 and "unit" in struct.lower():
lattice = Lattice.cubic(3.5) # Another example
structure = Structure(lattice, [formula[0], formula[1]], [[0, 0, 0], [0.5, 0.5, 0.5]])
else:
return f"Could not interpret the atomic structure description for {material_name}.", None
# Limit to 20 atoms if the generated structure has more
if structure.num_sites > 20:
structure = structure[:20]
if file_format == "xyz":
filepath = f"{material_name.replace(' ', '_')}_20atoms.xyz"
XYZ(structure).write_file(filepath)
elif file_format == "cif":
filepath = f"{material_name.replace(' ', '_')}_20atoms.cif"
CifWriter(structure, symprec=1e-5).write_file(filepath)
else:
return f"Unsupported file format: {file_format}", None
with open(filepath, 'r') as f:
file_content = f.read()
os.remove(filepath) # Clean up the temporary file
return f"Successfully created {file_format} file for {material_name} (first 20 atoms).", file_content
except Exception as e:
return f"Error creating structure file for {material_name}: {e}", None
def chat_and_generate(user_input, file_format):
material_info = get_material_info(user_input)
structure_message, file_content = create_structure_file(material_info, file_format)
output_text = ""
if isinstance(material_info, dict) and "materials" in material_info:
for i, material in enumerate(material_info["materials"]):
output_text += f"**Material {i+1}: {material['Material Name']}**\n"
output_text += f"Key Properties: {', '.join([f'{k}: {v}' for k, v in material['Key Properties'].items()])}\n"
output_text += f"Suitability: {material['Suitability Explanation']}\n"
output_text += f"Atomic Structure: {material['Atomic Structure']}\n\n"
else:
output_text = str(material_info)
return output_text, structure_message, file_content
# Create Gradio interface
inputs = [
gr.Textbox(lines=2, placeholder="Ask for material applications (e.g., 'materials for high-temperature superconductors')."),
gr.Radio(["xyz", "cif"], label="Generate Structure File (first material)", value="xyz")
]
outputs = [
gr.Markdown(),
gr.Textbox(label="Structure Generation Status"),
gr.Code(label="Generated Structure File Content")
]
interface = gr.Interface(
fn=chat_and_generate,
inputs=inputs,
outputs=outputs,
title="Materials Science Expert AI",
description="Ask about applications of materials and get information on the top 3 candidates with their properties and a generated atomic structure file (first 20 atoms).",
)
# Launch Gradio app
if __name__ == "__main__":
interface.launch() |