40m QIL Cryo_Lab CTN SUS_Lab TCS_Lab OMC_Lab CRIME_Lab FEA ENG_Labs OptContFac Mariner WBEEShop
  TCS elog, Page 3 of 6  Not logged in ELOG logo
New entries since:Wed Dec 31 16:00:00 1969
ID Date Author Type Categorydown Subject
  56   Wed Jun 23 06:49:48 2010 AidanMiscHartmann sensorSURF Log -- Day 5, more Hartmann image preliminary analysis

Nice work!



 Today I spoke with Dr. Brooks and got a rough outline of what my experiment for the next few weeks will entail. I'll be getting more of the details and getting started a bit more, tomorrow, but today I had a more thorough look around the Hartmann lab and we set up a few things on the optical table. The OLED is now focused through a microscope to keep the beam from diverging quite as much before it hits the sensor, and the beam is roughly aligned to shine onto the Hartmann plate. The Hartmann images currently look like this (on a color scale of intensity):


Where this image was taken with the camera set to exposure time 650 microseconds, frequency 58Hz. The visible 'streaks' on the image are believed to possibly be an artifact of the camera's data acquisition process.

I tested to see whether the same 'flickering' is present in images under this setup.

For frequency kept at 58Hz, the following statistics were found from a 200x200 pixel box within series of 10 images taken at different exposure times. Note that the range on the plot has been reduced to the region near the relevant feature, and that this range is not being changed from image to image:

750 microseconds:


1000 microseconds:


1500 microseconds:


2000 microseconds:


3000 microseconds:


4000 microseconds:


5000 microseconds. Note that the background level is approaching the level of the feature:


6000 microseconds. Note that the axis setup is not restricted to the same region, and that the background level exceeds the level range of the feature. This demonstrates that the 'feature' disappears from the plot when the plot does not include the specific range of ~115-130:



When images containing the feature intensities are averaged over a greater number of images, the plot takes on the following appearance (for a 200x200 box within a series of 100 images, 3000us exposure time):


This pattern changes a bit when averaged over more images. It looks as though this could, perhaps, just be the result of the decrease in the standard deviation of the standard deviations in each pixel resulting from the increased number of images being considered for each pixel (that is, the line being less 'spread out' in the y-axis direction). 


To demonstrate that frequency doesn't have any effect, I got the following plots from images where I set the camera to different frequencies then set the exposure time to 3000us (I wouldn't expect this to have any effect, given the previous images, but these appear to demonstrate that the 'feature' does not vary with time):


Set to 30Hz:


Set to 1Hz:



To make sure that something weird wasn't going on with my algorithm, I did the following: I constructed a 10-component vector of random numbers. Then, I concatenated that vector besides itself ten times. Then, I concatenated that vector into a 3D array by scaling the 2D vector with ten different integer multiples, ensuring that the standard deviations of each row would be integer multiples of each other when the standard deviation was found along the direction of the random change (I chose the integer multiples to ensure that some of these values would fall within the range of  115-130). Thus, if my function wasn't making any weird mistakes, I would end up with a linear plot of standard deviation vs. mean, with a slope of 1. When the array was inputted into the function with which the previous plots were found, the output plot was indeed observed to be linear, and a least squares regression of the mean/deviation data confirmed that the slope was exactly 1 and the intercept exactly 0. So I'm pretty certain that the feature observed in these plots is not any sort of 'artifact' of the algorithm used to analyze the data (and all the functions are pretty simple, so I wouldn't expect it to be, but it doesn't hurt to double-check).


I would conjecture from all of this that the observed feature in the plots is the result of some property of the CCD array or other element of the camera. It does not appear to have any dependence on exposure time or to scale with the relative overall intensity of the plots, and, rather, seems to depend on the actual digital number read out by the camera. This would suggest to me, at first glance, that the behavior is not the result of a physical process having to do with the wavefront.


EDIT: Some late-night conjecturing: Consider the following,

I don't know how the specific analog-to-digital conversion onboard the camera works, but I got to thinking about ADCs. I assume, perhaps incorrectly, that it works on roughly the same idea as the Flash ADCs that I dealt with back in my Digital Electronics class -- that is, I don't know if it has the same structure (a linear resistor ladder hooked up to comparators which compare the ladder voltages to the analog input, then uses some comb logic circuit which inputs the comparator outputs and outputs a digital level) but I assume that it must, at some level, be comparing the analog input to a number of different voltage thresholds, considering the highest 'threshold' that the analog input exceeds, then outputting the digital level corresponding to that particular threshold voltage.

Now, consider if there was a problem with such an ADC such that one of the threshold voltages was either unstable or otherwise different than the desired value (for a Flash ADC, perhaps this could result from a problem with the comparator connected to that threshold level, for example). Say, for example, that the threshold voltage corresponding to the 128th level was too low. In that case, an analog input voltage which should be placed into the 127th level could, perhaps, trip the comparator for the 128th level, and the digital output would read 128 even when the analog input should have corresponded to 127.

So if such an ADC was reading a voltage (with some noise) near that threshold, what would happen? Say that the analog voltage corresponded to 126 and had noise equivalent to one digital level. It should, then, give readings of 125, 126 or 127. However, if the voltage threshold for the 128th level was off, it would bounce between 125, 126, 127 and 128 -- that is, it would appear to have a larger standard deviation than the analog voltage actually possessed.

Similarly, consider an analog input voltage corresponding to 128 with noise equivalent to one digital level. It should read out 127, 128 and 129, but with the lower-than-desired threshold for 128 it would perhaps read out only 128 and 129 -- that is, the standard deviation of the digital signal would be lower for points just above 128.

This is very similar to the sort of behavior that we're seeing!

Thinking about this further, I reasoned that if this was what the ADC in the camera was doing, then if we looked in the image arrays for instances of the digital levels 127 and 128, we would see too few instances of 127 and too many instances of 128 -- several of the analog levels which should correspond to 127 would be 'misread' as 128. So I went back to MATLAB and wrote a function to look through a 1024x1024xN array of N images and, for every integer between an inputted minimum level and maximum level, find the number of instances of that level in the images. Inputting an array of 20 Hartmann sensor images, along with minimum and maximum levels of 50 and 200, gave the following:


Look at that huge spike at 128! This is more complex of behavior than my simple idea which would result in 127 having "too few" values and 128 having "too many", but to me, this seems consistent with the hypothesis that the voltage threshold for the 128th digital level is too low and is thus giving false output readings of 128, and is also reducing the number of correct outputs for values just below 128. And assuming that I'm thinking about the workings of the ADC correctly, this is consistent with an increase in the standard deviation in the digital level for values with a mean just below 128 and a lower standard deviation for values with a mean just above 128, which is what we observe.


This is my current hypothesis for why we're seeing that feature in the plots. Let me know what you think, and if that seems reasonable.



  57   Wed Jun 23 22:57:22 2010 James KMiscHartmann sensorSURF Log -- Day 6, Centroiding

 So in addition to taking steps towards starting to set stuff up for the experiment in the lab, I spent a good deal of the day figuring out how to use the pre-existing code for finding the centroids in spot images. I spent quite a bit of time trying to use an outdated version of the code that didn't work for the actual captured images, and then once I was directed towards the right version I was hindered for a little while by a bug.

The 'bug' turns out to be something very simple, yet relatively subtle. In the function centroid_images.m in '/opt/EDTpdv/hartmann/src/', the function was assuming a threshold of 0 with my images, even though it has not long before been working with an image that Dr. Brooks loaded. Looking through the code, I noticed that before finding the threshold using the MATLAB function graythresh, several adjustments were made so as to subtract out the background and normalize the array. After estimating and subtracting a background, the function divides the entries of the image array by the maximum value in the image so as to normalize this. For arrays composed of numbers represented as doubles, this is fine. However, the function that I wrote to import my image arrays into MATLAB outputs an image array with integer data. So when the function divided my integer image arrays by the maximum values in the array, it rounded every value in the array to the nearest integer -- that is, the "normalized" array only contained ones and zeros. The function graythresh views this as a black and white image, and thus outputs a threshold of 0.

To remedy this, I edited centroid_images.m to convert the image array into an array of doubles near the very beginning of the function. The only new line is simply "image=double(image);", and I made a note of my edit in a comment above that line. The function started working for me after I did that.


I then wrote a function which automatically centroids an input image and then plots the centroids as scatter-plot of red circles over the image. For an image taken off of the Hartmann camera, it gave the following:


Zoomed in on the higher-intensity peaks, the centroids look good. They're a little offset, but that could just be an artifact of the plotting procedure; I can't say for certain either way. They all appear offset by the same amount, though:


One problem is that, for spots with a much lower relative intensity than the maximum intensity peak, the centroid appears to be offset:


Better centering of the beam and more even illumination of the Hartmann plate could mitigate this problem, perhaps.


