from mdf_forge.forge import Forge

mdf = Forge()

"""
Explanation: Part 4 - General Helper Functions
End of explanation
"""


mdf.match_field("mdf.source_name", "oqmd")
mdf.current_query()

"""
Explanation: Generally Useful Help
current_query
You can see the query you're currently building with current_query().
Note that your query may be enclosed in parentheses automatically. This does not alter the results of the query.
End of explanation
"""


mdf.reset_query()

mdf.current_query()

"""
Explanation: reset_query
If you have a query in memory that you don't want, you can use reset_query() to start a new query. This method will clear the current query entirely.
End of explanation
"""


mdf.exclude_field("mdf.source_name", "sluschi").match_field("material.elements", "Al").exclude_field("mdf.source_name", "oqmd")
res, info = mdf.search(limit=10, info=True)

"""
Explanation: Query info
We can build a query using exclude_field() and match_field() and execute it with search(). But if you are interested in knowing more about the query, including the actual query string that was made, you can use the info=True argument to search().
End of explanation
"""


res[0]

info

"""
Explanation: When you use the info=True argument, search() will return a tuple instead of a list. The first element in the tuple will be the same list of results you're used to, but the second tuple element will be a dictionary of query info.
End of explanation
"""


mdf.match_field("mdf.source_name", "nist_xps_db")

res, info = mdf.search(limit=10, info=True, reset_query=False)
info["query"]

res, info = mdf.search(limit=10, info=True)
info["query"]

"""
Explanation: Repeat a query
You can stop a query from being cleared out of memory after a search by using the reset_query=False argument.
End of explanation
"""


mdf.show_fields()

"""
Explanation: show_fields
How do you know what fields there are to search on? Use show_fields() to find out. If you just call show_fields() by itself, it will show you all fields currently in the MDF Search index.
End of explanation
"""


mdf.show_fields("mdf")

"""
Explanation: If you give show_fields() a top-level block, it will show you the mapping for that block, including the expected datatypes.
End of explanation
"""


mdf.describe_field("dataset", field="mdf")

"""
Explanation: describe_field
To learn more about specific fields, use describe_field(). This method can tell you what a field means, what unit of measurement it uses, or other useful information. When you call describe_field(), you must pass in the resource_type you're interested in (such as dataset or record). Since the full schema for a resource_type is very long, you can also pass in a field you're interested in, in the standard dot notation (if you don't, you will get the full schema for the resource_type instead).
End of explanation
"""


mdf.describe_field("record", field="mdf.source_name", raw=True)

"""
Explanation: If you want your results in a dictionary instead of being printed out, you can set raw=True.
End of explanation
"""


mdf.describe_organization("argonne national laboratory")

mdf.describe_organization("CHiMaD")

"""
Explanation: describe_organization
To learn more about an organization registered with MDF, use describe_organization(). This method can tell you more about an organization, including the provided description, homepage, and submission rules. When you call describe_organization(), you just pass in the name or alias of an organization (capitalization doesn't matter).
End of explanation
"""


mdf.describe_organization("NIST", summary=True)

mdf.describe_organization("NIST MDR", raw=True)

"""
Explanation: You can also get a brief overview of an organization without the technical details by setting summary=True. describe_organization() also supports the raw argument to get results back as a dictionary (raw overrides summary).
End of explanation
"""


records = mdf.search("dft.converged:true AND mdf.resource_type:record")

res = mdf.fetch_datasets_from_results(records)
res[0]

"""
Explanation: Fetching Datasets
fetch_datasets_from_results
This method allows you to automatically collect all the datasets that have records returned from a search. In other words, if you search for mdf.elements:Al and a record from OQMD is returned, you can pass that record to fetch_datasets_from_results() and get the OQMD dataset entry back.
End of explanation
"""


res = mdf.match_field("material.elements", "Al").fetch_datasets_from_results()
res[0]

"""
Explanation: If you don't want to keep the results at all, you can also use fetch_datasets_from_results() to execute a search and use those results instead of passing it your own results.
End of explanation
"""


mdf.match_field("mdf.source_name", "oqmd*").match_field("material.elements", "Pb").exclude_field("material.elements", "Al")
res, info = mdf.search(limit=0, info=True, reset_query=False)
print("Number of results:", info["total_query_matches"])

"""
Explanation: Aggregations
aggregate
Queries submitted with search() are limited to returning 10,000 results. If this limit is too low, you can use aggregate() to retrieve all results from a query, no matter how many. Please be careful with this function, as you can easily accidentally retrieve a very large number of results without meaning to. Consider using search(your_query, limit=0, info=True) first to discover how many results you will get beforehand (see Query info above for more information).
For this example, we will see how many results the query will retrieve before aggregating.
End of explanation
"""


res = mdf.aggregate()
print("Number of results:", len(res))

"""
Explanation: Assuming we want all of these results, we can use aggregate() on the same query.
End of explanation
"""


