Hello everyone,
EDIT: I was wrong, NPRO’s last parameter is actually the wave number as pointed out by
EDIT: new version available in my last reply below!
I have made a user operand equivalent to INDX for non-sequential systems.
In non-sequential systems, INDX doesn’t work, and one workaround is to use a ZPL operand with the numeric function NPRO using the code 200 (index of refraction of an object). For some time, I used the following code in a ZPLM (I hope the code is self-explanatory but let me know otherwise):
object = PVHX()
OPTRETURN 0, NPRO(1, object, 200, 0)
However, if one has multiple wavelengths defined, it always seem to default to the first one (wave number: 1), and there’s no direct possibility to specify a wavelength in NPRO, whereas this is possible with INDX.
A work around is to use the Multi-Configuration Editor with the operand WAVE and a single wavelength defined in the System Explorer. That way, one can use a CONF operand before ZPLM to specify which configuration needs to be considered. However, this is not always desirable, which is why I made a C# user-operand that calculates the non-sequential refractive index with the wave number as a paramter. The complete code is available on my GitHub, but here is the important part:
// Add your custom code here...
// Object number from which to evaluate material index
int object_number = (int)Hx;
// Wave number at which to evaluate material index
int wave_number = (int)Hy;
// Actual wavelength
double wavelength = TheSystem.SystemData.Wavelengths.GetWavelength(wave_number).Wavelength;
// Wavelength squared
double wavel_squared = wavelength * wavelength;
// Catalog number (following look-up "switch" below, e.g. 1 = Schott)
int catalog_number = (int)Px;
// Catalog look-up
string catalog = "";
switch(catalog_number)
{
case 1:
catalog = "Schott";
break;
// Add other catalogs here
// ...
}
// Get Material name
string material = TheSystem.NCE.GetObjectAt(object_number).Material;
// Open >> Librairies..Materials Catalog
IMaterialsCatalog material_cat = TheSystem.Tools.OpenMaterialsCatalog();
// Select catalog and material
material_cat.SelectedCatalog = catalog;
material_cat.SelectedMaterial = material;
// Run Materials Catalog
material_cat.RunAndWaitForCompletion();
// Initialize dummy refractive index value
double refractive_index = -1.0;
// Look-up index formula
switch (material_cat.MaterialFormula)
{
// Sellmeier 1
case MaterialFormulas.Sellmeier1:
// Initialize fit coefficients
double K1, K2, K3, L1, L2, L3;
// Get fit coefficients
K1 = material_cat.GetFitCoefficient(0);
K2 = material_cat.GetFitCoefficient(2);
K3 = material_cat.GetFitCoefficient(4);
L1 = material_cat.GetFitCoefficient(1);
L2 = material_cat.GetFitCoefficient(3);
L3 = material_cat.GetFitCoefficient(5);
// Refractive index calculation
refractive_index = K1 / (wavel_squared - L1);
refractive_index += K2 / (wavel_squared - L2);
refractive_index += K3 / (wavel_squared - L3);
refractive_index *= wavel_squared;
refractive_index += 1.0;
refractive_index = Math.Sqrt(refractive_index);
break;
// Add other formulas here
// ...
}
// Close Materials Catalog
material_cat.Close();
operandResults>0] = refractive_index;
As you can see, I’ve only implemented the Schott catalog, which only uses the Sellmeier 1 formula, but we can add the other catalogs if people are interested.
The operand parameters are Hx: Object number, Hy: Wave number, Px: Catalog number (Schott = 1). And here is an example with N-BK7:
And the comparison with INDX in the same settings (Surface 2 is N-BK7 and F, d, C wavelength preset):
I’m also attaching the compiled operand UDOC06.exe file to my post.
Take care,
PS: there’s no error trapping. Avoid specifying an object number that hasn’t a material defined and use a wave number > 0
David