I also wrote a function which inputs two image matrices and outputs vector field plots representing the shift in each centroid from the first to the second images. To demonstrate that I could use this function to display the shifting of the centroids from a change in the wavefront, I translated the fiber mount of the SLED in the direction of the optical axis by about 6 turns of the z-control knob  (corresponding to a translation of about 1.9mm, according to the user's guide for the fiber aligner). This gave the following images:


Before the translation:




 This led to a displacement of the centroids shown as follows:


Note that the magnitudes of the actual displacements are small, making the shift difficult to see. However, when we scale the displacement vectors up, we can get much more readily visible Direction vectors (having the same direction as the actual displacement vectors, but not the same magnitude):


This was a very rough sort of measurement, since exposure time, focus of the microscope optic, etc. were not adjusted, and the centroids are compared between single images rather than composite images, meaning that random noise could have quite an effect, especially for the lower-magnitude displacements. However, this plot appears to show the centroids 'spreading out', which is as expected for moving the SLED closer to the sensor along the optical axis.


The following MATLAB functions were written for this (both attached):

centroidplot.m -- calls centroid_image and plots the data

centroidcompare.m -- calls centroid_image twice for two inputs matrices, using the first matrix's centroid output structure as a reference for the second. Does a vector field plot from the displacements and reference positions in the second output centroids structure.

  58   Fri Jun 25 00:11:13 2010 James KMiscHartmann sensorSURF Log -- Day 7, SLED Beam Characterization


In order to conduct future optical experiments with the SLED and to be able to predict the behavior of the beam as it propagates across the table and through various optics, it is necessary to know the properties of the beam. The spot size, divergence angle, and radius of curvature are all of interest if we wish to be able to predict the pattern which should appear on the Hartmann sensor given a certain optical layout.

It was therefore necessary to conduct an experiment to measure these properties. The wavefront emanating from the SLED is assumed to be approximately Gaussian, and thus has an intensity of the form:


where A is some amplitude, w is the spot size, x and y are the coordinates transverse to the optical axis, and x0 is the displacement of the optical axis in the x-direction from the optical axis. The displacement of the optical axis in the y-direction is assumed to be zero (that is, y0=0). A and w are both functions of z, which is the coordinate of displacement parallel to the optical axis.


Notice that the total intensity read by a photodetector reading the entire beam would be the double integral from negative infinity to infinity for both x and y. If a opaque plate was placed such that the the beam was blocked from some x=xm to x=inf (where xm is the location of the edge of the plate), then the intensity read by a photodetector reading the entire non-blocked portion of the beam would be:


Mathematica was used to simplify this integral, and it showed it to be equivalent to:

where Erfc() is the complementary error function. Note that for fixed z, this intensity is a function only of xm. If an experiment was carried out to measure the intensity of the beam blocked by a plate from x=-inf to x=xm for multiple values of xm, it would therefore be possible via regression analysis to compute the best-fit values of A, w, and x0 for the measured values of Ipd and xm. This would give us A, w and x0 for that z-value. By repeating this process for multiple values of z, we could therefore find the behavior of these parameters as a function of z.

Furthermore, we know that at z-values well beyond the Rayleigh range, w should be linear with respect to z. Assuming that our measurements are done in the far-field (which, for the SLED, they almost certainly would be) we could therefore find the divergence angle by knowing the slope of the linear relation between w and z. Knowing this, we could further calculate such quantities as the Rayleigh range, the minimum spot size, and the radius of curvature of the SLED output (see p.490 of "Lasers" by Milonni and Eberly for the relevant functional relationships for Gaussian beams).


An experiment was therefore carried out to measure the intensity of of beam blocked from x~=-inf to x=xm, for multiple values of xm, for multiple values of z. A diagram of the optical layout of the experiment is below:


(top view)

The razor blade was mounted on a New Focus 9091 Translational Stage, the relative displacement of which in the x-direction was measured with the Vernier micrometer mounted on the base. Tape was placed on the front of the razor so as to block light from passing through any of its holes. The portion of the beam not blocked by the razor then passed through a lens which was used to focus the beam back onto a PDA1001A Large Area Silicon Photodiode, the voltage output of which was monitored using a Fluke digital multimeter. The ruler stayed securely clamped onto the optical table (except when it was translated in the x-direction once during the experiment, as described later).

The following is a picture of this layout, as constructed:


The procedure of the experiment was as follows: first, the translational stage was clamped securely with the left-most edge of its base lined up with the desired z-value as measured on the ruler. The z-value as measured on the ruler was recorded. Then, the translational stage was moved in the negative x-direction until there was no change in the voltage measured on the DMM (which is directly proportional to the measured intensity of the beam). When no further DMM readout change was yielded from -x translation, it was assumed that the the razor was no longer blocking the beam. Then, the stage was moved in the +x direction until the voltage output on the DMM just began to change. The micrometer and DMM values were both recorded. The stage was then moved inward until the DMM read a voltage which was close to the nearest multiple of 0.5V, and this DMM voltage and micrometer reading were recorded. The stage was then translated until the DMM voltage dropped by approximately 0.5V, the micrometer and DMM readings were recorded, and this process was repeated until the voltage reached ~0.5V. The beam output was then covered by a card so as to completely block it, and the voltage output from the DMM was recorded as the intensity from the ambient light from that measurement. The stage was then unclamped and moved to the next z-value, and this process was repeated for 26 different values of z, starting at z=36.5mm and then incrementing z upwards by ~4mm for the first ten measurements, then by increments of ~6mm for the remaining measurements.
The data from these measurements can be found on the attached spreadsheet.
A few notes on the experiment:
The vernier micrometer has a measurement limit of 13.5mm. After the tenth measurement, the measured xm values began to exceed this limit. It was therefore necessary to translate the ruler in the negative x-direction without translating it in the z-direction. Plates were clamped snugly to either side of the ruler such that the ruler could not be translated in the z-direction, but could be moved in the x-direction when the ruler was unclamped. After securing these plates, the ruler was moved in the negative x-direction by approximately 5mm. The ruler was then clamped securely in place at its new x location. In order to better estimate the actual x-translation of the ruler, I took the following series of measurements: I moved the stage to z-values at which sets of measurements were previously taken. Then, I moved the razor out of the beam path and carefully moved it back inwards until the output on the DMM matched exactly the DMM output of the first measurement taken previously at that z-value. The xm value corresponding to this voltage was then read. The translation of the stage should be approximately equal to the difference of the measured xm values for that DMM voltage output at that z-value. This was done for 8 z-values, and the average difference was found to be 4.57+-0.03mm, which should also be the distance of stage translation (this data and calculation is included in the "x translation" sheet of the attached excel workbook).
At this same point, I started using two clamps to attach the translational stage to the table for each measurement set, as I was unhappy with the level of secureness which one clamp provided. I do not, however, believe that the use of one clamp compromised the quality of previous sets of measurements.



A MATLAB function 'gsbeam.m' was written to replicate the function:

and then another function 'beamdata.m' was written to input each dataset, fit the data to a curve of the functional form of the previous function for each set of data automatically, and then output PDF files plotting all of the fit curves against each other, each individual fit curve against the data from that measurement, and a plot showing the widths w as a function of z. Linear regression was done on w against z to find the slope of the w(z) (which, for these measurements, is clearly shown by the plot that the beam was measured in the far-field and thus w is approximately a linear function of z). An array of the z-location of the ruler, the fit parameters A, x0, x, and the 2-norm of the residual of the fit is also outputted, and is shown below for the experimental data:


z(ruler) A x0 w 2normres
36.5 7.5915 11.089 0.8741 0.1042
39.9 5.2604 11.1246 1.048 0.1013
44 3.8075 11.1561 1.2332 0.1164
48 2.777 11.1628 1.4479 0.0964
52 2.1457 11.1363 1.6482 0.1008
56 1.6872 11.4206 1.858 0.1029
60 1.3831 11.2469 2.0523 0.1021
64 1.1564 11.1997 2.2432 0.1059
68 0.972 11.1851 2.4483 0.0976
72 0.8356 11.1728 2.6392 0.1046
78 0.67 6.8821 2.9463 0.0991
84 0.5559 6.7548 3.2375 0.1036
90 0.4647 6.715 3.5402 0.0958
96 0.3993 6.7003 3.8158 0.1179
112 0.2719 6.8372 4.6292 0.0924
118 0.2398 6.7641 4.925 0.1029
124 0.2117 6.7674 5.2435 0.1002
130 0.189 6.8305 5.5513 0.0965
136 0.1709 6.8551 5.8383 0.1028
142 0.1544 6.8243 6.1412 0.0981
148 0.1408 6.7993 6.4313 0.099
154 0.1286 6.8062 6.7322 0.0948
160 0.1178 6.9059 7.0362 0.1009
166 0.1089 6.904 7.3178 0.0981
172 0.1001 6.8817 7.6333 0.1025
178 0.0998 6.711 7.6333 0


All outputted PDF's are included in the .zip file attached. The MATLAB functions themselves are also attached.The plots of the fit curves and the plot of the widths vs. the ruler location are also included below:


(note that I could probably improve on the colormap that I chose for this. note also that the 'gap' is because I temporarily forgot how to add integers while taking the measurements, and thus went from 96mm on the ruler to 112mm on the ruler despite going by a 6mm increment otherwise in that range. Also, note that all of these fit curves were automatically centered at x=0 for the plot, so they wouldn't necessarily intersect so neatly if I tried to include the difference in the estimated 'beam centers')

(note that the width calculated from the 26th measurement is not included in the regression calculation or included on this plot. The width parameter was calculated as being exactly the same as it was for the 25th measurement, despite the other parameters varying between the measurements. I suspect that the beam size was starting to exceed the dimensions blocked by the razor and that this caused this problem, and that would be easy to check, but I have yet to do it. Regardless, the fit looks good from just the other 25 measurements)

These results are as expected: that the beam spot-size should increase as a function of z and that it should do so linearly in the far-field. My next step will be to use the results of this experiment to calculate the properties of the SLED beam, characterizing the beam and thusly enabling me to predict its behavior within further optical systems.


  61   Wed Jun 30 00:00:13 2010 Kathryn and WonComputingHartmann sensorrms of centroid position changes

Given below is a brief overview of calculating rms of spot position changes to test the accuracy/precision of the centroiding code. Centroids are obtained by summing over the array of size 30 by 30 around peak pixels, as opposed to the old method of using matlab built-in functions only. Still peak pixel positions were obtained by using builtin matlab function. Plese see the code detect_peaks_bygrid.m for bit more details.


My apologies for codes being well modularised and bit messy...


Please unzip the attached file to find the matlab codes.

The rest of this log is mainly put together by Kathryn.




(EDIT/PS) The attached codes were run with raw image data saved on the hard disk, but it should be relatively easy to edit the script to use images acquired real time. We are yet to play with real-time images, and still operating under Windows XP...

When calculating the rms, the code outputs the results of two
different methods. The "old" method is using the built-in matlab
method while the "new" method is one Won constructed and seems to
give a result that is closer to the expected value. In calculating
and plotting the rms, the following codes were used:

- centroid_statics_raw_bygrid.m (main script run to do the analysis)
- process_raw.m (takes raw image data and converts them into 2D array)
- detect_peaks_bygrid.m (returns centroids obtained by old and new methods)
- shuffle.m (used to shuffle the images before averaging)

The reference image frame was obtained by averaging 4000 image frames,
the test image frames were obtained by averaging 1, 2, 5, 10 ... 500,
1000 frames respectively, from the remaining 1000 images.

In order to convert rms values in units of pixels to wavefront
aberration, do the following:

aberration = rms * pixel_width * hole_spacing / lever_arm

pixel_width: 12 micrometer
hole_spacing: about 37*12 micrometer
lever_arm: 0.01 meter

rms of 0.00018 roughly corresponds to lambda over 10000.

Note: In order to get smaller rms values the images had to be shuffled
before taking averages. By setting shuffle_array (in
centroid_statics_raw_bygrid.m) to be false one can
turn off the image array shuffling.

N_av        rms

1     0.004018866673087
2     0.002724680286563
5     0.002319477846009
10    0.001230553835673
20    0.000767638027270
50    0.000432681002432
100   0.000427139665006
200   0.000270955332752
500   0.000226521040455
1000  0.000153760240692

fitted_slope = -0.481436501422376

Here are some plots:



Next logs will be about centroid testing with simulated images, and wavefront changes due to the change in the camera temperature!

(PS) I uploaded the same figure twice by accident, and the site does not let me remove a copy!...

  62   Thu Jul 1 09:40:13 2010 James KunertMiscHartmann sensorSURF Log 8 -- more SLED characterization

As I started setting up my next experiment, I noticed that the beam size from the SLED appeared to be larger than expected from previous analysis. It was therefore necessary to conduct further experiments to characterize the divergence angle of the beam.

First, I set up the photodetector attached to an SLED and mounted a razor blade on a translational stage, in the same manner as done previously. All of these components were the exact same ones used in the previous beam size experiment. The only differences in the components of the apparatus were as follows: first, the photodetector was placed considerably closer to the SLED source than was done previously. Second, a different lens was used to focus the light onto the photodetector. Lens LX082 from the lenskit was used, which is a one-inch lens of focal length f=50.20mm.

Experiment 1: Columnated Beam Size Measurement

Before repeating the previous experiment, the following experiment was done: the beam was columnated by placing the lens 50.20mm away from the source and then adjusting until columnation was observed. Columnation was confirmed by setting a mirror in the optical path of the beam directing it to the other side of the room. The position of the lens along the optical axis was adjusted until the beam exiting the lens did not change in size across the length of the table and appeared to be roughly the same size as the spot on the opposite side of the room (as gauged roughly by the apparent size on an IR card and through an IR viewer).

Then,the translational stage onto with the laser was mounted was placed after the lens against the ruler clamped to the table, and beam size was measured using the same experimental procedure used to find the width in the previous experiment. The only variation in the experimental procedure was that measurements were not taken strictly at 0.5V intervals; rather, intensity readings were taken for 28 different intensity outputs. The following measurements were collected:

x(mm)   V(V)
13.00  7.25
12.00  7.24
10.80   7.18
10.15   7.09
9.50   6.92
9.30   6.86
9.00   6.74
8.75   6.61
8.50   6.47
8.25   6.31
8.00   6.12
7.75   5.92
7.50   5.69
7.30   5.49
7.15   5.33
7.00   5.17
6.75   4.88
6.50   4.58
6.25   4.27
6.00   3.95
5.75   3.63
5.50   3.32
5.25   3.02
5.00   2.729
4.60   2.306
4.50   2.205
4.25   1.981
4.00 1.770
ambient 0.585

When fit to gsbeam.m using lsqcurvefit, this yielded a width of 4.232mm. Since the beam is columnated through the lens, we know that it is approximately f=50.2mm from the source. Thus the divergence angle is approximately 0.084.

At this point, to double-check that the discrepency between this value and the previous experiment was not a result of a mistake in the function, I wrote a simpler function to go through the steps of using lsqcurvefit and plotting the fit curve versus the data automatically, 'manualbeam.m' (attached), which simply fits a curve to one set of data from a constant z-value. Using this one-by-one on each z-value in the previous experiment, it was shown that the slope of the widths was still ~0.05, so this discrepency was not the result of a mistake in the previous function somewhere.

Experiment 2: Blocked Beam Analysis 2

I then placed the razor before the lens in the beampath and repeated the previous experiment exactly. See the previous eLog for details on experimental procedure. Sets of measurements were taken at 6 different z-values, and widths were found using manualbeam.m in MATLAB. A curve of the calculated widths versus the z-position of the stage on the ruler is below:


Note that this appears to be consistant with the first experiment.

Experiment 3: Direct Beam Measurements on CCD

The front-plate of the Hartmann sensor was replaced with the new invar design (on a related note, the thread on the front plate needs a larger chamfer). In doing this, the Hartmann plate was removed. The sensor was moved much closer to the SLED along the optical axis, and an optical filter of OD 0.7 was screwed into the new frontplate. This setup allows for the direct imaging of the intensity of the beam, as shown below:


The spots and distortions on the image are from dust and other blemishes on the optical filter, as was confirmed by rotating the filter and observing the subsequent rotation of each feature.

Note that in some images, there may be a jump in intensity in the middle of the image. This is believed to be due to a inconsistant gain between the two sides of the image.

The means of the intensities of each row and each column will be Gaussian, and thus can be fit to a Gaussian using lsqcurvefit. Function 'gauss_beam1D.m' was written and this function was fit to using function 'autogaussfit1', which automatically imports the data from .raw files, fits Gaussians to the means of each row and column, and plots everything.

An example of the fit for the means of the columns of one image is as follows:


 And for the rows:


Note that for all the fits, the fitting generally looks a little better along the row than along the column (which is true here, as well).

The following procedure was used to calculate the change of the beam width as a function of distance: the left edge of the base of the Hartmann sensor was measured against a ruler which was clamped to the table. The ruler position z was recorded. Then, preliminary images would be taken and the exposure time would be adjusted as needed. The exposure time was then noted. Then, an image was taken and curves were fit to it, and the width was calculated. This was done for 15 different positions of the Hartmann sensor along the optical axis.

The calculated widths vs. displacements plot from this can be seen below:


Note that the row width and column width are not the same, implying that the beam is not circularly symmetric and is thusly probably off alignment by a little bit. Also, the calculated slopes are different than the value of 0.085 acquired from the previous two measurements. Further investigation into the beam size and divergence angle is required to finally put this question to rest.

  63   Sun Jul 4 06:45:50 2010 Kathryn and WonComputingHartmann sensoranalyzing the wavefront aberration

Happy Fourth of July!

The following is a brief overview of how we are analyzing the wavefront aberration and includes the aberration parameters calculated for 9 different temperature differences. So far we are still seeing the cylindrical power even after removing the tape/glue on the Hartmann plate. Attached are the relevant matlab codes and a couple of plots of the wavefront aberration.

We took pictures when the camera was in equilibrium at room temperature and then at each degree increase in camera temperature as we heated the room using the air conditioner. For each degree increase in camera temperature, we compared the spot positions at the increased temperature to the spot positions at room temperature. We used the following codes to generate the aberration parameters and make plots of the wavefront aberration:

-build_M.m (builds 8 by 8 matrix M from centroid displacements)
-wf_aberration_temperature_bygrid.m (main script)
-wf_from_parms.m (generates 2D aberration array from aberation parameters)
-intgrad2.m (generates 2D aberration array from an interpolated array of centroid displacements)

In order to perform the "inverse gradient" method to obtain contours, we first interpolated the centroid displacement vectors to generate a square array. As this array has some NaN (not a number) values, we cropped out some outer region of the array and used array values from (200,200) to (800,800). Sorry we forgot to put that part of the code in wf_aberration_temperature_bygrid.m.

The main script wf_aberration_temperature_bygrid.m needs to be revised so that the sign conventions are less confusing... We will update the code later.

The initial and final temperature values are as follows:


  Hand-held Digitizer Board Sensor Board
Initial 30.8 44.4 36.0
Final 40.8 51.2 43.2


Aberration parameters:

1) Comparing high temp (+10)  with room temp

        p: 1.888906773203923e-004
       al: -0.295042766811686
      phi: 0.195737681653530
        c: -0.001591869846958
        s: -0.003826146141562
        b: 0.098283157674967
       be: -0.376038636781319
        a: 5.967617809296910

2) Comparing +9 with room temp

        p: 1.629083055002727e-004
       al: -0.222506109890745
      phi: 0.193334452094940
        c: -0.001548838746542
        s: -0.003404217451916
        b: 0.091368295953142
       be: -0.351830698303612
        a: 5.764068008962653

