Solved

Search all glass across catalogs?

  • 22 February 2022
  • 7 replies
  • 716 views

Userlevel 3
Badge

Is there a way to search for a glass across all the catalogs?

More broadly, I’d like a Glasscat “database” view where I can view, filter, and combine glasses from all catalogs in an efficient way. Any tips or tricks would be appreciated.

Thank you,

John

icon

Best answer by John.Hygelund 2 March 2022, 03:32

View original

7 replies

Userlevel 7
Badge +3

Not all catalogs, but the Glass Compare tool lets you look at three catalogs at a time:

Does that help?

Userlevel 7
Badge +2

Hi John,

 

The glass catalogs are text files with the *.AGF extension (meaning you can open them with a text editor). Their syntax is described in the Help File under:

The Libraries Tab > Optical Materials Group > Using Material Catalogs > The AGF & BGF File Formats

 

You can use a third-party programing langage, such as Python, to parse through the files. I have done a dummy example for you below, which returns the glass vendors and names for each glass found in the GLASSCAT folder. Note that you need to change the path to your own GLASSCAT folder.

import os


# Path to {Documents}\Zemax\Glasscat
path = r'C:\Users\David Nguyen\Documents\Zemax\Glasscat'

# Initialize return array, which will contain the glass names and vendors
allglass = []

# Loop over the files in the GLASSCAT folder
for glasscat in os.listdir(path):
    # Select files with the *.AGF extension
    if glasscat.lower().endswith('.agf'):
        # Save vendor name
        vendor = glasscat[:-4]
        
        # Read the file
        with open(os.path.join(path, glasscat)) as glasstxt:
            # Search for the lines starting with NM (contains the glass name)
            for line in glasstxt:
                if line.lower().startswith('nm'):
                    # Save the glass name
                    glassname = line[3:]
                    glassname = glassname[:glassname.find(' ')]
                    allglass.append((vendor, glassname))
        
# Display results
for glass in allglass:
    print('Vendor: ' + glass[0] + ' | Glass: ' + glass[1])

 

If you run the code above, it’ll return the following (for all vendors and glasses):

 

Since you know the syntax of the glass catalogs, you can virtually return anything from the different glasses, and also make your own custom catalog.

I hope this helps,

 

David

Userlevel 3
Badge

Hello Mark, Yes this helps and seems like the best option for native searching. 

Hello David, Thank you very much for the example script and output. This seems like the route I need to take for specific investigations.

I would also like to search for indices at two specific wavelengths across catalogs. Does anyone know of available code for the various dispersions formulas? Programing them seems like a tedious chore.

Thank you!

Userlevel 7
Badge +2

Hi John,

 

I have made a second version of the code that implements the Schott formula at a single wavelength for your reference. Please note, it only returns glasses which use the Schott formula. I don’t have the time to implement all the formulas, but I believe it shouldn’t be too hard to complete.

import os


# Path to {Documents}\Zemax\Glasscat
path = r'C:\Users\David Nguyen\Documents\Zemax\Glasscat'

# Initialize return array, which will contain the glass names and vendors
allglass = []

# Dispersion formula flag
dispersionform = -1

# Wavelength of interest in micrometres
wave = 0.7

