This is a collection of text and code snippets, thoughts, and blurbs that didn't quite make it as posts but wanted to collect them somewhere.
Origin of the term analog in computing
I was confused about the term "analog" in electronics and where it
originates from with regard to the concept of signals and data. It
was chosen because a signal or data can be comparable
to
continuously variable physical quantities. This is in contrast to
digital systems, where signals or data are represented by discrete
numerical values. Looking at the etymology of the word, "analog"
comes from the Greek word "analogos," meaning "proportionate."
The first electronic devices were analog, as they operated by directly manipulating continuous signals. This allowed them to mimic or be analogous to the physical phenomena they were designed to measure, process, or transmit. For example, the voltage across a resistor in an electric circuit could be used to represent the temperature, with changes in voltage corresponding directly to changes in temperature. Hence, voltage signal is analogous to temperature.
Attention as a Form of message passing
- Transformers: In the Transformer architecture, the attention mechanism allows each token in the sequence to directly "attend" to every other token, essentially forming a fully connected graph where nodes represent tokens, and edges represent the attention weights between tokens. This can be viewed as a form of message passing where information (or messages) from all tokens are aggregated at each token according to the attention weights. The multi-head attention further enriches this process by allowing multiple relationships (or message types) to be learned and aggregated in parallel.
- Similarity to Graphs: This process is reminiscent of how information is propagated in graphs, especially in GNNs, where nodes aggregate information from their neighbors. The key difference lies in the structure of the graph. In traditional GNNs, the graph's structure is typically determined by the data (e.g., molecular structure) and is not fully connected. In contrast, the Transformer treats sequences as fully connected graphs, at least in the attention mechanism.
Message Passing in GNN
Materials Project Rest API Julia seed
using HTTP, JSON | |
""" | |
abstract type MaterialsProjectQuery end | |
An abstract type representing a query to the Materials Project database. | |
""" | |
abstract type MaterialsProjectQuery end | |
""" | |
struct MaterialIDs <: MaterialsProjectQuery | |
id::String | |
query::String | |
MaterialIDs(ids::Union{String,Vector{String}}) | |
A concrete type for querying materials by their IDs. | |
# Fields | |
- `id::String`: A single material ID or a comma-separated list of material IDs. | |
- `query::String`: The constructed query string for the material IDs. | |
# Constructor | |
- `MaterialIDs(ids::Union{String,Vector{String}})`: Create a new `MaterialIDs` object from a single ID or a vector of IDs. | |
""" | |
struct MaterialIDs <: MaterialsProjectQuery | |
id::String | |
query::String | |
MaterialIDs(ids::Union{String,Vector{String}}) = begin | |
search = isa(ids, Vector) ? join(ids, ",") : ids | |
query = "?material_ids=$(search)" | |
new(search,query) | |
end | |
end | |
""" | |
struct Formulas <: MaterialsProjectQuery | |
formula::String | |
query::String | |
Formulas(formulas::Union{String,Vector{String}}) | |
A concrete type for querying materials by their formulas. | |
# Fields | |
- `formula::String`: A single formula or a comma-separated list of formulas. | |
- `query::String`: The constructed query string for the formulas. | |
# Constructor | |
- `Formulas(formulas::Union{String,Vector{String}})`: Create a new `Formulas` object from a single formula or a vector of formulas. | |
""" | |
struct Formulas <: MaterialsProjectQuery | |
formula::String | |
query::String | |
Formulas(formulas::Union{String,Vector{String}}) = begin | |
search = isa(formulas, Vector) ? join(formulas, ",") : formulas | |
query = "?formula=$(search)" | |
new(search,query) | |
end | |
end | |
""" | |
struct Elements <: MaterialsProjectQuery | |
elements::String | |
query::String | |
Elements(elements::Union{String,Vector{String}}) | |
A concrete type for querying materials by their elements. | |
# Fields | |
- `elements::String`: A single element or a comma-separated list of elements. | |
- `query::String`: The constructed query string for the elements. | |
# Constructor | |
- `Elements(elements::Union{String,Vector{String}})`: Create a new `Elements` object from a single element or a vector of elements. | |
""" | |
struct Elements <: MaterialsProjectQuery | |
elements::String | |
query::String | |
Elements(elements::Union{String,Vector{String}}) = begin | |
search = isa(elements, Vector) ? join(elements, ",") : elements | |
query = "?elements=$(search)" | |
new(search,query) | |
end | |
end | |
""" | |
struct Spacegroup <: MaterialsProjectQuery | |
number::Int | |
query::String | |
Spacegroup(spacegroup::Int) | |
A concrete type for querying materials by their spacegroup number. | |
# Fields | |
- `number::Int`: The spacegroup number. | |
- `query::String`: The constructed query string for the spacegroup number. | |
# Constructor | |
- `Spacegroup(spacegroup::Int)`: Create a new `Spacegroup` object from a spacegroup number. | |
""" | |
struct Spacegroup <: MaterialsProjectQuery | |
number::Int | |
query::String | |
Spacegroup(spacegroup::Int) = begin | |
query = "?spacegroup_number=$(spacegroup)" | |
new(spacegroup,query) | |
end | |
end | |
""" | |
struct MultiQuery <: MaterialsProjectQuery | |
query::String | |
A concrete type for handling multiple query conditions. | |
# Fields | |
- `query::String`: The constructed query string combining multiple conditions. | |
""" | |
struct MultiQuery <: MaterialsProjectQuery | |
query::String | |
end | |
Base.join(q1::T,q2::S) where {T<:MaterialsProjectQuery, S<:MaterialsProjectQuery} = | |
begin | |
q2mod = strip(q2.query,'?') | |
query = join([q1.query,q2mod],"&") | |
MultiQuery(query) | |
end | |
""" | |
get_mp(qtype::MaterialsProjectQuery, | |
api_key::String, | |
endpoint="materials/summary", | |
all_fields=true) | |
Fetch data from the Materials Project API. | |
# Arguments | |
- `qtype::MaterialsProjectQuery`: A query type instance (e.g., `MaterialIDs`, `Formulas`, `Elements`, `Spacegroup`, `MultiQuery`). | |
- `api_key::String`: The API key for accessing the Materials Project API. | |
- `endpoint::String`: The API endpoint to query. Default is `"materials/summary"`. | |
- `all_fields::Bool`: Whether to fetch all fields in the query. Default is `true`. | |
# Returns | |
- A dictionary containing the response data if the query is successful. | |
- `nothing` if the query fails or if the API key is empty. | |
# Examples | |
```julia | |
# Query by material IDs | |
get_mp(MaterialIDs(["mp-1234", "mp-5678"]), "your_api_key") | |
# Query by formulas | |
get_mp(Formulas(["WC", "WC2", "W2C"]), "your_api_key") | |
# Query by elements | |
get_mp(Elements(["Fe", "O"]), "your_api_key") | |
# Query by spacegroup number | |
get_mp(Spacegroup(225), "your_api_key") | |
# Query by multiple | |
get_mp(join(Formulas(["WC","WC2","W2C"],Spacegroup(60))),"your_api_key") | |
``` | |
""" | |
function get_mp(qtype::MaterialsProjectQuery, | |
api_key::String, | |
endpoint="materials/summary", | |
all_fields=true) | |
if isempty(api_key) | |
@error "Materials Project API key is empty!" | |
return nothing | |
end | |
base_url = "https://api.materialsproject.org" | |
query = join([qtype.query,"_all_fields=$(all_fields)"],"&") | |
query_url = joinpath([base_url, endpoint, query]) | |
headers = ["accept" => "application/json", "X-API-KEY" => api_key] | |
response = HTTP.get(query_url,headers,status_exception=false) | |
# Successful response, parse and return the data | |
if response.status >= 200 && response.status < 300 | |
data = JSON.parse(String(response.body)) | |
if isempty(data["data"]) | |
@error "Materials Project data is empty!" | |
end | |
return data | |
else | |
# Response indicates an error, return nothing | |
@error "Failed query with:" response.status | |
end | |
end |
Generating coherent (hkl) interfaces
from pymatgen.core.structure import Structure | |
from pymatgen.analysis.interfaces import CoherentInterfaceBuilder | |
from pymatgen.core.surface import get_symmetrically_distinct_miller_indices | |
from pymatgen.io.ase import AseAtomsAdaptor | |
from ase.atoms import Atoms | |
from typing import List | |
from joblib import Parallel, delayed | |
import warnings | |
def generate_interfaces( | |
substrate: Structure, | |
film: Structure, | |
max_sub_miller_index: int = 1, | |
max_film_miller_index: int = 2, | |
interface_thickness: float = 1.5, | |
vacuum_over_film: float = 0.0, | |
film_thickness: int = 3, | |
sub_thickness: int = 5, | |
in_layers: bool = True | |
) -> List[Atoms]: | |
""" | |
In parallel, generate all geometrically suitable (hkl) interfaces | |
between a substrate and a film. | |
Parameters: | |
substrate (Structure): The `pymatgen` structure of the substrate material. | |
film (Structure): The `pymatgen` structure of the film material. | |
max_sub_miller_index (int): Maximum Miller index for the substrate surfaces. | |
max_film_miller_index (int): Maximum Miller index for the film surfaces. | |
interface_thickness (float): Thickness of the interface gap in angstroms. | |
vacuum_over_film (float): Thickness of vacuum above the film in angstroms. | |
film_thickness (int): Film thickness in unit layers or angstroms. | |
sub_thickness (int): Substrate thickness in unit layers or angstroms. | |
in_layers (bool): Whether the thickness parameters are in unit layers. | |
Returns: | |
List[Atoms]: A list of ASE Atoms objects representing the generated interfaces. | |
""" | |
# Surpress all DeprecationWarnings from pymatgen/spglib | |
with warnings.catch_warnings(): | |
warnings.simplefilter("ignore", category=DeprecationWarning) | |
sub_miller = get_symmetrically_distinct_miller_indices(substrate, max_sub_miller_index) | |
film_miller = get_symmetrically_distinct_miller_indices(film, max_film_miller_index) | |
def process_pair(sub_hkl: tuple, film_hkl: tuple) -> List[Atoms]: | |
local_interfaces = [] | |
builder = CoherentInterfaceBuilder( | |
substrate_structure=substrate, | |
film_structure=film, | |
film_miller=film_hkl, | |
substrate_miller=sub_hkl | |
) | |
for termination in builder.terminations: | |
interface_gen = builder.get_interfaces( | |
termination=termination, | |
gap=interface_thickness, | |
vacuum_over_film=vacuum_over_film, | |
film_thickness=film_thickness, | |
substrate_thickness=sub_thickness, | |
in_layers=in_layers | |
) | |
for interface in interface_gen: | |
ase_atoms = AseAtomsAdaptor.get_atoms(interface, msonable=False) | |
ase_atoms.info['substrate_hkl'] = sub_hkl | |
ase_atoms.info['film_hkl'] = film_hkl | |
ase_atoms.info['strain'] = interface.interface_properties.get('strain') | |
ase_atoms.info['von_mises'] = interface.interface_properties.get('von_mises') | |
ase_atoms.wrap() # Ensure periodic boundary conditions are visualized correctly | |
local_interfaces.append(ase_atoms) | |
return local_interfaces | |
interfaces = Parallel(n_jobs=-1)( | |
delayed(process_pair)(sub_hkl, film_hkl) for sub_hkl in sub_miller for film_hkl in film_miller | |
) | |
return [item for sublist in interfaces for item in sublist] |
Bringuier, S., Blurbs, Dirac's Student, (2024). Retrieved from https://www.diracs-student.blog/p/blurbs.html
No comments:
Post a Comment
Please refrain from using ad hominem attacks, profanity, slander, or any similar sentiment in your comments. Let's keep the discussion respectful and constructive.