3) Comparing +8 with room temp

        p: 1.485283322069376e-004
       al: -0.212605187544093
      phi: 0.206716196097728
        c: -0.001425962488852
        s: -0.003148796701331
        b: 0.089936286297599
       be: -0.363538909377296
        a: 5.546514425485094

4) Comparing +7 with room temp

        p: 1.284124028380585e-004
       al: -0.163672705473379
      phi: 0.229219952949728
        c: -0.001452457146947
        s: -0.002807207555944
        b: 0.084090100490331
       be: -0.379195428095102
        a: 5.289173743478881

5) Comparing +6 with room temp

        p: 1.141756950753851e-004
       al: -0.149439038317734
      phi: 0.240503450300707
        c: -0.001350015836130
        s: -0.002529240946848
        b: 0.078118977034120
       be: -0.326704416216547
        a: 4.847406652448727

6) Comparing +5 with room temp

        p: 8.833496828581757e-005
       al: -0.071871278822766
      phi: 0.263210114512376
        c: -0.001257787180513
        s: -0.002095618522105
        b: 0.069587080420443
       be: -0.335912998511077
        a: 4.542557551218057

7) Comparing +4 with room temp

        p: 6.217428324604411e-005
       al: 0.019965235199575
      phi: 0.250991433584904
        c: -0.001266061216964
        s: -0.001568527823273
        b: 0.058323732750548
       be: -0.289315790283207
        a: 3.957825468583509

8) Comparing +3 with room temp

        p: 4.781068895714900e-005
       al: 0.140720713391208
      phi: 0.270865276786418
        c: -0.001228146894728
        s: -0.001371110045136
        b: 0.052794990899554
       be: -0.273968130963666
        a: 3.591187350052610

9) Comparing +2 with room temp

        p: 2.491163442408281e-005
       al: 0.495136135872766
      phi: 0.220727346409557
        c: -9.897729773516012e-004
        s: -0.001076008621974
        b: 0.048467660428427
       be: -0.280879088681660
        a: 3.315430577872808

10) Comparing +1 with room temp

       p: 8.160828332639811e-006
      al: 1.368853902659128
     phi: 0.116300954280238
       c: -6.149390553733007e-004
       s: -3.621216621887707e-004
       b: 0.025454969698557
      be: -0.242584267252882
       a: 1.809039775332749

The first plot is of the wavefront aberration obtained by integrating the gradient of the aberration and the second plot fits the aberration according to the aberration parameters so is smoother since it is an approximation.

  64   Tue Jul 6 21:57:19 2010 James KunertMiscHartmann sensorSURF Log -- SLED fiber output temporal analysis

In the previous log, I describe the direct measurement of the fiber output beam using the Hartmann sensor with the plate removed. In order to analyze how these properties might change as a function of time, we left the camera running over the holiday weekend, Dr. Brooks having written a bash script which took images from the sensor every 500 seconds. This morning I wrote a MATLAB script to automatically analyze all of these images and plot the fit parameters as a function of time (weekendbeamtime.m, attached). Note that the formatiing of a few of the following graphs was edited manually after being outputted by the program (just to note why the plots look different than the code might imply).

The following plots were made:

Amplitude as a function of time:


Amplitude again, focused in with more analysis:



Offset level:



Beam Size:



