Computer Code for Materials Scientists: Igor Pro …...Computer Code for Materials Scientists: Igor...
Transcript of Computer Code for Materials Scientists: Igor Pro …...Computer Code for Materials Scientists: Igor...
Computer Code for Materials Scientists: Igor Pro Procedures for
Analyzing Dynamic Light Scattering, Rheology, and Synchrotron
X-ray Scattering Data
Adam K. Schmitt1,* and Mahesh K. Mahanthappa
1
1Department of Chemistry, University of Wisconsin-Madison, Madison, WI 53706
*Corresponding Author: Email [email protected].
Table of Contents
Abstract ......................................................................................................................................................... 2
Introduction ................................................................................................................................................... 2
Acknowledgments ......................................................................................................................................... 3
Procedure Explanations ................................................................................................................................ 3
DLS_Toolbar ............................................................................................................................................ 3
Rheology ................................................................................................................................................... 4
Sec5Tools .................................................................................................................................................. 4
Sec12Tools ................................................................................................................................................ 5
References ..................................................................................................................................................... 6
Procedure Help Files ..................................................................................................................................... 6
DLS_Toolbar ............................................................................................................................................ 6
Rheology ................................................................................................................................................... 8
Sec5Tools .................................................................................................................................................. 9
Sec12Tools .............................................................................................................................................. 11
Procedures ................................................................................................................................................... 14
DLS_Toolbar .......................................................................................................................................... 14
Rheology ................................................................................................................................................. 35
Sec5Tools ................................................................................................................................................ 40
Sec12Tools .............................................................................................................................................. 61
Abstract
The development of modern tools for rapidly screening the structures and properties of designer materials
for various technological applications mandates the development of new methods for quickly and
conveniently reducing, analyzing, and visualizing complex data sets to enable their meaningful
interpretation in multidimensional parameter spaces. Toward this end, procedures were written for use
with Igor Pro (Wavemetrics, Inc.) that allow fast data reduction and analysis for common Materials
Science characterization experiments. These techniques include dynamic light scattering (DLS), torsional
rheology, and synchrotron small- and wide-angle X-ray scattering (SAXS and WAXS, respectively). For
these experiments, the volume of data and complexity associated with its analysis in real-time are often
cumbersome to researchers. These procedures were written to assist and to enable the loading,
visualization, and analysis or interpretation of data in an effort to render tedious data analyses faster and
more convenient.
Introduction
Routine materials sample characterization quickly becomes tedious as the number of samples increases or
as the depth and complexity of the data analysis increases (e.g., multivariable fits). The following
procedures were written to ease this burden and to enable the reduction and complex analysis of data from
various techniques commonly used in advanced materials characterization. These procedures specifically
assist in the analysis of raw experimental data from dynamic light scattering, torsional rheology, and
synchrotron X-ray scattering. The research in our group primarily focuses on the morphological
properties of soft materials, including block copolymer melts and solutions,1-2
and polymer blends, and
lyotropic liquid crystalline phases of small molecule surfactants in water and in non-aqueous media.3 All
of these research projects necessitate quantitative structural characterization at various length scales,
ranging from ~ 1-100 nm. These properties may be probed by the above techniques, yet the data reduction
and analysis can be non-trivial in some cases.
These procedures are written for Igor Pro (Wavemetrics, Inc.), which allows for very high levels of end-
user customization in the way a program operates. Each of the procedures described herein consist of
three parts: (1) data loading, (2) visualization, and (3) analysis or interpretation. One very convenient
feature of these procedures is the ability to batch load files for processing by importing an entire file
directory. This eliminates the tedious sequential data loading that is usually associated with large data
sets. These programs also readily enable data visualization, which is critical for its interpretation.
Because the data analysis in each procedure differs slightly due to differences in the experimental
technique and the desired output and interpretation, a brief explanation of the capabilities of each analysis
routine follows.
The DLS_Toolbar is used to analyze dynamic light scattering data; specifically, it requires a .fit
file as input that is generated by a Brookhaven BI-9000AT digital autocorrelator. This procedure
can perform fits to different functional forms (single/double exponential decay) depending on the
system of interest. The diffusion coefficient and the hydrodynamic radius of one or more
populations in solution can be determined along with cumulants to analyze the population
dispersity.
The Rheology procedure is used to plot and to analyze data generated from a dynamic
temperature frequency sweep test; it requires that the data be collected and exported using the TA
Instruments Orchestrator software. This test in conjunction with the time-temperature
superposition principle allows for the determination of storage and loss moduli data at
experimentally inaccessible frequencies through the generation of master curves.
The Sec5Tools procedure analyzes small-angle X-ray scattering data from Sector 5 (DND-CAT)
at the Advanced Photon Source at Argonne National Laboratory (Argonne, IL). The procedure
allows for batch data loading, customizable visualization (e.g., overlay and stacked plots, option
for Kratky plot), and assistance in indexing scattering patterns through the addition of powder
diffraction peak indicators characteristic of commonly observed crystallographic symmetries.
The Sec12Tools procedure is used to analyze small- and wide-angle X-ray scattering from Sector
12 (12-ID-B) at the Advanced Photon Source at Argonne National Laboratory. The procedure
allows for batch data loading, customizable visualization (e.g., overlay and stacked plots, SAXS,
WAXS or SWAXS plots), and advanced data analysis including powder diffraction peak position
markers and conversion to file formats that are compatible with commonly used crystallographic
analysis programs.
Acknowledgments
The authors acknowledge financial support from University of Wisconsin-Madison and a National
Science Foundation CAREER Award (DMR-0748503) to M.K.M. We also acknowledge access to the
DuPont-Northwestern-Dow Collaborative Access Team 5-ID-D beam line and 12-ID-B beamlines at the
Advanced Photon Source at Argonne National Laboratory (Argonne, IL). The DuPont-Northwestern-Dow
Collaborative Access Team beamline (Sector 5), which is supported by E. I. DuPont de Nemours & Co.,
the Dow Chemical Company, the State of Illinois, and the U.S. Department of Energy, Office of Basic
Energy Sciences (Contract No. DE-AC02-06CH11357). The Chemical & Materials Science beamline
(Sector 12) is supported by the U.S. Department of Energy, Office of Basic Energy Sciences (Contract
No. DE-AC02-06CH11357).
Procedure Explanations
DLS_Toolbar
The DLS_Toolbar procedure is designed to analyze Dynamic Light Scattering (DLS) data acquired using
a Brookhaven Instruments DLS system (Brookhaven BI-9000AT digital autocorrelator). In a DLS
experiment, the fluctuating scattered light intensity is measured as a function of time and scattered angle.
These time-dependent fluctuations are then transformed into an autocorrelation function, which provides
insight into the time scales of the fluctuations, and thus, the diffusion of the particles in solution. The
autocorrelation function can be fit to different functional forms to determine the particle diffusion, which
can be related to the hydrodynamic radius of the particle using the Stokes-Einstein relation.4
This procedure takes as input a .fit file, which is the output from the autocorrelator. This file has a four-
row header and consists of three columns: time (s), measured intensity, and fitted intensity. This
procedure uses only the first two columns. After the data has been loaded, the autocorrelation function
can be fit to one of four built-in functions (single exponential, single exponential with cumulant, double
exponential, and double exponential with cumulant).4 Each of these functions applies to a specific
colloidal system of interest, subject to various simplifying assumptions. If you are unsure of which
function to use, please see the help file for this procedure.
This procedure also has the function to perform multi-angle light-scattering fits. After fitting all data
corresponding to a single sample at multiple detector angles, the resulting data can be compiled into a
multi-angle plot to determine more accurately the diffusion coefficient and the hydrodynamic radius
according to the Stokes-Einstein relation.4
Rheology
The Rheology procedure enables the analysis and generation of master curves from the time-temperature
superposition of temperature- and frequency-dependent rheological data. This procedure is compatible
with data acquired using TA Instruments ARES rheometers operated by the TA Orchestrator software.
Torsional Dynamic Mechanical Analysis (DMA) of a sample encompasses a wide variety of different
sample testing modes (isothermal frequency sweeps, isochronal temperature sweeps, and dynamic strain
sweeps). One very useful and comprehensive test is a dynamic frequency/temperature sweep test, the
results of which may be interpreted in the context of the time-temperature superposition principle (TTS).
TTS relies on the principle of corresponding states, such that a measurement at a specific frequency and
temperature can be related to another measurement at a slower frequency and lower temperature.5
When a dynamic temperature/frequency sweep is performed, isothermal frequency sweeps are measured
over a range of user-specified temperatures. Shift factors are applied to each of the various isothermal
frequency sweep data sets to align them with a single reference data set at a selected reference
temperature. This shifted data comprises a master curve, which shows the extended frequency behavior of
the sample. Further analysis, beyond the scope of this program, facilitates the determination of the
activation free energy of flow of the sample based on these shift factors.
This procedure takes as input the raw, unshifted data (Dynamic Frequency Temperature Sweep test data)
and the shift factors from the TA Orchestrator software. The data are separated by temperature and shifted
using the shift factors exported from the TA Orchestrator software. Additionally, it is possible to edit the
shift factors in order to obtain a better fit and to apply these modified shift factors to the plotted data. The
procedure allows for multiple plotting options of the resulting master curve and shift factors allowing for
the determination of the Williams-Landel-Ferry (WLF) parameters.5
Sec5Tools
The Sec5Tools procedure is used for reducing, visualizing, and analyzing small-angle X-ray scattering
(SAXS) data acquired at the 5-ID-D beamline (DND-CAT) at the Advanced Photon Source (APS) at
Argonne National Laboratory (Argonne, IL). SAXS is a useful tool for quantitatively interrogating the
morphology and principal domain spacing of a material. The observed scattering maxima in azimuthally-
integrated SAXS patterns can often be indexed to commonly-observed structures that are well known
(lamellae, the double gyroid, hexagonally-packed cylinders, and spheres packed on a body-centered cubic
lattice).6 The high flux at the APS allows for rapid analyses of a large volume of samples due to the short
X-ray exposure times required for high-resolution data acquisition, leading to the generation of very large
data sets in short periods of time. Furthermore, it is often necessary to analyze these giant data sets in
real-time in order to efficiently plan subsequent experiments and to minimize squandered experiment
time. This procedure offers a convenient way to import, organize, visualize, and index the patterns to
known morphologies facilitating real-time data analysis and planning at the beam line.
This procedure takes as input the large data sets often generated at Sector 5 at the APS. The files consist
of many data types, but the critical files for this procedure are the processed plot files containing intensity
(I(q)) versus scattering vector (q) data in addition to other relevant data. The typical filenames generated
at the beamline consist of user initials and a scan number. It is critical to keep good records of which scan
number corresponds to each sample and data acquisition temperature. To tag these data sets in a
meaningful manner, a comma separated text file (no spaces) must be generated that lists scan number,
sample name, exposure temperature and the number of scans (averaged). This text file is also an input for
the procedure.
After the text file is loaded, the entire directory of data can be loaded in a single user operation (see
procedure help file for more information). The scans may then be plotted on separate graphs or together in
stacked or overlayed configurations. In order to analyze the data, powder diffraction peak position
markers corresponding to four typical morphologies (lamellae, double gyroid, hexagonally-packed
cylinders, and spheres packed on a cubic lattice) can be overlayed on the azimuthally-integrated data to
determine the sample morphology.
Sec12Tools
The Sec12Tools procedure is used for reducing, visualizing, analyzing small- and wide-angle X-ray
scattering data (SWAXS) acquired at the Sector 12 beamline (12-ID-B) at the APS. SWAXS is used in
the same manner as SAXS (above) with the added benefit of being able to study phenomena that occur on
length scales ranging from ~1-50 nm (e.g., surfactant self-assembly, crystallization). As in SAXS (see
Sec5Tools), the positions of the observed scattering peaks and their associated scattering intensities may
be used to determine the underlying crystallographic space group symmetry of the nanostructured
material. In conjunction with other crystallographic software packages (JANA2006,7 Superflip,
8 and
VESTA9), one can perform Rietveld refinements of the X-ray data and construct electron density contrast
maps. Again, the amount of data generated during experimental runs at this beam line is overwhelming,
and this procedure provides a convenient means of importing, organizing, visualizing and interpreting the
data.
This procedure takes as input the large data sets generated at Sector 12, which are comprised of scattered
intensity (I(q)) versus scattering wavevector (q) data in addition to other relevant data. In contrast to the
data acquisition interface at the 5-ID-D beamline, the Sector 12 data station allows the user to define
custom filenames for each sample exposure. The entire directory of data is loaded in one user operation
and is available for subsequent use from a drop-down menu. The data can be plotted as described above
to display the SAXS data, the WAXS data, or both (SWAXS). Powder diffraction peak position indicator
lines may be overlayed to assist with morphological assignments. These lines can also be directly
converted to peak markers, facilitating quick export of publication quality figures. Additionally, in the
case of very complicated scattering patterns that do not index to the typically observed morphologies, the
azimuthally integrated SAXS pattern can be converted from I(q) vs. q to I(q) vs. 2θ and the intensity
scaled (relative intensity to “Counts”) for compatibility with the crystallographic software package Jade
(Materials Data, Inc.). Jade may then be used to determine the space group and refine the structure of the
sample.
References
1. L. Leibler, Theory of Microphase Separation in Block Copolymers. Macromolecules 1980, 13, 1602-
1617.
2. F. S. Bates, G. H. Fredrickson, Block Copolymers---Designer Soft Materials. Physics Today 1999,
52, 32-38.
3. T. Kato, N. Mizoshita, K. Kishimoto, Functional Liquid-Crystalline Assemblies: Self-Organized Soft
Materials. Angewandte Chemie International Edition 2006, 45, 38-68.
4. W. F. Edmonds, M. A. Hillmyer, T. P. Lodge, Block Copolymer Vesicles in Liquid CO2.
Macromolecules 2007, 40, 4917-4923.
5. P. C. Hiemenz, T. P. Lodge, Polymer Chemistry 2nd Edition. CRC Press: Boca Raton, FL, 2007.
6. S. Förster, A. Timmann, M. Konrad, C. Schellbach, A. Meyer, S. S. Funari, P. Mulvaney, R. Knott,
Scattering Curves of Ordered Mesoscopic Materials. The Journal of Physical Chemistry B 2005, 109,
1347-1360.
7. V. Petricek, M. Dusek, L. Palatinus, Jana2006. The crystallographic computing system. Institute of
Physics: Praha, Czech Republic, 2006.
8. L. Palatinus, G. Chapuis, SUPERFLIP - a computer program for the solution of crystal structures by
charge flipping in arbitrary dimensions. J. Appl. Cryst. 2007, 40, 786-790.
9. K. Momma, F. Izumi, VESTA: a three-dimensional visualization system for electronic and structural
analysis. J. Appl. Cryst. 2008, 41, 653-658.
Procedure Help Files
DLS_Toolbar
• Help File for DLS_Toolbar
DLS_Toolbar procedure and help file written by Adam K. Schmitt.
This procedure is used to import, plot, and fit autocorrelation functions generated by Brookhaven
Instruments Dynamic Light Scattering instruments. This procedure contains many different fit-functions
and can also fit multi-angle data.
• Loading DLS data into Igor
This procedure was designed to import .fit files generated by a Brookhaven BI-9000AT digital
autocorrelator. To load DLS data, select Tools > DLS > "Load and Graph" or "Load and Graph All".
"Load and Graph" enables examination of specific data sets in a folder containing many different
measurements. "Load and Graph All" is useful when you have a folder of the same sample measured at
different detector angles. To use "Load and Graph", simply select the data file you seek to open. To use
"Load and Graph All", select the directory containing the files you wish to open.
• Changing default parameters
If you are running experiments under non-standard conditions, you may select "Open and Set Parameters"
to change the default values for temperature (°C), wavelength (WL in nm), solvent refractive index (RI),
and solvent viscosity (Pa·s). The default conditions for this procedure are experiments in water at 25°C (T
= 298.15 K, WL = 532 nm, RI of solvent = 1.333, solvent viscosity = .001 Pa·s). These values are used
later in calculating the diffusion coefficient and hydrodynamic radius.
• Included fit-functions
There are four fit-functions included in this procedure file for fitting the observed autocorrelation
function. These include Single Exponential (SE), Single Exponential with Cumulant (SEWC), Double
Exponential (DE), and Double Exponential with Cumulant (DEWC). SE should be used for
measurements of monodisperse particles. If your solution contains a polydisperse mixture of particles that
exhibit a unimodal size distribution, SEWC should be used. If there are two populations of particles in
solution that exhibit different sizes, yet the two populations are narrowly dispersed, DE should be used. If
you have a mixture of two polydisperse populations, DEWC should be used. When using a cumulant fit,
the dispersity can be calculated as dispersity = /2.
If you do not know what is in solution, as is sometimes the case, you should work your way through the
fit functions in order of increasing complexity: SE, SEWC, DE, DEWC.
• Fitting autocorrelation functions
After you have loaded the data, set the default parameters, and decided which fit-function is most
appropriate for your sample, you are ready to start fitting your data. First, select the plot that you would
like to fit, then select “Fit Data” followed by the desired fit function. This will bring up a dialog to control
the fitting. The fitting equation is displayed on the top-right of the dialog. Use the slider bars to adjust the
values of the parameters to be used as the initial guess for fitting. Complex data fits sensitively depend on
good initial guesses to obtain accurate fits quickly. This procedure allows you to alter the parameters and
see the effect they have on the fit. Move the sliders until the fit line overlays almost exactly over the data.
If any of the parameters cannot reach the necessary value or if the value is too low on the slider bar, you
can adjust the sensitivity. To adjust the sensitivity, move the slider to the maximum value (to the right)
then click either "Up" or "Down" to increase or decrease the maximum value for that slider by a factor of
10. Once the initial guess lines up very nicely with the data, you can submit the initial guess and start the
fit by selecting the "Start Fit" button. You will be prompted to enter the detector angle (in degrees) of the
measurement. This allows for multi-angle plots and fitting later. Once you enter this value, the plot and fit
are shown along with the diffusion coefficient and hydrodynamic radius calculated using the Stokes-
Einstein relation.
• Multi-angle plots
After you have fit DLS data associated with all of the different measured angles for a given sample, you
may combine the data and perform a multi-angle plot. To do this, select "Multi-Angle Plot". This brings
up a small dialog box to ensure that you have analyzed all of the measurements at different angles. If you
have fitted your data, select "Start". This will bring up another dialog. Here, you should select the
different angles that you wish to use. You must use a minimum of two and up to a maximum of five
angles. Use the drop-down boxes to select the different angular data. NOTE: The procedure automatically
generates a wave specifically used to combine multiple angles into one plot. These waves will be names
based on the measurement angle and the fit function used (e.g., single exponential fit at 60° is named
60SE). Select the correct waves using the drop-down boxes being sure to put the waves in order from
smallest angle to largest angle. Once you have selected your data, select "_none_" on the remaining boxes
to remove them from evaluation, then select "Continue". This brings up the multi-angle data plot and fit,
which furnishes the diffusion coefficient and hydrodynamic radius calculated from the Stokes-Einstein
relation.
Rheology
• Help File for Rheology Procedure
Rheology procedure and help file written by Adam K. Schmitt.
This procedure is used to import data from time-temperature superpositions in TA Orchestrator (TA
Instruments, Inc.) to Igor Pro for plotting figures and adjusting shift factors.
• Working up files in TA Orchestrator
Open the Dynamic Frequency Temperature Sweep file in TA Orchestrator. The first step is to separate the
sweeps from each other. To do this, select Tools > Freq/Temp Sweep Separation in Orchestrator and
select Frequency. This will create many windows each with a frequency sweep at a different temperature.
To start the TTS session, select TTS > Select Data to Shift. Now, select all of the Freq. Sweep files,
choose the lowest temperature sweep as the "Reference Experiment Set" and press "Next > >". Now press
"Create TTS". This brings up two windows. On the left is the TTS data unshifted and on the right are the
shift factors at the different temperatures. To shift the data, select TTS > Shift All Data Sets. This
automatically determines the best fit shift factors and applies them to the data, to generate the Master
Curve, now shown on the left.
• Exporting files from TA Orchestrator
To export the files, select the right window and go to File > Export. Enter a suitable name at the dialog for
the .rad file generate, such as SampleShifts.rad. Now, select the original window containing the unshifted
data (the Dynamic Frequency Temperature Sweep data) and do the same, this time with a name such as
SampleTTS.rad. These are the files that need to be imported into Igor. NOTE: You cannot export the
shifted data sets in a usable form–you must export the original unshifted data.
• Loading files into Igor
Now the files that were just exported need to be imported into Igor. To do this, in Igor select Tools >
Rheology > Load TTS, Shift and Plot. This will bring up a dialog to select a file. Be sure to choose the
.rad file with the unshifted data from the Dynamic Frequency Temperature Sweep experiment. The next
dialog to appear is a renaming dialog box. Since the file names are typically complicated, this dialog box
allows the user to rename them with much simpler names. The final dialog is for importing the shift factor
.rad file.
Now the Master Curve is plotted for the storage modulus, G`. Also, the shift factors are shown in the table
for each different temperature.
• Modifying/updating shift factors
At this point, you can manually change the shift factors to try to obtain a better data fit. If you change the
values in the table, the graph will not update automatically. To update the graph, select Tools > Rheology
> Update Shifts. This will replot the newly shifted data. You can iteratively alter the shifts, until you
obtain a satisfactory fit.
• Plotting master curves
You can plot Master Curves of the shifted data by selecting Tools > Rheology > Plot Master Curve. You
are then prompted to choose between plotting only the Storage Modulus (G'), only the Loss Modulus (G'')
or both G’ and G”.
• Plotting shift factors
It is also convenient to show the shift factors at each temperature, allowing for the quantitative
determination of the Williams-Landel-Ferry (WLF) parameters. By selecting Tools > Rheology > Plot
Shift Factors, you can display an Arrhenius-type double y-plot with the horizontal shift factors plotted on
the left axis in a log scale and the vertical shift factors plotted on the right axis in a linear scale against
Temperature plotted on the horizontal axis.
Sec5Tools
• Help File for SAXS-APS-5
SAXS-APS-5 procedure and help file written by Adam K. Schmitt.
This procedure imports SAXS data taken at Sector 5-ID-D at the APS at Argonne National Lab (Argonne,
IL). It loads entire directories of files generated at the beamline and provides a convenient way to
visualize and to interpret the data rapidly and in real-time.
• Launching SAXS-APS-5 Panel
To launch the panel, select Tools > SAXS > Sector 5 > Sector 5 Tools. This will open the APSToolKit
panel, which allows access to all the functions in this procedure.
• Loading data into Igor
To load the SAXS data taken at Sector 5, there must be an accompanying info file generated by hand to
correlate the scan numbers to sample names and scan temperatures. This info file is a text file consisting
of four comma separated columns, those being Scan Number, Sample Name, Temperature, and Number
of Scans. There should be no spaces in this file and each scan number should be on a separate line.
NOTE: Not all scan numbers will need to be listed in this file, since dark scans also have scan numbers
that are not used for samples and thus not included in the imported data.
This file is then loaded into Igor by selecting "Load Info File" under the "Load Data Files" section at the
top of the panel. Pressing this button brings up a dialog to select the .txt info file.
The next step is to import the actual data files into Igor. It is easiest to import all the files at once using the
"Load Directory of Files" option. It is also possible to load only a single file using "Load One File". The
files that need to be loaded are located by searching for the "processing" folder in the SAXS data
generated at Sector 5. Inside this folder will be a list of folders containing different user folders. Select the
folder containing your data. This folder should contain a folder called "plot_files". This folder contains
the files that need to be imported into Igor. Select "Load Directory of Files" and navigate to the
aforementioned folder. You should see the files being loaded in the Command window. At this point, you
can either load other folders of data (by going back to the user folder list and selecting a different folder
containing another "plot_files" folder) or you may start plotting the data. NOTE: If the number of scans
for a sample is greater than one, the procedure selects the correct averaged file to import. Only use the
"Load One File" option if you are very familiar with the file output at Sector 5. NOTE: If you try to
import any other folder (besides plot_files), the files will not load and you will not be able to use the other
functions contained in this procedure.
• Plotting data
The plotting functions included in this procedure are diverse and allow for a high level of end-user
customization of the final plots generated. To start, select the wave you would like to plot from the
"Select Wave to Plot" drop-down menu. This menu contains a list of all of the scans that have been
imported into Igor. NOTE: If this drop-down menu simply says "_error_", no files have been loaded or
the file loading was performed incorrectly. To fix this problem, return to the previous section of the help
file and try to reload the files.
After you have selected the wave you wish to plot, you must ensure that the plotting options that follow
are correct. Under "Select Operation", select "Create New Graph" if you would like to start a new graph,
select "Append to Top Graph" if you would like to add this trace to a pre-existing graph that is currently
the highest (at the top), and select "Remove from Top Graph" if you would like to remove the selected
wave from the top most graph. NOTE: If there are no graphs created yet, "Append to Top Graph" and
"Remove from Top Graph" will have no effect. Also, if the selected wave is not on the top graph,
"Remove from Top Graph" will have no effect.
Under "Select Plot Style" there are two options. "Overlay plot" will plot multiple files on top of each
other and will not apply any offsets to additional waves that are appended to the graph. "Stacked Plot"
will apply the necessary vertical offsets so the data is not overlapping and can be visualized with ease.
NOTE: If the data have drastically differing intensities (disordered versus strongly microphase separated),
the offsets will not be sufficient to prevent overlapping traces.
Under "Select Plot Type" there are two options. You can either plot the log(I(q)) vs. q for a conventional
SAXS plot or you can plot the log(I(q)·q2) vs. q for a Kratky-type plot.
After the options have been correctly set, click the button to apply the changes. NOTE: This button will
say "Plot New!" if you are creating a new graph, "Append!" if you are appending the wave to the top
graph, or "Remove!" if you are removing the wave from the top graph.
Continue using these options to create stacked or overlayed plots containing multiple samples or
temperature sweeps.
• Interpreting data using powder diffraction peak position markers
Powder diffraction peak position markers are a useful way to identify morphologies in block copolymers
and lyotropic liquid crystals. This procedure includes functions for lamellar, hexagonal, spherical and
gyroid phases. To utilize the powder diffraction peak markers, select the wave that you want to index
using the "Select Wave to Plot" drop-down menu, then press the "Add Diffraction Lines" button. This
will bring up two new windows. The first window, titled "difflinesplot", is the I(q) vs. q plot of the wave
selected, and the second is the panel controlling the diffraction lines, titled "Add Diffraction Lines". To
display the powder diffraction peak position markers for a particular morphology, click the check box to
the left of the morphology name on the right side of the panel. In cases where the primary peak is the
most intense point on the plot, the procedure automatically finds the q-value of the primary reflection and
the diffraction markers should line up with the observed scattering peaks if the morphology is correct. In
the case where the scattering near the beam stop is more intense than your primary peak, you may have to
move the slider bar to the left of the morphology to select the proper q-value of the primary. NOTE: It is
possible to identify phase coexistence using this procedure. To do this, simply select both morphologies
present in the sample and set each to the corresponding q-value of the primary peak for each morphology.
When finished, make sure the plot is the top graph, and press the "Close" button on the panel. This will
close the "Add Diffraction Lines" panel and will rename the "difflinesplot" panel so as to not interfere
with future diffraction line plots. NOTE: If you close the "difflinesplot" window early or it is not the top
graph when "Close" is pressed, you will receive error messages during subsequent attempts to add
diffraction lines.
• Performing background subtraction
It is possible to perform background corrections with this procedure. To do this, you must select the
sample wave using the "Select Wave to Plot" drop-down menu. Then, select your background wave using
the "Select Background Wave" drop-down menu. NOTE: This background subtraction function is very
simple and does not apply any scaling factors. It will simply subtract the "background" wave from the
"sample" wave. To perform the background subtraction, press the "Subtract" button. The sample and
background traces are plotted in red (sample) and black (background) on the top half of the graph. On the
bottom half, the resulting background corrected trace is plotted in blue. These new background corrected
files are stored in a folder called "BackCorr" in the Igor file system. To get to these files using the data
browser, first navigate to the APS folder, then to the sample that you performed the background
subtraction on, then "BackCorr". The two files are "bci..." and "bcq..." and are the I(q) and q-value waves
respectively.
Sec12Tools
• Help File for SAXS-APS-12
SAXS-APS-12 procedure and help file written by Adam K. Schmitt.
This procedure is used to load, visualize and interpret X-ray scattering data collected at Sector 12-ID-B at
the APS at Argonne National Lab.
• Loading data
The easiest way to load the data generated at Sector 12 is to use the "Load Directory" option. It is also
possible to only import select files using the "Load One File" option, yet this is much less convenient for
large groups of data. When you select "Load Directory", you will need to pick the folder to load. This
folder is the "Averaged" folder located inside both the "SAXS" and "WAXS" folders. NOTE: If you
simply choose the "SAXS" or "WAXS" folders, no files will be loaded. The best practice is to load both
the SAXS and WAXS files generated at Sector 12 in order to view the largest possible q-range (range of
characteristic length scales).
After both SAXS and WAXS data sets are loaded using the "Load Directory" option, the data needs to be
combined to form the SWAXS data sets. The SWAXS data sets contain both the SAXS and WAXS
waves in an individual wave, which are useful for plotting both later in the process. To combine the data,
simply press the "Combine Data" button.
• Plotting data
The myriad plotting functions included in this procedure allow for a high level; of user customization of
the final plots generated. To get started, select the wave you would like to plot from the "Select Wave to
Plot" drop-down menu. In this menu are listed all of the scans that have been imported into Igor. NOTE:
If this drop-down menu simply says "_error_", no files have been loaded or the file loading was
performed incorrectly. To fix this problem, return the previous section of the help file and try to reload the
files.
After you have selected the wave you wish to plot, you must ensure that the plotting options that follow
are set correctly. Under "Select Operation", select "Create New Graph" to start a new graph, select
"Append to Top Graph" to add this trace to a pre-existing graph that is currently the highest (at the top),
and select "Remove from Top Graph" to remove the selected wave from the top most graph. NOTE: If
there are no graphs created yet, "Append to Top Graph" and "Remove from Top Graph" will have no
effect. Also, if the selected wave is not on the top graph, "Remove from Top Graph" will have no effect.
Under "Select Plot Style" there are two options. "Overlay plot" will plot multiple files on top of each
other and will not apply any offsets to additional waves that are appended to the graph. "Stacked Plot"
will apply the necessary offsets so the data is not overlapping and can be visualized with ease. NOTE: If
the data have dramatically different intensities (disordered versus strongly microphase separated), the
offsets will be insufficient to prevent overlapping traces.
Under "Select Which to Plot" there are three options. You can plot either only the "SAXS" or the
"WAXS" or you can plot the combined files by selecting "SWAXS",
After the options have been correctly set, click the button to apply the change. NOTE: This button will
say "Plot" if you are creating a new graph, "Append" if you are appending the wave to the top graph, or
"Remove" if you are removing the wave from the top graph.
Continue using these options to create stacked or overlayed plots containing multiple samples or
temperature sweeps.
• Converting data
This function is meant to simplify the export of data from Igor to Jade by converting from I(q) vs. q data
to I(q) vs. 2θ and modulating the intensity (from a relative intensity to “counts”), so that Jade (Materials
Data, Inc.) can read the file with sufficient resolution.
To convert a file for use in Jade, select the file using the "Select Wave to Plot" drop-down menu and press
the "Convert" button. This will briefly create a new table with converted values and will also bring up a
dialog. Navigate to where you would like to save the converted file and choose a suitable name. Upon
completion, the windows will disappear, yet the converted file will be saved in the specified location.
Because the beam energy is fixed at 12 keV at Sector 12, the conversion should work for all data taken at
this beamline. The q-values are converted to 2 data according to 2 = 180°/* sin-1
(1.033
Angstroms*q/4/).
• Adding powder diffraction peak markers to plots
Powder diffraction peak position markers are a useful way to identify morphologies in block copolymers
and lyotropic liquid crystals. This procedure includes functions for lamellar, hexagonal, spherical and
gyroid phases. To utilize the powder diffraction peak markers, select the wave that you want to index
using the "Select Wave to Plot" drop-down menu, then press the "Add Lines" button.
This will bring up two new windows. The first window, titled "difflinesplot", is the I(q) vs. q plot of the
wave selected, and the second is the panel controlling the powder diffraction peak position markers, titled
"Add Diffraction Lines". To display the powder diffraction markers for a particular morphology, click the
check box to the left of the morphology name on the right side of the panel. In cases where the primary
peak is the most intense point on the plot, the procedure automatically finds the q-value of the primary
and the diffraction peak markers should line up with the observed scattering peaks if the morphology is
correct. In the case where scattering near the beam stop is more intense than the primary peak, you may
have to move the slider bar to select the corresponding q-value of the peak. If your primary peak is out of
the range of the slider bars, you can use the "Low limit" and High limit" controls at the bottom of the
panel to adjust the range until you can accurately pinpoint the q-value of your primary scattering peak.
NOTE: It is possible to identify phase coexistence using this procedure. To do this, simply select both
morphologies present in the sample and set each to the corresponding q-value of the primary peak for
each morphology.
If you want to create markers on the plot in place of the vertical lines for use in figures, do not use the
"Close" button. Instead, make sure the "difflinesplot" is the top graph and press the "Markers" button.
This will bring up a dialog where you can enter the number of peaks you want indexed for each
morphology. NOTE: Only use a non-zero number of peaks if you want the peaks of that morphology to
be indexed on the plot. Typically, this means only one box is non-zero excluding cases with phase
coexistence. Finish the process by selecting "Continue" and the vertical lines will be converted to the
corresponding number of peaks for the morphologies selected.
If you do not want to add markers to the plot, make sure the plot is the top graph, and then press the
"Close" button on the panel. This will close the "Add Diffraction Lines" panel and will rename the
"difflinesplot" panel so as to not interfere with future diffraction line plots. NOTE: If you close the
"difflinesplot" window early or it is not the top graph when "Close" is pressed, you will receive error
messages during subsequent attempts to add diffraction lines.
Procedures
DLS_Toolbar
#pragma rtGlobals=1 // Use modern global access method.
// DLS Toolbar by AKS, 20130204
// This procedure is intended to be used to workup Dynamic Light Scattering data taken on a Brookhaven
Instruments multi-angle light scattering instrument using a Brookhaven BI-9000AT digital autocorrelator.
// This proceudre was developed by Adam K. Schmitt
Menu "Tools"
Submenu "DLS"
"Load and Graph All", LoadAndGraphAllDLS("")
"Load and Graph", LoadAndGraphDLS("","")
"Open and Set Parameters", ChangePar()
Submenu "Fit Data"
"SingleExponential", SingleExp2()
"Single Exponential with Cumulant", SingleExpWCum2()
"Single Exponential with Cumulant [g']", SingleExpWCumG()
"Double Exponential", DoubleExp2()
"Double Exponential with Cumulant", DoubleExpWCum2()
End
"Multi-Angle Plot", multipleAnglePlot()
End
End
// This function sets global parameters that are used throughout data workup
Function setVars()
// These variables are temperature, wavelength, refractive index of solvent, and viscosity of solvent
Variable/G gT = 298.15 // in K
Variable/G gWL=532 // in nm
Variable/G gRI=1.333
Variable/G gETA=.001 // in Pa s
End
// This function allows for changes to the default parameters
Function ChangePar()
NVAR gT
if (!NVAR_Exists(gT))
setVars()
endif
NVAR gT
NVAR gWL
NVAR gRI
NVAR gETA
NewPanel /W=(100,100,260,280)/K=1 as "Parameters"
TitleBox info1, pos={5,5}, title="Change Parameters and", frame=0
TitleBox info2, pos={5,30}, title="keep this window open", frame=0
SetVariable temp, pos={5,60}, limits={250,400,1}, value=gT, bodyWidth=120
SetVariable wavelen, pos={5,90}, limits={300,700,1}, value=gWL, bodyWidth=120
SetVariable ri, pos={5,120}, limits={0,4,.01}, value=gRI, bodyWidth=120
SetVariable eta, pos={5,150}, limits={.00001,.1,1}, value=gETA, bodyWidth=120
End
// This section defines the used functions and allows fits to data
Function SingleExpMy(w,x):FitFunc
Wave w
Variable x
return w[0]*exp(-2*w[1]*x)
End
Function SingleExpWCumMy(w,x):FitFunc
Wave w
Variable x
return w[0]*exp(-2*w[1]*x)*(1+w[2]*x^2/2)^2
End
Function SingleExpWCumGMy(w,x):FitFunc
Wave w
Variable x
return w[0]*exp(-w[1]*x)*(1+w[2]*x^2/2)
End
Function DoubleExpMy(w,x):FitFunc
Wave w
Variable x
return (w[0]*exp(-w[1]*x)+w[2]*exp(-w[3]*x))^2
End
Function DoubleExpWCumMy(w,x):FitFunc
Wave w
Variable x
return (w[0]*exp(-w[1]*x)*(1+w[2]*x^2/2)+w[3]*exp(-w[4]*x)*(1+w[5]*x^2/2))^2
End
Function LineThroughZero(w,x):FitFunc
Wave w
Variable x
return w[0]*x
End
// Function for loading data
Function LoadAndGraphAllDLS(pathName)
String pathName // Name of symbolic path or "" to get dialog
String fileName
Variable index=0
if (strlen(pathName)==0) // If no path specified, create one
NewPath/O temporaryPath // This will put up a dialog
if (V_flag != 0)
return -1 // User cancelled
endif
pathName = "temporaryPath"
endif
do // Loop through each file in folder
fileName = IndexedFile($pathName, index, ".fit")
if (strlen(fileName) == 0) // No more files?
break // Break
out of loop
endif
//start load and append to graph code
Display/K=1 //Create new graph
String name1 = fileName[0,strlen(fileName)-5]
String sxw, syw
sxw = name1+"0"
syw = name1+"1"
if(exists(sxw))
KillWaves $sxw,$syw
endif
LoadWave/N=$name1/J/D/K=0/L={3,4,0,0,2}/P=$pathName fileName
Wave xw = $sxw // Create wave references.
Wave yw = $syw
xw=xw/1000000
AppendToGraph yw vs xw
ModifyGraph log(bottom)=1
//end load and graph code
index +=1
while (1)
if (Exists("temporaryPath")) // Kill temp path if it exists
KillPath temporaryPath
endif
NVAR gT
if (!NVAR_Exists(gT))
ChangePar()
endif
return 0 // Signifies success.
End
Function LoadAndGraphDLS(fileName, pathName) // Load only one file
String pathName
String fileName
Display/K=1 //Create new graph
LoadWave/N=$fileName/J/D/K=0/L={3,4,0,0,2}/P=$pathName fileName
String name1 = S_fileName[0,strlen(S_fileName)-5] // Remove file suffix from name
String sxw, syw, sxw2, syw2
sxw = StringFromList(0,S_waveNames) // Get wave names
syw = StringFromList(1,S_waveNames)
sxw2=name1+"0" // Create new
wave names
syw2=name1+"1"
if (WaveExists(sxw2))
KillWaves sxw2,syw2 // Kill if they exist
endif
Rename $sxw, $sxw2 //Rename waves
Rename $syw, $syw2
Wave xw = $sxw2 // Create wave
references.
Wave yw = $syw2
xw=xw/1000000
AppendToGraph yw vs xw
ModifyGraph log(bottom)=1
NVAR gT
if (!NVAR_Exists(gT))
ChangePar()
endif
return 0 // Signifies success.
End
// Functions for fitting data to a single exponential function and extracting relevant data
Function SingleExp2()
Variable A,B
NewPanel /W=(100,100,500,260) as "Initial Guess for Fit"
TitleBox titleA, pos={5,5}, title="A=", frame=0
TitleBox titleB, pos={5,80}, title="B=", frame=0
Slider slideA, limits={0,.5,0}, pos={5,20}, size={200,50}, vert=0, ticks=1, variable=A,
proc=updateSingleExp
Slider slideB, limits={0,100000,0}, pos={5,95}, size={200,50}, vert=0, ticks=1, variable=B,
proc=updateSingleExp
Button senAup, pos={210,20}, title="Up", proc=updateSingleExpBut
Button senAdown, pos={210,40}, title="Down", proc=updateSingleExpBut
Button senBup, pos={210,95}, title="Up",proc=updateSingleExpBut
Button senBdown, pos={210,115}, title="Down", proc=updateSingleExpBut
TitleBox sens, pos={210,5}, title="Sensitivity", frame=0
TitleBox valA, pos={20,5}, title=num2str(A), frame=0
TitleBox valB, pos={20,80}, title=num2str(B), frame=0
TitleBox equation, pos={280,5}, title="f(t)=A*exp(-2*B*t)", frame=0
Button start, pos={280,55}, size={100,50},proc=startSingleExpFit, title="Start Fit"
End
Function updateSingleExpBut(ctrl): ButtonControl
String ctrl
Variable maxv
if (cmpstr(ctrl,"senAup")==0)
ControlInfo slideA; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideA, limits={0,maxv*10,0}
endif
if (cmpstr(ctrl,"senAdown")==0)
ControlInfo slideA; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideA, limits={0,maxv/10,0}
endif
if (cmpstr(ctrl,"senBup")==0)
ControlInfo slideB; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideB, limits={0,maxv*10,0}
endif
if (cmpstr(ctrl,"senBdown")==0)
ControlInfo slideB; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideB, limits={0,maxv/10,0}
endif
End
Function startSingleExpFit(ctrl): ButtonControl
String ctrl
String tempFit
NVAR gT
if (!NVAR_Exists(gT))
setVars()
endif
tempFit="tempFit"
//single fit function
if(exists(tempFit))
RemoveFromGraph tempFit
KillWaves tempFit
endif
Variable angle
Prompt angle, "Detector Angle in Degrees: "
DoPrompt "Experimental Paramters", angle
String xw, yw
xw=StringFromList(0,WaveList("*", ";","WIN:"))
yw=StringFromList(1,WaveList("*", ";","WIN:"))
if (WaveExists(cwave))
KillWaves cwave
endif
Make/N=2 cwave
ControlInfo slideA; cwave[0]=V_Value
ControlInfo slideB; cwave[1]=V_Value
DoWindow /K $WinName(0,64)
FuncFit/Q/NTHR=0 SingleExpMy cwave $yw /X=$xw /D
Variable A,B,q,D,R
NVAR gWL
NVAR gRI
NVAR gT
NVAR gETA
A=cwave[0]
B=cwave[1]
q=4*Pi*gRI/(gWL*10^-9)*sin(angle*Pi/360)
D=B/q^2
R=1.3806503*10^-23/6/Pi/D*gT/gETA
String texty = num2str(angle)+"º\r\rD ="+num2str(D)+" m\S2\M/s\rR\\Bh\\M
="+num2str(1000000000*R)+" nm"
TextBox/C/N=text0/F=0/A=RT texty
//end single fit function
ModifyGraph mirror=2,fSize=12,axThick=1.5,prescaleExp(left)=3,prescaleExp(bottom)=6;DelayUpdate
Label left "\Z14\F'Symbol'G\S(2)\M\Z14(t) - 1";DelayUpdate
Label bottom "\\Z16\\F'Symbol't(m\\F'Arial's)"
String name1= num2str(angle)+"SE"
Make $name1 = {q,B,D,R}
End
Function updateSingleExp(ctrl,ctrlVal,event): SliderControl
String ctrl
Variable ctrlVal,event
String xVals, tempFit
tempFit="tempFit"
Variable A,B
ControlInfo slideA; A=V_Value
ControlInfo slideB; B=V_Value
TitleBox valA, title=num2str(A)
TitleBox valB, title=num2str(B)
xVals = StringFromList(0,WaveList("*", ";","WIN:"))
if (exists(tempfit))
RemoveFromGraph tempFit
KillWaves tempFit
endif
Duplicate $xVals, $tempFit
Wave xs = $xVals
Wave fit = $tempFit
fit=A*exp(-2*B*xs)
Rename fit, tempfit
AppendToGraph fit vs xs
End
// Functions for fitting data to a single exponential function with a cumulant expansion and extracting relevant data
Function SingleExpWCum2()
Variable A,B,C
NewPanel /W=(100,100,540,330) as "Initial Guess for Fit"
TitleBox titleA, pos={5,5}, title="A=", frame=0
TitleBox titleB, pos={5,80}, title="B=", frame=0
TitleBox titleC, pos={5,155}, title="C=", frame=0
Slider slideA, limits={0,.5,0}, pos={5,20}, size={200,50}, vert=0, ticks=1, variable=A,
proc=updateSingleExpWCum
Slider slideB, limits={0,100000,0}, pos={5,95}, size={200,50}, vert=0, ticks=1, variable=B,
proc=updateSingleExpWCum
Slider slideC, limits={0,1000000000,0}, pos={5,170}, size={200,50}, vert=0, ticks=1, variable=C,
proc=updateSingleExpWCum
Button senAup, pos={210,20}, title="Up", proc=updateSingleExpWCumBut
Button senAdown, pos={210,40}, title="Down", proc=updateSingleExpWCumBut
Button senBup, pos={210,95}, title="Up",proc=updateSingleExpWCumBut
Button senBdown, pos={210,115}, title="Down", proc=updateSingleExpWCumBut
Button senCup, pos={210,170}, title="Up",proc=updateSingleExpWCumBut
Button senCdown, pos={210,190}, title="Down", proc=updateSingleExpWCumBut
TitleBox sens, pos={210,5}, title="Sensitivity", frame=0
TitleBox valA, pos={20,5}, title=num2str(A), frame=0
TitleBox valB, pos={20,80}, title=num2str(B), frame=0
TitleBox valC, pos={20,155}, title=num2str(C), frame=0
TitleBox titleVarian, pos={280,40}, title="Variance=", frame=0
TitleBox valVarian, pos={335,40}, title=num2str(C/B^2), frame=0
TitleBox equation, pos={280,5}, title="f(t)=A*exp(-B*t)*(1+C*t^2/2)", frame=0
Button start, pos={280,90}, size={100,50},proc=startSingleExpWCumFit, title="Start Fit"
End
Function updateSingleExpWCumBut(ctrl): ButtonControl
String ctrl
Variable maxv
if (cmpstr(ctrl,"senAup")==0)
ControlInfo slideA; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideA, limits={0,maxv*10,0}
endif
if (cmpstr(ctrl,"senAdown")==0)
ControlInfo slideA; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideA, limits={0,maxv/10,0}
endif
if (cmpstr(ctrl,"senBup")==0)
ControlInfo slideB; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideB, limits={0,maxv*10,0}
endif
if (cmpstr(ctrl,"senBdown")==0)
ControlInfo slideB; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideB, limits={0,maxv/10,0}
endif
if (cmpstr(ctrl,"senCup")==0)
ControlInfo slideC; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideC, limits={0,maxv*10,0}
endif
if (cmpstr(ctrl,"senCdown")==0)
ControlInfo slideC; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideC, limits={0,maxv/10,0}
endif
End
Function startSingleExpWCumFit(ctrl): ButtonControl
String ctrl
String tempFit
NVAR gT
if (!NVAR_Exists(gT))
setVars()
endif
tempFit="tempFit"
//single fit function
if(exists(tempFit))
RemoveFromGraph tempFit
KillWaves tempFit
endif
Variable angle
Prompt angle, "Detector Angle in Degrees: "
DoPrompt "Experimental Paramters", angle
String xw, yw
xw=StringFromList(0,WaveList("*", ";","WIN:"))
yw=StringFromList(1,WaveList("*", ";","WIN:"))
if (WaveExists(cwave))
KillWaves cwave
endif
Make/N=3 cwave
ControlInfo slideA; cwave[0]=V_Value
ControlInfo slideB; cwave[1]=V_Value
ControlInfo slideC; cwave[2]=V_Value
DoWindow /K $WinName(0,64)
FuncFit/Q/NTHR=0 SingleExpWCumMy cwave $yw /X=$xw /D
Variable A,B,C,varian,q,D,R
NVAR gWL
NVAR gRI
NVAR gT
NVAR gETA
A=cwave[0]
B=cwave[1]
C=cwave[2]
varian=C/B^2
q=4*Pi*gRI/(gWL*10^-9)*sin(angle*Pi/360)
D=B/q^2
R=1.3806503*10^-23/6/Pi/D*gT/gETA
String texty = num2str(angle)+"º\rD ="+num2str(D)+" m\S2\M/s\rR\\Bh\\M
="+num2str(1000000000*R)+" nm\r\\F'Symbol's\\F'Arial' ="+num2str(varian)
TextBox/C/N=text0/F=0/A=RT texty
//end single fit function
ModifyGraph mirror=2,fSize=12,axThick=1.5,prescaleExp(left)=3,prescaleExp(bottom)=6;DelayUpdate
Label left "\Z14\F'Symbol'G\S(2)\M\Z14(t) - 1";DelayUpdate
Label bottom "\\Z16\\F'Symbol't(m\\F'Arial's)"
String name1= num2str(angle)+"SEWC"
Make $name1 = {q,B,D,R}
End
Function updateSingleExpWCum(ctrl,ctrlVal,event): SliderControl
String ctrl
Variable ctrlVal,event
String xVals, tempFit
tempFit="tempFit"
Variable A,B,C
ControlInfo slideA; A=V_Value
ControlInfo slideB; B=V_Value
ControlInfo slideC; C=V_Value
TitleBox valA, title=num2str(A)
TitleBox valB, title=num2str(B)
TitleBox valC, title=num2str(C)
TitleBox valVarian, title=num2str(C/B^2)
xVals = StringFromList(0,WaveList("*", ";","WIN:"))
if (exists(tempfit))
RemoveFromGraph tempFit
KillWaves tempFit
endif
Duplicate $xVals, $tempFit
Wave xs = $xVals
Wave fit = $tempFit
fit=A*exp(-2*B*xs)*(1+C*xs^2/2)^2
Rename fit, tempfit
AppendToGraph fit vs xs
End
// Functions for fitting data to a single exponential function with cumulant expansion (G) and extracting relevant
data
Function SingleExpWCumG()
Variable A,B,C
NewPanel /W=(100,100,540,330) as "Initial Guess for Fit"
TitleBox titleA, pos={5,5}, title="A=", frame=0
TitleBox titleB, pos={5,80}, title="B=", frame=0
TitleBox titleC, pos={5,155}, title="C=", frame=0
Slider slideA, limits={0,.5,0}, pos={5,20}, size={200,50}, vert=0, ticks=1, variable=A,
proc=updateSingleExpWCumG
Slider slideB, limits={0,100000,0}, pos={5,95}, size={200,50}, vert=0, ticks=1, variable=B,
proc=updateSingleExpWCumG
Slider slideC, limits={0,1000000000,0}, pos={5,170}, size={200,50}, vert=0, ticks=1, variable=C,
proc=updateSingleExpWCumG
Button senAup, pos={210,20}, title="Up", proc=updateSingleExpWCumGBut
Button senAdown, pos={210,40}, title="Down", proc=updateSingleExpWCumGBut
Button senBup, pos={210,95}, title="Up",proc=updateSingleExpWCumGBut
Button senBdown, pos={210,115}, title="Down", proc=updateSingleExpWCumGBut
Button senCup, pos={210,170}, title="Up",proc=updateSingleExpWCumGBut
Button senCdown, pos={210,190}, title="Down", proc=updateSingleExpWCumGBut
TitleBox sens, pos={210,5}, title="Sensitivity", frame=0
TitleBox valA, pos={20,5}, title=num2str(A), frame=0
TitleBox valB, pos={20,80}, title=num2str(B), frame=0
TitleBox valC, pos={20,155}, title=num2str(C), frame=0
TitleBox titleVarian, pos={280,40}, title="Variance=", frame=0
TitleBox valVarian, pos={335,40}, title=num2str(C/B^2), frame=0
TitleBox equation, pos={280,5}, title="f(t)=A*exp(-2*B*t)*(1+C*t^2/2)^2", frame=0
Button start, pos={280,90}, size={100,50},proc=startSingleExpWCumGFit, title="Start Fit"
End
Function updateSingleExpWCumGBut(ctrl): ButtonControl
String ctrl
Variable maxv
if (cmpstr(ctrl,"senAup")==0)
ControlInfo slideA; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideA, limits={0,maxv*10,0}
endif
if (cmpstr(ctrl,"senAdown")==0)
ControlInfo slideA; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideA, limits={0,maxv/10,0}
endif
if (cmpstr(ctrl,"senBup")==0)
ControlInfo slideB; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideB, limits={0,maxv*10,0}
endif
if (cmpstr(ctrl,"senBdown")==0)
ControlInfo slideB; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideB, limits={0,maxv/10,0}
endif
if (cmpstr(ctrl,"senCup")==0)
ControlInfo slideC; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideC, limits={0,maxv*10,0}
endif
if (cmpstr(ctrl,"senCdown")==0)
ControlInfo slideC; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideC, limits={0,maxv/10,0}
endif
End
Function startSingleExpWCumGFit(ctrl): ButtonControl
String ctrl
String tempFit
NVAR gT
if (!NVAR_Exists(gT))
setVars()
endif
tempFit="tempFit"
//single fit function
if(exists(tempFit))
RemoveFromGraph tempFit
KillWaves tempFit
endif
Variable angle
Prompt angle, "Detector Angle in Degrees: "
DoPrompt "Experimental Paramters", angle
String xw, yw
xw=StringFromList(0,WaveList("*", ";","WIN:"))
yw=StringFromList(1,WaveList("*", ";","WIN:"))
if (WaveExists(cwave))
KillWaves cwave
endif
Make/N=3 cwave
ControlInfo slideA; cwave[0]=V_Value
ControlInfo slideB; cwave[1]=V_Value
ControlInfo slideC; cwave[2]=V_Value
DoWindow /K $WinName(0,64)
FuncFit/Q/NTHR=0 SingleExpWCumGMy cwave $yw /X=$xw /D
Variable A,B,C,varian,q,D,R
NVAR gWL
NVAR gRI
NVAR gT
NVAR gETA
A=cwave[0]
B=cwave[1]
C=cwave[2]
varian=C/B^2
q=4*Pi*gRI/(gWL*10^-9)*sin(angle*Pi/360)
D=B/q^2
R=1.3806503*10^-23/6/Pi/D*gT/gETA
String texty = num2str(angle)+"º\rD ="+num2str(D)+" m\S2\M/s\rR\\Bh\\M
="+num2str(1000000000*R)+" nm\r\\F'Symbol's\\F'Arial' ="+num2str(varian)
TextBox/C/N=text0/F=0/A=RT texty
//end single fit function
ModifyGraph mirror=2,fSize=12,axThick=1.5,prescaleExp(left)=3,prescaleExp(bottom)=6;DelayUpdate
Label left "\Z14\F'Symbol'G\S(2)\M\Z14(t) - 1";DelayUpdate
Label bottom "\\Z16\\F'Symbol't(m\\F'Arial's)"
String name1= num2str(angle)+"SEWCG"
Make $name1 = {q,B,D,R}
End
Function updateSingleExpWCumG(ctrl,ctrlVal,event): SliderControl
String ctrl
Variable ctrlVal,event
String xVals, tempFit
tempFit="tempFit"
Variable A,B,C
ControlInfo slideA; A=V_Value
ControlInfo slideB; B=V_Value
ControlInfo slideC; C=V_Value
TitleBox valA, title=num2str(A)
TitleBox valB, title=num2str(B)
TitleBox valC, title=num2str(C)
TitleBox valVarian, title=num2str(C/B^2)
xVals = StringFromList(0,WaveList("*", ";","WIN:"))
if (exists(tempfit))
RemoveFromGraph tempFit
KillWaves tempFit
endif
Duplicate $xVals, $tempFit
Wave xs = $xVals
Wave fit = $tempFit
fit=A*exp(-B*xs)*(1+C*xs^2/2)
Rename fit, tempfit
AppendToGraph fit vs xs
End
// Functions for fitting data to a double exponential function and extracting relevant data
Function DoubleExp2()
Variable A1,B1,A2,B2
NewPanel /W=(100,100,640,320) as "Initial Guess for Fit"
TitleBox titleA1, pos={5,5}, title="A1=", frame=0
TitleBox titleB1, pos={5,80}, title="B1=", frame=0
TitleBox titleA2, pos={265,5}, title="A2=", frame=0
TitleBox titleB2, pos={265,80}, title="B2=", frame=0
Slider slideA1, limits={0,.5,0}, pos={5,20}, size={200,50}, vert=0, ticks=1, variable=A1,
proc=updateDoubleExp
Slider slideB1, limits={0,100000,0}, pos={5,95}, size={200,50}, vert=0, ticks=1, variable=B1,
proc=updateDoubleExp
Slider slideA2, limits={0,.5,0}, pos={265,20}, size={200,50}, vert=0, ticks=1, variable=A2,
proc=updateDoubleExp
Slider slideB2, limits={0,10000,0}, pos={265,95}, size={200,50}, vert=0, ticks=1, variable=B2,
proc=updateDoubleExp
Button senA1up, pos={210,20}, title="Up", proc=updateDoubleExpBut
Button senA1down, pos={210,40}, title="Down", proc=updateDoubleExpBut
Button senB1up, pos={210,95}, title="Up",proc=updateDoubleExpBut
Button senB1down, pos={210,115}, title="Down", proc=updateDoubleExpBut
Button senA2up, pos={475,20}, title="Up", proc=updateDoubleExpBut
Button senA2down, pos={475,40}, title="Down", proc=updateDoubleExpBut
Button senB2up, pos={475,95}, title="Up",proc=updateDoubleExpBut
Button senB2down, pos={475,115}, title="Down", proc=updateDoubleExpBut
TitleBox sens1, pos={210,5}, title="Sensitivity", frame=0
TitleBox sens2, pos={475,5}, title="Sensitivity", frame=0
TitleBox valA1, pos={25,5}, title=num2str(A1), frame=0
TitleBox valB1, pos={25,80}, title=num2str(B1), frame=0
TitleBox valA2, pos={285,5}, title=num2str(A2), frame=0
TitleBox valB2, pos={285,80}, title=num2str(B2), frame=0
TitleBox equation, pos={120,170},title="f(t)=(A1*exp(-B1*t)+A2*exp(-B2*t))^2", frame=0
Button start, pos={5,157}, size={100,50},proc=startDoubleExpFit, title="Start Fit"
End
Function updateDoubleExpBut(ctrl): ButtonControl
String ctrl
Variable maxv
if (cmpstr(ctrl,"senA1up")==0)
ControlInfo slideA1; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideA1, limits={0,maxv*10,0}
endif
if (cmpstr(ctrl,"senA1down")==0)
ControlInfo slideA1; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideA1, limits={0,maxv/10,0}
endif
if (cmpstr(ctrl,"senB1up")==0)
ControlInfo slideB1; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideB1, limits={0,maxv*10,0}
endif
if (cmpstr(ctrl,"senB1down")==0)
ControlInfo slideB1; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideB1, limits={0,maxv/10,0}
endif
if (cmpstr(ctrl,"senA2up")==0)
ControlInfo slideA2; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideA2, limits={0,maxv*10,0}
endif
if (cmpstr(ctrl,"senA2down")==0)
ControlInfo slideA2; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideA2, limits={0,maxv/10,0}
endif
if (cmpstr(ctrl,"senB2up")==0)
ControlInfo slideB2; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideB2, limits={0,maxv*10,0}
endif
if (cmpstr(ctrl,"senB2down")==0)
ControlInfo slideB2; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideB2, limits={0,maxv/10,0}
endif
End
Function startDoubleExpFit(ctrl): ButtonControl
String ctrl
String tempFit
NVAR gT
if (!NVAR_Exists(gT))
setVars()
endif
tempFit="tempFit"
//single fit function
if(exists(tempFit))
RemoveFromGraph tempFit
KillWaves tempFit
endif
Variable angle
Prompt angle, "Detector Angle in Degrees: "
DoPrompt "Experimental Paramters", angle
String xw, yw
xw=StringFromList(0,WaveList("*", ";","WIN:"))
yw=StringFromList(1,WaveList("*", ";","WIN:"))
if (WaveExists(cwave))
KillWaves cwave
endif
Make/N=4 cwave
ControlInfo slideA1; cwave[0]=V_Value
ControlInfo slideB1; cwave[1]=V_Value
ControlInfo slideA2; cwave[2]=V_Value
ControlInfo slideB2; cwave[3]=V_Value
DoWindow /K $WinName(0,64)
FuncFit/Q/NTHR=0 DoubleExpMy cwave $yw /X=$xw /D
Variable A1,B1,A2,B2,q,D1,R1,D2,R2
NVAR gWL
NVAR gRI
NVAR gT
NVAR gETA
A1=cwave[0]
B1=cwave[1]
A1=cwave[2]
B2=cwave[3]
q=4*Pi*gRI/(gWL*10^-9)*sin(angle*Pi/360)
D1=B1/q^2
R1=1.3806503*10^-23/6/Pi/D1*gT/gETA
D2=B2/q^2
R2=1.3806503*10^-23/6/Pi/D2*gT/gETA
String texty = num2str(angle)+"º\r\rD1 ="+num2str(D1)+" m\S2\M/s\rR\\Bh\\M1
="+num2str(1000000000*R1)+" nm\r\rD2 ="+num2str(D2)+" m\S2\M/s\rR\\Bh\\M2
="+num2str(1000000000*R2)+"nm"
TextBox/C/N=text0/F=0/A=RT texty
//end single fit function
ModifyGraph mirror=2,fSize=12,axThick=1.5,prescaleExp(left)=3,prescaleExp(bottom)=6;DelayUpdate
Label left "\Z14\F'Symbol'G\S(2)\M\Z14(t) - 1";DelayUpdate
Label bottom "\\Z16\\F'Symbol't(m\\F'Arial's)"
String name1= num2str(angle)+"DE"
Make $name1 = {q,B1,D1,R1,B2,D2,R2}
End
Function updateDoubleExp(ctrl,ctrlVal,event): SliderControl
String ctrl
Variable ctrlVal,event
String xVals, tempFit
tempFit="tempFit"
Variable A1,B1,A2,B2
ControlInfo slideA1; A1=V_Value
ControlInfo slideB1; B1=V_Value
ControlInfo slideA2; A2=V_Value
ControlInfo slideB2; B2=V_Value
TitleBox valA1, title=num2str(A1)
TitleBox valB1, title=num2str(B1)
TitleBox valA2, title=num2str(A2)
TitleBox valB2, title=num2str(B2)
xVals = StringFromList(0,WaveList("*", ";","WIN:"))
if (exists(tempfit))
RemoveFromGraph tempFit
KillWaves tempFit
endif
Duplicate $xVals, $tempFit
Wave xs = $xVals
Wave fit = $tempFit
fit=(A1*exp(-B1*xs)+A2*exp(-B2*xs))^2
Rename fit, tempfit
AppendToGraph fit vs xs
End
// Functions for fitting data to a double exponential function with cumulant expansions and extracting relevant data
Function DoubleExpWCum2()
Variable A1,B1,C1,A2,B2,C2
NewPanel /W=(100,100,640,400) as "Initial Guess for Fit"
TitleBox titleA1, pos={5,5}, title="A1=", frame=0
TitleBox titleB1, pos={5,80}, title="B1=", frame=0
TitleBox titleC1, pos={5,156}, title="C1=", frame=0
Slider slideA1, limits={0,.5,0}, pos={5,20}, size={200,50}, vert=0, ticks=1, variable=A1,
proc=updateDoubleExpWCum
Slider slideB1, limits={0,100000,0}, pos={5,95}, size={200,50}, vert=0, ticks=1, variable=B1,
proc=updateDoubleExpWCum
Slider slideC1, limits={0,1000000000,0}, pos={5,170}, size={200,50}, vert=0, ticks=1, variable=C1,
proc=updateDoubleExpWCum
Button senA1up, pos={210,20}, title="Up", proc=updateDoubleExpWCumBut
Button senA1down, pos={210,40}, title="Down", proc=updateDoubleExpWCumBut
Button senB1up, pos={210,95}, title="Up",proc=updateDoubleExpWCumBut
Button senB1down, pos={210,115}, title="Down", proc=updateDoubleExpWCumBut
Button senC1up, pos={210,170}, title="Up",proc=updateDoubleExpWCumBut
Button senC1down, pos={210,190}, title="Down", proc=updateDoubleExpWCumBut
TitleBox sens1, pos={210,5}, title="Sensitivity", frame=0
TitleBox valA1, pos={25,5}, title=num2str(A1), frame=0
TitleBox valB1, pos={25,80}, title=num2str(B1), frame=0
TitleBox valC1, pos={25,156}, title=num2str(C1), frame=0
TitleBox titleVarian1, pos={120,230}, title="Variance1=", frame=0
TitleBox valVarian1, pos={175,230}, title=num2str(C1/B1^2), frame=0
TitleBox titleA2, pos={265,5}, title="A2=", frame=0
TitleBox titleB2, pos={265,80}, title="B2=", frame=0
TitleBox titleC2, pos={265,156}, title="C2=", frame=0
Slider slideA2, limits={0,.5,0}, pos={265,20}, size={200,50}, vert=0, ticks=1, variable=A2,
proc=updateDoubleExpWCum
Slider slideB2, limits={0,100000,0}, pos={265,95}, size={200,50}, vert=0, ticks=1, variable=B2,
proc=updateDoubleExpWCum
Slider slideC2, limits={0,1000000000,0}, pos={265,170}, size={200,50}, vert=0, ticks=1, variable=C2,
proc=updateDoubleExpWCum
Button senA2up, pos={475,20}, title="Up", proc=updateDoubleExpWCumBut
Button senA2down, pos={475,40}, title="Down", proc=updateDoubleExpWCumBut
Button senB2up, pos={475,95}, title="Up",proc=updateDoubleExpWCumBut
Button senB2down, pos={475,115}, title="Down", proc=updateDoubleExpWCumBut
Button senC2up, pos={475,170}, title="Up",proc=updateDoubleExpWCumBut
Button senC2down, pos={475,190}, title="Down", proc=updateDoubleExpWCumBut
TitleBox sens2, pos={475,5}, title="Sensitivity", frame=0
TitleBox valA2, pos={285,5}, title=num2str(A2), frame=0
TitleBox valB2, pos={285,80}, title=num2str(B2), frame=0
TitleBox valC2, pos={285,156}, title=num2str(C2), frame=0
TitleBox titleVarian2, pos={340,230}, title="Variance2=", frame=0
TitleBox valVarian2, pos={395,230}, title=num2str(C2/B2^2), frame=0
TitleBox equation, pos={120,260}, title="f(t)=(A1*exp(-B1*t)*(1+C1*t^2/2)+A2*exp(-
B2*t)*(1+C2*t^2/2))^2", frame=0
Button start, pos={5,230}, size={100,50},proc=startDoubleExpWCumFit, title="Start Fit"
End
Function updateDoubleExpWCumBut(ctrl): ButtonControl
String ctrl
Variable maxv
if (cmpstr(ctrl,"senA1up")==0)
ControlInfo slideA1; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideA1, limits={0,maxv*10,0}
endif
if (cmpstr(ctrl,"senA1down")==0)
ControlInfo slideA1; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideA1, limits={0,maxv/10,0}
endif
if (cmpstr(ctrl,"senB1up")==0)
ControlInfo slideB1; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideB1, limits={0,maxv*10,0}
endif
if (cmpstr(ctrl,"senB1down")==0)
ControlInfo slideB1; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideB1, limits={0,maxv/10,0}
endif
if (cmpstr(ctrl,"senC1up")==0)
ControlInfo slideC1; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideC1, limits={0,maxv*10,0}
endif
if (cmpstr(ctrl,"senC1down")==0)
ControlInfo slideC1; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideC1, limits={0,maxv/10,0}
endif
if (cmpstr(ctrl,"senA2up")==0)
ControlInfo slideA2; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideA2, limits={0,maxv*10,0}
endif
if (cmpstr(ctrl,"senA2down")==0)
ControlInfo slideA2; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideA2, limits={0,maxv/10,0}
endif
if (cmpstr(ctrl,"senB2up")==0)
ControlInfo slideB2; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideB2, limits={0,maxv*10,0}
endif
if (cmpstr(ctrl,"senB2down")==0)
ControlInfo slideB2; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideB2, limits={0,maxv/10,0}
endif
if (cmpstr(ctrl,"senC2up")==0)
ControlInfo slideC2; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideC2, limits={0,maxv*10,0}
endif
if (cmpstr(ctrl,"senC2down")==0)
ControlInfo slideC2; maxv=V_Value
if(maxv==0)
maxv=1
endif
Slider slideC2, limits={0,maxv/10,0}
endif
End
Function startDoubleExpWCumFit(ctrl): ButtonControl
String ctrl
String tempFit
NVAR gT
if (!NVAR_Exists(gT))
setVars()
endif
tempFit="tempFit"
//single fit function
if(exists(tempFit))
RemoveFromGraph tempFit
KillWaves tempFit
endif
Variable angle,A1,B1,C1,A2,B2,C2,varian1,varian2,q,D1,D2,R1,R2
NVAR gWL
NVAR gRI
NVAR gT
NVAR gETA
Prompt angle, "Detector Angle in Degrees: "
DoPrompt "Experimental Paramters", angle
String xw, yw
xw=StringFromList(0,WaveList("*", ";","WIN:"))
yw=StringFromList(1,WaveList("*", ";","WIN:"))
if (WaveExists(cwave))
KillWaves cwave
endif
Make/N=6 cwave
ControlInfo slideA1; cwave[0]=V_Value
ControlInfo slideB1; cwave[1]=V_Value
ControlInfo slideC1; cwave[2]=V_Value
ControlInfo slideA2; cwave[3]=V_Value
ControlInfo slideB2; cwave[4]=V_Value
ControlInfo slideC2; cwave[5]=V_Value
DoWindow /K $WinName(0,64)
FuncFit/Q/NTHR=0 DoubleExpWCumMy cwave $yw /X=$xw /D
A1=cwave[0]
B1=cwave[1]
C1=cwave[2]
A2=cwave[3]
B2=cwave[4]
C2=cwave[5]
varian1=C1/B1^2
varian2=C2/B2^2
q=4*Pi*gRI/(gWL*10^-9)*sin(angle*Pi/360)
D1=B1/q^2
R1=1.3806503*10^-23/6/Pi/D1*gT/gETA
D2=B2/q^2
R2=1.3806503*10^-23/6/Pi/D2*gT/gETA
String texty = num2str(angle)+"º\r\rD1 ="+num2str(D1)+" m\S2\M/s\rR\\Bh\\M1
="+num2str(1000000000*R1)+" nm\r\\F'Symbol's\\F'Arial'1 ="+num2str(varian1)+"\r\rD2 ="+num2str(D2)+"
m\S2\M/s\rR\\Bh\\M2 ="+num2str(1000000000*R2)+" nm\r\\F'Symbol's\\F'Arial'2 ="+num2str(varian2)
TextBox/C/N=text0/F=0/A=RT texty
//end single fit function
ModifyGraph mirror=2,fSize=12,axThick=1.5,prescaleExp(left)=3,prescaleExp(bottom)=6;DelayUpdate
Label left "\Z14\F'Symbol'G\S(2)\M\Z14(t) - 1";DelayUpdate
Label bottom "\\Z16\\F'Symbol't(m\\F'Arial's)"
String name1= num2str(angle)+"DEWC"
Make $name1 = {q,B1,D1,R1,B2,D2,R2}
End
Function updateDoubleExpWCum(ctrl,ctrlVal,event): SliderControl
String ctrl
Variable ctrlVal,event
String xVals, tempFit
tempFit="tempFit"
Variable A1,B1,C1,A2,B2,C2
ControlInfo slideA1; A1=V_Value
ControlInfo slideB1; B1=V_Value
ControlInfo slideC1; C1=V_Value
ControlInfo slideA2; A2=V_Value
ControlInfo slideB2; B2=V_Value
ControlInfo slideC2; C2=V_Value
TitleBox valA1, title=num2str(A1)
TitleBox valB1, title=num2str(B1)
TitleBox valC1, title=num2str(C1)
TitleBox valA2, title=num2str(A2)
TitleBox valB2, title=num2str(B2)
TitleBox valC2, title=num2str(C2)
TitleBox valVarian1, title=num2str(C1/B1^2)
TitleBox valVarian2, title=num2str(C2/B2^2)
xVals = StringFromList(0,WaveList("*", ";","WIN:"))
if (exists(tempfit))
RemoveFromGraph tempFit
KillWaves tempFit
endif
Duplicate $xVals, $tempFit
Wave xs = $xVals
Wave fit = $tempFit
fit=(A1*exp(-B1*xs)*(1+C1*xs^2/2)+A2*exp(-B2*xs)*(1+C2*xs^2/2))^2
Rename fit, tempfit
AppendToGraph fit vs xs
End
// Functions for combining data from different angles for further data analysis
Function multipleAnglePlot()
NewPanel /W=(100,100,260,190) as "Mulit-Angle Plot"
TitleBox info1, pos={5,5}, title="Open files and fit all", frame=0
TitleBox info2, pos={5,30}, title="Press Start when ready", frame=0
Button start, pos={55,55}, size={60,20}, title="Start", proc=createPlot
End
Function createPlot(ctrl): ButtonControl
String ctrl
NVAR gT
if (!NVAR_Exists(gT))
setVars()
endif
String wave1,wave2,wave3,wave4,wave5
Variable number=5
Prompt wave1, "Angle1:", popup, WaveList("*",";","")
Prompt wave2, "Angle2:", popup, WaveList("*",";","")
Prompt wave3, "Angle3:", popup, WaveList("*",";","")+";_none_"
Prompt wave4, "Angle4:", popup, WaveList("*",";","")+";_none_"
Prompt wave5, "Angle5:", popup, WaveList("*",";","")+";_none_"
Variable type=0
DoPrompt "Select angles", wave1, wave2, wave3, wave4, wave5
if(cmpstr(wave5,"_none_")==0)
number=4
endif
if(cmpstr(wave4,"_none_")==0)
number=3
endif
if(cmpstr(wave3,"_none_")==0)
number=2
endif
Wave w1 = $wave1
Wave w2 = $wave2
if(number>2)
Wave w3 = $wave3
endif
if(number>3)
Wave w4 = $wave4
endif
if(number>4)
Wave w5 = $wave5
endif
if(numpnts(w1)>5)
type=1
endif
if(exists("qs"))
KillWaves qs,bs,q2
endif
Make /N=(number) qs, bs, q2
qs[0]=w1[0]
bs[0]=w1[1]
qs[1]=w2[0]
bs[1]=w2[1]
if(number>2)
qs[2]=w3[0]
bs[2]=w3[1]
endif
if(number>3)
qs[3]=w4[0]
bs[3]=w4[1]
endif
if(number>4)
qs[4]=w5[0]
bs[4]=w5[1]
endif
q2=qs^2
if(exists("qs2"))
KillWaves qs2,bs2,q22
endif
if(type==1)
Make/N=(number) qs2,bs2, q22
qs2[0]=w1[0]
bs2[0]=w1[4]
qs2[1]=w2[0]
bs2[1]=w2[4]
if(number>2)
qs2[2]=w3[0]
bs2[2]=w3[4]
endif
if(number>3)
qs2[3]=w4[0]
bs2[3]=w4[4]
endif
if(number>4)
qs2[4]=w5[0]
bs2[4]=w5[4]
endif
q22=qs2^2
endif
Display/K=1
AppendToGraph bs vs q2
if(type==1)
AppendToGraph bs2 vs q22
endif
if(exists("coefs"))
KillWaves coefs,fit_bs
endif
if(exists("coefs2"))
KillWaves coefs2,fit_bs2
endif
Make coefs={1}
if(exists("W_sigma"))
KillWaves W_sigma
endif
Make/N=1 W_sigma
NVAR gT
NVAR gETA
Variable D,R,sig,sigr
FuncFit/Q LineThroughZero kwCWave=coefs bs /X=q2 /D
sig=W_sigma[0]
D=coefs[0]
R=1.3806503*10^-23/6/Pi/D*gT/gETA
sigr=sig/D*R
NVAR gT
String texty="T= "+num2str(gT)+"\ry="+num2str(coefs[0])+"*x\rD= "+num2str(D)+" ± "+num2str(sig)+"
m\S2\M/s\rR\\Bh\\M ="+num2str(1000000000*R)+" ± "+num2str(1000000000*sigr)+" nm"
if(type==1)
Make coefs2={1}
Variable D2,R2,sig2,sigr2
FuncFit/Q LineThroughZero kwCWave=coefs2 bs2 /X=q22 /D
sig2=W_sigma[0]
D2=coefs2[0]
R2=1.3806503*10^-23/6/Pi/D2*gT/gETA
sigr2=sig2/D2*R2
String texty2="y2="+num2str(coefs2[0])+"*x\rD2= "+num2str(D2)+" ± "+num2str(sig2)+"
m\S2\M/s\rR\\Bh\\M2 ="+num2str(1000000000*R2)+" ± "+num2str(1000000000*sigr2)+" nm"
texty+="\r\r"
texty+=texty2
endif
TextBox/C/A=RB/N=text1/F=0 texty
Label left "\\Z14\\F'Symbol'G\\F'Arial'(s\\S-1\\M)"
Label bottom "\Z14q\S2\M\Z14(m\S-2\M\Z14)"
ModifyGraph mirror=2,fSize=12,axThick=1.5
ModifyGraph mode=3,mrkThick=1
ModifyGraph mrkThick=1.5
ModifyGraph mode(fit_bs)=0
if(type==1)
ModifyGraph mode(fit_bs2)=0
endif
DoWindow /K $WinName(0,64)
Print sig,sig2
End
Rheology
#pragma rtGlobals=1 // Use modern global access method.
// Rheology by AKS, 20130204
// This procedure works with data sets generated from a dynamic frequency temperature sweep test on an ARES
rheometer
// This proceudre was developed by Adam K. Schmitt
Menu "Tools"
Submenu "Rheology"
"Load TTS, Shift, and Plot", TTSfull()
"Update Shifts", applyShifts()
"Plot Master Curve", plotMaster()
"Plot Shift Factors", plotShifts()
End
End
Function TTSfull()
loadTTS()
tempSep()
TTSShift()
plotMasterG1()
End
// Function to load the unshifted rheological data from a dynamic frequency temperature sweep test
Function loadTTS()
// Load the unshifted rheological data
String null="", name1
LoadWave/J/D/W/A/Q/K=0/L={0,27,0,0,5} /P=$null null
null=S_fileName
// Get new, more better file name
Prompt name1, "Select base name of "+null
DoPrompt "Enter Name", name1
//Make new names and rename loaded waves
String first=name1+"_FreqOrig", second=name1+"_G1Orig", third=name1+"_G2Orig",
fourth=name1+"_TanDOrig", fifth=name1+"_TempOrig"
Rename $StringFromList(0,S_waveNames), $first
Rename $StringFromList(1,S_waveNames), $second
Rename $StringFromList(2,S_waveNames), $third
Rename $StringFromList(3,S_waveNames), $fourth
Rename $StringFromList(4,S_waveNames), $fifth
String/G base=name1
End
// This function separates the data into isothermal frequency sweeps
Function tempSep()
SVAR base=base
String first=base+"_FreqOrig", second=base+"_G1Orig", third=base+"_G2Orig",
fourth=base+"_TanDOrig", fifth=base+"_TempOrig"
Wave freqs=$first
Wave G1s=$second
Wave G2s=$third
Wave TanDs=$fourth
Wave temps=$fifth
//Count how many freqs are in each scan
Variable freq1=freqs[0], i=1, numfreqs, j,k
do
if(freqs[i]==freq1)
numfreqs=i
break
endif
i+=1
while(1)
temps=round(temps)
i=0
do
j=0
String temp=base+"_"+num2str(temps[i]), curFreq=temp+"_Freq", curG1=temp+"_G1",
curG2=temp+"_G2", CurTD=temp+"_TanD", curTemp=temp+"_Temp"
String curFreq2=curFreq+"shifted", curG12=curG1+"shifted", curG22=curG2+"shifted",
CurTD2=curTD+"shifted", curTemp2=curTemp+"shifted"
Make/N=(numfreqs) $curFreq, $curG1, $curG2, $curTD, $curTemp, $curFreq2, $curG12,
$curG22, $curTD2, $curTemp2
Wave cfreq=$curFreq
Wave cfreq2=$curFreq2
Wave cg1=$curG1
Wave cg12=$curG12
Wave cg2=$curG2
Wave cg22=$curG22
Wave ctd=$curTD
Wave ctd2=$curTD2
Wave ctemp=$curTemp
Wave ctemp2=$curTemp2
do
cfreq[j]=freqs[i+j]
cg1[j]=G1s[i+j]
cg2[j]=G2s[i+j]
ctd[j]=TanDs[i+j]
ctemp[j]=temps[i+j]
cfreq2[j]=freqs[i+j]
cg12[j]=G1s[i+j]
cg22[j]=G2s[i+j]
ctd2[j]=TanDs[i+j]
ctemp2[j]=temps[i+j]
j+=1
while(j<numfreqs)
i+=numfreqs
while(i<numpnts(temps))
End
// This function loads the shift factors and shifts the data using applyShifts()
Function TTSshift()
SVAR base=base
String null="", curtemp
LoadWave/J/D/W/A/Q/K=0/L={0,19,0,0,3} /P=$null null
String first=base+"_Temps", second=base+"_As", third=base+"_Bs"
Rename $StringFromList(0,S_waveNames), $first
Rename $StringFromList(1,S_waveNames), $second
Rename $StringFromList(2,S_waveNames), $third
Wave temps=$first
Wave as=$second
Wave bs=$third
temps=round(temps)
Edit/K=1 $first, $second, $third
applyShifts()
End
// This functino shifts the data using the leaded shift factors
Function applyShifts()
SVAR base=base
String first=base+"_Temps", second=base+"_As", third=base+"_Bs",curtemp
Wave temps=$first
Wave as=$second
Wave bs=$third
Variable i=0
do
curtemp=num2str(temps[i])
Wave cfr=$(base+"_"+curtemp+"_Freq")
Wave cg1=$(base+"_"+curtemp+"_G1")
Wave cg2=$(base+"_"+curtemp+"_G2")
Wave cfr2=$(base+"_"+curtemp+"_Freqshifted")
Wave cg12=$(base+"_"+curtemp+"_G1shifted")
Wave cg22=$(base+"_"+curtemp+"_G2shifted")
cfr2=as[i]*cfr
cg12=bs[i]*cg1
cg22=bs[i]*cg2
i+=1
while(i<numpnts(temps))
End
// This function plots the storage modulus of the master curve (full shifted data set)
Function plotMasterG1()
SVAR base=base
String xs=WaveList("*Freqshifted",";","")
String ys=WaveList("*G1shifted",";","")
Display/K=1
Variable i=0
do
String x=StringFromList(i,xs), y=StringFromList(i,ys)
if(strlen(x)==0)
break
endif
AppendToGraph $y vs $x
i+=1
while(1)
ModifyGraph mode=2,lsize=2
ModifyGraph log=1,tick=2,mirror=1,fStyle=1,fSize=12,axThick=1.5;DelayUpdate
ModifyGraph lblMargin(left)=10,standoff=0;DelayUpdate
Label left "\\Z12\\f01Storgae Modulus (Pa)";DelayUpdate
Label bottom "\\Z12\\f01Shifted Frequency (Hz)"
End
// This function plots the loss modulus of the master curve (full shifted data set)
Function plotMasterG2()
SVAR base=base
String xs=WaveList("*Freqshifted",";","")
String ys=WaveList("*G2shifted",";","")
Display/K=1
Variable i=0
do
String x=StringFromList(i,xs), y=StringFromList(i,ys)
if(strlen(x)==0)
break
endif
AppendToGraph $y vs $x
i+=1
while(1)
ModifyGraph mode=2,lsize=2
ModifyGraph rgb=(0,0,65280)
ModifyGraph log=1,tick=2,mirror=1,fStyle=1,fSize=12,axThick=1.5;DelayUpdate
ModifyGraph lblMargin(left)=10,standoff=0;DelayUpdate
Label left "\\Z12\\f01Loss Modulus (Pa)";DelayUpdate
Label bottom "\\Z12\\f01Shifted Frequency (Hz)"
End
// This function plots the storage and loss moduli of the master curve (full shifted data set)
Function plotMasterBoth()
SVAR base=base
String xs=WaveList("*Freqshifted",";","")
String ys1=WaveList("*G1shifted",";","")
String ys2=WaveList("*G2shifted",";","")
Display/K=1
Variable i=0
do
String x=StringFromList(i,xs), y1=StringFromList(i,ys1), y2=StringFromList(i,ys2)
if(strlen(x)==0)
break
endif
AppendToGraph $y1 vs $x
AppendToGraph $y2 vs $x
ModifyGraph rgb($y2)=(0,0,65280)
i+=1
while(1)
ModifyGraph mode=2,lsize=2
ModifyGraph log=1,tick=2,mirror=1,fStyle=1,fSize=12,axThick=1.5;DelayUpdate
ModifyGraph lblMargin(left)=10,standoff=0;DelayUpdate
Label left "\\Z12\\f01Modulus (Pa)";DelayUpdate
Label bottom "\\Z12\\f01Shifted Frequency (Hz)"
End
// This function plots the master curve (full shifted data) in any form
Function plotMaster()
String choice=""
Prompt choice, "What to Plot", popup, "Storage Modulus;Loss Modulus;Storage and Loss"
DoPrompt "Plot Options", choice
if(stringmatch(choice,"Storage Modulus"))
plotMasterG1()
endif
if(stringmatch(choice,"Loss Modulus"))
plotMasterG2()
endif
if(stringmatch(choice,"Storage and Loss"))
plotMasterBoth()
endif
End
// This function plots the shift factors in the typical manner
Function plotShifts()
SVAR base=base
String t=base+"_Temps", a=base+"_As", b=base+"_Bs"
Display/K=1 $a vs $t
AppendToGraph/R/C=(0,0,65280) $b vs $t
ModifyGraph log(left)=1,tick=2,mirror(bottom)=2,fStyle=1,fSize=12,axThick=1.5;DelayUpdate
ModifyGraph standoff=0;DelayUpdate
Label left "\\Z12\\f01Horizontal Shift";DelayUpdate
Label bottom "\\Z12\\f01Temperature";DelayUpdate
Label right "\\Z12\\f01Vertical Shift";DelayUpdate
SetAxis right 0,1
ModifyGraph lsize=2
End
Sec5Tools
#pragma rtGlobals=1 // Use modern global access method.
// Sec5Tools by AKS, 20130204
// This procedure works with data sets generated at 5-ID-D at the Advanced Photon Source at Argonne National
Labs
// This proceudre was developed by Adam K. Schmitt
Menu "Tools"
Submenu "SAXS"
Submenu "Sector 5"
"Sector 5 Tools", APSTools()
End
"-",
End
End
Function/S GetLeafName(pathStr)
String pathStr
String leafName
Variable pos
leafName = ""
pos = strlen(pathStr) - 1 // Search from the
end
do
if (CmpStr(pathStr[pos], ":") == 0) // Found the colon?
leafName = pathStr[pos+1, strlen(pathStr)]
break
// Break out of loop.
endif
pos -= 1
while(pos > 0)
return leafName
End
Function APSLoadDir(pathName)
String pathName
String fileName
Variable index=0
if (strlen(pathName)==0) // If no path specified, create one
NewPath/O temporaryPath // This will put up a dialog
if (V_flag != 0)
return -1 // User cancelled
endif
pathName = "temporaryPath"
endif
do // Loop through each file in folder
fileName = IndexedFile($pathName, index, ".txt")
if (strlen(fileName) == 0) // No more files?
break // Break
out of loop
endif
// Load files section
// This section extracts the user initials, data type, and frames (exposures) from the file name
String expr="([[:alpha:]]+)[_]([[:alpha:]]+)[_]([[:digit:]]+)[_]([[:digit:]]+)([[:alpha:]]+)([[:digit:]]+)"
String inits, type, scan, frame1, to, frame2
SplitString/E=expr (fileName), inits, type, scan, frame1, to, frame2
if(V_flag==6)
if(stringmatch(type,"saxs")==1)
APSLoad(pathName,fileName)
endif
endif
if(V_flag==0)
expr="([[:alpha:]]+)[_]([[:alpha:]]+)[_]([[:digit:]]+)[_]"
SplitString/E=expr (fileName), inits, type, scan
Wave scans=root:APS:Info:ScanNo
Wave frames=root:APS:Info:Frames
Variable scan2=str2num(scan)
Variable i=0
Variable frame
do
if(scans[i]==scan2)
frame=frames[i]
break
endif
i=i+1
while(i<numpnts(scans))
if(frame==1)
if(stringmatch(type,"saxs")==1)
APSLoad(pathName, fileName)
endif
endif
endif
//End load files section
index += 1
while (1)
if (Exists("temporaryPath")) // Kill temp path if it exists
KillPath temporaryPath
endif
return 0 // Signifies success.
End
Function APSLoad(pathName, fileName)
String pathName // Name of an existing IGOR symbolic path or ""
String fileName // Name of file within folder pointed to by symbolic path or ""
SetDataFolder root:APS
// If either of the input parameters is "", put up a dialog to get file.
if ((strlen(pathName)==0) %| (strlen(pathName)==0))
Variable dummyRefNum
String pathToFolder
Open/R/D/M="Choose data file" dummyRefNum // This sets an automatically created
local variable named S_fileName.
if (strlen(S_fileName) == 0) // User cancelled?
return -1
endif
// Now break the full path to file down into path to folder plus file name.
// This is done by searching for the last colon in the full path.
fileName =GetLeafName(S_fileName)
if (strlen(fileName) == 0)
Print "LoadDataSetFromFile bug"
return -1
endif
pathToFolder = S_fileName[0, strlen(S_fileName) - strlen(fileName) - 1]
// Make sure there is an IGOR symbolic path pointing to the folder
NewPath/O/Q CurrentDataFilePath pathToFolder
pathName = "CurrentDataFilePath"
endif
//Find beginning of data
LoadWave/J/D/K=0/L={0,0,0,0,1}/B="N=finder;"/P=$pathName/W/A fileName
String finder="finder"
Wave/T find=finder
Variable i=0
Variable datastart=-1
do
if(strsearch(find[i],"#",0)==-1)
datastart=i
break
endif
i=i+1
while(i<numpnts(find))
KillWaves find
//Print datastart Prints starting line of data, end of header
String expr="([[:alpha:]]+)[_]([[:alpha:]]+)[_]([[:digit:]]+)[_]"
String inits, type, scan
SplitString/E=expr (fileName), inits, type, scan
Wave scans=root:APS:Info:ScanNo
Wave/T sams=root:APS:Info:Sample
Wave temps=root:APS:Info:Temp
Variable scan2=str2num(scan)
i=0
String sample
Variable temp
do
if(scans[i]==scan2)
temp=temps[i]
sample=sams[i]
break
endif
i=i+1
while(i<numpnts(scans))
NewDataFolder/O/S $sample
String tempst=num2str(temp)+"C"+scan
String
columninfo="N='_skip_';N=q"+tempst+";N=i"+tempst+";N=ie"+tempst+";C=2,N='_skip_';N=iqs"+tempst+";C=15,
N='_skip_';"
LoadWave/A/B=columninfo/D/J/K=0/L={datastart,datastart+1,0,0,0}/P=$pathName/W fileName
End
//Load info file to parse scan number info from (sample name, temperature, frames)
Function getInfoFile(pathName, fileName)
String pathName, fileName
SetDataFolder root:APS
// If either of the input parameters is "", put up a dialog to get file.
if ((strlen(pathName)==0) %| (strlen(pathName)==0))
Variable dummyRefNum
String pathToFolder
Open/R/D/M="Choose data file" dummyRefNum // This sets an automatically created
local variable named S_fileName.
if (strlen(S_fileName) == 0) // User cancelled?
return -1
endif
// Now break the full path to file down into path to folder plus file name.
// This is done by searching for the last colon in the full path.
fileName = GetLeafName(S_fileName)
if (strlen(fileName) == 0)
Print "LoadDataSetFromFile bug"
return -1
endif
pathToFolder = S_fileName[0, strlen(S_fileName) - strlen(fileName) - 1]
// Make sure there is an IGOR symbolic path pointing to the folder
NewPath/O/Q CurrentDataFilePath pathToFolder
pathName = "CurrentDataFilePath"
endif
NewDataFolder/O/S Info
LoadWave/J/D/W/A/K=0/B="F=0,N=ScanNo; F=-2,N=Sample; F=0,N=Temp; F=0,N=Frames;"
/P=$pathName fileName
End
// Retrieve data folders and waves from folders
Function/S getObjects(path, objectType)
String path
Variable objectType
DFREF pathref=$path
String list="", name
Variable i=0
do
name=GetIndexedObjNameDFR(pathref,objectType,i)
if(strlen(name)==0)
list=list[0,strlen(list)-2]
break
endif
if(stringmatch(name,"info")==0)
list+=name+";"
endif
i+=1
while(1)
return list
End
// Function to get a list of all APS generated waves that can be plotted
Function/S getAllWavesAPS()
String mainList="",subList="",item="", sub="", result=""
mainList=getObjects("root:APS:",4)
Variable i=0
do
item=StringFromList(i,mainList)
if(strlen(item)==0)
result=result[0,strlen(result)-2]
break
endif
DFREF path=root:APS:$item
SetDataFolder path
subList=getObjects(":",1)
Variable j=0
do
sub=StringFromList(j,subList)
if(strlen(sub)==0)
break
endif
if(stringmatch(sub[0],"q")==1)
String expr="[q]([[:digit:]]+)[C]([[:digit:]]+)"
String temp,scan
SplitString/E=expr (sub), temp, scan
result+=item+" - "+temp+"C - Scan "+scan+";"
endif
j+=1
while(1)
i+=1
while(1)
SetDataFolder root:
return result
End
Function test()
Print getAllWavesAPS()
End
// Function to get all other waves that have been imported
Function/S getAllWavesLS()
String mainList="",subList="",item="", sub="", result=""
mainList=getObjects("root:LS:",4)
Variable i=0
do
item=StringFromList(i,mainList)
if(strlen(item)==0)
result=result[0,strlen(result)-2]
break
endif
DFREF path=root:LS:$item
SetDataFolder path
subList=getObjects(":",1)
Variable j=0
do
sub=StringFromList(j,subList)
if(strlen(sub)==0)
break
endif
if(stringmatch(sub[0],"q")==1)
String expr="[q]([[:digit:]]+)[C]([[:digit:]]+)"
String temp,scan
SplitString/E=expr (sub), temp, scan
result+=item+" - "+temp+"C - Scan "+scan+";"
endif
j+=1
while(1)
i+=1
while(1)
SetDataFolder root:
return result
End
// Function to retireve all plottable waves
Function/S getAllWaves()
String waveaps=getAllWavesAPS(), wavels=getAllWavesLS(), result=""
if(strlen(waveaps)==0)
return wavels
endif
if(strlen(wavels)==0)
return waveaps
endif
return waveaps+";"+wavels
End
// Function that translates strings
Function/S getStuffFromString(str)
String str
Variable pt1, pt2
pt1=strsearch(str," - ",0)
pt2=strsearch(str,"C - Scan",0)
String folder, temp, scan, result
folder=str[0,pt1-1]
temp=str[pt1+3,pt2-1]
scan=str[pt2+9,strlen(str)-1]
result=folder+";q"+temp+"C"+scan
return result
End
Function checkaction(ctrlName,checked):CheckBoxControl
String ctrlName
Variable checked
if(stringmatch(ctrlName,"new")==1)
if(checked==1)
Checkbox app, value=0
Checkbox rem, value=0
Button go, title="Plot New!"
endif
endif
if(stringmatch(ctrlName,"app")==1)
if(checked==1)
Checkbox new, value=0
Checkbox rem, value=0
Button go, title="Append!"
endif
endif
if(stringmatch(ctrlName,"rem")==1)
if(checked==1)
Checkbox new, value=0
Checkbox app, value=0
Button go, title="Remove!"
endif
endif
if(stringmatch(ctrlName,"over")==1)
if(checked==1)
Checkbox stac, value=0
endif
endif
if(stringmatch(ctrlName,"stac")==1)
if(checked==1)
Checkbox over, value=0
endif
endif
if(stringmatch(ctrlName,"ivq")==1)
if(checked==1)
Checkbox iq2vq, value=0
endif
endif
if(stringmatch(ctrlName,"iq2vq")==1)
if(checked==1)
Checkbox ivq, value=0
endif
endif
End
Function butaction(ctrlName):ButtonControl
String ctrlName
if(stringmatch(ctrlName,"go")==1)
String wavepickval,waveinf
Variable newval, appval, remval, overval, stacval, ivqval, iq2vqval
ControlInfo wavepick; wavepickval=S_Value
ControlInfo new;newval=V_Value
ControlInfo app;appval=V_Value
ControlInfo rem;remval=V_Value
ControlInfo over;overval=V_Value
ControlInfo stac;stacval=V_Value
ControlInfo ivq;ivqval=V_Value
ControlInfo iq2vq;iq2vqval=V_Value
waveinf=getStuffFromString(wavepickval)
String y,x,curwave, fold=stringfromlist(0,waveinf), leg=""
DFREF path=root:APS:$fold
x=stringfromlist(1,waveinf)
if(ivqval==1)
y="i"+x[1,strlen(x)-1]
else
y="iqs"+x[1,strlen(x)-1]
endif
if(newval==1)
Display/K=1 path:$y vs path:$x
ModifyGraph log(left)=1,lsize=1.5,mirror=2,fSize=12,axThick=1.5;DelayUpdate
Label left "\\Z14I (a.u.)";DelayUpdate
Label bottom "\\Z14q (Å\\S-1\\M\\Z14)"
endif
if(appval==1)
if(strlen(StringfromList(0,WinList("*",";","WIN:1")))==0)
Display/K=1 path:$y vs path:$x
ModifyGraph log(left)=1,lsize=1.5,mirror=2,fSize=12,axThick=1.5;DelayUpdate
Label left "\\Z14I (a.u.)";DelayUpdate
Label bottom "\\Z14q (Å\\S-1\\M\\Z14)"
else
Appendtograph path:$y vs path:$x
ModifyGraph
log(left)=1,lsize=1.5,mirror=2,fSize=12,axThick=1.5;DelayUpdate
Label left "\\Z14I (a.u.)";DelayUpdate
Label bottom "\\Z14q (Å\\S-1\\M\\Z14)"
if(stacval==1)
Variable num=1,j=0
do
curwave=WaveName("",j,1)
if(strlen(curwave)==0)
break
endif
j+=1
num=10*num
while(1)
ModifyGraph muloffset($y)={0,num}
endif
endif
endif
if(remval==1)
Variable i=0
do
curwave=WaveName("",i,1)
if(strlen(curwave)==0)
break
endif
if(stringmatch(y,curwave)==1)
RemoveFromGraph $y
endif
i+=1
while(1)
endif
i=0
do
curwave=WaveName("",i,1)
if(strlen(curwave)==0)
break
endif
ModifyGraph rgb($curwave)=(getR(i),getG(i),getB(i))
i+=1
String expr="([[:digit:]]+)[C]([[:digit:]]+)"
String temp,scan
SplitString/E=expr (curwave), temp, scan
Wave scans=root:APS:Info:ScanNo
Wave/T sams=root:APS:Info:Sample
Variable scan2=str2num(scan)
j=0
String sample
do
if(scans[j]==scan2)
sample=sams[j]
break
endif
j=j+1
while(j<numpnts(scans))
leg+="\\s(\'"+curwave+"\')"+sample+" - "+temp+"C - Scan "+scan+"\r"
while(1)
leg=leg[0,strlen(leg)-2]
Legend/C/N=text0/A=RT leg
endif
if(stringmatch(ctrlname,"addlines")==1)
APSAddLines()
endif
if(stringmatch(ctrlname,"loadinfo")==1)
getInfoFile("","")
endif
if(stringmatch(ctrlname,"loadonefile")==1)
APSLoad("","")
PopupMenu wavepick, value=getAllWaves()
PopupMenu backpick, value=getAllWaves()
endif
if(stringmatch(ctrlname,"loaddirect")==1)
APSLoadDir("")
PopupMenu wavepick, value=getAllWaves()
PopupMenu backpick, value=getAllWaves()
endif
if(stringmatch(ctrlname,"subtract")==1)
APSSubtract()
endif
End
Function getR(num)
Variable num
Variable result=0
num=mod(num,9)
switch (num)
case 0:
case 1:
case 8:
result=65280
break
case 3:
case 4:
case 5:
case 6:
result=0
break
case 7:
result=39440
break
case 2:
result=52224
break
endswitch
return result
End
Function getG(num)
Variable num
Variable result=0
num=mod(num,9)
switch (num)
case 0:
case 6:
case 7:
case 8:
result=0
break
case 1:
case 5:
result=43520
break
case 3:
case 4:
result=65280
break
case 2:
result=52224
break
endswitch
return result
End
Function getB(num)
Variable num
Variable result=0
num=mod(num,9)
switch (num)
case 0:
case 1:
case 2:
case 3:
result=0
break
case 4:
case 5:
case 6:
result=65280
break
case 7:
result=58880
break
case 8:
result=52224
break
endswitch
return result
End
Function APSAddLines()
NewDataFolder/O/S root:APS:temp
String winf, winf2, wpath, type, ywave
String/G xwave
ControlInfo wavepick; winf=S_Value
winf2=getStuffFromString(winf)
wpath=StringFromList(0,winf2)
xwave=StringFromList(1,winf2)
Variable val
ControlInfo ivq; val=V_Value
if(val==1)
ywave="i"+xwave[1,strlen(xwave)-1]
else
ywave="iqs"+xwave[1,strlen(xwave)-1]
endif
DFREF path=root:APS:$wpath
Wave xs=path:$xwave
Wave ys=path:$ywave
String x2="x2"+xwave, y2="y2"+xwave, leg="\\s(\'"+y2+"\') "+winf
SetDataFolder root:APS:temp
Duplicate xs, $x2
Duplicate ys, $y2
Display/K=1/N=difflinesplot $y2 vs $x2
WAVE x2w=$x2
WAVE y2w=$y2
ModifyGraph log(left)=1,lsize=1.5,mirror=2,fSize=12,axThick=1.5;
Legend/C/N=text0/A=RT leg
Variable maxx=WaveMax(y2w),maxy
Variable i=0
do
if(y2w[i]==maxx)
maxy=x2w[i]
break
endif
i+=1
while(i<numpnts(y2w))
Variable L,C,S,G,start //range, beam
NewPanel /K=2/W=(100,100,400,420) as "Add Diffraction Lines"
TitleBox titleL, pos={5,5}, title="L=", frame=0
TitleBox titleC, pos={5,85}, title="C=", frame=0, fColor=(0,0,65535)
TitleBox titleS, pos={5,165}, title="S=", frame=0, fColor=(0,30000,0)
TitleBox titleG, pos={5,245}, title="G=", frame=0, fColor=(65535,0,0)
Slider slideL, limits={.0001,.1,0}, value=maxy, pos={5,20}, size={200,50}, vert=0, ticks=1, variable=L,
proc=APSupdateSlider
Slider slideC, limits={.0001,.1,0}, value=maxy, pos={5,100}, size={200,50}, vert=0, ticks=1, variable=C,
proc=APSupdateSlider, fColor=(0,0,65535)
Slider slideS, limits={.0001,.1,0}, value=maxy, pos={5,180}, size={200,50}, vert=0, ticks=1, variable=S,
proc=APSupdateSlider, fColor=(0,30000,0)
Slider slideG, limits={.0001,.1,0}, value=maxy, pos={5,260}, size={200,50}, vert=0, ticks=1, variable=G,
proc=APSupdateSlider, fColor=(65535,0,0)
TitleBox valL, pos={20,5}, title=num2str(L), frame=0
TitleBox valC, pos={20,85}, title=num2str(C), frame=0, fColor=(0,0,65535)
TitleBox valS, pos={20,165}, title=num2str(S), frame=0, fColor=(0,30000,0)
TitleBox valG, pos={20,245}, title=num2str(g), frame=0, fColor=(65535,0,0)
TitleBox titleL1, pos={240,20}, title="Lamellae", frame=0
TitleBox titleC1, pos={240,100}, title="Cylinders", frame=0, fColor=(0,0,65535)
TitleBox titleS1, pos={240,180}, title="Spheres", frame=0, fColor=(0,30000,0)
TitleBox titleG1, pos={240,260}, title="Gyroid", frame=0, fColor=(65535,0,0)
Checkbox checkL, value=0, pos={220,20}, title="", proc=APSupdateCheck
Checkbox checkC, value=0, pos={220,100}, title="", proc=APSupdateCheck
Checkbox checkS, value=0, pos={220,180}, title="", proc=APSupdateCheck
Checkbox checkG, value=0, pos={220,260}, title="", proc=APSupdateCheck
Button closer, pos={220,290}, title="Close", proc=APSclose
APSupdateLines()
End
Function APSclose(ctrlName):ButtonControl
String ctrlName
SetDataFolder root:APS:temp
KillVariables/A
String lamw,lamx,lamy,lamw2
lamw="lamw"
lamx="lamx"
lamy="lamy"
lamw2="lamw2"
if(exists("lamy")) //Remove from graph if unchecked and get rid of old waves
RemoveFromGraph/W=difflinesplot $lamy
KillWaves/Z $lamy,$lamx,lw,lw2
endif
String cylw,cylx,cyly,cylw2
cylw="cylw"
cylx="cylx"
cyly="cyly"
cylw2="cylw2"
if(exists("cyly")) //Remove from graph if unchecked and get rid of old waves
RemoveFromGraph/W=difflinesplot $cyly
KillWaves/Z $cyly,$cylx,cw,cw2
endif
String sphw,sphx,sphy,sphw2
sphw="sphw"
sphx="sphx"
sphy="sphy"
sphw2="sphw2"
if(exists("sphy")) //Remove from graph if unchecked and get rid of old waves
RemoveFromGraph/W=difflinesplot $sphy
KillWaves/Z $sphy,$sphx,sw,sw2
endif
String gyrw,gyrx,gyry,gyrw2
gyrw="gyrw"
gyrx="gyrx"
gyry="gyry"
gyrw2="gyrw2"
if(exists("gyry")) //Remove from graph if unchecked and get rid of old waves
RemoveFromGraph/W=difflinesplot $gyry
KillWaves/Z $gyry,$gyrx,gw,gw2
endif
String name="difflinesplot"
DoWindow/K $WinName(0,64)
DoWindow/C olddifflinesplot
End
Function APSupdateSlider(ctrl,ctrlVal,event): SliderControl
String ctrl
Variable ctrlVal,event
APSupdateLines()
End
Function APSupdateCheck(ctrl,val): CheckboxControl
String ctrl
Variable val
APSupdateLines()
End
Function APSupdateLines()
SetDataFolder root:APS:temp
SVAR xwave=xwave
String x2="x2"+xwave,y2="y2"+xwave
Wave ys =root:APS:temp:$y2
Wave xs = root:APS:temp:$x2
Variable max1=WaveMax(xs)
Variable L,C,S,G,lon,con,son,gon,i,j //range, beam, bon
ControlInfo slideL; L=V_Value
ControlInfo slideC; C=V_Value
ControlInfo slideS; S=V_Value
ControlInfo slideG; G=V_Value
ControlInfo checkL; lon=V_Value
ControlInfo checkC; con=V_Value
ControlInfo checkS; son=V_Value
ControlInfo checkG; gon=V_Value
Slider slideL, limits={.0001,0.1,0}
Slider slideC, limits={.0001,0.1,0}
Slider slideS, limits={.0001,0.1,0}
Slider slideG, limits={.0001,0.1,0}
TitleBox valL, title=num2str(L)
TitleBox valC, title=num2str(C)
TitleBox valS, title=num2str(S)
TitleBox valG, title=num2str(G)
String lamw,lamx,lamy,lamw2
lamw="lamw"
lamx="lamx"
lamy="lamy"
lamw2="lamw2"
if(exists("lamy")) //Remove from graph if unchecked and get rid of old waves
RemoveFromGraph/W=difflinesplot $lamy
KillWaves/Z $lamy,$lamx,lw,lw2
endif
String cylw,cylx,cyly,cylw2
cylw="cylw"
cylx="cylx"
cyly="cyly"
cylw2="cylw2"
if(exists("cyly")) //Remove from graph if unchecked and get rid of old waves
RemoveFromGraph/W=difflinesplot $cyly
KillWaves/Z $cyly,$cylx,cw,cw2
endif
String sphw,sphx,sphy,sphw2
sphw="sphw"
sphx="sphx"
sphy="sphy"
sphw2="sphw2"
if(exists("sphy")) //Remove from graph if unchecked and get rid of old waves
RemoveFromGraph/W=difflinesplot $sphy
KillWaves/Z $sphy,$sphx,sw,sw2
endif
String gyrw,gyrx,gyry,gyrw2
gyrw="gyrw"
gyrx="gyrx"
gyry="gyry"
gyrw2="gyrw2"
if(exists("gyry")) //Remove from graph if unchecked and get rid of old waves
RemoveFromGraph/W=difflinesplot $gyry
KillWaves/Z $gyry,$gyrx,gw,gw2
endif
if(lon>0) //Add lam diffraction lines if checked
Make lw={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}
i=0
j=20
do
if(L*lw[i]>max1)
j=i
break
endif
i+=1
while(i<numpnts(lw))
i=0
Make/N=(j) lw2
do
lw2[i]=lw[i]
i+=1
while(i<j)
Duplicate lw2,$lamx,$lamy
Wave lx = $lamx
Wave ly = $lamy
lx=L*lw2
i=0
j=0
do
do
if(xs[j]>lx[i])
ly[i]=ys[j]
break
endif
j+=1
while(j<numpnts(xs))
i+=1
while(i<numpnts(lx))
rename ly, $lamy
rename lx, $lamx
appendToGraph/W=difflinesplot ly vs lx
ModifyGraph/W=difflinesplot mode(lamy)=1,rgb(lamy)=(0,0,0)
endif
if(con>0) //Add cyl diffraction lines if checked
Make cw={1,3,4,7,9,12,13,16,19,21,25,27,28,31,36,37,39,43,48,49,52,57,61,63,64,67,73,75,76,79}
i=0
j=30
do
if(C*cw[i]^(1/2)>max1)
j=i
break
endif
i+=1
while(i<numpnts(cw))
i=0
Make/N=(j) cw2
do
cw2[i]=cw[i]^(1/2)
i+=1
while(i<j)
Duplicate cw2,$cylx,$cyly
Wave cx = $cylx
Wave cy = $cyly
cx=C*cw2
i=0
j=0
do
do
if(xs[j]>cx[i])
cy[i]=ys[j]
break
endif
j+=1
while(j<numpnts(xs))
i+=1
while(i<numpnts(cx))
rename cy, $cyly
rename cx, $cylx
appendToGraph/W=difflinesplot cy vs cx
ModifyGraph/W=difflinesplot mode(cyly)=1,rgb(cyly)=(0,0,65535)
endif
if(son>0) //Add sph diffraction lines if checked
Make
sw={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,
40}
i=0
j=40
do
if(S*sw[i]^(1/2)>max1)
j=i
break
endif
i+=1
while(i<numpnts(sw))
i=0
Make/N=(j) sw2
do
sw2[i]=sw[i]^(1/2)
i+=1
while(i<j)
Duplicate sw2,$sphx,$sphy
Wave sx = $sphx
Wave sy = $sphy
sx=S*sw2
i=0
j=0
do
do
if(xs[j]>sx[i])
sy[i]=ys[j]
break
endif
j+=1
while(j<numpnts(xs))
i+=1
while(i<numpnts(sx))
rename sy, $sphy
rename sx, $sphx
appendToGraph/W=difflinesplot sy vs sx
ModifyGraph/W=difflinesplot mode(sphy)=1,rgb(sphy)=(0,30000,0)
endif
if(gon>0) //Add gyr diffraction lines if checked
Make gw={6,8,14,16,20,22,24,26,30,32,38,40,42,46,48,50,52,54,56,62}
i=0
j=20
do
if(G*gw[i]^(1/2)>max1)
j=i
break
endif
i+=1
while(i<numpnts(gw))
i=0
Make/N=(j) gw2
do
gw2[i]=gw[i]^(1/2)
i+=1
while(i<j)
Duplicate gw2,$gyrx,$gyry
Wave gx = $gyrx
Wave gy = $gyry
gx=G*gw2
i=0
j=0
do
do
if(xs[j]>gx[i])
gy[i]=ys[j]
break
endif
j+=1
while(j<numpnts(xs))
i+=1
while(i<numpnts(gx))
rename gy, $gyry
rename gx, $gyrx
appendToGraph/W=difflinesplot gy vs gx
ModifyGraph/W=difflinesplot mode(gyry)=1,rgb(gyry)=(65535,0,0)
endif
End
Function APSSubtract()
String wave1val, backval, wave1, back, wave1root, backroot, wave1q, backq
ControlInfo wavepick; wave1val=S_Value
ControlInfo backpick; backval=S_Value
wave1root=StringfromList(0,getStuffFromString(wave1val))
wave1q=StringfromList(1,getStuffFromString(wave1val))
backroot=StringfromList(0,getStuffFromString(backval))
backq=StringfromList(1,getStuffFromString(backval))
wave1="i"+wave1q[1,strlen(wave1q)-1]
back="i"+backq[1,strlen(backq)-1]
DFREF wpath=root:APS:$wave1root
DFREF bpath=root:APS:$backroot
Wave q1=wpath:$wave1q
Wave w1=wpath:$wave1
Wave b1=bpath:$back
Display/K=1/L=topleft/B=bottom1 w1 vs wpath:$wave1q
AppendToGraph/L=topleft/B=bottom1 b1 vs bpath:$backq
SetDataFolder root:APS:$wave1root
NewDataFolder/O/S BackCorr
String neww="bc"+wave1
String newx="bc"+wave1q
Duplicate w1, $neww
Duplicate q1, $newx
Wave w2=$neww
w2=w1-b1
AppendToGraph/L=bottomleft/B=bottom2 w2 vs wpath:$wave1q
ModifyGraph log(topleft)=1, log(bottomleft)=1, lsize=1.5, axisEnab(topleft)={0.5,1},
axisEnab(bottomleft)={0,0.5}, freePos(topleft)=0, freePos(bottomleft)=0
ModifyGraph rgb($neww)=(0,0,65535), rgb($back)=(0,0,0), freePos(bottom1)=0,
freePos(bottom2)={0.5,kwFraction}
End
Function subt(ctrlName):ButtonControl
String ctrlName
Variable highy, highb, highdiff, lowdiff
Wave y1=CsrWaveRef(A)
Wave x1=CsrXWaveRef(A)
Wave by=CsrWaveRef(B)
Wave bx=CsrXWaveRef(B)
highy=getAveYFromEnd(y1,numpnts(y1)-xcsr(B))
highb=getAveYFromEnd(by,numpnts(by)-xcsr(B))
Print highy, highb
End
Function getAveYFromEnd(w1,numpts)
Wave w1
Variable numpts
Variable i=numpnts(w1)-numpts, total=0, num=0
do
total+=w1[i]
num+=1
i+=1
while(i<numpnts(w1))
return total/num
End
Function APSTools()
SetDataFolder root:
NewDataFolder/O LS
NewDataFolder/O/S APS
NewPanel /k=1/N=APSToolKit/W=(10,10,210,435)
//Section for loading data
TitleBox title0, title="Load Data Files", pos={5,5}, frame=0
Button loadinfo, pos={5,20}, title="Load Info File", proc=butaction, size={80,20}
Button loadonefile, pos={5,40}, title="Load One File", proc=butaction, size={80,20}
Button loaddirect, pos={5,60}, title="Load Directory of Files", proc=butaction, size={120,20}
//Section for plotting data
TitleBox title1, title="Select Wave to Plot", pos={5,90}, frame=0
PopupMenu wavepick, value=getAllWaves(), noproc, pos={5,105}
TitleBox title2, title="Select Operation", pos={5,135}, frame=0
CheckBox new, mode=1, pos={5,150}, value=1,title="Create New Graph", proc=checkaction
CheckBox app, mode=1, pos={5,165},value=0, title="Append to Top Graph", proc=checkaction
CheckBox rem, mode=1, pos={5,180},value=0, title="Remove from Top Graph", proc=checkaction
TitleBox title3, title="Select Plot Style", pos={5,200}, frame=0
CheckBox over, mode=1,pos={5,215},value=1, title="Overlay Plot", proc=checkaction
CheckBox stac, mode=1, pos={5,230},value=0, title="Stacked Plot", proc=checkaction
TitleBox title4, title="Select Plot Type", pos={5,250}, frame=0
CheckBox ivq, mode=1,pos={5,265},value=1, title="Plot I vs. q", proc=checkaction
CheckBox iq2vq, mode=1,pos={5,280},value=0, title="Plot I*q^2 vs. q", proc=checkaction
Button go, pos={5,300}, title="Plot!", proc=butaction, size={80,20}
//Section for adding diffraction lines - brings up external panel
Button addlines, pos={5,330}, title="Add Diffraction Lines", proc=butaction, size={120,20}
//Section for background subtraction
TitleBox title5, title="Select Background Wave", pos={5,360}, frame=0
PopupMenu backpick, value=getAllWaves(), noproc, pos={5,375}
Button subtract, pos={3,400}, title="Subtract", proc=butaction, size={80,20}
End
Sec12Tools
#pragma rtGlobals=1 // Use modern global access method.
// Sec12Tools by AKS, 20130204
// This procedure works with .dat files generated at 12-ID-B at the Advanced Photon Source at Argonne National
Labs
// This proceudre was developed by Adam K. Schmitt
Menu "Tools"
Submenu "SAXS"
Submenu "Sector 12"
"Sector 12 Tools", sector12tools()
"Lines", sec12lines()
End
"-"
End
End
Function/S GetLeafName12(pathStr)
String pathStr
String leafName
Variable pos
leafName = ""
pos = strlen(pathStr) - 1 // Search from the
end
do
if (CmpStr(pathStr[pos], ":") == 0) // Found the colon?
leafName = pathStr[pos+1, strlen(pathStr)]
break
// Break out of loop.
endif
pos -= 1
while(pos > 0)
return leafName
End
// Function to load an entire directory of files
Function Sec12LoadDir(pathName)
String pathName
String fileName
Variable index=0
if (strlen(pathName)==0) // If no path specified, create one
NewPath/O temporaryPath // This will put up a dialog
if (V_flag != 0)
return -1 // User cancelled
endif
pathName = "temporaryPath"
endif
do // Loop through each file in folder
fileName = IndexedFile($pathName, index, ".dat")
if (strlen(fileName) == 0) // No more files?
break // Break
out of loop
endif
//Load files section
Sec12LoadOne(pathName,fileName)
//End load files section
index += 1
while (1)
// Kill temp path if it exists
if (Exists("temporaryPath"))
KillPath temporaryPath
endif
// Signifies success.
return 0
End
// Function to load one file
Function Sec12LoadOne(pathName, fileName)
String pathName // Name of an existing IGOR symbolic path or ""
String fileName // Name of file within folder pointed to by symbolic path or ""
NewDataFolder/O/S root:Sec12
// If either of the input parameters is "", put up a dialog to get file.
if ((strlen(pathName)==0) %| (strlen(pathName)==0))
Variable dummyRefNum
String pathToFolder
Open/R/D/M="Choose data file" dummyRefNum // This sets an automatically created
local variable named S_fileName.
if (strlen(S_fileName) == 0) // User cancelled?
return -1
endif
// Now break the full path to file down into path to folder plus file name.
// This is done by searching for the last colon in the full path.
fileName =GetLeafName12(S_fileName)
if (strlen(fileName) == 0)
Print "LoadDataSetFromFile bug"
return -1
endif
pathToFolder = S_fileName[0, strlen(S_fileName) - strlen(fileName) - 1]
// Make sure there is an IGOR symbolic path pointing to the folder
NewPath/O/Q CurrentDataFilePath pathToFolder
pathName = "CurrentDataFilePath"
endif
//Load sector 12 data
//String expr="([[:alnum:]]+)[_]([[:digit:]]+)[_]([[:digit:]]+)"
String name, scan, frame
//SplitString/E=expr (fileName), name, scan, frame
name=filename[0,strlen(filename)-13], scan=filename[strlen(filename)-11,strlen(filename)-9]
String type=name[0], name2=name[1,strlen(name)]+"_"+scan
//Next line gives column info, eg how to name different waves and which ones to throw away
String
columninfo="N="+type+"q"+name2+";N="+type+"i"+name2+";N="+type+"e"+name2+";N='_skip_';N='_skip_';N=
'_skip_';"
LoadWave/A/B=columninfo/D/J/K=0/V={"\t, "," $",0,0}/P=$pathName/W fileName
End
// Function to retrieve list of loaded waves
Function/S Sec12getwaves()
NewDataFolder/O/S root:Sec12
//get waves that start with Si
String list = Wavelist("Si*",";",""), cur, list2=""
//Remove the Si to get more human readable wave names
Variable index=0
do
cur=stringfromlist(index,list)
if(stringmatch(cur,"")==1)
break
endif
list2+=cur[2,strlen(cur)]+";"
index+=1
while(1)
//Remove the last semicolon
list2=list2[0,strlen(list2)-2]
return list2
End
// Function to combine SAXS and WAXS data for get SWAXS data
Function sec12combine()
String list=Sec12getWaves(),cur
Variable index=0, i=0
do
cur=stringfromlist(index,list)
if(stringmatch(cur,"")==1)
break
endif
//Combine the q waves
String wavesq="Sq"+cur, wavewq="Wq"+cur, waveswq="SWq"+cur
Wave wsq = $wavesq
Wave wwq = $wavewq
Make/N=(numpnts(wsq)+numpnts(wwq)) $waveswq
Wave wswq = $waveswq
wswq=wswq+wsq
i=0
do
wswq[numpnts(wsq)+i]=wwq[i]
i+=1
while(i<numpnts(wwq))
//Combine the i waves
String wavesi="Si"+cur, wavewi="Wi"+cur, waveswi="SWi"+cur
Wave wsi = $wavesi
Wave wwi = $wavewi
Make/N=(numpnts(wsi)+numpnts(wwi)) $waveswi
Wave wswi = $waveswi
wswi=wswi+wsi
i=0
do
wswi[numpnts(wsi)+i]=wwi[i]
i+=1
while(i<numpnts(wwi))
//Combine the e waves
String wavese="Se"+cur, wavewe="We"+cur, waveswe="SWe"+cur
Wave wse = $wavese
Wave wwe = $wavewe
Make/N=(numpnts(wse)+numpnts(wwe)) $waveswe
Wave wswe = $waveswe
wswe=wswe+wse
i=0
do
wswe[numpnts(wse)+i]=wwe[i]
i+=1
while(i<numpnts(wwe))
//Now loop through all waves
index+=1
while(1)
End
Function Sector12Tools()
NewPanel/k=1/N=Sector12Tools/W=(10,10,200,390)
// Data Loading section
TitleBox title0, title="Load Files", pos={5,5}, frame=0
TitleBox ver, title="AKS v1.1", pos={140,5}, frame=0
Button loadone, pos={5,20}, title="Load One File", proc=sec12but, size={80,20}
Button loaddir, pos={5,40}, title="Load Directory", proc=sec12but, size={80,20}
Button combine, pos={5,60}, title="Combine Data", proc=sec12but, size={80,20}
// Data plotting section
TitleBox title1, title="Select Wave to Plot", pos={5,90}, frame=0
PopupMenu wavepick, value=Sec12getWaves(), noproc, pos={5,105}
TitleBox title2, title="Select Operation", pos={5,135}, frame=0
CheckBox new, mode=1, pos={5,150}, value=1,title="Create New Graph", proc=sec12check
CheckBox app, mode=1, pos={5,165},value=0, title="Append to Top Graph", proc=sec12check
CheckBox rem, mode=1, pos={5,180},value=0, title="Remove from Top Graph", proc=sec12check
TitleBox title3, title="Select Plot Style", pos={5,200}, frame=0
CheckBox over, mode=1, pos={5,215}, value=1,title="Overlay Plot", proc=sec12check
CheckBox stac, mode=1, pos={5,230}, value=0,title="Stacked Plot", proc=sec12check
TitleBox title4, title="Select Which to Plot", pos={5,250}, frame=0
CheckBox saxs, mode=1, pos={5,265}, value=1,title="Plot SAXS", proc=sec12check
CheckBox waxs, mode=1, pos={5,280}, value=0,title="Plot WAXS", proc=sec12check
CheckBox swaxs, mode=1, pos={5,295}, value=0,title="Plot SWAXS", proc=sec12check
Button plot, pos={5,315}, title="Plot", proc=sec12but, size={80,20}
// Data workup section
Button convert, pos={5,335}, title="Convert", proc=sec12but, size={80,20}
Button lines, pos={5,355}, title="Add Lines", proc=sec12but, size={80,20}
End
// Handle all button events
Function sec12but(ctrlname) : ButtonControl
String ctrlname
//Convert button
if(stringmatch(ctrlname,"convert")==1)
sec12convert()
endif
//Load File buttons
if(stringmatch(ctrlname,"loadone")==1)
Sec12LoadOne("","")
endif
if(stringmatch(ctrlname,"loaddir")==1)
Sec12LoadDir("")
endif
//Combine button
if(stringmatch(ctrlname,"combine")==1)
sec12combine()
endif
//Update wave list
PopupMenu wavepick, value=Sec12getWaves()
//Plotting button
if(stringmatch(ctrlname,"plot")==1)
//Get the relevant variables from controls
String thewave="",y="",x="", curwave="", leg="", cursam="", curtype=""
Variable newval, appval, remval, overval, stacval, saxsval, waxsval, swaxsval
ControlInfo wavepick; thewave=S_Value
ControlInfo new;newval=V_Value
ControlInfo app;appval=V_Value
ControlInfo rem;remval=V_Value
ControlInfo over;overval=V_Value
ControlInfo stac;stacval=V_Value
ControlInfo saxs;saxsval=V_Value
ControlInfo waxs;waxsval=V_Value
ControlInfo swaxs;swaxsval=V_Value
//Get the correct wave names
SetDataFolder root:Sec12
if(saxsval==1)
y="Si"+thewave
x="Sq"+thewave
else
if(waxsval==1)
y="Wi"+thewave
x="Wq"+thewave
else
y="SWi"+thewave
x="SWq"+thewave
endif
endif
//Start plotting i guess.
//If new plot selected
if(newval==1)
//Print y,x
Display/K=1 $y vs $x
//Make the plot look nice
ModifyGraph log(left)=1,mirror=2,axThick=1.5,lblMargin=5,standoff=0;DelayUpdate
Label left "Log(Intensity) (a.u.)";DelayUpdate
Label bottom "q(Å\\S-1\\M)"
endif
//If append is selected
if(appval==1)
//Make sure there is actually a plot up
if(strlen(Stringfromlist(0,WinList("*",";","WIN:1")))==0)
//Same as plot new
Display/K=1 $y vs $x
//Make the plot look nice
ModifyGraph
log(left)=1,mirror=2,axThick=1.5,lblMargin=5,standoff=0;DelayUpdate
Label left "Log(Intensity) (a.u.)";DelayUpdate
Label bottom "q(Å\\S-1\\M)"
else
Appendtograph $y vs $x
//If stacked plot is selected
if(stacval==1)
//Find the new offset value
Variable num=1, j=0
do
curwave=WaveName("",j,1)
if(strlen(curwave)==0)
break
endif
j+=1
num=10*num
while(1)
//Apply the vertical offset
ModifyGraph muloffset($y)={0,num}
endif
endif
endif
//If remove is selected
if(remval==1)
Variable i=0
//Find the wave to remove
do
curwave=WaveName("",i,1)
if(strlen(curwave)==0)
break
endif
if(stringmatch(y,curwave)==1)
//Remove the wave
Removefromgraph $y
endif
i+=1
while(1)
endif
//Chenge the plot colors and make the legend
i=0
do
curwave=WaveName("",i,1)
if(strlen(curwave)==0)
break
endif
//Apply correct colors
ModifyGraph rgb($curwave)=(sec12R(i),sec12G(i),sec12B(i))
i+=1
//Find current sample name
if(stringmatch(curwave[0,1],"SW")==1)
cursam=curwave[3,strlen(curwave)]
curtype=" - SWAXS\r"
else
cursam=curwave[2,strlen(curwave)]
if(stringmatch(curwave[0],"S")==1)
curtype=" - SAXS\r"
else
curtype=" - WAXS\r"
endif
endif
//Add curent wave to legend
leg+="\\s(\'"+curwave+"\')"+cursam+curtype
while(1)
//Trim legend and apply to plot
leg=leg[0,strlen(leg)-2]
Legend/C/N=text0/A=RT leg
endif
//Add lines
if(stringmatch(ctrlname,"lines")==1)
sec12lines()
endif
End
// Handle all checkbox change events
Function sec12check(ctrlname, checked) : CheckBoxControl
String ctrlname
Variable checked
//Select Operation controls
if(stringmatch(ctrlName,"new")==1)
if(checked==1)
Checkbox app, value=0
Checkbox rem, value=0
Button plot, title="Plot"
endif
endif
if(stringmatch(ctrlName,"app")==1)
if(checked==1)
Checkbox new, value=0
Checkbox rem, value=0
Button plot, title="Append"
endif
endif
if(stringmatch(ctrlName,"rem")==1)
if(checked==1)
Checkbox new, value=0
Checkbox app, value=0
Button plot, title="Remove"
endif
endif
//Select Plot Style controls
if(stringmatch(ctrlName,"over")==1)
if(checked==1)
Checkbox stac, value=0
endif
endif
if(stringmatch(ctrlName,"stac")==1)
if(checked==1)
Checkbox over, value=0
endif
endif
//Select Which to Plot controls
if(stringmatch(ctrlName,"saxs")==1)
if(checked==1)
Checkbox waxs, value=0
Checkbox swaxs, value=0
endif
endif
if(stringmatch(ctrlName,"waxs")==1)
if(checked==1)
Checkbox saxs, value=0
Checkbox swaxs, value=0
endif
endif
if(stringmatch(ctrlName,"swaxs")==1)
if(checked==1)
Checkbox saxs, value=0
Checkbox waxs, value=0
endif
endif
End
Function sec12R(num)
Variable num
Variable result=0
num=mod(num,9)
switch (num)
case 0:
case 1:
case 8:
result=65280
break
case 3:
case 4:
case 5:
case 6:
result=0
break
case 7:
result=39440
break
case 2:
result=52224
break
endswitch
return result
End
Function sec12G(num)
Variable num
Variable result=0
num=mod(num,9)
switch (num)
case 0:
case 6:
case 7:
case 8:
result=0
break
case 1:
case 5:
result=43520
break
case 3:
case 4:
result=65280
break
case 2:
result=52224
break
endswitch
return result
End
Function sec12B(num)
Variable num
Variable result=0
num=mod(num,9)
switch (num)
case 0:
case 1:
case 2:
case 3:
result=0
break
case 4:
case 5:
case 6:
result=65280
break
case 7:
result=58880
break
case 8:
result=52224
break
endswitch
return result
End
// Convert file for use in Jade crystallography software for further data analysis
Function sec12convert()
String thewave="", y="", x="", t="", ti="",
win=StringfromList(1,WinList("Sector12Tools*",";","WIN:64")), name=""
//Get the wave
Variable saxsval, waxsval, swaxsval
ControlInfo/W=$win wavepick; thewave=S_Value
ControlInfo/W=$win saxs;saxsval=V_Value
ControlInfo/W=$win waxs;waxsval=V_Value
ControlInfo/W=$win swaxs;swaxsval=V_Value
//Get the correct wave names
SetDataFolder root:Sec12
if(saxsval==1)
y="Si"+thewave
x="Sq"+thewave
t="St"+thewave
ti="Sti"+thewave
name=thewave+"saxs"
else
if(waxsval==1)
y="Wi"+thewave
x="Wq"+thewave
t="Wt"+thewave
ti="Wti"+thewave
name=thewave+"waxs"
else
y="SWi"+thewave
x="SWq"+thewave
t="SWt"+thewave
ti="SWti"+thewave
name=thewave+"swaxs"
endif
endif
//Convert q to two theta
Wave wx=$x
Duplicate/O $x, $t
Wave wt=$t
wt=180/pi*asin(1.033*wx/4/pi)
//Modulate the intensity of a duplicate intensity wave for Jade importing
Duplicate/O $y, $ti
Wave newint=$ti
newint=newint*1000000
//Put waves in new table, format them for export and save
Edit/N=convert $x, $t, $ti
ModifyTable format($ti)=1, format($t)=3,digits($t)=6
Save/J/F/M="\r\n" $t,$ti as name
DoWindow/K convert
End
// Function to add diffraction lines to data for data analysis
Function sec12lines()
NewDataFolder/O/S root:Sec12
String/G xwave, ywave
String thewave="",win=StringfromList(1,WinList("Sector12Tools*",";","WIN:64"))
//Get the wave
Variable saxsval, waxsval, swaxsval
ControlInfo/W=$win wavepick; thewave=S_Value
ControlInfo/W=$win saxs;saxsval=V_Value
ControlInfo/W=$win waxs;waxsval=V_Value
ControlInfo/W=$win swaxs;swaxsval=V_Value
//Get the correct wave names
SetDataFolder root:Sec12
if(saxsval==1)
ywave="Si"+thewave
xwave="Sq"+thewave
else
if(waxsval==1)
ywave="Wi"+thewave
xwave="Wq"+thewave
else
ywave="SWi"+thewave
xwave="SWq"+thewave
endif
endif
Wave xs=$xwave
Wave ys=$ywave
String x2="x2"+xwave, y2="y2"+ywave, leg="\\s(\'"+y2+"\') "+thewave
SetDataFolder root:Sec12
Duplicate xs, $x2
Duplicate ys, $y2
Display/K=1/N=difflinesplot $y2 vs $x2
WAVE x2w=$x2
WAVE y2w=$y2
ModifyGraph log(left)=1,lsize=1.5,mirror=2,fSize=12,axThick=1.5;
Legend/C/N=text0/A=RT leg
Variable maxx=WaveMax(y2w),maxy
Variable i=0
do
if(y2w[i]==maxx)
maxy=x2w[i]
break
endif
i+=1
while(i<numpnts(y2w))
Variable L,C,S,G,start,low=0.0001,high=0.1
NewPanel /K=2/W=(100,100,400,450) as "Add Diffraction Lines"
TitleBox titleL, pos={5,5}, title="L=", frame=0
TitleBox titleC, pos={5,85}, title="C=", frame=0, fColor=(0,0,65535)
TitleBox titleS, pos={5,165}, title="S=", frame=0, fColor=(0,30000,0)
TitleBox titleG, pos={5,245}, title="G=", frame=0, fColor=(65535,0,0)
Slider slideL, limits={.0001,.1,0}, value=maxy, pos={5,20}, size={200,50}, vert=0, ticks=1, variable=L,
proc=sec12linesSlider
Slider slideC, limits={.0001,.1,0}, value=maxy, pos={5,100}, size={200,50}, vert=0, ticks=1, variable=C,
proc=sec12linesSlider, fColor=(0,0,65535)
Slider slideS, limits={.0001,.1,0}, value=maxy, pos={5,180}, size={200,50}, vert=0, ticks=1, variable=S,
proc=sec12linesSlider, fColor=(0,30000,0)
Slider slideG, limits={.0001,.1,0}, value=maxy, pos={5,260}, size={200,50}, vert=0, ticks=1, variable=G,
proc=sec12linesSlider, fColor=(65535,0,0)
TitleBox valL, pos={20,5}, title=num2str(L), frame=0
TitleBox valC, pos={20,85}, title=num2str(C), frame=0, fColor=(0,0,65535)
TitleBox valS, pos={20,165}, title=num2str(S), frame=0, fColor=(0,30000,0)
TitleBox valG, pos={20,245}, title=num2str(g), frame=0, fColor=(65535,0,0)
TitleBox titleL1, pos={240,20}, title="Lamellae", frame=0
TitleBox titleC1, pos={240,100}, title="Cylinders", frame=0, fColor=(0,0,65535)
TitleBox titleS1, pos={240,180}, title="Spheres", frame=0, fColor=(0,30000,0)
TitleBox titleG1, pos={240,260}, title="Gyroid", frame=0, fColor=(65535,0,0)
Checkbox checkL, value=0, pos={220,20}, title="", proc=sec12linesCheck
Checkbox checkC, value=0, pos={220,100}, title="", proc=sec12linesCheck
Checkbox checkS, value=0, pos={220,180}, title="", proc=sec12linesCheck
Checkbox checkG, value=0, pos={220,260}, title="", proc=sec12linesCheck
Button closer, pos={220,290}, title="Close", proc=sec12linesclose, help={"Close the diffraction lines tool
which will remove lines"}
Button markers, pos={220,320}, title="Markers", proc=sec12linesclose, help={"Close the diffraction lines
tool and leave behind markers where the lines where"}
SetVariable lowvar activate, limits={0.0001,1,0.0001}, size={100,20}, noedit=0, live=1,
value=_NUM:0.0001, frame=0, pos={10,320}, title="Low limit", proc=sec12linesLimits
SetVariable highvar activate, limits={0.001,1,0.001}, size={90,20}, noedit=0, live=1, value=_NUM:0.1,
frame=0, pos={120,320}, title="Highlimit", proc=sec12linesLimits
Sec12updateLines()
End
Function sec12linesclose(ctrlName):ButtonControl
String ctrlName
SetDataFolder root:Sec12
SVAR xwave=xwave, ywave=ywave
String y2="y2"+ywave, x2="x2"+xwave
Wave xs=$x2
String lamw,lamx,lamy,lamw2,cylw,cylx,cyly,cylw2,sphw,sphx,sphy,sphw2,gyrw,gyrx,gyry,gyrw2
//Checks to see if markers should be added before close
if(stringmatch(ctrlname,"markers")==1)
Variable lon, i=0, xval, j=0, con, lamnum, cylnum,sphnum,gyrnum, son, gon
//How many peaks of each morphology to mark, if 0 it means do them all
Prompt lamnum, "Number of Lam Peaks"
Prompt cylnum, "Number of Cyl Peaks"
Prompt sphnum, "Number of Sph Peaks"
Prompt gyrnum, "Number of Gyr Peaks"
DoPrompt "Input Peak Numbers", lamnum,cylnum,sphnum,gyrnum
if(lamnum==0)
lamnum=50
endif
if(cylnum==0)
cylnum=50
endif
if(sphnum==0)
sphnum=50
endif
if(gyrnum==0)
gyrnum=50
endif
//Add lamellar tags
ControlInfo checkL; lon=V_Value
if(lon>0)
lamx="lamx"
Wave lx = $lamx
do
xval=lx[i]
j=0
do
if(xs[j]>lx[i])
xval=j
break
endif
j+=1
while(1)
Tag/F=0/X=0/Y=5/L=0/TL=0/B=1/T=0.005 $y2, xval,"\\W523"
i+=1
if(i==numpnts(lx)||i==lamnum)
break
endif
while(1)
endif
//Reset index and add cylinder tags
i=0
ControlInfo checkC; con=V_Value
if(con>0)
cylx="cylx"
Wave cx = $cylx
do
xval=cx[i]
j=0
do
if(xs[j]>cx[i])
xval=j
break
endif
j+=1
while(1)
Tag/F=0/X=0/Y=5/L=0/TL=0/B=1/T=0.005 $y2, xval,"\\W522"
i+=1
if(i==numpnts(cx)||i==cylnum)
break
endif
while(1)
endif
//Reset index and add spheres tags
i=0
ControlInfo checkS; son=V_Value
if(son>0)
sphx="sphx"
Wave sx = $sphx
do
xval=sx[i]
j=0
do
if(xs[j]>sx[i])
xval=j
break
endif
j+=1
while(1)
Tag/F=0/X=0/Y=5/L=0/TL=0/B=1/T=0.005 $y2, xval,"\\W518"
i+=1
if(i==numpnts(sx)||i==sphnum)
break
endif
while(1)
endif
//Reset index and add gyroid tags
i=0
ControlInfo checkG; gon=V_Value
if(gon>0)
gyrx="gyrx"
Wave gx = $gyrx
do
xval=gx[i]
j=0
do
if(xs[j]>gx[i])
xval=j
break
endif
j+=1
while(1)
Tag/F=0/X=0/Y=5/L=0/TL=0/B=1/T=0.005 $y2, xval,"\\W507"
i+=1
if(i==numpnts(gx)||i==gyrnum)
break
endif
while(1)
endif
endif
//Change legend
String text1=""
if(lon>0)
text1+="\\W523Lamellae\r"
endif
if(con>0)
text1+="\\W522Cylinders\r"
endif
if(son>0)
text1+="\\W518Spheres\r"
endif
if(gon>0)
text1+="\\W507Gyroid\r"
endif
text1=text1[0,strlen(text1)-2]
Legend/C/N=text41/J/F=0/B=1/A=RC/LS=1 text1
SetDataFolder root:Sec12
KillVariables/A
lamw="lamw"
lamx="lamx"
lamy="lamy"
lamw2="lamw2"
if(exists("lamy")) //Remove from graph if unchecked and get rid of old waves
RemoveFromGraph/W=difflinesplot $lamy
KillWaves/Z $lamy,$lamx,lw,lw2
endif
cylw="cylw"
cylx="cylx"
cyly="cyly"
cylw2="cylw2"
if(exists("cyly")) //Remove from graph if unchecked and get rid of old waves
RemoveFromGraph/W=difflinesplot $cyly
KillWaves/Z $cyly,$cylx,cw,cw2
endif
sphw="sphw"
sphx="sphx"
sphy="sphy"
sphw2="sphw2"
if(exists("sphy")) //Remove from graph if unchecked and get rid of old waves
RemoveFromGraph/W=difflinesplot $sphy
KillWaves/Z $sphy,$sphx,sw,sw2
endif
gyrw="gyrw"
gyrx="gyrx"
gyry="gyry"
gyrw2="gyrw2"
if(exists("gyry")) //Remove from graph if unchecked and get rid of old waves
RemoveFromGraph/W=difflinesplot $gyry
KillWaves/Z $gyry,$gyrx,gw,gw2
endif
String name="difflinesplot"
DoWindow/K $WinName(0,64)
DoWindow/C olddifflinesplot
End
// Handle diffraction lines events
Function sec12linesLimits(ctrlName,varNum,varStr,varName) : SetVariableControl
String ctrlName
Variable varNum
String varStr,varName
Sec12updateLines()
End
Function sec12linesSlider(ctrl,ctrlVal,event): SliderControl
String ctrl
Variable ctrlVal,event
Sec12updateLines()
End
Function sec12linesCheck(ctrl,val): CheckboxControl
String ctrl
Variable val
Sec12updateLines()
End
Function Sec12updateLines()
SetDataFolder root:Sec12
SVAR xwave=xwave, ywave=ywave
String x2="x2"+xwave,y2="y2"+ywave
Wave ys =$y2
Wave xs =$x2
Variable max1=WaveMax(xs)
Variable L,C,S,G,lon,con,son,gon,i,j,high,low
ControlInfo lowvar; low=V_Value
ControlInfo highvar; high=V_Value
ControlInfo slideL; L=V_Value
ControlInfo slideC; C=V_Value
ControlInfo slideS; S=V_Value
ControlInfo slideG; G=V_Value
ControlInfo checkL; lon=V_Value
ControlInfo checkC; con=V_Value
ControlInfo checkS; son=V_Value
ControlInfo checkG; gon=V_Value
Slider slideL, limits={low,high,0}
Slider slideC, limits={low,high,0}
Slider slideS, limits={low,high,0}
Slider slideG, limits={low,high,0}
TitleBox valL, title=num2str(L)
TitleBox valC, title=num2str(C)
TitleBox valS, title=num2str(S)
TitleBox valG, title=num2str(G)
String lamw,lamx,lamy,lamw2
lamw="lamw"
lamx="lamx"
lamy="lamy"
lamw2="lamw2"
if(exists("lamy")) //Remove from graph if unchecked and get rid of old waves
RemoveFromGraph/W=difflinesplot $lamy
KillWaves/Z $lamy,$lamx,lw,lw2
endif
String cylw,cylx,cyly,cylw2
cylw="cylw"
cylx="cylx"
cyly="cyly"
cylw2="cylw2"
if(exists("cyly")) //Remove from graph if unchecked and get rid of old waves
RemoveFromGraph/W=difflinesplot $cyly
KillWaves/Z $cyly,$cylx,cw,cw2
endif
String sphw,sphx,sphy,sphw2
sphw="sphw"
sphx="sphx"
sphy="sphy"
sphw2="sphw2"
if(exists("sphy")) //Remove from graph if unchecked and get rid of old waves
RemoveFromGraph/W=difflinesplot $sphy
KillWaves/Z $sphy,$sphx,sw,sw2
endif
String gyrw,gyrx,gyry,gyrw2
gyrw="gyrw"
gyrx="gyrx"
gyry="gyry"
gyrw2="gyrw2"
if(exists("gyry")) //Remove from graph if unchecked and get rid of old waves
RemoveFromGraph/W=difflinesplot $gyry
KillWaves/Z $gyry,$gyrx,gw,gw2
endif
if(lon>0) //Add lam diffraction lines if checked
Make lw={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}
i=0
j=20
do
if(L*lw[i]>max1)
j=i
break
endif
i+=1
while(i<numpnts(lw))
i=0
Make/N=(j) lw2
do
lw2[i]=lw[i]
i+=1
while(i<j)
Duplicate lw2,$lamx,$lamy
Wave lx = $lamx
Wave ly = $lamy
lx=L*lw2
i=0
j=0
do
do
if(xs[j]>lx[i])
ly[i]=ys[j]
break
endif
j+=1
while(j<numpnts(xs))
i+=1
while(i<numpnts(lx))
rename ly, $lamy
rename lx, $lamx
appendToGraph/W=difflinesplot ly vs lx
ModifyGraph/W=difflinesplot mode(lamy)=1,rgb(lamy)=(0,0,0)
endif
if(con>0) //Add cyl diffraction lines if checked
Make cw={1,3,4,7,9,12,13,16,19,21,25,27,28,31,36,37,39,43,48,49,52,57,61,63,64,67,73,75,76,79}
i=0
j=30
do
if(C*cw[i]^(1/2)>max1)
j=i
break
endif
i+=1
while(i<numpnts(cw))
i=0
Make/N=(j) cw2
do
cw2[i]=cw[i]^(1/2)
i+=1
while(i<j)
Duplicate cw2,$cylx,$cyly
Wave cx = $cylx
Wave cy = $cyly
cx=C*cw2
i=0
j=0
do
do
if(xs[j]>cx[i])
cy[i]=ys[j]
break
endif
j+=1
while(j<numpnts(xs))
i+=1
while(i<numpnts(cx))
rename cy, $cyly
rename cx, $cylx
appendToGraph/W=difflinesplot cy vs cx
ModifyGraph/W=difflinesplot mode(cyly)=1,rgb(cyly)=(0,0,65535)
endif
if(son>0) //Add sph diffraction lines if checked
Make
sw={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,
40}
i=0
j=40
do
if(S*sw[i]^(1/2)>max1)
j=i
break
endif
i+=1
while(i<numpnts(sw))
i=0
Make/N=(j) sw2
do
sw2[i]=sw[i]^(1/2)
i+=1
while(i<j)
Duplicate sw2,$sphx,$sphy
Wave sx = $sphx
Wave sy = $sphy
sx=S*sw2
i=0
j=0
do
do
if(xs[j]>sx[i])
sy[i]=ys[j]
break
endif
j+=1
while(j<numpnts(xs))
i+=1
while(i<numpnts(sx))
rename sy, $sphy
rename sx, $sphx
appendToGraph/W=difflinesplot sy vs sx
ModifyGraph/W=difflinesplot mode(sphy)=1,rgb(sphy)=(0,30000,0)
endif
if(gon>0) //Add gyr diffraction lines if checked
Make gw={6,8,14,16,20,22,24,26,30,32,38,40,42,46,48,50,52,54,56,62}
i=0
j=20
do
if(G*gw[i]^(1/2)>max1)
j=i
break
endif
i+=1
while(i<numpnts(gw))
i=0
Make/N=(j) gw2
do
gw2[i]=gw[i]^(1/2)
i+=1
while(i<j)
Duplicate gw2,$gyrx,$gyry
Wave gx = $gyrx
Wave gy = $gyry
gx=G*gw2
i=0
j=0
do
do
if(xs[j]>gx[i])
gy[i]=ys[j]
break
endif
j+=1
while(j<numpnts(xs))
i+=1
while(i<numpnts(gx))
rename gy, $gyry
rename gx, $gyrx
appendToGraph/W=difflinesplot gy vs gx
ModifyGraph/W=difflinesplot mode(gyry)=1,rgb(gyry)=(65535,0,0)
endif
End