# Loop over the files in the GLASSCAT folder
for glasscat in os.listdir(path):
    # Select files with the *.AGF extension
    if glasscat.lower().endswith('.agf'):
        # Save vendor name
        vendor = glasscat[:-4]
        
        # Read the file
        with open(os.path.join(path, glasscat)) as glasstxt:
            # Search for the lines starting with NM (contains the glass name)
            for line in glasstxt:
                if line.lower().startswith('nm'):
                    # Split the parameters of the glass name entry
                    glassnamedata = line.split()
                    
                    # Save the glass name
                    glassname = glassnamedata[1]
                    
                    # Dispersion formula
                    dispersionform = int(float(glassnamedata[2]))
                else:
                    # Are we returning the refractive index?
                    if line.lower().startswith('cd') and dispersionform != -1:
                        # Schott dispersion formula
                        if dispersionform == 1:
                            dispersioncoef = line.split()
                            
                            # Coefficients
                            a0 = float(dispersioncoef[1])
                            a1 = float(dispersioncoef[2])
                            a2 = float(dispersioncoef[3])
                            a3 = float(dispersioncoef[4])
                            a4 = float(dispersioncoef[5])
                            a5 = float(dispersioncoef[6])
                            
                            # Refractive index
                            nschott = a0 + a1 * wave**2 + a2 * wave**-2 +\
                                a3 * wave**-4 + a4 * wave**-6 + a5 * wave**-8
                            nschott = nschott**0.5
                            
                            allglass.append((vendor, glassname, str(nschott)))
                            
                        # Reset flag
                        dispersionform = -1
        
# Display results
allglasstxt = ''

for glass in allglass:
    allglasstxt += 'Vendor: ' + glass[0] + ' | Glass: ' + glass[1]
    allglasstxt += ' | Refractive index (Schott): ' + glass[2] + '\n'
    
with open('allglass.txt', 'w') as glasstxt:
    glasstxt.writelines(allglasstxt)
                

 

This is what it looks like for the glasses that use the Schott formula and a wavelength of 0.7 um:

 

 

Take care,

 

David

Userlevel 6
Badge +2

Hi all,

Thanks to David for the code! I wanted to jump in here and say this can also be done with the ZOS-API which might make it seem like a less tedious task. For example, if I want to search the SCHOTT catalog for all materials with a wavelength range of 0.1 - 2.0 um, then I would use the following code:

matCat = TheSystem.Tools.OpenMaterialsCatalog()
matCat.SelectedCatalog = "SCHOTT.AGF"
allMats = matCat.GetAllMaterials()
numMats = len(allMats)

print()
print("Material: ", "MinWave: ", "MaxWave: ", sep = " ", end = "\n")
for mat in range(numMats - 1):
matCat.SelectedMaterial = allMats[mat + 1]
minWave = matCat.MinimumWavelength
maxWave = matCat.MaximumWavelength
if minWave > 0.1 and maxWave < 2.0:
print(matCat.SelectedMaterial, minWave, maxWave, sep = " ", end = "\n")

matCat.Close()

If we wanted to search across all catalogs for all materials with the same wavelength range, then we can add a second FOR loop, but the computation time may increase. This would look like the following:

matCat = TheSystem.Tools.OpenMaterialsCatalog()

print()
print("Material: ", "MinWave: ", "MaxWave: ", sep = " ", end = "\n")

allCats = matCat.GetAllCatalogs()
numCats = len(allCats)

for cat in range(numCats - 1):
matCat.SelectedCatalog = allCats[cat+1]
allMats = matCat.GetAllMaterials()
numMats = len(allMats)
for mat in range(numMats - 1):
matCat.SelectedMaterial = allMats[mat+1]
minWave = matCat.MinimumWavelength
maxWave = matCat.MaximumWavelength
if minWave > 0.1 and maxWave < 2.0:
print(matCat.SelectedCatalog, matCat.SelectedMaterial, minWave, maxWave, sep = " ", end = '\n')

matCat.Close()

The Material Catalog interface was implemented in the ZOS-API relatively recently, and allows you to programmatically search and update the catalogs with the following commands:

This might help to simplify future searches!

Userlevel 3
Badge

An excellent conversation regarding better tools for glass material evaluation!

Thank you David and Allie for your contributions.

Inspired by David, I wrote a Matlab script (my language of choice) that puts all .agf glasses into a single structure. This can then be used for easy filtering and evaluation.

As an example, I created a partial dispersion PgF for all glasses

Attached is the script, with .m extension changed to .txt to allow attachment

Userlevel 7
Badge +2

Really nice, thanks for sharing John, and thanks to @Allie for the ZOS-API approach.

Good luck with your project, and take care,

 

David

Reply