Centroid Displacement (note the axis values, it's fairly zoomed in):


Note that these values were converted into radians by approximating the fiber-output/CCD distance and dividing this from the displacement in mm (after converting from pixels). This distance was approximated by assuming a divergence angle of 0.085 and a beam size of ~5.1mm (being a value inbetween the horizontal and vertical beam sizes calculated). This gave a value of ~60mm, which was confirmed as plausible by a quick examination in the lab.

In the first three plots, there are obvious temporary effects which seem to cause the values to fluctuate much more rapidly than they do for the rest of the duration. It is suspected that this could be related to temperature changes within the sensor as the camera begins taking images. Further investigation (tomorrow) will investigate these effects further, while collecting temperature data.

  65   Thu Jul 15 20:06:37 2010 James KMiscHartmann sensorSURF Log: Thermally Induced Defocus Experiments

A quick write-up on recent work can be found at: Google Docs


I can't find a Tex interpreter or any other sort of equation editor on the eLog, is why I kept it on Google Docs for now instead of transferring it over.




  69   Thu Jul 22 21:46:55 2010 James KunertMiscHartmann sensorHartmann Sensor Thermal Defocus Measurement Noise & Ambient Light Effects

As discussed during the teleconference, a series of experiments have been conducted which attempt to measure the thermally induced defocus in the Hartmann sensor measurement. However, there was a limiting source of noise which caused a very large displacement of the centroids between images, making the images much too noisy to properly analyze.

The general setup of this series of experiments is as follows: the fiber output from the SLED was mounted about one meter away from the Hartmann sensor. No other optics were placed in the optical path. Everything except for the Hartmann sensor was enclosed (a box was constructed out of wall segments and posterboard, with a hole cut in the end which allowed the beam to propagate into the sensor. The sensor was a short distance from the end of the box, less than a centimeter. There was no obvious difference in test images taken with the lights on and the lights off, which previously suggested to me that ambient light would not have a large effect). Temperature variations in the sensor were induced by changing the set temperature of the lab with the thermostat. A python script was used to take cumulative sums of 200 images (taken at 11Hz) every ~5 minutes.

This overly large centroid displacement appeared only in certain areas of the images. However, changing the orientation of the plate appeared to change the regions which were noisy. That is, if the orientation of the Hartmann plate was not changed between measurements, the noise would appear in the same regions in consecutive experiments (even in experiments conducted on different days). However, if the orientation of the Hartmann plate was changed between measurements, the noise would appear in a different region in the next experiment. This suggests that the noise is perhaps due to a physical phenomenon which would change with the orientation of the plate.

There were a few hypotheses which attempted to explain this noise but were shown to not be the likely cause. I hypothesized that the large thermal expansion coefficient of the aluminum camera housing could be inducing a stress on the invar frontplate, causing the Hartmann plate to warp. This hypothesis was tested by loosening the screws which attach the front and back portion of the frontplate (such that the Hartmann plate was not strongly mechanically coupled with the rest of the frontplate) and running another iteration of the experiment. The noisy regions were seen to still appear, indicating that thermally induced stress was not the cause of the distortion. Furthermore, experiments done while the sensor was in relative thermal equilibrium over long periods still showed noisy regions, and there was no apparent correlation between noise magnitude and sensor temperature for any experiment, indicating that thermal effects in general were not responsible.

Another suspected cause was the increased noise at intensity levels of 128 (as discussed in a previous eLog). However, it was observed that there was no apparent difference in the prevalence of 128-count pixels between the noisy regions and the cleaner regions, indicating that this was not the cause either.

A video was made which shows vector plots of centroid displacements for each summed image relative to the first image taken in an experiment, and was posted as an unlisted youtube video at: http://www.youtube.com/watch?v=HUH1tHRr98I

The length of each vector in the video is proportional to the magnitude of the displacement. The localization of the noise can be seen. Notice also the sudden appearance and disappearance of the noise at images 19 and 33, indicating that the cause of the noise is relatively sudden and does not vary smoothly.

Another video showing a logarithmic plot of the absolute value of the difference of each image from the first image (for the same experiment as previous) can be seen here: http://www.youtube.com/watch?v=_CiaMpw9Ig0

Notice there are jumps in the background level which appear to correspond with the disappearance and appearance of the noisy regions in the centroids (at images 18 and 32) (I forgot to manually set the framerate on these last three .avi's, so they go by a little too quickly, but it's still all there). The one-image delay between the intensity shift and centroid noise shift is perhaps related to the fact that the analysis uses the previous image centroids as the reference to find the new image centroid locations.

A video showing histograms of the intensity of each pixel in an image (within the intensity range of 50 and 140 in the averaged summed-image) for this same experiment can be seen at: http://www.youtube.com/watch?v=MogPd-vaWn4

Notice that the peak of the distribution corresponding to the background appears to shift by ~5 counts at images 18 and 32.


An experiment was then done which had the exact same procedure except that it was done at a stabilized lab temperature and with the SLED turned off, such that only the background appears in each image. A logarithmic plot of the absolute value of the difference in intensity at each pixel for each image can be seen at: http://www.youtube.com/watch?v=Y66wL5usN18

Other work was being done in the lab throughout the day, so the lights were on for every image but one. I made a point of turning off the lights while the 38th image was being taken. The framerate of the linked video is unfortunately a little too fast to really see what goes on (I adjusted the framerate while viewing it in MATLAB but forgot to do so for the AVI), but you can clearly see a major change in the image during the 38th image, and during that image only (it looks like a red 'flash' at the 38th frame, near the very end). The only thing that was changed while taking this specific image was the ambient light level, so this major difference must be due to ambient light. A plot of the difference between images 38 and 1 is shown below:


Note that the maximum difference between the images is 1107 levels, which for the 200 images in each summed image corresponds to an average shift of ~5.5 levels. This is of a very similar magnitude to the shift that can be seen in the histogram of the previous experiment. This suggests that changes in ambient light levels are perhaps somehow responsible for the noisy regions of the image. Note also the non-uniformity of the ambient light; such a non-uniform change could certainly shift the centroid positions.

One question is how, exactly, this change might have propagated into the analysis. The shape of the background level change appears to be very different from the shape of the noisy regions seen for this plate configuration. This is something which I need to examine further; this, combined with the fact that the changes in the noise appear to occur one image after the actual change in intensities, suggests to me that there could perhaps be some subtle things going on with my data analysis procedures which I don't currently fully understand.

Still, I highly suspect that ambient light is the root cause of the noisy regions. It would be a remarkable coincidence if the centroid displacement shift was not ultimately due to the observed intensity shift, or if the intensity shift was not due to a change in ambient light (since the intensity shift in the histogram analysis and ambient light change in the background analysis are observed to correspond to roughly the same magnitude of intensity change). I had initially suspected that effects from ambient light would be negligible since, while taking test images while setting up each experiment, the image did not appear to change based upon whether I had the lights on or off. I checked this a few times, but did not examine the images closely enough to be able to detect such a small non-uniform change in the intensity of each image.

If ambient light was responsible, this could also perhaps explain why the location of the noise appeared to depend on the orientation of the plate. The Hartmann plate would be in the optical path of any ambient light leaking in, so a change in the orientation of the plate could perhaps change the way that the ambient light was propagating onto the sensor (especially since the Hartmann plates are slightly warped and not perfectly planar). That's all purely speculation at this point, but it's something that I intend to investigate further.

I tried analyzing some previous data by subtracting part of the background, but was unsuccessful at reducing the noise in the results. I attempted to reduce the background in previous data by setting all values below a certain threshold equal to zero (before inputting the image into the centroiding function). However, the maximum threshold which I could use before getting an error message was ~130. If I set the threshold to, say, 135, I received an error from the centroiding function that the image was 'too dissimilar to the hex grid'. I did analysis of the images with a threshold of 130, but this still left random patches of background spaced between the spots in each image. The presence of only patches of background as opposed to the complete background actually increased the level of noise in the results by about a factor of 3. I would need to come up with a better method of subtracting the background level if I wanted to actually reduce the noise in this data.

The next step in this work, I think, will perhaps be to better enclose the system from ambient light to where I'm confident that it could have little or no effect. If noisy regions were not seen to appear after this was done, that would more or less confirm that ambient light was the cause of all this trouble. Hopefully, if ambient light is indeed the cause of the noise, reducing it will enable an accurate and reliable measurement of thermally induced defocus within the Hartmann sensor.

  70   Fri Jul 23 10:33:08 2010 AidanComputingHartmann sensorDalsa camera ADC 8th digitizer error

I plotted a histogram of the total intensity of the Hartmann sensor when illuminated and found that the 128 count problem extends all the way up through the distribution. This isn't unreasonable since that digitizer is going to be called on mutliple times.

First things first, the value of 128 equals a 1 in the 8th digitizer, so for a 16-bit number in binary, it looks like this: 0000 0000 1000 0000 and in hex-code 080

The values of the peaks in the attached distribution are as follows:


Number of counts Hex Code


384  180
640  280
896  380
1152  480
1408  580
1664  680
1920  780
2176  880
2432  980
2688  A80
2944  B80
3200  C80


  71   Fri Jul 23 12:33:51 2010 AidanComputingHartmann sensorInvar clamp scatter

I illuminated the Hartmann sensor with the output of a fiber placed ~1m away.

I noticed that the illumination was not uniform, rather there was some sort of 'burst' or 'star' right near the center of the image. This turned out to be due to the Hartmann plate clamps - it disappeared when I removed those. It appears that there is scatter off the inner surface of the holes through the clamp plates. I'm not sure if it's from the front or back plates.

Needs further investigation ...

  72   Fri Jul 23 12:38:58 2010 AidanComputingHartmann sensorImages for Dalsa

Attached are the background and 80% illumination (~uniform spatially uniform) images that Dalsa requested.

Note that the gain of the taps does not appear to be balanced.


  73   Fri Jul 23 19:52:49 2010 AidanComputingHartmann sensorDalsa camera ADC 8th digitizer error

I've attached an image that shows the locations of those pixels that record a number of counts = (2*n-1)*128. 

The image is the sum of 200 binary images where pixels are given values of 1 if their number of counts = (2*n-1)*128 and 0 otherwise.

The excess of counts is clearly coming from the left hand tap. This is good news because the two taps have independent ADCs and it suggests that it is only a malfunctioning ADC on the LHS that is giving us this problem.


I plotted a histogram of the total intensity of the Hartmann sensor when illuminated and found that the 128 count problem extends all the way up through the distribution. This isn't unreasonable since that digitizer is going to be called on mutliple times.

First things first, the value of 128 equals a 1 in the 8th digitizer, so for a 16-bit number in binary, it looks like this: 0000 0000 1000 0000 and in hex-code 080

The values of the peaks in the attached distribution are as follows:


Number of counts Hex Code


384  180
640  280
896  380
1152  480
1408  580
1664  680
1920  780
2176  880
2432  980
2688  A80
2944  B80
3200  C80



  74   Sat Jul 24 10:50:14 2010 AidanElectronicsHartmann sensorLab Temperature and HWS temperature: pre-indium

 Hour-long trend puts the lab temperature at 19.51C

Dalsa temperature:


Camera Temperature on Digitizer Board: 41.0 Celsius
Camera Temperature on Sensor Board: 32.9 Celsius
There is currently no Indium in the HWS.


  77   Mon Jul 26 12:17:25 2010 AidanElectronicsHartmann sensorAdded Indium to HWS

 I added some 0.004" thick indium sheet to the copper heat spreaders and and the heat sinks on the side of the HWS to try and improve the thermal contact. Once installed the steady state temperature of the sensor was the same as before. It's possible that the surface of the copper is even more uneven than 0.004".



  78   Mon Jul 26 18:47:12 2010 James KMiscHartmann sensorHex Grid Analysis Errors and Thermal Defocus Noise

My previous eLog details how the noise in Hartmann Sensor defocus measurements appears to vary with ambient light. New troubleshooting analysis reveals that the rapid shifts in the noise were still related to the ambient light, sort of, but that ambient light is not the real issue. Rather, the noise was the result of some trouble with the centroiding algorithm.

The centroiding functions I have been using can be found on the SVN under /users/aidan/cit_centroid_code. When finding centroids for non-uniform intensity distributions, it is desirable to avoid simply using a single threshold level to isolate individual spots, as dimmer spots may be below this threshold and would therefore not be "seen" by the algorithm. The centroiding functions used here get around this issue by initially setting a relatively high threshold to find the centroids of the brighter spots, and then fitting a hexagonal close-packed array to these spots so as to be able to infer where the rest of the spots are located. Centroiding is then done within small boxes around each estimated centroid location (as determined by the hexagonal array). The functions "find_hex_grid.m" and "flesh_out_hex_grid.m" serve the purpose of finding this hexagonal grid. However, there appear to be bugs in these functions which compromise the ability of the functions to accurately locate spots and their centroids.

The centroiding error can be clearly seen in the following plot of calculated centroids plotted against the raw image from which they were calculated:


At the bottom of the image, it can be seen that the functions fail at estimating the location of the spots. Because of this, centroiding is actually being done on a small box surrounding each point which consists only of the background of the image. This can explain why these centroids were calculated to have much larger displacements and shifted dramatically with small changes in ambient light levels. The centroiding algorithm was being applied to the background surrounding each of these points, so it's very reasonable to believe that a non-uniform background fluctuation could cause a large shift in the calculated centroid of each of these regions.

It was determined that this error arose during the application of the hex grid by going through the centroiding functions step-by-step to narrow down where specifically the results appeared to be incorrect. The function's initial estimate for the centroids right before the application of the hex grid  is shown plotted against the original image:


The centroids in this image appear to correspond well to the location of each spot, so it does not appear that the error arises before this point in the function. However, when flesh_out_hex_grid and its subfunction find_hex_grid were called, they produced the following hexagonal grid:


It can be seen in this image that the estimated "spot locations" (the intersections of the grid) near the bottom of the image differ from the actual spot locations. The centroiding algorithm is applied to small regions around each of these intersections, which explains why the calculated "spot centroids" appear at incorrect locations.

It will be necessary to fix the hexagonal grid fitting so as to allow for accurate centroiding over non-uniform intensity distributions. However, recent experiments in measuring thermally induced defocus produce images with a fairly uniform distribution. It should therefore be possible to find the centroids of the images from these experiments to decent accuracy by simply temporarily bypassing the hexagonal-grid fitting functions. To demonstrate this, I analyzed some data from last week (experiment 72010a). Without bypassing the hex-grid functions, analysis yielded the following results:


However, when hexagonal grid fitting was bypassed, analysis yielded the following:


The level of noise in the centroid displacement vs. centroid location plot, though still not ideal, is seen to decrease by nearly two orders of magnitude. This indicates that bypassing or fixing the problems with the hexagonal grid fitting functions should enable a more accurate measurement of thermally induced defocus in future experiments.

  82   Fri Jul 30 10:04:54 2010 AidanComputingHartmann sensorRestarted the HWS EPICS channels

 Restarted the HWS EPICS channels on hartmann with the following command:

/cvs/opt/epics-3.14.10-RC2-i386/base/bin/linux-x86/softIoc -S HWS.cmd &

  83   Fri Jul 30 11:01:31 2010 AidanComputingHartmann sensorEPICS softIoc alias

 I added an alias HWSIoc to controls which can be used to start the HWS EPICS softIoc.


alias HWSIoc='/cvs/cds/caltech/target/softIoc/startHWSIOC.sh'
and the bash script is:

cd /cvs/cds/caltech/target/softIoc
/cvs/opt/epics-3.14.10-RC2-i386/base/bin/linux-x86/softIoc -S  /cvs/cds/caltech/
target/softIoc/HWS.cmd &
cd -


  84   Fri Jul 30 13:38:39 2010 James KunertComputingHartmann sensorSummary of Thermal Defocus Data Analysis

Below is a table summarizing the results of recent thermal defocus experiments. The values are the calculated change in measured defocus per unit temperature change of the sensor:

Experiment 72710a 72710b 72810a 72910a
DeltaS/DeltaT (x) [m^-1/K] -1.31E-4 -1.46E-4 -1.40E-4 -1.52E-4
DeltaS/DeltaT (y) [m^-1/K] -1.63E-4 -1.53E-4 -1.56E-4 -1.70E-4

More detail on these experiments will be available in my second progress report, which will be uploaded to the LIGO DCC by next Monday.

The main purpose of this particular eLog is to summarize what functions I wrote and used to do this data analysis, and how I used them. All relevant code which is referenced here can be found on the SVN; I uploaded my most recent versions earlier today.

Here is a flowchart summarizing the three master functions which were specifically addressed for each experiment:


py4plot.m is probably the most complicated of these three functions, in terms of the amount of data analysis done, so here's a flowchart which shows how the function works and the main subfunctions that it addresses:



Also, here is a step-by-step example of how these functions might be used during a particular experiment:


(1)Suppose that I have an experiment which I have named "73010a", in which I wish to take 40 images of 200 sums. I would open the code for framesumexport2.py and change lines 7, 8 and 17 to read:

7  LoopN=40
8 SumN=200
17 mainoutbase="73010a"

And I would then save the changes. I would double-check that the output basename had indeed been changed to 73010a (it will overwrite existing data files, if you forget to change the basename before running it). I would then let the script run (changing the set temperature of the lab after the first summed image was taken). Note that the total duration of the measurement is a function of how many images are summed and how many summed images are taken (in this example, if I was taking each single image at a rate of 11Hz, data collection would take ~20 seconds and data processing (summing the images) would take ~4 minutes (on the order of ~1 second per image in the sum) (the script isn't very quick at summing images, obviously).

EDIT(7/30 3:40pm):  I just updated framesumexport2.py so that the program prompts you for this information. I also changed enabled execute permissions on the copy of the code on the Hartmann machine located in /users/jkunert/, so going to that directory and typing ./framesumexport2.py then inputting the information when prompted is all you need to do now. No need to go change around the actual code every time, any more.


(2)Once data collection had ceased entirely, I would open MATLAB and enter the following:


The function would then look for 73010a.raw and 73010a.txt in ./opt/EDTpdv/ and import the 40 images individually and centroid them. The x and y outputs are the centroid locations. If, for example, 952 centroids were located, x and y would be 952x1x40 arrays. M would be a 40x4 array of the form:

[time_before_img_taken      time_after_img_taken      digitizer_temp      sensor_temp]


(3)Once MATLAB had finished the previous function, I would input:

py4plot('73010a',0,39,x,y,'73010a','200',[1 952],2,tG)

The inputs are, respectively:

(1)python output basename,
(2)first image to analyze (where the first image is image 0),
(3)last image to analyze,
(4)x data (or, rather, data to analyze. to analyze y instead, just flip around "x" and "y" in the input),
(5)y data (or, if you want to analyze the y-direction, "x" would be the entry here),
(6)experiment name,
(7)number of sums in each image (as a string),
(8)range of centroids to include in analysis (if you have 952 centroids, for example, and no ridiculous noise at the edges of the CCD, then [1 952] would be the best entry here),
(9)outlier tolerance (number of standard deviations from initial fit line that a datapoint must be within to be included in the second line fitting, in the dx vs x plot),
(10)exponential fitting structure (input an empty structure unless the temperature/time exponential fit turns out poorly, in which case a better fit parameter guess can be inputted as field tG.guess)

  88   Wed Aug 4 09:57:38 2010 Aidan, JamesComputingHartmann sensorRMS measurements with Hartmann sensor


We set up the Hartmann sensor and illuminated it with the output from the fiber-coupled SLED placed about 1m away. The whole arrangement was covered with a box to block out ambient light. The exposure time on the Hartmann sensor was adjusted so that the maximum number of counts in a pixel was about 95% of the saturation level.

We recorded a set of 5000 images to file and analyzed them using the Caltech and Adelaide centroiding codes. The results are shown below. Basically, we see the same deviation from ideal improvement that is observed at Adelaide.

  92   Wed Aug 18 18:38:11 2010 AidanComputingHartmann sensorHartmann sensor code

 I downloaded and tested revision 47 of the Adelaide Hartmann sensor code from the SVN (https://trac.ligo.caltech.edu/Hartmann_Sensor/browser/users/won/HS_OO?rev=47). After giving it the correct input filenames it centroided the Hartmann sensor images pretty seamlessly. The output and code is attached below.

The code takes two Hartmann images. Locates the centroids in both instances and then determines the displacements of all the centroids between the two images. The locations of the centroids are plotted in a diagram and the x- and y- centroid displacements are plotted vs the index of each centroid.

The following comments are output on the command line in MATLAB:


>> test_HS_Classes
Current plot held
Current plot released
Obtained reference and test centroids.
Number of centroids in reference centroids = 951
average position of reference centroids:
x = 506.39615297  y = 512.890603168
Number of centroids in test centroids = 951
average position of test centroids:
x = 506.396160891  y = 512.892513673


HWS_code_output.png - shows the output from the code: we'll need to get more labels on these plots.

HWS_input_image.png - the reference input image (using false color scale) to the Hartmann code

  94   Mon Sep 13 18:24:52 2010 AidanLaserHartmann sensorEnclosure for the HWS

I've assembled the box Mindy ordered from Newport that will house the Hartmann sensor. It's mainly to reduce ambient light, air currents and to keep the table cleaner than it would otherwise be.

We need to add a few more holes to allow access for extra cables.


  95   Tue Sep 28 10:41:32 2010 AidanLaserHartmann sensorAligning HWS cross-sample experiment - polarization issues

I'm in the process of aligning the cross-sampling experiment for the HWS. I've put the 1" PBS cube into the beam from the fiber-coupled SLED and found that the split between s- and p-polarizations is not 50-50. In fact, it looks more like 80% reflected and 20% transmitted. This will, probably, be due to the polarization-maintaining patch-cord that connects to the SLED. I'll try switching it out with a non-PM maintaining fiber.


Later ...

That worked.

  96   Tue Sep 28 17:53:40 2010 AidanLaserHartmann sensorCrude alignment of cross-sampling measurement

I've set up a crude alignment of the cross-sampling system (optical layout to come). This was just a sanity check to make sure that the beam could successfully get to the Hartmann sensor. The next step is to replace the crappy beam-splitter with one that is actually 50/50.

Attached is an image from the Hartmann sensor.

  97   Wed Sep 29 16:49:36 2010 AidanLaserHartmann sensorCross-sampling experiment power budget

I've been setting up the cross-sampling test of the Hartmann sensor, Right now I'm waiting on a 50/50 BS so I'm improvising with a BS for 1064nm.

The output from the SLED (green-beam @ 980nm) is around 420uW (the beam completely falls on the power meter.) There are a couple of irises shortly afterwards that cut out a lot of the power - apparently down to 77uW (but the beam is larger than the detection area of the power meter at this point - by ~50%). The BS is not very efficient on reflection and cuts down the power to 27uW (overfilled power meter). The measurement of 39uW is near a focus and the power meter captures the whole beam. There is a PBS cube that is splitting the beam unequally between s- and p-polarizations (I think this is due to uneven reflections for s- and p-polarizations from the 1064nm BS). The beam is retro-reflected back to the HWS where about 0.95uW makes it to the detector.

There is a 1mW 633nm laser diode that is used to align the optical axis. There are two irises that are used to match the optical axis of the laser diode and the SLED output.


  98   Mon Oct 4 19:44:03 2010 AidanLaserHartmann sensorCross-sampling experiment - two beams on HWS

I've set up the HWS with the probe beam sampling two optics in a Michelson configuration (source = SLED, beamsplitter = PBS cube). The return beams from the Michelson interferometer are incident on the HWS. I misaligned the reflected beam from the transmitted beam to create two Hartmann patterns, as shown below.

The next step is to show that the centroiding is a linear superposition of these two wavefronts.

  99   Tue Oct 5 12:51:16 2010 AidanLaserHartmann sensorVariable power in two beams of cross-sampling experiment

The SLED in the cross-sampling experiment produces unpolarized light at 980nm. So I added a PBS after the output and then a HWP (for 1064nm sadly) after that. In this way I produced linearly p-polarized light from the PBS. Then I could rotate it to any angle by rotating the HWP. The only drawback was that the HWP was only close to half a wave of retardation at 980nm. As a result, the output from this plate became slightly elliptically polarized.

The beam then went into another PBS which split it into two beams in a Michelson-type configuration (REFL and TRANS beams) - see attached image. By rotating the HWP I could vary the relative amount of power in the two arms of the Michelson. The two beams were retro-reflected and we then incident onto a HWS.

I measured the power in the REFL beam relative to the total power as a function of the HWP angle. The results are shown in the attached plot.


  100   Thu Nov 4 13:31:19 2010 Won KimComputingHartmann sensorFrame Grabber SDK installation

 Appended below is the step by step procedure that I used to install and
use the frame grabber SDK. Note that the installation process was a lot
simpler with the SDK version than the previous version.

Lines starting with ":" are my inputs and with ">" the computer outputs.

I tried to put this into elog but the web page says the laser password is
wrong so I could not.



0. Turn on or restart the computer. For installation of the frame grabber
  SDK, go to step 1. If using the existing installation go to step 5.

1. Copy the script EDTpdv_lnx_4.2.4.3.run to my home folder.

2. Ensure that the script is executable.

: chmod +x EDTpdv_lnx_4.2.4.3.run

3. Run the script.

: sudo ./EDTpdv_lnx_4.2.4.3.run

4. After entering the root password, the script asks for the installation
  directory. Default is /opt/EDTpdv, to which I type 'y'.

  The script then runs, printing out a massive log. This completes the
  installation process.

5. Move to the directory in which the SDK is installed.

: cd /opt/EDTpdv

6. Initialise the camera by loading a camera configuration file
  dalasa_1m60.cfg located in the camera_config folder.

: ./initcam -f camera_config/dalsa_1m60.cfg

  Which will output the message (if successful)

opening pdv unit 0....

7. Take an image frame.

: ./take -f ~/matlab/images/test.raw

  which will save the raw file as specified above and generate following
  message on the terminal:

reading image from Dalsa 1M60 12 bit dual channel camera link
width 1024 height 1024 depth 12  total bytes 2097152
writing 1024x1024x12 raw file to /home/won/matlab/images/test.raw

(actual size 2097152)

1 images 0 timeouts 0 overruns

Whether the image taken was valid or not, I followed the exactly same
procedure. In step 7, when the image was not valid, the message after
executing the take command said "1 timeoutouts", and when the image was
valid I got "0 timeouts".

You will also get "1 timeouts" if you turn off the camera and execute the
take command. So at least I know that when an image taken was not valid it
is due to the frame grabber failing to obtain the image from the camera.

  101   Tue Nov 23 06:15:08 2010 WonComputingHartmann sensorImage folder structure

Attached below is a diagram that describes the organisation of image folders that I am using at the moment with Run_initialize and Run_acquire scripts.

Once the uppermost folder 'image' is set up, other folders in it will be created by the matlab codes if not present. Still it may be of less hassle to create the folders beforehand.

Images that are used during State 1 are saved inside 'probe' and 'secondary' folders (but not inside 'cbt' folders) with prefixes, e.g., 'dark' (for background count estimation) 'expadj' (for exposure adjustments), 'test' etc.

Hope this helps to understand image saving/reading procedures used throuout the two Run scripts. 


  109   Wed Feb 23 20:18:30 2011 AidanElectronicsHartmann sensorSuccessfully re-started the Hartmann sensor

 I reattached the Hartmann Sensor to the LENOVO machine that is running Ubuntu and turned it on (it's been disconnected for a couple of months). The /opt/EDTpdv/serial_cmd was able to communicate successfully with the camera.

  113   Thu Feb 24 14:23:58 2011 AidanLab InfrastructureHartmann sensorHartmann Sensor box cut down to size

 I reduced the height of the Hartmann sensor box. This is what it looks like now:


  114   Mon Feb 28 17:33:07 2011 AidanComputingHartmann sensorHartmann Seidel abberation channels in frame builder

Using the same methods as before, see below, I've added some Hartmann sensor EPICS channels to the frames.

The channels record the Hartmann sensor Probe (and Secondary) Coefficients of the Seidel aberrations (PSC, SSC) that are specified (PRISM, ALPHA, PHI, etc).

  1. Created /cvs/cds/caltech/chans/daq/C4HWS.ini with the attached contents.
  2. Added a line to /cvs/cds/caltech/target/fb1/master to load C4HWS.ini
  3. restarted the frame builder by killing daqd




 I've added the digitizer and sensor board temperature readings from the HWS to the frames. This was done in the following way

1. Create a new file /cvs/cds/caltech/chans/daq/C4TCS.ini - with the channels in it - see below

2.  open /cvs/cds/caltech/target/fb1/master

3. add a line that includes the C4TCS.ini file when the frame builder starts

4. restart frame-builder by killing the daq daemon - kill <process id for daqd> (this is the only thing that needs to be entered as it will automatically restart)























  115   Mon Feb 28 17:56:32 2011 AidanComputingHartmann sensorGot HWS code running and interface to EPICS

Here are the notes from today's efforts:



- When you 'Run_HWS' in MATLAB and the camera has not been initialized, it says the camera is not accessible. Either that or you need to run 'sudo matlab' (no, sudo doesn't help)

- In Ubuntu have to run '/opt/EDTpdv/initcam -f ~/dalsa_1m60.cfg' to start the camera

- Now have to install MCA

- MCA installed by is crashing MATLAB - not sure why. Maybe its a 'sudo' problem again?
- sudo matlab has the following problem:
??? Invalid MEX-file
libdbStaticHost.so.3.14: cannot open shared object file: No such file or
- adjusting Makefile for MCA to include the correct suffix for a Linux based MEX file ('mexa64', not 'mexglnx') gets the program to compile correctly and then MATLAB runs MCA fine.

- Running 'Run_HWS' with EPICS running but no channels crashes the program

- copy the HWS.db file to the EPICS db location

- cannot create the matlab images folder when the program runs.
- created these manually
- program is trying to adjust the maximum pixel count - it is failing and the camera is complaining (intensity is quite low right now)
- why exposure mode 6? - requires an external SYNC signal
- can't handle low exposure - FIX THIS!!
- why is the expsoure time increased in stepwise fashion? Use algorithm!
      - Commenting this out!!
    - same for the secondary beam
- After running State 1 it asks to continue to State 2 - if you select 'n' the program crashes

- steered beam properly onto HWS
- continue to State 2 - 'yes' crashes the program
- HS_report is doesn't work
- commented out lines 37 to 47

- get rid of constant requests to continue [run_acquire_auto.m]
- change names of EPICS variables [done]
- add an RMS variable
- the named EPICS variables need to be dynamically named rather than statically named.

run_acquire_auto.m CHANGES
0. Update sensor date: mres = 'y'
1. pres = 'n'; - don't update reference centroids
2. sres = 'n'; - don't update secondary reference centroids
3. select probe beam commented out
4. select secondary beam commented out
5. State 2B - select probe live commented out
6. set user_response = 'y' for continue

A1 - added a loopcounter that starts at zero. the first loop includes user prompts and then they're bypassed in subsequent loops.


-Seidel aberration fitting seems wrong - not resembling the integrated field
- get rid of the constant pop ups
- have a network license EPICS variable
- how many images are used for reference image?
    - added a variable in run_acquire_auto.m :
        - no_of_cim_ref = 200; (no_of_cim = 5 images was previous)
    - changed the averaging in reference image acquisition from
        - "no_of_cim" to "no_of_cim_ref"
    - didn't change the take command from 5 to 200 images
- commented out lines 239-242 in run_initialize - gives a second way to start run_acquire.m
- probe and secondary beams share the probe background - deliberate?
- average all the images and save as a single matlab 16-bit array
- what is the rms noise as a function of the reference image number of averages?

Changing the EPICS variable names.
1. HS_WF - where Seidel coefficients are named.
    - in function seidel_from
2. changed the following lines in 'run_acquire_auto.m'
        %channelname = ['probe-seidel-',fn{counter}];
            channelname = ['C4:TCS-HWSX_PSC_', fn{counter}];

        %channelname = ['secondary-seidel-',fn{counter}];
            channelname = ['C4:TCS-HWSX_SSC_', fn{counter}];
3. ammended the following code in 'run_acquire_auto.m'

    maxEPICSLength = 14;
    for counter = 1:length(fn)
        %channelname = ['probe-seidel-',fn{counter}];
        strname = upper(fn{counter});
        if (numel(strname) > maxEPICSLength)
            strname = strname(1:maxEPICSLength);
        channelname = ['C4:TCS-HWSX_PSC_', strname];
        probe_seidel_array{counter} = HS_EPICS(channelname);
- bug: on restarting and pressing 'space' and enter at approximately the same times here, the program crashed:

Is it okay to assign one of the already existing handle (y or n)? y
Assigned handle 2 to the instance.
Established the connection to the channel secondary_shutter_open.

hsep_secondary =

  HS_EPICS handle

         channelname: 'secondary_shutter_open'
             handler: 2
    EPICS_is_running: 1

  Methods, Events, Superclasses

Please select the probe beam as the light source. Hit any key to continue.

??? Error using ==> textscan
First input can not be empty.

Error in ==> HS_Camera>HS_Camera.get_exposure_time at 942
        ccet = textscan(ccet,'%f %s');


Added the following lines to HWS.db

record(ai, "C4:TCS-HWSX_PSC_PRISM")
record(ai, "C4:TCS-HWSX_PSC_ALPHA")
record(ai, "C4:TCS-HWSX_PSC_PHI")
record(ai, "C4:TCS-HWSX_PSC_COMA")
record(ai, "C4:TCS-HWSX_PSC_BETA")
record(ai, "C4:TCS-HWSX_SSC_PRISM")
record(ai, "C4:TCS-HWSX_SSC_ALPHA")
record(ai, "C4:TCS-HWSX_SSC_PHI")
record(ai, "C4:TCS-HWSX_SSC_COMA")
record(ai, "C4:TCS-HWSX_SSC_BETA")

- restarting IOC with C4:TCS-HWSX channels


-time to add these to the frames


  116   Tue Mar 1 10:47:18 2011 AidanMiscHartmann sensorElectron to Counts conversion efficiency

Using some of the old data from James (attached below), I calculated the CCD conversion efficiency (CE) from electrons to bits (Counts).

Number of electrons(Ne) = QE*Number of Photons(Np)

noiseE = sqrt(Ne);

Number of Counts (NCo)= CE*Ne

Noise in Counts (noiseCo)= CE*sqrt(Ne)

noiseCo = sqrt(CE * NCo)

log(CE) = 2*noiseCo - NCo

Therefore CE = 10.0^(2*noiseCo - NCo)

From James's data on the intensity noise in the CCD, CE = 0.0269


Using this function, I did the same analysis of the upper-left 200x200 pixels over all 200 images:

(data from 200 images, over the upper-left 200x200 pixels)


  119   Tue Mar 1 17:05:45 2011 AidanElectronicsHartmann sensorDalsa 1M60 current draw

Steve and I measured the current drawn by the Dalsa 1M60 by connecting it to the BK Precision 1735 lab power supply that display current and voltage supplied. We tried the camera at a variety of different voltages. The results are presented below:

Voltage  Current(t<5s)  Current(5s<t<10s)   Current(t>10s)

12.7V       0.6A              0.8A              1.11A

15.0V       0.55A             0.69A             0.91A

18.0V       0.41A             0.57A             0.75A

20.0V       0.42A             0.52A             0.67A

Additionally, we tried running the other camera with the lab power supply. I varied the exposure mode and exposure time and checked the current drawn. The supplied voltage was 18.0V.

Exposure Mode 4: current = 0.67A

Exposure Mode 2: 58Hz, exposure time = 16 ms, current = 0.70A

Exposure Mode 2: 58Hz, exposure time = 100 us, current = 0.72A

Exposure Mode 2: 1Hz, exposure time = 998 ms, current = 0.68A

Exposure Mode 2: 1Hz, exposure time = 16 us, gm 0, current = 0.69A

Exposure Mode 2: 1Hz, exposure time = 16 us, gm 2, current = 0.69A

  120   Thu Mar 3 07:30:18 2011 WonComputingHartmann sensorEffect of high pixel count on rms

We have been investigating how pixel count is related to the centroid displacements by taking several sets of image frames with different camera
exposure time and input current.

It appears that the reason why rms value did not drop as fast as it should (as the number of averaged image frames increases) is that the pixel counts were too high.

As was previously done, we took 5000 images for rms analysis, and the reference set of centroids were generated from averaging 4000 sets of centroids using first 2000 and last 2000 images. Once a set of centroids for each image frame is obtained and saved (it took about 30 minutes to obtain centroids of 5000 image frames), rms analysis could be done in seconds.

(Alternatively, one could average the images first then find centroids, but this is much slower and the rms values do not change much.)

First figure is the log plot of rms versus N_av (number of image frames that are averaged over), where the maximum pixel count was about 2000.

Blue line is the calculated rms values, red line is the linear fit of the rms values, and black line is the line of the ideal slope -0.5. The rms values are in pixel units. The slope of the linear fit is -0.487. 

Centroids are obtained from the images taken with the exposure time of 23ms, the value of the current driving light source 28 mA, and the distance between the CCD and the light source was about 50 cm. 


Second figure is the plot using images whose max pixel counts were about 2700 (30ms exposure, same current): this gave the fitted slope to be -0.07.


Next two figures are the plots of rms with the same image set (images with max pixel count of 2700), using 

1. centroids whose peak pixel counts are below 2048 (45 out of 904 centroids), and

2. centroids whose peak pixel counts are above 2047 (859 out of 904 centroids). 
Peak pixel counts were obtained from the first image frame. As pixel counts fluctuate between image frames, it would perhaps be better to use averaged images but the outcome will still be qualitatively the same.

These plots clearly show that centroids with high peak pixel counts are responsible for poor reproducibility of the centroids.

The reason why the value of 2048 was chosen to separate centroids is because the camera will have to use the 12th bit for pixel counts 2048 or above.

I need to do more analysis to determine conclusively if the 12th bit is indeed responsible. What is clear at this point is that, once peak pixel counts go over about 2000, the reproducibility of centroids worsens significantly.


Further investigation revealed that, for the second centroids set (i.e., the centroids obtained from 30ms images) I discussed here, the decrease in centroids reproducibility is due to one spot whose position fluctuated much more wildly than others. That same spot does not cause problems in my first set with lower pixel counts. Here is the 2D plot of rms values of individual centroids fluctuations over image frames. I used griddata command to interpolate values between centroids to get this false color map;


The spot shown on the plot corresponds to the centroid located at the pixel (x,y) = (749,353). Its rms value with N_av = 1000 was 0.055 pixel uniits, which is more than ten times as big as average centroid displacements between two images (which is about 0.003).

Once you remove this centroid from the reference set and redo the analysis, the fitted slope goes back to -0.46.

Since I was wondering if high pixel counts worsens the reproducibility of the centroids, I also generated scatter plot of (1) rms vs peak pixel counts and (2) fitted slope for each centroid vs peak pixel counts (without removing the problematic centroid):

rms_v_pc-with.png slope_v_pc-with.png

It is evident that one centroid is a huge outlier in rms vs pixel counts plot, but it is not so obvious in the plot of slopes vs pixel counts. Furthermore, there does not appear to be any correlation between pixel counts and the values of the fitted slopes. 

And here are the scatter plots after removing the problematic centroid:


which suggests that there is no real correlation between peak pixel counts of centroids and their values of rms or fitted slope. What is still happening, although, is that as we increase pixel counts by either increasing the camera exposure time or the intensity of the light source, the value of the fitted slope increases as well (hence decreases the reproducibility of centroids).

I will continue this discussion in my next post...

  121   Tue Mar 8 11:30:26 2011 AidanComputingHartmann sensorHartmann sensor code changes and NTP server

I've made the following changes to the Hartmann sensor code and to the machine running the HWS.

  • Machine name is now princess_sparkle (
  • I set up ntpd on that machine to sync the clock to GPS - roughly.
  • I added a MATLAB function (store_current_centroids.m) to the Hartmann sensor that saves the centroids and peak intensities to file in GPS labeled files
  • ~/Hartmann_Sensor_Data/centroids/<GPSTIME1>/<GPSTIME2>/<GPSTIME>_<name>.mat

GPSTIME1 = floor(GPSTIME/4E4)*4E4

GPSTIME2 = floor(GPSTIME/2E2)*2E2

I had to add a line in the run_acquire_auto.m script to accommodate this new function and I had to add a function that calculates the peak intensities to the HS_Centroids.m class.

  123   Tue Mar 8 18:48:00 2011 AidanComputingHartmann sensorHWS code is running and recording centroids

The Hartmann sensor is running continuously and is now recording data to file. The formatting has changed slightly with the data now stored in structures called store_measurement every 200s in files in the following way:

  • store_measurement(ii).centroids - the ii-th centroids
  • store_measurement(ii).intensities - the ii-th intensity list
  • store_measurement(ii).time - the time of the ii-th measurement

The files are stored in ~/Hartmann_Sensor_Data/centroids/<GPSTIME rounded to nearest 4E4 seconds>/<GPSTIME rounded to nearest 2E2 seconds>_<subname>.mat


  125   Wed Mar 9 01:00:12 2011 Peter Veitch, Won KimComputingHartmann sensorControl of frame rate usign external trigger

We managed to successfully apply frame rate control via external trigger from a pulse generator.

We supplied 5V pulse train when connected to the optocoupler load, and connected to pins 1 and 2 of external trigger (on the frame grabber board) for using camera 0 (which is the case for us).

Then made the following changes to the config file dalsa_1m60.cfg;

MODE_CNTL_NORM: A0 (previously this value would have been 00)

user_timeout: 0    (this line should be added)

Then I saved the new config file as dalsa_1m60_et.cfg

Next, I loaded the new config using initcam command, then set the exposure mode to be 3. This can be done either using serial_cmd directly or using HS_Camera method set_exposure_mode.

In exposure mode 3, the exposure time is set by the time separation between the falling edges of the pulses, and the camera sets the expousure time to be the maximum value possible (as specified in the camera manual). 

Then I took 10 images using take command, and verified that the frame rate is equal to the frequency of the pulse. We tested 1 Hz and 2 Hz pulse trains, and the frame grabber recoded 1 frames per sec and 2 frames per sec respectively.

We could not yet test the frequency values < 1 Hz as pulse generator we used could not go under 1 Hz.


We used another pulse generator to test pulse frequencies under 1 Hz, and verified that external trigger mode still works.

  128   Mon Mar 28 13:00:50 2011 AidanLaserHartmann sensorTo do: Check the polarization from the SLED
  129   Wed Mar 30 12:55:54 2011 AidanLaserHartmann sensorPrism modulation experiment

I've set up a quick experiment to modulate the angle of the Hartmann sensor probe beam at 10mHz and to monitor the measured prism. The beam from the SLED is collimated by a lens and this is incident on a galvo mirror. The reflection travels around 19" and is incident on the HWS. When the galvo mirror is sent a 1.1Vpp sine wave, then beam moves around +/- 0.5" on the surface of the Hartmann sensor, giving around 50mrad per Vpp.

The galvo is currently being sent a 0.02Vpp sine wave at 10mHz.

  130   Thu Mar 31 11:27:02 2011 AidanLaserHartmann sensorPrism modulation experiment

I changed the drive amplitude on the function generator to 0.05Vpp and have measured the angle of deflection by bouncing a laser off the laser mirror and projecting it 5.23m onto the wall. The total displacement of the spot was ~3.3mm +/- 0.4mm, so the amplitude of the angular signal is 1.6mm/5.23m ~ 3.1E-4 radians. The Hartmann Sensor should measure a prism of corresponding magnitude.

The frequency is still 10mHz.


I've set up a quick experiment to modulate the angle of the Hartmann sensor probe beam at 10mHz and to monitor the measured prism. The beam from the SLED is collimated by a lens and this is incident on a galvo mirror. The reflection travels around 19" and is incident on the HWS. When the galvo mirror is sent a 1.1Vpp sine wave, then beam moves around +/- 0.5" on the surface of the Hartmann sensor, giving around 50mrad per Vpp.

The galvo is currently being sent a 0.02Vpp sine wave at 10mHz.


  131   Fri Apr 1 02:41:55 2011 WonComputingHartmann sensorexposure time and reproducibility of centroids

 Here is a brief and preliminary summary of rms of centroid displacements calculated at a number of different exposure time values. To get the results I did the following for each value of exposure time:

1. Take a set of images. I took 2000 images for shorter exposure times, 1000 images with exposure times greater than 1 second, and 200 images with exposure time 4.4 second. I tried to keep the maximum pixel count to be roughly the same (about 2430 plus/minus 40).

2. Obtain the centroids for each image frames in a set. I saved centroids as an array of n by m by 2, where n is the number of image frames that I took, m is the number of centroids in each frame, and 2 for x and y coordinates.

Then I iterated through the centroid sets to calculate total rms, using various N_av values. If N_av = 100; then reference centroids were obtained by averaging the centroids of first 50 and the last 50 frames, and remaining 100 frames are averaged to get the other (or non-reference) centroids. I think this method gives a better view of the centroid reproducibility than fixing the number of reference centroids to be, say, first 1000 and last 1000 frames and varying the number of frames to be averaged for non-reference centroid.

Datasets of centroids are labelled as spcdet_I_t, where spcdet stands for "same (maximum) pixel count (with) differen exposure times", I the value of the current that drives the light source, and t the exposure time that I used.

Here are the plots:






It can be seen from these plots that the benefit of averaging multiple frames quickly diminish once we go over 1 second. I am investigating if there is any way to improve the reproducibility while using the same sets of images.

Issues that need further investigation:

  1. Effect of pixels with unusually high pixel count. Dark images that we took show that, with longer exposure times, not only overall dark noise increase (and become less uniform) but also several pixels show unusually high pixel count (even higher than 2000), without a light source on. More investigation is needed to determine how much this affects the centroids calculation and to devise an way to deal with it.

  2. Extra/Duplicate centroids. As exposure time increased, I observed that duplicate centroids start to appear, i.e., HS_Centroids##centroids had duplicate entries. The number of duplicate entries increased as exposure time increased. I believe this is due to the images getting noisier as exposure time increases. So After taking initial reference centroids, I removed duplicate centroid entries before calculating rms. I am thinking about adding a method to do this in HS_Centroids class.

In addition, there were one 'false' centroid when the exposure time was 4.4 seconds. For now I chose to manually remove it myself before calculating rms.

  132   Fri Apr 1 09:51:45 2011 AidanComputingHartmann sensorPrism measurement

 I analyzed the results from the prism experiment. The time series and spectra of the prism are attached.

Conclusions to follow ...

  137   Sun Apr 17 21:55:51 2011 AidanLaserHartmann sensorHartmann sensor prism/displacement test

I've set up an experiment to test the HWS intensity distribution displacement measurement code. Basically the beam from a SLED is just reflecting off a galvo mirror onto the HWS. The mirror is being fed a 0.02Vpp *10 gain, 10mHz sinewave from the function generator.

The experimental setup is shown below.

I hacked the HWS code to export the Gaussian X and Y centers to Seidel Alpha and Beta channels in EPICS (C4:TCS-HWSX_PSC_ALPHA, C4:TCS-HWSX_PSC_BETA)

  139   Mon Apr 18 15:06:53 2011 AidanThings to BuyHartmann sensorOrdered 2" optics from Newport

 Given that the HWS requires several 2" optics to handle the big beam size, I've ordered the following items from Newport:

  • 2x 2" 50/50 beam splitter: 20B20BS.2
  • 6x 2" NIR mirrors: 5122
  • 8x 2" Ultima mirror mounts: U200-A2K
  144   Tue May 10 00:55:08 2011 WonComputingHartmann sensorMatlab Compiler and Matlab Compiler Runtime


I have spent some time with Matlab Compiler and Matlab Compiler Runtime (MCR). I could only get my hands on 2008b version so far, but I believe 2009b version will work in the same way.


Below is a set of notes based on my experience so far.



Matlab compiler installation

1. Copy the toolbox archive files to the folder where matlab is installed. To me this is /usr/matlab_2008b/ (may need to do as root or use sudo). Two files to be copied are tbx.compiler.common and tbx.compiler.glnxa64.

sudo cp tbx.compiler.* /usr/matlab_2008b/

2. Execute the install script.

cd /usr/matlab_2008b
sudo ./install

3. Enter the file installation key that came with the matlab compiler files.

4. Leave the root directory as it was.

5. Finish the installation by activating the toolbox with the license file.

Build a standalone application using matlab compiler

I created a folder called matlab_project as a place to put compiled applications, and matlab_predep as a place to put files to be deployed.

Once Matlab Compiler is installed, it can be launched from the matlab console by typing deploytool. Then I proceeded as below:

1. Create a new project by clicking the New icon (the first one from the left).

2. Choose a standalone application.

3. Click main file and Go to menu Project -> Add Files (or right_click on "main file" icon).

4. Choose the matlab file hello.m (in my case, from matlab_predep folder). hello.m could be, for example, a simple script like

function hello

5. Click the Build icon (third from the right).

When the process finishes, inside matlab_project folder I found a file called "hello.prj" and a folder called "hello". Insider the hello folder was two folders "distrib" and "src".



Install Matlab Compiler Runtime

1. Run MCRinstaller.bin as root. I found this file in the folder /usr/matlab_2008b/toolbox/compiler/deploy/glnxa64

2. Go along with the default options unless desired otherwise.

3. Add following to .bashrc, below the entries regarding EPICS. $LD_LIBRARY_PATH should now be aware of EPICS as well as MCR related paths. 

export MCR_ROOT=/opt/MATLAB/MATLAB_Compiler_Runtime
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MCR_ROOT/v79/runtime/glnxa64:$MCR_ROOT/sys/os/glnxa64:$MCR_ROOT/v79/sys/java/jre/glnxa64/jre1.6.0/lib/amd64/native_threads:$MCR_ROOT/v79/sys/java/jre/glnxa64/jre1.6.0/lib/amd64/server:$MCR_ROOT/v79/sys/java/jre/glnxa64/jre1.6.0/lib/amd64
export XAPPLRESDIR=$MCR_ROOT/v79/X11/app-defaults

4. Run the revised .bashrc by typing 'source ~/.bashrc'. Next time the user logs in, doing this won't be necessary.


Run the built application

1. Go to distrib folder to find the executable application file (e.g., hello). You will also find the executable shell script (e.g., run_hello.sh), the role of which is basically to set up environment variables and run the application, in case the environment variables are not globally set up.

2. Once in that folder, run the application by simply typing ./ and its name (e.g., ./hello). If the library environment variable is set up as in the step 3 of "Install Matlab Compiler Runtime", the application will be run and you should see the hello message as the output.

Build an application that uses HS classes

I wrote a simple script test_HS.m that takes and saves 10 images using the camera, averages the images and finds centroids. Thus the script requires the class files HS_Base, HS_Camera, HS_Image, and HS_Centroids.

I added those four class files by right-clicking Other Files (found below Main function) then choosing Add File, then clicked the build icon.

  145   Wed May 11 09:07:03 2011 AidanComputingHartmann sensorChanged ownership of /opt/EDTpdv

 I changed the ownership of /opt/EDTpdv to controls with the command:

controls@princess_sparkle:/opt/EDTpdv$ sudo chown controls EDTpdv/


  146   Wed May 11 18:38:47 2011 AidanComputingHartmann sensortest_HS binary

 From Won: (the zip file is also on the SVN /users/won/compiled_code/test_HS.zip)


Attached is test_HS.zip file, that contains

- test_HS.prj: project file created by Matlab Compiler. This file is not
 required to run the application but I included it just in case someone's

- test_HS folder contains two subfolders src and distrib, each of which
 contains the standalone application test_HS.

Usage: test_HS <path to the image folder>, for example

 test_HS ~/test_images/

Make sure you create the folder prior to running the application, and the
folder name ends with "/". Running test_HS will take and save 10 images
using the camera (provided the frame grabber applications are installed in
/opt/EDTpdv), averages those 10 images and find centroids, then plots the

As I put in the eLOG, one needs MCRInstaller.bin and run it to install MCR
(probably 2008b 64bit version to test my files). If there are difficulties
getting MCRInstaller, let me know.



  147   Wed May 11 18:44:54 2011 AidanComputingHartmann sensorMatlab Compiler and Matlab Compiler Runtime

Installing MCR

I located the MCRInstaller on our distribution of MATLAB on the Ubuntu machine (/MATLAB_R2009b/toolbox/compiler/deploy/glnxa64/MCRInstaller.bin). I ran the installer, as root,and followed the default options to install it. Next I updated the .bashrc file to include the necessary pointers to various libraries:


export LD_LIBRARY_PATH=/home/controls/base-3-14-11/lib/linux-x86_64:/MATLAB_R2009b/runtime/glnxa64:/MATLAB_R2009b/bin/glnxa64
export MCR_ROOT=/opt/MATLAB/MATLAB_Compiler_Runtime
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MCR_ROOT/v79/runtime/glnxa64:$MCR_ROOT/sys/os/glnxa64:$MCR_ROOT/v79/sys/java/jre/glnxa64/jre1.6.0/lib/amd64/native_threads:$MCR_ROOT/v79/sys/java/jre/glnxa64/jre1.6.0/lib/amd64/server:$MCR_
export XAPPLRESDIR=$MCR_ROOT/v79/X11/app-defaults
Running test_HS binary from Adelaide on Ubuntu distribution


I've downloaded the test_HS binary from the SVN and added the ~/test_images/ directory as recommended by Won. I then ran the code by entering ./test_HS ~/test_images/


The code ran successfully through the serial_cmd access and the image acquisition process and only crashed when it tried to access the variable mes_message. This indicates a run-time error, not a compilation error. If you examine lines 751 and 752 of HS_Camera.m you can see the typo (mes_meesage vs mes_message) in the code that is the source of the error:

751                 mes_meesage = ['Intensity too high: ',fobj.name];
752                 cam.inform_messenger('ImageNotValid',mes_message);

Here's the output:


controls@princess_sparkle:~/Hartmann_Sensor_SVN/users/won/compiled_code/test_HS/test_HS/distrib$ ./test_HS ~/test_images/
The camera is accessible.

G E N E R A L   C A M E R A   S E T T I N G S:

Camera Model No.:               DS-22-01M60-11E
Camera Serial No.:              04437062
Sensor Serial No.:              0411218

Tap 1 Gain:                     0
Tap 2 Gain:                     0

Firmware Design Rev.:           03-81-00070-03  Sep 30 2004
DSP Design Rev.:                17.3

Pretrigger:                     0      
Video Mode:                     Normal Operating Mode
Data Mode:                      12 bit 
Binning Mode:                   1x1

Gain Mode:                      1x Output Gain Mode
Output Configuration:           2 Tap
Exposure Control:               enabled
Exposure Mode:                  2      

SYNC Frequency:                 8 Hz
Exposure Time:                  123646.66 uSec


executing /opt/EDTpdv/take -s 1 -l 10 -f /home/controls/test_images/test ...
??? Undefined function or variable "mes_message".

Error in ==> HS_Camera>HS_Camera.read_raw at 752

Error in ==> HS_Camera>HS_Camera.read_from_folder at 668

Error in ==> HS_Camera>HS_Camera.read_from_fg at 721

Error in ==> HS_Camera>HS_Camera.read_images at 590

Error in ==> test_HS at 9




Build an application that uses HS classes

I wrote a simple script test_HS.m that takes and saves 10 images using the camera, averages the images and finds centroids. Thus the script requires the class files HS_Base, HS_Camera, HS_Image, and HS_Centroids.

I added those four class files by right-clicking Other Files (found below Main function) then choosing Add File, then clicked the build icon.


ELOG V3.1.3-