-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
179 additions
and
185 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,133 +1,130 @@ | ||
from lib import * | ||
import numpy as np | ||
|
||
# Author: Damian Mendroch, | ||
# Project repository: https://github.com/drocheam/miol-reng-tools | ||
|
||
""" | ||
Generate a mathematical representation of a lens profile using a confocal lens measurement. | ||
Processing includes: Centering, alignment, interpolation, filtering and parameter regression. | ||
The output of this script is a numpy archive (.npz) that holds the radius vector, | ||
parameters for the refractive base part as well as filtered data of the diffractive part (both 1 dimensional) | ||
User Interaction: | ||
1. Chose stiching method | ||
2. Depending on stitching method specify path to nms or sms and smi file | ||
3. Lens plot | ||
4. Specify lens center and lens diameter using the setLensProperties() Interface | ||
5. Plots of conic section, polynomials and diffractive part | ||
6. Specify if polynomials and diffractive parts will be excluded | ||
7. if diffractive part included: do for both lens surface sides: | ||
a) set interpolation regions for diffractive profile | ||
b) set filtering parameters for diffractive profile (setFiltering() Interface) | ||
8. set saving path for output .npz archive | ||
""" | ||
|
||
|
||
def GenerateProfiles(x=None, y=None, h_data=None): | ||
""" | ||
Processing of a lens measurement to a adjusted, filtered and fitted profile of the lens. The processing settings, | ||
fitting properties and the processed data is saved in a numpy archive. | ||
If this function is called without parameters, a measurement file is imported at runtime | ||
:param x: x coordinate vector (1D array) | ||
:param y: y coordinate vector (1D array) | ||
:param h_data: z values (2D array) | ||
""" | ||
|
||
#################################### Data Import and Stitching ##################################################### | ||
|
||
# no data given | ||
if x is None or y is None or h_data is None: | ||
|
||
SM = setStitching() | ||
if SM == "usurf": | ||
path = inputFilePath("Path to nms file: ", ftype=".nms") | ||
x, y, h_data = importMeasurement(path) | ||
else: | ||
path_smt = inputFilePath("Path to sms file: ", ftype=".sms") | ||
path_smi = inputFilePath("Path to smi file: ", ftype=".smi") | ||
path = path_smt # also path used for saving | ||
|
||
x0, y0, Images = importImages(path_smt) | ||
SP = getStitchingPreferences(path_smi) | ||
|
||
sr = round(25/(x0[1] -x0[0])) # search region is 25um in every direction | ||
arrx, arry = getShiftVectors(Images, ovlp=SP['ovlp'], sr=sr, mode=SM, transpose=SP['upwards'], debug=False) | ||
x, y, h_data = Stitch(x0, y0, Images, SP, arrx.astype(int), arry.astype(int)) | ||
# data given | ||
else: | ||
path = "./" | ||
SM = "not specified" | ||
|
||
################################### Geometric Manipulations #########0############################################### | ||
|
||
# Interpolation of missing data | ||
h_data_i = interpolateNan(h_data) | ||
|
||
# Lens Plot | ||
LensPlot(x, y, h_data_i) | ||
|
||
# User specifies lens properties | ||
LP = setLensProperties(x, y, h_data_i) | ||
|
||
# Cut Lens | ||
h_data_c = cutLens(x, y, h_data_i, LP['r2'], LP['xm'], LP['ym']) | ||
|
||
# compensate lens tilt | ||
radX, radY = tiltRegression(x, y, h_data_c, LP, cp=-1) | ||
print("\nTilt x direction:", "{:.3f}".format(radX*1000), "mrad (", "{:.4f}".format(radX/np.pi*180), "deg)") | ||
print("Tilt y direction:", "{:.3f}".format(radY*1000), "mrad (", "{:.4f}".format(radY/np.pi*180), "deg)") | ||
|
||
# Generate 1D Profiles from 2D data | ||
r, prof1, prof2 = getProfiles(x, y, h_data_c, LP, [-radX, -radY]) | ||
|
||
profs = np.nanmean(np.concatenate((prof1, prof2)), axis=0) | ||
CR = ConicSectionRegression(r, profs, cp=0.75) | ||
PR = SymPolyRegression(r, profs- ConicSection(r, *CR), order=8) | ||
|
||
ProfileInformation(CR, PR, r) | ||
|
||
# Left and Right Profile Comparisons | ||
ProfilePlot(r, (ConicSection(r, *CR), ConicSection(r, *CR)+Poly(r, PR)), | ||
legentries=["Conic Section", "Conic Section + Polynomial"], title="Conic Section", blocking=False) | ||
ProfilePlot(r, Poly(r, PR), legentries=["Polynomial"], blocking=False, title="Polynomial") | ||
ComparisonPlot(r, prof1 - ConicSection(r, *CR)-Poly(r, PR), prof2 - ConicSection(r, *CR)-Poly(r, PR), | ||
blocking=True, title="Diffraction Profile") | ||
|
||
# decide if to use polynomials and profile | ||
use_poly, use_diff = setProfileUsage() | ||
|
||
if not use_poly: | ||
PR = [] | ||
|
||
if not use_diff: | ||
filtered1, filtered2 = 0, 0 | ||
F1, F2, I1, I2 = [], [], [], [] | ||
else: | ||
######################### Filtering Left Profile ############################################################### | ||
|
||
# Profile Interpolation | ||
diff1 = np.mean(prof1, axis=0) - ConicSection(r, *CR) - Poly(r, PR) | ||
prof_f1, I1 = setInterpolation(r, diff1) | ||
|
||
# Filtering | ||
filtered1, F1 = setFiltering(r, prof_f1) | ||
|
||
######################### Filtering Right Profile ############################################################## | ||
|
||
# Profile Interpolation | ||
diff2 = np.mean(prof2, axis=0) - ConicSection(r, *CR) - Poly(r, PR) | ||
prof_f2, I2 = setInterpolation(r, diff2) | ||
|
||
# Filtering | ||
filtered2, F2 = setFiltering(r, prof_f2) | ||
|
||
############################# Save Data ############################################################################ | ||
savdict = dict(r=r, diff1=filtered1, diff2=filtered2, SM=SM, LP=LP, tilt=[-radX, -radY], CR=CR, PR=PR, I1=I1, I2=I2, F1=F1, F2=F2) | ||
saveData(path, "Profile", savdict) | ||
|
||
|
||
# execute function when called as main file | ||
if __name__ == "__main__": | ||
GenerateProfiles() | ||
#!/usr/bin/env python3 | ||
|
||
from lib import * | ||
import numpy as np | ||
from pathlib import Path | ||
|
||
# Author: Damian Mendroch, | ||
# Project repository: https://github.com/drocheam/miol-reng-tools | ||
|
||
""" | ||
Generate a mathematical representation of a lens profile using a confocal lens measurement. | ||
Processing includes: Centering, alignment, interpolation, filtering and parameter regression. | ||
The output of this script is a numpy archive (.npz) that holds the radius vector, | ||
parameters for the refractive base part as well as filtered data of the diffractive part (both 1 dimensional) | ||
User Interaction: | ||
1. specify path of sms and smi file | ||
2. Lens plot | ||
3. Specify lens center and lens diameter using the setLensProperties() Interface | ||
4. Plots of conic section, polynomials and diffractive part | ||
5. Specify if polynomials and diffractive parts will be excluded | ||
6. if diffractive part is included: | ||
a) set interpolation regions for diffractive profile | ||
b) set filtering parameters for diffractive profile (setFiltering() Interface) | ||
7. set saving path for output .npz archive | ||
""" | ||
|
||
|
||
def GenerateProfiles(): | ||
""" | ||
Processing of a lens measurement to a adjusted, filtered and fitted profile of the lens. The processing settings, | ||
fitting properties and the processed data are saved in a numpy archive. | ||
""" | ||
|
||
#################################### Data Import and Stitching ##################################################### | ||
|
||
path_smt = inputFilePath("Path to sms file: ", ftype=".sms") | ||
path_smi = inputFilePath("Path to smi file: ", ftype=".smi") | ||
path = path_smt # also the path used for saving | ||
|
||
x0, y0, Images = importImages(path_smt) | ||
SP = getStitchingPreferences(path_smi) | ||
|
||
sr = round(25/(x0[1] -x0[0])) # search region is 25um in every direction | ||
arrx, arry = getShiftVectors(Images, ovlp=SP['ovlp'], sr=sr, mode="fft", transpose=SP['upwards'], debug=False) | ||
x, y, h_data = Stitch(x0, y0, Images, SP, arrx.astype(int), arry.astype(int)) | ||
|
||
################################### Geometric Manipulations #########0############################################## | ||
|
||
# Interpolation of missing data | ||
h_data_i = interpolateNan(h_data) | ||
|
||
# Lens Plot | ||
LensPlot(x, y, h_data_i, blocking=False) | ||
|
||
# User specifies lens properties | ||
LP = setLensProperties(x, y, h_data_i) | ||
|
||
# Cut Lens | ||
h_data_c = cutLens(x, y, h_data_i, LP['r2'], LP['xm'], LP['ym']) | ||
|
||
# remove outliers | ||
h_data_c = removeOutliers(h_data_c, 20, 1) | ||
|
||
# compensate lens tilt | ||
tc = getTiltCorrection(x, y, h_data_c, LP, cut=0.8) | ||
print(f"\nCorrection tilt x direction: {tc[0]*1000:.3f}mrad ({tc[0]/np.pi*180:.4f}deg)") | ||
print(f"Correction tilt y direction: {tc[1]*1000:.3f}mrad ({tc[1]/np.pi*180:.4f}deg)") | ||
r, prof1, prof2 = getProfiles(x, y, h_data_c, LP, tc) | ||
|
||
profs = np.nanmean(np.concatenate((prof1, prof2)), axis=0) | ||
CR = ConicSectionRegression(r, profs, cp=0.75) | ||
PR = SymPolyRegression(r, profs - ConicSection(r, *CR), order=10) | ||
|
||
# remove offset | ||
prof1 -= PR[-1] | ||
prof2 -= PR[-1] | ||
profs -= PR[-1] | ||
PR[-1] = 0 | ||
|
||
# calculate overall height | ||
h = profs[0] - profs[-1] | ||
|
||
# print stats | ||
ProfileInformation(CR, PR, r, h) | ||
|
||
ProfilePlot(r, (ConicSection(r, *CR[:2], k=0), ConicSection(r, *CR), ConicSection(r, *CR) + Poly(r, PR)), | ||
legentries=["Sphere", "Conic Section", "Conic Section + Polynomial"], | ||
title="Lens Base Profile", blocking=False) | ||
|
||
ProfilePlot(r, profs- ConicSection(r, *CR) - Poly(r, PR), legentries=["Mean Diffraction Profile"], | ||
blocking=False, title="Mean Diffraction Profile") | ||
|
||
ProfilePlot(r, Poly(r, PR), legentries=["Polynomial"], blocking=False, title="Polynomial") | ||
ComparisonPlot(r, prof1, prof2, blocking=False, title="Diffraction Profile") | ||
ComparisonPlot(r, prof1 - ConicSection(r, *CR)-Poly(r, PR), prof2 - ConicSection(r, *CR) - Poly(r, PR), | ||
blocking=True, title="Lens Profile") | ||
|
||
# decide if to use polynomials and profile | ||
use_poly, use_diff = setProfileUsage() | ||
|
||
if not use_poly: | ||
PR = [] | ||
|
||
if not use_diff: | ||
filtered = 0 | ||
diff = 0 | ||
F, I = [], [] | ||
else: | ||
# Profile Interpolation | ||
diff = profs - ConicSection(r, *CR) - Poly(r, PR) | ||
prof_f, I = setInterpolation(r, diff) | ||
|
||
# Filtering | ||
filtered, F = setFiltering(r, prof_f) | ||
|
||
ProfilePlot(r, (diff, filtered), legentries=["Measured Data", "Fitted Data"], | ||
title="Diffraction Profile", blocking=True) | ||
|
||
############################# Save Data ############################################################################ | ||
ppath = Path(path) | ||
filename = ppath.stem + "_Profile" | ||
savdict = dict(r=r, h=h, diff=filtered, diff_org=diff, LP=LP, tilt=tc, CR=CR, PR=PR, I=I, F=F) | ||
saveData(path, filename, savdict) | ||
|
||
|
||
# execute function when called as main file | ||
if __name__ == "__main__": | ||
GenerateProfiles() | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,52 +1,49 @@ | ||
from lib import * | ||
|
||
# Author: Damian Mendroch, | ||
# Project repository: https://github.com/drocheam/miol-reng-tools | ||
|
||
""" | ||
Visualizes processed diffractive MIOL data from a .npz archive. | ||
.npz archive needs to include all data generated from function GenerateProfiles() | ||
Plot of the conic section, polynomials and diffractive profiles are shown, | ||
as well as profile information. | ||
User Interaction: | ||
1. Enter Path to .npz archive | ||
2. Profile plots | ||
""" | ||
|
||
def ShowProfiles(path=None): | ||
""" | ||
loads the generated profile from GenerateProfiles() and shows several properties and plots. | ||
If path is not given, the user specifies a path at runtime | ||
:param path: (optional): path to numpy archive | ||
""" | ||
|
||
if path is None: | ||
path = inputFilePath("Path to npz file: ", ftype=".npz") | ||
S1 = loadData(path) | ||
|
||
ProfileInformation(S1['CR'], S1['PR'], S1['r']) | ||
|
||
Conic = ConicSection(S1['r'], *S1['CR']) | ||
ConicCircle = ConicSectionCircle(S1['r'], *S1['CR']) | ||
Polynomial = Poly(S1['r'], S1['PR']) | ||
|
||
legend1 = ["Profile 1", "Profile 2", "Conic Section + Polynomial"] | ||
legend2 = ["Conic Section", "Curvature Circle", "Conic Section + Polynomial"] | ||
legend3 = ["Diffractive Profile 1", "Diffractive Profile 2"] | ||
|
||
hasprofile = S1['diff1'].size > 1 # if diffraction profile needs to be shown | ||
|
||
ProfilePlot(S1['r'], (Conic + S1['diff1'] + Polynomial, Conic + S1['diff2'] + Polynomial, Conic+Polynomial), | ||
legentries=legend1, blocking=False) | ||
ProfilePlot(S1['r'], (Conic, ConicCircle, Conic+Polynomial), legentries=legend2, blocking=not hasprofile) | ||
|
||
if hasprofile: | ||
ProfilePlot(S1['r'], (S1['diff1'], S1['diff2']), legentries=legend3, blocking=True) | ||
|
||
|
||
# execute function when called as main file | ||
if __name__ == "__main__": | ||
ShowProfiles() | ||
#!/usr/bin/env python3 | ||
|
||
from lib import * | ||
|
||
# Author: Damian Mendroch | ||
# Project repository: https://github.com/drocheam/miol-reng-tools | ||
|
||
""" | ||
Visualizes processed diffractive MIOL data from a .npz archive. | ||
.npz archive needs to include all data generated from function GenerateProfiles() | ||
Plot of the conic section, polynomials and diffractive profiles are shown, | ||
as well as profile information. | ||
""" | ||
|
||
|
||
def ShowProfiles(): | ||
""" | ||
loads the generated profile from GenerateProfiles() and shows several properties and plots. | ||
""" | ||
|
||
path = inputFilePath("Path to npz file: ", ftype=".npz") | ||
S1 = loadData(path) | ||
|
||
ProfileInformation(S1['CR'], S1['PR'], S1['r'], S1['h']) | ||
|
||
Conic = ConicSection(S1['r'], *S1['CR']) | ||
ConicCircle = ConicSectionCircle(S1['r'], *S1['CR']) | ||
Polynomial = Poly(S1['r'], S1['PR']) | ||
|
||
legend1 = ["Profile", "Conic Section + Polynomial"] | ||
legend2 = ["Conic Section", "Curvature Circle", "Conic Section + Polynomial"] | ||
legend3 = ["Mean Profile", "Fitted Profile"] | ||
|
||
hasprofile = S1['diff'].size > 1 # if diffraction profile needs to be shown | ||
|
||
ProfilePlot(S1['r'], (Conic + S1['diff_org'] + Polynomial, Conic+Polynomial), | ||
legentries=legend1, blocking=False) | ||
ProfilePlot(S1['r'], (Conic, ConicCircle, Conic+Polynomial), legentries=legend2, blocking=not hasprofile) | ||
|
||
if hasprofile: | ||
ProfilePlot(S1['r'], (S1['diff_org'], S1['diff']), legentries=legend3, blocking=True) | ||
|
||
|
||
# execute function when called as main file | ||
if __name__ == "__main__": | ||
ShowProfiles() | ||
|